Files
simple-react-app-kit/packages/appearance/docs/en-US/advanced/atomic-composition.mdx
T
2026-09-21 17:09:54 +08:00

59 lines
1.9 KiB
Plaintext

---
title: Atomic composition
description: Build a custom appearance surface from controlled components without the preset dialog.
order: 1
toc:
- id: controlled-atoms
title: Controlled atoms
- id: compose-card
title: Compose a theme card
- id: connected-layer
title: State bindings
- id: live-preview
title: Live preview
---
## Controlled atoms {#controlled-atoms}
`ThemeModeField`, `CompactLayoutField`, `ThemeColorPicker`, and `ThemeToggle` are driven by values and callbacks. They do not require preference context, so they can work with forms, preview tools, or another state library.
```tsx
<ThemeModeField value={mode} onValueChange={setMode} />
<CompactLayoutField checked={compacted} onCheckedChange={setCompacted} />
```
## Compose a theme card {#compose-card}
`ThemeConfigCard` combines a preview with base and accent color controls while keeping the configuration owned by the caller.
```tsx
<ThemeConfigCard
active={resolvedTheme === "light"}
compacted={compacted}
config={lightTheme}
onConfigChange={setLightTheme}
scheme="light"
/>
```
For a more granular layout, compose `ThemePreview`, `baseColorSwatches`, `accentColorSwatches`, and `ThemeColorSwatchButton` directly.
## State bindings {#connected-layer}
`AppearanceSettings` is the default binding layer between the atoms and the shared `PreferencesProvider`. A custom surface can call `usePreference` from `@workspace/preferences` for individual values without reusing the default layout.
## Live preview {#live-preview}
The documentation Sandbox can load a typed, multi-file example without embedding implementation details in MDX:
<Sandbox example="appearance/theme-colors" title="Theme color controls" />
For a single file, import the component and its raw source directly instead of creating a manifest:
```mdx
import Demo from "./Demo"
import source from "./Demo.tsx?raw"
<SingleFileSandbox component={Demo} filename="Demo.tsx" source={source} />
```