docs(appearance): add bilingual package guides
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: 原子化组合
|
||||
description: 不依赖预设弹窗,使用受控组件构建自己的外观界面。
|
||||
order: 1
|
||||
toc:
|
||||
- id: controlled-atoms
|
||||
title: 受控原子组件
|
||||
- id: compose-card
|
||||
title: 组合主题卡片
|
||||
- id: connected-layer
|
||||
title: 状态连接层
|
||||
---
|
||||
|
||||
## 受控原子组件 {#controlled-atoms}
|
||||
|
||||
`ThemeModeField`、`CompactLayoutField`、`ThemeColorPicker` 和 `ThemeToggle` 都由 `value` 与回调驱动。它们不要求使用偏好上下文,因此可以接入表单、预览工具或其他状态库。
|
||||
|
||||
```tsx
|
||||
<ThemeModeField value={mode} onValueChange={setMode} />
|
||||
<CompactLayoutField checked={compacted} onCheckedChange={setCompacted} />
|
||||
```
|
||||
|
||||
## 组合主题卡片 {#compose-card}
|
||||
|
||||
`ThemeConfigCard` 把预览、基础色和强调色选择组合在一起,但仍由调用方持有配置。
|
||||
|
||||
```tsx
|
||||
<ThemeConfigCard
|
||||
active={resolvedTheme === "light"}
|
||||
compacted={compacted}
|
||||
config={lightTheme}
|
||||
onConfigChange={setLightTheme}
|
||||
scheme="light"
|
||||
/>
|
||||
```
|
||||
|
||||
需要更细粒度的布局时,可以分别使用 `ThemePreview`、`baseColorSwatches`、`accentColorSwatches` 和 `ThemeColorSwatchButton`。
|
||||
|
||||
## 状态连接层 {#connected-layer}
|
||||
|
||||
`AppearanceSettings` 是原子组件与共享 `PreferencesProvider` 之间的默认连接层。自定义界面可以直接使用 `@workspace/preferences` 的 `usePreference` 读取单个字段,而不必复用默认布局。
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: 外观设置弹窗
|
||||
description: 组合触发器、控制器和快捷键得到完整的外观设置流程。
|
||||
order: 1
|
||||
toc:
|
||||
- id: controller
|
||||
title: 挂载控制器
|
||||
- id: trigger
|
||||
title: 添加触发器
|
||||
- id: custom-handle
|
||||
title: 独立弹窗实例
|
||||
---
|
||||
|
||||
## 挂载控制器 {#controller}
|
||||
|
||||
在应用共享的 `PreferencesProvider` 内挂载一次 `AppearanceController`。它组合默认设置内容,并注册 `Mod+,` 打开弹窗和 `Mod+D` 切换主题。
|
||||
|
||||
```tsx
|
||||
<PreferencesProvider
|
||||
effects={[appearancePreferenceEffect]}
|
||||
initialPreferences={preferences}
|
||||
>
|
||||
<AppearanceController />
|
||||
<App />
|
||||
</PreferencesProvider>
|
||||
```
|
||||
|
||||
## 添加触发器 {#trigger}
|
||||
|
||||
`AppearanceDialogTrigger` 可以放在用户菜单、设置按钮或命令面板中。默认情况下,它会连接到默认控制器使用的 handle。
|
||||
|
||||
```tsx
|
||||
<AppearanceDialogTrigger render={<button type="button" />}>
|
||||
界面外观
|
||||
</AppearanceDialogTrigger>
|
||||
```
|
||||
|
||||
## 独立弹窗实例 {#custom-handle}
|
||||
|
||||
页面中需要隔离的外观弹窗时,为控制器和触发器传入同一个新 handle。
|
||||
|
||||
```tsx
|
||||
const handle = createAppearanceDialogHandle()
|
||||
|
||||
<AppearanceDialogTrigger handle={handle} render={<button type="button" />}>
|
||||
打开主题设置
|
||||
</AppearanceDialogTrigger>
|
||||
<AppearanceController handle={handle} />
|
||||
```
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: 接入外观偏好
|
||||
description: 使用应用共享的偏好系统聚合外观定义与副作用。
|
||||
order: 1
|
||||
toc:
|
||||
- id: provider
|
||||
title: 聚合偏好
|
||||
- id: effects
|
||||
title: 注册副作用
|
||||
- id: theme-style
|
||||
title: 注入主题变量
|
||||
- id: persistence
|
||||
title: 持久化更新
|
||||
---
|
||||
|
||||
## 聚合偏好 {#provider}
|
||||
|
||||
在应用边界构建一份完整的偏好定义。把外观、语言、快捷键等功能 package 的 definitions 合并,再创建默认值或从服务端加载初始值。
|
||||
|
||||
```tsx
|
||||
import {
|
||||
createDefaultPreferences,
|
||||
PreferencesProvider,
|
||||
} from "@workspace/preferences"
|
||||
import {
|
||||
appearancePreferenceDefinitions,
|
||||
appearancePreferenceEffect,
|
||||
} from "@workspace/appearance"
|
||||
|
||||
const preferenceDefinitions = {
|
||||
...appearancePreferenceDefinitions,
|
||||
...localePreferenceDefinitions,
|
||||
}
|
||||
|
||||
const initialPreferences = createDefaultPreferences(preferenceDefinitions)
|
||||
const preferenceEffects = [
|
||||
appearancePreferenceEffect,
|
||||
localePreferenceEffect,
|
||||
] as const
|
||||
|
||||
export function Root({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<PreferencesProvider
|
||||
effects={preferenceEffects}
|
||||
initialPreferences={initialPreferences}
|
||||
>
|
||||
{children}
|
||||
</PreferencesProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
只需要外观偏好切片时仍可使用 `defaultAppearancePreferences`;聚合多个 package 时,应优先以 definitions 作为生成完整默认值的单一来源。
|
||||
|
||||
## 注册副作用 {#effects}
|
||||
|
||||
`appearancePreferenceEffect` 组合了两个公开回调:`applyAppearancePreferenceEffect` 在浏览器绘制前更新文档类名和主题变量,`subscribeSystemThemePreferenceEffect` 在绘制后监听操作系统主题。把组合后的 effect 放进传给 `PreferencesProvider` 的稳定 `effects` 数组中。
|
||||
|
||||
## 注入主题变量 {#theme-style}
|
||||
|
||||
使用 `buildThemeStyleSheet` 生成浅色、深色以及跟随系统时使用的 CSS 变量。保留固定的元素 ID 后,外观 effect 可以在颜色偏好变化时更新同一个节点。
|
||||
|
||||
```tsx
|
||||
import {
|
||||
buildThemeStyleSheet,
|
||||
THEME_STYLE_ELEMENT_ID,
|
||||
} from "@workspace/appearance"
|
||||
|
||||
;<style
|
||||
id={THEME_STYLE_ELEMENT_ID}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: buildThemeStyleSheet(themeLight, themeDark),
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## 持久化更新 {#persistence}
|
||||
|
||||
共享的 `onPreferenceChange` 只在值实际变化时收到类型安全的 `{ key, value }`。应用可以把它交给服务端函数或 Cookie 写入器。
|
||||
|
||||
```tsx
|
||||
<PreferencesProvider
|
||||
effects={preferenceEffects}
|
||||
initialPreferences={preferences}
|
||||
onPreferenceChange={(update) => savePreference(update)}
|
||||
>
|
||||
{children}
|
||||
</PreferencesProvider>
|
||||
```
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: 概览
|
||||
description: 了解 Appearance 包的原子组件、主题数据和偏好边界。
|
||||
order: 1
|
||||
toc:
|
||||
- id: package-role
|
||||
title: 包的职责
|
||||
- id: atomic-components
|
||||
title: 原子组件
|
||||
- id: preferences
|
||||
title: 偏好集成
|
||||
---
|
||||
|
||||
## 包的职责 {#package-role}
|
||||
|
||||
`@workspace/appearance` 提供主题模式、基础色、强调色和紧凑布局所需的定义、副作用、主题数据与界面组件。它不创建自己的 Provider 或 store,而是由应用通过 `@workspace/preferences` 与其他偏好 package 统一聚合。
|
||||
|
||||
## 原子组件 {#atomic-components}
|
||||
|
||||
受控组件可以独立组合,不依赖偏好上下文:
|
||||
|
||||
- `ThemeModeField` 选择浅色、深色或跟随系统。
|
||||
- `CompactLayoutField` 切换主内容宽度。
|
||||
- `ThemeColorPicker` 与 `ThemeColorSwatchButton` 选择主题颜色。
|
||||
- `ThemePreview` 预览一组主题变量。
|
||||
- `ThemeConfigCard` 组合预览、基础色与强调色设置。
|
||||
- `ThemeToggle` 在浅色和深色主题之间切换。
|
||||
|
||||
`AppearanceSettings`、`AppearanceDialog` 与 `AppearanceController` 是建立在这些原子组件之上的可选组合层。
|
||||
|
||||
## 偏好集成 {#preferences}
|
||||
|
||||
```tsx
|
||||
import {
|
||||
createDefaultPreferences,
|
||||
PreferencesProvider,
|
||||
} from "@workspace/preferences"
|
||||
import {
|
||||
AppearanceController,
|
||||
appearancePreferenceDefinitions,
|
||||
appearancePreferenceEffect,
|
||||
} from "@workspace/appearance"
|
||||
|
||||
const preferenceDefinitions = {
|
||||
...appearancePreferenceDefinitions,
|
||||
}
|
||||
const initialPreferences = createDefaultPreferences(preferenceDefinitions)
|
||||
const preferenceEffects = [appearancePreferenceEffect] as const
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<PreferencesProvider
|
||||
effects={preferenceEffects}
|
||||
initialPreferences={initialPreferences}
|
||||
>
|
||||
<AppearanceController />
|
||||
</PreferencesProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
把语言、快捷键等 package 的 definitions 和 effects 添加到相同对象即可。应用可以通过共享的 `onPreferenceChange` 持久化所有 `{ key, value }` 更新,并在服务端使用聚合后的 definitions 解析 Cookie。
|
||||
Reference in New Issue
Block a user