@fakhrirafiki/theme-engine 0.4.7 → 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/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$1 = Record<string, TweakCNThemePreset>;
359
- type CustomPresetId$1<TCustomPresets> = TCustomPresets extends CustomPresetsRecord$1 ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
360
- type PresetId<TCustomPresets> = BuiltInPresetId | CustomPresetId$1<TCustomPresets>;
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$1 | undefined = undefined> {
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$1 | undefined = undefined>({ children, defaultMode, defaultPreset, enableTransitions, modeStorageKey, presetStorageKey, enablePresets, customPresets, includeBuiltInPresets, disableScript, deferRenderUntilReady, }: UnifiedThemeProviderProps<TCustomPresets>): react_jsx_runtime.JSX.Element | null;
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$1 = Record<string, TweakCNThemePreset>;
359
- type CustomPresetId$1<TCustomPresets> = TCustomPresets extends CustomPresetsRecord$1 ? string extends keyof TCustomPresets ? never : Extract<keyof TCustomPresets, string> : never;
360
- type PresetId<TCustomPresets> = BuiltInPresetId | CustomPresetId$1<TCustomPresets>;
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$1 | undefined = undefined> {
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$1 | undefined = undefined>({ children, defaultMode, defaultPreset, enableTransitions, modeStorageKey, presetStorageKey, enablePresets, customPresets, includeBuiltInPresets, disableScript, deferRenderUntilReady, }: UnifiedThemeProviderProps<TCustomPresets>): react_jsx_runtime.JSX.Element | null;
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,
@@ -4308,17 +4309,10 @@ function ThemeProvider({
4308
4309
  children,
4309
4310
  defaultMode = "system",
4310
4311
  defaultPreset,
4311
- enableTransitions = true,
4312
4312
  modeStorageKey = THEME_STORAGE_KEY,
4313
4313
  presetStorageKey = "theme-preset",
4314
- enablePresets = true,
4315
- customPresets,
4316
- includeBuiltInPresets = true,
4317
- disableScript = false,
4318
- deferRenderUntilReady
4314
+ customPresets
4319
4315
  }) {
4320
- const shouldInjectScript = !disableScript;
4321
- const shouldDeferRenderUntilReady = deferRenderUntilReady ?? disableScript;
4322
4316
  const normalizedCustomPresets = (0, import_react2.useMemo)(() => customPresets ?? {}, [customPresets]);
4323
4317
  const [mode, setMode] = (0, import_react2.useState)(() => {
4324
4318
  const stored = getStoredMode(modeStorageKey);
@@ -4332,9 +4326,7 @@ function ThemeProvider({
4332
4326
  });
4333
4327
  const availablePresets = (0, import_react2.useMemo)(() => {
4334
4328
  const merged = {};
4335
- if (includeBuiltInPresets) {
4336
- Object.assign(merged, tweakcnPresets);
4337
- }
4329
+ Object.assign(merged, tweakcnPresets);
4338
4330
  if (Object.keys(normalizedCustomPresets).length > 0) {
4339
4331
  const validationResult = validateCustomPresets(normalizedCustomPresets);
4340
4332
  const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
@@ -4350,8 +4342,8 @@ function ThemeProvider({
4350
4342
  }
4351
4343
  }
4352
4344
  return merged;
4353
- }, [includeBuiltInPresets, normalizedCustomPresets]);
4354
- const builtInPresets = (0, import_react2.useMemo)(() => includeBuiltInPresets ? tweakcnPresets : {}, [includeBuiltInPresets]);
4345
+ }, [normalizedCustomPresets]);
4346
+ const builtInPresets = tweakcnPresets;
4355
4347
  const getAvailablePresetById = (0, import_react2.useCallback)(
4356
4348
  (id) => {
4357
4349
  return availablePresets[id] || null;
@@ -4359,12 +4351,8 @@ function ThemeProvider({
4359
4351
  [availablePresets]
4360
4352
  );
4361
4353
  const [currentPreset, setCurrentPreset] = (0, import_react2.useState)(null);
4362
- const [isReady, setIsReady] = (0, import_react2.useState)(() => !shouldDeferRenderUntilReady);
4363
4354
  (0, import_react2.useEffect)(() => {
4364
- if (!enablePresets || typeof window === "undefined") {
4365
- setIsReady(true);
4366
- return;
4367
- }
4355
+ if (typeof window === "undefined") return;
4368
4356
  try {
4369
4357
  const stored = localStorage.getItem(presetStorageKey);
4370
4358
  const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
@@ -4417,10 +4405,8 @@ function ThemeProvider({
4417
4405
  if (isDevelopment) {
4418
4406
  console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset from storage:", error);
4419
4407
  }
4420
- } finally {
4421
- setIsReady(true);
4422
4408
  }
4423
- }, [presetStorageKey, enablePresets, defaultPreset, getAvailablePresetById]);
4409
+ }, [presetStorageKey, defaultPreset, getAvailablePresetById]);
4424
4410
  (0, import_react2.useEffect)(() => {
4425
4411
  if (mode === "system") {
4426
4412
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -4499,7 +4485,7 @@ function ThemeProvider({
4499
4485
  (coordinates) => {
4500
4486
  const newMode = resolvedMode === "light" ? "dark" : "light";
4501
4487
  const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
4502
- if (enableTransitions && !prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
4488
+ if (!prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
4503
4489
  const root = document.documentElement;
4504
4490
  if (coordinates) {
4505
4491
  root.style.setProperty("--x", `${coordinates.x}px`);
@@ -4512,7 +4498,7 @@ function ThemeProvider({
4512
4498
  handleModeChange(newMode);
4513
4499
  }
4514
4500
  },
4515
- [resolvedMode, enableTransitions, handleModeChange]
4501
+ [resolvedMode, handleModeChange]
4516
4502
  );
4517
4503
  (0, import_react2.useEffect)(() => {
4518
4504
  if (!currentPreset || typeof window === "undefined") return;
@@ -4527,7 +4513,7 @@ function ThemeProvider({
4527
4513
  appliedAt: Date.now()
4528
4514
  };
4529
4515
  setCurrentPreset(presetData);
4530
- if (enablePresets && typeof window !== "undefined") {
4516
+ if (typeof window !== "undefined") {
4531
4517
  try {
4532
4518
  localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
4533
4519
  } catch (error) {
@@ -4538,7 +4524,7 @@ function ThemeProvider({
4538
4524
  applyPresetColors(preset.colors, resolvedMode);
4539
4525
  }
4540
4526
  },
4541
- [presetStorageKey, enablePresets, applyPresetColors, resolvedMode]
4527
+ [presetStorageKey, applyPresetColors, resolvedMode]
4542
4528
  );
4543
4529
  const setThemePresetById = (0, import_react2.useCallback)(
4544
4530
  (presetId) => {
@@ -4562,53 +4548,50 @@ function ThemeProvider({
4562
4548
  [getAvailablePresetById, applyPreset]
4563
4549
  );
4564
4550
  const clearPreset = (0, import_react2.useCallback)(() => {
4565
- if (enablePresets && typeof window !== "undefined") {
4551
+ if (typeof window !== "undefined") {
4566
4552
  try {
4567
4553
  localStorage.removeItem(presetStorageKey);
4568
4554
  } catch (error) {
4569
4555
  console.error("\u{1F3A8} UnifiedTheme: Failed to clear preset:", error);
4570
4556
  }
4571
- if (defaultPreset) {
4572
- const preset = getAvailablePresetById(defaultPreset);
4573
- if (preset) {
4574
- const presetData = {
4575
- presetId: defaultPreset,
4576
- presetName: preset.label,
4577
- colors: {
4578
- light: preset.styles.light,
4579
- dark: preset.styles.dark
4580
- },
4581
- appliedAt: Date.now()
4582
- };
4583
- setCurrentPreset(presetData);
4584
- applyPresetColors(presetData.colors, resolvedMode);
4585
- } else {
4586
- console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
4587
- setCurrentPreset(null);
4588
- }
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);
4589
4572
  } else {
4573
+ console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
4590
4574
  setCurrentPreset(null);
4591
- const root = document.documentElement;
4592
- const allProperties = [
4593
- ...CSS_PROPERTY_CATEGORIES.colors,
4594
- ...CSS_PROPERTY_CATEGORIES.typography,
4595
- ...CSS_PROPERTY_CATEGORIES.layout,
4596
- ...CSS_PROPERTY_CATEGORIES.shadows,
4597
- ...CSS_PROPERTY_CATEGORIES.spacing
4598
- ];
4599
- let clearedCount = 0;
4600
- allProperties.forEach((prop) => {
4601
- const cssVar = `--${prop}`;
4602
- root.style.removeProperty(cssVar);
4603
- clearedCount++;
4604
- });
4605
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
+ });
4606
4592
  }
4607
- }, [presetStorageKey, enablePresets, defaultPreset, applyPresetColors, resolvedMode]);
4608
- const scriptElement = shouldInjectScript ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeScript, { presetStorageKey, defaultPreset }) : null;
4609
- if (!isReady && shouldDeferRenderUntilReady) {
4610
- return scriptElement;
4611
- }
4593
+ }, [presetStorageKey, defaultPreset, getAvailablePresetById, applyPresetColors, resolvedMode]);
4594
+ const scriptElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeScript, { presetStorageKey, defaultPreset });
4612
4595
  const isUsingDefaultPreset = !!defaultPreset && currentPreset?.presetId === defaultPreset;
4613
4596
  const contextValue = {
4614
4597
  mode,
@@ -4864,7 +4847,7 @@ var AnimatedRow = ({
4864
4847
  }) => {
4865
4848
  if (presets.length === 0) return null;
4866
4849
  const duplicatedPresets = Array(animation.duplicationFactor).fill(presets).flat();
4867
- 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;
4868
4851
  const effectiveScrollSpeed = Math.max(0.1, animation.scrollSpeed || 1);
4869
4852
  const animationDuration = presets.length * animation.duration / effectiveScrollSpeed;
4870
4853
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -5061,6 +5044,42 @@ function useTypedTheme(customPresets) {
5061
5044
  setThemePresetById
5062
5045
  };
5063
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
+ }
5064
5083
  // Annotate the CommonJS export names for ESM import in node:
5065
5084
  0 && (module.exports = {
5066
5085
  ThemePresetButtons,
@@ -5078,6 +5097,7 @@ function useTypedTheme(customPresets) {
5078
5097
  searchPresets,
5079
5098
  tweakcnPresets,
5080
5099
  useTheme,
5100
+ useThemeEngine,
5081
5101
  useTypedTheme,
5082
5102
  validateCustomPresets,
5083
5103
  validateTweakCNPreset,