@charstudios/pallet 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,400 @@
1
+ import * as React from 'react';
2
+
3
+ /**
4
+ * The full theming contract for a Pallet theme. Every field is optional in the
5
+ * partial variants used by presets and overrides; the resolved theme (produced
6
+ * by {@link resolveTheme}) always has concrete values.
7
+ */
8
+ /** Any CSS color string. OKLCH is recommended to match shadcn's token system. */
9
+ type CssColor = string;
10
+ /** The set of color roles shadcn/ui expects, per color scheme. */
11
+ interface ColorTokens {
12
+ background: CssColor;
13
+ foreground: CssColor;
14
+ card: CssColor;
15
+ cardForeground: CssColor;
16
+ popover: CssColor;
17
+ popoverForeground: CssColor;
18
+ primary: CssColor;
19
+ primaryForeground: CssColor;
20
+ secondary: CssColor;
21
+ secondaryForeground: CssColor;
22
+ muted: CssColor;
23
+ mutedForeground: CssColor;
24
+ accent: CssColor;
25
+ accentForeground: CssColor;
26
+ destructive: CssColor;
27
+ destructiveForeground: CssColor;
28
+ border: CssColor;
29
+ input: CssColor;
30
+ ring: CssColor;
31
+ chart1: CssColor;
32
+ chart2: CssColor;
33
+ chart3: CssColor;
34
+ chart4: CssColor;
35
+ chart5: CssColor;
36
+ sidebar: CssColor;
37
+ sidebarForeground: CssColor;
38
+ sidebarPrimary: CssColor;
39
+ sidebarPrimaryForeground: CssColor;
40
+ sidebarAccent: CssColor;
41
+ sidebarAccentForeground: CssColor;
42
+ sidebarBorder: CssColor;
43
+ sidebarRing: CssColor;
44
+ }
45
+ /** Typography configuration. Font values are CSS `font-family` stacks. */
46
+ interface Typography {
47
+ /** Body font. Maps to `--font-sans`. */
48
+ sans: string;
49
+ /** Display/heading font. Maps to `--font-heading`. */
50
+ heading: string;
51
+ /** Monospace font. Maps to `--font-mono`. */
52
+ mono: string;
53
+ /**
54
+ * Google Font family names to auto-load at runtime (e.g. "Inter", "Outfit").
55
+ * Leave empty when fonts are self-hosted or provided by the host app.
56
+ */
57
+ googleFonts?: string[];
58
+ }
59
+ /**
60
+ * Roundness. `base` is the anchor radius (maps to `--radius`); the derived
61
+ * `--radius-sm..4xl` scale is computed from it, mirroring shadcn conventions.
62
+ */
63
+ interface RadiusConfig {
64
+ /** Anchor radius, e.g. "0.45rem" or "1.25rem". Maps to `--radius`. */
65
+ base: string;
66
+ /** Multipliers used to derive the radius scale from `base`. */
67
+ scale?: Partial<RadiusScale>;
68
+ }
69
+ interface RadiusScale {
70
+ sm: number;
71
+ md: number;
72
+ lg: number;
73
+ xl: number;
74
+ "2xl": number;
75
+ "3xl": number;
76
+ "4xl": number;
77
+ }
78
+ /**
79
+ * Elevation controls the "skin" feel: shadows, border/ring strength and the
80
+ * surface treatment used by variant stylesheets.
81
+ */
82
+ interface ElevationConfig {
83
+ /** Named shadow ramp. Each maps to `--shadow-*`. */
84
+ shadows: {
85
+ xs: string;
86
+ sm: string;
87
+ md: string;
88
+ lg: string;
89
+ xl: string;
90
+ };
91
+ /**
92
+ * Strength of hairline borders/rings on surfaces (0-1). Maps to
93
+ * `--surface-border-strength`, consumed by variant CSS.
94
+ */
95
+ borderStrength: number;
96
+ /**
97
+ * Default elevation level applied to elevated surfaces (cards, popovers).
98
+ * Maps to `--elevation` and references one of the shadow ramp keys.
99
+ */
100
+ level: "none" | "xs" | "sm" | "md" | "lg" | "xl";
101
+ }
102
+ /** Spacing density scales the base spacing unit and component paddings. */
103
+ interface Density {
104
+ /** Base spacing unit, e.g. "0.25rem". Maps to `--spacing`. */
105
+ spacing: string;
106
+ /** Multiplier applied to component internal padding. Maps to `--density`. */
107
+ scale: number;
108
+ }
109
+ /** Motion controls animation duration and easing intensity. */
110
+ interface Motion {
111
+ /** Base transition duration in ms. Maps to `--motion-duration`. */
112
+ duration: number;
113
+ /** CSS easing function. Maps to `--motion-ease`. */
114
+ easing: string;
115
+ /** 0 disables motion; 1 is full intensity. Maps to `--motion-intensity`. */
116
+ intensity: number;
117
+ }
118
+ /** Built-in visual variants ("skins"). Custom names are also allowed. */
119
+ type VariantName = "flat" | "launch" | (string & {});
120
+ /** A color scheme. */
121
+ type ColorScheme = "light" | "dark";
122
+ /**
123
+ * A complete theme. Presets are `ThemeConfig`; user overrides are
124
+ * `DeepPartial<ThemeConfig>` merged on top.
125
+ */
126
+ interface ThemeConfig {
127
+ /** Identifier for this theme (used for persistence + tooling). */
128
+ name: string;
129
+ /** Which variant skin to apply. Sets `data-pallet-variant`. */
130
+ variant: VariantName;
131
+ /** Color tokens per scheme. */
132
+ colors: {
133
+ light: ColorTokens;
134
+ dark: ColorTokens;
135
+ };
136
+ typography: Typography;
137
+ radius: RadiusConfig;
138
+ elevation: ElevationConfig;
139
+ density: Density;
140
+ motion: Motion;
141
+ }
142
+ /** Recursive partial used for overrides and preset composition. */
143
+ type DeepPartial<T> = {
144
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
145
+ };
146
+ type ThemeOverride = DeepPartial<ThemeConfig>;
147
+ /** A flat map of CSS custom properties ("--primary" -> value). */
148
+ type CssVarMap = Record<string, string>;
149
+
150
+ /** Preference for the color scheme; "system" follows the OS setting. */
151
+ type SchemePreference = ColorScheme | "system";
152
+ /** The value exposed by {@link ThemeProvider} through {@link useTheme}. */
153
+ interface PalletContextValue {
154
+ /** The fully resolved theme (base preset with overrides applied). */
155
+ theme: ThemeConfig;
156
+ /** The base preset before overrides. */
157
+ basePreset: ThemeConfig;
158
+ /** The current user overrides layered on top of the preset. */
159
+ overrides: ThemeOverride;
160
+ /** The actual color scheme currently rendered. */
161
+ scheme: ColorScheme;
162
+ /** The user's scheme preference (may be "system"). */
163
+ schemePreference: SchemePreference;
164
+ /** Resolved CSS variables for the current scheme. */
165
+ vars: CssVarMap;
166
+ /** Replaces the entire theme with a new preset (by object). Clears overrides. */
167
+ setTheme: (theme: ThemeConfig) => void;
168
+ /** Applies a built-in/custom preset by name or object. Clears overrides. */
169
+ applyPreset: (preset: ThemeConfig | string) => void;
170
+ /** Merges a partial override on top of the current overrides. */
171
+ updateTheme: (override: ThemeOverride) => void;
172
+ /** Clears all overrides, returning to the base preset. */
173
+ resetOverrides: () => void;
174
+ /** Sets the color-scheme preference. */
175
+ setSchemePreference: (preference: SchemePreference) => void;
176
+ }
177
+ declare const PalletContext: React.Context<PalletContextValue | null>;
178
+ /** Reads the Pallet context. Throws if used outside a `ThemeProvider`. */
179
+ declare function usePalletContext(): PalletContextValue;
180
+
181
+ interface ThemeProviderProps {
182
+ children: React.ReactNode;
183
+ /**
184
+ * Preset to start from: a preset name (from built-ins or `presets`), or a
185
+ * full `ThemeConfig` object. Defaults to "flat".
186
+ */
187
+ defaultPreset?: ThemeConfig | string;
188
+ /** Initial overrides layered on top of the preset. */
189
+ defaultOverride?: ThemeOverride;
190
+ /** Initial color-scheme preference. Defaults to "system". */
191
+ defaultScheme?: SchemePreference;
192
+ /**
193
+ * Extra presets available to `applyPreset(name)`, merged with the built-ins.
194
+ */
195
+ presets?: Record<string, ThemeConfig>;
196
+ /**
197
+ * Where CSS variables are written:
198
+ * - "root" (default): on `document.documentElement`, plus the `.dark` class
199
+ * and `data-pallet-variant` attribute. Best for app-wide theming.
200
+ * - "self": on a wrapper `<div>` this provider renders. Best for scoped
201
+ * theming / previews. Emits SSR inline styles to avoid a flash.
202
+ */
203
+ scope?: "root" | "self";
204
+ /**
205
+ * If set, overrides + preset name + scheme are persisted to localStorage
206
+ * under this key and restored on mount.
207
+ */
208
+ storageKey?: string;
209
+ /** Class name applied to the wrapper element when `scope` is "self". */
210
+ className?: string;
211
+ }
212
+ declare function ThemeProvider({ children, defaultPreset, defaultOverride, defaultScheme, presets: extraPresets, scope, storageKey, className, }: ThemeProviderProps): React.JSX.Element;
213
+
214
+ /**
215
+ * Access the full theming context: the resolved theme, current scheme, resolved
216
+ * CSS variables, and all mutation helpers. Must be used within a
217
+ * `<ThemeProvider>`.
218
+ */
219
+ declare function useTheme(): PalletContextValue;
220
+
221
+ /** Which scheme(s) a color update targets. */
222
+ type SchemeTarget = ColorScheme | "both";
223
+ interface ThemeControls {
224
+ /** Set a single color role for one or both schemes. */
225
+ setColor: (role: keyof ColorTokens, value: string, target?: SchemeTarget) => void;
226
+ /** Convenience for the primary color. */
227
+ setPrimary: (value: string, target?: SchemeTarget) => void;
228
+ /** Convenience for the accent color. */
229
+ setAccent: (value: string, target?: SchemeTarget) => void;
230
+ /** Merge multiple color roles at once for a given scheme. */
231
+ setColors: (colors: Partial<ColorTokens>, target?: SchemeTarget) => void;
232
+ /** Set the anchor radius (e.g. "0.5rem", "1.25rem"). */
233
+ setRadius: (base: string) => void;
234
+ /** Override individual radius-scale multipliers. */
235
+ setRadiusScale: (scale: Partial<RadiusScale>) => void;
236
+ /** Set one of the font stacks. */
237
+ setFont: (kind: "sans" | "heading" | "mono", family: string) => void;
238
+ /** Set the Google Font families to auto-load. */
239
+ setGoogleFonts: (families: string[]) => void;
240
+ /** Switch the visual variant/skin (sets `data-pallet-variant`). */
241
+ setVariant: (variant: VariantName) => void;
242
+ /** Set the default elevation level for surfaces. */
243
+ setElevationLevel: (level: ElevationConfig["level"]) => void;
244
+ /** Override a single shadow ramp entry. */
245
+ setShadow: (key: keyof ElevationConfig["shadows"], value: string) => void;
246
+ /** Set hairline border/ring strength (0-1). */
247
+ setBorderStrength: (value: number) => void;
248
+ /** Update spacing density. */
249
+ setDensity: (density: Partial<Density>) => void;
250
+ /** Update motion settings. */
251
+ setMotion: (motion: Partial<Motion>) => void;
252
+ /** Escape hatch: merge an arbitrary override. */
253
+ update: (override: ThemeOverride) => void;
254
+ /** Clear all overrides, returning to the base preset. */
255
+ reset: () => void;
256
+ }
257
+ /**
258
+ * Granular setters for building a theme-editor UI. Every setter layers an
259
+ * override on top of the active preset, so `reset()` always returns to a clean
260
+ * baseline. Colors default to updating both light and dark schemes; pass a
261
+ * target to scope them.
262
+ */
263
+ declare function useThemeControls(): ThemeControls;
264
+
265
+ interface UsePresetResult {
266
+ /** The active base preset. */
267
+ preset: ThemeConfig;
268
+ /** Names of the built-in presets. */
269
+ builtinNames: string[];
270
+ /** Apply a preset by name or object (clears overrides). */
271
+ applyPreset: (preset: ThemeConfig | string) => void;
272
+ }
273
+ /** Read the active preset and switch between presets. */
274
+ declare function usePreset(): UsePresetResult;
275
+
276
+ interface UseColorSchemeResult {
277
+ /** The actual scheme currently rendered. */
278
+ scheme: ColorScheme;
279
+ /** The user's preference (may be "system"). */
280
+ preference: SchemePreference;
281
+ /** Set the preference explicitly. */
282
+ setPreference: (preference: SchemePreference) => void;
283
+ /** Toggle between light and dark (resolves "system" to its current value). */
284
+ toggle: () => void;
285
+ }
286
+ /** Read and control the color scheme (light / dark / system). */
287
+ declare function useColorScheme(): UseColorSchemeResult;
288
+
289
+ /**
290
+ * Runtime Google Fonts loader. Injects a single stylesheet <link> for the given
291
+ * font families. Safe to call repeatedly: each unique family set is only loaded
292
+ * once, and the loader is a no-op on the server.
293
+ */
294
+ interface GoogleFontsOptions {
295
+ /** Weights to request per family. Defaults to a useful range. */
296
+ weights?: number[];
297
+ /** `font-display` strategy. Defaults to "swap". */
298
+ display?: "auto" | "block" | "swap" | "fallback" | "optional";
299
+ }
300
+ /** Builds a Google Fonts CSS2 URL for the given families. */
301
+ declare function buildGoogleFontsUrl(families: string[], options?: GoogleFontsOptions): string;
302
+ /**
303
+ * Ensures the given Google Font families are loaded in the document. Returns the
304
+ * injected/updated <link> element, or null when running on the server or when
305
+ * there is nothing to load.
306
+ */
307
+ declare function loadGoogleFonts(families: string[], options?: GoogleFontsOptions): HTMLLinkElement | null;
308
+
309
+ /** Default radius multipliers, mirroring shadcn's derived `--radius-*` scale. */
310
+ declare const DEFAULT_RADIUS_SCALE: RadiusScale;
311
+ /** Converts a single color scheme's tokens into a CSS variable map. */
312
+ declare function colorTokensToVars(tokens: ColorTokens): CssVarMap;
313
+ /** Builds the scheme-independent CSS variables (radius, fonts, elevation, ...). */
314
+ declare function structuralVars(theme: ThemeConfig): CssVarMap;
315
+ /**
316
+ * Resolves a full theme into the CSS variables for a given color scheme.
317
+ * Combines the scheme's colors with the structural (scheme-independent) tokens.
318
+ */
319
+ declare function resolveTheme(theme: ThemeConfig, scheme: ColorScheme): CssVarMap;
320
+ /** Resolves only the color variables for a scheme (no structural tokens). */
321
+ declare function resolveColors(theme: ThemeConfig, scheme: ColorScheme): CssVarMap;
322
+
323
+ /**
324
+ * Applies a CSS variable map to a DOM element's inline style. Runs only in the
325
+ * browser; on the server it is a no-op (SSR should use {@link themeToCss}).
326
+ */
327
+ declare function applyCssVars(element: HTMLElement | null | undefined, vars: CssVarMap): void;
328
+ /** Removes the given CSS variable names from an element's inline style. */
329
+ declare function clearCssVars(element: HTMLElement | null | undefined, names: string[]): void;
330
+ /** Serializes a CSS variable map into a `key:value;` declaration string. */
331
+ declare function cssVarsToString(vars: CssVarMap): string;
332
+
333
+ /**
334
+ * Deeply merges `override` onto `base`, returning a new object. Arrays and
335
+ * primitives from `override` replace those in `base`; nested plain objects are
336
+ * merged recursively. `undefined` values in the override are ignored.
337
+ */
338
+ declare function deepMerge<T>(base: T, override?: DeepPartial<T>): T;
339
+ /** Merges any number of overrides left-to-right onto a base theme. */
340
+ declare function mergeAll<T>(base: T, ...overrides: Array<DeepPartial<T> | undefined>): T;
341
+
342
+ interface ThemeToCssOptions {
343
+ /**
344
+ * CSS selector the light-scheme variables are attached to. Defaults to
345
+ * `:root`. Use e.g. `[data-pallet-scope]` to scope a theme to a subtree.
346
+ */
347
+ selector?: string;
348
+ /**
349
+ * Selector for dark-scheme colors. Defaults to `.dark`, combined with
350
+ * `selector` (e.g. `.dark`, or `[data-pallet-scope].dark`). If you use the
351
+ * `.dark` class strategy this default is what you want.
352
+ */
353
+ darkSelector?: string;
354
+ /**
355
+ * When true, also emit `data-pallet-variant` as an attribute selector note in
356
+ * a comment. (The attribute itself is set by the provider or manually.)
357
+ */
358
+ includeVariantComment?: boolean;
359
+ }
360
+ /**
361
+ * Renders a full theme to a static CSS string, safe to inline in a server
362
+ * component (e.g. a Next.js layout) to avoid a flash of unstyled/incorrect
363
+ * theme before hydration.
364
+ *
365
+ * Structural tokens (radius, fonts, elevation, spacing, motion) are emitted on
366
+ * the light selector; dark-scheme *colors* are emitted on the dark selector.
367
+ */
368
+ declare function themeToCss(theme: ThemeConfig, options?: ThemeToCssOptions): string;
369
+ /** Serializes a theme (or override) to a compact JSON string for persistence. */
370
+ declare function serializeTheme(theme: ThemeConfig | ThemeOverride): string;
371
+ /** Parses a JSON string produced by {@link serializeTheme}. Returns null on error. */
372
+ declare function deserializeTheme<T = ThemeOverride>(json: string): T | null;
373
+ /** Produces the inline `style` attribute value for a scheme, for React usage. */
374
+ declare function themeToInlineStyle(theme: ThemeConfig, scheme: ColorScheme): Record<string, string>;
375
+
376
+ /**
377
+ * The "flat" preset: crisp hairline borders, minimal shadows, tighter radius.
378
+ * Mirrors the default Quill look and serves as the baseline variant.
379
+ */
380
+ declare const flat: ThemeConfig;
381
+
382
+ /**
383
+ * The "launch" preset: soft, elevated, and pill-shaped. Large radius, gentle
384
+ * layered shadows, subtle borders and a little extra breathing room. Pairs with
385
+ * `styles/variant-launch.css` which rounds controls into pills.
386
+ */
387
+ declare const launch: ThemeConfig;
388
+
389
+ /** All built-in presets, keyed by name. */
390
+ declare const presets: {
391
+ flat: ThemeConfig;
392
+ launch: ThemeConfig;
393
+ };
394
+ type PresetName = keyof typeof presets;
395
+ /** Returns a built-in preset by name, or undefined if it is not registered. */
396
+ declare function getPreset(name: VariantName): ThemeConfig | undefined;
397
+ /** The default preset used when none is specified. */
398
+ declare const defaultPreset: ThemeConfig;
399
+
400
+ export { type ColorScheme, type ColorTokens, type CssColor, type CssVarMap, DEFAULT_RADIUS_SCALE, type DeepPartial, type Density, type ElevationConfig, type GoogleFontsOptions, type Motion, PalletContext, type PalletContextValue, type PresetName, type RadiusConfig, type RadiusScale, type SchemePreference, type SchemeTarget, type ThemeConfig, type ThemeControls, type ThemeOverride, ThemeProvider, type ThemeProviderProps, type ThemeToCssOptions, type Typography, type UseColorSchemeResult, type UsePresetResult, type VariantName, applyCssVars, buildGoogleFontsUrl, clearCssVars, colorTokensToVars, cssVarsToString, deepMerge, defaultPreset, deserializeTheme, flat, getPreset, launch, loadGoogleFonts, mergeAll, presets, resolveColors, resolveTheme, serializeTheme, structuralVars, themeToCss, themeToInlineStyle, useColorScheme, usePalletContext, usePreset, useTheme, useThemeControls };