Files
simple-react-app-kit/packages/appearance/docs/en-US/guide/setup.mdx
T
2026-09-29 20:58:46 +08:00

105 lines
3.3 KiB
Plaintext

---
title: Set up appearance preferences
description: Aggregate appearance definitions and effects with the application's shared preferences.
order: 1
toc:
- id: provider
title: Aggregate preferences
- id: effects
title: Register effects
- id: theme-style
title: Inject theme variables
- id: persistence
title: Persist updates
---
## Aggregate preferences {#provider}
Build one complete preference definition map at the application boundary. Spread definitions from appearance, locale, keyboard, and other feature packages into this map, then create or load the initial values.
Import Appearance after UI in the application stylesheet. No UI component changes are required:
```css
@import "@workspace/ui/globals.css";
@import "@workspace/appearance/globals.css";
```
```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` remains available when only the appearance slice is needed, but the definition map is the preferred source when several packages are combined.
## Register effects {#effects}
`appearancePreferenceEffect` updates document classes, root attributes, and theme variables before paint, then watches operating-system theme and motion preferences after paint. Register it in the stable `effects` array passed to `PreferencesProvider`.
## Inject theme variables {#theme-style}
Use `buildThemeStyleSheet` to generate light and dark CSS variables from one base color, one accent color, and a color-vision mode. Keep the stable element ID so the appearance effect can update the same node when preferences change.
```tsx
import {
buildThemeStyleSheet,
THEME_STYLE_ELEMENT_ID,
} from "@workspace/appearance"
;<style
id={THEME_STYLE_ELEMENT_ID}
dangerouslySetInnerHTML={{
__html: buildThemeStyleSheet(
{ baseColor, accentColor },
colorVisionMode,
brightness
),
}}
/>
```
Assistance modes adjust chart and destructive semantic colors and set `data-ui-color-vision`. They are not color-vision simulators and do not transform photos, video, or brand assets.
Text scaling changes the root font size through `data-ui-text-scale`; reduced motion shortens global animation through `data-ui-motion` while preserving low-motion loading feedback; brightness adjusts theme surface variables without using `filter: brightness()`.
## Persist updates {#persistence}
The shared `onPreferenceChange` receives a typed `{ key, value }` only when a value actually changes. Forward it to a server function or cookie writer owned by the application.
```tsx
<PreferencesProvider
effects={preferenceEffects}
initialPreferences={preferences}
onPreferenceChange={(update) => savePreference(update)}
>
{children}
</PreferencesProvider>
```