@fakhrirafiki/theme-engine 0.2.1 → 0.2.5

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 CHANGED
@@ -390,6 +390,22 @@ function CustomControls() {
390
390
  </button>
391
391
  )
392
392
  }
393
+
394
+ // Or apply a preset by ID (from built-in or custom presets)
395
+ function QuickPresetSwitcher() {
396
+ const { setThemePresetById } = useTheme()
397
+
398
+ return (
399
+ <div>
400
+ <button onClick={() => setThemePresetById('modern-minimal')}>
401
+ Modern Minimal
402
+ </button>
403
+ <button onClick={() => setThemePresetById('tiket-ngobrol')}>
404
+ Ngobrol Blue
405
+ </button>
406
+ </div>
407
+ )
408
+ }
393
409
  ```
394
410
 
395
411
  ## 🔄 Migration Guide
@@ -563,4 +579,4 @@ This architecture ensures seamless coordination between appearance modes and col
563
579
 
564
580
  ## 📄 License
565
581
 
566
- MIT License - see the monorepo root for details.
582
+ MIT License - see the monorepo root for details.
package/dist/index.d.mts CHANGED
@@ -318,7 +318,7 @@ interface UnifiedThemeContextValue {
318
318
  /** Current appearance mode setting */
319
319
  mode: Mode;
320
320
  /** Resolved appearance mode (never 'system') */
321
- resolvedMode: 'light' | 'dark';
321
+ resolvedMode: "light" | "dark";
322
322
  /** Change the appearance mode */
323
323
  setMode: (mode: Mode) => void;
324
324
  /** Toggle between light and dark modes with optional animation */
@@ -330,14 +330,18 @@ interface UnifiedThemeContextValue {
330
330
  /** Human-readable preset name */
331
331
  presetName: string;
332
332
  /** Color values for light and dark modes */
333
- colors: ThemePreset['colors'];
333
+ colors: ThemePreset["colors"];
334
334
  /** Timestamp when preset was applied */
335
335
  appliedAt: number;
336
336
  } | null;
337
337
  /** Apply a new color preset */
338
338
  applyPreset: (preset: ThemePreset) => void;
339
+ /** Apply a preset by its ID from the available preset collection */
340
+ setThemePresetById: (presetId: string) => void;
339
341
  /** Clear the current preset and revert to default colors */
340
342
  clearPreset: () => void;
343
+ /** Whether the currently active preset matches the defaultPreset prop */
344
+ isUsingDefaultPreset: boolean;
341
345
  /** Available presets (merged built-in + custom) */
342
346
  availablePresets: Record<string, TweakCNThemePreset>;
343
347
  /** Built-in presets only */
package/dist/index.d.ts CHANGED
@@ -318,7 +318,7 @@ interface UnifiedThemeContextValue {
318
318
  /** Current appearance mode setting */
319
319
  mode: Mode;
320
320
  /** Resolved appearance mode (never 'system') */
321
- resolvedMode: 'light' | 'dark';
321
+ resolvedMode: "light" | "dark";
322
322
  /** Change the appearance mode */
323
323
  setMode: (mode: Mode) => void;
324
324
  /** Toggle between light and dark modes with optional animation */
@@ -330,14 +330,18 @@ interface UnifiedThemeContextValue {
330
330
  /** Human-readable preset name */
331
331
  presetName: string;
332
332
  /** Color values for light and dark modes */
333
- colors: ThemePreset['colors'];
333
+ colors: ThemePreset["colors"];
334
334
  /** Timestamp when preset was applied */
335
335
  appliedAt: number;
336
336
  } | null;
337
337
  /** Apply a new color preset */
338
338
  applyPreset: (preset: ThemePreset) => void;
339
+ /** Apply a preset by its ID from the available preset collection */
340
+ setThemePresetById: (presetId: string) => void;
339
341
  /** Clear the current preset and revert to default colors */
340
342
  clearPreset: () => void;
343
+ /** Whether the currently active preset matches the defaultPreset prop */
344
+ isUsingDefaultPreset: boolean;
341
345
  /** Available presets (merged built-in + custom) */
342
346
  availablePresets: Record<string, TweakCNThemePreset>;
343
347
  /** Built-in presets only */
package/dist/index.js CHANGED
@@ -3748,9 +3748,12 @@ function ThemeProvider({
3748
3748
  }, [includeBuiltInPresets, customPresets]);
3749
3749
  const builtInPresets = (0, import_react.useMemo)(() => includeBuiltInPresets ? tweakcnPresets : {}, [includeBuiltInPresets]);
3750
3750
  const normalizedCustomPresets = (0, import_react.useMemo)(() => customPresets || {}, [customPresets]);
3751
- const getAvailablePresetById = (0, import_react.useCallback)((id) => {
3752
- return availablePresets[id] || null;
3753
- }, [availablePresets]);
3751
+ const getAvailablePresetById = (0, import_react.useCallback)(
3752
+ (id) => {
3753
+ return availablePresets[id] || null;
3754
+ },
3755
+ [availablePresets]
3756
+ );
3754
3757
  const [currentPreset, setCurrentPreset] = (0, import_react.useState)(null);
3755
3758
  const [isReady, setIsReady] = (0, import_react.useState)(false);
3756
3759
  (0, import_react.useEffect)(() => {
@@ -3760,10 +3763,9 @@ function ThemeProvider({
3760
3763
  }
3761
3764
  try {
3762
3765
  const stored = localStorage.getItem(presetStorageKey);
3763
- if (stored) {
3764
- const preset = JSON.parse(stored);
3765
- setCurrentPreset(preset);
3766
- } else if (defaultPreset) {
3766
+ const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
3767
+ const applyDefaultPreset = () => {
3768
+ if (!defaultPreset) return;
3767
3769
  const preset = getAvailablePresetById(defaultPreset);
3768
3770
  if (preset) {
3769
3771
  const presetData = {
@@ -3779,13 +3781,42 @@ function ThemeProvider({
3779
3781
  } else {
3780
3782
  console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
3781
3783
  }
3784
+ };
3785
+ if (stored) {
3786
+ try {
3787
+ const parsed = JSON.parse(stored);
3788
+ const isValidObject = parsed && typeof parsed === "object";
3789
+ const hasColors = isValidObject && "colors" in parsed && parsed.colors && typeof parsed.colors === "object" && parsed.colors.light && parsed.colors.dark;
3790
+ if (hasColors) {
3791
+ setCurrentPreset(parsed);
3792
+ if (isDevelopment) {
3793
+ }
3794
+ } else {
3795
+ if (isDevelopment) {
3796
+ console.warn("\u{1F3A8} UnifiedTheme: Invalid persisted preset shape. Clearing and falling back.");
3797
+ }
3798
+ localStorage.removeItem(presetStorageKey);
3799
+ applyDefaultPreset();
3800
+ }
3801
+ } catch (error) {
3802
+ if (isDevelopment) {
3803
+ console.warn("\u{1F3A8} UnifiedTheme: Failed to parse persisted preset. Clearing key.", error);
3804
+ }
3805
+ localStorage.removeItem(presetStorageKey);
3806
+ applyDefaultPreset();
3807
+ }
3808
+ } else {
3809
+ applyDefaultPreset();
3782
3810
  }
3783
3811
  } catch (error) {
3784
- console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset:", error);
3812
+ const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
3813
+ if (isDevelopment) {
3814
+ console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset from storage:", error);
3815
+ }
3785
3816
  } finally {
3786
3817
  setIsReady(true);
3787
3818
  }
3788
- }, [presetStorageKey, enablePresets, defaultPreset]);
3819
+ }, [presetStorageKey, enablePresets, defaultPreset, getAvailablePresetById]);
3789
3820
  (0, import_react.useEffect)(() => {
3790
3821
  if (mode === "system") {
3791
3822
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -3806,11 +3837,12 @@ function ThemeProvider({
3806
3837
  root.style.colorScheme = resolvedMode;
3807
3838
  }, [resolvedMode]);
3808
3839
  const applyPresetColors = (0, import_react.useCallback)((preset, mode2) => {
3840
+ if (!preset) return;
3809
3841
  const root = document.documentElement;
3810
3842
  const colors = preset[mode2];
3811
3843
  if (!colors) return;
3812
3844
  const defaultValues = {
3813
- "spacing": "0.25rem",
3845
+ spacing: "0.25rem",
3814
3846
  "letter-spacing": "normal"
3815
3847
  };
3816
3848
  const allCategories = [
@@ -3849,49 +3881,79 @@ function ThemeProvider({
3849
3881
  }
3850
3882
  });
3851
3883
  }, []);
3852
- const handleModeChange = (0, import_react.useCallback)((newMode) => {
3853
- setMode(newMode);
3854
- setStoredMode(newMode, modeStorageKey);
3855
- }, [modeStorageKey]);
3856
- const handleModeToggle = (0, import_react.useCallback)((coordinates) => {
3857
- const newMode = resolvedMode === "light" ? "dark" : "light";
3858
- const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
3859
- if (enableTransitions && !prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
3860
- const root = document.documentElement;
3861
- if (coordinates) {
3862
- root.style.setProperty("--x", `${coordinates.x}px`);
3863
- root.style.setProperty("--y", `${coordinates.y}px`);
3864
- }
3865
- document.startViewTransition(() => {
3884
+ const handleModeChange = (0, import_react.useCallback)(
3885
+ (newMode) => {
3886
+ setMode(newMode);
3887
+ setStoredMode(newMode, modeStorageKey);
3888
+ },
3889
+ [modeStorageKey]
3890
+ );
3891
+ const handleModeToggle = (0, import_react.useCallback)(
3892
+ (coordinates) => {
3893
+ const newMode = resolvedMode === "light" ? "dark" : "light";
3894
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
3895
+ if (enableTransitions && !prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
3896
+ const root = document.documentElement;
3897
+ if (coordinates) {
3898
+ root.style.setProperty("--x", `${coordinates.x}px`);
3899
+ root.style.setProperty("--y", `${coordinates.y}px`);
3900
+ }
3901
+ document.startViewTransition(() => {
3902
+ handleModeChange(newMode);
3903
+ });
3904
+ } else {
3866
3905
  handleModeChange(newMode);
3867
- });
3868
- } else {
3869
- handleModeChange(newMode);
3870
- }
3871
- }, [resolvedMode, enableTransitions, handleModeChange]);
3906
+ }
3907
+ },
3908
+ [resolvedMode, enableTransitions, handleModeChange]
3909
+ );
3872
3910
  (0, import_react.useEffect)(() => {
3873
3911
  if (!currentPreset || typeof window === "undefined") return;
3874
3912
  applyPresetColors(currentPreset.colors, resolvedMode);
3875
3913
  }, [currentPreset, resolvedMode, applyPresetColors]);
3876
- const applyPreset = (0, import_react.useCallback)((preset) => {
3877
- const presetData = {
3878
- presetId: preset.id,
3879
- presetName: preset.name,
3880
- colors: preset.colors,
3881
- appliedAt: Date.now()
3882
- };
3883
- setCurrentPreset(presetData);
3884
- if (enablePresets && typeof window !== "undefined") {
3885
- try {
3886
- localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
3887
- } catch (error) {
3888
- console.error("\u{1F3A8} UnifiedTheme: Failed to save preset:", error);
3914
+ const applyPreset = (0, import_react.useCallback)(
3915
+ (preset) => {
3916
+ const presetData = {
3917
+ presetId: preset.id,
3918
+ presetName: preset.name,
3919
+ colors: preset.colors,
3920
+ appliedAt: Date.now()
3921
+ };
3922
+ setCurrentPreset(presetData);
3923
+ if (enablePresets && typeof window !== "undefined") {
3924
+ try {
3925
+ localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
3926
+ } catch (error) {
3927
+ console.error("\u{1F3A8} UnifiedTheme: Failed to save preset:", error);
3928
+ }
3889
3929
  }
3890
- }
3891
- if (typeof window !== "undefined") {
3892
- applyPresetColors(preset.colors, resolvedMode);
3893
- }
3894
- }, [presetStorageKey, enablePresets, applyPresetColors, resolvedMode]);
3930
+ if (typeof window !== "undefined") {
3931
+ applyPresetColors(preset.colors, resolvedMode);
3932
+ }
3933
+ },
3934
+ [presetStorageKey, enablePresets, applyPresetColors, resolvedMode]
3935
+ );
3936
+ const setThemePresetById = (0, import_react.useCallback)(
3937
+ (presetId) => {
3938
+ const preset = getAvailablePresetById(presetId);
3939
+ if (!preset) {
3940
+ if (typeof window !== "undefined") {
3941
+ console.warn("\u{1F3A8} UnifiedTheme: Preset not found for id:", presetId);
3942
+ }
3943
+ return;
3944
+ }
3945
+ const presetData = {
3946
+ id: presetId,
3947
+ name: preset.label,
3948
+ colors: {
3949
+ light: preset.styles.light,
3950
+ dark: preset.styles.dark
3951
+ }
3952
+ };
3953
+ applyPreset(presetData);
3954
+ },
3955
+ [getAvailablePresetById, applyPreset]
3956
+ );
3895
3957
  const clearPreset = (0, import_react.useCallback)(() => {
3896
3958
  if (enablePresets && typeof window !== "undefined") {
3897
3959
  try {
@@ -3939,6 +4001,7 @@ function ThemeProvider({
3939
4001
  if (!isReady) {
3940
4002
  return null;
3941
4003
  }
4004
+ const isUsingDefaultPreset = !!defaultPreset && currentPreset?.presetId === defaultPreset;
3942
4005
  const contextValue = {
3943
4006
  mode,
3944
4007
  resolvedMode,
@@ -3946,7 +4009,9 @@ function ThemeProvider({
3946
4009
  toggleMode: handleModeToggle,
3947
4010
  currentPreset,
3948
4011
  applyPreset,
4012
+ setThemePresetById,
3949
4013
  clearPreset,
4014
+ isUsingDefaultPreset,
3950
4015
  availablePresets,
3951
4016
  builtInPresets,
3952
4017
  customPresets: normalizedCustomPresets
package/dist/index.mjs CHANGED
@@ -3707,9 +3707,12 @@ function ThemeProvider({
3707
3707
  }, [includeBuiltInPresets, customPresets]);
3708
3708
  const builtInPresets = useMemo(() => includeBuiltInPresets ? tweakcnPresets : {}, [includeBuiltInPresets]);
3709
3709
  const normalizedCustomPresets = useMemo(() => customPresets || {}, [customPresets]);
3710
- const getAvailablePresetById = useCallback((id) => {
3711
- return availablePresets[id] || null;
3712
- }, [availablePresets]);
3710
+ const getAvailablePresetById = useCallback(
3711
+ (id) => {
3712
+ return availablePresets[id] || null;
3713
+ },
3714
+ [availablePresets]
3715
+ );
3713
3716
  const [currentPreset, setCurrentPreset] = useState(null);
3714
3717
  const [isReady, setIsReady] = useState(false);
3715
3718
  useEffect(() => {
@@ -3719,10 +3722,9 @@ function ThemeProvider({
3719
3722
  }
3720
3723
  try {
3721
3724
  const stored = localStorage.getItem(presetStorageKey);
3722
- if (stored) {
3723
- const preset = JSON.parse(stored);
3724
- setCurrentPreset(preset);
3725
- } else if (defaultPreset) {
3725
+ const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
3726
+ const applyDefaultPreset = () => {
3727
+ if (!defaultPreset) return;
3726
3728
  const preset = getAvailablePresetById(defaultPreset);
3727
3729
  if (preset) {
3728
3730
  const presetData = {
@@ -3738,13 +3740,42 @@ function ThemeProvider({
3738
3740
  } else {
3739
3741
  console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
3740
3742
  }
3743
+ };
3744
+ if (stored) {
3745
+ try {
3746
+ const parsed = JSON.parse(stored);
3747
+ const isValidObject = parsed && typeof parsed === "object";
3748
+ const hasColors = isValidObject && "colors" in parsed && parsed.colors && typeof parsed.colors === "object" && parsed.colors.light && parsed.colors.dark;
3749
+ if (hasColors) {
3750
+ setCurrentPreset(parsed);
3751
+ if (isDevelopment) {
3752
+ }
3753
+ } else {
3754
+ if (isDevelopment) {
3755
+ console.warn("\u{1F3A8} UnifiedTheme: Invalid persisted preset shape. Clearing and falling back.");
3756
+ }
3757
+ localStorage.removeItem(presetStorageKey);
3758
+ applyDefaultPreset();
3759
+ }
3760
+ } catch (error) {
3761
+ if (isDevelopment) {
3762
+ console.warn("\u{1F3A8} UnifiedTheme: Failed to parse persisted preset. Clearing key.", error);
3763
+ }
3764
+ localStorage.removeItem(presetStorageKey);
3765
+ applyDefaultPreset();
3766
+ }
3767
+ } else {
3768
+ applyDefaultPreset();
3741
3769
  }
3742
3770
  } catch (error) {
3743
- console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset:", error);
3771
+ const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
3772
+ if (isDevelopment) {
3773
+ console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset from storage:", error);
3774
+ }
3744
3775
  } finally {
3745
3776
  setIsReady(true);
3746
3777
  }
3747
- }, [presetStorageKey, enablePresets, defaultPreset]);
3778
+ }, [presetStorageKey, enablePresets, defaultPreset, getAvailablePresetById]);
3748
3779
  useEffect(() => {
3749
3780
  if (mode === "system") {
3750
3781
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -3765,11 +3796,12 @@ function ThemeProvider({
3765
3796
  root.style.colorScheme = resolvedMode;
3766
3797
  }, [resolvedMode]);
3767
3798
  const applyPresetColors = useCallback((preset, mode2) => {
3799
+ if (!preset) return;
3768
3800
  const root = document.documentElement;
3769
3801
  const colors = preset[mode2];
3770
3802
  if (!colors) return;
3771
3803
  const defaultValues = {
3772
- "spacing": "0.25rem",
3804
+ spacing: "0.25rem",
3773
3805
  "letter-spacing": "normal"
3774
3806
  };
3775
3807
  const allCategories = [
@@ -3808,49 +3840,79 @@ function ThemeProvider({
3808
3840
  }
3809
3841
  });
3810
3842
  }, []);
3811
- const handleModeChange = useCallback((newMode) => {
3812
- setMode(newMode);
3813
- setStoredMode(newMode, modeStorageKey);
3814
- }, [modeStorageKey]);
3815
- const handleModeToggle = useCallback((coordinates) => {
3816
- const newMode = resolvedMode === "light" ? "dark" : "light";
3817
- const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
3818
- if (enableTransitions && !prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
3819
- const root = document.documentElement;
3820
- if (coordinates) {
3821
- root.style.setProperty("--x", `${coordinates.x}px`);
3822
- root.style.setProperty("--y", `${coordinates.y}px`);
3823
- }
3824
- document.startViewTransition(() => {
3843
+ const handleModeChange = useCallback(
3844
+ (newMode) => {
3845
+ setMode(newMode);
3846
+ setStoredMode(newMode, modeStorageKey);
3847
+ },
3848
+ [modeStorageKey]
3849
+ );
3850
+ const handleModeToggle = useCallback(
3851
+ (coordinates) => {
3852
+ const newMode = resolvedMode === "light" ? "dark" : "light";
3853
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
3854
+ if (enableTransitions && !prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
3855
+ const root = document.documentElement;
3856
+ if (coordinates) {
3857
+ root.style.setProperty("--x", `${coordinates.x}px`);
3858
+ root.style.setProperty("--y", `${coordinates.y}px`);
3859
+ }
3860
+ document.startViewTransition(() => {
3861
+ handleModeChange(newMode);
3862
+ });
3863
+ } else {
3825
3864
  handleModeChange(newMode);
3826
- });
3827
- } else {
3828
- handleModeChange(newMode);
3829
- }
3830
- }, [resolvedMode, enableTransitions, handleModeChange]);
3865
+ }
3866
+ },
3867
+ [resolvedMode, enableTransitions, handleModeChange]
3868
+ );
3831
3869
  useEffect(() => {
3832
3870
  if (!currentPreset || typeof window === "undefined") return;
3833
3871
  applyPresetColors(currentPreset.colors, resolvedMode);
3834
3872
  }, [currentPreset, resolvedMode, applyPresetColors]);
3835
- const applyPreset = useCallback((preset) => {
3836
- const presetData = {
3837
- presetId: preset.id,
3838
- presetName: preset.name,
3839
- colors: preset.colors,
3840
- appliedAt: Date.now()
3841
- };
3842
- setCurrentPreset(presetData);
3843
- if (enablePresets && typeof window !== "undefined") {
3844
- try {
3845
- localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
3846
- } catch (error) {
3847
- console.error("\u{1F3A8} UnifiedTheme: Failed to save preset:", error);
3873
+ const applyPreset = useCallback(
3874
+ (preset) => {
3875
+ const presetData = {
3876
+ presetId: preset.id,
3877
+ presetName: preset.name,
3878
+ colors: preset.colors,
3879
+ appliedAt: Date.now()
3880
+ };
3881
+ setCurrentPreset(presetData);
3882
+ if (enablePresets && typeof window !== "undefined") {
3883
+ try {
3884
+ localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
3885
+ } catch (error) {
3886
+ console.error("\u{1F3A8} UnifiedTheme: Failed to save preset:", error);
3887
+ }
3848
3888
  }
3849
- }
3850
- if (typeof window !== "undefined") {
3851
- applyPresetColors(preset.colors, resolvedMode);
3852
- }
3853
- }, [presetStorageKey, enablePresets, applyPresetColors, resolvedMode]);
3889
+ if (typeof window !== "undefined") {
3890
+ applyPresetColors(preset.colors, resolvedMode);
3891
+ }
3892
+ },
3893
+ [presetStorageKey, enablePresets, applyPresetColors, resolvedMode]
3894
+ );
3895
+ const setThemePresetById = useCallback(
3896
+ (presetId) => {
3897
+ const preset = getAvailablePresetById(presetId);
3898
+ if (!preset) {
3899
+ if (typeof window !== "undefined") {
3900
+ console.warn("\u{1F3A8} UnifiedTheme: Preset not found for id:", presetId);
3901
+ }
3902
+ return;
3903
+ }
3904
+ const presetData = {
3905
+ id: presetId,
3906
+ name: preset.label,
3907
+ colors: {
3908
+ light: preset.styles.light,
3909
+ dark: preset.styles.dark
3910
+ }
3911
+ };
3912
+ applyPreset(presetData);
3913
+ },
3914
+ [getAvailablePresetById, applyPreset]
3915
+ );
3854
3916
  const clearPreset = useCallback(() => {
3855
3917
  if (enablePresets && typeof window !== "undefined") {
3856
3918
  try {
@@ -3898,6 +3960,7 @@ function ThemeProvider({
3898
3960
  if (!isReady) {
3899
3961
  return null;
3900
3962
  }
3963
+ const isUsingDefaultPreset = !!defaultPreset && currentPreset?.presetId === defaultPreset;
3901
3964
  const contextValue = {
3902
3965
  mode,
3903
3966
  resolvedMode,
@@ -3905,7 +3968,9 @@ function ThemeProvider({
3905
3968
  toggleMode: handleModeToggle,
3906
3969
  currentPreset,
3907
3970
  applyPreset,
3971
+ setThemePresetById,
3908
3972
  clearPreset,
3973
+ isUsingDefaultPreset,
3909
3974
  availablePresets,
3910
3975
  builtInPresets,
3911
3976
  customPresets: normalizedCustomPresets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fakhrirafiki/theme-engine",
3
- "version": "0.2.1",
3
+ "version": "0.2.5",
4
4
  "description": "Elegant theming system with smooth transitions, custom presets, semantic accent colors, and complete shadcn/ui support for modern React applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -57,7 +57,7 @@
57
57
  "dark-mode",
58
58
  "light-mode",
59
59
  "react",
60
- "typescript",
60
+ "typescript",
61
61
  "transitions",
62
62
  "shadcn",
63
63
  "tailwind",
@@ -70,6 +70,6 @@
70
70
  "accent-colors",
71
71
  "semantic-colors"
72
72
  ],
73
- "author": "NgobrolLink Team",
73
+ "author": "Tiket Ngobrol Team",
74
74
  "license": "MIT"
75
- }
75
+ }