AppearanceService

# AppearanceService

管理宿主的视觉外观:主题模式、强调色、壁纸、图标动效。

import { useService, useServiceState } from '@autumnbox/sdk/hooks';
import { AppearanceService } from '@autumnbox/sdk/hooks';

# 响应式状态

状态 类型 说明
themeMode IReadonlyState<'light' \| 'dark' \| 'system'> 当前主题偏好
isDark IReadonlyState<boolean> 解析后的暗色模式布尔值(system 时跟随系统)
accentColor IReadonlyState<string> 强调色 CSS 值(默认 #4a90d9
currentWallpaper IReadonlyState<string> 当前壁纸(CSS background 值)
magnification IReadonlyState<boolean> 桌面图标放大动效开关
iconMouseLight IReadonlyState<boolean> 桌面图标鼠标光效开关

# 主题切换

const appearance = useService(AppearanceService);

// 循环切换 light → dark → system → light
appearance.toggleThemeMode();

// 直接设置模式
appearance.setMode('dark');
appearance.setMode('light');
appearance.setMode('system');  // 跟随操作系统

# 强调色

强调色(主色)影响 Ant Design 的 colorPrimary、按钮、链接等元素。

appearance.setAccent('#ff6b6b');   // 珊瑚红
appearance.setAccent('#4a90d9');   // 默认蓝

# 壁纸

// 设置内置壁纸
appearance.setWallpaper({ type: 'builtin', id: 'aurora' });

// 关闭壁纸
appearance.setWallpaper({ type: 'none' });

// 获取所有内置壁纸
const entries = appearance.getBuiltinEntries();
// → [
//   { id: 'aurora', name: '极光', css: 'linear-gradient(...)' },
//   { id: 'sunset', name: '日落', css: 'linear-gradient(...)' },
//   { id: 'ocean',  name: '海洋', css: 'linear-gradient(...)' },
//   { id: 'forest', name: '森林', css: 'linear-gradient(...)' },
//   { id: 'lavender', name: '薰衣草', css: 'linear-gradient(...)' },
//   { id: 'night',  name: '夜空', css: 'linear-gradient(...)' },
//   { id: 'peach',  name: '蜜桃', css: 'linear-gradient(...)' },
//   { id: 'cosmic', name: '星河', css: 'linear-gradient(...)' },
// ]

# 图标动效

// 鼠标悬停时图标放大效果
appearance.toggleMagnification();
appearance.setMagnificationEnabled(true);

// 鼠标悬停时图标光效
appearance.toggleIconMouseLight();
appearance.setIconMouseLightEnabled(false);

# 实战示例:设置面板

import React from 'react';
import { Card, Switch, Space, Typography, ColorPicker } from 'antd';
import { useService, useServiceState } from '@autumnbox/sdk/hooks';
import { AppearanceService } from '@autumnbox/sdk/hooks';

const { Text } = Typography;

const AppearancePanel: React.FC = () => {
  const appearance = useService(AppearanceService);
  const isDark = useServiceState(appearance.isDark);
  const accent = useServiceState(appearance.accentColor);
  const magnification = useServiceState(appearance.magnification);
  const mouseLight = useServiceState(appearance.iconMouseLight);
  const wallpapers = appearance.getBuiltinEntries();

  return (
    <Space direction="vertical" style={{ width: '100%' }}>
      <Card title="主题">
        <Space>
          <Text>暗色模式</Text>
          <Switch
            checked={isDark}
            onChange={() => appearance.toggleThemeMode()}
          />
        </Space>
      </Card>

      <Card title="强调色">
        <ColorPicker
          value={accent}
          onChange={(_, hex) => appearance.setAccent(hex)}
        />
      </Card>

      <Card title="壁纸">
        <Space wrap>
          {wallpapers.map((wp) => (
            <div
              key={wp.id}
              onClick={() => appearance.setWallpaper({ type: 'builtin', id: wp.id })}
              style={{
                width: 80, height: 50, borderRadius: 8, cursor: 'pointer',
                background: wp.css,
              }}
            />
          ))}
          <div
            onClick={() => appearance.setWallpaper({ type: 'none' })}
            style={{
              width: 80, height: 50, borderRadius: 8, cursor: 'pointer',
              background: '#f0f0f0', display: 'flex', alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <Text type="secondary"></Text>
          </div>
        </Space>
      </Card>

      <Card title="动效">
        <Space direction="vertical">
          <Space>
            <Text>图标放大</Text>
            <Switch checked={magnification} onChange={() => appearance.toggleMagnification()} />
          </Space>
          <Space>
            <Text>鼠标光效</Text>
            <Switch checked={mouseLight} onChange={() => appearance.toggleIconMouseLight()} />
          </Space>
        </Space>
      </Card>
    </Space>
  );
};

# 适配暗色模式

插件的 UI 通常不需要手动处理暗色模式——Ant Design 的 ConfigProvider 会自动切换 token。但如果你使用了自定义样式,可以通过 isDark 状态适配:

const MyComponent: React.FC = () => {
  const appearance = useService(AppearanceService);
  const isDark = useServiceState(appearance.isDark);

  return (
    <div style={{
      background: isDark ? '#1a1a2e' : '#ffffff',
      color: isDark ? '#e0e0e0' : '#333333',
    }}>
      自适应内容
    </div>
  );
};

# 下一步