@shohojdhara/atomix 0.3.10 → 0.3.12

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/atomix.css +9 -6
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +9 -6
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.js +82 -60
  7. package/dist/charts.js.map +1 -1
  8. package/dist/core.js +82 -60
  9. package/dist/core.js.map +1 -1
  10. package/dist/forms.js +82 -60
  11. package/dist/forms.js.map +1 -1
  12. package/dist/heavy.js +82 -60
  13. package/dist/heavy.js.map +1 -1
  14. package/dist/index.d.ts +11 -107
  15. package/dist/index.esm.js +165 -407
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +169 -412
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.min.js +1 -1
  20. package/dist/index.min.js.map +1 -1
  21. package/dist/theme.d.ts +1 -32
  22. package/dist/theme.js +12 -207
  23. package/dist/theme.js.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/AtomixGlass/AtomixGlass.tsx +124 -127
  26. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +28 -32
  27. package/src/components/AtomixGlass/GlassFilter.tsx +15 -4
  28. package/src/components/EdgePanel/EdgePanel.stories.tsx +2 -7
  29. package/src/components/EdgePanel/EdgePanel.tsx +0 -10
  30. package/src/components/Form/Radio.stories.tsx +235 -103
  31. package/src/components/Navigation/Nav/NavDropdown.tsx +8 -4
  32. package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -22
  33. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +11 -15
  34. package/src/lib/config/index.ts +5 -5
  35. package/src/lib/theme/config/index.ts +1 -1
  36. package/src/lib/theme/core/createTheme.ts +11 -40
  37. package/src/lib/theme/generators/index.ts +1 -4
  38. package/src/lib/theme/index.ts +4 -16
  39. package/src/lib/theme/runtime/ThemeProvider.tsx +1 -16
  40. package/src/lib/types/components.ts +2 -26
  41. package/src/styles/06-components/_components.edge-panel.scss +4 -4
  42. package/src/styles/06-components/_components.nav.scss +3 -0
  43. package/src/lib/config/loader.ts +0 -147
  44. package/src/lib/theme/config/__tests__/configLoader.test.ts +0 -207
  45. package/src/lib/theme/config/configLoader.ts +0 -113
  46. package/src/lib/theme/config/loader.ts +0 -293
  47. package/src/lib/theme/generators/cssFile.ts +0 -79
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
 
3
- import React, { useState, useRef, useEffect, memo, forwardRef, useId, useMemo, useCallback, Children, isValidElement, cloneElement, createContext, useContext, useImperativeHandle, Component } from "react";
3
+ import React, { useState, useRef, useEffect, memo, forwardRef, useMemo, useCallback, useId, Children, isValidElement, cloneElement, createContext, useContext, useImperativeHandle, Component } from "react";
4
4
 
5
5
  import * as PhosphorIcons from "@phosphor-icons/react";
6
6
 
@@ -1692,7 +1692,6 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
1692
1692
  inset: 0
1693
1693
  },
1694
1694
  "aria-hidden": "true",
