/** * `` and `useTheme()` — the design-system-neutral theme engine. * * Themes are palettes of CSS custom properties (`--color-*` / `--radius-*` / * `--size-*` / `--text-*`) declared **inline** on the provider's host view. * Custom properties inherit to descendants by default in Lynx, and * `@sigx/lynx-plugin` encodes `enableCSSInlineVariables` into the template's * page config so the native engine (Lynx ≥ 3.6) registers inline declarations * from the very first paint (#116) — design-system components read the vars * directly via `var(--color-*)`. * * Theme *data* comes from the design-system package: it seeds the registry at * module load (`registerTheme()` in `./registry.ts`). Custom themes — * including tenant themes fetched at runtime — register the same way and * paint their exact palette on frame one; `followSystem` and `toggle()` treat * them like any built-in. * * Usage (here with `@sigx/lynx-daisyui`'s themes): * * ```tsx * import { ThemeProvider, useTheme } from '@sigx/lynx-daisyui'; * * // System-aware (default): picks the first registered light/dark theme from * // the OS scheme, live-flips when the user toggles dark mode. * defineApp(() => () => ( * * * * )); * * // Pin a specific theme — ignores system appearance. * * * // Custom light/dark pair under followSystem. * * ``` */ import { type Define } from '@sigx/lynx'; import { type IconColorResolver } from '@sigx/lynx-icons/context'; import type { ColorToken } from '../contract.js'; /** * Declaration-merge a typed `variant` prop onto `` (and the pinned * adapters). `@sigx/lynx-icons` has no notion of variants; the foundation owns * the concept so every design system inherits it. The merge fires the moment * any consumer imports anything from `@sigx/lynx-zero` (or a DS that re-exports * it). `` provides the resolver that turns the variant into the * active theme's hex (below). */ declare module '@sigx/lynx-icons' { interface IconPropsExtensions { /** Semantic color token applied as the icon's `fill`, resolved to the * active theme's hex via `useIconColorResolver`. */ variant?: ColorToken; } } /** * Theme class applied to the provider's host view. Plain string — a design * system layers a literal union on top for autocomplete (e.g. daisyui's * `DaisyTheme`). Multi-class compositions like `'daisy-light daisy-rounded'` * are accepted. */ export type ThemeName = string & {}; export interface ThemeController { /** Current theme class. Reactive — read inside render/effect to track. */ readonly name: ThemeName; /** * Whether the theme is currently being driven by the system color * scheme (true when no `initial` was passed and `set()` hasn't been * called since mount). UI like a settings screen can read this to show * a "Follow system" indicator. */ readonly followingSystem: boolean; /** * Replace the active theme. Pins the choice — subsequent system * appearance changes won't override it (until `followSystem()` is called). */ set(name: ThemeName): void; /** * Flip to the paired theme — light ↔ dark by default; follows the `pair` * declared in `registerTheme()`, or the first theme of the opposite * variant. */ toggle(): void; /** * Resume following system appearance. Equivalent to mounting fresh * with no `initial` prop. Useful for a "Reset to system" button. */ followSystem(): void; /** * Current global text-scale multiplier (`1` = the theme's default ramp). * Reactive — read inside render/effect to track. Orthogonal to the theme: * `set()` / `toggle()` leave it untouched. */ readonly fontScale: number; /** * Set the global text-scale multiplier — the `--text-*` ramp is re-emitted * at `defaultPx × scale`. Persists across theme switches, so it's the place * to wire a user accessibility preference or a backend-driven setting (e.g. * `setFontScale(1.25)`). Inherits into nested `` subtrees. */ setFontScale(scale: number): void; } /** * Access the active theme controller. Resolves to the nearest * ``'s controller (a content sub-scope), or — at the app root * and in *headless* code with no provider mounted — the global controller * (`themeController`). Never throws: theme control is reachable from anywhere. * For control that must always target the app/OS theme regardless of scope * (e.g. a status-bar sync), import `themeController`. */ export declare const useTheme: import("@sigx/runtime-core").InjectableFunction; export type ThemeProviderProps = /** * Pin the initial theme. When set, the provider ignores system * appearance until `controller.followSystem()` is called. When * omitted, the provider follows the OS color scheme and live-flips * with it. */ Define.Prop<'initial', ThemeName, false> /** * Theme to use when the system color scheme is `'light'`. Defaults to * the first registered light theme. Only consulted while * `followingSystem` is true. */ & Define.Prop<'light', ThemeName, false> /** * Theme to use when the system color scheme is `'dark'`. Defaults to * the first registered dark theme. Only consulted while * `followingSystem` is true. */ & Define.Prop<'dark', ThemeName, false> /** * Initial global text-scale multiplier (`1` = default ramp). Seeds the * controller's `fontScale`; change it later via `controller.setFontScale()`. * On the root provider an explicit value wins over any scale a headless * caller set before mount. */ & Define.Prop<'fontScale', number, false> /** Extra classes appended to the theme class on the host view. */ & Define.Prop<'class', string, false> /** Extra inline style on the host view. Merged after the base flex-fill defaults. */ & Define.Prop<'style', Record, false> /** * Override the icon-color resolver this scope provides. By default the * provider resolves an `` to the active theme's palette hex * — design-system-agnostic, works for any registered theme. Supply this to * customize the mapping (e.g. a DS-specific token aliasing). */ & Define.Prop<'iconColorResolver', IconColorResolver, false> & Define.Slot<'default'>; /** * Wraps children in a `` whose inline style declares the * theme's full custom-property set, so the variables inherit down to every * descendant from first paint. The theme name rides along as a class for * shape/behavior modifiers (e.g. `daisy-rounded`). * * Layout: the root provider defaults to flex-fill long-form so the wrapper * doesn't collapse between ancestors that flex (e.g. ``) * and descendants that need a sized parent (``). A nested * provider is a content island and sizes to its content instead — flex-fill's * `flexBasis: 0` computes to height 0 inside scroll-view content, where * nothing grows it back (#269). Consumers override via `style`. * * Theme name is held in an *object* signal (not a primitive) so literal-union * types a DS layers on survive — `signal` widens primitive literals to * plain `string` via `Widen`. */ export declare const ThemeProvider: import("@sigx/runtime-core").ComponentFactory import("@sigx/runtime-core").JSXElement | import("@sigx/runtime-core").JSXElement[] | null) | undefined; }>; export { listThemes, registerTheme, extendTheme, pickThemeFor, pairOf, variantOf, colorsOf, radiusOf, sizesOf, } from './registry.js'; export type { Theme, ThemePalette, ThemeRadius, ThemeSizes, ThemeVariant, } from './registry.js'; //# sourceMappingURL=ThemeProvider.d.ts.map