@shohojdhara/atomix 0.3.11 → 0.3.13

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 (34) hide show
  1. package/dist/atomix.css +15 -17
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +5 -15255
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/charts.js +94 -74
  6. package/dist/charts.js.map +1 -1
  7. package/dist/core.js +94 -74
  8. package/dist/core.js.map +1 -1
  9. package/dist/forms.js +94 -74
  10. package/dist/forms.js.map +1 -1
  11. package/dist/heavy.js +94 -74
  12. package/dist/heavy.js.map +1 -1
  13. package/dist/index.d.ts +9 -27
  14. package/dist/index.esm.js +163 -161
  15. package/dist/index.esm.js.map +1 -1
  16. package/dist/index.js +163 -161
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.min.js +1 -1
  19. package/dist/index.min.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/components/AtomixGlass/AtomixGlass.tsx +124 -127
  22. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +55 -62
  23. package/src/components/AtomixGlass/GlassFilter.tsx +15 -4
  24. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -2
  25. package/src/components/EdgePanel/EdgePanel.stories.tsx +2 -7
  26. package/src/components/EdgePanel/EdgePanel.tsx +0 -10
  27. package/src/components/Form/Radio.stories.tsx +235 -103
  28. package/src/components/Navigation/Nav/NavDropdown.tsx +8 -4
  29. package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -22
  30. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +11 -15
  31. package/src/lib/types/components.ts +2 -26
  32. package/src/styles/06-components/_components.atomix-glass.scss +14 -15
  33. package/src/styles/06-components/_components.edge-panel.scss +4 -4
  34. package/src/styles/06-components/_components.nav.scss +3 -0
package/dist/index.d.ts CHANGED
@@ -2343,19 +2343,7 @@ interface SideMenuProps extends BaseComponentProps {
2343
2343
  * <SideMenu LinkComponent={Link} />
2344
2344
  * ```
2345
2345
  */
2346
- LinkComponent?: React.ComponentType<{
2347
- href?: string;
2348
- to?: string;
2349
- children: React.ReactNode;
2350
- className?: string;
2351
- onClick?: (event: React.MouseEvent) => void;
2352
- target?: string;
2353
- rel?: string;
2354
- 'aria-disabled'?: boolean;
2355
- 'aria-current'?: string;
2356
- tabIndex?: number;
2357
- ref?: React.Ref<HTMLAnchorElement>;
2358
- }>;
2346
+ LinkComponent?: React.ElementType;
2359
2347
  /**
2360
2348
  * Menu items
2361
2349
  */
@@ -2437,19 +2425,7 @@ interface SideMenuItemProps extends BaseComponentProps {
2437
2425
  * <SideMenuItem href="/about" LinkComponent={Link}>About</SideMenuItem>
2438
2426
  * ```
2439
2427
  */
2440
- LinkComponent?: React.ComponentType<{
2441
- href?: string;
2442
- to?: string;
2443
- children: React.ReactNode;
2444
- className?: string;
2445
- onClick?: (event: React.MouseEvent) => void;
2446
- target?: string;
2447
- rel?: string;
2448
- 'aria-disabled'?: boolean;
2449
- 'aria-current'?: string;
2450
- tabIndex?: number;
2451
- ref?: React.Ref<HTMLAnchorElement>;
2452
- }>;
2428
+ LinkComponent?: React.ElementType;
2453
2429
  }
2454
2430
  /**
2455
2431
  * EdgePanel position options
@@ -12015,7 +11991,13 @@ declare const SideMenu: React__default.ForwardRefExoticComponent<SideMenuProps &
12015
11991
  * Click me
12016
11992
  * </SideMenuItem>
12017
11993
  *
12018
- * // With icon
11994
+ * // With icon and custom link component
11995
+ * import Link from 'next/link';
11996
+ * <SideMenuItem href="/settings" icon={<Icon name="Settings" />} LinkComponent={Link}>
11997
+ * Settings
11998
+ * </SideMenuItem>
11999
+ *
12000
+ * // With icon and custom link component
12019
12001
  * <SideMenuItem href="/settings" icon={<Icon name="Settings" />}>
12020
12002
  * Settings
12021
12003
  * </SideMenuItem>
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%",
@@ -1826,7 +1825,13 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
1826
1825
  */ GlassFilterComponent.displayName = "GlassFilter";
