feat(branding): per-brand default theme + palette via brand.json
Lets a deployer set the in-app color scheme a fresh visitor sees (e.g. cfaun → darkmatter light) without forking. Two optional brand.json fields, `theme` (light|dark|system) and `palette` (one of PALETTES), distinct from `themeColor` which is PWA chrome only. - vite-branding.ts surfaces them as VITE_BRAND_THEME / VITE_BRAND_PALETTE at module load, so the default applies app-wide (hub + all standalones) with no per-config wiring. - theme-provider reads them as the INITIAL value of theme/palette; a user's stored choice in localStorage still wins and persists. - Splits the catppuccin = bare `:root` invariant (now BASE_PALETTE, used by applyPalette to drop data-theme) from the configurable default. Without this, a non-catppuccin brand default would strip the data-theme attribute and silently render catppuccin instead. Unset → the app's built-ins (dark + catppuccin), unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8f2c401e00
commit
d4d088fb50
4 changed files with 53 additions and 4 deletions
|
|
@ -28,12 +28,35 @@ export interface Brand {
|
|||
* config keeps its hardcoded value.
|
||||
*/
|
||||
backgroundColor?: string
|
||||
/**
|
||||
* Optional default in-app theme mode (light / dark / system). Sets the
|
||||
* INITIAL value the theme-provider uses when the user has no saved
|
||||
* preference; a user's later choice still wins and persists. Unset →
|
||||
* the app's built-in default ('dark'). Distinct from `themeColor`,
|
||||
* which is PWA chrome only.
|
||||
*/
|
||||
theme?: 'light' | 'dark' | 'system'
|
||||
/**
|
||||
* Optional default in-app color palette (e.g. 'darkmatter'). Same
|
||||
* initial-default semantics as `theme`. Must be one of the palettes in
|
||||
* src/components/theme-provider (PALETTES). Unset → 'catppuccin'.
|
||||
*/
|
||||
palette?: string
|
||||
}
|
||||
|
||||
export const brand: Brand = JSON.parse(
|
||||
readFileSync(resolve(BRAND_DIR, 'brand.json'), 'utf-8'),
|
||||
)
|
||||
|
||||
// Surface the brand's in-app theme defaults to the client as VITE_*
|
||||
// env vars (read by the theme-provider). Set here at module load — every
|
||||
// vite.<app>.config.ts imports this file — so the default applies
|
||||
// app-wide (hub + all standalones) without per-config wiring. Always
|
||||
// assigned (empty when unset) so a prior brand's value can't leak into a
|
||||
// later build in the same process.
|
||||
process.env.VITE_BRAND_THEME = brand.theme ?? ''
|
||||
process.env.VITE_BRAND_PALETTE = brand.palette ?? ''
|
||||
|
||||
/**
|
||||
* Spread into a vite config's `resolve.alias` map. Lets components
|
||||
* import deployer-provided assets via `@brand/<file>` instead of
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue