@shohojdhara/atomix 0.4.5 → 0.4.7

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 (54) hide show
  1. package/dist/atomix.css +70 -33
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +2 -2
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/charts.d.ts +93 -109
  6. package/dist/charts.js +273 -371
  7. package/dist/charts.js.map +1 -1
  8. package/dist/core.js +183 -184
  9. package/dist/core.js.map +1 -1
  10. package/dist/forms.js +183 -184
  11. package/dist/forms.js.map +1 -1
  12. package/dist/heavy.js +183 -184
  13. package/dist/heavy.js.map +1 -1
  14. package/dist/index.d.ts +7 -51
  15. package/dist/index.esm.js +281 -470
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +287 -476
  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/package.json +1 -1
  22. package/src/components/AtomixGlass/AtomixGlass.tsx +60 -38
  23. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +6 -35
  24. package/src/components/AtomixGlass/glass-utils.ts +27 -14
  25. package/src/components/AtomixGlass/stories/Overview.stories.tsx +19 -21
  26. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1162 -515
  27. package/src/components/AtomixGlass/stories/shared-components.tsx +11 -3
  28. package/src/components/Chart/BubbleChart.tsx +6 -2
  29. package/src/components/Chart/Chart.stories.tsx +108 -96
  30. package/src/components/Chart/ChartToolbar.tsx +6 -4
  31. package/src/components/Chart/ChartTooltip.tsx +5 -4
  32. package/src/components/Chart/GaugeChart.tsx +20 -12
  33. package/src/components/Chart/HeatmapChart.tsx +53 -23
  34. package/src/components/Chart/TreemapChart.tsx +44 -15
  35. package/src/components/Chart/index.ts +0 -2
  36. package/src/components/Chart/types.ts +4 -4
  37. package/src/components/Navigation/Navbar/Navbar.tsx +13 -5
  38. package/src/components/index.ts +0 -1
  39. package/src/lib/composables/index.ts +1 -2
  40. package/src/lib/composables/useAtomixGlass.ts +246 -222
  41. package/src/lib/composables/useAtomixGlassStyles.ts +46 -23
  42. package/src/lib/constants/components.ts +3 -1
  43. package/src/styles/01-settings/_settings.chart.scss +13 -13
  44. package/src/styles/06-components/_components.atomix-glass.scss +45 -20
  45. package/src/styles/06-components/_components.chart.scss +23 -5
  46. package/src/components/Chart/AnimatedChart.tsx +0 -230
  47. package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +0 -329
  48. package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +0 -82
  49. package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +0 -153
  50. package/src/lib/composables/atomix-glass/useGlassOverLight.ts +0 -198
  51. package/src/lib/composables/atomix-glass/useGlassState.ts +0 -112
  52. package/src/lib/composables/atomix-glass/useGlassTransforms.ts +0 -160
  53. package/src/lib/composables/glass-styles.ts +0 -302
  54. package/src/lib/composables/useGlassContainer.ts +0 -177
package/dist/index.js CHANGED
@@ -1753,7 +1753,9 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
1753
1753
  ENABLE_OVER_LIGHT_LAYERS: !0
1754
1754
  },
1755
1755
  CONSTANTS: {
1756
- ACTIVATION_ZONE: 200,
1756
+ ACTIVATION_ZONE: 350,
1757
+ LERP_FACTOR: .08,
1758
+ SMOOTHSTEP_POWER: 2.5,
1757
1759
  MIN_BLUR: .1,
1758
1760
  MOUSE_INFLUENCE_DIVISOR: 100,
1759
1761
  EDGE_FADE_PIXELS: 2,
@@ -2048,7 +2050,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
2048
2050
  // Silently handle errors
2049
2051
  }
2050
2052
  return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
2051
- }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
2053
+ }, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
2052
2054
  switch (mode) {
2053
2055
  case "standard":
2054
2056
  return displacementMap;
@@ -2408,20 +2410,12 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
2408
2410
  onClick: onClick,
2409
2411
  children: jsxRuntime.jsxs("div", {
2410
2412
  className: ATOMIX_GLASS.INNER_CLASS,
2411
- style: {
2412
- padding: "var(--atomix-glass-container-padding)",
2413
- boxShadow: "var(--atomix-glass-container-box-shadow)"
2414
- },
2415
2413
  onMouseEnter: onMouseEnter,
2416
2414
  onMouseLeave: onMouseLeave,
2417
2415
  onMouseDown: onMouseDown,
2418
2416
  onMouseUp: onMouseUp,
2419
2417
  children: [ jsxRuntime.jsxs("div", {
2420
2418
  className: ATOMIX_GLASS.FILTER_CLASS,
2421
- style: {
2422
- position: "absolute",
2423
- inset: 0
2424
- },
2425
2419
  children: [ jsxRuntime.jsx(GlassFilter, {
2426
2420
  blurAmount: blurAmount,
2427
2421
  mode: mode,
@@ -2436,26 +2430,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
2436
2430
  },
2437
2431
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
2438
2432
  style: {
2439
- filter: `url(#${filterId})`,
2440
- backdropFilter: "var(--atomix-glass-container-backdrop)",
2441
- borderRadius: "var(--atomix-glass-container-radius)"
2433
+ filter: `url(#${filterId})`
2442
2434
  }
2443
2435
  }), jsxRuntime.jsx("div", {
2444
- className: ATOMIX_GLASS.FILTER_SHADOW_CLASS,
2445
- style: {
2446
- boxShadow: "var(--atomix-glass-container-shadow)",
2447
- opacity: "var(--atomix-glass-container-shadow-opacity)",
2448
- background: "var(--atomix-glass-container-bg)",
2449
- borderRadius: "var(--atomix-glass-container-radius)"
2450
- }
2436
+ className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
2451
2437
  }) ]
2452
2438
  }), jsxRuntime.jsx("div", {
2453
2439
  ref: contentRef,
2454
2440
  className: ATOMIX_GLASS.CONTENT_CLASS,
2455
- style: {
2456
- position: "relative",
2457
- textShadow: "var(--atomix-glass-container-text-shadow)"
2458
- },
2459
2441
  children: children
2460
2442
  }) ]
2461
2443
  })
@@ -2559,31 +2541,39 @@ class {
2559
2541
  saturationBoost: baseOverLightConfig.saturationBoost
2560
2542
  };
2561
2543
  // Calculate mouse influence
2562
- // Calculate elastic translation
2563
- let elasticTranslation = {
2544
+ let computedDirectionalScale = directionalScale, elasticTranslation = {
2564
2545
  x: 0,
2565
2546
  y: 0
2566
2547
  };
2567
- if (!effectiveWithoutEffects && wrapperElement) {
2548
+ // Calculate elastic translation and directional scale
2549
+ if (!effectiveWithoutEffects && wrapperElement) {
2568
2550
  const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
2569
- // Calculate fade in factor
2570
- let fadeInFactor = 0;
2551
+ // Mouse presence and edge distance logic
2571
2552
  if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
2572
- const edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
2553
+ const deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
2573
2554
  x: edgeDistanceX,
2574
2555
  y: edgeDistanceY
2575
2556
  }, {
2576
2557
  x: 0,
2577
2558
  y: 0
2578
- });
2579
- fadeInFactor = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
2559
+ }), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
2560
+ const clamped = Math.max(0, Math.min(1, t));
2561
+ return clamped * clamped * (3 - 2 * clamped);
2562
+ })(rawT);
2563
+ // Directional scale
2564
+ if (elasticTranslation = {
2565
+ x: deltaX * elasticity * .1 * fadeInFactor,
2566
+ y: deltaY * elasticity * .1 * fadeInFactor
2567
+ }, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
2568
+ const centerDistance = calculateDistance(globalMousePosition, center);
2569
+ if (centerDistance > 0) {
2570
+ const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15, softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), .2), softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), .2);
2571
+ computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
2572
+ }
2573
+ }
2580
2574
  }
2581
- elasticTranslation = {
2582
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
2583
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
2584
- };
2585
2575
  }
2586
- const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`;
2576
+ const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : computedDirectionalScale}`;
2587
2577
  // Update Wrapper Styles (glassVars)
2588
2578
  if (wrapperElement) {
2589
2579
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), 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), 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 ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
@@ -2690,7 +2680,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2690
2680
  }), internalMouseOffsetRef = React.useRef({
2691
2681
  x: 0,
2692
2682
  y: 0
2693
- }), [dynamicBorderRadius, setDynamicCornerRadius] = React.useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = React.useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = React.useState(!1), [detectedOverLight, setDetectedOverLight] = React.useState(!1), effectiveBorderRadius = React.useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
2683
+ }), targetMouseOffsetRef = React.useRef({
2684
+ x: 0,
2685
+ y: 0
2686
+ }), targetGlobalMousePositionRef = React.useRef({
2687
+ x: 0,
2688
+ y: 0
2689
+ }), lerpRafRef = React.useRef(null), lerpActiveRef = React.useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = React.useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = React.useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = React.useState(!1), [detectedOverLight, setDetectedOverLight] = React.useState(!1), effectiveBorderRadius = React.useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
2694
2690
  const [glassSize, setGlassSize] = React.useState({
2695
2691
  width: 270,
2696
2692
  height: 69
@@ -2787,7 +2783,23 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2787
2783
  const timeoutId = setTimeout(extractRadius, 100);
2788
2784
  return () => clearTimeout(timeoutId);
2789
2785
  }), [ children, debugBorderRadius, contentRef ]),