1827
1826
 
1828
1827
  // Memoize component to prevent unnecessary re-renders
1829
- const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
1828
+ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount));
1829
+
1830
+ // Module-level counter for deterministic ID generation
1831
+ let idCounter = 0;
1832
+
1833
+ // Module-level shared shader cache with LRU eviction
1834
+ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
1830
1835
  x: 0,
1831
1836
  y: 0
1832
1837
  }, globalMousePosition: globalMousePosition = {
@@ -1837,10 +1842,8 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1837
1842
  height: 0
1838
1843
  }, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
1839
1844
  // 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);
1845
+ // Use a module-level counter that's consistent across server and client
1846
+ const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
1844
1847
  // Lazy load shader utilities only when shader mode is needed
1845
1848
  useEffect((() => {
1846
1849
  "shader" === mode ?
@@ -1851,7 +1854,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1851
1854
  fragmentShaders: shaderUtils.fragmentShaders
1852
1855
  };
1853
1856
  })).catch((error => {
1854
- console.warn("AtomixGlassContainer: Error loading shader utilities", error);
1857
+ console.warn("AtomixGlassContainer: Error loading shader utilities", String(error).replace(/[\r\n]/g, ""));
1855
1858
  })) :
1856
1859
  // Clear shader utils when not in shader mode to free memory
1857
1860
  shaderUtilsRef.current = null;
@@ -1881,9 +1884,9 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1881
1884
  width: glassSize.width,
1882
1885
  height: glassSize.height,
1883
1886
  fragment: selectedShader
1884
- });
1885
- // Use requestIdleCallback if available for non-blocking generation
1886
- const generate = () => {
1887
+ }),
1888
+ // Defer shader generation with longer delay to avoid blocking
1889
+ setTimeout((() => {
1887
1890
  const url = shaderGeneratorRef.current?.updateShader() || "";
1888
1891
  ((key, url) => {
1889
1892
  // Evict oldest entries if at capacity
@@ -1902,20 +1905,15 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1902
1905
  // Development mode: log cache size
1903
1906
  "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
1904
1907
  })(cacheKey, url), setShaderMapUrl(url);
1905
- };
1906
- "undefined" != typeof requestIdleCallback ? requestIdleCallback(generate, {
1907
- timeout: 1e3
1908
- }) :
1909
- // Fallback to setTimeout for browsers without requestIdleCallback
1910
- setTimeout(generate, 0);
1908
+ }), 100);
1911
1909
  } catch (error) {
1912
1910
  console.warn("AtomixGlassContainer: Error generating shader map", error), setShaderMapUrl("");
1913
1911
  } else
1914
1912
  // Shader utils not loaded yet, retry after a short delay
1915
1913
  shaderDebounceTimeoutRef.current = setTimeout(generateShader, 100);
1916
1914
  };
1917
- // Debounce with 300ms delay
1918
- shaderDebounceTimeoutRef.current = setTimeout(generateShader, 300);
1915
+ // Debounce with 500ms delay to reduce frequency
1916
+ shaderDebounceTimeoutRef.current = setTimeout(generateShader, 500);
1919
1917
  } else
1920
1918
  // Not in shader mode, clear URL
1921
1919
  setShaderMapUrl("");
@@ -1982,7 +1980,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
1982
1980
  backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
1983
1981
  };
1984
1982
  }
1985
- }), [ filterId, liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveDisableEffects, enableLiquidBlur ]), containerVars = useMemo((() => {
1983
+ }), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveDisableEffects, enableLiquidBlur ]), containerVars = useMemo((() => {
1986
1984
  try {
1987
1985
  // Safe extraction of mouse offset values
1988
1986
  const mx = mouseOffset && "number" == typeof mouseOffset.x && !isNaN(mouseOffset.x) ? mouseOffset.x : 0, my = mouseOffset && "number" == typeof mouseOffset.y && !isNaN(mouseOffset.y) ? mouseOffset.y : 0;
@@ -2041,7 +2039,6 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
2041
2039
  shaderMapUrl: shaderMapUrl
2042
2040
  }), jsx("div", {
2043
2041
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
2044
- suppressHydrationWarning: !0,
2045
2042
  style: {
2046
2043
  filter: `url(#${filterId})`,
2047
2044
  backdropFilter: "var(--atomix-glass-container-backdrop)",
@@ -2072,7 +2069,6 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
2072
2069
  });
2073
2070
  }));
