@fakhrirafiki/theme-engine 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,501 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+ import react__default, { ReactNode } from 'react';
4
+
5
+ /**
6
+ * Complete shadcn/ui color system - all semantic color tokens
7
+ *
8
+ * @public
9
+ */
10
+ interface ShadcnColorSystem {
11
+ /** Base colors */
12
+ background: string;
13
+ foreground: string;
14
+ /** Card colors */
15
+ card: string;
16
+ 'card-foreground': string;
17
+ popover: string;
18
+ 'popover-foreground': string;
19
+ /** Brand colors */
20
+ primary: string;
21
+ 'primary-foreground': string;
22
+ secondary: string;
23
+ 'secondary-foreground': string;
24
+ /** Supporting colors */
25
+ muted: string;
26
+ 'muted-foreground': string;
27
+ accent: string;
28
+ 'accent-foreground': string;
29
+ /** System colors */
30
+ destructive: string;
31
+ 'destructive-foreground': string;
32
+ border: string;
33
+ input: string;
34
+ ring: string;
35
+ /** Chart colors */
36
+ 'chart-1': string;
37
+ 'chart-2': string;
38
+ 'chart-3': string;
39
+ 'chart-4': string;
40
+ 'chart-5': string;
41
+ /** Sidebar colors */
42
+ sidebar: string;
43
+ 'sidebar-foreground': string;
44
+ 'sidebar-primary': string;
45
+ 'sidebar-primary-foreground': string;
46
+ 'sidebar-accent': string;
47
+ 'sidebar-accent-foreground': string;
48
+ 'sidebar-border': string;
49
+ 'sidebar-ring': string;
50
+ }
51
+ /**
52
+ * Typography system - font family definitions
53
+ *
54
+ * @public
55
+ */
56
+ interface TypographySystem {
57
+ 'font-sans': string;
58
+ 'font-serif': string;
59
+ 'font-mono': string;
60
+ }
61
+ /**
62
+ * Layout system - spacing and sizing
63
+ *
64
+ * @public
65
+ */
66
+ interface LayoutSystem {
67
+ /** Border radius for components */
68
+ radius: string;
69
+ }
70
+ /**
71
+ * Shadow system - complete shadow definition
72
+ *
73
+ * @public
74
+ */
75
+ interface ShadowSystem {
76
+ 'shadow-color': string;
77
+ 'shadow-opacity': string;
78
+ 'shadow-blur': string;
79
+ 'shadow-spread': string;
80
+ 'shadow-offset-x': string;
81
+ 'shadow-offset-y': string;
82
+ }
83
+ /**
84
+ * Spacing system - text and layout spacing
85
+ *
86
+ * @public
87
+ */
88
+ interface SpacingSystem {
89
+ 'letter-spacing': string;
90
+ spacing: string;
91
+ }
92
+ /**
93
+ * Complete shadcn/ui theme schema - all CSS custom properties
94
+ * Supports the full shadcn/ui theming system with 36+ properties
95
+ *
96
+ * @public
97
+ */
98
+ interface CompleteThemeSchema extends ShadcnColorSystem, TypographySystem, LayoutSystem, ShadowSystem, SpacingSystem {
99
+ /** Allow additional custom properties */
100
+ [key: string]: string;
101
+ }
102
+ /**
103
+ * Theme preset interface with complete shadcn/ui support
104
+ *
105
+ * @public
106
+ */
107
+ interface ThemePreset {
108
+ /** Unique preset identifier */
109
+ id: string;
110
+ /** Human-readable name */
111
+ name: string;
112
+ /** Color scheme for light and dark modes */
113
+ colors: {
114
+ light: CompleteThemeSchema;
115
+ dark: CompleteThemeSchema;
116
+ };
117
+ /** Optional metadata for preset categorization */
118
+ metadata?: {
119
+ category?: string;
120
+ tags?: string[];
121
+ description?: string;
122
+ author?: string;
123
+ createdAt?: string;
124
+ [key: string]: any;
125
+ };
126
+ }
127
+ /**
128
+ * Preset provider interface for data source abstraction
129
+ *
130
+ * @public
131
+ */
132
+ interface PresetProvider {
133
+ /** Get all available presets */
134
+ getPresets(): ThemePreset[] | Promise<ThemePreset[]>;
135
+ /** Get specific preset by ID */
136
+ getPreset(id: string): ThemePreset | null | Promise<ThemePreset | null>;
137
+ /** Optional: Subscribe to preset changes */
138
+ onPresetChange?: (callback: (presets: ThemePreset[]) => void) => () => void;
139
+ /** Optional: Search/filter presets */
140
+ searchPresets?: (query: string) => ThemePreset[] | Promise<ThemePreset[]>;
141
+ }
142
+ /**
143
+ * Animation configuration for preset buttons
144
+ *
145
+ * @public
146
+ */
147
+ interface AnimationConfig {
148
+ /** Enable/disable animations */
149
+ enabled: boolean;
150
+ /** Animation duration in seconds */
151
+ duration: number;
152
+ /** CSS easing function */
153
+ easing: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | string;
154
+ /** Number of preset rows */
155
+ rowCount: number;
156
+ /** Scroll speed multiplier */
157
+ scrollSpeed: number;
158
+ /** Pause animation on hover */
159
+ hoverPause: boolean;
160
+ /** Duplication factor for infinite scroll */
161
+ duplicationFactor: number;
162
+ }
163
+ /**
164
+ * Layout configuration for preset buttons
165
+ *
166
+ * @public
167
+ */
168
+ interface LayoutConfig {
169
+ /** Button width in pixels */
170
+ buttonWidth: number;
171
+ /** Gap between buttons in pixels */
172
+ buttonGap: number;
173
+ /** Gap between rows in pixels */
174
+ rowGap: number;
175
+ /** Show color preview boxes */
176
+ showColorBoxes: boolean;
177
+ /** Number of color boxes to show */
178
+ colorBoxCount: number;
179
+ /** Gradient mask for edge fading */
180
+ enableMask: boolean;
181
+ }
182
+ /**
183
+ * Theme preset buttons component props - Zero-config design
184
+ *
185
+ * State management (preset provider, selection, and mode) is handled internally
186
+ * via ThemeProvider context. Just configure appearance and behavior!
187
+ *
188
+ * @public
189
+ */
190
+ interface ThemePresetButtonsProps {
191
+ /** Animation configuration */
192
+ animation?: Partial<AnimationConfig>;
193
+ /** Layout configuration */
194
+ layout?: Partial<LayoutConfig>;
195
+ /** Custom preset renderer */
196
+ renderPreset?: (preset: ThemePreset, isSelected: boolean) => ReactNode;
197
+ /** Custom color box renderer */
198
+ renderColorBox?: (color: string, index: number) => ReactNode;
199
+ /** Additional CSS class */
200
+ className?: string;
201
+ /** Filter presets by categories */
202
+ categories?: string[];
203
+ /** Maximum number of presets to show */
204
+ maxPresets?: number;
205
+ /** Show built-in presets (default: true) */
206
+ showBuiltIn?: boolean;
207
+ /** Show custom presets (default: true) */
208
+ showCustom?: boolean;
209
+ /** Group presets by category or provider (default: 'none') */
210
+ groupBy?: 'none' | 'category' | 'provider';
211
+ /** Custom section labels */
212
+ labels?: {
213
+ /** Label for built-in presets section (default: "Built-in Themes") */
214
+ builtIn?: string;
215
+ /** Label for custom presets section (default: "Custom Themes") */
216
+ custom?: string;
217
+ };
218
+ /** Show section headers when grouping is enabled (default: true) */
219
+ showSectionHeaders?: boolean;
220
+ }
221
+
222
+ type Mode = "light" | "dark" | "system";
223
+ interface Coordinates {
224
+ x: number;
225
+ y: number;
226
+ }
227
+ interface ThemeToggleProps {
228
+ className?: string;
229
+ size?: "sm" | "md" | "lg";
230
+ variant?: "default" | "outline" | "ghost";
231
+ children?: ReactNode;
232
+ }
233
+
234
+ /**
235
+ * TweakCN Compatible Preset Collection
236
+ *
237
+ * This file matches TweakCN's exact structure to make it easy to copy-paste
238
+ * the complete defaultPresets from TweakCN's theme-presets.ts file.
239
+ *
240
+ * Structure: Record<string, TweakCNThemePreset>
241
+ *
242
+ * Usage:
243
+ * 1. Copy the entire defaultPresets object from TweakCN's theme-presets.ts
244
+ * 2. Paste it into the tweakcnPresets constant below
245
+ * 3. The conversion utilities will handle the rest
246
+ */
247
+ /**
248
+ * TweakCN's ThemePreset interface structure (exact match with TweakCN)
249
+ */
250
+ interface TweakCNThemePreset {
251
+ /** Display name for the preset */
252
+ label: string;
253
+ /** Theme styles for light and dark modes */
254
+ styles: {
255
+ light: Record<string, string>;
256
+ dark: Record<string, string>;
257
+ };
258
+ /** Optional creation date (present in some TweakCN presets) */
259
+ createdAt?: string;
260
+ }
261
+ /**
262
+ * TweakCN Compatible Preset Collection
263
+ *
264
+ * 🚀 COPY-PASTE READY:
265
+ * Replace this object with the complete defaultPresets from TweakCN
266
+ */
267
+ declare const tweakcnPresets: Record<string, TweakCNThemePreset>;
268
+ /**
269
+ * Get all preset IDs
270
+ */
271
+ declare function getPresetIds(): string[];
272
+ /**
273
+ * Get preset by ID
274
+ */
275
+ declare function getPresetById(id: string): TweakCNThemePreset | null;
276
+ /**
277
+ * Get all preset labels
278
+ */
279
+ declare function getPresetLabels(): string[];
280
+ /**
281
+ * Search presets by name (case-insensitive)
282
+ */
283
+ declare function searchPresets(query: string): Array<{
284
+ id: string;
285
+ preset: TweakCNThemePreset;
286
+ }>;
287
+ /**
288
+ * Get presets count
289
+ */
290
+ declare function getPresetsCount(): number;
291
+ /**
292
+ * Get preset entries (id + preset pairs)
293
+ */
294
+ declare function getPresetEntries(): Array<[string, TweakCNThemePreset]>;
295
+
296
+ /**
297
+ * Context value for the unified theming system.
298
+ * Provides access to both appearance mode (light/dark) and color presets.
299
+ *
300
+ * @public
301
+ */
302
+ interface UnifiedThemeContextValue {
303
+ /** Current appearance mode setting */
304
+ mode: Mode;
305
+ /** Resolved appearance mode (never 'system') */
306
+ resolvedMode: 'light' | 'dark';
307
+ /** Change the appearance mode */
308
+ setMode: (mode: Mode) => void;
309
+ /** Toggle between light and dark modes with optional animation */
310
+ toggleMode: (coordinates?: Coordinates) => void;
311
+ /** Currently applied preset (null if using default colors) */
312
+ currentPreset: {
313
+ /** Unique identifier for the preset */
314
+ presetId: string;
315
+ /** Human-readable preset name */
316
+ presetName: string;
317
+ /** Color values for light and dark modes */
318
+ colors: ThemePreset['colors'];
319
+ /** Timestamp when preset was applied */
320
+ appliedAt: number;
321
+ } | null;
322
+ /** Apply a new color preset */
323
+ applyPreset: (preset: ThemePreset) => void;
324
+ /** Clear the current preset and revert to default colors */
325
+ clearPreset: () => void;
326
+ /** Available presets (merged built-in + custom) */
327
+ availablePresets: Record<string, TweakCNThemePreset>;
328
+ /** Built-in presets only */
329
+ builtInPresets: Record<string, TweakCNThemePreset>;
330
+ /** Custom presets only */
331
+ customPresets: Record<string, TweakCNThemePreset>;
332
+ }
333
+ /**
334
+ * Props for the UnifiedThemeProvider component.
335
+ *
336
+ * @public
337
+ */
338
+ interface UnifiedThemeProviderProps {
339
+ /** React children to wrap with theming context */
340
+ children: react__default.ReactNode;
341
+ /** Default appearance mode when no stored preference exists */
342
+ defaultMode?: Mode;
343
+ /** Default preset ID to use when no stored preset exists or when resetting */
344
+ defaultPreset?: string;
345
+ /** Enable smooth transitions between modes */
346
+ enableTransitions?: boolean;
347
+ /** localStorage key for appearance mode persistence */
348
+ modeStorageKey?: string;
349
+ /** localStorage key for color preset persistence */
350
+ presetStorageKey?: string;
351
+ /** Enable custom color preset functionality */
352
+ enablePresets?: boolean;
353
+ /** Custom presets to add to the available collection */
354
+ customPresets?: Record<string, TweakCNThemePreset>;
355
+ /** Whether to include built-in TweakCN presets (default: true) */
356
+ includeBuiltInPresets?: boolean;
357
+ }
358
+ /**
359
+ * Theme Provider - The heart of the elegant theming system.
360
+ *
361
+ * Coordinates two theming concerns seamlessly:
362
+ * 1. **Appearance Mode** (light/dark/system) - Controls the base color scheme
363
+ * 2. **Color Presets** - Customizes the actual colors within that scheme
364
+ *
365
+ * ## Key Features
366
+ * - 🤝 **Perfect coordination** between appearance modes and presets
367
+ * - 💾 **Reliable persistence** with separate localStorage keys
368
+ * - ⚡ **SSR-safe** with pre-hydration script support
369
+ * - 🎨 **CSS `!important`** ensures presets override mode defaults
370
+ * - 👀 **MutationObserver** automatically reapplies presets on mode changes
371
+ *
372
+ * @example
373
+ * ```tsx
374
+ * <ThemeProvider
375
+ * defaultMode="system"
376
+ * modeStorageKey="app-mode"
377
+ * presetStorageKey="app-preset"
378
+ * enablePresets={true}
379
+ * >
380
+ * <App />
381
+ * </ThemeProvider>
382
+ * ```
383
+ *
384
+ * @public
385
+ */
386
+ declare function ThemeProvider({ children, defaultMode, defaultPreset, enableTransitions, modeStorageKey, presetStorageKey, enablePresets, customPresets, includeBuiltInPresets, }: UnifiedThemeProviderProps): react_jsx_runtime.JSX.Element | null;
387
+ /**
388
+ * Hook for accessing the unified theming system.
389
+ *
390
+ * Provides access to both appearance mode controls and preset management
391
+ * in a single, coordinated interface.
392
+ *
393
+ * @example
394
+ * ```tsx
395
+ * // Mode controls
396
+ * function ModeControls() {
397
+ * const { mode, setMode } = useTheme()
398
+ *
399
+ * return (
400
+ * <button onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}>
401
+ * Toggle Mode
402
+ * </button>
403
+ * )
404
+ * }
405
+ *
406
+ * // Preset management
407
+ * function PresetSelector() {
408
+ * const {
409
+ * currentPreset, // Active color preset
410
+ * applyPreset, // Apply new preset
411
+ * clearPreset // Reset to defaults
412
+ * } = useTheme()
413
+ *
414
+ * return (
415
+ * <div>
416
+ * <p>Active: {currentPreset?.presetName || 'Default'}</p>
417
+ * <ThemePresetButtons
418
+ * selectedPresetId={currentPreset?.presetId || null}
419
+ * onPresetSelect={applyPreset}
420
+ * />
421
+ * {currentPreset && (
422
+ * <button onClick={clearPreset}>Reset</button>
423
+ * )}
424
+ * </div>
425
+ * )
426
+ * }
427
+ * ```
428
+ *
429
+ * @throws Error if used outside of ThemeProvider
430
+ * @returns The theme context value
431
+ *
432
+ * @public
433
+ */
434
+ declare function useTheme(): UnifiedThemeContextValue;
435
+
436
+ interface ThemeScriptProps {
437
+ /**
438
+ * Storage key for theme preset persistence
439
+ * @default 'theme-preset'
440
+ */
441
+ presetStorageKey?: string;
442
+ /**
443
+ * Default preset ID to apply when no stored preset exists
444
+ */
445
+ defaultPreset?: string;
446
+ }
447
+ /**
448
+ * Simplified theme script that only handles preset restoration
449
+ * Works in harmony with ThemeProvider for dark/light mode
450
+ */
451
+ declare function ThemeScript({ presetStorageKey, defaultPreset }: ThemeScriptProps): react_jsx_runtime.JSX.Element;
452
+
453
+ declare const ThemeToggle: react.ForwardRefExoticComponent<ThemeToggleProps & react.RefAttributes<HTMLButtonElement>>;
454
+
455
+ /**
456
+ * Main ThemePresetButtons component
457
+ */
458
+ declare const ThemePresetButtons: ({ animation: animationOverrides, layout: layoutOverrides, renderPreset, renderColorBox, className, categories, maxPresets, showBuiltIn, showCustom, groupBy, labels, showSectionHeaders, }: ThemePresetButtonsProps) => react_jsx_runtime.JSX.Element;
459
+
460
+ /**
461
+ * Lightweight color utilities for theme-engine
462
+ * Provides basic color manipulation without heavy dependencies
463
+ */
464
+ type ColorFormat = 'hsl' | 'rgb' | 'hex';
465
+ /**
466
+ * Universal color formatter
467
+ * Attempts to parse any color format and output in specified format
468
+ */
469
+ declare function formatColor(colorInput: string, outputFormat?: ColorFormat, includeFunctionWrapper?: boolean): string;
470
+ /**
471
+ * Create color with alpha transparency
472
+ */
473
+ declare function withAlpha(colorInput: string, alpha: number): string;
474
+
475
+ /**
476
+ * Preset validation utilities for theme-engine
477
+ * Provides validation and error handling for custom presets
478
+ */
479
+
480
+ /**
481
+ * Validation result type
482
+ */
483
+ interface ValidationResult {
484
+ isValid: boolean;
485
+ errors: string[];
486
+ warnings: string[];
487
+ }
488
+ /**
489
+ * Validate a single TweakCN preset
490
+ */
491
+ declare function validateTweakCNPreset(preset: any, presetId?: string): ValidationResult;
492
+ /**
493
+ * Validate a collection of custom presets
494
+ */
495
+ declare function validateCustomPresets(customPresets: Record<string, TweakCNThemePreset>): ValidationResult;
496
+ /**
497
+ * Helper function to log validation results
498
+ */
499
+ declare function logValidationResult(result: ValidationResult, context?: string): void;
500
+
501
+ export { type CompleteThemeSchema, type Coordinates, type Mode, type PresetProvider, type ThemePreset, ThemePresetButtons, type ThemePresetButtonsProps, ThemeProvider, ThemeScript, ThemeToggle, type ThemeToggleProps, type TweakCNThemePreset, type ValidationResult, formatColor, getPresetById, getPresetEntries, getPresetIds, getPresetLabels, getPresetsCount, logValidationResult, searchPresets, tweakcnPresets, useTheme, validateCustomPresets, validateTweakCNPreset, withAlpha };