2790
- // Media query handlers and background detection
2786
+ // Media query detection for reduced motion and high contrast
2787
+ React.useEffect((() => {
2788
+ if ("undefined" == typeof window || "function" != typeof window.matchMedia) return;
2789
+ const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
2790
+ setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
2791
+ const handleReducedMotionChange = e => {
2792
+ setUserPrefersReducedMotion(e.matches);
2793
+ }, handleHighContrastChange = e => {
2794
+ setUserPrefersHighContrast(e.matches);
2795
+ };
2796
+ return mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
2797
+ mediaQueryHighContrast.addEventListener("change", handleHighContrastChange), () => {
2798
+ mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
2799
+ mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange);
2800
+ };
2801
+ }), []),
2802
+ // Background detection for overLight auto-detect
2791
2803
  React.useEffect((() => {
2792
2804
  if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
2793
2805
  const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
@@ -2887,102 +2899,36 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2887
2899
  }), 150);
2888
2900
  return () => clearTimeout(timeoutId);
2889
2901
  }
2890
- if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
2891
- const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
2892
- setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
2893
- const handleReducedMotionChange = e => {
2894
- setUserPrefersReducedMotion(e.matches);
2895
- }, handleHighContrastChange = e => {
2896
- setUserPrefersHighContrast(e.matches);
2897
- };
2898
- return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
2899
- mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
2900
- mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
2901
- // ignore
2902
- };
2903
- } catch (error) {
2904
- return;
2905
- }
2906
- }), [ overLight, glassRef, debugOverLight ]);
2902
+ "boolean" == typeof overLight && setDetectedOverLight(!1);
2903
+ }), [ overLight, glassRef ]);
2907
2904
  /**
2908
2905
  * Get effective overLight value based on configuration
2909
2906
  */