2074
2071
 
2075
- // Module-level shared shader cache with LRU eviction
2076
2072
  AtomixGlassContainer.displayName = "AtomixGlassContainer";
2077
2073
 
2078
2074
  // Singleton instance
@@ -2669,38 +2665,80 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2669
2665
  }, adjustedSize = {
2670
2666
  width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
2671
2667
  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
- };
2668
+ }, gradientValues = useMemo((() => {
2669
+ const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
2670
+ return {
2671
+ borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
2672
+ borderStop1: Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER),
2673
+ borderStop2: Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER),
2674
+ 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 ],
2675
+ hoverPositions: {
2676
+ hover1: {
2677
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
2678
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
2679
+ },
2680
+ hover2: {
2681
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
2682
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2
2683
+ },
2684
+ hover3: {
2685
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
2686
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3
2687
+ }
2688
+ },
2689
+ basePosition: {
2690
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
2691
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
2692
+ },
2693
+ mx: mx,
2694
+ my: my,
2695
+ absMx: absMx,
2696
+ absMy: absMy
2697
+ };
2698
+ }), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
2699
+ const overLightOpacity = overLightConfig.opacity;
2700
+ return {
2701
+ hover1: isHovered || isActive ? .5 : 0,
2702
+ hover2: isActive ? .5 : 0,
2703
+ hover3: isHovered ? .4 : isActive ? .8 : 0,
2704
+ base: isOverLight ? overLightOpacity || .4 : 0,
2705
+ over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
2706
+ };
2707
+ }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
2708
+ 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;
2709
+ return {
2710
+ "--atomix-glass-radius": `${effectiveCornerRadius}px`,
2711
+ "--atomix-glass-transform": transformStyle || "none",
2712
+ "--atomix-glass-position": positionStyles.position,
2713
+ "--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
2714
+ "--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
2715
+ "--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
2716
+ "--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
2717
+ "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
2718
+ "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
2719
+ "--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%)`,
2720
+ "--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%)`,
2721
+ "--atomix-glass-hover-1-opacity": opacityValues.hover1,
2722
+ "--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}%)`,
2723
+ "--atomix-glass-hover-2-opacity": opacityValues.hover2,
2724
+ "--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}%)`,
2725
+ "--atomix-glass-hover-3-opacity": opacityValues.hover3,
2726
+ "--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}%)`,
2727
+ "--atomix-glass-base-opacity": opacityValues.base,
2728
+ "--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})`,
2729
+ "--atomix-glass-overlay-opacity": opacityValues.over,
2730
+ "--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})`
2731
+ };
2732
+ }), [ gradientValues, opacityValues, effectiveCornerRadius, transformStyle, positionStyles, adjustedSize, style.position, isOverLight ]), renderBackgroundLayer = layerType => jsx("div", {
2733
+ 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(" "),
2734
+ style: {
2735
+ ...positionStyles,
2736
+ height: adjustedSize.height,
2737
+ width: adjustedSize.width,
2738
+ borderRadius: `${effectiveCornerRadius}px`,
2739
+ transform: baseStyle.transform
2740
+ }
2741
+ });
2704
2742
  return jsxs("div", {
2705
2743
  className: componentClassName,
2706
2744
  style: glassVars,
@@ -2756,25 +2794,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2756
2794
  }), jsx("div", {
2757
2795
  className: ATOMIX_GLASS.HOVER_3_CLASS
2758
2796
  }) ]
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, {
2797
+ }), renderBackgroundLayer("dark"), renderBackgroundLayer("black"), shouldRenderOverLightLayers && jsxs(Fragment, {
2778
2798
  children: [ jsx("div", {
2779
2799
  className: ATOMIX_GLASS.BASE_LAYER_CLASS
2780
2800
  }), jsx("div", {
@@ -10772,16 +10792,6 @@ const EdgePanel = ({title: title, children: children, position: position = "star
10772
10792
  className: "c-edge-panel__container",
10773
10793
  children: glass ? jsx(AtomixGlass, {
10774
10794
  ...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
10795
  children: jsx("div", {
10786
10796
  ref: glassContentRef,
10787
10797
  className: "c-edge-panel__glass-content",
@@ -14369,7 +14379,13 @@ SideMenuList.displayName = "SideMenuList";
14369
14379
  * Click me
14370
14380
  * </SideMenuItem>
14371
14381
  *
14372
- * // With icon
14382
+ * // With icon and custom link component
14383
+ * import Link from 'next/link';
14384
+ * <SideMenuItem href="/settings" icon={<Icon name="Settings" />} LinkComponent={Link}>
14385
+ * Settings
14386
+ * </SideMenuItem>
14387
+ *
14388
+ * // With icon and custom link component
14373
14389
  * <SideMenuItem href="/settings" icon={<Icon name="Settings" />}>
14374
14390
  * Settings
14375
14391
  * </SideMenuItem>
@@ -14381,16 +14397,14 @@ SideMenuList.displayName = "SideMenuList";
14381
14397
  * ```
14382
14398
  */
14383
14399
  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({
14400
+ const {generateSideMenuItemClass: generateSideMenuItemClass, handleClick: handleClick} = useSideMenuItem({
14385
14401
  active: active,
14386
14402
  disabled: disabled,
14387
14403
  className: className
14388
14404
  }), itemClass = generateSideMenuItemClass();
14389
- // Use LinkComponent from props first, then fall back to context
14390
- // Render as link if href is provided
14405
+ // Render as link if href is provided
14391
14406
  if (href) {
14392
- // When using a custom LinkComponent (e.g., Next.js Link, React Router Link)
14393
- if (LinkComponent) {
14407
+ if (LinkComponentProp) {
14394
14408
  const linkProps = {
14395
14409
  ref: ref,
14396
14410
  className: itemClass,
@@ -14402,16 +14416,12 @@ const SideMenuItem = forwardRef((({children: children, href: href, onClick: onC
14402
14416
  target: target,
14403
14417
  rel: rel,
14404
14418
  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
14419
  ...disabled ? {} : {
14408
14420
  href: href,
14409
14421
  to: href
14410
14422
  }
14411
14423
  };
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, {
14424
+ return jsxs(LinkComponentProp, {
14415
14425
  ...linkProps,
14416
14426
  children: [ icon && jsx("span", {
14417
14427
  className: "c-side-menu__link-icon",
@@ -14466,8 +14476,6 @@ const SideMenuItem = forwardRef((({children: children, href: href, onClick: onC
14466
14476
 
14467
14477
  SideMenuItem.displayName = "SideMenuItem";
14468
14478
 
14469
- // Context for passing LinkComponent to SideMenuItem children
14470
- const SideMenuContext = createContext({}), useSideMenuContext = () => useContext(SideMenuContext)
14471
14479
  /**
14472
14480
  * SideMenu component provides a collapsible navigation menu with title and menu items.
14473
14481
  * Automatically collapses on mobile devices and can be toggled via a header button.
@@ -14482,7 +14490,8 @@ const SideMenuContext = createContext({}), useSideMenuContext = () => useContex
14482
14490
  * </SideMenuList>
14483
14491
  * </SideMenu>
14484
14492
  * ```
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) => {
14493
+ */
14494
+ 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
14495
  const {isOpenState: isOpenState, wrapperRef: wrapperRef, innerRef: innerRef, sideMenuRef: sideMenuRef, generateSideMenuClass: generateSideMenuClass, generateWrapperClass: generateWrapperClass, handleToggle: handleToggle} = useSideMenu({
14487
14496
  isOpen: isOpen,
14488
14497
  onToggle: onToggle,
@@ -14587,68 +14596,63 @@ const SideMenuContext = createContext({}), useSideMenuContext = () => useContex
14587
14596
  className: wrapperClass,
14588
14597
  id: id ? `${id}-content` : void 0,
14589
14598
  "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", {
14599
+ children: jsxs("div", {
14600
+ ref: innerRef,
14601
+ className: "c-side-menu__inner",
14602
+ children: [ children, menuItems?.map(((item, index) => {
14603
+ const isNestedItemOpen = nestedItemStates[index] ?? !0, hasItems = item.items && item.items.length > 0, canToggle = hasItems && !disabled, handleNestedToggle = () => {
14604
+ canToggle && setNestedItemStates((prev => ({
14605
+ ...prev,
14606
+ [index]: !prev[index]
14607
+ })));
14608
+ };
14609
+ return jsxs("div", {
14610
+ className: "c-side-menu__item",
14611
+ children: [ item.title && jsxs("div", {
14612
+ className: [ "c-side-menu__toggler", canToggle && "c-side-menu__toggler--nested", isNestedItemOpen && "is-open" ].filter(Boolean).join(" "),
14613
+ onClick: canToggle ? handleNestedToggle : void 0,
14614
+ role: canToggle ? "button" : void 0,
14615
+ tabIndex: canToggle && !disabled ? 0 : void 0,
14616
+ "aria-expanded": canToggle ? isNestedItemOpen : void 0,
14617
+ "aria-disabled": disabled,
14618
+ onKeyDown: canToggle ? e => {
14619
+ "Enter" !== e.key && " " !== e.key || disabled || (e.preventDefault(), handleNestedToggle());
14620
+ } : void 0,
14621
+ children: [ jsx("span", {
14622
+ className: "c-side-menu__title",
14623
+ children: item.title
14624
+ }), canToggle && jsx("span", {
14625
+ className: "c-side-menu__toggler-icon",
14626
+ children: item.toggleIcon || jsx(Icon, {
14627
+ name: "CaretRight",
14628
+ size: "xs"
14629
+ })
14630
+ }) ]
14631
+ }), hasItems && jsx("div", {
14632
+ ref: node => {
14633
+ nestedWrapperRefs.current[index] = node;
14634
+ },
14635
+ className: "c-side-menu__nested-wrapper",
14636
+ children: jsx("div", {
14627
14637
  ref: node => {
14628
- nestedWrapperRefs.current[index] = node;
14638
+ nestedInnerRefs.current[index] = node;
14629
14639
  },
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
- })
14640
+ className: "c-side-menu__nested-inner",
14641
+ children: jsx(SideMenuList, {
14642
+ children: item.items?.map(((subItem, subIndex) => jsx(SideMenuItem, {
14643
+ href: subItem.href,
14644
+ onClick: subItem.onClick,
14645
+ active: subItem.active,
14646
+ disabled: subItem.disabled,
14647
+ icon: subItem.icon,
14648
+ LinkComponent: LinkComponent,
14649
+ children: subItem.title
14650
+ }, subIndex)))
14647
14651
  })
14648
- }) ]
14649
- }, index);
14650
- })) ]
14651
- })
14652
+ })
14653
+ }) ]
14654
+ }, index);
14655
+ })) ]
14652
14656
  })
14653
14657
  }) ]
