@fakhrirafiki/theme-engine 0.4.5 → 0.4.8
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.
- package/README.md +281 -115
- package/dist/index.d.mts +65 -26
- package/dist/index.d.ts +65 -26
- package/dist/index.js +132 -65
- package/dist/index.mjs +131 -65
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -355,40 +355,27 @@ interface UnifiedThemeContextValue {
|
|
|
355
355
|
/** Custom presets only */
|
|
356
356
|
customPresets: Record<string, TweakCNThemePreset>;
|
|
357
357
|
}
|
|
358
|
-
type CustomPresetsRecord$
|
|
359
|
-
type CustomPresetId$
|
|
360
|
-
type PresetId<TCustomPresets> = BuiltInPresetId | CustomPresetId$
|
|
358
|
+
type CustomPresetsRecord$2 = Record<string, TweakCNThemePreset>;
|
|
359
|
+
type CustomPresetId$2<TCustomPresets> = TCustomPresets extends CustomPresetsRecord$2 ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
360
|
+
type PresetId<TCustomPresets> = BuiltInPresetId | CustomPresetId$2<TCustomPresets>;
|
|
361
361
|
/**
|
|
362
362
|
* Props for the UnifiedThemeProvider component.
|
|
363
363
|
*
|
|
364
364
|
* @public
|
|
365
365
|
*/
|
|
366
|
-
interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$
|
|
366
|
+
interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$2 | undefined = undefined> {
|
|
367
367
|
/** React children to wrap with theming context */
|
|
368
368
|
children: react__default.ReactNode;
|
|
369
369
|
/** Default appearance mode when no stored preference exists */
|
|
370
370
|
defaultMode?: Mode;
|
|
371
371
|
/** Default preset ID to use when no stored preset exists or when resetting */
|
|
372
372
|
defaultPreset?: PresetId<TCustomPresets>;
|
|
373
|
-
/** Enable smooth transitions between modes */
|
|
374
|
-
enableTransitions?: boolean;
|
|
375
373
|
/** localStorage key for appearance mode persistence */
|
|
376
374
|
modeStorageKey?: string;
|
|
377
375
|
/** localStorage key for color preset persistence */
|
|
378
376
|
presetStorageKey?: string;
|
|
379
|
-
/** Enable custom color preset functionality */
|
|
380
|
-
enablePresets?: boolean;
|
|
381
377
|
/** Custom presets to add to the available collection */
|
|
382
378
|
customPresets?: TCustomPresets;
|
|
383
|
-
/** Whether to include built-in TweakCN presets (default: true) */
|
|
384
|
-
includeBuiltInPresets?: boolean;
|
|
385
|
-
/** Disable injecting `ThemeScript` from inside `ThemeProvider` (useful if you render it in `<head>` yourself). */
|
|
386
|
-
disableScript?: boolean;
|
|
387
|
-
/**
|
|
388
|
-
* When true, the provider renders `null` until persisted preset is loaded from storage.
|
|
389
|
-
* Defaults to `true` when `disableScript` is enabled (backwards behavior), otherwise `false`.
|
|
390
|
-
*/
|
|
391
|
-
deferRenderUntilReady?: boolean;
|
|
392
379
|
}
|
|
393
380
|
/**
|
|
394
381
|
* Theme Provider - The heart of the elegant theming system.
|
|
@@ -410,7 +397,6 @@ interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$1
|
|
|
410
397
|
* defaultMode="system"
|
|
411
398
|
* modeStorageKey="app-mode"
|
|
412
399
|
* presetStorageKey="app-preset"
|
|
413
|
-
* enablePresets={true}
|
|
414
400
|
* >
|
|
415
401
|
* <App />
|
|
416
402
|
* </ThemeProvider>
|
|
@@ -418,7 +404,7 @@ interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$1
|
|
|
418
404
|
*
|
|
419
405
|
* @public
|
|
420
406
|
*/
|
|
421
|
-
declare function ThemeProvider<const TCustomPresets extends CustomPresetsRecord$
|
|
407
|
+
declare function ThemeProvider<const TCustomPresets extends CustomPresetsRecord$2 | undefined = undefined>({ children, defaultMode, defaultPreset, modeStorageKey, presetStorageKey, customPresets, }: UnifiedThemeProviderProps<TCustomPresets>): react_jsx_runtime.JSX.Element;
|
|
422
408
|
/**
|
|
423
409
|
* Hook for accessing the unified theming system.
|
|
424
410
|
*
|
|
@@ -492,10 +478,10 @@ declare const ThemeToggle: react.ForwardRefExoticComponent<ThemeToggleProps & re
|
|
|
492
478
|
*/
|
|
493
479
|
declare const ThemePresetButtons: ({ animation: animationOverrides, layout: layoutOverrides, renderPreset, renderColorBox, className, categories, maxPresets, showBuiltIn, showCustom, }: ThemePresetButtonsProps) => react_jsx_runtime.JSX.Element;
|
|
494
480
|
|
|
495
|
-
type CustomPresetsRecord = Record<string, TweakCNThemePreset>;
|
|
496
|
-
type CustomPresetId<TCustomPresets> = TCustomPresets extends CustomPresetsRecord ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
497
|
-
type ThemePresetId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = BuiltInPresetId | CustomPresetId<TCustomPresets>;
|
|
498
|
-
type LooseString = string & {};
|
|
481
|
+
type CustomPresetsRecord$1 = Record<string, TweakCNThemePreset>;
|
|
482
|
+
type CustomPresetId$1<TCustomPresets> = TCustomPresets extends CustomPresetsRecord$1 ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
483
|
+
type ThemePresetId$1<TCustomPresets extends CustomPresetsRecord$1 | undefined = undefined> = BuiltInPresetId | CustomPresetId$1<TCustomPresets>;
|
|
484
|
+
type LooseString$1 = string & {};
|
|
499
485
|
/**
|
|
500
486
|
* Typed convenience wrapper around `useTheme()` that provides IntelliSense for preset IDs.
|
|
501
487
|
*
|
|
@@ -504,8 +490,8 @@ type LooseString = string & {};
|
|
|
504
490
|
*
|
|
505
491
|
* The resulting `setThemePresetById()` still accepts any string, but VS Code will suggest known IDs first.
|
|
506
492
|
*/
|
|
507
|
-
declare function useTypedTheme<const TCustomPresets extends CustomPresetsRecord | undefined = undefined>(customPresets?: TCustomPresets): {
|
|
508
|
-
setThemePresetById: (presetId: LooseString | ThemePresetId<TCustomPresets>) => void;
|
|
493
|
+
declare function useTypedTheme<const TCustomPresets extends CustomPresetsRecord$1 | undefined = undefined>(customPresets?: TCustomPresets): {
|
|
494
|
+
setThemePresetById: (presetId: LooseString$1 | ThemePresetId$1<TCustomPresets>) => void;
|
|
509
495
|
mode: Mode;
|
|
510
496
|
resolvedMode: "light" | "dark";
|
|
511
497
|
setMode: (mode: Mode) => void;
|
|
@@ -524,6 +510,59 @@ declare function useTypedTheme<const TCustomPresets extends CustomPresetsRecord
|
|
|
524
510
|
customPresets: Record<string, TweakCNThemePreset>;
|
|
525
511
|
};
|
|
526
512
|
|
|
513
|
+
type CustomPresetsRecord = Record<string, TweakCNThemePreset>;
|
|
514
|
+
type CustomPresetId<TCustomPresets> = TCustomPresets extends CustomPresetsRecord ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
515
|
+
type ThemePresetId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = BuiltInPresetId | CustomPresetId<TCustomPresets>;
|
|
516
|
+
type LooseString = string & {};
|
|
517
|
+
/**
|
|
518
|
+
* Type helper to "register" your presets for autocomplete.
|
|
519
|
+
*
|
|
520
|
+
* Usage:
|
|
521
|
+
* `useThemeEngine<ThemePresets<typeof customPresets>>()`
|
|
522
|
+
*/
|
|
523
|
+
type ThemePresets<T> = T extends CustomPresetsRecord ? T : never;
|
|
524
|
+
type ThemeEnginePresetId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = ThemePresetId<TCustomPresets>;
|
|
525
|
+
type ThemeId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = ThemeEnginePresetId<TCustomPresets> | LooseString;
|
|
526
|
+
/**
|
|
527
|
+
* DX-first hook for Theme Engine.
|
|
528
|
+
*
|
|
529
|
+
* Unifies:
|
|
530
|
+
* - mode controls (`light` | `dark` | `system`)
|
|
531
|
+
* - preset controls (apply/clear by ID)
|
|
532
|
+
*
|
|
533
|
+
* For typed preset ID autocomplete (built-in + your custom IDs):
|
|
534
|
+
* `useThemeEngine<ThemePresets<typeof customPresets>>()`
|
|
535
|
+
*/
|
|
536
|
+
declare function useThemeEngine<const TCustomPresets extends CustomPresetsRecord | undefined = undefined>(): {
|
|
537
|
+
darkMode: boolean;
|
|
538
|
+
mode: Mode;
|
|
539
|
+
resolvedMode: "light" | "dark";
|
|
540
|
+
setDarkMode: (mode: Mode) => void;
|
|
541
|
+
setMode: (mode: Mode) => void;
|
|
542
|
+
toggleDarkMode: (coordinates?: Coordinates) => void;
|
|
543
|
+
toggleMode: (coordinates?: Coordinates) => void;
|
|
544
|
+
applyThemeById: (themeId: ThemeId<TCustomPresets>) => void;
|
|
545
|
+
applyPresetById: (themeId: ThemeId<TCustomPresets>) => void;
|
|
546
|
+
clearTheme: () => void;
|
|
547
|
+
clearPreset: () => void;
|
|
548
|
+
currentTheme: {
|
|
549
|
+
presetId: string;
|
|
550
|
+
presetName: string;
|
|
551
|
+
colors: ThemePreset["colors"];
|
|
552
|
+
appliedAt: number;
|
|
553
|
+
} | null;
|
|
554
|
+
currentPreset: {
|
|
555
|
+
presetId: string;
|
|
556
|
+
presetName: string;
|
|
557
|
+
colors: ThemePreset["colors"];
|
|
558
|
+
appliedAt: number;
|
|
559
|
+
} | null;
|
|
560
|
+
isUsingDefaultPreset: boolean;
|
|
561
|
+
availablePresets: Record<string, TweakCNThemePreset>;
|
|
562
|
+
builtInPresets: Record<string, TweakCNThemePreset>;
|
|
563
|
+
customPresets: Record<string, TweakCNThemePreset>;
|
|
564
|
+
};
|
|
565
|
+
|
|
527
566
|
/**
|
|
528
567
|
* Lightweight color utilities for theme-engine
|
|
529
568
|
* Provides basic color manipulation without heavy dependencies
|
|
@@ -565,4 +604,4 @@ declare function validateCustomPresets(customPresets: Record<string, TweakCNThem
|
|
|
565
604
|
*/
|
|
566
605
|
declare function logValidationResult(result: ValidationResult, context?: string): void;
|
|
567
606
|
|
|
568
|
-
export { type BuiltInPresetId, type CompleteThemeSchema, type Coordinates, type Mode, type PresetProvider, type ThemePreset, ThemePresetButtons, type ThemePresetButtonsProps, type ThemePresetId, ThemeProvider, ThemeScript, ThemeToggle, type ThemeToggleProps, type TweakCNThemePreset, type ValidationResult, builtInPresetIds, formatColor, getPresetById, getPresetEntries, getPresetIds, getPresetLabels, getPresetsCount, logValidationResult, searchPresets, tweakcnPresets, useTheme, useTypedTheme, validateCustomPresets, validateTweakCNPreset, withAlpha };
|
|
607
|
+
export { type BuiltInPresetId, type CompleteThemeSchema, type Coordinates, type Mode, type PresetProvider, type ThemeEnginePresetId, type ThemeId, type ThemePreset, ThemePresetButtons, type ThemePresetButtonsProps, type ThemePresetId$1 as ThemePresetId, type ThemePresets, ThemeProvider, ThemeScript, ThemeToggle, type ThemeToggleProps, type TweakCNThemePreset, type ValidationResult, builtInPresetIds, formatColor, getPresetById, getPresetEntries, getPresetIds, getPresetLabels, getPresetsCount, logValidationResult, searchPresets, tweakcnPresets, useTheme, useThemeEngine, useTypedTheme, validateCustomPresets, validateTweakCNPreset, withAlpha };
|
package/dist/index.d.ts
CHANGED
|
@@ -355,40 +355,27 @@ interface UnifiedThemeContextValue {
|
|
|
355
355
|
/** Custom presets only */
|
|
356
356
|
customPresets: Record<string, TweakCNThemePreset>;
|
|
357
357
|
}
|
|
358
|
-
type CustomPresetsRecord$
|
|
359
|
-
type CustomPresetId$
|
|
360
|
-
type PresetId<TCustomPresets> = BuiltInPresetId | CustomPresetId$
|
|
358
|
+
type CustomPresetsRecord$2 = Record<string, TweakCNThemePreset>;
|
|
359
|
+
type CustomPresetId$2<TCustomPresets> = TCustomPresets extends CustomPresetsRecord$2 ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
360
|
+
type PresetId<TCustomPresets> = BuiltInPresetId | CustomPresetId$2<TCustomPresets>;
|
|
361
361
|
/**
|
|
362
362
|
* Props for the UnifiedThemeProvider component.
|
|
363
363
|
*
|
|
364
364
|
* @public
|
|
365
365
|
*/
|
|
366
|
-
interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$
|
|
366
|
+
interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$2 | undefined = undefined> {
|
|
367
367
|
/** React children to wrap with theming context */
|
|
368
368
|
children: react__default.ReactNode;
|
|
369
369
|
/** Default appearance mode when no stored preference exists */
|
|
370
370
|
defaultMode?: Mode;
|
|
371
371
|
/** Default preset ID to use when no stored preset exists or when resetting */
|
|
372
372
|
defaultPreset?: PresetId<TCustomPresets>;
|
|
373
|
-
/** Enable smooth transitions between modes */
|
|
374
|
-
enableTransitions?: boolean;
|
|
375
373
|
/** localStorage key for appearance mode persistence */
|
|
376
374
|
modeStorageKey?: string;
|
|
377
375
|
/** localStorage key for color preset persistence */
|
|
378
376
|
presetStorageKey?: string;
|
|
379
|
-
/** Enable custom color preset functionality */
|
|
380
|
-
enablePresets?: boolean;
|
|
381
377
|
/** Custom presets to add to the available collection */
|
|
382
378
|
customPresets?: TCustomPresets;
|
|
383
|
-
/** Whether to include built-in TweakCN presets (default: true) */
|
|
384
|
-
includeBuiltInPresets?: boolean;
|
|
385
|
-
/** Disable injecting `ThemeScript` from inside `ThemeProvider` (useful if you render it in `<head>` yourself). */
|
|
386
|
-
disableScript?: boolean;
|
|
387
|
-
/**
|
|
388
|
-
* When true, the provider renders `null` until persisted preset is loaded from storage.
|
|
389
|
-
* Defaults to `true` when `disableScript` is enabled (backwards behavior), otherwise `false`.
|
|
390
|
-
*/
|
|
391
|
-
deferRenderUntilReady?: boolean;
|
|
392
379
|
}
|
|
393
380
|
/**
|
|
394
381
|
* Theme Provider - The heart of the elegant theming system.
|
|
@@ -410,7 +397,6 @@ interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$1
|
|
|
410
397
|
* defaultMode="system"
|
|
411
398
|
* modeStorageKey="app-mode"
|
|
412
399
|
* presetStorageKey="app-preset"
|
|
413
|
-
* enablePresets={true}
|
|
414
400
|
* >
|
|
415
401
|
* <App />
|
|
416
402
|
* </ThemeProvider>
|
|
@@ -418,7 +404,7 @@ interface UnifiedThemeProviderProps<TCustomPresets extends CustomPresetsRecord$1
|
|
|
418
404
|
*
|
|
419
405
|
* @public
|
|
420
406
|
*/
|
|
421
|
-
declare function ThemeProvider<const TCustomPresets extends CustomPresetsRecord$
|
|
407
|
+
declare function ThemeProvider<const TCustomPresets extends CustomPresetsRecord$2 | undefined = undefined>({ children, defaultMode, defaultPreset, modeStorageKey, presetStorageKey, customPresets, }: UnifiedThemeProviderProps<TCustomPresets>): react_jsx_runtime.JSX.Element;
|
|
422
408
|
/**
|
|
423
409
|
* Hook for accessing the unified theming system.
|
|
424
410
|
*
|
|
@@ -492,10 +478,10 @@ declare const ThemeToggle: react.ForwardRefExoticComponent<ThemeToggleProps & re
|
|
|
492
478
|
*/
|
|
493
479
|
declare const ThemePresetButtons: ({ animation: animationOverrides, layout: layoutOverrides, renderPreset, renderColorBox, className, categories, maxPresets, showBuiltIn, showCustom, }: ThemePresetButtonsProps) => react_jsx_runtime.JSX.Element;
|
|
494
480
|
|
|
495
|
-
type CustomPresetsRecord = Record<string, TweakCNThemePreset>;
|
|
496
|
-
type CustomPresetId<TCustomPresets> = TCustomPresets extends CustomPresetsRecord ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
497
|
-
type ThemePresetId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = BuiltInPresetId | CustomPresetId<TCustomPresets>;
|
|
498
|
-
type LooseString = string & {};
|
|
481
|
+
type CustomPresetsRecord$1 = Record<string, TweakCNThemePreset>;
|
|
482
|
+
type CustomPresetId$1<TCustomPresets> = TCustomPresets extends CustomPresetsRecord$1 ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
483
|
+
type ThemePresetId$1<TCustomPresets extends CustomPresetsRecord$1 | undefined = undefined> = BuiltInPresetId | CustomPresetId$1<TCustomPresets>;
|
|
484
|
+
type LooseString$1 = string & {};
|
|
499
485
|
/**
|
|
500
486
|
* Typed convenience wrapper around `useTheme()` that provides IntelliSense for preset IDs.
|
|
501
487
|
*
|
|
@@ -504,8 +490,8 @@ type LooseString = string & {};
|
|
|
504
490
|
*
|
|
505
491
|
* The resulting `setThemePresetById()` still accepts any string, but VS Code will suggest known IDs first.
|
|
506
492
|
*/
|
|
507
|
-
declare function useTypedTheme<const TCustomPresets extends CustomPresetsRecord | undefined = undefined>(customPresets?: TCustomPresets): {
|
|
508
|
-
setThemePresetById: (presetId: LooseString | ThemePresetId<TCustomPresets>) => void;
|
|
493
|
+
declare function useTypedTheme<const TCustomPresets extends CustomPresetsRecord$1 | undefined = undefined>(customPresets?: TCustomPresets): {
|
|
494
|
+
setThemePresetById: (presetId: LooseString$1 | ThemePresetId$1<TCustomPresets>) => void;
|
|
509
495
|
mode: Mode;
|
|
510
496
|
resolvedMode: "light" | "dark";
|
|
511
497
|
setMode: (mode: Mode) => void;
|
|
@@ -524,6 +510,59 @@ declare function useTypedTheme<const TCustomPresets extends CustomPresetsRecord
|
|
|
524
510
|
customPresets: Record<string, TweakCNThemePreset>;
|
|
525
511
|
};
|
|
526
512
|
|
|
513
|
+
type CustomPresetsRecord = Record<string, TweakCNThemePreset>;
|
|
514
|
+
type CustomPresetId<TCustomPresets> = TCustomPresets extends CustomPresetsRecord ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
|
|
515
|
+
type ThemePresetId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = BuiltInPresetId | CustomPresetId<TCustomPresets>;
|
|
516
|
+
type LooseString = string & {};
|
|
517
|
+
/**
|
|
518
|
+
* Type helper to "register" your presets for autocomplete.
|
|
519
|
+
*
|
|
520
|
+
* Usage:
|
|
521
|
+
* `useThemeEngine<ThemePresets<typeof customPresets>>()`
|
|
522
|
+
*/
|
|
523
|
+
type ThemePresets<T> = T extends CustomPresetsRecord ? T : never;
|
|
524
|
+
type ThemeEnginePresetId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = ThemePresetId<TCustomPresets>;
|
|
525
|
+
type ThemeId<TCustomPresets extends CustomPresetsRecord | undefined = undefined> = ThemeEnginePresetId<TCustomPresets> | LooseString;
|
|
526
|
+
/**
|
|
527
|
+
* DX-first hook for Theme Engine.
|
|
528
|
+
*
|
|
529
|
+
* Unifies:
|
|
530
|
+
* - mode controls (`light` | `dark` | `system`)
|
|
531
|
+
* - preset controls (apply/clear by ID)
|
|
532
|
+
*
|
|
533
|
+
* For typed preset ID autocomplete (built-in + your custom IDs):
|
|
534
|
+
* `useThemeEngine<ThemePresets<typeof customPresets>>()`
|
|
535
|
+
*/
|
|
536
|
+
declare function useThemeEngine<const TCustomPresets extends CustomPresetsRecord | undefined = undefined>(): {
|
|
537
|
+
darkMode: boolean;
|
|
538
|
+
mode: Mode;
|
|
539
|
+
resolvedMode: "light" | "dark";
|
|
540
|
+
setDarkMode: (mode: Mode) => void;
|
|
541
|
+
setMode: (mode: Mode) => void;
|
|
542
|
+
toggleDarkMode: (coordinates?: Coordinates) => void;
|
|
543
|
+
toggleMode: (coordinates?: Coordinates) => void;
|
|
544
|
+
applyThemeById: (themeId: ThemeId<TCustomPresets>) => void;
|
|
545
|
+
applyPresetById: (themeId: ThemeId<TCustomPresets>) => void;
|
|
546
|
+
clearTheme: () => void;
|
|
547
|
+
clearPreset: () => void;
|
|
548
|
+
currentTheme: {
|
|
549
|
+
presetId: string;
|
|
550
|
+
presetName: string;
|
|
551
|
+
colors: ThemePreset["colors"];
|
|
552
|
+
appliedAt: number;
|
|
553
|
+
} | null;
|
|
554
|
+
currentPreset: {
|
|
555
|
+
presetId: string;
|
|
556
|
+
presetName: string;
|
|
557
|
+
colors: ThemePreset["colors"];
|
|
558
|
+
appliedAt: number;
|
|
559
|
+
} | null;
|
|
560
|
+
isUsingDefaultPreset: boolean;
|
|
561
|
+
availablePresets: Record<string, TweakCNThemePreset>;
|
|
562
|
+
builtInPresets: Record<string, TweakCNThemePreset>;
|
|
563
|
+
customPresets: Record<string, TweakCNThemePreset>;
|
|
564
|
+
};
|
|
565
|
+
|
|
527
566
|
/**
|
|
528
567
|
* Lightweight color utilities for theme-engine
|
|
529
568
|
* Provides basic color manipulation without heavy dependencies
|
|
@@ -565,4 +604,4 @@ declare function validateCustomPresets(customPresets: Record<string, TweakCNThem
|
|
|
565
604
|
*/
|
|
566
605
|
declare function logValidationResult(result: ValidationResult, context?: string): void;
|
|
567
606
|
|
|
568
|
-
export { type BuiltInPresetId, type CompleteThemeSchema, type Coordinates, type Mode, type PresetProvider, type ThemePreset, ThemePresetButtons, type ThemePresetButtonsProps, type ThemePresetId, ThemeProvider, ThemeScript, ThemeToggle, type ThemeToggleProps, type TweakCNThemePreset, type ValidationResult, builtInPresetIds, formatColor, getPresetById, getPresetEntries, getPresetIds, getPresetLabels, getPresetsCount, logValidationResult, searchPresets, tweakcnPresets, useTheme, useTypedTheme, validateCustomPresets, validateTweakCNPreset, withAlpha };
|
|
607
|
+
export { type BuiltInPresetId, type CompleteThemeSchema, type Coordinates, type Mode, type PresetProvider, type ThemeEnginePresetId, type ThemeId, type ThemePreset, ThemePresetButtons, type ThemePresetButtonsProps, type ThemePresetId$1 as ThemePresetId, type ThemePresets, ThemeProvider, ThemeScript, ThemeToggle, type ThemeToggleProps, type TweakCNThemePreset, type ValidationResult, builtInPresetIds, formatColor, getPresetById, getPresetEntries, getPresetIds, getPresetLabels, getPresetsCount, logValidationResult, searchPresets, tweakcnPresets, useTheme, useThemeEngine, useTypedTheme, validateCustomPresets, validateTweakCNPreset, withAlpha };
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
searchPresets: () => searchPresets,
|
|
37
37
|
tweakcnPresets: () => tweakcnPresets,
|
|
38
38
|
useTheme: () => useTheme,
|
|
39
|
+
useThemeEngine: () => useThemeEngine,
|
|
39
40
|
useTypedTheme: () => useTypedTheme,
|
|
40
41
|
validateCustomPresets: () => validateCustomPresets,
|
|
41
42
|
validateTweakCNPreset: () => validateTweakCNPreset,
|
|
@@ -3983,6 +3984,29 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3983
3984
|
if (rgb) return toTriplet(rgbToHsl(rgb.r, rgb.g, rgb.b));
|
|
3984
3985
|
}
|
|
3985
3986
|
|
|
3987
|
+
// Any other CSS color (e.g. oklch(...), named colors) -> resolve via computed styles.
|
|
3988
|
+
try {
|
|
3989
|
+
const probe = document.createElement('span');
|
|
3990
|
+
probe.style.color = trimmed;
|
|
3991
|
+
probe.style.position = 'absolute';
|
|
3992
|
+
probe.style.left = '-9999px';
|
|
3993
|
+
probe.style.top = '-9999px';
|
|
3994
|
+
probe.style.visibility = 'hidden';
|
|
3995
|
+
document.documentElement.appendChild(probe);
|
|
3996
|
+
const computed = getComputedStyle(probe).color; // rgb(...) or rgba(...)
|
|
3997
|
+
probe.remove();
|
|
3998
|
+
|
|
3999
|
+
const match = computed && computed.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/i);
|
|
4000
|
+
if (match) {
|
|
4001
|
+
const r = clamp(parseFloat(match[1]) || 0, 0, 255);
|
|
4002
|
+
const g = clamp(parseFloat(match[2]) || 0, 0, 255);
|
|
4003
|
+
const b = clamp(parseFloat(match[3]) || 0, 0, 255);
|
|
4004
|
+
return toTriplet(rgbToHsl(r, g, b));
|
|
4005
|
+
}
|
|
4006
|
+
} catch (e) {
|
|
4007
|
+
// ignore and fall through
|
|
4008
|
+
}
|
|
4009
|
+
|
|
3986
4010
|
return value;
|
|
3987
4011
|
}
|
|
3988
4012
|
|
|
@@ -4255,23 +4279,40 @@ function normalizeColorValueToHslTriplet(value) {
|
|
|
4255
4279
|
if (parsedHsl) return formatHSL(parsedHsl, false);
|
|
4256
4280
|
const parsedRgb = parseHex(trimmed);
|
|
4257
4281
|
if (parsedRgb) return formatHSL(rgbToHsl(parsedRgb), false);
|
|
4258
|
-
|
|
4282
|
+
if (typeof document !== "undefined") {
|
|
4283
|
+
try {
|
|
4284
|
+
if (trimmed.startsWith("var(")) return trimmed;
|
|
4285
|
+
const probe = document.createElement("span");
|
|
4286
|
+
probe.style.color = trimmed;
|
|
4287
|
+
probe.style.position = "absolute";
|
|
4288
|
+
probe.style.left = "-9999px";
|
|
4289
|
+
probe.style.top = "-9999px";
|
|
4290
|
+
probe.style.visibility = "hidden";
|
|
4291
|
+
document.documentElement.appendChild(probe);
|
|
4292
|
+
const computed = getComputedStyle(probe).color;
|
|
4293
|
+
probe.remove();
|
|
4294
|
+
const match = computed.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/i);
|
|
4295
|
+
if (match) {
|
|
4296
|
+
const r = Number(match[1]);
|
|
4297
|
+
const g = Number(match[2]);
|
|
4298
|
+
const b = Number(match[3]);
|
|
4299
|
+
if (Number.isFinite(r) && Number.isFinite(g) && Number.isFinite(b)) {
|
|
4300
|
+
return formatHSL(rgbToHsl({ r, g, b }), false);
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4303
|
+
} catch {
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
return trimmed;
|
|
4259
4307
|
}
|
|
4260
4308
|
function ThemeProvider({
|
|
4261
4309
|
children,
|
|
4262
4310
|
defaultMode = "system",
|
|
4263
4311
|
defaultPreset,
|
|
4264
|
-
enableTransitions = true,
|
|
4265
4312
|
modeStorageKey = THEME_STORAGE_KEY,
|
|
4266
4313
|
presetStorageKey = "theme-preset",
|
|
4267
|
-
|
|
4268
|
-
customPresets,
|
|
4269
|
-
includeBuiltInPresets = true,
|
|
4270
|
-
disableScript = false,
|
|
4271
|
-
deferRenderUntilReady
|
|
4314
|
+
customPresets
|
|
4272
4315
|
}) {
|
|
4273
|
-
const shouldInjectScript = !disableScript;
|
|
4274
|
-
const shouldDeferRenderUntilReady = deferRenderUntilReady ?? disableScript;
|
|
4275
4316
|
const normalizedCustomPresets = (0, import_react2.useMemo)(() => customPresets ?? {}, [customPresets]);
|
|
4276
4317
|
const [mode, setMode] = (0, import_react2.useState)(() => {
|
|
4277
4318
|
const stored = getStoredMode(modeStorageKey);
|
|
@@ -4285,9 +4326,7 @@ function ThemeProvider({
|
|
|
4285
4326
|
});
|
|
4286
4327
|
const availablePresets = (0, import_react2.useMemo)(() => {
|
|
4287
4328
|
const merged = {};
|
|
4288
|
-
|
|
4289
|
-
Object.assign(merged, tweakcnPresets);
|
|
4290
|
-
}
|
|
4329
|
+
Object.assign(merged, tweakcnPresets);
|
|
4291
4330
|
if (Object.keys(normalizedCustomPresets).length > 0) {
|
|
4292
4331
|
const validationResult = validateCustomPresets(normalizedCustomPresets);
|
|
4293
4332
|
const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
|
|
@@ -4303,8 +4342,8 @@ function ThemeProvider({
|
|
|
4303
4342
|
}
|
|
4304
4343
|
}
|
|
4305
4344
|
return merged;
|
|
4306
|
-
}, [
|
|
4307
|
-
const builtInPresets =
|
|
4345
|
+
}, [normalizedCustomPresets]);
|
|
4346
|
+
const builtInPresets = tweakcnPresets;
|
|
4308
4347
|
const getAvailablePresetById = (0, import_react2.useCallback)(
|
|
4309
4348
|
(id) => {
|
|
4310
4349
|
return availablePresets[id] || null;
|
|
@@ -4312,12 +4351,8 @@ function ThemeProvider({
|
|
|
4312
4351
|
[availablePresets]
|
|
4313
4352
|
);
|
|
4314
4353
|
const [currentPreset, setCurrentPreset] = (0, import_react2.useState)(null);
|
|
4315
|
-
const [isReady, setIsReady] = (0, import_react2.useState)(() => !shouldDeferRenderUntilReady);
|
|
4316
4354
|
(0, import_react2.useEffect)(() => {
|
|
4317
|
-
if (
|
|
4318
|
-
setIsReady(true);
|
|
4319
|
-
return;
|
|
4320
|
-
}
|
|
4355
|
+
if (typeof window === "undefined") return;
|
|
4321
4356
|
try {
|
|
4322
4357
|
const stored = localStorage.getItem(presetStorageKey);
|
|
4323
4358
|
const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
|
|
@@ -4370,10 +4405,8 @@ function ThemeProvider({
|
|
|
4370
4405
|
if (isDevelopment) {
|
|
4371
4406
|
console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset from storage:", error);
|
|
4372
4407
|
}
|
|
4373
|
-
} finally {
|
|
4374
|
-
setIsReady(true);
|
|
4375
4408
|
}
|
|
4376
|
-
}, [presetStorageKey,
|
|
4409
|
+
}, [presetStorageKey, defaultPreset, getAvailablePresetById]);
|
|
4377
4410
|
(0, import_react2.useEffect)(() => {
|
|
4378
4411
|
if (mode === "system") {
|
|
4379
4412
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
@@ -4452,7 +4485,7 @@ function ThemeProvider({
|
|
|
4452
4485
|
(coordinates) => {
|
|
4453
4486
|
const newMode = resolvedMode === "light" ? "dark" : "light";
|
|
4454
4487
|
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
4455
|
-
if (
|
|
4488
|
+
if (!prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
|
|
4456
4489
|
const root = document.documentElement;
|
|
4457
4490
|
if (coordinates) {
|
|
4458
4491
|
root.style.setProperty("--x", `${coordinates.x}px`);
|
|
@@ -4465,7 +4498,7 @@ function ThemeProvider({
|
|
|
4465
4498
|
handleModeChange(newMode);
|
|
4466
4499
|
}
|
|
4467
4500
|
},
|
|
4468
|
-
[resolvedMode,
|
|
4501
|
+
[resolvedMode, handleModeChange]
|
|
4469
4502
|
);
|
|
4470
4503
|
(0, import_react2.useEffect)(() => {
|
|
4471
4504
|
if (!currentPreset || typeof window === "undefined") return;
|
|
@@ -4480,7 +4513,7 @@ function ThemeProvider({
|
|
|
4480
4513
|
appliedAt: Date.now()
|
|
4481
4514
|
};
|
|
4482
4515
|
setCurrentPreset(presetData);
|
|
4483
|
-
if (
|
|
4516
|
+
if (typeof window !== "undefined") {
|
|
4484
4517
|
try {
|
|
4485
4518
|
localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
|
|
4486
4519
|
} catch (error) {
|
|
@@ -4491,7 +4524,7 @@ function ThemeProvider({
|
|
|
4491
4524
|
applyPresetColors(preset.colors, resolvedMode);
|
|
4492
4525
|
}
|
|
4493
4526
|
},
|
|
4494
|
-
[presetStorageKey,
|
|
4527
|
+
[presetStorageKey, applyPresetColors, resolvedMode]
|
|
4495
4528
|
);
|
|
4496
4529
|
const setThemePresetById = (0, import_react2.useCallback)(
|
|
4497
4530
|
(presetId) => {
|
|
@@ -4515,53 +4548,50 @@ function ThemeProvider({
|
|
|
4515
4548
|
[getAvailablePresetById, applyPreset]
|
|
4516
4549
|
);
|
|
4517
4550
|
const clearPreset = (0, import_react2.useCallback)(() => {
|
|
4518
|
-
if (
|
|
4551
|
+
if (typeof window !== "undefined") {
|
|
4519
4552
|
try {
|
|
4520
4553
|
localStorage.removeItem(presetStorageKey);
|
|
4521
4554
|
} catch (error) {
|
|
4522
4555
|
console.error("\u{1F3A8} UnifiedTheme: Failed to clear preset:", error);
|
|
4523
4556
|
}
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
|
|
4540
|
-
setCurrentPreset(null);
|
|
4541
|
-
}
|
|
4557
|
+
}
|
|
4558
|
+
if (defaultPreset) {
|
|
4559
|
+
const preset = getAvailablePresetById(defaultPreset);
|
|
4560
|
+
if (preset) {
|
|
4561
|
+
const presetData = {
|
|
4562
|
+
presetId: defaultPreset,
|
|
4563
|
+
presetName: preset.label,
|
|
4564
|
+
colors: {
|
|
4565
|
+
light: preset.styles.light,
|
|
4566
|
+
dark: preset.styles.dark
|
|
4567
|
+
},
|
|
4568
|
+
appliedAt: Date.now()
|
|
4569
|
+
};
|
|
4570
|
+
setCurrentPreset(presetData);
|
|
4571
|
+
applyPresetColors(presetData.colors, resolvedMode);
|
|
4542
4572
|
} else {
|
|
4573
|
+
console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
|
|
4543
4574
|
setCurrentPreset(null);
|
|
4544
|
-
const root = document.documentElement;
|
|
4545
|
-
const allProperties = [
|
|
4546
|
-
...CSS_PROPERTY_CATEGORIES.colors,
|
|
4547
|
-
...CSS_PROPERTY_CATEGORIES.typography,
|
|
4548
|
-
...CSS_PROPERTY_CATEGORIES.layout,
|
|
4549
|
-
...CSS_PROPERTY_CATEGORIES.shadows,
|
|
4550
|
-
...CSS_PROPERTY_CATEGORIES.spacing
|
|
4551
|
-
];
|
|
4552
|
-
let clearedCount = 0;
|
|
4553
|
-
allProperties.forEach((prop) => {
|
|
4554
|
-
const cssVar = `--${prop}`;
|
|
4555
|
-
root.style.removeProperty(cssVar);
|
|
4556
|
-
clearedCount++;
|
|
4557
|
-
});
|
|
4558
4575
|
}
|
|
4576
|
+
} else {
|
|
4577
|
+
setCurrentPreset(null);
|
|
4578
|
+
const root = document.documentElement;
|
|
4579
|
+
const allProperties = [
|
|
4580
|
+
...CSS_PROPERTY_CATEGORIES.colors,
|
|
4581
|
+
...CSS_PROPERTY_CATEGORIES.typography,
|
|
4582
|
+
...CSS_PROPERTY_CATEGORIES.layout,
|
|
4583
|
+
...CSS_PROPERTY_CATEGORIES.shadows,
|
|
4584
|
+
...CSS_PROPERTY_CATEGORIES.spacing
|
|
4585
|
+
];
|
|
4586
|
+
let clearedCount = 0;
|
|
4587
|
+
allProperties.forEach((prop) => {
|
|
4588
|
+
const cssVar = `--${prop}`;
|
|
4589
|
+
root.style.removeProperty(cssVar);
|
|
4590
|
+
clearedCount++;
|
|
4591
|
+
});
|
|
4559
4592
|
}
|
|
4560
|
-
}, [presetStorageKey,
|
|
4561
|
-
const scriptElement =
|
|
4562
|
-
if (!isReady && shouldDeferRenderUntilReady) {
|
|
4563
|
-
return scriptElement;
|
|
4564
|
-
}
|
|
4593
|
+
}, [presetStorageKey, defaultPreset, getAvailablePresetById, applyPresetColors, resolvedMode]);
|
|
4594
|
+
const scriptElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeScript, { presetStorageKey, defaultPreset });
|
|
4565
4595
|
const isUsingDefaultPreset = !!defaultPreset && currentPreset?.presetId === defaultPreset;
|
|
4566
4596
|
const contextValue = {
|
|
4567
4597
|
mode,
|
|
@@ -4817,7 +4847,7 @@ var AnimatedRow = ({
|
|
|
4817
4847
|
}) => {
|
|
4818
4848
|
if (presets.length === 0) return null;
|
|
4819
4849
|
const duplicatedPresets = Array(animation.duplicationFactor).fill(presets).flat();
|
|
4820
|
-
const totalWidth = presets.reduce((sum, preset) => sum + (Number(preset.metadata?.buttonWidth) || layout.buttonWidth), 0) + presets.length * layout.buttonGap;
|
|
4850
|
+
const totalWidth = presets.reduce((sum, preset) => sum + (Number(preset.metadata?.buttonWidth) || layout.buttonWidth), 0) + Math.max(0, presets.length - 1) * layout.buttonGap;
|
|
4821
4851
|
const effectiveScrollSpeed = Math.max(0.1, animation.scrollSpeed || 1);
|
|
4822
4852
|
const animationDuration = presets.length * animation.duration / effectiveScrollSpeed;
|
|
4823
4853
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -5014,6 +5044,42 @@ function useTypedTheme(customPresets) {
|
|
|
5014
5044
|
setThemePresetById
|
|
5015
5045
|
};
|
|
5016
5046
|
}
|
|
5047
|
+
|
|
5048
|
+
// src/hooks/useThemeEngine.ts
|
|
5049
|
+
function useThemeEngine() {
|
|
5050
|
+
const theme = useTheme();
|
|
5051
|
+
const darkMode = theme.resolvedMode === "dark";
|
|
5052
|
+
const setDarkMode = (mode) => theme.setMode(mode);
|
|
5053
|
+
const toggleDarkMode = (coordinates) => theme.toggleMode(coordinates);
|
|
5054
|
+
const applyThemeById = (themeId) => theme.setThemePresetById(themeId);
|
|
5055
|
+
const applyPresetById = applyThemeById;
|
|
5056
|
+
const clearTheme = () => theme.clearPreset();
|
|
5057
|
+
const clearPreset = clearTheme;
|
|
5058
|
+
const currentTheme = theme.currentPreset;
|
|
5059
|
+
const currentPreset = theme.currentPreset;
|
|
5060
|
+
return {
|
|
5061
|
+
// Mode
|
|
5062
|
+
darkMode,
|
|
5063
|
+
mode: theme.mode,
|
|
5064
|
+
resolvedMode: theme.resolvedMode,
|
|
5065
|
+
setDarkMode,
|
|
5066
|
+
setMode: theme.setMode,
|
|
5067
|
+
toggleDarkMode,
|
|
5068
|
+
toggleMode: theme.toggleMode,
|
|
5069
|
+
// Presets (theme naming)
|
|
5070
|
+
applyThemeById,
|
|
5071
|
+
applyPresetById,
|
|
5072
|
+
clearTheme,
|
|
5073
|
+
clearPreset,
|
|
5074
|
+
currentTheme,
|
|
5075
|
+
currentPreset,
|
|
5076
|
+
// Advanced / diagnostics
|
|
5077
|
+
isUsingDefaultPreset: theme.isUsingDefaultPreset,
|
|
5078
|
+
availablePresets: theme.availablePresets,
|
|
5079
|
+
builtInPresets: theme.builtInPresets,
|
|
5080
|
+
customPresets: theme.customPresets
|
|
5081
|
+
};
|
|
5082
|
+
}
|
|
5017
5083
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5018
5084
|
0 && (module.exports = {
|
|
5019
5085
|
ThemePresetButtons,
|
|
@@ -5031,6 +5097,7 @@ function useTypedTheme(customPresets) {
|
|
|
5031
5097
|
searchPresets,
|
|
5032
5098
|
tweakcnPresets,
|
|
5033
5099
|
useTheme,
|
|
5100
|
+
useThemeEngine,
|
|
5034
5101
|
useTypedTheme,
|
|
5035
5102
|
validateCustomPresets,
|
|
5036
5103
|
validateTweakCNPreset,
|