1695
- suppressHydrationWarning: !0,
1696
1695
  children: jsxs("defs", {
1697
1696
  children: [ jsxs("radialGradient", {
1698
1697
  id: `${id}-edge-mask`,
@@ -1720,7 +1719,7 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
1720
1719
  height: "170%",
1721
1720
  colorInterpolationFilters: "sRGB",
1722
1721
  children: [ jsx("feImage", {
1723
- id: "feimage",
1722
+ id: `${id}-image`,
1724
1723
  x: "0",
1725
1724
  y: "0",
1726
1725
  width: "100%",
@@ -1837,10 +1836,10 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1837
1836
  height: 0
1838
1837
  }, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
1839
1838
  // Generate a stable, deterministic ID for SSR compatibility
1840
- // React's useId() should produce the same ID on server and client for the same
1841
- // component position in the tree. We use useState to ensure the ID is only
1842
- // generated once and remains stable across renders.
1843
- const baseId = useId(), [filterId] = useState((() => `atomix-glass-filter-${baseId.replace(/:/g, "-").replace(/^[^a-z]/i, "atomix-")}`)), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
1839
+ // Use a counter-based approach to avoid hydration mismatches
1840
+ const [filterId] = useState((() =>
1841
+ // Use a simple counter for deterministic IDs
1842
+ "undefined" == typeof window ? `atomix-glass-filter-ssr-${Math.random().toString(36).substring(2, 11)}` : `atomix-glass-filter-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`)), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
1844
1843
  // Lazy load shader utilities only when shader mode is needed
1845
1844
  useEffect((() => {
1846
1845
  "shader" === mode ?
@@ -1851,7 +1850,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1851
1850
  fragmentShaders: shaderUtils.fragmentShaders
1852
1851
  };
1853
1852
  })).catch((error => {
1854
- console.warn("AtomixGlassContainer: Error loading shader utilities", error);
1853
+ console.warn("AtomixGlassContainer: Error loading shader utilities", String(error).replace(/[\r\n]/g, ""));
1855
1854
  })) :
1856
1855
  // Clear shader utils when not in shader mode to free memory
1857
1856
  shaderUtilsRef.current = null;
@@ -2041,7 +2040,6 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
2041
2040
  shaderMapUrl: shaderMapUrl
2042
2041
  }), jsx("div", {
2043
2042
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
2044
- suppressHydrationWarning: !0,
2045
2043
  style: {
2046
2044
  filter: `url(#${filterId})`,
2047
2045
  backdropFilter: "var(--atomix-glass-container-backdrop)",
@@ -2669,38 +2667,80 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2669
2667
  }, adjustedSize = {
2670
2668
  width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
2671
2669
  height: "fixed" !== style.position ? "100%" : style.height ? style.height : Math.max(glassSize.height, 0)
2672
- }, mx = mouseOffset.x, my = mouseOffset.y, GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), borderOpacity1 = GRADIENT.BORDER_OPACITY.BASE_1 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity2 = GRADIENT.BORDER_OPACITY.BASE_2 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, borderOpacity3 = GRADIENT.BORDER_OPACITY.BASE_3 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity4 = GRADIENT.BORDER_OPACITY.BASE_4 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, hover1X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1, hover1Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1, hover2X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2, hover2Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2, hover3X = GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3, hover3Y = GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3, baseX = GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER, baseY = GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER, overLightOpacity = overLightConfig.opacity, opacityValues = {
2673
- hover1: isHovered || isActive ? .5 : 0,
2674
- hover2: isActive ? .5 : 0,
2675
- hover3: isHovered ? .4 : isActive ? .8 : 0,
2676
- base: isOverLight ? overLightOpacity || .4 : 0,
2677
- over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
2678
- }, whiteColor = "255, 255, 255", glassVars = {
2679
- // Standard CSS custom properties for dynamic values
2680
- "--atomix-glass-radius": `${effectiveCornerRadius}px`,
2681
- "--atomix-glass-transform": transformStyle || "none",
2682
- "--atomix-glass-position": positionStyles.position,
2683
- "--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
2684
- "--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
2685
- "--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
2686
- "--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
2687
- // Border width: Use spacing token for consistency
2688
- "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
2689
- "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
2690
- // Dynamic gradients and backgrounds
2691
- "--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacity1}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacity2}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
2692
- "--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacity3}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacity4}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
2693
- "--atomix-glass-hover-1-opacity": opacityValues.hover1,
2694
- "--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hover1X}% ${hover1Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hover1X}% ${hover1Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
2695
- "--atomix-glass-hover-2-opacity": opacityValues.hover2,
2696
- "--atomix-glass-hover-2-gradient": isOverLight ? `radial-gradient(circle at ${hover2X}% ${hover2Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hover2X}% ${hover2Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
2697
- "--atomix-glass-hover-3-opacity": opacityValues.hover3,
2698
- "--atomix-glass-hover-3-gradient": isOverLight ? `radial-gradient(circle at ${hover3X}% ${hover3Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${hover3X}% ${hover3Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
2699
- "--atomix-glass-base-opacity": opacityValues.base,
2700
- "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + Math.abs(mx) * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
2701
- "--atomix-glass-overlay-opacity": opacityValues.over,
2702
- "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${baseX}% ${baseY}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + Math.abs(mx) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + Math.abs(my) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
2703
- };
2670
+ }, gradientValues = useMemo((() => {
2671
+ const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
2672
+ return {
2673
+ borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
2674
+ borderStop1: Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER),
2675
+ borderStop2: Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER),
2676
+ borderOpacities: [ GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH ],
2677
+ hoverPositions: {
2678
+ hover1: {
2679
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
2680
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
2681
+ },
2682
+ hover2: {
2683
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
2684
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2
2685
+ },
2686
+ hover3: {
2687
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
2688
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3
2689
+ }
2690
+ },
2691
+ basePosition: {
2692
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
2693
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
2694
+ },
2695
+ mx: mx,
2696
+ my: my,
2697
+ absMx: absMx,
2698
+ absMy: absMy
2699
+ };
2700
+ }), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
2701
+ const overLightOpacity = overLightConfig.opacity;
2702
+ return {
2703
+ hover1: isHovered || isActive ? .5 : 0,
2704
+ hover2: isActive ? .5 : 0,
2705
+ hover3: isHovered ? .4 : isActive ? .8 : 0,
2706
+ base: isOverLight ? overLightOpacity || .4 : 0,
2707
+ over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
2708
+ };
2709
+ }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
2710
+ const whiteColor = "255, 255, 255", {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues;
2711
+ return {
2712
+ "--atomix-glass-radius": `${effectiveCornerRadius}px`,
2713
+ "--atomix-glass-transform": transformStyle || "none",
2714
+ "--atomix-glass-position": positionStyles.position,
2715
+ "--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
2716
+ "--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
2717
+ "--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
2718
+ "--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
2719
+ "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
2720
+ "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
2721
+ "--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacities[0]}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacities[1]}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
2722
+ "--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacities[2]}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacities[3]}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
2723
+ "--atomix-glass-hover-1-opacity": opacityValues.hover1,
2724
+ "--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
2725
+ "--atomix-glass-hover-2-opacity": opacityValues.hover2,
2726
+ "--atomix-glass-hover-2-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
2727
+ "--atomix-glass-hover-3-opacity": opacityValues.hover3,
2728
+ "--atomix-glass-hover-3-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
2729
+ "--atomix-glass-base-opacity": opacityValues.base,
2730
+ "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
2731
+ "--atomix-glass-overlay-opacity": opacityValues.over,
2732
+ "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
2733
+ };
2734
+ }), [ gradientValues, opacityValues, effectiveCornerRadius, transformStyle, positionStyles, adjustedSize, style.position, isOverLight ]), renderBackgroundLayer = layerType => jsx("div", {
2735
+ className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" "),
2736
+ style: {
2737
+ ...positionStyles,
2738
+ height: adjustedSize.height,
2739
+ width: adjustedSize.width,
2740
+ borderRadius: `${effectiveCornerRadius}px`,
2741
+ transform: baseStyle.transform
2742
+ }
2743
+ });
2704
2744
  return jsxs("div", {
2705
2745
  className: componentClassName,
2706
2746
  style: glassVars,
@@ -2756,25 +2796,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2756
2796
  }), jsx("div", {
2757
2797
  className: ATOMIX_GLASS.HOVER_3_CLASS
2758
2798
  }) ]
2759
- }), jsx("div", {
2760
- className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" "),
2761
- style: {
2762
- ...positionStyles,
2763
- height: adjustedSize.height,
2764
- width: adjustedSize.width,
2765
- borderRadius: `${effectiveCornerRadius}px`,
2766
- transform: baseStyle.transform
2767
- }
2768
- }), jsx("div", {
2769
- className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" "),
2770
- style: {
2771
- ...positionStyles,
2772
- height: adjustedSize.height,
2773
- width: adjustedSize.width,
2774
- borderRadius: `${effectiveCornerRadius}px`,
2775
- transform: baseStyle.transform
2776
- }
2777
- }), shouldRenderOverLightLayers && jsxs(Fragment, {
2799
+ }), renderBackgroundLayer("dark"), renderBackgroundLayer("black"), shouldRenderOverLightLayers && jsxs(Fragment, {
2778
2800
  children: [ jsx("div", {
2779
2801
  className: ATOMIX_GLASS.BASE_LAYER_CLASS
2780
2802
  }), jsx("div", {
@@ -10772,16 +10794,6 @@ const EdgePanel = ({title: title, children: children, position: position = "star
10772
10794
  className: "c-edge-panel__container",
10773
10795
  children: glass ? jsx(AtomixGlass, {
10774
10796
  ...glassProps,
10775
- className: "c-edge-panel__glass-wrapper",
10776
- style: {
10777
- position: "fixed",
10778
- width: glassContentRef.current?.offsetWidth,
10779
- height: glassContentRef.current?.offsetHeight,
10780
- top: containerRef.current?.offsetTop,
10781
- left: containerRef.current?.offsetLeft,
10782
- bottom: containerRef.current?.style.bottom,
10783
- right: containerRef.current?.style.right
10784
- },
10785
10797
  children: jsx("div", {
10786
10798
  ref: glassContentRef,
10787
10799
  className: "c-edge-panel__glass-content",
@@ -14369,7 +14381,13 @@ SideMenuList.displayName = "SideMenuList";
14369
14381
  * Click me
14370
14382
  * </SideMenuItem>
14371
14383
  *
14372
- * // With icon
14384
+ * // With icon and custom link component
14385
+ * import Link from 'next/link';
14386
+ * <SideMenuItem href="/settings" icon={<Icon name="Settings" />} LinkComponent={Link}>
14387
+ * Settings
14388
+ * </SideMenuItem>
14389
+ *
14390
+ * // With icon and custom link component
14373
14391
  * <SideMenuItem href="/settings" icon={<Icon name="Settings" />}>
14374
14392
  * Settings
14375
14393
  * </SideMenuItem>
@@ -14381,16 +14399,14 @@ SideMenuList.displayName = "SideMenuList";
14381
14399
  * ```
14382
14400
  */
14383
14401
  const SideMenuItem = forwardRef((({children: children, href: href, onClick: onClick, active: active = !1, disabled: disabled = !1, icon: icon, className: className = "", target: target, rel: rel, LinkComponent: LinkComponentProp}, ref) => {
14384
- const {LinkComponent: LinkComponentFromContext} = useSideMenuContext(), LinkComponent = LinkComponentProp ?? LinkComponentFromContext, {generateSideMenuItemClass: generateSideMenuItemClass, handleClick: handleClick} = useSideMenuItem({
14402
+ const {generateSideMenuItemClass: generateSideMenuItemClass, handleClick: handleClick} = useSideMenuItem({
14385
14403
  active: active,
14386
14404
  disabled: disabled,
14387
14405
  className: className
14388
14406
  }), itemClass = generateSideMenuItemClass();
14389
- // Use LinkComponent from props first, then fall back to context
14390
- // Render as link if href is provided
14407
+ // Render as link if href is provided
14391
14408
  if (href) {
14392
- // When using a custom LinkComponent (e.g., Next.js Link, React Router Link)
14393
- if (LinkComponent) {
14409
+ if (LinkComponentProp) {
14394
14410
  const linkProps = {
14395
14411
  ref: ref,
14396
14412
  className: itemClass,
@@ -14402,16 +14418,12 @@ const SideMenuItem = forwardRef((({children: children, href: href, onClick: onC
14402
14418
  target: target,
14403
14419
  rel: rel,
14404
14420
  tabIndex: disabled ? -1 : 0,
14405
- // Support both Next.js (href) and React Router (to) Link components
14406
- // Pass both props - the Link component will use whichever it needs
14407
14421
  ...disabled ? {} : {
14408
14422
  href: href,
14409
14423
  to: href
14410
14424
  }
14411
14425
  };
14412
- // Build link props - support both 'href' (Next.js) and 'to' (React Router)
14413
- // The Link component will use whichever prop it needs
14414
- return jsxs(LinkComponent, {
14426
+ return jsxs(LinkComponentProp, {
14415
14427
  ...linkProps,
14416
14428
  children: [ icon && jsx("span", {
14417
14429
  className: "c-side-menu__link-icon",
@@ -14466,8 +14478,6 @@ const SideMenuItem = forwardRef((({children: children, href: href, onClick: onC
14466
14478
 
14467
14479
  SideMenuItem.displayName = "SideMenuItem";
14468
14480
 
14469
- // Context for passing LinkComponent to SideMenuItem children
14470
- const SideMenuContext = createContext({}), useSideMenuContext = () => useContext(SideMenuContext)
14471
14481
  /**
14472
14482
  * SideMenu component provides a collapsible navigation menu with title and menu items.
14473
14483
  * Automatically collapses on mobile devices and can be toggled via a header button.
@@ -14482,7 +14492,8 @@ const SideMenuContext = createContext({}), useSideMenuContext = () => useContex
14482
14492
  * </SideMenuList>
14483
14493
  * </SideMenu>
14484
14494
  * ```
14485
- */ , SideMenu = forwardRef((({title: title, children: children, menuItems: menuItems = [], isOpen: isOpen, onToggle: onToggle, collapsible: collapsible = !0, collapsibleDesktop: collapsibleDesktop = !1, defaultCollapsedDesktop: defaultCollapsedDesktop = !1, className: className = "", style: style, disabled: disabled = !1, toggleIcon: toggleIcon, id: id, glass: glass, LinkComponent: LinkComponent}, ref) => {
14495
+ */
14496
+ const SideMenu = forwardRef((({title: title, children: children, menuItems: menuItems = [], isOpen: isOpen, onToggle: onToggle, collapsible: collapsible = !0, collapsibleDesktop: collapsibleDesktop = !1, defaultCollapsedDesktop: defaultCollapsedDesktop = !1, className: className = "", style: style, disabled: disabled = !1, toggleIcon: toggleIcon, id: id, glass: glass, LinkComponent: LinkComponent}, ref) => {
14486
14497
  const {isOpenState: isOpenState, wrapperRef: wrapperRef, innerRef: innerRef, sideMenuRef: sideMenuRef, generateSideMenuClass: generateSideMenuClass, generateWrapperClass: generateWrapperClass, handleToggle: handleToggle} = useSideMenu({
14487
14498
  isOpen: isOpen,
14488
14499
  onToggle: onToggle,
@@ -14587,68 +14598,63 @@ const SideMenuContext = createContext({}), useSideMenuContext = () => useContex
14587
14598
  className: wrapperClass,
14588
14599
  id: id ? `${id}-content` : void 0,
14589
14600
  "aria-hidden": !!shouldShowToggler && !isOpenState,
14590
- children: jsx(SideMenuContext.Provider, {
14591
- value: {
14592
- LinkComponent: LinkComponent
14593
- },
14594
- children: jsxs("div", {
14595
- ref: innerRef,
14596
- className: "c-side-menu__inner",
14597
- children: [ children, menuItems?.map(((item, index) => {
14598
- const isNestedItemOpen = nestedItemStates[index] ?? !0, hasItems = item.items && item.items.length > 0, canToggle = hasItems && !disabled, handleNestedToggle = () => {
14599
- canToggle && setNestedItemStates((prev => ({
14600
- ...prev,
14601
- [index]: !prev[index]
14602
- })));
14603
- };
14604
- return jsxs("div", {
14605
- className: "c-side-menu__item",
14606
- children: [ item.title && jsxs("div", {
14607
- className: [ "c-side-menu__toggler", canToggle && "c-side-menu__toggler--nested", isNestedItemOpen && "is-open" ].filter(Boolean).join(" "),
14608
- onClick: canToggle ? handleNestedToggle : void 0,
14609
- role: canToggle ? "button" : void 0,
14610
- tabIndex: canToggle && !disabled ? 0 : void 0,
14611
- "aria-expanded": canToggle ? isNestedItemOpen : void 0,
14612
- "aria-disabled": disabled,
14613
- onKeyDown: canToggle ? e => {
14614
- "Enter" !== e.key && " " !== e.key || disabled || (e.preventDefault(), handleNestedToggle());
14615
- } : void 0,
14616
- children: [ jsx("span", {
14617
- className: "c-side-menu__title",
14618
- children: item.title
14619
- }), canToggle && jsx("span", {
14620
- className: "c-side-menu__toggler-icon",
14621
- children: item.toggleIcon || jsx(Icon, {
14622
- name: "CaretRight",
14623
- size: "xs"
14624
- })
14625
- }) ]
14626
- }), hasItems && jsx("div", {
14601
+ children: jsxs("div", {
14602
+ ref: innerRef,
14603
+ className: "c-side-menu__inner",
14604
+ children: [ children, menuItems?.map(((item, index) => {
14605
+ const isNestedItemOpen = nestedItemStates[index] ?? !0, hasItems = item.items && item.items.length > 0, canToggle = hasItems && !disabled, handleNestedToggle = () => {
14606
+ canToggle && setNestedItemStates((prev => ({
14607
+ ...prev,
14608
+ [index]: !prev[index]
14609
+ })));
14610
+ };
14611
+ return jsxs("div", {
14612
+ className: "c-side-menu__item",
14613
+ children: [ item.title && jsxs("div", {
14614
+ className: [ "c-side-menu__toggler", canToggle && "c-side-menu__toggler--nested", isNestedItemOpen && "is-open" ].filter(Boolean).join(" "),
14615
+ onClick: canToggle ? handleNestedToggle : void 0,
14616
+ role: canToggle ? "button" : void 0,
14617
+ tabIndex: canToggle && !disabled ? 0 : void 0,
14618
+ "aria-expanded": canToggle ? isNestedItemOpen : void 0,
14619
+ "aria-disabled": disabled,
14620
+ onKeyDown: canToggle ? e => {
14621
+ "Enter" !== e.key && " " !== e.key || disabled || (e.preventDefault(), handleNestedToggle());
14622
+ } : void 0,
14623
+ children: [ jsx("span", {
14624
+ className: "c-side-menu__title",
14625
+ children: item.title
14626
+ }), canToggle && jsx("span", {
14627
+ className: "c-side-menu__toggler-icon",
14628
+ children: item.toggleIcon || jsx(Icon, {
14629
+ name: "CaretRight",
14630
+ size: "xs"
14631
+ })
14632
+ }) ]
14633
+ }), hasItems && jsx("div", {
14634
+ ref: node => {
14635
+ nestedWrapperRefs.current[index] = node;
14636
+ },
14637
+ className: "c-side-menu__nested-wrapper",
14638
+ children: jsx("div", {
14627
14639
  ref: node => {
14628
- nestedWrapperRefs.current[index] = node;
14640
+ nestedInnerRefs.current[index] = node;
14629
14641
  },
14630
- className: "c-side-menu__nested-wrapper",
14631
- children: jsx("div", {
14632
- ref: node => {
14633
- nestedInnerRefs.current[index] = node;
14634
- },
14635
- className: "c-side-menu__nested-inner",
14636
- children: jsx(SideMenuList, {
14637
- children: item.items?.map(((subItem, subIndex) => jsx(SideMenuItem, {
14638
- href: subItem.href,
14639
- onClick: subItem.onClick,
14640
- active: subItem.active,
14641
- disabled: subItem.disabled,
14642
- icon: subItem.icon,
14643
- LinkComponent: LinkComponent,
14644
- children: subItem.title
14645
- }, subIndex)))
14646
- })
14642
+ className: "c-side-menu__nested-inner",
14643
+ children: jsx(SideMenuList, {
14644
+ children: item.items?.map(((subItem, subIndex) => jsx(SideMenuItem, {
14645
+ href: subItem.href,
14646
+ onClick: subItem.onClick,
14647
+ active: subItem.active,
14648
+ disabled: subItem.disabled,
14649
+ icon: subItem.icon,
14650
+ LinkComponent: LinkComponent,
14651
+ children: subItem.title
14652
+ }, subIndex)))
14647
14653
  })
14648
- }) ]
14649
- }, index);
14650
- })) ]
14651
- })
14654
+ })
14655
+ }) ]
14656
+ }, index);
14657
+ })) ]
14652
14658
  })
14653
14659
  }) ]
14654
14660
  });
@@ -14682,7 +14688,6 @@ const SideMenuContext = createContext({}), useSideMenuContext = () => useContex
14682
14688
  });
14683
14689
  }));
14684
14690
 
14685
- // Hook to use SideMenu context
14686
14691
  SideMenu.displayName = "SideMenu";
14687
14692
 
14688
14693
  const Menu = forwardRef((({children: children, className: className = "", style: style, disabled: disabled = !1}, ref) => jsx("div", {
@@ -14878,14 +14883,13 @@ const NavDropdown = forwardRef((({title: title, children: children, alignment:
14878
14883
  size: "sm",
14879
14884
  className: "c-nav__icon"
14880
14885
  }) ]
14881
- }), menuContent = jsx("div", {
14886
+ }), menuContent = jsx(megaMenu ? "div" : "ul", {
14882
14887
  className: dropdownMenuClass,
14883
14888
  ref: dropdownRef,
14884
14889
  "aria-hidden": !isActive,
14885
14890
  children: children
14886
14891
  });
14887
- // Create the dropdown/mega menu content
14888
- return jsxs(NavItem, {
14892
+ return jsxs(NavItem, {
14889
14893
  dropdown: !megaMenu,
14890
14894
  megaMenu: megaMenu,
14891
14895
  disabled: disabled,
@@ -19255,39 +19259,13 @@ class ThemeLogger {
19255
19259
  tokens = input;
19256
19260
  }
19257
19261
  // Merge with defaults and generate CSS
19258
- else {
19259
- // Check if we're in a browser environment
19260
- if ("undefined" != typeof window) throw new ThemeError("No input provided and config loading is not available in browser environment. Please provide tokens explicitly or use Node.js/SSR environment.", ThemeErrorCode.CONFIG_LOAD_FAILED, {
19261
- environment: "browser"
19262
- });
19263
- // Load from config when no input provided
19264
- let loadThemeFromConfigSync, loadAtomixConfig;
19265
- try {
19266
- const configLoaderModule = require("../config/configLoader"), loaderModule = require("../../config/loader");
19267
- // Get prefix from config if needed
19268
- if (loadThemeFromConfigSync = configLoaderModule.loadThemeFromConfigSync, loadAtomixConfig = loaderModule.loadAtomixConfig,
19269
- tokens = loadThemeFromConfigSync(), !options?.prefix) try {
19270
- const config = loadAtomixConfig({
19271
- configPath: "atomix.config.ts",
19272
- required: !1
19273
- });
19274
- options = {
19275
- ...options,
19276
- prefix: config?.prefix || "atomix"
19277
- };
19278
- } catch (error) {
19279
- // If config loading fails, use default prefix
19280
- options = {
19281
- ...options,
19282
- prefix: "atomix"
19283
- };
19284
- }
19285
- } catch (error) {
19286
- throw new ThemeError("No input provided and config loading is not available in this environment. Please provide tokens explicitly.", ThemeErrorCode.CONFIG_LOAD_FAILED, {
19287
- error: error instanceof Error ? error.message : String(error)
19288
- });
19289
- }
19290
- }
19262
+ else
19263
+ // Auto-loading config from file system is removed for browser compatibility.
19264
+ // If no input is provided, we return an empty theme (using defaults only) or user must provide tokens.
19265
+ // This allows createTheme to be isomorphic.
19266
+ // Warn in development if no input provided
19267
+ "production" !== process.env.NODE_ENV && "undefined" != typeof window && console.warn("Atomix: createTheme() called without tokens. Using default tokens only."),
19268
+ tokens = {};
19291
19269
  const allTokens = createTokens(tokens), prefix = options?.prefix ?? "atomix";
19292
19270
  // Get prefix from options or use default
19293
19271
  return generateCSSVariables$1(allTokens, {
@@ -19520,24 +19498,12 @@ class ThemeLogger {
19520
19498
  }
19521
19499
 
19522
19500
  /**
19523
- * CSS File Utilities
19501
+ * Theme System Constants
19524
19502
  *
19525
- * Save CSS to file system (Node.js only).
19503
+ * Centralized constants for the theme system to avoid magic numbers and strings.
19526
19504
  */
19527
19505
  /**
19528
- * Save CSS to file
19529
- *
19530
- * Writes CSS string to a file. Only works in Node.js environment.
19531
- *
19532
- * @param css - CSS string to save
19533
- * @param filePath - Output file path
19534
- * @throws Error if called in browser environment
19535
- *
19536
- * @example
19537
- * ```typescript
19538
- * const css = ':root { --atomix-color-primary: #7AFFD7; }';
19539
- * await saveCSSFile(css, './themes/custom.css');
19540
- * ```
19506
+ * Default storage key for theme persistence
19541
19507
  */ "undefined" != typeof process && process.env;
19542
19508
 
19543
19509
  /**
@@ -20314,176 +20280,6 @@ function generateClassName(block, element, modifiers) {
20314
20280
  return property => getComponentThemeValue(component, property, variant, size);
20315
20281
  }
20316
20282
 
20317
- /**
20318
- * Atomix Config Loader
20319
- *
20320
- * Helper functions to load atomix.config.ts from external projects.
20321
- * Similar to how Tailwind loads tailwind.config.js
20322
- */
20323
- /**
20324
- * Load Atomix configuration from project root
20325
- *
20326
- * Attempts to load atomix.config.ts from the current working directory.
20327
- * Falls back to default config if file doesn't exist.
20328
- *
20329
- * @param options - Loader options
20330
- * @returns Loaded configuration or default
20331
- *
20332
- * @example
20333
- * ```typescript
20334
- * import { loadAtomixConfig } from '@shohojdhara/atomix/config';
20335
- * import { createTheme } from '@shohojdhara/atomix/theme';
20336
- *
20337
- * const config = loadAtomixConfig();
20338
- * const theme = createTheme(config.theme?.tokens || {});
20339
- * ```
20340
- */ function loadAtomixConfig(options = {}) {
20341
- const {configPath: configPath = "atomix.config.ts", required: required = !1} = options, defaultConfig = {
20342
- prefix: "atomix",
20343
- theme: {
20344
- extend: {}
20345
- }
20346
- };
20347
- // Default config
20348
- // In browser environments, config loading is not supported
20349
- if ("undefined" != typeof window) {
20350
- if (required) throw new Error("loadAtomixConfig: Not available in browser environment. Config loading requires Node.js/SSR environment.");
20351
- return defaultConfig;
20352
- }
20353
- // Try to load config file
20354
- try {
20355
- // Use dynamic import for ESM compatibility
20356
- const configModule = require(configPath), config = configModule.default || configModule;
20357
- // Validate it's an AtomixConfig
20358
- if (config && "object" == typeof config) return config;
20359
- throw new Error("Invalid config format");
20360
- } catch (error) {
20361
- if (required) throw new Error(`Failed to load config from ${configPath}: ${error.message}`);
20362
- // Return default config if not required
20363
- return defaultConfig;
20364
- }
20365
- }
20366
-
20367
- /**
20368
- * Resolve config path
20369
- *
20370
- * Finds atomix.config.ts in the project, checking common locations.
20371
- * Returns null in browser environments where file system access is not available.
20372
- *
20373
- * This function is designed to work in Node.js environments only.
20374
- * In browser builds, it will always return null without attempting to access Node.js modules.
20375
- *
20376
- * @internal This function uses Node.js modules and should not be called in browser environments.
20377
- */ function resolveConfigPath() {
20378
- // Early return for browser environments - prevents any Node.js module access
20379
- // This check happens before any require() calls, preventing bundlers from analyzing them
20380
- if ("undefined" != typeof window || "undefined" == typeof process || !process.cwd) return null;
20381
- // Only attempt to load Node.js modules in Node.js runtime
20382
- // Use a lazy-loading pattern that prevents static analysis by bundlers
20383
- try {
20384
- // Create a function that only executes in Node.js runtime
20385
- // Use string-based module names to prevent static analysis by bundlers
20386
- const modules = (() => {
20387
- // These requires are only executed at runtime in Node.js environments
20388
- // They are marked as external in Rollup config and should not be bundled
20389
- // Using string concatenation and computed property access to prevent static analysis
20390
- if ("undefined" == typeof require) return null;
20391
- // Use a try-catch wrapper to safely access require
20392
- try {
20393
- // Build module names dynamically to prevent static analysis
20394
- const moduleNames = [ "fs", "path" ];
20395
- // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
20396
- return {
20397
- fs: require(moduleNames[0]),
20398
- path: require(moduleNames[1])
20399
- };
20400
- } catch {
20401
- return null;
20402
- }
20403
- })();
20404
- if (!modules) return null;
20405
- const {fs: fs, path: path} = modules, cwd = process.cwd(), possiblePaths = [ path.join(cwd, "atomix.config.ts"), path.join(cwd, "atomix.config.js"), path.join(cwd, "atomix.config.mjs") ];
20406
- for (const configPath of possiblePaths) if (fs.existsSync(configPath)) return configPath;
20407
- } catch (error) {
20408
- // Silently fail in browser environments or when modules are unavailable
20409
- return null;
20410
- }
20411
- return null;
20412
- }
20413
-
20414
- /**
20415
- * Theme Configuration Loader
20416
- *
20417
- * Provides functions to load theme configurations from atomix.config.ts
20418
- * Includes both sync and async versions, with automatic fallbacks
20419
- */
20420
- /**
20421
- * Load theme from config file (synchronous, Node.js only)
20422
- * @param configPath - Path to config file (default: atomix.config.ts)
20423
- * @returns DesignTokens from theme configuration
20424
- * @throws Error if config loading is not available in browser environment
20425
- */ function loadThemeFromConfigSync(options) {
20426
- // Check if we're in a browser environment
20427
- if ("undefined" != typeof window) throw new Error("loadThemeFromConfigSync: Not available in browser environment. Config loading requires Node.js/SSR environment.");
20428
- // Use static import - the function handles browser environment checks internally
20429
- let config;
20430
- try {
20431
- config = loadAtomixConfig({
20432
- configPath: options?.configPath || "atomix.config.ts",
20433
- required: !1 !== options?.required
20434
- });
20435
- } catch (error) {
20436
- if (!1 !== options?.required) throw new Error("Config loader module not available");
20437
- // Return empty tokens if config is not required
20438
- return createTokens({});
20439
- }
20440
- if (!config?.theme) return createTokens({});
20441
- // Extract tokens from config.theme structure
20442
- // config.theme can have: { extend?: ThemeTokens, tokens?: ThemeTokens, themes?: ... }
20443
- // We need to extract the actual DesignTokens (flat structure)
20444
- const themeConfig = config.theme;
20445
- // Check if theme is directly a flat object (DesignTokens format)
20446
- // This handles the case where config.theme might be passed as DesignTokens directly
20447
- return createTokens(!themeConfig || "object" != typeof themeConfig || "extend" in themeConfig || "tokens" in themeConfig || "themes" in themeConfig ? {} : themeConfig);
20448
- // If theme has nested structure (extend/tokens/themes), we can't directly use it
20449
- // Return empty tokens - the theme system will use defaults
20450
- // TODO: Add proper conversion from ThemeTokens to DesignTokens if needed
20451
- }
20452
-
20453
- /**
20454
- * Load theme from config file (asynchronous)
20455
- * @param configPath - Path to config file (default: atomix.config.ts)
20456
- * @returns Promise resolving to DesignTokens from theme configuration
20457
- */ async function loadThemeFromConfig(options) {
20458
- // Check if we're in a browser environment
20459
- if ("undefined" != typeof window) throw new Error("loadThemeFromConfig: Not available in browser environment. Config loading requires Node.js/SSR environment.");
20460
- // Use static import with runtime check
20461
- // The function will handle browser environment checks internally
20462
- let config;
20463
- try {
20464
- // loadAtomixConfig is synchronous, not async
20465
- config = loadAtomixConfig({
20466
- configPath: options?.configPath || "atomix.config.ts",
20467
- required: !1 !== options?.required
20468
- });
20469
- } catch (error) {
20470
- if (!1 !== options?.required) throw new Error("Config loader module not available");
20471
- // Return empty tokens if config is not required
20472
- return createTokens({});
20473
- }
20474
- if (!config?.theme) return createTokens({});
20475
- // Extract tokens from config.theme structure
20476
- // config.theme can have: { extend?: ThemeTokens, tokens?: ThemeTokens, themes?: ... }
20477
- // We need to extract the actual DesignTokens (flat structure)
20478
- const themeConfig = config.theme;
20479
- // Check if theme is directly a flat object (DesignTokens format)
20480
- // This handles the case where config.theme might be passed as DesignTokens directly
20481
- return createTokens(!themeConfig || "object" != typeof themeConfig || "extend" in themeConfig || "tokens" in themeConfig || "themes" in themeConfig ? {} : themeConfig);
20482
- // If theme has nested structure (extend/tokens/themes), we can't directly use it
20483
- // Return empty tokens - the theme system will use defaults
20484
- // TODO: Add proper conversion from ThemeTokens to DesignTokens if needed
20485
- }
20486
-
20487
20283
  /**
20488
20284
  * Theme Context
20489
20285
  *
@@ -20525,21 +20321,9 @@ const ThemeProvider = ({children: children, defaultTheme: defaultTheme, themes:
20525
20321
  if (stored) return stored;
20526
20322
  }
20527
20323
  // If defaultTheme is provided, use it
20528
- if (null != defaultTheme) return defaultTheme;
20529
- // Try to load from atomix.config.ts as fallback, but only in Node.js/SSR environments
20530
- if ("undefined" == typeof window) try {
20531
- // Dynamically import the config loader to avoid bundling issues in browser
20532
- // eslint-disable-next-line @typescript-eslint/no-var-requires
20533
- const {loadThemeFromConfigSync: loadThemeFromConfigSync} = require("../config/configLoader"), configTokens = loadThemeFromConfigSync();
20534
- if (configTokens && Object.keys(configTokens).length > 0)
20535
- // For simplicity, we'll treat config tokens as a special theme name
20536
- return "config-theme";
20537
- } catch (error) {
20538
- // Failed to load theme from config, using default
20539
- }
20324
+ return null != defaultTheme ? defaultTheme : "default";
20540
20325
  // Default fallback
20541
- return "default";
20542
- }), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() =>
20326
+ }), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() =>
20543
20327
  // If defaultTheme is DesignTokens, store them
20544
20328
  defaultTheme && "string" != typeof defaultTheme ? createTokens(defaultTheme) : null)), [isLoading, setIsLoading] = useState(!1), [error, setError] = useState(null), loadedThemesRef = useRef(new Set), themePromisesRef = useRef({}), abortControllerRef = useRef(null);
20545
20329
  // Handle initial DesignTokens defaultTheme
@@ -23530,6 +23314,7 @@ class RTLManager {
23530
23314
  // Core Theme Functions
23531
23315
  // ============================================================================
23532
23316
  // Create theme CSS from DesignTokens
23317
+ // File saving utilities removed to prevent bundling Node.js modules in browser
23533
23318
  /**
23534
23319
  * Inject theme CSS into DOM
23535
23320
  */ function injectTheme(css, id = "atomix-theme") {
@@ -23542,30 +23327,6 @@ class RTLManager {
23542
23327
  removeCSS(id);
23543
23328
  }
23544
23329
 
23545
- /**
23546
- * Save theme to CSS file
23547
- */ async function saveTheme(css, filePath) {
23548
- await async function(css, filePath) {
23549
- // Check if in browser environment
23550
- if ("undefined" != typeof window) throw new Error("saveCSSFile can only be used in Node.js environment. Use injectCSS() for browser environments.");
23551
- // Dynamic import to avoid bundling Node.js modules in browser builds
23552
- const fs = await import("fs/promises"), dir = (await import("path")).dirname(filePath);
23553
- await fs.mkdir(dir, {
23554
- recursive: !0
23555
- }),
23556
- // Write file
23557
- await fs.writeFile(filePath, css, "utf8");
23558
- }
23559
- /**
23560
- * Theme System Constants
23561
- *
23562
- * Centralized constants for the theme system to avoid magic numbers and strings.
23563
- */
23564
- /**
23565
- * Default storage key for theme persistence
23566
- */ (css, filePath);
23567
- }
23568
-
23569
23330
  const themeImport = Object.freeze( Object.defineProperty({
23570
23331
  __proto__: null,
23571
23332
  RTLManager: RTLManager,
@@ -23610,8 +23371,6 @@ const themeImport = Object.freeze( Object.defineProperty({
23610
23371
  isCSSInjected: isCSSInjected,
23611
23372
  isDesignTokens: isDesignTokens,
23612
23373
  isValidCSSVariableName: isValidCSSVariableName,
23613
- loadThemeFromConfig: loadThemeFromConfig,
23614
- loadThemeFromConfigSync: loadThemeFromConfigSync,
23615
23374
  mapSCSSTokensToCSSVars: mapSCSSTokensToCSSVars,
23616
23375
  mergeCSSVars: mergeCSSVars,
23617
23376
  mergeTheme: mergeTheme,
@@ -23620,7 +23379,6 @@ const themeImport = Object.freeze( Object.defineProperty({
23620
23379
  removeCSS: removeCSS,
23621
23380
  removeCSSVariables: removeCSSVariables,
23622
23381
  removeTheme: removeTheme,
23623
- saveTheme: saveTheme,
23624
23382
  themePropertyToCSSVar: themePropertyToCSSVar,
23625
23383
  unregisterTheme: unregisterTheme,
23626
23384
  useComponentTheme: useComponentTheme,
@@ -24247,5 +24005,5 @@ const atomix = {
24247
24005
  types: types
24248
24006
  };
24249
24007
 
24250
- export { ACCORDION, ATOMIX_GLASS, AVATAR, AVATAR_GROUP, Accordion, AnimatedChart, AreaChart, AtomixGlass, AtomixLogo, Avatar, AvatarGroup, BADGE, BADGE_CSS_VARS, BLOCK, BREADCRUMB, BUTTON, BUTTON_CSS_VARS, BUTTON_GROUP, Badge, BarChart, Block, Breadcrumb, BubbleChart, Button, ButtonGroup, CALLOUT, CARD, CARD_CSS_VARS, CHART, CHECKBOX_CSS_VARS, CLASS_PREFIX, CODE_SNIPPET, COMPONENT_CSS_VARS, COUNTDOWN, Callout, CandlestickChart, Card, Chart, ChartRenderer, Checkbox, ColorModeToggle, Container, Countdown, DATA_TABLE_CLASSES, DATA_TABLE_SELECTORS, DATEPICKER, DEFAULT_ATOMIX_FONTS, DOTS, DROPDOWN, DROPDOWN_CSS_VARS, DataTable, DatePicker, DonutChart, Dropdown, EDGE_PANEL, EdgePanel, ElevationCard, FOOTER, FORM, FORM_GROUP, Footer, FooterLink, FooterSection, FooterSocialLink, Form, FormGroup, FunnelChart, GLASS_CONTAINER, GaugeChart, Grid, GridCol, HERO, HeatmapChart, Hero, INPUT, INPUT_CSS_VARS, Icon, Input, LIST, LIST_GROUP, LineChart, List, ListGroup, MESSAGES, MODAL, MODAL_CSS_VARS, MasonryGrid, MasonryGridItem, MegaMenu, MegaMenuColumn, MegaMenuLink, Menu, MenuDivider, MenuItem, Messages, Modal, MultiAxisChart, NAV, NAVBAR, Nav, NavDropdown, NavItem, Navbar, PAGINATION_DEFAULTS, PHOTOVIEWER, POPOVER, PROGRESS, PROGRESS_CSS_VARS, Pagination, PhotoViewer, PieChart, Popover, ProductReview, Progress, RADIO, RADIO_CSS_VARS, RATING, RIVER, RTLManager, RadarChart, Radio, Rating, River, Row, SECTION_INTRO, SELECT, SIDE_MENU, SIZES, SLIDER, SPINNER, STEPS, ScatterChart, SectionIntro, Select, SideMenu, SideMenuItem, SideMenuList, Slider, Spinner, Steps, TAB, TABS_CSS_VARS, TESTIMONIAL, TEXTAREA, THEME_COLORS, THEME_NAMING, TODO, TOGGLE, TOOLTIP, TOOLTIP_CSS_VARS, Tabs, Testimonial, Textarea, ThemeApplicator, ThemeComparator, ThemeContext, ThemeErrorBoundary, ThemeInspector, ThemeLiveEditor, ThemePreview, ThemeProvider, ThemeValidator, Todo, Toggle, Tooltip, TreemapChart, UPLOAD, Upload, VIDEO_PLAYER, VideoPlayer, WaterfallChart, applyCSSVariables, applyCSSVarsToStyle, applyComponentTheme, applyPartStyles, applyTheme, camelToKebab, clearThemes, composables, constants, createCSSVarStyle, createDarkVariant, createDebugAttrs, createFontPreloadLink, createPartProps, createSlotComponent, createSlotProps, createTheme, createThemeRegistry, createTokens, cssVarsToStyle, deepMerge, atomix as default, defaultTokens, defineConfig, designTokensToCSSVars, exportTheme, extendTheme, extractComponentName, extractYouTubeId, generateCSSVariableName, generateCSSVariables$1 as generateCSSVariables, generateCSSVariablesForSelector, generateClassName, generateComponentCSSVars, generateFontPreloadTags, generateUUID, getAllThemes, getCSSVariable, getComponentCSSVars, getComponentThemeValue, getPartStyles, getTheme, getThemeApplicator, getThemeCount, getThemeIds, getThemeMetadata, hasCustomization, hasTheme, importTheme, injectCSS$1 as injectCSS, injectTheme, isCSSInjected, isDesignTokens, isSlot, isValidCSSVariableName, isYouTubeUrl, loadAtomixConfig, loadThemeFromConfig, loadThemeFromConfigSync, mapSCSSTokensToCSSVars, mergeCSSVars, mergeClassNames, mergeComponentProps, mergePartStyles, mergeSlots, mergeTheme, normalizeThemeTokens, preloadFonts, quickTheme, registerTheme, removeCSS, removeCSSVariables, removeTheme, renderSlot, resolveConfigPath, saveTheme, sliderConstants, supportsDarkMode, theme, themePropertyToCSSVar, themeToCSS, types, unregisterTheme, useAccordion, useAtomixGlass, useBadge, useBarChart, useBlock, useBreadcrumb, useButton, useCard, useChartData, useChartInteraction, useChartScale, useCheckbox, useComponentCustomization, useComponentDefaultProps, useComponentTheme, useDataTable, useEdgePanel, useForm, useFormGroup, useGlassContainer, useHero, useHistory, useInput, useLineChart, useMergedProps, useModal$1 as useModal, useNav, useNavDropdown, useNavItem, useNavbar, usePagination, usePieChart, useRadio, useRiver, useSelect, useSideMenu, useSideMenuItem, useSlider, useSlot, useSpinner, useTextarea, useTheme, useThemeTokens, useTodo, utils, validateTheme };
24008
+ export { ACCORDION, ATOMIX_GLASS, AVATAR, AVATAR_GROUP, Accordion, AnimatedChart, AreaChart, AtomixGlass, AtomixLogo, Avatar, AvatarGroup, BADGE, BADGE_CSS_VARS, BLOCK, BREADCRUMB, BUTTON, BUTTON_CSS_VARS, BUTTON_GROUP, Badge, BarChart, Block, Breadcrumb, BubbleChart, Button, ButtonGroup, CALLOUT, CARD, CARD_CSS_VARS, CHART, CHECKBOX_CSS_VARS, CLASS_PREFIX, CODE_SNIPPET, COMPONENT_CSS_VARS, COUNTDOWN, Callout, CandlestickChart, Card, Chart, ChartRenderer, Checkbox, ColorModeToggle, Container, Countdown, DATA_TABLE_CLASSES, DATA_TABLE_SELECTORS, DATEPICKER, DEFAULT_ATOMIX_FONTS, DOTS, DROPDOWN, DROPDOWN_CSS_VARS, DataTable, DatePicker, DonutChart, Dropdown, EDGE_PANEL, EdgePanel, ElevationCard, FOOTER, FORM, FORM_GROUP, Footer, FooterLink, FooterSection, FooterSocialLink, Form, FormGroup, FunnelChart, GLASS_CONTAINER, GaugeChart, Grid, GridCol, HERO, HeatmapChart, Hero, INPUT, INPUT_CSS_VARS, Icon, Input, LIST, LIST_GROUP, LineChart, List, ListGroup, MESSAGES, MODAL, MODAL_CSS_VARS, MasonryGrid, MasonryGridItem, MegaMenu, MegaMenuColumn, MegaMenuLink, Menu, MenuDivider, MenuItem, Messages, Modal, MultiAxisChart, NAV, NAVBAR, Nav, NavDropdown, NavItem, Navbar, PAGINATION_DEFAULTS, PHOTOVIEWER, POPOVER, PROGRESS, PROGRESS_CSS_VARS, Pagination, PhotoViewer, PieChart, Popover, ProductReview, Progress, RADIO, RADIO_CSS_VARS, RATING, RIVER, RTLManager, RadarChart, Radio, Rating, River, Row, SECTION_INTRO, SELECT, SIDE_MENU, SIZES, SLIDER, SPINNER, STEPS, ScatterChart, SectionIntro, Select, SideMenu, SideMenuItem, SideMenuList, Slider, Spinner, Steps, TAB, TABS_CSS_VARS, TESTIMONIAL, TEXTAREA, THEME_COLORS, THEME_NAMING, TODO, TOGGLE, TOOLTIP, TOOLTIP_CSS_VARS, Tabs, Testimonial, Textarea, ThemeApplicator, ThemeComparator, ThemeContext, ThemeErrorBoundary, ThemeInspector, ThemeLiveEditor, ThemePreview, ThemeProvider, ThemeValidator, Todo, Toggle, Tooltip, TreemapChart, UPLOAD, Upload, VIDEO_PLAYER, VideoPlayer, WaterfallChart, applyCSSVariables, applyCSSVarsToStyle, applyComponentTheme, applyPartStyles, applyTheme, camelToKebab, clearThemes, composables, constants, createCSSVarStyle, createDarkVariant, createDebugAttrs, createFontPreloadLink, createPartProps, createSlotComponent, createSlotProps, createTheme, createThemeRegistry, createTokens, cssVarsToStyle, deepMerge, atomix as default, defaultTokens, defineConfig, designTokensToCSSVars, exportTheme, extendTheme, extractComponentName, extractYouTubeId, generateCSSVariableName, generateCSSVariables$1 as generateCSSVariables, generateCSSVariablesForSelector, generateClassName, generateComponentCSSVars, generateFontPreloadTags, generateUUID, getAllThemes, getCSSVariable, getComponentCSSVars, getComponentThemeValue, getPartStyles, getTheme, getThemeApplicator, getThemeCount, getThemeIds, getThemeMetadata, hasCustomization, hasTheme, importTheme, injectCSS$1 as injectCSS, injectTheme, isCSSInjected, isDesignTokens, isSlot, isValidCSSVariableName, isYouTubeUrl, mapSCSSTokensToCSSVars, mergeCSSVars, mergeClassNames, mergeComponentProps, mergePartStyles, mergeSlots, mergeTheme, normalizeThemeTokens, preloadFonts, quickTheme, registerTheme, removeCSS, removeCSSVariables, removeTheme, renderSlot, sliderConstants, supportsDarkMode, theme, themePropertyToCSSVar, themeToCSS, types, unregisterTheme, useAccordion, useAtomixGlass, useBadge, useBarChart, useBlock, useBreadcrumb, useButton, useCard, useChartData, useChartInteraction, useChartScale, useCheckbox, useComponentCustomization, useComponentDefaultProps, useComponentTheme, useDataTable, useEdgePanel, useForm, useFormGroup, useGlassContainer, useHero, useHistory, useInput, useLineChart, useMergedProps, useModal$1 as useModal, useNav, useNavDropdown, useNavItem, useNavbar, usePagination, usePieChart, useRadio, useRiver, useSelect, useSideMenu, useSideMenuItem, useSlider, useSlot, useSpinner, useTextarea, useTheme, useThemeTokens, useTodo, utils, validateTheme };
24251
24009
  //# sourceMappingURL=index.esm.js.map