@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.mjs CHANGED
@@ -4265,17 +4265,10 @@ function ThemeProvider({
4265
4265
  children,
4266
4266
  defaultMode = "system",
4267
4267
  defaultPreset,
4268
- enableTransitions = true,
4269
4268
  modeStorageKey = THEME_STORAGE_KEY,
4270
4269
  presetStorageKey = "theme-preset",
4271
- enablePresets = true,
4272
- customPresets,
4273
- includeBuiltInPresets = true,
4274
- disableScript = false,
4275
- deferRenderUntilReady
4270
+ customPresets
4276
4271
  }) {
4277
- const shouldInjectScript = !disableScript;
4278
- const shouldDeferRenderUntilReady = deferRenderUntilReady ?? disableScript;
4279
4272
  const normalizedCustomPresets = useMemo2(() => customPresets ?? {}, [customPresets]);
4280
4273
  const [mode, setMode] = useState(() => {
4281
4274
  const stored = getStoredMode(modeStorageKey);
@@ -4289,9 +4282,7 @@ function ThemeProvider({
4289
4282
  });
4290
4283
  const availablePresets = useMemo2(() => {
4291
4284
  const merged = {};
4292
- if (includeBuiltInPresets) {
4293
- Object.assign(merged, tweakcnPresets);
4294
- }
4285
+ Object.assign(merged, tweakcnPresets);
4295
4286
  if (Object.keys(normalizedCustomPresets).length > 0) {
4296
4287
  const validationResult = validateCustomPresets(normalizedCustomPresets);
4297
4288
  const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
@@ -4307,8 +4298,8 @@ function ThemeProvider({
4307
4298
  }
4308
4299
  }
4309
4300
  return merged;
4310
- }, [includeBuiltInPresets, normalizedCustomPresets]);
4311
- const builtInPresets = useMemo2(() => includeBuiltInPresets ? tweakcnPresets : {}, [includeBuiltInPresets]);
4301
+ }, [normalizedCustomPresets]);
4302
+ const builtInPresets = tweakcnPresets;
4312
4303
  const getAvailablePresetById = useCallback(
4313
4304
  (id) => {
4314
4305
  return availablePresets[id] || null;
@@ -4316,12 +4307,8 @@ function ThemeProvider({
4316
4307
  [availablePresets]
4317
4308
  );
4318
4309
  const [currentPreset, setCurrentPreset] = useState(null);
4319
- const [isReady, setIsReady] = useState(() => !shouldDeferRenderUntilReady);
4320
4310
  useEffect(() => {
4321
- if (!enablePresets || typeof window === "undefined") {
4322
- setIsReady(true);
4323
- return;
4324
- }
4311
+ if (typeof window === "undefined") return;
4325
4312
  try {
4326
4313
  const stored = localStorage.getItem(presetStorageKey);
4327
4314
  const isDevelopment = typeof window !== "undefined" && window.location?.hostname === "localhost";
@@ -4374,10 +4361,8 @@ function ThemeProvider({
4374
4361
  if (isDevelopment) {
4375
4362
  console.warn("\u{1F3A8} UnifiedTheme: Failed to load preset from storage:", error);
4376
4363
  }
4377
- } finally {
4378
- setIsReady(true);
4379
4364
  }
4380
- }, [presetStorageKey, enablePresets, defaultPreset, getAvailablePresetById]);
4365
+ }, [presetStorageKey, defaultPreset, getAvailablePresetById]);
4381
4366
  useEffect(() => {
4382
4367
  if (mode === "system") {
4383
4368
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -4456,7 +4441,7 @@ function ThemeProvider({
4456
4441
  (coordinates) => {
4457
4442
  const newMode = resolvedMode === "light" ? "dark" : "light";
4458
4443
  const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
4459
- if (enableTransitions && !prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
4444
+ if (!prefersReducedMotion && typeof document !== "undefined" && "startViewTransition" in document) {
4460
4445
  const root = document.documentElement;
4461
4446
  if (coordinates) {
4462
4447
  root.style.setProperty("--x", `${coordinates.x}px`);
@@ -4469,7 +4454,7 @@ function ThemeProvider({
4469
4454
  handleModeChange(newMode);
4470
4455
  }
4471
4456
  },
4472
- [resolvedMode, enableTransitions, handleModeChange]
4457
+ [resolvedMode, handleModeChange]
4473
4458
  );
4474
4459
  useEffect(() => {
4475
4460
  if (!currentPreset || typeof window === "undefined") return;
@@ -4484,7 +4469,7 @@ function ThemeProvider({
4484
4469
  appliedAt: Date.now()
4485
4470
  };
4486
4471
  setCurrentPreset(presetData);
4487
- if (enablePresets && typeof window !== "undefined") {
4472
+ if (typeof window !== "undefined") {
4488
4473
  try {
4489
4474
  localStorage.setItem(presetStorageKey, JSON.stringify(presetData));
4490
4475
  } catch (error) {
@@ -4495,7 +4480,7 @@ function ThemeProvider({
4495
4480
  applyPresetColors(preset.colors, resolvedMode);
4496
4481
  }
4497
4482
  },
4498
- [presetStorageKey, enablePresets, applyPresetColors, resolvedMode]
4483
+ [presetStorageKey, applyPresetColors, resolvedMode]
4499
4484
  );
4500
4485
  const setThemePresetById = useCallback(
4501
4486
  (presetId) => {
@@ -4519,53 +4504,50 @@ function ThemeProvider({
4519
4504
  [getAvailablePresetById, applyPreset]
4520
4505
  );
4521
4506
  const clearPreset = useCallback(() => {
4522
- if (enablePresets && typeof window !== "undefined") {
4507
+ if (typeof window !== "undefined") {
4523
4508
  try {
4524
4509
  localStorage.removeItem(presetStorageKey);
4525
4510
  } catch (error) {
4526
4511
  console.error("\u{1F3A8} UnifiedTheme: Failed to clear preset:", error);
4527
4512
  }
4528
- if (defaultPreset) {
4529
- const preset = getAvailablePresetById(defaultPreset);
4530
- if (preset) {
4531
- const presetData = {
4532
- presetId: defaultPreset,
4533
- presetName: preset.label,
4534
- colors: {
4535
- light: preset.styles.light,
4536
- dark: preset.styles.dark
4537
- },
4538
- appliedAt: Date.now()
4539
- };
4540
- setCurrentPreset(presetData);
4541
- applyPresetColors(presetData.colors, resolvedMode);
4542
- } else {
4543
- console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
4544
- setCurrentPreset(null);
4545
- }
4513
+ }
4514
+ if (defaultPreset) {
4515
+ const preset = getAvailablePresetById(defaultPreset);
4516
+ if (preset) {
4517
+ const presetData = {
4518
+ presetId: defaultPreset,
4519
+ presetName: preset.label,
4520
+ colors: {
4521
+ light: preset.styles.light,
4522
+ dark: preset.styles.dark
4523
+ },
4524
+ appliedAt: Date.now()
4525
+ };
4526
+ setCurrentPreset(presetData);
4527
+ applyPresetColors(presetData.colors, resolvedMode);
4546
4528
  } else {
4529
+ console.warn("\u{1F3A8} UnifiedTheme: Default preset not found:", defaultPreset);
4547
4530
  setCurrentPreset(null);
4548
- const root = document.documentElement;
4549
- const allProperties = [
4550
- ...CSS_PROPERTY_CATEGORIES.colors,
4551
- ...CSS_PROPERTY_CATEGORIES.typography,
4552
- ...CSS_PROPERTY_CATEGORIES.layout,
4553
- ...CSS_PROPERTY_CATEGORIES.shadows,
4554
- ...CSS_PROPERTY_CATEGORIES.spacing
4555
- ];
4556
- let clearedCount = 0;
4557
- allProperties.forEach((prop) => {
4558
- const cssVar = `--${prop}`;
4559
- root.style.removeProperty(cssVar);
4560
- clearedCount++;
4561
- });
4562
4531
  }
4532
+ } else {
4533
+ setCurrentPreset(null);
4534
+ const root = document.documentElement;
4535
+ const allProperties = [
4536
+ ...CSS_PROPERTY_CATEGORIES.colors,
4537
+ ...CSS_PROPERTY_CATEGORIES.typography,
4538
+ ...CSS_PROPERTY_CATEGORIES.layout,
4539
+ ...CSS_PROPERTY_CATEGORIES.shadows,
4540
+ ...CSS_PROPERTY_CATEGORIES.spacing
4541
+ ];
4542
+ let clearedCount = 0;
4543
+ allProperties.forEach((prop) => {
4544
+ const cssVar = `--${prop}`;
4545
+ root.style.removeProperty(cssVar);
4546
+ clearedCount++;
4547
+ });
4563
4548
  }
4564
- }, [presetStorageKey, enablePresets, defaultPreset, applyPresetColors, resolvedMode]);
4565
- const scriptElement = shouldInjectScript ? /* @__PURE__ */ jsx2(ThemeScript, { presetStorageKey, defaultPreset }) : null;
4566
- if (!isReady && shouldDeferRenderUntilReady) {
4567
- return scriptElement;
4568
- }
4549
+ }, [presetStorageKey, defaultPreset, getAvailablePresetById, applyPresetColors, resolvedMode]);
4550
+ const scriptElement = /* @__PURE__ */ jsx2(ThemeScript, { presetStorageKey, defaultPreset });
4569
4551
  const isUsingDefaultPreset = !!defaultPreset && currentPreset?.presetId === defaultPreset;
4570
4552
  const contextValue = {
4571
4553
  mode,
@@ -4821,7 +4803,7 @@ var AnimatedRow = ({
4821
4803
  }) => {
4822
4804
  if (presets.length === 0) return null;
4823
4805
  const duplicatedPresets = Array(animation.duplicationFactor).fill(presets).flat();
4824
- const totalWidth = presets.reduce((sum, preset) => sum + (Number(preset.metadata?.buttonWidth) || layout.buttonWidth), 0) + presets.length * layout.buttonGap;
4806
+ const totalWidth = presets.reduce((sum, preset) => sum + (Number(preset.metadata?.buttonWidth) || layout.buttonWidth), 0) + Math.max(0, presets.length - 1) * layout.buttonGap;
4825
4807
  const effectiveScrollSpeed = Math.max(0.1, animation.scrollSpeed || 1);
4826
4808
  const animationDuration = presets.length * animation.duration / effectiveScrollSpeed;
4827
4809
  return /* @__PURE__ */ jsx4(
@@ -5018,6 +5000,42 @@ function useTypedTheme(customPresets) {
5018
5000
  setThemePresetById
5019
5001
  };
5020
5002
  }
5003
+
5004
+ // src/hooks/useThemeEngine.ts
5005
+ function useThemeEngine() {
5006
+ const theme = useTheme();
5007
+ const darkMode = theme.resolvedMode === "dark";
5008
+ const setDarkMode = (mode) => theme.setMode(mode);
5009
+ const toggleDarkMode = (coordinates) => theme.toggleMode(coordinates);
5010
+ const applyThemeById = (themeId) => theme.setThemePresetById(themeId);
5011
+ const applyPresetById = applyThemeById;
5012
+ const clearTheme = () => theme.clearPreset();
5013
+ const clearPreset = clearTheme;
5014
+ const currentTheme = theme.currentPreset;
5015
+ const currentPreset = theme.currentPreset;
5016
+ return {
5017
+ // Mode
5018
+ darkMode,
5019
+ mode: theme.mode,
5020
+ resolvedMode: theme.resolvedMode,
5021
+ setDarkMode,
5022
+ setMode: theme.setMode,
5023
+ toggleDarkMode,
5024
+ toggleMode: theme.toggleMode,
5025
+ // Presets (theme naming)
5026
+ applyThemeById,
5027
+ applyPresetById,
5028
+ clearTheme,
5029
+ clearPreset,
5030
+ currentTheme,
5031
+ currentPreset,
5032
+ // Advanced / diagnostics
5033
+ isUsingDefaultPreset: theme.isUsingDefaultPreset,
5034
+ availablePresets: theme.availablePresets,
5035
+ builtInPresets: theme.builtInPresets,
5036
+ customPresets: theme.customPresets
5037
+ };
5038
+ }
5021
5039
  export {
5022
5040
  ThemePresetButtons,
5023
5041
  ThemeProvider,
@@ -5034,6 +5052,7 @@ export {
5034
5052
  searchPresets,
5035
5053
  tweakcnPresets,
5036
5054
  useTheme,
5055
+ useThemeEngine,
5037
5056
  useTypedTheme,
5038
5057
  validateCustomPresets,
5039
5058
  validateTweakCNPreset,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fakhrirafiki/theme-engine",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
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",