/** * Theme registry — the single source of truth for registered themes. * * A theme is *data*: a name, a light/dark variant, and a full color palette * (plus an optional toggle `pair` and roundness overrides). Both rendering and * any DS-specific consumers (e.g. icon tinting) read from here — * `` applies a theme's `colors` as inline CSS custom properties * on its host view (Lynx inherits custom properties to descendants, so * component classes resolve `var(--color-*)`). There is no per-theme CSS or * parallel JS palette to keep in sync. * * The registry starts **empty** — design-system packages seed it at module * load (e.g. `@sigx/lynx-daisyui` registers its six built-ins on import). * Register more — including tenant themes fetched at runtime — with * `registerTheme()`, or `extendTheme()` to derive one from a base. Order * matters for `pickThemeFor()`: the first theme of a given variant is the * follow-system default for that variant. * * Structural tokens (radius, sizing, component dimensions) are theme-agnostic * and ship once in the bundled `.lynx-zero` base class (`styles/tokens.css`); * a theme may override roundness via `radius` and base size units via `sizes`. * * Colors are engine-safe strings — hex or `rgb()`. Lynx's CSS engine does not * parse `oklch()`, so convert before registering. */ import { type ColorToken, type CoreColorToken, type SoftColorToken } from '../contract.js'; export type ThemeVariant = 'light' | 'dark'; /** * Full *registered* color palette — every semantic token including the * `*-soft` tints, no holes. This is what `colorsOf()` returns. */ export type ThemePalette = Record; /** * What a theme *author* writes: every core token, with the `*-soft` tints * optional — any omitted soft is computed at registration (`softMix` of the * variant color into `base-100`). */ export type ThemePaletteInput = Record & Partial>; /** * Roundness token overrides. Emitted as `--radius-selector` / * `--radius-field` / `--radius-box`. Defaults live in the bundled * `.lynx-zero` base. */ export interface ThemeRadius { /** Small selectable controls — checkbox, toggle, badge. */ selector?: string; /** Fields — button, input, select, textarea. */ field?: string; /** Boxes — card, modal, alert. */ box?: string; } /** * Base size-unit overrides. Emitted as `--size-selector` / `--size-field`; * component dimensions are integer multiples of these. Defaults live in the * bundled `.lynx-zero` base. */ export interface ThemeSizes { /** Base unit for selector controls (checkbox, toggle, badge). */ selector?: string; /** Base unit for fields (button, input, select). */ field?: string; } export interface ThemeInput { /** Unique id — also the value of `theme.name`. */ name: string; /** Light or dark — drives follow-system selection and status-bar tint. */ variant: ThemeVariant; /** Color palette — core tokens required, `*-soft` tints optional. */ colors: ThemePaletteInput; /** * Which theme `toggle()` flips to. Defaults to the first registered theme of * the opposite variant. */ pair?: string; /** Optional roundness overrides; unspecified tokens fall back to the base. */ radius?: ThemeRadius; /** Optional base size-unit overrides; unspecified tokens fall back to the base. */ sizes?: ThemeSizes; /** * How strong the computed `*-soft` tints are: the ratio of the variant * color mixed into `base-100` for any soft token the palette doesn't set * explicitly. Design-system flavor, carried as theme data — daisy's * built-ins use `0.08` (daisyUI v5's ~8% tints), hero's use `0.2` * (HeroUI's `color/20`). Default `0.16`. */ softMix?: number; } /** A registered theme — same shape as the input, with the palette completed. */ export interface Theme extends Omit { colors: ThemePalette; } /** * Complete a theme's palette: any `*-soft` token the author didn't set is * computed as `softMix` of the variant color mixed into `base-100` (in JS — * Lynx CSS can't alpha-compose `var()` colors, so the tints are materialized * in the palette). Idempotent; explicitly provided softs are kept verbatim. * * DS packages run their builtin arrays through this before exporting them so * any consumer of the exported arrays sees the same palette the registry * serves. */ export declare function completeTheme(input: ThemeInput): Theme; /** * All registered themes in insertion order. Returns a shallow copy so callers * can't mutate the internal registry — re-registration goes through * `registerTheme()`. Each entry is a full `Theme` (name, variant, palette), * so consumers can render swatches in a picker. */ export declare function listThemes(): readonly Theme[]; /** * Register (or replace, by `name`) a theme. Call at module-load time before * mounting `` so it shows up in `listThemes()` / `pickThemeFor()`. * The palette is completed on the way in (`completeTheme`): any `*-soft` * token the author didn't set is computed from `softMix`. */ export declare function registerTheme(theme: ThemeInput): void; /** * Derive a new theme from a registered base, overriding any colors / roundness. * Ergonomic for "tenant tweaks a few tokens": the result is a full `Theme` you * pass to `registerTheme()`. Throws if `base` isn't registered. * * ```ts * registerTheme(extendTheme('daisy-dark', { * name: 'acme-dark', * colors: { primary: '#fb7185' }, * })); * ``` */ export declare function extendTheme(base: string, patch: { name: string; variant?: ThemeVariant; pair?: string; colors?: Partial; radius?: ThemeRadius; sizes?: ThemeSizes; softMix?: number; }): Theme; /** The variant of a registered theme, or `undefined` if not registered. */ export declare function variantOf(name: string | undefined): ThemeVariant | undefined; /** The color palette of a registered theme, or `undefined` if not registered. */ export declare function colorsOf(name: string | undefined): ThemePalette | undefined; /** The roundness overrides of a registered theme, if any. */ export declare function radiusOf(name: string | undefined): ThemeRadius | undefined; /** The base size-unit overrides of a registered theme, if any. */ export declare function sizesOf(name: string | undefined): ThemeSizes | undefined; /** * The first registered palette — the engine's last-resort fallback when an * active theme name isn't registered. `undefined` only when no design system * has seeded the registry yet. * @internal */ export declare function fallbackPalette(): ThemePalette | undefined; /** * Pick a default theme for a given system color scheme — the first registered * theme of that variant. Falls back to the first registered theme of any * variant, or `''` while the registry is empty (a design-system package seeds * it at module load, so this is only reachable before any DS import). */ export declare function pickThemeFor(scheme: ThemeVariant): string; /** * Resolve the paired theme of a given name — used by `theme.toggle()`. Follows * `pair` if set, otherwise the first theme of the opposite variant. Returns the * input unchanged when the theme isn't registered. */ export declare function pairOf(name: string): string; //# sourceMappingURL=registry.d.ts.map