import { type ReactNode } from "react"; import { useColorScheme } from "react-native"; import { type BreakpointKey, type ColorScheme, type ColorTokens, type GlassTokens, type Palette } from "./tokens.js"; import { type ThemeFonts } from "./fonts.js"; export type Surface = "solid" | "glass"; /** * Brand token overrides for the ThemeProvider `tokens` prop. Two shapes: * * - A flat `Partial` applies the same overrides to BOTH schemes * (the common rebrand: `tokens={{ primary: "#7c3aed" }}`). * - A `{ light, dark }` object overrides each scheme separately, for brands * whose colors shift between appearances. * - An explicit `primary-text` overrides brand text independently. A primary-only * override keeps its existing text color; custom brands own their contrast. * - `destructive-text` behaves the same way for error/action text; a destructive-only * override retains its existing text color without changing the fill contract. * * The two shapes are unambiguous because `ColorTokens` has no `light`/`dark` key. */ export type ThemeTokenOverrides = Partial | { light?: Partial; dark?: Partial; }; export interface ThemeValue { scheme: ColorScheme; /** * The accent palette in force: `"violet"` (the default), `"cyan"`, `"mint"`, `"rose"` or * `"amber"`. It applies in both schemes. */ palette: Palette; surface: Surface; tokens: ColorTokens; /** * The glass material's own tokens for the active scheme (the `glass-tint` fill * GlassSurface paints under the material). Always present, because it describes what * glass LOOKS like in this scheme; whether glass actually paints is `surface` plus the * two accessibility flags below, and GlassSurface owns that ladder. Nothing else may * read this: hand-painting the tint outside GlassSurface would bypass the ladder and * the material (see CLAUDE.md, "no component hand-paints glass"). */ glass: GlassTokens; /** * The typefaces the app registered: this provider's `fonts` prop, else the nearest * parent ThemeProvider's, else `{}`. The themed Text/TextInput primitives read this * to put the brand face on every kit label; nothing else needs to. */ fonts: ThemeFonts; dark: boolean; /** OS "Reduce Transparency" is on: GlassSurface renders opaque (Apple AX). */ reducedTransparency: boolean; /** OS "Increase Contrast" is on: GlassSurface renders opaque + a contrasting border (Apple AX). */ increasedContrast: boolean; } export interface ThemeProviderProps { /** Force the dark color scheme. */ dark?: boolean; /** Force the light color scheme. */ light?: boolean; /** * Legacy value form of the scheme axis ("light" | "dark"), kept for * back-compat and for config-driven code that already holds a `ColorScheme` * value (a stored preference, an hook). The boolean axis above wins * when both are passed. */ scheme?: ColorScheme; /** * The scheme the SERVER rendered, for SSR/SSG apps (Next.js and the like) * whose client scheme can differ from it (a stored preference, the OS). * Canvas resolves colors in JS and serializes them into the server HTML as * literal inline styles, so when the hydration render disagrees with that * HTML, React logs a mismatch and keeps the server's colors on any element * that never re-renders again: components stay stuck in the server's scheme. * With `ssrScheme` set, the provider renders it on the server AND for the * hydration render (matching the server HTML exactly), then applies the * requested scheme (the boolean axis or the legacy `scheme` prop) right * after mount; that switch re-renders every consumer, which writes the * real colors to the DOM. Pass the same value the server resolves (e.g. the * next-themes `defaultTheme`). Omit in client-only apps and on native. */ ssrScheme?: ColorScheme; /** Paint the accent violet (hue 285), the default. */ violet?: boolean; /** Paint the accent cyan (hue 205). */ cyan?: boolean; /** Paint the accent mint (hue 165). */ mint?: boolean; /** Paint the accent rose (hue 20). */ rose?: boolean; /** Paint the accent amber (hue 75). */ amber?: boolean; /** * The palette the SERVER rendered, for SSR/SSG apps whose client palette can differ * from it (a stored preference: `getPalette()` reads one on the web). The `ssrScheme` * contract applied to the palette axis: the server render and the hydration render * paint this palette, matching the server HTML exactly, and the requested one (`cyan`, * `mint` and so on) applies right after mount. Omit in client-only apps and on native. */ ssrPalette?: Palette; /** * The breakpoint bucket the SERVER should assume, for SSR/SSG apps (the * `ssrScheme` contract applied to the viewport axis). The server cannot * measure a window, so `useBreakpoint`/`useResponsive`/`useFormFactor` * resolve to the desktop `base` there by default; an app that knows it is * serving a narrow client (UA hints) passes the bucket the server should * render instead (e.g. "sm" for phones). The server render and the * hydration render use it, then the real measured bucket re-renders every * consumer right after hydration. Omit in client-only apps and on native. */ ssrBreakpoint?: BreakpointKey | "base"; /** Request role-appropriate glass: stable content material and functional * Liquid Glass where supported. Semantic tokens remain opaque. */ glass?: boolean; /** Request complete opaque surfaces without glass effects, even on iOS 26+. */ solid?: boolean; /** * Legacy value form of the surface axis ("solid" | "glass"), kept for * back-compat and for config-driven code that already holds a `Surface` * value. The boolean axis above wins when both are passed. */ surface?: Surface; /** * Brand token overrides, merged over the active palette's base tokens so a * consumer can rebrand the kit (e.g. `tokens={{ primary: "#7c3aed" }}`) * without forking the token files. Pass a flat `Partial` to * apply the same overrides to both schemes, or `{ light, dark }` to override * each scheme separately. These are the SEMANTIC tokens only; the glass material * carries its own fill (`glassByScheme`) and is never rewritten by a rebrand, so * the two are independent. Pass a stable reference (a module constant or a memoized * object); an inline literal re-creates the theme value on every render. * * Unlike `fonts`, a nested ThemeProvider does not inherit a parent's `tokens`: a * nested provider is how a subtree shows its own palette or brand, so it paints its * palette unbranded unless it is given overrides of its own. Pass the same constant * again to carry a rebrand into a nested provider. */ tokens?: ThemeTokenOverrides; /** * The typefaces the app registered, so the kit can paint its labels in the brand * faces (`typeface.sans` is Instrument Sans, `typeface.display` Bricolage Grotesque, * `typeface.mono` JetBrains Mono). Each entry is either one family name that carries * every weight (a variable font, an OS-installed family) or a map from weight to the * face registered for that weight (expo-google-fonts style: `{ "400": * "InstrumentSans_400Regular", "500": "InstrumentSans_500Medium" }`). * * Pass it once, on the app's root provider: the faces are what the app loaded, not * a per-subtree choice, so a nested ThemeProvider that omits `fonts` keeps the * nearest parent provider's, and one that passes it uses its own map in place of * the parent's (the roles are not merged; a stable empty map, `{}`, returns that * subtree to the system face). Omit it on the root and the kit renders in the * platform's system face, as it always has. Pass a stable reference (a module * constant); an inline literal re-creates the theme value on every render. */ fonts?: ThemeFonts; children: ReactNode; } export declare function requestedPaletteOf(p: Pick): Palette; export declare function requestedSchemeOf(p: Pick, system: ReturnType): ColorScheme; export declare function requestedSurfaceOf(p: Pick, platformDefault: () => Surface): Surface; /** * Resolves the theme for everything below it: the scheme (`dark`, `light`, or the OS * appearance), the palette (violet, or `cyan`, `mint`, `rose`, `amber`), the surface (`glass`, `solid`, or the * platform default), token overrides and the app's registered fonts. Read it with * useTheme. */ export declare function ThemeProvider({ dark, light, scheme, ssrScheme, violet, cyan, mint, rose, amber, ssrPalette, ssrBreakpoint, glass, solid, surface, tokens, fonts, children }: ThemeProviderProps): import("react").JSX.Element; /** * The theme from the nearest ThemeProvider: the resolved scheme, palette, surface, color * tokens, glass tints, registered fonts and accessibility flags. The default light, solid * theme when no provider is mounted. */ export declare function useTheme(): ThemeValue; //# sourceMappingURL=theme.d.ts.map