KQ-1661 · THEME/FITTING
Theme Fitting
An Appearance panel beside a miniature of the app it dresses. Choosing a theme sweeps it across the miniature as a circle growing from the chosen swatch — a clip-path on a tween of revealSpeed, stacked over the old theme and dropped once it covers — while density reflows the miniature's rows and tiles on springs.glide and an accent recolours its accent parts on a short colour tween; Revert sweeps everything back from the Revert button, and Auto follows the system setting. Theme, Density and Accent are radiogroups whose arrows move and select, the chosen ring and thumb slide on springs.snap, and a failed save keeps the choice on and says so.
Appearance
How Coldbrook looks on this device
Theme
Density
Accent
light · default · cobalt · trying on
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/theme-fitting
Props
- themes
- ThemeFittingTheme[]
- default defaultThemeFittingThemes
- The app's themes, { id, name, palette: { canvas, panel, raised, ink, muted, line } }. Palettes are the app's own fixed colours, so the preview is true on a light or a dark page.
- densities
- ThemeFittingDensity[]
- default defaultThemeFittingDensities
- Row spacing choices, { id, name, row, pad } in em of the miniature.
- accents
- ThemeFittingAccent[]
- default defaultThemeFittingAccents
- Accent choices, { id, name, color }.
- value / defaultValue
- { theme: string; density: string; accent: string }
- default — / defaultThemeFittingValue
- The appearance being tried on, controlled or initial; theme may be "auto".
- onValueChange
- (value: ThemeFittingValue) => void
- default —
- Fires with the whole appearance from the choice, key or Revert that changed it.
- savedValue
- ThemeFittingValue
- default the last successful save
- What is saved and what Revert returns to; omit it and the panel tracks its own saves.
- onThemeChange
- (themeId: string) => void
- default —
- The theme changed.
- onDensityChange
- (densityId: string) => void
- default —
- The density changed.
- onAccentChange
- (accentId: string) => void
- default —
- The accent changed.
- onSave
- (value: ThemeFittingValue) => void | Promise<unknown>
- default —
- Save was pressed. Return a promise to show it saving; a rejection keeps the choice on and says so.
- onRevert
- (value: ThemeFittingValue) => void
- default —
- Revert was pressed, with the saved appearance it returns to.
- allowAuto
- boolean
- default true
- Offer Auto, which follows the system's light or dark setting and sweeps from its own swatch when the system flips.
- appName
- string
- default "Coldbrook"
- The app in the miniature and the copy.
- previewScale
- number
- default 1
- The miniature's zoom, 0.8 to 1.2: larger shows less of the app, bigger.
- swatchShape
- "circle" | "square" | "chip"
- default "circle"
- Theme and accent swatches as circles, rounded squares, or labelled chips.
- revealSpeed
- number
- default 640
- How long the circular sweep takes, ms.
- maxHeight
- number
- default 552
- Tallest the surface grows before its body scrolls inside, px.
- disabled
- boolean
- default false
- Nothing can be chosen, reverted or saved; the surface dims.
- className
- string
- default —
- Classes for the outer surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| themes | ThemeFittingTheme[] | defaultThemeFittingThemes | The app's themes, { id, name, palette: { canvas, panel, raised, ink, muted, line } }. Palettes are the app's own fixed colours, so the preview is true on a light or a dark page. |
| densities | ThemeFittingDensity[] | defaultThemeFittingDensities | Row spacing choices, { id, name, row, pad } in em of the miniature. |
| accents | ThemeFittingAccent[] | defaultThemeFittingAccents | Accent choices, { id, name, color }. |
| value / defaultValue | { theme: string; density: string; accent: string } | — / defaultThemeFittingValue | The appearance being tried on, controlled or initial; theme may be "auto". |
| onValueChange | (value: ThemeFittingValue) => void | — | Fires with the whole appearance from the choice, key or Revert that changed it. |
| savedValue | ThemeFittingValue | the last successful save | What is saved and what Revert returns to; omit it and the panel tracks its own saves. |
| onThemeChange | (themeId: string) => void | — | The theme changed. |
| onDensityChange | (densityId: string) => void | — | The density changed. |
| onAccentChange | (accentId: string) => void | — | The accent changed. |
| onSave | (value: ThemeFittingValue) => void | Promise<unknown> | — | Save was pressed. Return a promise to show it saving; a rejection keeps the choice on and says so. |
| onRevert | (value: ThemeFittingValue) => void | — | Revert was pressed, with the saved appearance it returns to. |
| allowAuto | boolean | true | Offer Auto, which follows the system's light or dark setting and sweeps from its own swatch when the system flips. |
| appName | string | "Coldbrook" | The app in the miniature and the copy. |
| previewScale | number | 1 | The miniature's zoom, 0.8 to 1.2: larger shows less of the app, bigger. |
| swatchShape | "circle" | "square" | "chip" | "circle" | Theme and accent swatches as circles, rounded squares, or labelled chips. |
| revealSpeed | number | 640 | How long the circular sweep takes, ms. |
| maxHeight | number | 552 | Tallest the surface grows before its body scrolls inside, px. |
| disabled | boolean | false | Nothing can be chosen, reverted or saved; the surface dims. |
| className | string | — | Classes for the outer surface. |