@shohojdhara/atomix 0.4.1 → 0.4.2

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 (126) hide show
  1. package/dist/atomix.css +9341 -9249
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +4 -4
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/charts.d.ts +12 -19
  6. package/dist/charts.js +555 -358
  7. package/dist/charts.js.map +1 -1
  8. package/dist/core.d.ts +16 -23
  9. package/dist/core.js +418 -262
  10. package/dist/core.js.map +1 -1
  11. package/dist/forms.d.ts +11 -18
  12. package/dist/forms.js +411 -257
  13. package/dist/forms.js.map +1 -1
  14. package/dist/heavy.d.ts +14 -21
  15. package/dist/heavy.js +408 -254
  16. package/dist/heavy.js.map +1 -1
  17. package/dist/index.d.ts +33 -40
  18. package/dist/index.esm.js +663 -453
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/index.js +667 -460
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.min.js +1 -1
  23. package/dist/index.min.js.map +1 -1
  24. package/package.json +1 -1
  25. package/scripts/atomix-cli.js +34 -1
  26. package/src/components/AtomixGlass/AtomixGlass.tsx +82 -54
  27. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +17 -18
  28. package/src/components/AtomixGlass/README.md +5 -5
  29. package/src/components/AtomixGlass/stories/Customization.stories.tsx +2 -2
  30. package/src/components/AtomixGlass/stories/Examples.stories.tsx +42 -42
  31. package/src/components/AtomixGlass/stories/Modes.stories.tsx +5 -5
  32. package/src/components/AtomixGlass/stories/Overview.stories.tsx +3 -3
  33. package/src/components/AtomixGlass/stories/Performance.stories.tsx +2 -2
  34. package/src/components/AtomixGlass/stories/Playground.stories.tsx +45 -45
  35. package/src/components/AtomixGlass/stories/Shaders.stories.tsx +3 -3
  36. package/src/components/Badge/Badge.stories.tsx +1 -1
  37. package/src/components/Badge/Badge.tsx +1 -1
  38. package/src/components/Breadcrumb/Breadcrumb.tsx +90 -76
  39. package/src/components/Breadcrumb/index.ts +2 -2
  40. package/src/components/Button/Button.stories.tsx +1 -1
  41. package/src/components/Button/README.md +2 -2
  42. package/src/components/Callout/Callout.test.tsx +3 -3
  43. package/src/components/Callout/Callout.tsx +2 -2
  44. package/src/components/Callout/README.md +2 -2
  45. package/src/components/Chart/Chart.stories.tsx +1 -1
  46. package/src/components/Chart/Chart.tsx +5 -5
  47. package/src/components/Chart/TreemapChart.tsx +37 -29
  48. package/src/components/DatePicker/readme.md +3 -3
  49. package/src/components/Dropdown/Dropdown.stories.tsx +1 -1
  50. package/src/components/EdgePanel/EdgePanel.stories.tsx +7 -7
  51. package/src/components/Form/Checkbox.stories.tsx +1 -1
  52. package/src/components/Form/Checkbox.tsx +1 -1
  53. package/src/components/Form/Input.stories.tsx +1 -1
  54. package/src/components/Form/Input.tsx +1 -1
  55. package/src/components/Form/Radio.stories.tsx +1 -1
  56. package/src/components/Form/Radio.tsx +1 -1
  57. package/src/components/Form/Select.stories.tsx +1 -1
  58. package/src/components/Form/Select.tsx +1 -1
  59. package/src/components/Form/Textarea.stories.tsx +1 -1
  60. package/src/components/Form/Textarea.tsx +1 -1
  61. package/src/components/Hero/Hero.stories.tsx +2 -2
  62. package/src/components/Hero/Hero.tsx +2 -2
  63. package/src/components/Messages/Messages.stories.tsx +1 -1
  64. package/src/components/Messages/Messages.tsx +2 -2
  65. package/src/components/Modal/Modal.stories.tsx +1 -1
  66. package/src/components/Navigation/Nav/Nav.stories.tsx +2 -2
  67. package/src/components/Navigation/Nav/Nav.tsx +1 -1
  68. package/src/components/Navigation/Navbar/Navbar.stories.tsx +3 -3
  69. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  70. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +2 -2
  71. package/src/components/Navigation/SideMenu/SideMenu.tsx +1 -1
  72. package/src/components/Pagination/Pagination.stories.tsx +1 -1
  73. package/src/components/Pagination/Pagination.tsx +1 -1
  74. package/src/components/Popover/Popover.stories.tsx +1 -1
  75. package/src/components/Popover/Popover.tsx +1 -1
  76. package/src/components/Progress/Progress.tsx +1 -1
  77. package/src/components/Rating/Rating.stories.tsx +1 -1
  78. package/src/components/Rating/Rating.test.tsx +73 -0
  79. package/src/components/Rating/Rating.tsx +25 -37
  80. package/src/components/Spinner/Spinner.tsx +1 -1
  81. package/src/components/Steps/Steps.stories.tsx +1 -1
  82. package/src/components/Steps/Steps.tsx +2 -2
  83. package/src/components/Tabs/Tabs.stories.tsx +1 -1
  84. package/src/components/Tabs/Tabs.tsx +1 -1
  85. package/src/components/Todo/Todo.tsx +0 -1
  86. package/src/components/Toggle/Toggle.stories.tsx +1 -1
  87. package/src/components/Toggle/Toggle.tsx +1 -1
  88. package/src/components/Tooltip/Tooltip.stories.tsx +1 -1
  89. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +2 -2
  90. package/src/lib/composables/__tests__/useAtomixGlassPerf.test.tsx +88 -0
  91. package/src/lib/composables/__tests__/useChart.test.ts +50 -0
  92. package/src/lib/composables/__tests__/useChart.test.tsx +139 -0
  93. package/src/lib/composables/__tests__/useHeroBackgroundSlider.test.tsx +59 -0
  94. package/src/lib/composables/__tests__/useSliderAutoplay.test.tsx +68 -0
  95. package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +329 -0
  96. package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +82 -0
  97. package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +153 -0
  98. package/src/lib/composables/atomix-glass/useGlassOverLight.ts +198 -0
  99. package/src/lib/composables/atomix-glass/useGlassSize.ts +117 -0
  100. package/src/lib/composables/atomix-glass/useGlassState.ts +112 -0
  101. package/src/lib/composables/atomix-glass/useGlassTransforms.ts +160 -0
  102. package/src/lib/composables/glass-styles.ts +302 -0
  103. package/src/lib/composables/index.ts +0 -4
  104. package/src/lib/composables/useAtomixGlass.ts +331 -522
  105. package/src/lib/composables/useAtomixGlassStyles.ts +307 -0
  106. package/src/lib/composables/useBarChart.ts +1 -1
  107. package/src/lib/composables/useBreadcrumb.ts +6 -6
  108. package/src/lib/composables/useChart.ts +104 -21
  109. package/src/lib/composables/useHeroBackgroundSlider.ts +16 -7
  110. package/src/lib/composables/useSlider.ts +66 -34
  111. package/src/lib/theme/devtools/CLI.ts +1 -1
  112. package/src/lib/theme/utils/__tests__/themeUtils.test.ts +213 -0
  113. package/src/lib/types/components.ts +13 -21
  114. package/src/lib/utils/__tests__/dom.test.ts +100 -0
  115. package/src/lib/utils/__tests__/fontPreloader.test.ts +102 -0
  116. package/src/styles/02-tools/_tools.breakpoints.scss +1 -1
  117. package/src/styles/02-tools/_tools.utility-api.scss +6 -6
  118. package/src/styles/06-components/_components.accordion.scss +0 -2
  119. package/src/styles/06-components/_components.chart.scss +0 -1
  120. package/src/styles/06-components/_components.dropdown.scss +0 -1
  121. package/src/styles/06-components/_components.edge-panel.scss +0 -2
  122. package/src/styles/06-components/_components.photoviewer.scss +0 -1
  123. package/src/styles/06-components/_components.river.scss +0 -1
  124. package/src/styles/06-components/_components.slider.scss +0 -3
  125. package/src/styles/99-utilities/_utilities.glass-fixes.scss +0 -1
  126. package/src/styles/99-utilities/_utilities.text.scss +1 -0
package/dist/index.esm.js CHANGED
@@ -1949,7 +1949,7 @@ function useAccordion(initialProps) {
1949
1949
  };
1950
1950
  }
1951
1951
 
1952
- const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2) => {
1952
+ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2) => {
1953
1953
  if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
1954
1954
  const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
1955
1955
  return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
@@ -1962,36 +1962,36 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
1962
1962
  }, calculateMouseInfluence = mouseOffset => {
1963
1963
  if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
1964
1964
  // Bounded calculation — keeps the glass effect subtle and stable
1965
- const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$1.MOUSE_INFLUENCE_DIVISOR;
1965
+ const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$2.MOUSE_INFLUENCE_DIVISOR;
1966
1966
  return Math.min(.8, influence);
1967
1967
  // Tighter cap to prevent blur/filter blow-out
1968
- }, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$1.MIN_BLUR : Math.max(CONSTANTS$1.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$1.MAX_SIZE && size.height <= CONSTANTS$1.MAX_SIZE, parseBorderRadiusValue = value => {
1968
+ }, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$2.MIN_BLUR : Math.max(CONSTANTS$2.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$2.MAX_SIZE && size.height <= CONSTANTS$2.MAX_SIZE, parseBorderRadiusValue = value => {
1969
1969
  if ("number" == typeof value) return Math.max(0, value);
1970
- if ("string" != typeof value || !value.trim()) return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
1970
+ if ("string" != typeof value || !value.trim()) return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
1971
1971
  const trimmedValue = value.trim();
1972
1972
  // Handle px values
1973
1973
  if (trimmedValue.endsWith("px")) {
1974
1974
  const parsed = parseFloat(trimmedValue);
1975
- return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
1975
+ return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
1976
1976
  }
1977
1977
  // Handle rem values (assume 16px = 1rem)
1978
1978
  if (trimmedValue.endsWith("rem")) {
1979
1979
  const parsed = parseFloat(trimmedValue);
1980
- return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
1980
+ return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
1981
1981
  }
1982
1982
  // Handle em values (assume 16px = 1em for simplicity)
1983
1983
  if (trimmedValue.endsWith("em")) {
1984
1984
  const parsed = parseFloat(trimmedValue);
1985
- return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
1985
+ return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
1986
1986
  }
1987
1987
  // Handle percentage (convert to approximate px value, assuming 200px container)
1988
1988
  if (trimmedValue.endsWith("%")) {
1989
1989
  const parsed = parseFloat(trimmedValue);
1990
- return isNaN(parsed) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
1990
+ return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
1991
1991
  }
1992
1992
  // Handle unitless numbers
1993
1993
  const numValue = parseFloat(trimmedValue);
1994
- return isNaN(numValue) ? CONSTANTS$1.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
1994
+ return isNaN(numValue) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
1995
1995
  }, extractBorderRadiusFromElement = element => {
1996
1996
  if (!element || !element.props) return null;
1997
1997
  // Check inline styles first (highest priority)
@@ -2007,11 +2007,11 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
2007
2007
  // If element has children, recursively check them
2008
2008
  if (element.props.children) {
2009
2009
  const childRadius = extractBorderRadiusFromChildren(element.props.children);
2010
- if (childRadius > 0 && childRadius !== CONSTANTS$1.DEFAULT_CORNER_RADIUS) return childRadius;
2010
+ if (childRadius > 0 && childRadius !== CONSTANTS$2.DEFAULT_CORNER_RADIUS) return childRadius;
2011
2011
  }
2012
2012
  return null;
2013
2013
  }, extractBorderRadiusFromChildren = children => {
2014
- if (!children) return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
2014
+ if (!children) return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
2015
2015
  try {
2016
2016
  const childArray = React.Children.toArray(children);
2017
2017
  for (let i = 0; i < childArray.length; i++) {
@@ -2024,7 +2024,7 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
2024
2024
  } catch (error) {
2025
2025
  // Silently handle errors
2026
2026
  }
2027
- return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
2027
+ return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
2028
2028
  }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
2029
2029
  switch (mode) {
2030
2030
  case "standard":
@@ -2195,10 +2195,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2195
2195
  }, globalMousePosition: globalMousePosition = {
2196
2196
  x: 0,
2197
2197
  y: 0
2198
- }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, cornerRadius: cornerRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
2198
+ }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
2199
2199
  width: 0,
2200
2200
  height: 0
2201
- }, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
2201
+ }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
2202
2202
  // Generate a stable, deterministic ID for SSR compatibility
2203
2203
  // Use a module-level counter that's consistent across server and client
2204
2204
  const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
@@ -2308,7 +2308,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2308
2308
  flowBlur: 1.2 * blurAmount
2309
2309
  };
2310
2310
  // Enhanced validation for liquid blur
2311
- if (!enableLiquidBlur || !rectCache || !mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y || isNaN(mouseOffset.x) || isNaN(mouseOffset.y)) return defaultBlur;
2311
+ if (!withLiquidBlur || !rectCache || !mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y || isNaN(mouseOffset.x) || isNaN(mouseOffset.y)) return defaultBlur;
2312
2312
  try {
2313
2313
  const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = 2 * blurAmount, baseBlur = Math.min(maxBlur, blurAmount + mouseInfluence * blurAmount * .15), edgeIntensity = .15 * mouseInfluence, edgeBlur = Math.min(maxBlur, baseBlur * (.8 + .4 * edgeIntensity)), centerIntensity = .1 * mouseInfluence, centerBlur = Math.min(maxBlur, baseBlur * (.3 + .3 * centerIntensity)), flowBlur = Math.min(maxBlur, 1.2 * baseBlur);
2314
2314
  // NOTE: hover/active multipliers intentionally omitted here —
@@ -2323,14 +2323,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2323
2323
  return console.warn("AtomixGlassContainer: Error calculating liquid blur", error),
2324
2324
  defaultBlur;
2325
2325
  }