2910
- const getEffectiveOverLight = React.useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = React.useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), baseOverLightConfig = React.useMemo((() => {
2911
- const isOverLight = getEffectiveOverLight(), baseConfig = {
2907
+ const getEffectiveOverLight = React.useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = React.useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = React.useMemo((() => {
2908
+ const isOverLight = getEffectiveOverLight(), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
2912
2909
  isOverLight: isOverLight,
2913
2910
  threshold: .7,
2914
- opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
2915
- contrast: 1,
2916
- // Base contrast
2917
- brightness: 1,
2918
- // Base brightness
2911
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
2912
+ contrast: 1.4,
2913
+ brightness: .9,
2919
2914
  saturationBoost: 1.3,
2915
+ // Fixed value — dynamic saturation amplifies perceived displacement
2920
2916
  shadowIntensity: .9,
2921
2917
  borderOpacity: .7
2922
2918
  };
2923
2919
  if ("object" == typeof overLight && null !== overLight) {
2924
- const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost);
2925
- return {
2920
+ const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), finalConfig = {
2926
2921
  ...baseConfig,
2927
2922
  threshold: validatedThreshold,
2928
- opacity: validatedOpacity,
2923
+ opacity: validatedOpacity * hoverIntensity * activeIntensity,
2929
2924
  contrast: validatedContrast,
2930
2925
  brightness: validatedBrightness,
2931
2926
  saturationBoost: validatedSaturationBoost
2932
2927
  };
2928
+ return "undefined" == typeof process || process.env, finalConfig;
2933
2929
  }
2934
- return baseConfig;
2935
- }), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = React.useMemo((() => {
2936
- const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
2937
- return {
2938
- isOverLight: baseOverLightConfig.isOverLight,
2939
- threshold: baseOverLightConfig.threshold,
2940
- opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
2941
- contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
2942
- brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
2943
- saturationBoost: baseOverLightConfig.saturationBoost,
2944
- shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
2945
- borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
2946
- };
2947
- }), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = React.useRef(null), calculateDirectionalScale = React.useCallback((() => {
2948
- if (baseOverLightConfig.isOverLight) return "scale(1)";
2949
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
2950
- const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
2951
- x: edgeDistanceX,
2952
- y: edgeDistanceY
2953
- }, {
2954
- x: 0,
2955
- y: 0
2956
- });
2957
- if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
2958
- const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
2959
- if (0 === centerDistance) return "scale(1)";
2960
- const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15;
2961
- return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
2962
- }), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = React.useCallback((() => {
2963
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
2964
- const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
2965
- x: edgeDistanceX,
2966
- y: edgeDistanceY
2967
- }, {
2968
- x: 0,
2969
- y: 0
2970
- });
2971
- return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
2972
- }), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = React.useCallback((() => {
2973
- if (!glassRef.current) return {
2974
- x: 0,
2975
- y: 0
2976
- };
2977
- const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
2978
- return {
2979
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
2980
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
2981
- };
2982
- }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = React.useMemo((() => effectiveWithoutEffects ? {
2983
- x: 0,
2984
- y: 0
2985
- } : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveWithoutEffects ]), directionalScale = React.useMemo((() => effectiveWithoutEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveWithoutEffects ]), transformStyle = React.useMemo((() => effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`), [ elasticTranslation, isActive, onClick, directionalScale, effectiveWithoutEffects ]), handleGlobalMousePosition = React.useCallback((globalPos => {
2930
+ return "undefined" == typeof process || process.env, baseConfig;
2931
+ }), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = React.useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = React.useRef(null), handleGlobalMousePosition = React.useCallback((globalPos => {
2986
2932
  if (externalGlobalMousePosition && externalMouseOffset) return;
2987
2933
  if (effectiveWithoutEffects) return;
2988
2934
  const container = mouseContainer?.current || glassRef.current;
@@ -2991,35 +2937,61 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2991
2937
  let rect = cachedRectRef.current;
2992
2938
  if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
2993
2939
  cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
2994
- const center = calculateElementCenter(rect), newOffset = {
2940
+ const center = calculateElementCenter(rect);
2941
+ // Write raw target — the lerp loop will smoothly pursue it
2942
+ targetMouseOffsetRef.current = {
2995
2943
  x: (globalPos.x - center.x) / rect.width * 100,
2996
2944
  y: (globalPos.y - center.y) / rect.height * 100
2945
+ }, targetGlobalMousePositionRef.current = globalPos;
2946
+ }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = React.useCallback((() => {
2947
+ if (lerpActiveRef.current) return;
2948
+ lerpActiveRef.current = !0;
2949
+ const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
2950
+ if (!lerpActiveRef.current) return;
2951
+ const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
2952
+ // If we're close enough, snap and park
2953
+ if (Math.abs(dx) < .05 && Math.abs(dy) < .05) internalMouseOffsetRef.current = {
2954
+ ...tgt
2955
+ }, internalGlobalMousePositionRef.current = {
2956
+ ...targetGlobalMousePositionRef.current
2957
+ }; else {
2958
+ internalMouseOffsetRef.current = {
2959
+ x: lerp(cur.x, tgt.x, LERP_T),
2960
+ y: lerp(cur.y, tgt.y, LERP_T)
2961
+ };
2962
+ const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
2963
+ internalGlobalMousePositionRef.current = {
2964
+ x: lerp(curG.x, tgtG.x, LERP_T),
2965
+ y: lerp(curG.y, tgtG.y, LERP_T)
2966
+ };
2967
+ }
2968
+ // Imperative style update with the smoothed values
2969
+ updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
2970
+ mouseOffset: internalMouseOffsetRef.current,
2971
+ globalMousePosition: internalGlobalMousePositionRef.current,
2972
+ glassSize: glassSize,
2973
+ isHovered: isHovered,
2974
+ isActive: isActive,
2975
+ isOverLight: overLightConfig.isOverLight,
2976
+ baseOverLightConfig: overLightConfig,
2977
+ effectiveBorderRadius: effectiveBorderRadius,
2978
+ effectiveWithoutEffects: effectiveWithoutEffects,
2979
+ effectiveReducedMotion: effectiveReducedMotion,
2980
+ elasticity: elasticity,
2981
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
2982
+ onClick: onClick,
2983
+ withLiquidBlur: withLiquidBlur,
2984
+ blurAmount: blurAmount,
2985
+ saturation: saturation,
2986
+ padding: padding
2987
+ }), lerpRafRef.current = requestAnimationFrame(tick);
2997
2988
  };
2998
- // Calculate offset relative to this container
2999
- // Store in refs instead of state
3000
- internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
3001
- // Imperative style update
3002
- updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
3003
- mouseOffset: newOffset,
3004
- globalMousePosition: globalPos,
3005
- glassSize: glassSize,
3006
- isHovered: isHovered,
3007
- isActive: isActive,
3008
- isOverLight: baseOverLightConfig.isOverLight,
3009
- baseOverLightConfig: baseOverLightConfig,
3010
- effectiveBorderRadius: effectiveBorderRadius,
3011
- effectiveWithoutEffects: effectiveWithoutEffects,
3012
- effectiveReducedMotion: effectiveReducedMotion,
3013
- elasticity: elasticity,
3014
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
3015
- // Simplified directional scale for fast path
3016
- onClick: onClick,
3017
- withLiquidBlur: withLiquidBlur,
3018
- blurAmount: blurAmount,
3019
- saturation: saturation,
3020
- padding: padding
3021
- });
3022
- }), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
2989
+ // 0.08 lower = more viscous
2990
+ lerpRafRef.current = requestAnimationFrame(tick);
2991
+ }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]), stopLerpLoop = React.useCallback((() => {
2992
+ lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
2993
+ lerpRafRef.current = null);
2994
+ }), []);
3023
2995
  /**
3024
2996
  * Validate and clamp a numeric config value
3025
2997
  */
@@ -3027,7 +2999,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3027
2999
  React.useEffect((() => {
3028
3000
  if (externalGlobalMousePosition && externalMouseOffset) return;
3029
3001
  if (effectiveWithoutEffects) return;
3030
- const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
3002
+ const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
3003
+ // Start the lerp loop — it will smoothly chase the target
3004
+ startLerpLoop();
3005
+ const container = mouseContainer?.current || glassRef.current;
3031
3006
  let resizeObserver = null;
3032
3007
  return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
3033
3008
  null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
@@ -3035,10 +3010,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3035
3010
  container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
3036
3011
  }));
3037
3012
  })), resizeObserver.observe(container)), () => {
3038
- unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
3013
+ unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
3039
3014
  updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
3040
3015
  };
3041
- }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
3016
+ }), [ handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
3042
3017
  // Also call updateStyles on other state changes (hover, active, etc)
3043
3018
  React.useEffect((() => {
3044
3019
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
@@ -3047,22 +3022,22 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3047
3022
  glassSize: glassSize,
3048
3023
  isHovered: isHovered,
3049
3024
  isActive: isActive,
3050
- isOverLight: baseOverLightConfig.isOverLight,
3051
- baseOverLightConfig: baseOverLightConfig,
3025
+ isOverLight: overLightConfig.isOverLight,
3026
+ baseOverLightConfig: overLightConfig,
3052
3027
  effectiveBorderRadius: effectiveBorderRadius,
3053
3028
  effectiveWithoutEffects: effectiveWithoutEffects,
3054
3029
  effectiveReducedMotion: effectiveReducedMotion,
3055
3030
  elasticity: elasticity,
3056
- directionalScale: directionalScale,
3031
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
3057
3032
  onClick: onClick,
3058
3033
  withLiquidBlur: withLiquidBlur,
3059
3034
  blurAmount: blurAmount,
3060
3035
  saturation: saturation,
3061
3036
  padding: padding
3062
3037
  });
3063
- }), [ isHovered, isActive, glassSize, baseOverLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, directionalScale, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
3038
+ }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
3064
3039
  // Event handlers
3065
- const handleMouseEnter = React.useCallback((() => setIsHovered(!0)), []), handleMouseLeave = React.useCallback((() => setIsHovered(!1)), []), handleMouseDown = React.useCallback((() => setIsActive(!0)), []), handleMouseUp = React.useCallback((() => setIsActive(!1)), []), handleMouseMove = React.useCallback((_e => {}), []), handleKeyDown = React.useCallback((e => {
3040
+ const handleMouseEnter = React.useCallback((() => setIsHovered(!0)), []), handleMouseLeave = React.useCallback((() => setIsHovered(!1)), []), handleMouseDown = React.useCallback((() => setIsActive(!0)), []), handleMouseUp = React.useCallback((() => setIsActive(!1)), []), handleKeyDown = React.useCallback((e => {
3066
3041
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
3067
3042
  }), [ onClick ]);
3068
3043
  return {
@@ -3080,14 +3055,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3080
3055
  mouseOffset: mouseOffset,
3081
3056
  // This is now static (refs or props) unless prop changes
3082
3057
  overLightConfig: overLightConfig,
3083
- elasticTranslation: elasticTranslation,
3084
- directionalScale: directionalScale,
3085
3058
  transformStyle: transformStyle,
3086
3059
  handleMouseEnter: handleMouseEnter,
3087
3060
  handleMouseLeave: handleMouseLeave,
3088
3061
  handleMouseDown: handleMouseDown,
3089
3062
  handleMouseUp: handleMouseUp,
3090
- handleMouseMove: handleMouseMove,
3091
3063
  handleKeyDown: handleKeyDown
3092
3064
  };
3093
3065
  }
@@ -3185,25 +3157,56 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3185
3157
  withLiquidBlur: withLiquidBlur,
3186
3158
  padding: padding,
3187
3159
  style: style
3188
- }), isOverLight = React.useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
3189
- ...style,
3190
- ...!effectiveWithoutEffects && {
3191
- transform: transformStyle
3160
+ }), isOverLight = React.useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, rootLayoutStyle = React.useMemo((() => {
3161
+ if (!isFixedOrSticky) return {};
3162
+ const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
3163
+ return {
3164
+ ...p && {
3165
+ position: p
3166
+ },
3167
+ ...void 0 !== t && {
3168
+ top: t
3169
+ },
3170
+ ...void 0 !== l && {
3171
+ left: l
3172
+ },
3173
+ ...void 0 !== r && {
3174
+ right: r
3175
+ },
3176
+ ...void 0 !== b && {
3177
+ bottom: b
3178
+ }
3179
+ };
3180
+ }), [ isFixedOrSticky, restStyle ]), baseStyle = React.useMemo((() => {
3181
+ if (isFixedOrSticky) {
3182
+ const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
3183
+ return {
3184
+ ...visualStyle,
3185
+ ...!effectiveWithoutEffects && {
3186
+ transform: transformStyle
3187
+ }
3188
+ };
3192
3189
  }
3193
- }, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = React.useMemo((() => ({
3194
- position: style.position || "absolute",
3195
- top: style.top || 0,
3196
- left: style.left || 0
3197
- })), [ style.position, style.top, style.left ]), adjustedSize = React.useMemo((() => {
3190
+ return {
3191
+ ...restStyle,
3192
+ ...!effectiveWithoutEffects && {
3193
+ transform: transformStyle
3194
+ }
3195
+ };
3196
+ }), [ isFixedOrSticky, restStyle, effectiveWithoutEffects, transformStyle ]), componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = React.useMemo((() => ({
3197
+ position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
3198
+ top: isFixedOrSticky ? 0 : restStyle.top || 0,
3199
+ left: isFixedOrSticky ? 0 : restStyle.left || 0
3200
+ })), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left ]), adjustedSize = React.useMemo((() => {
3198
3201
  const resolveSize = (propValue, styleValue, measuredSize) => {
3199
3202
  const explicitSize = propValue ?? styleValue;
3200
3203
  return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
3201
3204
  };
3202
3205
  return {
3203
- width: resolveSize(width, style.width, glassSize.width),
3204
- height: resolveSize(height, style.height, glassSize.height)
3206
+ width: resolveSize(width, restStyle.width, glassSize.width),
3207
+ height: resolveSize(height, restStyle.height, glassSize.height)
3205
3208
  };
3206
- }), [ width, height, style.width, style.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = React.useMemo((() => {
3209
+ }), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = React.useMemo((() => {
3207
3210
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
3208
3211
  return {
3209
3212
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -3245,6 +3248,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3245
3248
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = React.useMemo((() => {
3246
3249
  const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues, configBorderOpacity = overLightConfig?.borderOpacity ?? 1;
3247
3250
  return {
3251
+ ...void 0 !== customZIndex && {
3252
+ "--atomix-glass-base-z-index": customZIndex
3253
+ },
3248
3254
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
3249
3255
  "--atomix-glass-transform": transformStyle || "none",
3250
3256
  "--atomix-glass-position": positionStyles.position,
@@ -3265,22 +3271,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3265
3271
  "--atomix-glass-base-opacity": opacityValues.base,
3266
3272
  "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${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(${blackColor}, ${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})`,
3267
3273
  "--atomix-glass-overlay-opacity": opacityValues.over,
3268
- "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${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})`
3274
+ "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${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})`,
3275
+ "--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
3276
+ "--atomix-glass-overlay-highlight-bg": `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
3269
3277
  };
3270
- }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsxRuntime.jsx("div", {
3271
- 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(" "),
3272
- style: {
3273
- ...positionStyles,
3274
- height: adjustedSize.height,
3275
- width: adjustedSize.width,
3276
- borderRadius: `${effectiveBorderRadius}px`,
3277
- transform: baseStyle.transform
3278
- }
3278
+ }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity, customZIndex ]), renderBackgroundLayer = layerType => jsxRuntime.jsx("div", {
3279
+ 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(" ")
3279
3280
  });
3280
3281
  return jsxRuntime.jsxs("div", {
3281
3282
  ...rest,
3282
3283
  className: componentClassName,
3283
- style: glassVars,
3284
+ style: {
3285
+ ...glassVars
3286
+ },
3284
3287
  role: role || (onClick ? "button" : void 0),
3285
3288
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
3286
3289
  "aria-label": ariaLabel,
@@ -3292,7 +3295,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3292
3295
  ref: glassRef,
3293
3296
  contentRef: contentRef,
3294
3297
  className: className,
3295
- style: baseStyle,
3298
+ style: rootLayoutStyle,
3296
3299
  borderRadius: effectiveBorderRadius,
3297
3300
  displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
3298
3301
  blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
@@ -3343,11 +3346,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
3343
3346
  }), jsxRuntime.jsx("div", {
3344
3347
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
3345
3348
  }), jsxRuntime.jsx("div", {
3346
- className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS,
3347
- style: {
3348
- opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
3349
- background: `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
3350
- }
3349
+ className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
3351
3350
  }) ]
3352
3351
  }), withBorder && jsxRuntime.jsxs(jsxRuntime.Fragment, {
3353
3352
  children: [ jsxRuntime.jsx("span", {
@@ -5436,7 +5435,7 @@ function getDatasetBounds(data) {
5436
5435
  pan: !0,
5437
5436
  reset: !0
5438
5437
  }, exportFormats: exportFormats = [ "png", "svg", "csv" ], size: size = "md", position: position = "top", onRefresh: onRefresh, onExport: onExport, onFullscreen: onFullscreen, onSettings: onSettings, onZoomIn: onZoomIn, onZoomOut: onZoomOut, onZoomReset: onZoomReset, onPanToggle: onPanToggle, onReset: onReset, onGridToggle: onGridToggle, onLegendToggle: onLegendToggle, onTooltipsToggle: onTooltipsToggle, onAnimationsToggle: onAnimationsToggle, state: state = {}, className: className = "", ...props}, ref) => {
5439
- const [showExportMenu, setShowExportMenu] = React.useState(!1), [showSettingsMenu, setShowSettingsMenu] = React.useState(!1), exportMenuRef = React.useRef(null), settingsMenuRef = React.useRef(null), exportButtonRef = React.useRef(null), settingsButtonRef = React.useRef(null), effectiveDefaults = groups && groups.length > 0 ? {
5438
+ const [showExportMenu, setShowExportMenu] = React.useState(!1), [showSettingsMenu, setShowSettingsMenu] = React.useState(!1), exportMenuRef = React.useRef(null), settingsMenuRef = React.useRef(null), exportButtonRef = React.useRef(null), settingsButtonRef = React.useRef(null), effectiveDefaults = React.useMemo((() => groups && groups.length > 0 ? {
5440
5439
  refresh: defaults.refresh ?? !0,
5441
5440
  export: defaults.export ?? !0,
5442
5441
  fullscreen: defaults.fullscreen ?? !0,
@@ -5448,7 +5447,7 @@ function getDatasetBounds(data) {
5448
5447
  legend: defaults.legend ?? !0,
5449
5448
  tooltips: defaults.tooltips ?? !0,
5450
5449
  animations: defaults.animations ?? !0
5451
- } : defaults;
5450
+ } : defaults), [ groups, defaults ]);
5452
5451
  // Close menus when clicking outside
5453
5452
  React.useEffect((() => {
5454
5453
  const handleClickOutside = event => {
@@ -6898,120 +6897,6 @@ const BaseChart = React.memo( React.forwardRef((({type: type, datasets: dataset
6898
6897
 
6899
6898
  BaseChart.displayName = "BaseChart";
6900
6899
 
6901
- const AnimatedChart = React.memo( React.forwardRef((({datasets: datasets = [], config: config = {}, chartType: chartType = "line", particleEffects: particleEffects, onDataPointClick: onDataPointClick, ...props}, ref) => {
6902
- const animationRef = React.useRef(0), timeRef = React.useRef(0), particlesRef = React.useRef([]);
6903
- // Animation time tracking - moved outside callback
6904
- React.useEffect((() => {
6905
- const animateFrame = timestamp => {
6906
- timeRef.current = timestamp, animationRef.current = requestAnimationFrame(animateFrame);
6907
- };
6908
- return animationRef.current = requestAnimationFrame(animateFrame), () => {
6909
- animationRef.current && cancelAnimationFrame(animationRef.current);
6910
- };
6911
- }), []);
6912
- const renderContent = React.useCallback((({scales: scales, colors: colors, datasets: chartDatasets, handlers: handlers, hoveredPoint: hoveredPoint, toolbarState: toolbarState, config: renderConfig}) => {
6913
- if (!chartDatasets.length) return null;
6914
- const chartWidth = scales.width - 80, chartHeight = scales.height - 80, elements = [];
6915
- // Particle effects
6916
- if (chartDatasets.forEach(((dataset, datasetIndex) => {
6917
- const color = dataset.color || colors[datasetIndex % colors.length];
6918
- switch (chartType) {
6919
- case "bar":
6920
- // Create animated bars
6921
- dataset.data.forEach(((point, pointIndex) => {
6922
- const barWidth = chartWidth / dataset.data.length * .8, x = 40 + pointIndex * (chartWidth / dataset.data.length) + (chartWidth / dataset.data.length - barWidth) / 2, height = point.value / 100 * chartHeight, y = 40 + chartHeight - height;
6923
- elements.push(jsxRuntime.jsx("rect", {
6924
- x: x,
6925
- y: y,
6926
- width: barWidth,
6927
- height: height,
6928
- fill: color,
6929
- style: {
6930
- transform: `scaleY(${.1 * Math.sin(.01 * timeRef.current + .2 * pointIndex) + .9})`,
6931
- transformOrigin: "bottom"
6932
- },
6933
- onClick: () => handlers.onDataPointClick?.(point, datasetIndex, pointIndex)
6934
- }, `bar-${datasetIndex}-${pointIndex}`));
6935
- }));
6936
- break;
6937
-
6938
- default:
6939
- {
6940
- // Create animated line/area
6941
- const points = dataset.data.map(((point, pointIndex) => ({
6942
- x: 40 + pointIndex / (dataset.data.length - 1) * chartWidth,
6943
- y: 40 + chartHeight - point.value / 100 * chartHeight
6944
- })));
6945
- if (points.length > 0) {
6946
- const linePath = `M ${points.map((p => `${p.x},${p.y}`)).join(" L ")}`;
6947
- // Area for area chart
6948
- if ("area" === chartType) {
6949
- const areaPath = `${linePath} L ${40 + chartWidth},${40 + chartHeight} L 40,${40 + chartHeight} Z`;
6950
- elements.push(jsxRuntime.jsx("path", {
6951
- d: areaPath,
6952
- fill: color,
6953
- fillOpacity: "0.3",
6954
- style: {
6955
- transform: `translateY(${2 * Math.sin(.01 * timeRef.current)}px)`
6956
- }
6957
- }, `area-${datasetIndex}`));
6958
- }
6959
- // Line
6960
- elements.push(jsxRuntime.jsx("path", {
6961
- d: linePath,
6962
- stroke: color,
6963
- fill: "none",
6964
- className: "c-chart__data-line",
6965
- style: {
6966
- transform: `translateY(${2 * Math.sin(.01 * timeRef.current)}px)`
6967
- }
6968
- }, `line-${datasetIndex}`)),
6969
- // Data points
6970
- points.forEach(((point, pointIndex) => {
6971
- elements.push(jsxRuntime.jsx("circle", {
6972
- cx: point.x,
6973
- cy: point.y,
6974
- r: "4",
6975
- fill: color,
6976
- style: {
6977
- transform: `scale(${1 + .2 * Math.sin(.01 * timeRef.current + pointIndex)})`
6978
- },
6979
- onClick: () => handlers.onDataPointClick?.(dataset.data[pointIndex], datasetIndex, pointIndex)
6980
- }, `point-${datasetIndex}-${pointIndex}`));
6981
- }));
6982
- }
6983
- break;
6984
- }
6985
- }
6986
- })), particleEffects?.enabled) for (let i = 0; i < particleEffects.count; i++) {
6987
- const particle = particlesRef.current[i];
6988
- particle && elements.push(jsxRuntime.jsx("circle", {
6989
- cx: particle.x,
6990
- cy: particle.y,
6991
- r: particle.size,
6992
- fill: particle.color,
6993
- style: {
6994
- opacity: particle.life
6995
- }
6996
- }, `particle-${i}`));
6997
- }
6998
- return jsxRuntime.jsx("g", {
6999
- children: elements
7000
- });
7001
- }), [ chartType, particleEffects ]);
7002
- return jsxRuntime.jsx(BaseChart, {
7003
- ref: ref,
7004
- type: "line",
7005
- datasets: datasets,
7006
- config: config,
7007
- renderContent: renderContent,
7008
- onDataPointClick: onDataPointClick,
7009
- ...props
7010
- });
7011
- })));
7012
-
7013
- AnimatedChart.displayName = "AnimatedChart";
7014
-
7015
6900
  const ChartTooltip = React.memo((({dataPoint: dataPoint, datasetLabel: datasetLabel, datasetColor: datasetColor, position: position, visible: visible, customRenderer: customRenderer}) => {
7016
6901
  const tooltipRef = React.useRef(null), [adjustedPosition, setAdjustedPosition] = React.useState(position);
7017
6902
  // Dynamic positioning to keep tooltip in viewport
@@ -7033,15 +6918,16 @@ const ChartTooltip = React.memo((({dataPoint: dataPoint, datasetLabel: datasetL
7033
6918
  ref: tooltipRef,
7034
6919
  className: "c-chart__tooltip",
7035
6920
  style: {
7036
- left: `${adjustedPosition.x}px`,
7037
- top: `${adjustedPosition.y}px`,
6921
+ transform: `translate3d(${adjustedPosition.x}px, ${adjustedPosition.y}px, 0)`,
7038
6922
  opacity: visible ? 1 : 0,
7039
6923
  visibility: visible ? "visible" : "hidden",
7040
- transition: "opacity 0.2s ease, transform 0.2s ease",
7041
- transform: "translateZ(0)",
6924
+ transition: "opacity 0.2s ease",
7042
6925
  position: "fixed",
6926
+ left: 0,
6927
+ top: 0,
7043
6928
  zIndex: 1e3,
7044
- pointerEvents: "none"
6929
+ pointerEvents: "none",
6930
+ willChange: "transform"
7045
6931
  },
7046
6932
  children: customRenderer ? customRenderer(dataPoint) : jsxRuntime.jsxs(jsxRuntime.Fragment, {
7047
6933
  children: [ jsxRuntime.jsx("div", {
@@ -7360,8 +7246,9 @@ const BubbleChart = React.memo( React.forwardRef((({bubbleData: bubbleData = []
7360
7246
  if (!bubbleData.length) return null;
7361
7247
  const showTooltips = toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? !0, sizeValues = bubbleData.map((b => b.size)), minSize = Math.min(...sizeValues), sizeRange = Math.max(...sizeValues) - minSize || 1, bubbles = bubbleData.map(((bubble, index) => {
7362
7248
  // Calculate scaled size
7363
- const scaledSize = minBubbleSize + (bubble.size - minSize) / sizeRange * (maxBubbleSize - minBubbleSize), x = scales.padding.left + bubble.x / 100 * scales.innerWidth, y = scales.padding.top + scales.innerHeight - bubble.y / 100 * scales.innerHeight;
7249
+ const scaledSize = minBubbleSize + (bubble.size - minSize) / sizeRange * (maxBubbleSize - minBubbleSize), effectiveWidth = scales.innerWidth - 2 * maxBubbleSize, effectiveHeight = scales.innerHeight - 2 * maxBubbleSize, x = scales.padding.left + maxBubbleSize + bubble.x / 100 * effectiveWidth, y = scales.padding.top + maxBubbleSize + effectiveHeight - bubble.y / 100 * effectiveHeight;
7364
7250
  // Calculate position
7251
+ // Ensure bubbles don't get cut off by adding padding equal to maxBubbleSize
7365
7252
  // Determine color
7366
7253
  let bubbleColor = bubble.color;
7367
7254
  if (!bubbleColor) if (sizeBasedColoring) {
@@ -7823,9 +7710,10 @@ const GaugeChart = React.memo( React.forwardRef((({value: value, min: min = 0,
7823
7710
  // Create ticks
7824
7711
  const ticks = [];
7825
7712
  if (showTicks) {
7713
+ const innerRadius = radius * (1 - thickness);
7826
7714
  // Major ticks
7827
- for (let i = 0; i <= majorTicks; i++) {
7828
- const tickValue = min + i / majorTicks * (max - min), tickAngle = startAngleRad + i / majorTicks * angleRange, tickRadius = .95 * radius, tickLength = .05 * radius, x1 = centerX + tickRadius * Math.cos(tickAngle), y1 = centerY + tickRadius * Math.sin(tickAngle), x2 = centerX + (tickRadius - tickLength) * Math.cos(tickAngle), y2 = centerY + (tickRadius - tickLength) * Math.sin(tickAngle);
7715
+ for (let i = 0; i <= majorTicks; i++) {
7716
+ const tickValue = min + i / majorTicks * (max - min), tickAngle = startAngleRad + i / majorTicks * angleRange, tickRadius = innerRadius - 2, tickLength = .05 * radius, x1 = centerX + tickRadius * Math.cos(tickAngle), y1 = centerY + tickRadius * Math.sin(tickAngle), x2 = centerX + (tickRadius - tickLength) * Math.cos(tickAngle), y2 = centerY + (tickRadius - tickLength) * Math.sin(tickAngle);
7829
7717
  // Labels for major ticks
7830
7718
  if (ticks.push(jsxRuntime.jsx("line", {
7831
7719
  x1: x1,
@@ -7835,12 +7723,12 @@ const GaugeChart = React.memo( React.forwardRef((({value: value, min: min = 0,
7835
7723
  stroke: "var(--atomix-brand-border-subtle)",
7836
7724
  strokeWidth: "2"
7837
7725
  }, `major-tick-${i}`)), showMinMaxLabels) {
7838
- const labelX = centerX + (tickRadius - tickLength - 10) * Math.cos(tickAngle), labelY = centerY + (tickRadius - tickLength - 10) * Math.sin(tickAngle);
7726
+ const labelRadius = tickRadius - tickLength - 15, labelX = centerX + labelRadius * Math.cos(tickAngle), labelY = centerY + labelRadius * Math.sin(tickAngle);
7839
7727
  ticks.push(jsxRuntime.jsx("text", {
7840
7728
  x: labelX,
7841
7729
  y: labelY,
7842
7730
  textAnchor: "middle",
7843
- dominantBaseline: "middle",
7731
+ dominantBaseline: "central",
7844
7732
  fontSize: "12",
7845
7733
  fill: "var(--atomix-brand-text-emphasis)",
7846
7734
  children: tickValue
@@ -7848,8 +7736,9 @@ const GaugeChart = React.memo( React.forwardRef((({value: value, min: min = 0,
7848
7736
  }
7849
7737
  }
7850
7738
  // Minor ticks
7851
- for (let i = 0; i < majorTicks * minorTicks; i++) {
7852
- const tickAngle = startAngleRad + i / (majorTicks * minorTicks) * angleRange, tickRadius = .95 * radius, tickLength = .025 * radius, x1 = centerX + tickRadius * Math.cos(tickAngle), y1 = centerY + tickRadius * Math.sin(tickAngle), x2 = centerX + (tickRadius - tickLength) * Math.cos(tickAngle), y2 = centerY + (tickRadius - tickLength) * Math.sin(tickAngle);
7739
+ for (let i = 0; i <= majorTicks * minorTicks; i++) {
7740
+ if (i % minorTicks == 0) continue;
7741
+ const tickAngle = startAngleRad + i / (majorTicks * minorTicks) * angleRange, tickRadius = innerRadius - 2, tickLength = .025 * radius, x1 = centerX + tickRadius * Math.cos(tickAngle), y1 = centerY + tickRadius * Math.sin(tickAngle), x2 = centerX + (tickRadius - tickLength) * Math.cos(tickAngle), y2 = centerY + (tickRadius - tickLength) * Math.sin(tickAngle);
7853
7742
  ticks.push(jsxRuntime.jsx("line", {
7854
7743
  x1: x1,
7855
7744
  y1: y1,
@@ -7860,39 +7749,43 @@ const GaugeChart = React.memo( React.forwardRef((({value: value, min: min = 0,
7860
7749
  }, `minor-tick-${i}`));
7861
7750
  }
7862
7751
  }
7863
- // Create needle
7864
- const needle = showNeedle ? jsxRuntime.jsxs("g", {
7752
+ const innerRadius = radius * (1 - thickness), needle = showNeedle ? jsxRuntime.jsxs("g", {
7865
7753
  children: [ jsxRuntime.jsx("line", {
7866
7754
  x1: centerX,
7867
7755
  y1: centerY,
7868
- x2: centerX + .8 * radius * Math.cos(valueAngle),
7869
- y2: centerY + .8 * radius * Math.sin(valueAngle),
7756
+ x2: centerX + (innerRadius - 15) * Math.cos(valueAngle),
7757
+ y2: centerY + (innerRadius - 15) * Math.sin(valueAngle),
7870
7758
  stroke: needleColor,
7871
- strokeWidth: "3",
7759
+ strokeWidth: "4",
7872
7760
  strokeLinecap: "round"
7873
7761
  }), jsxRuntime.jsx("circle", {
7874
7762
  cx: centerX,
7875
7763
  cy: centerY,
7876
7764
  r: "8",
7877
7765
  fill: needleColor
7766
+ }), jsxRuntime.jsx("circle", {
7767
+ cx: centerX,
7768
+ cy: centerY,
7769
+ r: "3",
7770
+ fill: "var(--atomix-primary-bg, #fff)"
7878
7771
  }) ]
7879
7772
  }) : null, valueText = showValue ? jsxRuntime.jsx("text", {
7880
7773
  x: centerX,
7881
- y: centerY + 10,
7774
+ y: centerY + 35,
7882
7775
  textAnchor: "middle",
7883
- fontSize: "24",
7776
+ fontSize: "32",
7884
7777
  fontWeight: "bold",
7885
7778
  fill: "var(--atomix-primary-text-emphasis)",
7886
7779
  children: valueFormatter(clampedValue)
7887
7780
  }) : null, labelText = label ? jsxRuntime.jsx("text", {
7888
7781
  x: centerX,
7889
- y: "top" === labelPosition ? centerY - .7 * radius : centerY + .7 * radius,
7782
+ y: "top" === labelPosition ? centerY - .7 * radius : centerY + .7 * radius + 10,
7890
7783
  textAnchor: "middle",
7891
7784
  fontSize: "16",
7892
7785
  fill: "var(--atomix-brand-text-emphasis)",
7893
7786
  children: label
7894
7787
  }) : null;
7895
- // Value text
7788
+ // Create needle
7896
7789
  return jsxRuntime.jsxs("g", {
7897
7790
  children: [ jsxRuntime.jsx("path", {
7898
7791
  d: createArcPath(centerX, centerY, radius, startAngleRad, endAngleRad, thickness),
@@ -7924,11 +7817,9 @@ const colorSchemes = {
7924
7817
  greens: [ "var(--atomix-green-1)", "var(--atomix-green-2)", "var(--atomix-green-3)", "var(--atomix-green-4)", "var(--atomix-green-5)", "var(--atomix-green-6)", "var(--atomix-green-7)", "var(--atomix-green-8)", "var(--atomix-green-9)" ],
7925
7818
  github: [ "var(--atomix-gray-2)", "var(--atomix-green-3)", "var(--atomix-green-4)", "var(--atomix-green-5)", "var(--atomix-green-6)" ]
7926
7819
  }, HeatmapChart = React.memo( React.forwardRef((({data: data = [], config: config = {}, colorScale: colorScale = {
7927
- scheme: "viridis",
7820
+ scheme: "blues",
7928
7821
  steps: 9
7929
7822
  }, cellConfig: cellConfig = {
7930
- width: 40,
7931
- height: 40,
7932
7823
  spacing: 2,
7933
7824
  borderRadius: 4,
7934
7825
  showLabels: !1
@@ -7988,9 +7879,8 @@ const colorSchemes = {
7988
7879
  renderContent: ({scales: scales, colors: colors, datasets: renderedDatasets, handlers: handlers, hoveredPoint: hoveredPoint, toolbarState: toolbarState, config: renderConfig}) => {
7989
7880
  const {matrix: matrix, xLabels: xLabels, yLabels: yLabels} = processedData, showTooltips = toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? !0;
7990
7881
  if (!matrix.length) return null;
7991
- const cellWidth = cellConfig.width || 40, cellHeight = cellConfig.height || 40, spacing = cellConfig.spacing || 2, borderRadius = cellConfig.borderRadius || 4;
7992
- // Leave space for x-axis labels
7993
- return xLabels.length, yLabels.length, jsxRuntime.jsxs(jsxRuntime.Fragment, {
7882
+ const spacing = cellConfig.spacing ?? 2, borderRadius = cellConfig.borderRadius ?? 4, {width: width, height: height} = scales, paddingRight = 20 + (showColorLegend ? 60 : 0), availableWidth = Math.max(0, width - 60 - paddingRight), availableHeight = Math.max(0, height - 20 - 40), cols = Math.max(1, xLabels.length), rows = Math.max(1, yLabels.length), maxCellWidth = Math.max(2, Math.floor((availableWidth - (cols - 1) * spacing) / cols)), maxCellHeight = Math.max(2, Math.floor((availableHeight - (rows - 1) * spacing) / rows)), cellWidth = cellConfig.width || maxCellWidth, cellHeight = cellConfig.height || maxCellHeight, totalWidth = cols * cellWidth + (cols - 1) * spacing, totalHeight = rows * cellHeight + (rows - 1) * spacing, startX = 60 + Math.max(0, (availableWidth - totalWidth) / 2), startY = 20 + Math.max(0, (availableHeight - totalHeight) / 2);
7883
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
7994
7884
  children: [ jsxRuntime.jsxs("g", {
7995
7885
  children: [ jsxRuntime.jsx("defs", {
7996
7886
  children: showColorLegend && (() => {
@@ -8009,7 +7899,7 @@ const colorSchemes = {
8009
7899
  })()
8010
7900
  }), matrix.map(((row, rowIndex) => row.map(((cell, colIndex) => {
8011
7901
  if (!cell) return null;
8012
- const x = 100 + colIndex * (cellWidth + spacing), y = 50 + rowIndex * (cellHeight + spacing), color = getColorForValue(cell.value), isHovered = hoveredCell === cell;
7902
+ const x = startX + colIndex * (cellWidth + spacing), y = startY + rowIndex * (cellHeight + spacing), color = getColorForValue(cell.value), isHovered = hoveredCell === cell;
8013
7903
  return jsxRuntime.jsxs("g", {
8014
7904
  children: [ jsxRuntime.jsx("rect", {
8015
7905
  x: x,
@@ -8020,11 +7910,6 @@ const colorSchemes = {
8020
7910
  ry: borderRadius,
8021
7911
  fill: color,
8022
7912
  className: "c-chart__heatmap-cell " + (isHovered ? "c-chart__heatmap-cell--hovered" : ""),
8023
- style: {
8024
- transition: "all 0.2s ease",
8025
- transform: isHovered ? "scale(1.05)" : "scale(1)",
8026
- transformOrigin: "center"
8027
- },
8028
7913
  onClick: () => {
8029
7914
  cell && handlers.onDataPointClick?.({
8030
7915
  ...cell,
@@ -8034,8 +7919,14 @@ const colorSchemes = {
8034
7919
  },
8035
7920
  onMouseEnter: e => {
8036
7921
  setHoveredCell(cell);
7922
+ const pointIndex = data.findIndex((d => d.x === cell.x && d.y === cell.y)), rect = e.currentTarget.getBoundingClientRect();
7923
+ handlers.onPointHover(0,
7924
+ // datasetIndex is always 0 for Heatmap
7925
+ pointIndex >= 0 ? pointIndex : 0, x, y, rect.left + rect.width / 2, rect.top + rect.height / 2);
8037
7926
  },
8038
- onMouseLeave: () => setHoveredCell(null)
7927
+ onMouseLeave: () => {
7928
+ setHoveredCell(null), handlers.onPointLeave();
7929
+ }
8039
7930
  }), cellConfig.showLabels && cell.label && jsxRuntime.jsx("text", {
8040
7931
  x: x + cellWidth / 2,
8041
7932
  y: y + cellHeight / 2,
@@ -8046,7 +7937,7 @@ const colorSchemes = {
8046
7937
  }) ]
8047
7938
  }, `cell-${rowIndex}-${colIndex}`);
8048
7939
  })))), xLabels.map(((label, index) => {
8049
- const x = 100 + index * (cellWidth + spacing) + cellWidth / 2, y = 50 + matrix.length * (cellHeight + spacing) + 20;
7940
+ const x = startX + index * (cellWidth + spacing) + cellWidth / 2, y = startY + matrix.length * (cellHeight + spacing) + 20;
8050
7941
  return jsxRuntime.jsx("text", {
8051
7942
  x: x,
8052
7943
  y: y,
@@ -8055,9 +7946,9 @@ const colorSchemes = {
8055
7946
  children: String(label)
8056
7947
  }, `x-label-${index}`);
8057
7948
  })), yLabels.map(((label, index) => {
8058
- const y = 50 + index * (cellHeight + spacing) + cellHeight / 2;
7949
+ const x = startX - 20, y = startY + index * (cellHeight + spacing) + cellHeight / 2;
8059
7950
  return jsxRuntime.jsx("text", {
8060
- x: 80,
7951
+ x: x,
8061
7952
  y: y,
8062
7953
  textAnchor: "end",
8063
7954
  dominantBaseline: "middle",
@@ -8065,29 +7956,31 @@ const colorSchemes = {
8065
7956
  children: String(label)
8066
7957
  }, `y-label-${index}`);
8067
7958
  })), showColorLegend && jsxRuntime.jsxs("g", {
8068
- transform: "translate(600, 100)",
7959
+ transform: `translate(${startX + totalWidth + 20}, ${startY})`,
8069
7960
  children: [ jsxRuntime.jsx("rect", {
8070
7961
  x: "0",
8071
7962
  y: "0",
8072
- width: "20",
8073
- height: "200",
7963
+ width: "12",
7964
+ height: totalHeight,
8074
7965
  fill: "url(#heatmap-legend-gradient)",
8075
7966
  stroke: "var(--atomix-border-color)",
8076
- className: "c-chart__grid"
7967
+ className: "c-chart__grid",
7968
+ rx: borderRadius,
7969
+ ry: borderRadius
8077
7970
  }), jsxRuntime.jsx("text", {
8078
- x: "-10",
7971
+ x: "-5",
8079
7972
  y: "-10",
8080
7973
  className: "c-chart__heatmap-legend-title",
8081
7974
  children: "Values"
8082
7975
  }), jsxRuntime.jsx("text", {
8083
- x: "25",
8084
- y: "5",
7976
+ x: "20",
7977
+ y: "8",
8085
7978
  textAnchor: "start",
8086
7979
  className: "c-chart__heatmap-legend-label",
8087
7980
  children: "High"
8088
7981
  }), jsxRuntime.jsx("text", {
8089
- x: "25",
8090
- y: "200",
7982
+ x: "20",
7983
+ y: totalHeight,
8091
7984
  textAnchor: "start",
8092
7985
  className: "c-chart__heatmap-legend-label",
8093
7986
  children: "Low"
@@ -8859,8 +8752,7 @@ const DEFAULT_COLOR_CONFIG = {
8859
8752
  }, DEFAULT_LABEL_CONFIG = {
8860
8753
  showLabels: !0,
8861
8754
  minSize: 1e3,
8862
- fontSize: 12,
8863
- textColor: "white"
8755
+ fontSize: 12
8864
8756
  }, DEFAULT_CONFIG = {}, TreemapChart = React.memo( React.forwardRef((({data: data = [], algorithm: algorithm = "squarified", colorConfig: colorConfig = DEFAULT_COLOR_CONFIG, labelConfig: labelConfig = DEFAULT_LABEL_CONFIG, onDataPointClick: onDataPointClick, config: config = DEFAULT_CONFIG, ...props}, ref) => {
8865
8757
  const [hoveredNode, setHoveredNode] = React.useState(null), [selectedNode, setSelectedNode] = React.useState(null);
8866
8758
  React.useState({
@@ -8924,13 +8816,13 @@ const DEFAULT_COLOR_CONFIG = {
8924
8816
  }
8925
8817
  // Sort nodes by value (descending)
8926
8818
  const sortedNodes = [ ...nodes ].sort(((a, b) => b.value - a.value)), aspectRatio = rect => Math.max(rect.width / rect.height, rect.height / rect.width);
8927
- let currentRow = [], remainingNodes = [ ...sortedNodes ], currentX = x, currentY = y, remainingWidth = width, remainingHeight = height;
8819
+ let currentRow = [], remainingNodes = [ ...sortedNodes ], currentX = x, currentY = y, remainingWidth = width, remainingHeight = height, remainingValue = totalValue;
8928
8820
  for (;remainingNodes.length > 0; ) {
8929
8821
  const node = remainingNodes.shift();
8930
8822
  if (!node) break;
8931
8823
  currentRow.push(node);
8932
8824
  // Calculate dimensions for current row
8933
- const rowValue = _reduceInstanceProperty(currentRow).call(currentRow, ((sum, n) => sum + n.value), 0), rowRatio = rowValue / totalValue;
8825
+ const rowValue = _reduceInstanceProperty(currentRow).call(currentRow, ((sum, n) => sum + n.value), 0), rowRatio = remainingValue > 0 ? rowValue / remainingValue : 0;
8934
8826
  let rowWidth, rowHeight;
8935
8827
  remainingWidth >= remainingHeight ? (rowWidth = remainingWidth * rowRatio, rowHeight = remainingHeight) : (rowWidth = remainingWidth,
8936
8828
  rowHeight = remainingHeight * rowRatio);
@@ -8939,7 +8831,7 @@ const DEFAULT_COLOR_CONFIG = {
8939
8831
  if (remainingNodes.length > 0) {
8940
8832
  const nextNode = remainingNodes[0];
8941
8833
  if (!nextNode) break;
8942
- const testRow = [ ...currentRow, nextNode ], testRowValue = _reduceInstanceProperty(testRow).call(testRow, ((sum, n) => sum + n.value), 0), testRowRatio = testRowValue / totalValue;
8834
+ const testRow = [ ...currentRow, nextNode ], testRowValue = _reduceInstanceProperty(testRow).call(testRow, ((sum, n) => sum + n.value), 0), testRowRatio = remainingValue > 0 ? testRowValue / remainingValue : 0;
8943
8835
  let testRowWidth, testRowHeight;
8944
8836
  remainingWidth >= remainingHeight ? (testRowWidth = remainingWidth * testRowRatio,
8945
8837
  testRowHeight = remainingHeight) : (testRowWidth = remainingWidth, testRowHeight = remainingHeight * testRowRatio);
@@ -8970,14 +8862,14 @@ const DEFAULT_COLOR_CONFIG = {
8970
8862
  })),
8971
8863
  // Update remaining space
8972
8864
  remainingWidth >= remainingHeight ? (currentX += rowWidth, remainingWidth -= rowWidth) : (currentY += rowHeight,
8973
- remainingHeight -= rowHeight), currentRow = [];
8865
+ remainingHeight -= rowHeight), remainingValue -= rowValue, currentRow = [];
8974
8866
  }
8975
8867
  }
8976
- }), []), renderContent = React.useCallback((({scales: scales, colors: colors, datasets: renderedDatasets, handlers: handlers, hoveredPoint: hoveredPoint}) => {
8868
+ }), []), renderContent = React.useCallback((({scales: scales, colors: colors, datasets: renderedDatasets, handlers: handlers, hoveredPoint: hoveredPoint, toolbarState: toolbarState, config: renderConfig}) => {
8977
8869
  if (!data.length) return null;
8978
- // Calculate available space with padding
8979
- const availableWidth = scales.width - 40, availableHeight = scales.height - 40, leafNodes = data.filter((item => !item.children || 0 === item.children.length));
8980
- if (!leafNodes.length) return null;
8870
+ const showTooltips = toolbarState?.showTooltips ?? renderConfig?.showTooltips ?? !0, availableWidth = Math.max(0, scales.width), availableHeight = Math.max(0, scales.height), leafNodes = data.filter((item => !item.children || 0 === item.children.length));
8871
+ // Calculate available space
8872
+ if (!leafNodes.length) return null;
8981
8873
  const totalValue = _reduceInstanceProperty(leafNodes).call(leafNodes, ((sum, node) => sum + node.value), 0), treemapNodes = leafNodes.map(((item, index) => ({
8982
8874
  id: item.id,
8983
8875
  label: item.label,
@@ -8997,24 +8889,26 @@ const DEFAULT_COLOR_CONFIG = {
8997
8889
  })));
8998
8890
  // Create treemap nodes with proper dimensions
8999
8891
  // Apply squarified algorithm to layout nodes proportionally by value
9000
- if ("squarified" === algorithm && totalValue > 0) squarify(treemapNodes, 20, 20, availableWidth, availableHeight); else {
8892
+ if ("squarified" === algorithm && totalValue > 0) squarify(treemapNodes, 0, 0, availableWidth, availableHeight); else {
9001
8893
  // Fallback: simple grid layout (equal sizes)
9002
8894
  const cols = Math.ceil(Math.sqrt(leafNodes.length)), rows = Math.ceil(leafNodes.length / cols), nodeWidth = availableWidth / cols, nodeHeight = availableHeight / rows;
9003
8895
  treemapNodes.forEach(((node, index) => {
9004
8896
  const col = index % cols, row = Math.floor(index / cols);
9005
- node.x = 20 + col * nodeWidth, node.y = 20 + row * nodeHeight, node.width = nodeWidth,
8897
+ node.x = 0 + col * nodeWidth, node.y = 0 + row * nodeHeight, node.width = nodeWidth,
9006
8898
  node.height = nodeHeight;
9007
8899
  }));
9008
8900
  }
9009
- return jsxRuntime.jsx(jsxRuntime.Fragment, {
9010
- children: treemapNodes.map((node => {
8901
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, {
8902
+ children: [ treemapNodes.map((node => {
9011
8903
  const isHovered = hoveredNode === node, isSelected = selectedNode === node, area = node.width * node.height, showLabel = labelConfig.showLabels && area >= (labelConfig.minSize || 1e3);
9012
8904
  return jsxRuntime.jsxs("g", {
9013
8905
  children: [ jsxRuntime.jsx("rect", {
9014
- x: node.x,
9015
- y: node.y,
9016
- width: node.width,
9017
- height: node.height,
8906
+ x: node.x + 2,
8907
+ y: node.y + 2,
8908
+ width: Math.max(0, node.width - 4),
8909
+ height: Math.max(0, node.height - 4),
8910
+ rx: 6,
8911
+ ry: 6,
9018
8912
  fill: node.color,
9019
8913
  className: `c-chart__treemap-node ${isHovered ? "c-chart__treemap-node--hovered" : ""} ${isSelected ? "c-chart__treemap-node--selected" : ""}`,
9020
8914
  onClick: () => {
@@ -9022,8 +8916,8 @@ const DEFAULT_COLOR_CONFIG = {
9022
8916
  },
9023
8917
  onMouseEnter: e => {
9024
8918
  setHoveredNode(node);
9025
- const rect = e.currentTarget.getBoundingClientRect();
9026
- handlers.onPointHover(0, 0, node.x, node.y, rect.left + rect.width / 2, rect.top + rect.height / 2);
8919
+ const rect = e.currentTarget.getBoundingClientRect(), pointIndex = data.indexOf(node.originalData);
8920
+ handlers.onPointHover(0, pointIndex >= 0 ? pointIndex : 0, node.x, node.y, rect.left + rect.width / 2, rect.top + rect.height / 2);
9027
8921
  },
9028
8922
  onMouseLeave: () => {
9029
8923
  setHoveredNode(null), handlers.onPointLeave();
@@ -9035,13 +8929,21 @@ const DEFAULT_COLOR_CONFIG = {
9035
8929
  dominantBaseline: "middle",
9036
8930
  className: "c-chart__treemap-label",
9037
8931
  style: {
9038
- fontSize: labelConfig.fontSize,
9039
- fill: labelConfig.textColor
8932
+ fontSize: labelConfig.fontSize
9040
8933
  },
9041
8934
  children: node.label
9042
8935
  }) ]
9043
8936
  }, node.id);
9044
- }))
8937
+ })), showTooltips && hoveredPoint && renderedDatasets[hoveredPoint.datasetIndex]?.data?.[hoveredPoint.pointIndex] && jsxRuntime.jsx(ChartTooltip, {
8938
+ dataPoint: renderedDatasets[hoveredPoint.datasetIndex].data[hoveredPoint.pointIndex],
8939
+ datasetLabel: renderedDatasets[hoveredPoint.datasetIndex]?.label,
8940
+ datasetColor: renderedDatasets[hoveredPoint.datasetIndex]?.color || colors[hoveredPoint.datasetIndex % colors.length],
8941
+ position: {
8942
+ x: hoveredPoint.clientX,
8943
+ y: hoveredPoint.clientY
8944
+ },
8945
+ visible: !0
8946
+ }) ]
9045
8947
  });
9046
8948
  }), [ data, algorithm, generateColor, squarify, labelConfig, hoveredNode, selectedNode ]), datasets = React.useMemo((() => [ {
9047
8949
  label: "Treemap Data",
@@ -12373,96 +12275,6 @@ const DEFAULT_ATOMIX_FONTS = [ {
12373
12275
  };
12374
12276
  }
12375
12277
 
12376
- /**
12377
- * Custom hook for managing GlassContainer state and interactions
12378
- */ function useGlassContainer(props) {
12379
- const {glassSize: glassSize = {
12380
- width: 270,
12381
- height: 69
12382
- }, elasticity: elasticity = .15, mouseContainer: mouseContainer, globalMousePos: externalGlobalMousePos, mouseOffset: externalMouseOffset} = props, filterId = React.useId(), glassRef = React.useRef(null), [isHovered, setIsHovered] = React.useState(!1), [isActive, setIsActive] = React.useState(!1), [currentGlassSize, setCurrentGlassSize] = React.useState(glassSize), [internalGlobalMousePos, setInternalGlobalMousePos] = React.useState({
12383
- x: 0,
12384
- y: 0
12385
- }), [internalMouseOffset, setInternalMouseOffset] = React.useState({
12386
- x: 0,
12387
- y: 0
12388
- }), globalMousePos = externalGlobalMousePos || internalGlobalMousePos, mouseOffset = externalMouseOffset || internalMouseOffset, handleMouseMove = React.useCallback((e => {
12389
- const container = mouseContainer?.current || glassRef.current;
12390
- if (!container) return;
12391
- const rect = container.getBoundingClientRect(), centerX = rect.left + rect.width / 2, centerY = rect.top + rect.height / 2;
12392
- setInternalMouseOffset({
12393
- x: (e.clientX - centerX) / rect.width * 100,
12394
- y: (e.clientY - centerY) / rect.height * 100
12395
- }), setInternalGlobalMousePos({
12396
- x: e.clientX,
12397
- y: e.clientY
12398
- });
12399
- }), [ mouseContainer ]);
12400
- // Set up mouse tracking if no external mouse position is provided
12401
- React.useEffect((() => {
12402
- if (externalGlobalMousePos && externalMouseOffset) return;
12403
- const container = mouseContainer?.current || glassRef.current;
12404
- return container ? (container.addEventListener("mousemove", handleMouseMove), () => container.removeEventListener("mousemove", handleMouseMove)) : void 0;
12405
- }), [ handleMouseMove, mouseContainer, externalGlobalMousePos, externalMouseOffset ]);
12406
- // Calculate directional scaling based on mouse position
12407
- const calculateDirectionalScale = React.useCallback((() => {
12408
- if (!globalMousePos.x || !globalMousePos.y || !glassRef.current) return "scale(1)";
12409
- const rect = glassRef.current.getBoundingClientRect(), pillCenterX = rect.left + rect.width / 2, pillCenterY = rect.top + rect.height / 2, pillWidth = currentGlassSize.width, pillHeight = currentGlassSize.height, deltaX = globalMousePos.x - pillCenterX, deltaY = globalMousePos.y - pillCenterY, edgeDistanceX = Math.max(0, Math.abs(deltaX) - pillWidth / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - pillHeight / 2), edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY);
12410
- if (edgeDistance > 200) return "scale(1)";
12411
- const fadeInFactor = 1 - edgeDistance / 200, centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
12412
- if (0 === centerDistance) return "scale(1)";
12413
- const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15;
12414
- return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
12415
- }), [ globalMousePos, elasticity, currentGlassSize ]), calculateElasticTranslation = React.useCallback((() => {
12416
- if (!glassRef.current) return {
12417
- x: 0,
12418
- y: 0
12419
- };
12420
- const rect = glassRef.current.getBoundingClientRect(), pillCenterX = rect.left + rect.width / 2, pillCenterY = rect.top + rect.height / 2, pillWidth = currentGlassSize.width, pillHeight = currentGlassSize.height, edgeDistanceX = Math.max(0, Math.abs(globalMousePos.x - pillCenterX) - pillWidth / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePos.y - pillCenterY) - pillHeight / 2), edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY), fadeInFactor = edgeDistance > 200 ? 0 : 1 - edgeDistance / 200;
12421
- return {
12422
- x: (globalMousePos.x - pillCenterX) * elasticity * .1 * fadeInFactor,
12423
- y: (globalMousePos.y - pillCenterY) * elasticity * .1 * fadeInFactor
12424
- };
12425
- }), [ globalMousePos, elasticity, currentGlassSize ]);
12426
- // Calculate elastic translation
12427
- // Update glass size
12428
- React.useEffect((() => {
12429
- const updateGlassSize = () => {
12430
- if (glassRef.current) {
12431
- const rect = glassRef.current.getBoundingClientRect();
12432
- setCurrentGlassSize({
12433
- width: rect.width,
12434
- height: rect.height
12435
- });
12436
- }
12437
- };
12438
- return updateGlassSize(), window.addEventListener("resize", updateGlassSize), () => window.removeEventListener("resize", updateGlassSize);
12439
- }), []);
12440
- const handleMouseEnter = React.useCallback((() => {
12441
- setIsHovered(!0);
12442
- }), []), handleMouseLeave = React.useCallback((() => {
12443
- setIsHovered(!1);
12444
- }), []), handleMouseDown = React.useCallback((() => {
12445
- setIsActive(!0);
12446
- }), []), handleMouseUp = React.useCallback((() => {
12447
- setIsActive(!1);
12448
- }), []);
12449
- return {
12450
- filterId: filterId,
12451
- glassRef: glassRef,
12452
- isHovered: isHovered,
12453
- isActive: isActive,
12454
- currentGlassSize: currentGlassSize,
12455
- globalMousePos: globalMousePos,
12456
- mouseOffset: mouseOffset,
12457
- calculateDirectionalScale: calculateDirectionalScale,
12458
- calculateElasticTranslation: calculateElasticTranslation,
12459
- handleMouseEnter: handleMouseEnter,
12460
- handleMouseLeave: handleMouseLeave,
12461
- handleMouseDown: handleMouseDown,
12462
- handleMouseUp: handleMouseUp
12463
- };
12464
- }
12465
-
12466
12278
  /**
12467
12279
  * Radio state and functionality
12468
12280
  * @param initialProps - Initial radio properties
@@ -12955,7 +12767,6 @@ var composablesImport = Object.freeze({
12955
12767
  useEdgePanel: useEdgePanel,
12956
12768
  useForm: useForm,
12957
12769
  useFormGroup: useFormGroup,
12958
- useGlassContainer: useGlassContainer,
12959
12770
  useHero: useHero,
12960
12771
  useInput: useInput,
12961
12772
  useLineChart: useLineChart,
@@ -15035,17 +14846,18 @@ const Navbar = React.forwardRef((({brand: brand, children: children, variant: v
15035
14846
  }, glassProps = !0 === glass ? defaultGlassProps : {
15036
14847
  ...defaultGlassProps,
15037
14848
  ...glass
15038
- };
14849
+ }, isFixed = "fixed" === position || "fixed-bottom" === position;
15039
14850
  return jsxRuntime.jsx(AtomixGlass, {
15040
14851
  ...glassProps,
15041
14852
  style: {
15042
- ..."fixed" === position && {
15043
- position: "fixed"
15044
- },
15045
- left: 0,
15046
- right: 0,
15047
- top: 0,
15048
- zIndex: 1e3
14853
+ ...isFixed && {
14854
+ position: "fixed",
14855
+ top: "fixed" === position ? 0 : void 0,
14856
+ bottom: "fixed-bottom" === position ? 0 : void 0,
14857
+ left: 0,
14858
+ right: 0,
14859
+ zIndex: 1030
14860
+ }
15049
14861
  },
15050
14862
  children: jsxRuntime.jsx("nav", {
15051
14863
  ref: ref,
@@ -19435,7 +19247,6 @@ VideoPlayer.displayName = "VideoPlayer";
19435
19247
  var components = Object.freeze({
19436
19248
  __proto__: null,
19437
19249
  Accordion: Accordion,
19438
- AnimatedChart: AnimatedChart,
19439
19250
  AreaChart: AreaChart,
19440
19251
  AtomixGlass: AtomixGlass,
19441
19252
  AtomixLogo: AtomixLogo,
@@ -25219,11 +25030,11 @@ const composables = composablesImport, utils = utilsImport, types = typesImport,
25219
25030
  };
25220
25031
 
25221
25032
  exports.ACCORDION = ACCORDION, exports.ATOMIX_GLASS = ATOMIX_GLASS, exports.AVATAR = AVATAR,
25222
- exports.AVATAR_GROUP = AVATAR_GROUP, exports.Accordion = Accordion, exports.AnimatedChart = AnimatedChart,
25223
- exports.AreaChart = AreaChart, exports.AtomixGlass = AtomixGlass, exports.AtomixLogo = AtomixLogo,
25224
- exports.Avatar = Avatar, exports.AvatarGroup = AvatarGroup, exports.BADGE = BADGE,
25225
- exports.BADGE_CSS_VARS = BADGE_CSS_VARS, exports.BLOCK = BLOCK, exports.BREADCRUMB = BREADCRUMB,
25226
- exports.BUTTON = BUTTON, exports.BUTTON_CSS_VARS = BUTTON_CSS_VARS, exports.BUTTON_GROUP = BUTTON_GROUP,
25033
+ exports.AVATAR_GROUP = AVATAR_GROUP, exports.Accordion = Accordion, exports.AreaChart = AreaChart,
25034
+ exports.AtomixGlass = AtomixGlass, exports.AtomixLogo = AtomixLogo, exports.Avatar = Avatar,
25035
+ exports.AvatarGroup = AvatarGroup, exports.BADGE = BADGE, exports.BADGE_CSS_VARS = BADGE_CSS_VARS,
25036
+ exports.BLOCK = BLOCK, exports.BREADCRUMB = BREADCRUMB, exports.BUTTON = BUTTON,
25037
+ exports.BUTTON_CSS_VARS = BUTTON_CSS_VARS, exports.BUTTON_GROUP = BUTTON_GROUP,
25227
25038
  exports.Badge = Badge, exports.BarChart = BarChart, exports.Block = Block, exports.Breadcrumb = Breadcrumb,
25228
25039
  exports.BubbleChart = BubbleChart, exports.Button = Button, exports.ButtonGroup = ButtonGroup,
25229
25040
  exports.CALLOUT = CALLOUT, exports.CARD = CARD, exports.CARD_CSS_VARS = CARD_CSS_VARS,
@@ -25595,8 +25406,8 @@ function(component, props) {
25595
25406
  * Hook to merge default props with provided props
25596
25407
  */ , exports.useComponentTheme = useComponentTheme, exports.useDataTable = useDataTable,
25597
25408
  exports.useEdgePanel = useEdgePanel, exports.useForm = useForm, exports.useFormGroup = useFormGroup,
25598
- exports.useGlassContainer = useGlassContainer, exports.useHero = useHero, exports.useHistory = useHistory,
25599
- exports.useInput = useInput, exports.useLineChart = useLineChart, exports.useMergedProps = function(defaultProps, props) {
25409
+ exports.useHero = useHero, exports.useHistory = useHistory, exports.useInput = useInput,
25410
+ exports.useLineChart = useLineChart, exports.useMergedProps = function(defaultProps, props) {
25600
25411
  return React.useMemo((() => ({
25601
25412
  ...defaultProps,
25602
25413
  ...props