14654
14658
  });
@@ -14682,7 +14686,6 @@ const SideMenuContext = createContext({}), useSideMenuContext = () => useContex
14682
14686
  });
14683
14687
  }));
14684
14688
 
14685
- // Hook to use SideMenu context
14686
14689
  SideMenu.displayName = "SideMenu";
14687
14690
 
14688
14691
  const Menu = forwardRef((({children: children, className: className = "", style: style, disabled: disabled = !1}, ref) => jsx("div", {
@@ -14878,14 +14881,13 @@ const NavDropdown = forwardRef((({title: title, children: children, alignment:
14878
14881
  size: "sm",
14879
14882
  className: "c-nav__icon"
14880
14883
  }) ]
14881
- }), menuContent = jsx("div", {
14884
+ }), menuContent = jsx(megaMenu ? "div" : "ul", {
14882
14885
  className: dropdownMenuClass,
14883
14886
  ref: dropdownRef,
14884
14887
  "aria-hidden": !isActive,
14885
14888
  children: children
14886
14889
  });
14887
- // Create the dropdown/mega menu content
14888
- return jsxs(NavItem, {
14890
+ return jsxs(NavItem, {
14889
14891
  dropdown: !megaMenu,
14890
14892
  megaMenu: megaMenu,
14891
14893
  disabled: disabled,