2326
- }), [ enableLiquidBlur, blurAmount, mouseOffset, rectCache ]), backdropStyle = useMemo((() => {
2326
+ }), [ withLiquidBlur, blurAmount, mouseOffset, rectCache ]), backdropStyle = useMemo((() => {
2327
2327
  try {
2328
2328
  const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), validatedBaseBlur = "number" != typeof liquidBlur.baseBlur || isNaN(liquidBlur.baseBlur) ? 0 : liquidBlur.baseBlur, validatedEdgeBlur = "number" != typeof liquidBlur.edgeBlur || isNaN(liquidBlur.edgeBlur) ? 0 : liquidBlur.edgeBlur, validatedCenterBlur = "number" != typeof liquidBlur.centerBlur || isNaN(liquidBlur.centerBlur) ? 0 : liquidBlur.centerBlur, validatedFlowBlur = "number" != typeof liquidBlur.flowBlur || isNaN(liquidBlur.flowBlur) ? 0 : liquidBlur.flowBlur, area = rectCache ? rectCache.width * rectCache.height : 0;
2329
2329
  // Validate blur values before using them
2330
- return !enableLiquidBlur || effectiveReducedMotion || effectiveDisableEffects || area > 18e4 ? {
2330
+ return !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? {
2331
2331
  backdropFilter: `blur(${clampBlur(Math.max(validatedBaseBlur, .8 * validatedEdgeBlur, 1.1 * validatedCenterBlur, .9 * validatedFlowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1.05}) brightness(${overLightConfig?.brightness || 1.05})`
2332
2332
  } : {
2333
- backdropFilter: `blur(${clampBlur(.4 * validatedBaseBlur + .25 * validatedEdgeBlur + .15 * validatedCenterBlur + .2 * validatedFlowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1.05}) brightness(${overLightConfig?.brightness || 1.05})`
2333
+ backdropFilter: `blur(${clampBlur(.4 * validatedBaseBlur + .25 * validatedEdgeBlur + .15 * validatedCenterBlur + .2 * validatedFlowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1}) brightness(${overLightConfig?.brightness || 1})`
2334
2334
  };
2335
2335
  // Single-pass fallback: stronger radius to match perceived blur of multi-pass
2336
2336
  } catch (error) {
@@ -2339,7 +2339,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2339
2339
  backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
2340
2340
  };
2341
2341
  }
2342
- }), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveDisableEffects, enableLiquidBlur ]), containerVars = useMemo((() => {
2342
+ }), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveWithoutEffects, withLiquidBlur ]), containerVars = useMemo((() => {
2343
2343
  try {
2344
2344
  // Safe extraction of mouse offset values
2345
2345
  const mx = mouseOffset && "number" == typeof mouseOffset.x && !isNaN(mouseOffset.x) ? mouseOffset.x : 0, my = mouseOffset && "number" == typeof mouseOffset.y && !isNaN(mouseOffset.y) ? mouseOffset.y : 0;
@@ -2347,10 +2347,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2347
2347
  "--atomix-glass-container-width": `${glassSize?.width}`,
2348
2348
  "--atomix-glass-container-height": `${glassSize?.height}`,
2349
2349
  "--atomix-glass-container-padding": padding || "0 0",
2350
- "--atomix-glass-container-radius": `${"number" != typeof cornerRadius || isNaN(cornerRadius) ? 0 : cornerRadius}px`,
2350
+ "--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`,
2351
2351
  "--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
2352
2352
  "--atomix-glass-container-shadow": overLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.4 + .002 * mx) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.2 + .001 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.08 + .001 * Math.abs(mx + my)) * (overLightConfig?.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.12 + .002 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset",
2353
- "--atomix-glass-container-shadow-opacity": effectiveDisableEffects ? 0 : 1,
2353
+ "--atomix-glass-container-shadow-opacity": effectiveWithoutEffects ? 0 : 1,
2354
2354
  // Background and shadow values use design token-aligned RGB values
2355
2355
  "--atomix-glass-container-bg": overLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none",
2356
2356
  "--atomix-glass-container-text-shadow": overLight ? "0px 2px 12px rgba(0, 0, 0, 0)" : "0px 2px 12px rgba(0, 0, 0, 0.4)",
@@ -2368,14 +2368,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2368
2368
  "--atomix-glass-container-text-shadow": "none"
2369
2369
  };
2370
2370
  }
2371
- }), [ glassSize, padding, cornerRadius, backdropStyle, mouseOffset, overLight, effectiveDisableEffects ]), setForceNoTransition = el => {
2372
- el && (el.style.setProperty("transition-duration", "0s", "important"), el.style.setProperty("animation-duration", "0s", "important"),
2373
- el.style.setProperty("transition-delay", "0s", "important"));
2374
- };
2371
+ }), [ glassSize, padding, borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects ]);
2375
2372
  return jsx("div", {
2376
2373
  ref: el => {
2377
2374
  // Apply force no-transition
2378
- setForceNoTransition(el),
2379
2375
  // Handle forwarded ref
2380
2376
  "function" == typeof ref ? ref(el) : ref && (ref.current = el);
2381
2377
  },
@@ -2410,7 +2406,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
2410
2406
  aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
2411
2407
  shaderMapUrl: shaderMapUrl
2412
2408
  }), jsx("div", {
2413
- ref: setForceNoTransition,
2409
+ ref: el => {
2410
+ el && (el.style.setProperty("transition-duration", "0s", "important"), el.style.setProperty("animation-duration", "0s", "important"),
2411
+ el.style.setProperty("transition-delay", "0s", "important"));
2412
+ },
2414
2413
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
2415
2414
  style: {
2416
2415
  filter: `url(#${filterId})`,
@@ -2527,7 +2526,128 @@ class {
2527
2526
  */ getSubscriberCount() {
2528
2527
  return this.listeners.size;
2529
2528
  }
2530
- }, {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
2529
+ }, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
2530
+ if (!wrapperElement && !containerElement) return;
2531
+ const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, directionalScale: directionalScale, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
2532
+ opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
2533
+ contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
2534
+ brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
2535
+ shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
2536
+ borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
2537
+ saturationBoost: baseOverLightConfig.saturationBoost
2538
+ };
2539
+ // Calculate mouse influence
2540
+ // Calculate elastic translation
2541
+ let elasticTranslation = {
2542
+ x: 0,
2543
+ y: 0
2544
+ };
2545
+ if (!effectiveWithoutEffects && wrapperElement) {
2546
+ const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
2547
+ // Calculate fade in factor
2548
+ let fadeInFactor = 0;
2549
+ if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
2550
+ 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({
2551
+ x: edgeDistanceX,
2552
+ y: edgeDistanceY
2553
+ }, {
2554
+ x: 0,
2555
+ y: 0
2556
+ });
2557
+ fadeInFactor = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
2558
+ }
2559
+ elasticTranslation = {
2560
+ x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
2561
+ y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
2562
+ };
2563
+ }
2564
+ 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}`;
2565
+ // Update Wrapper Styles (glassVars)
2566
+ if (wrapperElement) {
2567
+ 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 = {
2568
+ hover1: {
2569
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
2570
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
2571
+ },
2572
+ hover2: {
2573
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
2574
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2
2575
+ },
2576
+ hover3: {
2577
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
2578
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3
2579
+ }
2580
+ }, basePosition = {
2581
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
2582
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
2583
+ }, opacityValues = {
2584
+ hover1: isHovered || isActive ? .5 : 0,
2585
+ hover2: isActive ? .5 : 0,
2586
+ hover3: isHovered ? .4 : isActive ? .8 : 0,
2587
+ base: isOverLight ? overLightConfig.opacity : 0,
2588
+ over: isOverLight ? 1.1 * overLightConfig.opacity : 0
2589
+ }, style = wrapperElement.style;
2590
+ style.setProperty("--atomix-glass-transform", transformStyle || "none"),
2591
+ // Gradients
2592
+ style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
2593
+ style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
2594
+ // Hover gradients
2595
+ style.setProperty("--atomix-glass-hover-1-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 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}%)`),
2596
+ style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 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}%)`),
2597
+ style.setProperty("--atomix-glass-hover-3-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(${blackColor}, 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}%)`),
2598
+ style.setProperty("--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})`),
2599
+ style.setProperty("--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})`),
2600
+ // Opacities
2601
+ style.setProperty("--atomix-glass-hover-1-opacity", opacityValues.hover1.toString()),
2602
+ style.setProperty("--atomix-glass-hover-2-opacity", opacityValues.hover2.toString()),
2603
+ style.setProperty("--atomix-glass-hover-3-opacity", opacityValues.hover3.toString()),
2604
+ style.setProperty("--atomix-glass-base-opacity", opacityValues.base.toString()),
2605
+ style.setProperty("--atomix-glass-overlay-opacity", opacityValues.over.toString()),
2606
+ style.setProperty("--atomix-glass-overlay-highlight-opacity", (opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER).toString()),
2607
+ // Other
2608
+ style.setProperty("--atomix-glass-blend-mode", isOverLight ? "multiply" : "overlay"),
2609
+ style.setProperty("--atomix-glass-radius", `${effectiveBorderRadius}px`);
2610
+ }
2611
+ // Update Container Styles (containerVars)
2612
+ if (containerElement) {
2613
+ const mx = mouseOffset.x, my = mouseOffset.y, EDGE_BLUR_MULTIPLIER = 1.25, CENTER_BLUR_MULTIPLIER = 1.1, FLOW_BLUR_MULTIPLIER = 1.2, MOUSE_INFLUENCE_BLUR_FACTOR = .15, EDGE_INTENSITY_MOUSE_FACTOR = .15, CENTER_INTENSITY_MOUSE_FACTOR = .1, MAX_BLUR_RELATIVE = 2, rect = containerElement.getBoundingClientRect();
2614
+ let liquidBlur = {
2615
+ baseBlur: blurAmount,
2616
+ edgeBlur: blurAmount * EDGE_BLUR_MULTIPLIER,
2617
+ centerBlur: blurAmount * CENTER_BLUR_MULTIPLIER,
2618
+ flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
2619
+ };
2620
+ if (withLiquidBlur && rect) {
2621
+ const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur = Math.min(maxBlur, blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR), edgeIntensity = mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR, edgeBlur = Math.min(maxBlur, baseBlur * (.8 + .4 * edgeIntensity)), centerIntensity = mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR, centerBlur = Math.min(maxBlur, baseBlur * (.3 + .3 * centerIntensity)), flowBlur = Math.min(maxBlur, baseBlur * FLOW_BLUR_MULTIPLIER);
2622
+ liquidBlur = {
2623
+ baseBlur: clampBlur(baseBlur),
2624
+ edgeBlur: clampBlur(edgeBlur),
2625
+ centerBlur: clampBlur(centerBlur),
2626
+ flowBlur: clampBlur(flowBlur)
2627
+ };
2628
+ }
2629
+ // Backdrop filter
2630
+ let backdropFilterString = `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`;
2631
+ const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), area = rect ? rect.width * rect.height : 0;
2632
+ backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})`;
2633
+ // Container variables
2634
+ const style = containerElement.style;
2635
+ style.setProperty("--atomix-glass-container-width", `${glassSize.width}`), style.setProperty("--atomix-glass-container-height", `${glassSize.height}`),
2636
+ style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
2637
+ style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
2638
+ // Shadows
2639
+ style.setProperty("--atomix-glass-container-shadow", isOverLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.4 + .002 * mx) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.2 + .001 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.08 + .001 * Math.abs(mx + my)) * (overLightConfig.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.12 + .002 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset"),
2640
+ style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
2641
+ style.setProperty("--atomix-glass-container-bg", isOverLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none"),
2642
+ style.setProperty("--atomix-glass-container-text-shadow", isOverLight ? "0px 2px 12px rgba(0, 0, 0, 0)" : "0px 2px 12px rgba(0, 0, 0, 0.4)"),
2643
+ style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)");
2644
+ }
2645
+ }, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
2646
+
2647
+ /**
2648
+ * Updates the styles of the AtomixGlass wrapper and container elements imperatively
2649
+ * to avoid React re-renders on mouse movement.
2650
+ */ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
2531
2651
  parentElement && backgroundDetectionCache.set(parentElement, {
2532
2652
  result: result,
2533
2653
  timestamp: Date.now(),
@@ -2540,18 +2660,74 @@ class {
2540
2660
  * Composable hook for AtomixGlass component logic
2541
2661
  * Manages all state, calculations, and event handlers
2542
2662
  */
2543
- function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadius: cornerRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, disableEffects: disableEffects = !1, elasticity: elasticity = .05, onClick: onClick, debugCornerRadius: debugCornerRadius = !1, debugOverLight: debugOverLight = !1, children: children}) {
2663
+ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, elasticity: elasticity = .05, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, debugPerformance: debugPerformance = !1, children: children, blurAmount: blurAmount, saturation: saturation, padding: padding, withLiquidBlur: withLiquidBlur}) {
2544
2664
  // State
2545
- const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), [glassSize, setGlassSize] = useState({
2546
- width: 270,
2547
- height: 69
2548
- }), [internalGlobalMousePosition, setInternalGlobalMousePosition] = useState({
2665
+ const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
2549
2666
  x: 0,
2550
2667
  y: 0
2551
- }), [internalMouseOffset, setInternalMouseOffset] = useState({
2668
+ }), internalMouseOffsetRef = useRef({
2552
2669
  x: 0,
2553
2670
  y: 0
2554
- }), [dynamicCornerRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveCornerRadius = useMemo((() => void 0 !== cornerRadius ? Math.max(0, cornerRadius) : Math.max(0, dynamicCornerRadius)), [ cornerRadius, dynamicCornerRadius ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveDisableEffects = useMemo((() => disableEffects || effectiveReducedMotion), [ disableEffects, effectiveReducedMotion ]), globalMousePosition = useMemo((() => externalGlobalMousePosition || internalGlobalMousePosition), [ externalGlobalMousePosition, internalGlobalMousePosition ]), mouseOffset = useMemo((() => externalMouseOffset || internalMouseOffset), [ externalMouseOffset, internalMouseOffset ]);
2671
+ }), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
2672
+ const [glassSize, setGlassSize] = useState({
2673
+ width: 270,
2674
+ height: 69
2675
+ });
2676
+ return useEffect((() => {
2677
+ const isValidElement = element => null !== element && element instanceof HTMLElement && element.isConnected;
2678
+ let rafId = null, lastSize = {
2679
+ width: 0,
2680
+ height: 0
2681
+ }, lastCornerRadius = effectiveBorderRadius;
2682
+ const updateGlassSize = (forceUpdate = !1) => {
2683
+ null !== rafId && cancelAnimationFrame(rafId), rafId = requestAnimationFrame((() => {
2684
+ if (!isValidElement(glassRef.current)) return void (rafId = null);
2685
+ const rect = glassRef.current.getBoundingClientRect();
2686
+ if (rect.width <= 0 || rect.height <= 0) return void (rafId = null);
2687
+ // Measure actual rendered size without artificial offsets to avoid feedback loops
2688
+ const newSize = {
2689
+ width: Math.round(rect.width),
2690
+ height: Math.round(rect.height)
2691
+ }, cornerRadiusChanged = lastCornerRadius !== effectiveBorderRadius, dimensionsChanged = Math.abs(newSize.width - lastSize.width) > 1 || Math.abs(newSize.height - lastSize.height) > 1;
2692
+ var size;
2693
+ (forceUpdate || cornerRadiusChanged || dimensionsChanged) && validateGlassSize(size = newSize) && size.width <= CONSTANTS$1.MAX_SIZE && size.height <= CONSTANTS$1.MAX_SIZE && (lastSize = newSize,
2694
+ lastCornerRadius = effectiveBorderRadius, setGlassSize(newSize)), rafId = null;
2695
+ }));
2696
+ };
2697
+ let resizeTimeoutId = null;
2698
+ const debouncedResizeHandler = () => {
2699
+ resizeTimeoutId && clearTimeout(resizeTimeoutId), resizeTimeoutId = setTimeout((() => updateGlassSize(!1)), 16);
2700
+ }, initialTimeoutId = setTimeout((() => updateGlassSize(!0)), 0);
2701
+ let resizeObserver = null, resizeDebounceTimeout = null;
2702
+ // ResizeObserver has 98%+ browser support, no need for fallback
2703
+ if ("undefined" != typeof ResizeObserver && isValidElement(glassRef.current)) try {
2704
+ resizeObserver = new ResizeObserver((entries => {
2705
+ for (const entry of entries) if (entry.target === glassRef.current) {
2706
+ // Update cached rect when size changes
2707
+ glassRef.current && cachedRectRef && (cachedRectRef.current = glassRef.current.getBoundingClientRect()),
2708
+ // Debounce resize updates to match RAF timing (16ms)
2709
+ resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), resizeDebounceTimeout = setTimeout((() => updateGlassSize(!1)), 16);
2710
+ break;
2711
+ }
2712
+ })), resizeObserver.observe(glassRef.current);
2713
+ } catch (error) {
2714
+ console.warn("AtomixGlass: ResizeObserver not available, using window resize only", error);
2715
+ }
2716
+ return window.addEventListener("resize", debouncedResizeHandler, {
2717
+ passive: !0
2718
+ }), () => {
2719
+ clearTimeout(initialTimeoutId), null !== rafId && cancelAnimationFrame(rafId), resizeTimeoutId && clearTimeout(resizeTimeoutId),
2720
+ resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), window.removeEventListener("resize", debouncedResizeHandler),
2721
+ resizeObserver?.disconnect();
2722
+ };
2723
+ }), [ effectiveBorderRadius, glassRef, cachedRectRef ]), {
2724
+ glassSize: glassSize
2725
+ };
2726
+ }({
2727
+ glassRef: glassRef,
2728
+ effectiveBorderRadius: effectiveBorderRadius,
2729
+ cachedRectRef: cachedRectRef
2730
+ }), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
2555
2731
  // Extract border-radius from children
2556
2732
  useEffect((() => {
2557
2733
  const extractRadius = () => {
@@ -2582,13 +2758,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2582
2758
  }
2583
2759
  null !== extractedRadius && extractedRadius > 0 && setDynamicCornerRadius(extractedRadius);
2584
2760
  } catch (error) {
2585
- "undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugCornerRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
2761
+ "undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugBorderRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
2586
2762
  }
2587
2763
  };
2588
2764
  extractRadius();
2589
2765
  const timeoutId = setTimeout(extractRadius, 100);
2590
2766
  return () => clearTimeout(timeoutId);
2591
- }), [ children, debugCornerRadius, contentRef ]),
2767
+ }), [ children, debugBorderRadius, contentRef ]),
2592
2768
  // Media query handlers and background detection
2593
2769
  useEffect((() => {
2594
2770
  if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
@@ -2644,72 +2820,52 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2644
2820
  const rgb = bgColor.match(/\d+/g);
2645
2821
  if (rgb && rgb.length >= 3) {
2646
2822
  const r = Number(rgb[0]), g = Number(rgb[1]), b = Number(rgb[2]);
2647
- // Validate RGB values are valid numbers
2648
- if (!isNaN(r) && !isNaN(g) && !isNaN(b) && isFinite(r) && isFinite(g) && isFinite(b) && r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && (r > 10 || g > 10 || b > 10)) {
2823
+ if (!isNaN(r) && !isNaN(g) && !isNaN(b) && (r > 10 || g > 10 || b > 10)) {
2649
2824
  const luminance = (.299 * r + .587 * g + .114 * b) / 255;
2650
2825
  !isNaN(luminance) && isFinite(luminance) && (totalLuminance += luminance, validSamples++,
2651
2826
  hasValidBackground = !0);
2652
2827
  }
2653
2828
  }
2654
2829
  }
2655
- // Check for image backgrounds
2656
- bgImage && "none" !== bgImage && "initial" !== bgImage && (
2657
- // For image backgrounds, assume medium luminance
2658
- totalLuminance += .5, validSamples++, hasValidBackground = !0);
2830
+ bgImage && "none" !== bgImage && "initial" !== bgImage && (totalLuminance += .5,
2831
+ validSamples++, hasValidBackground = !0);
2659
2832
  } catch (styleError) {
2660
- "undefined" == typeof process || process.env;
2833
+ // Silently continue
2661
2834
  }
2662
- // Move to parent element for next iteration
2663
- if (!currentElement) break;
2664
- // Exit loop if currentElement becomes null
2665
- currentElement = currentElement.parentElement, depth++;
2835
+ if (!currentElement) break;
2836
+ currentElement = currentElement.parentElement, depth++;
2666
2837
  }
2667
- // More conservative detection with better error handling
2668
- if (hasValidBackground && validSamples > 0) {
2838
+ if (hasValidBackground && validSamples > 0) {
2669
2839
  const avgLuminance = totalLuminance / validSamples;
2670
2840
  if (!isNaN(avgLuminance) && isFinite(avgLuminance)) {
2671
2841
  let threshold = .7;
2672
- // Conservative threshold for overlight
2673
- // If overLight is an object, use its threshold property with validation
2674
- if ("object" == typeof overLight && null !== overLight) {
2842
+ if ("object" == typeof overLight && null !== overLight) {
2675
2843
  const objConfig = overLight;
2676
2844
  if (void 0 !== objConfig.threshold) {
2677
- const configThreshold = "number" == typeof objConfig.threshold && !isNaN(objConfig.threshold) && isFinite(objConfig.threshold) ? objConfig.threshold : .7;
2845
+ const configThreshold = "number" != typeof objConfig.threshold || isNaN(objConfig.threshold) ? .7 : objConfig.threshold;
2678
2846
  threshold = Math.min(.9, Math.max(.1, configThreshold));
2679
2847
  }
2680
2848
  }
2681
2849
  const isOverLightDetected = avgLuminance > threshold;
2682
- // Cache the result in shared cache
2683
- setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold),
2850
+ setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold),
2684
2851
  setDetectedOverLight(isOverLightDetected);
2685
2852
  } else {
2686
- // Invalid luminance calculation, default to false
2687
2853
  const result = !1, threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
2688
2854
  setCachedBackgroundDetection(element.parentElement, overLight, result, threshold),
2689
2855
  setDetectedOverLight(result);
2690
2856
  }
2691
2857
  } else {
2692
- // Default to false if no valid background found
2693
2858
  const result = !1, threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
2694
2859
  setCachedBackgroundDetection(element.parentElement, overLight, result, threshold),
2695
2860
  setDetectedOverLight(result);
2696
2861
  }
2697
2862
  } catch (error) {
2698
- // Enhanced error logging with context
2699
- "undefined" != typeof process && "development" !== process.env?.NODE_ENV || console.warn("AtomixGlass: Error detecting background brightness:", error);
2700
- const result = !1;
2701
- if (element && element.parentElement) {
2702
- const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
2703
- setCachedBackgroundDetection(element.parentElement, overLight, result, threshold);
2704
- }
2705
- setDetectedOverLight(result);
2863
+ setDetectedOverLight(!1);
2706
2864
  }
2707
2865
  }), 150);
2708
2866
  return () => clearTimeout(timeoutId);
2709
2867
  }
2710
- if ("boolean" == typeof overLight &&
2711
- // For boolean values, disable auto-detection
2712
- setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
2868
+ if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
2713
2869
  const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
2714
2870
  setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
2715
2871
  const handleReducedMotionChange = e => {
@@ -2720,64 +2876,54 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2720
2876
  return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
2721
2877
  mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
2722
2878
  mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
2723
- try {
2724
- mediaQueryReducedMotion.removeEventListener ? (mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
2725
- mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.removeListener && (mediaQueryReducedMotion.removeListener(handleReducedMotionChange),
2726
- mediaQueryHighContrast.removeListener(handleHighContrastChange));
2727
- } catch (cleanupError) {
2728
- console.error("AtomixGlass: Error cleaning up media query listeners:", cleanupError);
2729
- }
2879
+ // ignore
2730
2880
  };
2731
2881
  } catch (error) {
2732
- return void console.error("AtomixGlass: Error setting up media queries:", error);
2882
+ return;
2733
2883
  }
2734
2884
  }), [ overLight, glassRef, debugOverLight ]);
2735
- // Mouse tracking using shared global tracker
2736
- // Cache bounding rect to avoid repeated getBoundingClientRect calls
2737
- const cachedRectRef = useRef(null), updateRectRef = useRef(null), handleGlobalMousePosition = useCallback((globalPos => {
2738
- if (externalGlobalMousePosition && externalMouseOffset)
2739
- // External mouse position provided, skip internal tracking
2740
- return;
2741
- if (effectiveDisableEffects) return;
2742
- const container = mouseContainer?.current || glassRef.current;
2743
- if (!container) return;
2744
- // Use cached rect if available, otherwise get new one
2745
- let rect = cachedRectRef.current;
2746
- if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
2747
- cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
2748
- const center = calculateElementCenter(rect), newOffset = {
2749
- x: (globalPos.x - center.x) / rect.width * 100,
2750
- y: (globalPos.y - center.y) / rect.height * 100
2885
+ /**
2886
+ * Get effective overLight value based on configuration
2887
+ */
2888
+ const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), baseOverLightConfig = useMemo((() => {
2889
+ const isOverLight = getEffectiveOverLight(), baseConfig = {
2890
+ isOverLight: isOverLight,
2891
+ threshold: .7,
2892
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
2893
+ contrast: 1,
2894
+ // Base contrast
2895
+ brightness: 1,
2896
+ // Base brightness
2897
+ saturationBoost: 1.3,
2898
+ shadowIntensity: .9,
2899
+ borderOpacity: .7
2751
2900
  };
2752
- // Calculate offset relative to this container
2753
- // React 18 automatically batches these updates
2754
- setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos);
2755
- }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects ]);
2756
- // Subscribe to shared mouse tracker
2757
- useEffect((() => {
2758
- if (externalGlobalMousePosition && externalMouseOffset)
2759
- // External mouse position provided, don't subscribe
2760
- return;
2761
- if (effectiveDisableEffects)
2762
- // Effects disabled, don't subscribe
2763
- return;
2764
- // Subscribe to shared tracker
2765
- const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
2766
- // Update cached rect when container size changes
2767
- let resizeObserver = null;
2768
- return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
2769
- null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
2770
- const container = mouseContainer?.current || glassRef.current;
2771
- container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
2772
- }));
2773
- })), resizeObserver.observe(container)), () => {
2774
- unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
2775
- updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
2901
+ if ("object" == typeof overLight && null !== overLight) {
2902
+ 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);
2903
+ return {
2904
+ ...baseConfig,
2905
+ threshold: validatedThreshold,
2906
+ opacity: validatedOpacity,
2907
+ contrast: validatedContrast,
2908
+ brightness: validatedBrightness,
2909
+ saturationBoost: validatedSaturationBoost
2910
+ };
2911
+ }
2912
+ return baseConfig;
2913
+ }), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = useMemo((() => {
2914
+ const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
2915
+ return {
2916
+ isOverLight: baseOverLightConfig.isOverLight,
2917
+ threshold: baseOverLightConfig.threshold,
2918
+ opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
2919
+ contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
2920
+ brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
2921
+ saturationBoost: baseOverLightConfig.saturationBoost,
2922
+ shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
2923
+ borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
2776
2924
  };
2777
- }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects ]);
2778
- // Transform calculations
2779
- const calculateDirectionalScale = useCallback((() => {
2780
- if (!0 === overLight || "auto" === overLight && detectedOverLight || "object" == typeof overLight && null !== overLight && detectedOverLight) return "scale(1)";
2925
+ }), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = useRef(null), calculateDirectionalScale = useCallback((() => {
2926
+ if (baseOverLightConfig.isOverLight) return "scale(1)";
2781
2927
  if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
2782
2928
  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({
2783
2929
  x: edgeDistanceX,
@@ -2791,7 +2937,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2791
2937
  if (0 === centerDistance) return "scale(1)";
2792
2938
  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;
2793
2939
  return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
2794
- }), [ globalMousePosition, elasticity, glassSize, glassRef, overLight, detectedOverLight ]), calculateFadeInFactor = useCallback((() => {
2940
+ }), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = useCallback((() => {
2795
2941
  if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
2796
2942
  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({
2797
2943
  x: edgeDistanceX,
@@ -2811,122 +2957,110 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2811
2957
  x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
2812
2958
  y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
2813
2959
  };
2814
- }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveDisableEffects ? {
2960
+ }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveWithoutEffects ? {
2815
2961
  x: 0,
2816
2962
  y: 0
2817
- } : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveDisableEffects ]), directionalScale = useMemo((() => effectiveDisableEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveDisableEffects ]), transformStyle = useMemo((() => effectiveDisableEffects ? 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, effectiveDisableEffects ]);
2818
- // Size management
2819
- useEffect((() => {
2820
- const isValidElement = element => null !== element && element instanceof HTMLElement && element.isConnected;
2821
- let rafId = null, lastSize = {
2822
- width: 0,
2823
- height: 0
2824
- }, lastCornerRadius = effectiveCornerRadius;
2825
- const updateGlassSize = (forceUpdate = !1) => {
2826
- null !== rafId && cancelAnimationFrame(rafId), rafId = requestAnimationFrame((() => {
2827
- if (!isValidElement(glassRef.current)) return void (rafId = null);
2828
- const rect = glassRef.current.getBoundingClientRect();
2829
- if (rect.width <= 0 || rect.height <= 0) return void (rafId = null);
2830
- // Measure actual rendered size without artificial offsets to avoid feedback loops
2831
- const newSize = {
2832
- width: Math.round(rect.width),
2833
- height: Math.round(rect.height)
2834
- }, cornerRadiusChanged = lastCornerRadius !== effectiveCornerRadius, dimensionsChanged = Math.abs(newSize.width - lastSize.width) > 1 || Math.abs(newSize.height - lastSize.height) > 1;
2835
- var size;
2836
- (forceUpdate || cornerRadiusChanged || dimensionsChanged) && validateGlassSize(size = newSize) && size.width <= CONSTANTS.MAX_SIZE && size.height <= CONSTANTS.MAX_SIZE && (lastSize = newSize,
2837
- lastCornerRadius = effectiveCornerRadius, setGlassSize(newSize)), rafId = null;
2838
- }));
2839
- };
2840
- let resizeTimeoutId = null;
2841
- const debouncedResizeHandler = () => {
2842
- resizeTimeoutId && clearTimeout(resizeTimeoutId), resizeTimeoutId = setTimeout((() => updateGlassSize(!1)), 16);
2843
- }, initialTimeoutId = setTimeout((() => updateGlassSize(!0)), 0);
2844
- let resizeObserver = null, resizeDebounceTimeout = null;
2845
- // ResizeObserver has 98%+ browser support, no need for fallback
2846
- if ("undefined" != typeof ResizeObserver && isValidElement(glassRef.current)) try {
2847
- resizeObserver = new ResizeObserver((entries => {
2848
- for (const entry of entries) if (entry.target === glassRef.current) {
2849
- // Update cached rect when size changes
2850
- glassRef.current && (cachedRectRef.current = glassRef.current.getBoundingClientRect()),
2851
- // Debounce resize updates to match RAF timing (16ms)
2852
- resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), resizeDebounceTimeout = setTimeout((() => updateGlassSize(!1)), 16);
2853
- break;
2854
- }
2855
- })), resizeObserver.observe(glassRef.current);
2856
- } catch (error) {
2857
- console.warn("AtomixGlass: ResizeObserver not available, using window resize only", error);
2858
- }
2859
- return window.addEventListener("resize", debouncedResizeHandler, {
2860
- passive: !0
2861
- }), () => {
2862
- clearTimeout(initialTimeoutId), null !== rafId && cancelAnimationFrame(rafId), resizeTimeoutId && clearTimeout(resizeTimeoutId),
2863
- resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), window.removeEventListener("resize", debouncedResizeHandler),
2864
- resizeObserver?.disconnect();
2963
+ } : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveWithoutEffects ]), directionalScale = useMemo((() => effectiveWithoutEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveWithoutEffects ]), transformStyle = 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 = useCallback((globalPos => {
2964
+ if (externalGlobalMousePosition && externalMouseOffset) return;
2965
+ if (effectiveWithoutEffects) return;
2966
+ const container = mouseContainer?.current || glassRef.current;
2967
+ if (!container) return;
2968
+ // Use cached rect if available, otherwise get new one
2969
+ let rect = cachedRectRef.current;
2970
+ if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
2971
+ cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
2972
+ const center = calculateElementCenter(rect), newOffset = {
2973
+ x: (globalPos.x - center.x) / rect.width * 100,
2974
+ y: (globalPos.y - center.y) / rect.height * 100
2865
2975
  };
2866
- }), [ effectiveCornerRadius, glassRef ]);
2867
- // OverLight config
2976
+ // Calculate offset relative to this container
2977
+ // Store in refs instead of state
2978
+ internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
2979
+ // Imperative style update
2980
+ updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
2981
+ mouseOffset: newOffset,
2982
+ globalMousePosition: globalPos,
2983
+ glassSize: glassSize,
2984
+ isHovered: isHovered,
2985
+ isActive: isActive,
2986
+ isOverLight: baseOverLightConfig.isOverLight,
2987
+ baseOverLightConfig: baseOverLightConfig,
2988
+ effectiveBorderRadius: effectiveBorderRadius,
2989
+ effectiveWithoutEffects: effectiveWithoutEffects,
2990
+ effectiveReducedMotion: effectiveReducedMotion,
2991
+ elasticity: elasticity,
2992
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
2993
+ // Simplified directional scale for fast path
2994
+ onClick: onClick,
2995
+ withLiquidBlur: withLiquidBlur,
2996
+ blurAmount: blurAmount,
2997
+ saturation: saturation,
2998
+ padding: padding
2999
+ });
3000
+ }), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
2868
3001
  /**
2869
- * Get effective overLight value based on configuration
2870
- * - boolean: returns the boolean value directly
2871
- * - 'auto': returns detectedOverLight (auto-detected from background)
2872
- * - object: returns detectedOverLight (auto-detected, but config object provides customization)
2873
- */
2874
- const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
2875
- const isOverLight = getEffectiveOverLight(), mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
2876
- isOverLight: isOverLight,
2877
- threshold: .7,
2878
- opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
2879
- contrast: Math.min(1.6, Math.max(1, 1.4 + .1 * mouseInfluence)),
2880
- brightness: Math.min(1.1, Math.max(.8, .9 + .05 * mouseInfluence)),
2881
- saturationBoost: 1.3,
2882
- // Fixed value dynamic saturation amplifies perceived displacement
2883
- shadowIntensity: Math.min(1.2, Math.max(.5, .9 + .2 * mouseInfluence)),
2884
- borderOpacity: Math.min(1, Math.max(.3, .7 + .1 * mouseInfluence))
3002
+ * Validate and clamp a numeric config value
3003
+ */
3004
+ // Subscribe to shared mouse tracker
3005
+ useEffect((() => {
3006
+ if (externalGlobalMousePosition && externalMouseOffset) return;
3007
+ if (effectiveWithoutEffects) return;
3008
+ const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
3009
+ let resizeObserver = null;
3010
+ return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
3011
+ null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
3012
+ const container = mouseContainer?.current || glassRef.current;
3013
+ container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
3014
+ }));
3015
+ })), resizeObserver.observe(container)), () => {
3016
+ unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
3017
+ updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
2885
3018
  };
2886
- if ("object" == typeof overLight && null !== overLight) {
2887
- 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 = {
2888
- ...baseConfig,
2889
- threshold: validatedThreshold,
2890
- opacity: validatedOpacity * hoverIntensity * activeIntensity,
2891
- contrast: Math.min(1.6, validatedContrast + .1 * mouseInfluence),
2892
- brightness: Math.min(1.1, validatedBrightness + .05 * mouseInfluence),
2893
- saturationBoost: validatedSaturationBoost
2894
- };
2895
- // Validate and apply object config values with proper clamping
2896
- return "undefined" == typeof process || process.env, finalConfig;
2897
- }
2898
- // Debug logging for non-object configs
2899
- return "undefined" == typeof process || process.env, baseConfig;
2900
- }), [ overLight, getEffectiveOverLight, mouseOffset, isHovered, isActive, validateConfigValue, debugOverLight ]), handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
3019
+ }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
3020
+ // Also call updateStyles on other state changes (hover, active, etc)
3021
+ useEffect((() => {
3022
+ updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
3023
+ mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
3024
+ globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
3025
+ glassSize: glassSize,
3026
+ isHovered: isHovered,
3027
+ isActive: isActive,
3028
+ isOverLight: baseOverLightConfig.isOverLight,
3029
+ baseOverLightConfig: baseOverLightConfig,
3030
+ effectiveBorderRadius: effectiveBorderRadius,
3031
+ effectiveWithoutEffects: effectiveWithoutEffects,
3032
+ effectiveReducedMotion: effectiveReducedMotion,
3033
+ elasticity: elasticity,
3034
+ directionalScale: directionalScale,
3035
+ onClick: onClick,
3036
+ withLiquidBlur: withLiquidBlur,
3037
+ blurAmount: blurAmount,
3038
+ saturation: saturation,
3039
+ padding: padding
3040
+ });
3041
+ }), [ isHovered, isActive, glassSize, baseOverLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, directionalScale, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
3042
+ // Event handlers
3043
+ const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleMouseMove = useCallback((_e => {}), []), handleKeyDown = useCallback((e => {
2901
3044
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
2902
- }), [ onClick ]), handleMouseMove = useCallback((_e => {}), []);
2903
- /**
2904
- * Validate and clamp a numeric config value
2905
- * @param value - The value to validate
2906
- * @param min - Minimum allowed value
2907
- * @param max - Maximum allowed value
2908
- * @param defaultValue - Default value if validation fails
2909
- * @returns Validated and clamped value
2910
- */ return {
2911
- // State
3045
+ }), [ onClick ]);
3046
+ return {
2912
3047
  isHovered: isHovered,
2913
3048
  isActive: isActive,
2914
3049
  glassSize: glassSize,
2915
- dynamicCornerRadius: dynamicCornerRadius,
2916
- effectiveCornerRadius: effectiveCornerRadius,
3050
+ dynamicBorderRadius: dynamicBorderRadius,
3051
+ effectiveBorderRadius: effectiveBorderRadius,
2917
3052
  effectiveReducedMotion: effectiveReducedMotion,
2918
3053
  effectiveHighContrast: effectiveHighContrast,
2919
- effectiveDisableEffects: effectiveDisableEffects,
3054
+ effectiveWithoutEffects: effectiveWithoutEffects,
2920
3055
  detectedOverLight: detectedOverLight,
2921
3056
  globalMousePosition: globalMousePosition,
3057
+ // This is now static (refs or props) unless prop changes
2922
3058
  mouseOffset: mouseOffset,
2923
- // OverLight config
3059
+ // This is now static (refs or props) unless prop changes
2924
3060
  overLightConfig: overLightConfig,
2925
- // Transform calculations
2926
3061
  elasticTranslation: elasticTranslation,
2927
3062
  directionalScale: directionalScale,
2928
3063
  transformStyle: transformStyle,
2929
- // Event handlers
2930
3064
  handleMouseEnter: handleMouseEnter,
2931
3065
  handleMouseLeave: handleMouseLeave,
2932
3066
  handleMouseDown: handleMouseDown,
@@ -2965,7 +3099,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
2965
3099
  *
2966
3100
  * @example
2967
3101
  * // Manual border-radius override
2968
- * <AtomixGlass cornerRadius={20}>
3102
+ * <AtomixGlass borderRadius={20}>
2969
3103
  * <div>Content with 20px glass radius</div>
2970
3104
  * </AtomixGlass>
2971
3105
  *
@@ -3006,37 +3140,48 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
3006
3140
  * <AtomixGlass overLight="auto" debugOverLight={true}>
3007
3141
  * <div>Content with debug logging enabled</div>
3008
3142
  * </AtomixGlass>
3009
- */ function AtomixGlass({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, cornerRadius: cornerRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, disableEffects: disableEffects = !1, enableLiquidBlur: enableLiquidBlur = !1, enableBorderEffect: enableBorderEffect = !0, enableOverLightLayers: enableOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, enablePerformanceMonitoring: enablePerformanceMonitoring = !1, debugCornerRadius: debugCornerRadius = !1, debugOverLight: debugOverLight = !1}) {
3010
- const glassRef = useRef(null), contentRef = useRef(null), {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveCornerRadius: effectiveCornerRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveDisableEffects: effectiveDisableEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
3143
+ */ function AtomixGlass({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, withLiquidBlur: withLiquidBlur = !1, withBorder: withBorder = !0, withOverLightLayers: withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, debugPerformance: debugPerformance = !1, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, height: height, width: width, ...rest}) {
3144
+ const glassRef = useRef(null), contentRef = useRef(null), {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
3011
3145
  glassRef: glassRef,
3012
3146
  contentRef: contentRef,
3013
- cornerRadius: cornerRadius,
3147
+ borderRadius: borderRadius,
3014
3148
  globalMousePosition: externalGlobalMousePosition,
3015
3149
  mouseOffset: externalMouseOffset,
3016
3150
  mouseContainer: mouseContainer,
3017
3151
  overLight: overLight,
3018
3152
  reducedMotion: reducedMotion,
3019
3153
  highContrast: highContrast,
3020
- disableEffects: disableEffects,
3154
+ withoutEffects: withoutEffects,
3021
3155
  elasticity: elasticity,
3022
3156
  onClick: onClick,
3023
- debugCornerRadius: debugCornerRadius,
3157
+ debugBorderRadius: debugBorderRadius,
3024
3158
  debugOverLight: debugOverLight,
3025
- enablePerformanceMonitoring: enablePerformanceMonitoring,
3026
- children: children
3027
- }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
3159
+ debugPerformance: debugPerformance,
3160
+ children: children,
3161
+ blurAmount: blurAmount,
3162
+ saturation: saturation,
3163
+ withLiquidBlur: withLiquidBlur,
3164
+ padding: padding,
3165
+ style: style
3166
+ }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
3028
3167
  ...style,
3029
- ...!effectiveDisableEffects && {
3168
+ ...!effectiveWithoutEffects && {
3030
3169
  transform: transformStyle
3031
3170
  }
3032
- }, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveDisableEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
3171
+ }, 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 = useMemo((() => ({
3033
3172
  position: style.position || "absolute",
3034
3173
  top: style.top || 0,
3035
3174
  left: style.left || 0
3036
- })), [ style.position, style.top, style.left ]), adjustedSize = useMemo((() => ({
3037
- width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
3038
- height: "fixed" !== style.position ? "100%" : style.height ? style.height : Math.max(glassSize.height, 0)
3039
- })), [ style.position, style.width, style.height, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
3175
+ })), [ style.position, style.top, style.left ]), adjustedSize = useMemo((() => {
3176
+ const resolveSize = (propValue, styleValue, measuredSize) => {
3177
+ const explicitSize = propValue ?? styleValue;
3178
+ return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
3179
+ };
3180
+ return {
3181
+ width: resolveSize(width, style.width, glassSize.width),
3182
+ height: resolveSize(height, style.height, glassSize.height)
3183
+ };
3184
+ }), [ width, height, style.width, style.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
3040
3185
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
3041
3186
  return {
3042
3187
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -3078,13 +3223,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
3078
3223
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
3079
3224
  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;
3080
3225
  return {
3081
- "--atomix-glass-radius": `${effectiveCornerRadius}px`,
3226
+ "--atomix-glass-radius": `${effectiveBorderRadius}px`,
3082
3227
  "--atomix-glass-transform": transformStyle || "none",
3083
3228
  "--atomix-glass-position": positionStyles.position,
3084
3229
  "--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
3085
3230
  "--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
3086
- "--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
3087
- "--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
3231
+ "--atomix-glass-width": adjustedSize.width,
3232
+ "--atomix-glass-height": adjustedSize.height,
3088
3233
  "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
3089
3234
  "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
3090
3235
  "--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
@@ -3100,24 +3245,25 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
3100
3245
  "--atomix-glass-overlay-opacity": opacityValues.over,
3101
3246
  "--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})`
