@shohojdhara/atomix 0.3.11 → 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.
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%",
@@ -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,