3102
3247
  };
3103
- }), [ gradientValues, opacityValues, effectiveCornerRadius, transformStyle, positionStyles, adjustedSize, style.position, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
3248
+ }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
3104
3249
  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(" "),
3105
3250
  style: {
3106
3251
  ...positionStyles,
3107
3252
  height: adjustedSize.height,
3108
3253
  width: adjustedSize.width,
3109
- borderRadius: `${effectiveCornerRadius}px`,
3254
+ borderRadius: `${effectiveBorderRadius}px`,
3110
3255
  transform: baseStyle.transform
3111
3256
  }
3112
3257
  });
3113
3258
  return jsxs("div", {
3259
+ ...rest,
3114
3260
  className: componentClassName,
3115
3261
  style: glassVars,
3116
3262
  role: role || (onClick ? "button" : void 0),
3117
3263
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
3118
3264
  "aria-label": ariaLabel,
3119
3265
  "aria-describedby": ariaDescribedBy,
3120
- "aria-disabled": !(!onClick || !effectiveDisableEffects) || !onClick && void 0,
3266
+ "aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
3121
3267
  "aria-pressed": !(!onClick || !isActive) || !onClick && void 0,
3122
3268
  onKeyDown: onClick ? handleKeyDown : void 0,
3123
3269
  children: [ jsx(AtomixGlassContainer, {
@@ -3125,18 +3271,18 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
3125
3271
  contentRef: contentRef,
3126
3272
  className: className,
3127
3273
  style: baseStyle,
3128
- cornerRadius: effectiveCornerRadius,
3129
- displacementScale: effectiveDisableEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
3130
- blurAmount: effectiveDisableEffects ? 0 : blurAmount,
3274
+ borderRadius: effectiveBorderRadius,
3275
+ displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
3276
+ blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
3131
3277
  saturation: effectiveHighContrast ? ATOMIX_GLASS.CONSTANTS.SATURATION.HIGH_CONTRAST : isOverLight ? saturation * overLightConfig.saturationBoost : saturation,
3132
- aberrationIntensity: effectiveDisableEffects ? 0 : "shader" === mode ? aberrationIntensity * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_ABERRATION : aberrationIntensity,
3278
+ aberrationIntensity: effectiveWithoutEffects ? 0 : "shader" === mode ? aberrationIntensity * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_ABERRATION : aberrationIntensity,
3133
3279
  glassSize: glassSize,
3134
3280
  padding: padding,
3135
- mouseOffset: effectiveDisableEffects ? {
3281
+ mouseOffset: effectiveWithoutEffects ? {
3136
3282
  x: 0,
3137
3283
  y: 0
3138
3284
  } : mouseOffset,
3139
- globalMousePosition: effectiveDisableEffects ? {
3285
+ globalMousePosition: effectiveWithoutEffects ? {
3140
3286
  x: 0,
3141
3287
  y: 0
3142
3288
  } : globalMousePosition,
@@ -3156,11 +3302,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
3156
3302
  onClick: onClick,
3157
3303
  mode: mode,
3158
3304
  transform: baseStyle.transform,
3159
- effectiveDisableEffects: effectiveDisableEffects,
3305
+ effectiveWithoutEffects: effectiveWithoutEffects,
3160
3306
  effectiveReducedMotion: effectiveReducedMotion,
3161
3307
  shaderVariant: shaderVariant,
3162
3308
  elasticity: elasticity,
3163
- enableLiquidBlur: enableLiquidBlur,
3309
+ withLiquidBlur: withLiquidBlur,
3164
3310
  children: children
3165
3311
  }), Boolean(onClick) && jsxs(Fragment, {
3166
3312
  children: [ jsx("div", {
@@ -3182,11 +3328,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
3182
3328
  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}%)`
3183
3329
  }
3184
3330
  }) ]
3185
- }), enableBorderEffect && jsxs(Fragment, {
3331
+ }), withBorder && jsxs(Fragment, {
3186
3332
  children: [ jsx("span", {
3187
- className: ATOMIX_GLASS.BORDER_1_CLASS
3333
+ className: ATOMIX_GLASS.BORDER_1_CLASS,
3334
+ style: {
3335
+ width: glassSize.width,
3336
+ height: glassSize.height
3337
+ }
3188
3338
  }), jsx("span", {
3189
- className: ATOMIX_GLASS.BORDER_2_CLASS
3339
+ className: ATOMIX_GLASS.BORDER_2_CLASS,
3340
+ style: {
3341
+ width: glassSize.width,
3342
+ height: glassSize.height
3343
+ }
3190
3344
  }) ]
3191
3345
  }) ]
3192
3346
  });
@@ -3788,7 +3942,7 @@ const Badge = memo((({label: label, variant: variant = "primary", size: size =
3788
3942
  // Default glass settings for badges
3789
3943
  const defaultGlassProps = {
3790
3944
  displacementScale: 20,
3791
- cornerRadius: ref.current?.getBoundingClientRect().width ? ref.current?.getBoundingClientRect().width / 2 : 16,
3945
+ borderRadius: ref.current?.getBoundingClientRect().width ? ref.current?.getBoundingClientRect().width / 2 : 16,
3792
3946
  className: "c-badge--glass",
3793
3947
  elasticity: 0
3794
3948
  }, glassProps = !0 === glass ? defaultGlassProps : {
@@ -3909,7 +4063,7 @@ const useBlock = () => ({
3909
4063
  * ```
3910
4064
  */ Block.displayName = "Block";
3911
4065
 
3912
- const BreadcrumbItem = forwardRef((({children: children, href: href, active: active, icon: icon, onClick: onClick, className: className = "", style: style, linkAs: LinkComponent, linkProps: linkProps = {}, ...props}, ref) => {
4066
+ const BreadcrumbItem = forwardRef((({children: children, href: href, active: active, icon: icon, onClick: onClick, className: className = "", style: style, linkAs: linkAs, linkProps: linkProps = {}, ...props}, ref) => {
3913
4067
  const itemClasses = [ BREADCRUMB.CLASSES.ITEM, active ? BREADCRUMB.CLASSES.ACTIVE : "", className ].filter(Boolean).join(" "), linkContent = jsxs(Fragment, {
3914
4068
  children: [ icon && jsx("span", {
3915
4069
  className: "c-breadcrumb__icon",
@@ -3927,7 +4081,9 @@ const BreadcrumbItem = forwardRef((({children: children, href: href, active: ac
3927
4081
  className: itemClasses,
3928
4082
  style: style,
3929
4083
  ...props,
3930
- children: href && !active ? jsx(LinkComponent || "a", {
4084
+ children: href && !active ?
4085
+ // @ts-ignore - Dynamic components are tricky in TS without stricter types
4086
+ jsx(linkAs || "a", {
3931
4087
  href: href,
3932
4088
  ...commonLinkProps,
3933
4089
  children: linkContent
@@ -3940,7 +4096,7 @@ const BreadcrumbItem = forwardRef((({children: children, href: href, active: ac
3940
4096
 
3941
4097
  BreadcrumbItem.displayName = "BreadcrumbItem";
3942
4098
 
3943
- const Breadcrumb = memo((({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", LinkComponent: LinkComponent, style: style, children: children}) => {
4099
+ const Breadcrumb = memo((function({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", LinkComponent: LinkComponent, style: style, children: children}) {
3944
4100
  const breadcrumbClasses = [ BREADCRUMB.CLASSES.BASE, className ].filter(Boolean).join(" ");
3945
4101
  let content;
3946
4102
  if (items && items.length > 0)
@@ -3962,11 +4118,11 @@ const Breadcrumb = memo((({items: items, divider: divider, className: className
3962
4118
  const childrenCount = Children.count(children);
3963
4119
  content = Children.map(children, ((child, index) => {
3964
4120
  if ( isValidElement(child)) {
3965
- const isLast = index === childrenCount - 1, childProps = child.props;
4121
+ const isLast = index === childrenCount - 1, childProps = child.props, {active: active, linkAs: linkAs, ...otherProps} = childProps;
3966
4122
 
3967
4123
  return cloneElement(child, {
3968
- active: childProps.active ?? (!!isLast || void 0),
3969
- linkAs: childProps.linkAs ?? LinkComponent
4124
+ active: active ?? (!!isLast || void 0),
4125
+ linkAs: linkAs ?? LinkComponent
3970
4126
  });
3971
4127
  }
3972
4128
  return child;
@@ -4034,7 +4190,7 @@ const Spinner = memo((({size: size = "md", variant: variant = "primary", fullsc
4034
4190
  const defaultGlassProps = {
4035
4191
  displacementScale: 20,
4036
4192
  blurAmount: 1,
4037
- cornerRadius: 999,
4193
+ borderRadius: 999,
4038
4194
  mode: "shader"
4039
4195
  }, glassProps = !0 === glass ? defaultGlassProps : {
4040
4196
  ...defaultGlassProps,
@@ -4431,7 +4587,7 @@ const Callout = memo((({title: title, children: children, icon: icon, variant:
4431
4587
  // Default glass settings for callouts
4432
4588
  const defaultGlassProps = {
4433
4589
  displacementScale: 30,
4434
- cornerRadius: 8,
4590
+ borderRadius: 8,
4435
4591
  elasticity: 0
4436
4592
  }, glassProps = !0 === glass ? defaultGlassProps : {
4437
4593
  ...defaultGlassProps,
@@ -4453,7 +4609,7 @@ const Callout = memo((({title: title, children: children, icon: icon, variant:
4453
4609
  children: jsx("div", {
4454
4610
  className: "c-callout__glass-content",
4455
4611
  style: {
4456
- borderRadius: glassProps.cornerRadius
4612
+ borderRadius: glassProps.borderRadius
4457
4613
  },
4458
4614
  children: calloutContent
4459
4615
  })
@@ -5132,12 +5288,22 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
5132
5288
  left: 40
5133
5289
  }, config) => {
5134
5290
  if (!datasets || 0 === datasets.length) return null;
5135
- // Flatten all data points to find min/max values
5136
- const allDataPoints = datasets.flatMap((dataset => dataset.data));
5137
- if (0 === allDataPoints.length) return null;
5138
- const minValue = Math.min(...allDataPoints.map((point => point.value))), maxValue = Math.max(...allDataPoints.map((point => point.value))), valueRange = maxValue - minValue || 1, innerWidth = width - padding.left - padding.right, innerHeight = height - padding.top - padding.bottom;
5139
- return {
5140
- xScale: (index, dataLength = allDataPoints.length) => dataLength <= 1 ? padding.left + innerWidth / 2 : padding.left + index / (dataLength - 1) * innerWidth,
5291
+ // Calculate total points and min/max values efficiently avoiding spread operator
5292
+ let totalPoints = 0, minValue = 1 / 0, maxValue = -1 / 0, hasValidData = !1;
5293
+ for (const dataset of datasets) if (dataset.data) {
5294
+ totalPoints += dataset.data.length;
5295
+ const {min: min, max: max, hasValid: hasValid} = getDatasetBounds(dataset.data);
5296
+ hasValid && (min < minValue && (minValue = min), max > maxValue && (maxValue = max),
5297
+ hasValidData = !0);
5298
+ }
5299
+ if (0 === totalPoints) return null;
5300
+ // Handle case with no valid numeric data
5301
+ hasValidData || (minValue = 0, maxValue = 0);
5302
+ const valueRange = maxValue - minValue || 1, innerWidth = width - padding.left - padding.right, innerHeight = height - padding.top - padding.bottom;
5303
+ // Avoid division by zero
5304
+ // Apply padding
5305
+ return {
5306
+ xScale: (index, dataLength = totalPoints) => dataLength <= 1 ? padding.left + innerWidth / 2 : padding.left + index / (dataLength - 1) * innerWidth,
5141
5307
  yScale: value => padding.top + innerHeight - (value - minValue) / valueRange * innerHeight,
5142
5308
  minValue: minValue,
5143
5309
  maxValue: maxValue,
@@ -5192,6 +5358,29 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
5192
5358
 
5193
5359
  /**
5194
5360
  * Hook for chart data processing and transformation
5361
+ */
5362
+ /**
5363
+ * Helper to calculate min/max values from a dataset efficiently
5364
+ * avoiding spread operator which can cause stack overflow on large arrays
5365
+ */
5366
+ function getDatasetBounds(data) {
5367
+ let min = 1 / 0, max = -1 / 0, hasValid = !1;
5368
+ if (data && data.length > 0) for (let i = 0; i < data.length; i++) {
5369
+ const point = data[i];
5370
+ if (point && "number" == typeof point.value) {
5371
+ const val = point.value;
5372
+ val < min && (min = val), val > max && (max = val), hasValid = !0;
5373
+ }
5374
+ }
5375
+ return {
5376
+ min: min,
5377
+ max: max,
5378
+ hasValid: hasValid
5379
+ };
5380
+ }
5381
+
5382
+ /**
5383
+ * Hook for managing chart toolbar state and generating chart-specific configurations
5195
5384
  */ const ChartToolbar = memo( forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
5196
5385
  refresh: !0,
5197
5386
  export: !0,
@@ -5612,11 +5801,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
5612
5801
  onZoomReset: handleZoomReset,
5613
5802
  onPanToggle: handlePanToggle,
5614
5803
  onReset: handleReset
5615
- })), [ onRefresh, onExport, handleFullscreenChange, handleZoomIn, handleZoomOut, handleZoomReset, handlePanToggle, handleReset ]), {state: toolbarState, handlers: toolbarHandlers, toolbarGroups: toolbarGroups} =
5616
- /**
5617
- * Hook for managing chart toolbar state and generating chart-specific configurations
5618
- */
5619
- function(chartType, config = {}, handlers = {}) {
5804
+ })), [ onRefresh, onExport, handleFullscreenChange, handleZoomIn, handleZoomOut, handleZoomReset, handlePanToggle, handleReset ]), {state: toolbarState, handlers: toolbarHandlers, toolbarGroups: toolbarGroups} = function(chartType, config = {}, handlers = {}) {
5620
5805
  const [state, setState] = useState({
5621
5806
  isFullscreen: !1,
5622
5807
  isExporting: !1,
@@ -6001,16 +6186,16 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6001
6186
  aberrationIntensity: 1.5,
6002
6187
  elasticity: 0,
6003
6188
  // No elastic effect for charts
6004
- enableLiquidBlur: !1,
6189
+ withLiquidBlur: !1,
6005
6190
  // Keep it simple
6006
- enableBorderEffect: !0,
6191
+ withBorder: !0,
6007
6192
  mode: "standard",
6008
6193
  mouseContainer: chartContainerRef,
6009
6194
  reducedMotion: !1
6010
6195
  })), []), glassProps = useMemo((() => glass ? !0 === glass ? defaultChartGlassProps : {
6011
6196
  ...defaultChartGlassProps,
6012
6197
  ...glass
6013
- } : null), [ glass, defaultChartGlassProps ]), chartBorderRadius = useMemo((() => glassProps?.cornerRadius || void 0), [ glassProps?.cornerRadius ]), chartContextValue = useMemo((() => ({
6198
+ } : null), [ glass, defaultChartGlassProps ]), chartBorderRadius = useMemo((() => glassProps?.borderRadius || void 0), [ glassProps?.borderRadius ]), chartContextValue = useMemo((() => ({
6014
6199
  zoomLevel: zoomLevel,
6015
6200
  panOffset: panOffset,
6016
6201
  panEnabled: panEnabled,
@@ -6141,7 +6326,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6141
6326
  }) ]
6142
6327
  }), wrappedChart = glassProps ? jsx(AtomixGlass, {
6143
6328
  ...glassProps,
6144
- cornerRadius: chartBorderRadius,
6329
+ borderRadius: chartBorderRadius,
6145
6330
  style: {
6146
6331
  width: "100%",
6147
6332
  height: "100%",
@@ -6194,7 +6379,13 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
6194
6379
  // Get chart context (zoom/pan state from toolbar) - optional
6195
6380
  // Always call useContext to maintain consistent hook order
6196
6381
  const chartContext = useContext(ChartContext), {calculateScales: calculateScales, getChartColors: getChartColors} = useChart(), {processedData: processedData, isProcessing: isProcessing} = function(datasets, options) {
6197
- const [processedData, setProcessedData] = useState(datasets), [isProcessing, setIsProcessing] = useState(!1), {enableDecimation: enableDecimation = !1, maxDataPoints: maxDataPoints = 1e3, enableRealTime: enableRealTime = !1, realTimeInterval: realTimeInterval = 1e3} = options || {}, decimateData = useCallback(((data, maxPoints) => {
6382
+ const [processedData, setProcessedData] = useState(datasets), [isProcessing, setIsProcessing] = useState(!1), {enableDecimation: enableDecimation = !1, maxDataPoints: maxDataPoints = 1e3, enableRealTime: enableRealTime = !1, realTimeInterval: realTimeInterval = 1e3} = options || {}, lastDataSignature = useRef(""), getDatasetSignature = useCallback((data => data.map((d => `${d.label}:${JSON.stringify(d.data)}`)).join("|")), []);
6383
+ // Update signature when processedData changes (e.g. via props)
6384
+ useEffect((() => {
6385
+ lastDataSignature.current = getDatasetSignature(processedData);
6386
+ }), [ processedData, getDatasetSignature ]);
6387
+ // Data decimation for performance
6388
+ const decimateData = useCallback(((data, maxPoints) => {
6198
6389
  if (!enableDecimation || !data.length) return data;
6199
6390
  const dataLength = data[0]?.data?.length || 0;
6200
6391
  if (dataLength <= maxPoints) return data;
@@ -6214,10 +6405,17 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
6214
6405
  }), []), calculateTrendLine = useCallback((values => {
6215
6406
  const n = values.length;
6216
6407
  if (n < 2) return values.map((() => null));
6217
- const xSum = _reduceInstanceProperty(values).call(values, ((sum, _, i) => sum + i), 0), ySum = _reduceInstanceProperty(values).call(values, ((sum, val) => sum + val), 0), slope = (n * _reduceInstanceProperty(values).call(values, ((sum, val, i) => sum + i * val), 0) - xSum * ySum) / (n * _reduceInstanceProperty(values).call(values, ((sum, _, i) => sum + i * i), 0) - xSum * xSum), intercept = (ySum - slope * xSum) / n;
6408
+ let xSum = 0, ySum = 0, xySum = 0, x2Sum = 0;
6409
+ for (let i = 0; i < n; i++) {
6410
+ const val = values[i], safeVal = "number" == typeof val ? val : 0;
6411
+ // Treat null/undefined as 0 to match original reduce behavior
6412
+ xSum += i, ySum += safeVal, xySum += i * safeVal, x2Sum += i * i;
6413
+ }
6414
+ const slope = (n * xySum - xSum * ySum) / (n * x2Sum - xSum * xSum), intercept = (ySum - slope * xSum) / n;
6218
6415
  return values.map(((_, i) => slope * i + intercept));
6219
6416
  }), []);
6220
- // Process data when datasets change
6417
+ // Moving average calculation
6418
+ // Process data when datasets change
6221
6419
  return useEffect((() => {
6222
6420
  setIsProcessing(!0), (async () => {
6223
6421
  let processed = [ ...datasets ];
@@ -6229,11 +6427,12 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
6229
6427
  useEffect((() => {
6230
6428
  if (!enableRealTime) return;
6231
6429
  const interval = setInterval((() => {
6232
- setProcessedData((prev => [ ...prev ]));
6233
- // Trigger re-render for real-time updates
6234
- }), realTimeInterval);
6430
+ setProcessedData((prev =>
6431
+ // Only trigger update if signature changed
6432
+ getDatasetSignature(prev) === lastDataSignature.current ? prev : [ ...prev ]));
6433
+ }), realTimeInterval);
6235
6434
  return () => clearInterval(interval);
6236
- }), [ enableRealTime, realTimeInterval ]), {
6435
+ }), [ enableRealTime, realTimeInterval, getDatasetSignature ]), {
6237
6436
  processedData: processedData,
6238
6437
  isProcessing: isProcessing,
6239
6438
  decimateData: decimateData,
@@ -6254,12 +6453,12 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
6254
6453
  */
6255
6454
  function(datasets, options) {
6256
6455
  const {enableVirtualization: enableVirtualization = !1, enableMemoization: enableMemoization = !0, debounceMs: debounceMs = 100} = options || {}, [isOptimizing, setIsOptimizing] = useState(!1), debounceRef = useRef(null), memoizedScales = useMemo((() => enableMemoization ? datasets.map((dataset => {
6257
- const values = dataset.data?.map((d => d.value)).filter((v => "number" == typeof v)) || [], validValues = values.length > 0 ? values : [ 0 ];
6456
+ const {min: min, max: max, hasValid: hasValid} = getDatasetBounds(dataset.data);
6258
6457
  return {
6259
6458
  label: dataset.label,
6260
6459
  dataLength: dataset.data?.length || 0,
6261
- minValue: Math.min(...validValues),
6262
- maxValue: Math.max(...validValues)
6460
+ minValue: hasValid ? min : 0,
6461
+ maxValue: hasValid ? max : 0
6263
6462
  };
6264
6463
  })) : null), [ datasets, enableMemoization ]), debouncedUpdate = useCallback((callback => {
6265
6464
  debounceRef.current && clearTimeout(debounceRef.current), debounceRef.current = setTimeout((() => {
@@ -6358,8 +6557,8 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
6358
6557
  const getAccessibleDescription = useCallback((() => {
6359
6558
  if (!datasets.length) return "Empty chart";
6360
6559
  const datasetDescriptions = datasets.map(((dataset, i) => {
6361
- const dataCount = dataset.data?.length || 0, values = dataset.data?.map((d => d.value)).filter((v => "number" == typeof v)) || [], min = values.length > 0 ? Math.min(...values) : 0, max = values.length > 0 ? Math.max(...values) : 0;
6362
- return `Dataset ${i + 1}: ${dataset.label}, ${dataCount} points, range ${min} to ${max}`;
6560
+ const dataCount = dataset.data?.length || 0, {min: min, max: max, hasValid: hasValid} = getDatasetBounds(dataset.data), minVal = hasValid ? min : 0, maxVal = hasValid ? max : 0;
6561
+ return `Dataset ${i + 1}: ${dataset.label}, ${dataCount} points, range ${minVal} to ${maxVal}`;
6363
6562
  })).join(". ");
6364
6563
  return `Chart with ${datasets.length} datasets. ${datasetDescriptions}`;
6365
6564
  }), [ datasets ]);
@@ -8605,14 +8804,14 @@ const ScatterChart = memo( forwardRef((({datasets: datasets = [], config: confi
8605
8804
 
8606
8805
  ScatterChart.displayName = "ScatterChart";
8607
8806
 
8608
- const TreemapChart = memo( forwardRef((({data: data = [], algorithm: algorithm = "squarified", colorConfig: colorConfig = {
8807
+ const DEFAULT_COLOR_CONFIG = {
8609
8808
  scheme: "category"
8610
- }, labelConfig: labelConfig = {
8809
+ }, DEFAULT_LABEL_CONFIG = {
8611
8810
  showLabels: !0,
8612
8811
  minSize: 1e3,
8613
8812
  fontSize: 12,
8614
8813
  textColor: "white"
8615
- }, onDataPointClick: onDataPointClick, config: config = {}, ...props}, ref) => {
8814
+ }, DEFAULT_CONFIG = {}, TreemapChart = memo( forwardRef((({data: data = [], algorithm: algorithm = "squarified", colorConfig: colorConfig = DEFAULT_COLOR_CONFIG, labelConfig: labelConfig = DEFAULT_LABEL_CONFIG, onDataPointClick: onDataPointClick, config: config = DEFAULT_CONFIG, ...props}, ref) => {
8616
8815
  const [hoveredNode, setHoveredNode] = useState(null), [selectedNode, setSelectedNode] = useState(null);
8617
8816
  useState({
8618
8817
  x: 0,
@@ -8724,87 +8923,87 @@ const TreemapChart = memo( forwardRef((({data: data = [], algorithm: algorithm
8724
8923
  remainingHeight -= rowHeight), currentRow = [];
8725
8924
  }
8726
8925
  }
8727
- }), []);
8926
+ }), []), renderContent = useCallback((({scales: scales, colors: colors, datasets: renderedDatasets, handlers: handlers, hoveredPoint: hoveredPoint}) => {
8927
+ if (!data.length) return null;
8928
+ // Calculate available space with padding
8929
+ const availableWidth = scales.width - 40, availableHeight = scales.height - 40, leafNodes = data.filter((item => !item.children || 0 === item.children.length));
8930
+ if (!leafNodes.length) return null;
8931
+ const totalValue = _reduceInstanceProperty(leafNodes).call(leafNodes, ((sum, node) => sum + node.value), 0), treemapNodes = leafNodes.map(((item, index) => ({
8932
+ id: item.id,
8933
+ label: item.label,
8934
+ value: item.value,
8935
+ color: generateColor(item, 0, index) || "transparent",
8936
+ x: 0,
8937
+ // Will be calculated by squarify
8938
+ y: 0,
8939
+ // Will be calculated by squarify
8940
+ width: 0,
8941
+ // Will be calculated by squarify
8942
+ height: 0,
8943
+ // Will be calculated by squarify
8944
+ depth: 0,
8945
+ children: [],
8946
+ originalData: item
8947
+ })));
8948
+ // Create treemap nodes with proper dimensions
8949
+ // Apply squarified algorithm to layout nodes proportionally by value
8950
+ if ("squarified" === algorithm && totalValue > 0) squarify(treemapNodes, 20, 20, availableWidth, availableHeight); else {
8951
+ // Fallback: simple grid layout (equal sizes)
8952
+ const cols = Math.ceil(Math.sqrt(leafNodes.length)), rows = Math.ceil(leafNodes.length / cols), nodeWidth = availableWidth / cols, nodeHeight = availableHeight / rows;
8953
+ treemapNodes.forEach(((node, index) => {
8954
+ const col = index % cols, row = Math.floor(index / cols);
8955
+ node.x = 20 + col * nodeWidth, node.y = 20 + row * nodeHeight, node.width = nodeWidth,
8956
+ node.height = nodeHeight;
8957
+ }));
8958
+ }
8959
+ return jsx(Fragment, {
8960
+ children: treemapNodes.map((node => {
8961
+ const isHovered = hoveredNode === node, isSelected = selectedNode === node, area = node.width * node.height, showLabel = labelConfig.showLabels && area >= (labelConfig.minSize || 1e3);
8962
+ return jsxs("g", {
8963
+ children: [ jsx("rect", {
8964
+ x: node.x,
8965
+ y: node.y,
8966
+ width: node.width,
8967
+ height: node.height,
8968
+ fill: node.color,
8969
+ className: `c-chart__treemap-node ${isHovered ? "c-chart__treemap-node--hovered" : ""} ${isSelected ? "c-chart__treemap-node--selected" : ""}`,
8970
+ onClick: () => {
8971
+ setSelectedNode(node), handlers.onDataPointClick?.(node.originalData, 0, 0);
8972
+ },
8973
+ onMouseEnter: e => {
8974
+ setHoveredNode(node);
8975
+ const rect = e.currentTarget.getBoundingClientRect();
8976
+ handlers.onPointHover(0, 0, node.x, node.y, rect.left + rect.width / 2, rect.top + rect.height / 2);
8977
+ },
8978
+ onMouseLeave: () => {
8979
+ setHoveredNode(null), handlers.onPointLeave();
8980
+ }
8981
+ }), showLabel && jsx("text", {
8982
+ x: node.x + node.width / 2,
8983
+ y: node.y + node.height / 2,
8984
+ textAnchor: "middle",
8985
+ dominantBaseline: "middle",
8986
+ className: "c-chart__treemap-label",
8987
+ style: {
8988
+ fontSize: labelConfig.fontSize,
8989
+ fill: labelConfig.textColor
8990
+ },
8991
+ children: node.label
8992
+ }) ]
8993
+ }, node.id);
8994
+ }))
8995
+ });
8996
+ }), [ data, algorithm, generateColor, squarify, labelConfig, hoveredNode, selectedNode ]), datasets = useMemo((() => [ {
8997
+ label: "Treemap Data",
8998
+ data: data
8999
+ } ]), [ data ]);
8728
9000
  // Squarified treemap algorithm
8729
9001
  return jsx(BaseChart, {
8730
9002
  ref: ref,
8731
9003
  type: "treemap",
8732
- datasets: [ {
8733
- label: "Treemap Data",
8734
- data: data
8735
- } ],
9004
+ datasets: datasets,
8736
9005
  config: config,
8737
- renderContent: ({scales: scales, colors: colors, datasets: renderedDatasets, handlers: handlers, hoveredPoint: hoveredPoint}) => {
8738
- if (!data.length) return null;
8739
- // Calculate available space with padding
8740
- const availableWidth = scales.width - 40, availableHeight = scales.height - 40, leafNodes = data.filter((item => !item.children || 0 === item.children.length));
8741
- if (!leafNodes.length) return null;
8742
- const totalValue = _reduceInstanceProperty(leafNodes).call(leafNodes, ((sum, node) => sum + node.value), 0), treemapNodes = leafNodes.map(((item, index) => ({
8743
- id: item.id,
8744
- label: item.label,
8745
- value: item.value,
8746
- color: generateColor(item, 0, index) || "transparent",
8747
- x: 0,
8748
- // Will be calculated by squarify
8749
- y: 0,
8750
- // Will be calculated by squarify
8751
- width: 0,
8752
- // Will be calculated by squarify
8753
- height: 0,
8754
- // Will be calculated by squarify
8755
- depth: 0,
8756
- children: [],
8757
- originalData: item
8758
- })));
8759
- // Create treemap nodes with proper dimensions
8760
- // Apply squarified algorithm to layout nodes proportionally by value
8761
- if ("squarified" === algorithm && totalValue > 0) squarify(treemapNodes, 20, 20, availableWidth, availableHeight); else {
8762
- // Fallback: simple grid layout (equal sizes)
8763
- const cols = Math.ceil(Math.sqrt(leafNodes.length)), rows = Math.ceil(leafNodes.length / cols), nodeWidth = availableWidth / cols, nodeHeight = availableHeight / rows;
8764
- treemapNodes.forEach(((node, index) => {
8765
- const col = index % cols, row = Math.floor(index / cols);
8766
- node.x = 20 + col * nodeWidth, node.y = 20 + row * nodeHeight, node.width = nodeWidth,
8767
- node.height = nodeHeight;
8768
- }));
8769
- }
8770
- return jsx(Fragment, {
8771
- children: treemapNodes.map((node => {
8772
- const isHovered = hoveredNode === node, isSelected = selectedNode === node, area = node.width * node.height, showLabel = labelConfig.showLabels && area >= (labelConfig.minSize || 1e3);
8773
- return jsxs("g", {
8774
- children: [ jsx("rect", {
8775
- x: node.x,
8776
- y: node.y,
8777
- width: node.width,
8778
- height: node.height,
8779
- fill: node.color,
8780
- className: `c-chart__treemap-node ${isHovered ? "c-chart__treemap-node--hovered" : ""} ${isSelected ? "c-chart__treemap-node--selected" : ""}`,
8781
- onClick: () => {
8782
- setSelectedNode(node), handlers.onDataPointClick?.(node.originalData, 0, 0);
8783
- },
8784
- onMouseEnter: e => {
8785
- setHoveredNode(node);
8786
- const rect = e.currentTarget.getBoundingClientRect();
8787
- handlers.onPointHover(0, 0, node.x, node.y, rect.left + rect.width / 2, rect.top + rect.height / 2);
8788
- },
8789
- onMouseLeave: () => {
8790
- setHoveredNode(null), handlers.onPointLeave();
8791
- }
8792
- }), showLabel && jsx("text", {
8793
- x: node.x + node.width / 2,
8794
- y: node.y + node.height / 2,
8795
- textAnchor: "middle",
8796
- dominantBaseline: "middle",
8797
- className: "c-chart__treemap-label",
8798
- style: {
8799
- fontSize: labelConfig.fontSize,
8800
- fill: labelConfig.textColor
8801
- },
8802
- children: node.label
8803
- }) ]
8804
- }, node.id);
8805
- }))
8806
- });
8807
- },
9006
+ renderContent: renderContent,
8808
9007
  onDataPointClick: onDataPointClick,
8809
9008
  interactive: !0,
8810
9009
  ...props
@@ -9492,7 +9691,7 @@ const DOTS = "...", range = (start, end) => {
9492
9691
  blurAmount: 1,
9493
9692
  saturation: 160,
9494
9693
  aberrationIntensity: .5,
9495
- cornerRadius: 8,
9694
+ borderRadius: 8,
9496
9695
  mode: "shader"
9497
9696
  }, glassProps = !0 === glass ? defaultGlassProps : {
9498
9697
  ...defaultGlassProps,
@@ -9563,7 +9762,7 @@ const Checkbox = React.memo( forwardRef((({label: label, checked: checked, onCh
9563
9762
  blurAmount: 1,
9564
9763
  saturation: 160,
9565
9764
  aberrationIntensity: .3,
9566
- cornerRadius: 6,
9765
+ borderRadius: 6,
9567
9766
  mode: "shader"
9568
9767
  }, glassProps = !0 === glass ? defaultGlassProps : {
9569
9768
  ...defaultGlassProps,
@@ -11236,7 +11435,7 @@ const Input = memo( forwardRef((({type: type = "text", value: value, defaultVal
11236
11435
  blurAmount: 1,
11237
11436
  saturation: 180,
11238
11437
  aberrationIntensity: .2,
11239
- cornerRadius: 12,
11438
+ borderRadius: 12,
11240
11439
  mode: "shader"
11241
11440
  }, glassProps = !0 === glass ? defaultGlassProps : {
11242
11441
  ...defaultGlassProps,
@@ -11276,7 +11475,7 @@ function useHero(initialProps) {
11276
11475
  * @returns Slider state and methods
11277
11476
  */
11278
11477
  function(config) {
11279
- const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), autoplayRef = useRef(null), isPausedRef = useRef(!1), slideRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides.length ]), videoRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides.length ]), handleSlideTransition = useCallback((nextIndex => {
11478
+ const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), autoplayRef = useRef(null), isPausedRef = useRef(!1), callbackRef = useRef(), slideRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides.length ]), videoRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides.length ]), handleSlideTransition = useCallback((nextIndex => {
11280
11479
  if (nextIndex === currentIndex || isTransitioning) return;
11281
11480
  if (nextIndex < 0 || nextIndex >= slides.length) return;
11282
11481
  setIsTransitioning(!0),
@@ -11297,7 +11496,17 @@ function useHero(initialProps) {
11297
11496
  let nextIndex;
11298
11497
  nextIndex = loop ? (currentIndex + 1) % slides.length : Math.min(currentIndex + 1, slides.length - 1),
11299
11498
  handleSlideTransition(nextIndex);
11300
- }), [ currentIndex, slides.length, loop, handleSlideTransition ]), pauseAutoplay = useCallback((() => {
11499
+ }), [ currentIndex, slides.length, loop, handleSlideTransition ]);
11500
+ // Update callbackRef whenever nextSlide or isTransitioning changes
11501
+ useEffect((() => {
11502
+ callbackRef.current = () => {
11503
+ isPausedRef.current || isTransitioning || nextSlide();
11504
+ };
11505
+ }), [ nextSlide, isTransitioning ]);
11506
+ /**
11507
+ * Pause autoplay
11508
+ */
11509
+ const pauseAutoplay = useCallback((() => {
11301
11510
  isPausedRef.current = !0, autoplayRef.current && (clearInterval(autoplayRef.current),
11302
11511
  autoplayRef.current = null);
11303
11512
  }), []), resumeAutoplay = useCallback((() => {
@@ -11306,24 +11515,26 @@ function useHero(initialProps) {
11306
11515
  const delay = "object" == typeof autoplay ? autoplay.delay : 3e3;
11307
11516
  // Restart autoplay
11308
11517
  autoplayRef.current || (autoplayRef.current = setInterval((() => {
11309
- isPausedRef.current || isTransitioning || nextSlide();
11518
+ callbackRef.current && callbackRef.current();
11310
11519
  }), delay));
11311
11520
  }
11312
- }), [ autoplay, slides.length, nextSlide, isTransitioning ]);
11521
+ }), [ autoplay, slides.length ]);
11522
+ /**
11523
+ * Resume autoplay
11524
+ */
11313
11525
  // Autoplay effect
11314
11526
  return useEffect((() => {
11315
11527
  if (!autoplay || slides.length <= 1) return;
11316
11528
  const delay = "object" == typeof autoplay ? autoplay.delay : 3e3;
11317
- return "object" == typeof autoplay && autoplay.pauseOnHover,
11318
11529
  // Clear any existing interval
11319
- autoplayRef.current && (clearInterval(autoplayRef.current), autoplayRef.current = null),
11530
+ return autoplayRef.current && (clearInterval(autoplayRef.current), autoplayRef.current = null),
11320
11531
  // Start autoplay if not paused
11321
11532
  isPausedRef.current || (autoplayRef.current = setInterval((() => {
11322
- isPausedRef.current || isTransitioning || nextSlide();
11533
+ callbackRef.current && callbackRef.current();
11323
11534
  }), delay)), () => {
11324
11535
  autoplayRef.current && (clearInterval(autoplayRef.current), autoplayRef.current = null);
11325
11536
  };
11326
- }), [ autoplay, slides.length, nextSlide, isTransitioning ]),
11537
+ }), [ autoplay, slides.length ]),
11327
11538
  // Initialize first video if needed
11328
11539
  useEffect((() => {
11329
11540
  if (slides.length > 0 && "video" === slides[currentIndex]?.type) {
@@ -12324,7 +12535,14 @@ function useTodo(initialProps) {
12324
12535
  }
12325
12536
 
12326
12537
  function useSlider(options) {
12327
- const {slides: slides, slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, autoplay: autoplay, onSlideChange: onSlideChange} = options, containerRef = useRef(null), wrapperRef = useRef(null), repositioningRef = useRef(!1), autoplayRef = useRef(null), [autoplayRunning, setAutoplayRunning] = useState(!1), [realIndex, setRealIndex] = useState(initialSlide), [internalIndex, setInternalIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), [containerSize, setContainerSize] = useState(0), [touching, setTouching] = useState(!1), [touchStart, setTouchStart] = useState(0), [dragOffset, setDragOffset] = useState(0), slideWidth = useMemo((() => 0 === containerSize ? 0 : (containerSize - spaceBetween * (slidesToShow - 1)) / slidesToShow), [ containerSize, spaceBetween, slidesToShow ]), allSlides = useMemo((() => loop && 0 !== slides.length ? [ ...slides.map(((slide, i) => ({
12538
+ const {slides: slides, slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, autoplay: autoplay, onSlideChange: onSlideChange} = options, containerRef = useRef(null), wrapperRef = useRef(null), repositioningRef = useRef(!1), autoplayRef = useRef(null), [autoplayRunning, setAutoplayRunning] = useState(!1), sliderStateRef = useRef({
12539
+ isTransitioning: !1,
12540
+ loop: loop,
12541
+ slides: slides,
12542
+ slidesToShow: slidesToShow,
12543
+ speed: speed,
12544
+ onSlideChange: onSlideChange
12545
+ }), [realIndex, setRealIndex] = useState(initialSlide), [internalIndex, setInternalIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), [containerSize, setContainerSize] = useState(0), [touching, setTouching] = useState(!1), [touchStart, setTouchStart] = useState(0), [dragOffset, setDragOffset] = useState(0), slideWidth = useMemo((() => 0 === containerSize ? 0 : (containerSize - spaceBetween * (slidesToShow - 1)) / slidesToShow), [ containerSize, spaceBetween, slidesToShow ]), allSlides = useMemo((() => loop && 0 !== slides.length ? [ ...slides.map(((slide, i) => ({
12328
12546
  ...slide,
12329
12547
  id: `set1-${slide.id || i}`
12330
12548
  }))), ...slides.map(((slide, i) => ({
@@ -12334,6 +12552,17 @@ function useSlider(options) {
12334
12552
  ...slide,
12335
12553
  id: `set3-${slide.id || i}`
12336
12554
  }))) ] : slides), [ slides, loop ]), loopedSlides = slides.length, translateValue = useMemo((() => 0 === slideWidth ? 0 : -internalIndex * slideWidth + dragOffset), [ slideWidth, internalIndex, dragOffset ]);
12555
+ // Update the ref whenever the relevant state/props change
12556
+ useEffect((() => {
12557
+ sliderStateRef.current = {
12558
+ isTransitioning: isTransitioning,
12559
+ loop: loop,
12560
+ slides: slides,
12561
+ slidesToShow: slidesToShow,
12562
+ speed: speed,
12563
+ onSlideChange: onSlideChange
12564
+ };
12565
+ }), [ isTransitioning, loop, slides, slidesToShow, speed, onSlideChange ]),
12337
12566
  // Autoplay effect
12338
12567
  useEffect((() => {
12339
12568
  if (!autoplay) return autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -12345,32 +12574,34 @@ function useSlider(options) {
12345
12574
  autoplayRef.current && clearInterval(autoplayRef.current),
12346
12575
  // Create new interval
12347
12576
  autoplayRef.current = setInterval((() => {
12577
+ // Use ref to get the latest state without resetting the interval
12578
+ const {isTransitioning: currentIsTransitioning, loop: currentLoop, slides: currentSlides, slidesToShow: currentSlidesToShow, speed: currentSpeed, onSlideChange: currentOnSlideChange} = sliderStateRef.current;
12348
12579
  // We need to use a functional update to get the latest values
12349
- setRealIndex((prevRealIndex => {
12350
- if (isTransitioning) return prevRealIndex;
12580
+ setRealIndex((prevRealIndex => {
12581
+ if (currentIsTransitioning) return prevRealIndex;
12351
12582
  // Stop autoplay on interaction if disableOnInteraction is true
12352
12583
  let nextIndex;
12353
12584
  // Trigger the slide change
12354
12585
  if (disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
12355
- autoplayRef.current = null, setAutoplayRunning(!1)), nextIndex = loop ? (prevRealIndex + 1) % slides.length : Math.min(prevRealIndex + 1, slides.length - slidesToShow),
12586
+ autoplayRef.current = null, setAutoplayRunning(!1)), nextIndex = currentLoop ? (prevRealIndex + 1) % currentSlides.length : Math.min(prevRealIndex + 1, currentSlides.length - currentSlidesToShow),
12356
12587
  reverseDirection) {
12357
12588
  // For reverse direction, we would go to previous slide
12358
- const prevIndex = loop ? 0 === prevRealIndex ? slides.length - 1 : prevRealIndex - 1 : Math.max(prevRealIndex - 1, 0);
12359
- return setInternalIndex(loop ? slides.length + prevIndex : prevIndex), setIsTransitioning(!0),
12360
- setDragOffset(0), setTimeout((() => {
12361
- setIsTransitioning(!1), onSlideChange?.(prevIndex);
12362
- }), speed), prevIndex;
12589
+ const prevIndex = currentLoop ? 0 === prevRealIndex ? currentSlides.length - 1 : prevRealIndex - 1 : Math.max(prevRealIndex - 1, 0);
12590
+ return setInternalIndex(currentLoop ? currentSlides.length + prevIndex : prevIndex),
12591
+ setIsTransitioning(!0), setDragOffset(0), setTimeout((() => {
12592
+ setIsTransitioning(!1), currentOnSlideChange?.(prevIndex);
12593
+ }), currentSpeed), prevIndex;
12363
12594
  }
12364
12595
  // Normal direction
12365
- return setInternalIndex(loop ? slides.length + nextIndex : nextIndex), setIsTransitioning(!0),
12366
- setDragOffset(0), setTimeout((() => {
12367
- setIsTransitioning(!1), onSlideChange?.(nextIndex),
12596
+ return setInternalIndex(currentLoop ? currentSlides.length + nextIndex : nextIndex),
12597
+ setIsTransitioning(!0), setDragOffset(0), setTimeout((() => {
12598
+ setIsTransitioning(!1), currentOnSlideChange?.(nextIndex),
12368
12599
  // Reposition after transition ends for looped sliders
12369
- loop && nextIndex >= 2 * slides.length && (repositioningRef.current = !0, setInternalIndex(slides.length + nextIndex),
12370
- setTimeout((() => {
12600
+ currentLoop && nextIndex >= 2 * currentSlides.length && (repositioningRef.current = !0,
12601
+ setInternalIndex(currentSlides.length + nextIndex), setTimeout((() => {
12371
12602
  repositioningRef.current = !1;
12372
12603
  }), 0));
12373
- }), speed), nextIndex;
12604
+ }), currentSpeed), nextIndex;
12374
12605
  }));
12375
12606
  }), delay), setAutoplayRunning(!0);
12376
12607
  // Handle pause on mouse enter/leave if enabled
@@ -12381,17 +12612,18 @@ function useSlider(options) {
12381
12612
  }, handleMouseLeave = () => {
12382
12613
  // Restart autoplay
12383
12614
  autoplayRef.current && clearInterval(autoplayRef.current), autoplayRef.current = setInterval((() => {
12615
+ const {isTransitioning: currentIsTransitioning, loop: currentLoop, slides: currentSlides, slidesToShow: currentSlidesToShow, speed: currentSpeed, onSlideChange: currentOnSlideChange} = sliderStateRef.current;
12384
12616
  setRealIndex((prevRealIndex => {
12385
- if (isTransitioning) return prevRealIndex;
12617
+ if (currentIsTransitioning) return prevRealIndex;
12386
12618
  let nextIndex;
12387
- return nextIndex = loop ? (prevRealIndex + 1) % slides.length : Math.min(prevRealIndex + 1, slides.length - slidesToShow),
12388
- setInternalIndex(loop ? slides.length + nextIndex : nextIndex), setIsTransitioning(!0),
12619
+ return nextIndex = currentLoop ? (prevRealIndex + 1) % currentSlides.length : Math.min(prevRealIndex + 1, currentSlides.length - currentSlidesToShow),
12620
+ setInternalIndex(currentLoop ? currentSlides.length + nextIndex : nextIndex), setIsTransitioning(!0),
12389
12621
  setDragOffset(0), setTimeout((() => {
12390
- setIsTransitioning(!1), onSlideChange?.(nextIndex), loop && nextIndex >= 2 * slides.length && (repositioningRef.current = !0,
12391
- setInternalIndex(slides.length + nextIndex), setTimeout((() => {
12622
+ setIsTransitioning(!1), currentOnSlideChange?.(nextIndex), currentLoop && nextIndex >= 2 * currentSlides.length && (repositioningRef.current = !0,
12623
+ setInternalIndex(currentSlides.length + nextIndex), setTimeout((() => {
12392
12624
  repositioningRef.current = !1;
12393
12625
  }), 0));
12394
- }), speed), nextIndex;
12626
+ }), currentSpeed), nextIndex;
12395
12627
  }));
12396
12628
  }), delay), setAutoplayRunning(!0);
12397
12629
  };
@@ -12403,7 +12635,7 @@ function useSlider(options) {
12403
12635
  containerElement && (containerElement.removeEventListener("mouseenter", handleMouseEnter),
12404
12636
  containerElement.removeEventListener("mouseleave", handleMouseLeave)), setAutoplayRunning(!1);
12405
12637
  };
12406
- }), [ autoplay, slides.length, loop, slidesToShow, isTransitioning, speed, onSlideChange, repositioningRef ]),
12638
+ }), [ autoplay, repositioningRef ]),
12407
12639
  // Initialize
12408
12640
  useEffect((() => {
12409
12641
  setInternalIndex(loop ? slides.length + initialSlide : initialSlide);
@@ -12863,7 +13095,7 @@ const Select = memo((({options: options, value: value, onChange: onChange, onBl
12863
13095
  blurAmount: 1,
12864
13096
  saturation: 180,
12865
13097
  aberrationIntensity: .2,
12866
- cornerRadius: 12,
13098
+ borderRadius: 12,
12867
13099
  mode: "shader"
12868
13100
  }, glassProps = !0 === glass ? defaultGlassProps : {
12869
13101
  ...defaultGlassProps,
@@ -12921,7 +13153,7 @@ const Radio = memo((({label: label, checked: checked = !1, onChange: onChange,
12921
13153
  blurAmount: 1,
12922
13154
  saturation: 160,
12923
13155
  aberrationIntensity: .3,
12924
- cornerRadius: 6,
13156
+ borderRadius: 6,
12925
13157
  mode: "shader"
12926
13158
  }, glassProps = !0 === glass ? defaultGlassProps : {
12927
13159
  ...defaultGlassProps,
@@ -12987,7 +13219,7 @@ const Textarea = memo( forwardRef((({value: value, defaultValue: defaultValue,
12987
13219
  blurAmount: 1,
12988
13220
  saturation: 180,
12989
13221
  aberrationIntensity: 1,
12990
- cornerRadius: 8,
13222
+ borderRadius: 8,
12991
13223
  mode: "shader"
12992
13224
  }, glassProps = !0 === glass ? defaultGlassProps : {
12993
13225
  ...defaultGlassProps,
@@ -13828,7 +14060,7 @@ const Hero = ({title: title, subtitle: subtitle, text: text, imageSrc: imageSrc,
13828
14060
  blurAmount: 3,
13829
14061
  saturation: 180,
13830
14062
  aberrationIntensity: 0,
13831
- cornerRadius: 8,
14063
+ borderRadius: 8,
13832
14064
  overLight: !1,
13833
14065
  mode: "standard",
13834
14066
  children: jsxs("div", {
@@ -14033,7 +14265,7 @@ Hero.Title = ({children: children, className: className, level: level = "h1", ..
14033
14265
  blurAmount: 3,
14034
14266
  saturation: 180,
14035
14267
  aberrationIntensity: 0,
14036
- cornerRadius: 8,
14268
+ borderRadius: 8,
14037
14269
  overLight: !1,
14038
14270
  mode: "standard"
14039
14271
  } : glass;
@@ -14147,7 +14379,7 @@ const Messages = ({messages: messages = [], otherAvatar: otherAvatar, selfAvatar
14147
14379
  onSendMessage: onSendMessage
14148
14380
  }), messagesId = id || `messages-${Math.random().toString(36).substr(2, 9)}`, inputId = `${messagesId}-input`, defaultGlassProps = {
14149
14381
  displacementScale: 150,
14150
- cornerRadius: 12,
14382
+ borderRadius: 12,
14151
14383
  elasticity: 0,
14152
14384
  aberrationIntensity: 2
14153
14385
  }, messagesClasses = `${MESSAGES.CLASSES.BASE} ${glass ? "c-messages--glass" : ""} ${disabled ? "is-disabled" : ""} ${className}`, messagesContent = jsxs(Fragment, {
@@ -14293,7 +14525,7 @@ const Messages = ({messages: messages = [], otherAvatar: otherAvatar, selfAvatar
14293
14525
  children: jsx("div", {
14294
14526
  className: "c-messages__glass-content",
14295
14527
  style: {
14296
- borderRadius: glassProps.cornerRadius
14528
+ borderRadius: glassProps.borderRadius
14297
14529
  },
14298
14530
  children: messagesContent
14299
14531
  })
@@ -14521,7 +14753,7 @@ const Modal = ModalWithSubcomponents, Nav = forwardRef((({children: children, a
14521
14753
  const defaultGlassProps = {
14522
14754
  displacementScale: 60,
14523
14755
  blurAmount: 1.5,
14524
- cornerRadius: 8,
14756
+ borderRadius: 8,
14525
14757
  mode: "shader"
14526
14758
  }, glassProps = !0 === glass ? defaultGlassProps : {
14527
14759
  ...defaultGlassProps,
@@ -14727,7 +14959,7 @@ const Navbar = forwardRef((({brand: brand, children: children, variant: variant
14727
14959
  const defaultGlassProps = {
14728
14960
  displacementScale: 30,
14729
14961
  blurAmount: 2,
14730
- cornerRadius: 0,
14962
+ borderRadius: 0,
14731
14963
  elasticity: 0,
14732
14964
  mode: "shader",
14733
14965
  shaderVariant: "premiumGlass"
@@ -15108,7 +15340,7 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
15108
15340
  const defaultGlassProps = {
15109
15341
  displacementScale: 70,
15110
15342
  blurAmount: 2,
15111
- cornerRadius: 12,
15343
+ borderRadius: 12,
15112
15344
  mode: "shader"
15113
15345
  }, glassProps = !0 === glass ? defaultGlassProps : {
15114
15346
  ...defaultGlassProps,
@@ -16681,7 +16913,7 @@ const PopoverContext = createContext({
16681
16913
  blurAmount: 1,
16682
16914
  saturation: 160,
16683
16915
  aberrationIntensity: .5,
16684
- cornerRadius: 8,
16916
+ borderRadius: 8,
16685
16917
  mode: "shader"
16686
16918
  }, glassProps = !0 === glass ? defaultGlassProps : {
16687
16919
  ...defaultGlassProps,
@@ -16732,7 +16964,14 @@ const PopoverContext = createContext({
16732
16964
  /**
16733
16965
  * Hook for managing rating component state and interactions
16734
16966
  */
16735
- const Rating = forwardRef((({value: valueProp = 0, defaultValue: defaultValue, maxValue: maxValue = 5, allowHalf: allowHalf = !1, readOnly: readOnly = !1, size: size = "md", variant: variant, onChange: onChange, className: className = "", style: style, label: label, id: id, useVanillaJS: useVanillaJS = !1, glass: glass, ...restProps}, ref) => {
16967
+ const calculateStarValue = (e, starValue, allowHalf) => {
16968
+ if (!allowHalf) return starValue;
16969
+ // Get the star element's bounding rectangle
16970
+ const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2, adjustedValue = e.clientX < starCenterX ? starValue - .5 : starValue;
16971
+ // Calculate the x position within the star
16972
+ return Math.max(.5, adjustedValue);
16973
+ // Ensure minimum of 0.5
16974
+ }, Rating = forwardRef((({value: valueProp = 0, defaultValue: defaultValue, maxValue: maxValue = 5, allowHalf: allowHalf = !1, readOnly: readOnly = !1, size: size = "md", variant: variant, onChange: onChange, className: className = "", style: style, label: label, id: id, useVanillaJS: useVanillaJS = !1, glass: glass, ...restProps}, ref) => {
16736
16975
  const internalRef = useRef(null), ratingInstance = useRef(null), {currentValue: currentValue, hoverValue: hoverValue, focusedIndex: focusedIndex, setHoverValue: setHoverValue, setFocused: setFocused, handleKeyDown: handleKeyDown} = (({value: value = 0, maxValue: maxValue = 5, allowHalf: allowHalf = !1, readOnly: readOnly = !1, onChange: onChange}) => {
16737
16976
  // Determine if component is in controlled mode
16738
16977
  const isControlled = void 0 !== onChange, [internalValue, setInternalValue] = useState(value), [hoverValue, setHoverValue] = useState(null), [focusedIndex, setFocusedIndex] = useState(null), currentValue = isControlled ? value : internalValue, handleMouseEnter = useCallback((starValue => {
@@ -16794,30 +17033,14 @@ const Rating = forwardRef((({value: valueProp = 0, defaultValue: defaultValue,
16794
17033
  readOnly: readOnly,
16795
17034
  onChange: onChange
16796
17035
  }), forkedRef = useForkRef(internalRef, ref), handleMouseEnter = useCallback(((e, starValue) => {
16797
- if (!readOnly) if (allowHalf) {
16798
- // Get the star element's bounding rectangle
16799
- const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2, adjustedValue = e.clientX < starCenterX ? starValue - .5 : starValue;
16800
- // Calculate the x position within the star
16801
- setHoverValue(Math.max(.5, adjustedValue));
16802
- } else setHoverValue(starValue);
17036
+ readOnly || setHoverValue(calculateStarValue(e, starValue, !!allowHalf));
16803
17037
  }), [ readOnly, allowHalf, setHoverValue ]), handleMouseMove = useCallback(((e, starValue) => {
16804
- if (readOnly || !allowHalf) return;
16805
- // Get the star element's bounding rectangle
16806
- const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2, adjustedValue = e.clientX < starCenterX ? starValue - .5 : starValue;
16807
- // Calculate the x position within the star
16808
- setHoverValue(Math.max(.5, adjustedValue));
16809
- } // Ensure minimum of 0.5
16810
- ), [ readOnly, allowHalf, setHoverValue ]), handleMouseLeave = useCallback((() => {
17038
+ !readOnly && allowHalf && setHoverValue(calculateStarValue(e, starValue, !!allowHalf));
17039
+ }), [ readOnly, allowHalf, setHoverValue ]), handleMouseLeave = useCallback((() => {
16811
17040
  readOnly || setHoverValue(null);
16812
17041
  }), [ readOnly, setHoverValue ]), handleClick = useCallback(((e, starValue) => {
16813
17042
  if (readOnly) return;
16814
- let newValue = starValue;
16815
- if (allowHalf) {
16816
- // Get the star element's bounding rectangle
16817
- const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2;
16818
- // Calculate the x position within the star
16819
- newValue = e.clientX < starCenterX ? starValue - .5 : starValue, newValue = Math.max(.5, newValue);
16820
- }
17043
+ const newValue = calculateStarValue(e, starValue, !!allowHalf);
16821
17044
  onChange?.(newValue);
16822
17045
  }), [ readOnly, onChange, allowHalf ]);
16823
17046
  // Use vanilla JS implementation if specified
@@ -16922,7 +17145,7 @@ const Rating = forwardRef((({value: valueProp = 0, defaultValue: defaultValue,
16922
17145
  blurAmount: 1,
16923
17146
  saturation: 160,
16924
17147
  aberrationIntensity: .5,
16925
- cornerRadius: 8,
17148
+ borderRadius: 8,
16926
17149
  mode: "shader"
16927
17150
  }, glassProps = !0 === glass ? defaultGlassProps : {
16928
17151
  ...defaultGlassProps,
@@ -16936,21 +17159,8 @@ const Rating = forwardRef((({value: valueProp = 0, defaultValue: defaultValue,
16936
17159
  return ratingContent;
16937
17160
  }));
16938
17161
 
16939
- /**
16940
- * Rating component for displaying and collecting star ratings
16941
- *
16942
- * @example
16943
- * // Basic usage
16944
- * <Rating value={3} onChange={handleRatingChange} />
16945
- *
16946
- * @example
16947
- * // Read-only with custom variant
16948
- * <Rating value={4.5} readOnly variant="warning" />
16949
- *
16950
- * @example
16951
- * // With half-star support
16952
- * <Rating value={3.5} allowHalf maxValue={5} />
16953
- */ Rating.displayName = "Rating";
17162
+ // Helper function to calculate star value based on mouse position
17163
+ Rating.displayName = "Rating";
16954
17164
 
16955
17165
  /**
16956
17166
  * ProductReview component for collecting user ratings and feedback
@@ -17095,7 +17305,7 @@ const Progress = memo( forwardRef((({value: value, variant: variant = "primary"
17095
17305
  const defaultGlassProps = {
17096
17306
  displacementScale: 30,
17097
17307
  blurAmount: .5,
17098
- cornerRadius: 8,
17308
+ borderRadius: 8,
17099
17309
  mode: "shader"
17100
17310
  }, glassProps = !0 === glass ? defaultGlassProps : {
17101
17311
  ...defaultGlassProps,
@@ -17499,7 +17709,7 @@ const Steps = ({items: items, activeIndex: activeIndex = 0, vertical: vertical =
17499
17709
  blurAmount: 1,
17500
17710
  saturation: 160,
17501
17711
  aberrationIntensity: .5,
17502
- cornerRadius: 8,
17712
+ borderRadius: 8,
17503
17713
  mode: "shader"
17504
17714
  }, glassProps = !0 === glass ? defaultGlassProps : {
17505
17715
  ...defaultGlassProps,
@@ -17657,7 +17867,7 @@ const Tabs = memo((({items: items, activeIndex: activeIndex = TAB.DEFAULTS.ACTI
17657
17867
  blurAmount: 1,
17658
17868
  saturation: 160,
17659
17869
  aberrationIntensity: .5,
17660
- cornerRadius: 8,
17870
+ borderRadius: 8,
17661
17871
  mode: "shader"
17662
17872
  }, glassProps = !0 === glass ? defaultGlassProps : {
17663
17873
  ...defaultGlassProps,
@@ -17900,7 +18110,7 @@ const Toggle = ({checked: controlledChecked, defaultChecked: defaultChecked = !1
17900
18110
  blurAmount: 1,
17901
18111
  saturation: 160,
17902
18112
  aberrationIntensity: .5,
17903
- cornerRadius: 8,
18113
+ borderRadius: 8,
17904
18114
  mode: "shader"
17905
18115
  }, glassProps = !0 === glass ? defaultGlassProps : {
17906
18116
  ...defaultGlassProps,