@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.
- package/dist/atomix.css +9341 -9249
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +4 -4
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.d.ts +12 -19
- package/dist/charts.js +555 -358
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +16 -23
- package/dist/core.js +418 -262
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +11 -18
- package/dist/forms.js +411 -257
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +14 -21
- package/dist/heavy.js +408 -254
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +33 -40
- package/dist/index.esm.js +663 -453
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +667 -460
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
- package/scripts/atomix-cli.js +34 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +82 -54
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +17 -18
- package/src/components/AtomixGlass/README.md +5 -5
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +2 -2
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +42 -42
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +5 -5
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +3 -3
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +2 -2
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +45 -45
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +3 -3
- package/src/components/Badge/Badge.stories.tsx +1 -1
- package/src/components/Badge/Badge.tsx +1 -1
- package/src/components/Breadcrumb/Breadcrumb.tsx +90 -76
- package/src/components/Breadcrumb/index.ts +2 -2
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Button/README.md +2 -2
- package/src/components/Callout/Callout.test.tsx +3 -3
- package/src/components/Callout/Callout.tsx +2 -2
- package/src/components/Callout/README.md +2 -2
- package/src/components/Chart/Chart.stories.tsx +1 -1
- package/src/components/Chart/Chart.tsx +5 -5
- package/src/components/Chart/TreemapChart.tsx +37 -29
- package/src/components/DatePicker/readme.md +3 -3
- package/src/components/Dropdown/Dropdown.stories.tsx +1 -1
- package/src/components/EdgePanel/EdgePanel.stories.tsx +7 -7
- package/src/components/Form/Checkbox.stories.tsx +1 -1
- package/src/components/Form/Checkbox.tsx +1 -1
- package/src/components/Form/Input.stories.tsx +1 -1
- package/src/components/Form/Input.tsx +1 -1
- package/src/components/Form/Radio.stories.tsx +1 -1
- package/src/components/Form/Radio.tsx +1 -1
- package/src/components/Form/Select.stories.tsx +1 -1
- package/src/components/Form/Select.tsx +1 -1
- package/src/components/Form/Textarea.stories.tsx +1 -1
- package/src/components/Form/Textarea.tsx +1 -1
- package/src/components/Hero/Hero.stories.tsx +2 -2
- package/src/components/Hero/Hero.tsx +2 -2
- package/src/components/Messages/Messages.stories.tsx +1 -1
- package/src/components/Messages/Messages.tsx +2 -2
- package/src/components/Modal/Modal.stories.tsx +1 -1
- package/src/components/Navigation/Nav/Nav.stories.tsx +2 -2
- package/src/components/Navigation/Nav/Nav.tsx +1 -1
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +3 -3
- package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +2 -2
- package/src/components/Navigation/SideMenu/SideMenu.tsx +1 -1
- package/src/components/Pagination/Pagination.stories.tsx +1 -1
- package/src/components/Pagination/Pagination.tsx +1 -1
- package/src/components/Popover/Popover.stories.tsx +1 -1
- package/src/components/Popover/Popover.tsx +1 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/Rating/Rating.stories.tsx +1 -1
- package/src/components/Rating/Rating.test.tsx +73 -0
- package/src/components/Rating/Rating.tsx +25 -37
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Steps/Steps.stories.tsx +1 -1
- package/src/components/Steps/Steps.tsx +2 -2
- package/src/components/Tabs/Tabs.stories.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +1 -1
- package/src/components/Todo/Todo.tsx +0 -1
- package/src/components/Toggle/Toggle.stories.tsx +1 -1
- package/src/components/Toggle/Toggle.tsx +1 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +1 -1
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +2 -2
- package/src/lib/composables/__tests__/useAtomixGlassPerf.test.tsx +88 -0
- package/src/lib/composables/__tests__/useChart.test.ts +50 -0
- package/src/lib/composables/__tests__/useChart.test.tsx +139 -0
- package/src/lib/composables/__tests__/useHeroBackgroundSlider.test.tsx +59 -0
- package/src/lib/composables/__tests__/useSliderAutoplay.test.tsx +68 -0
- package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +329 -0
- package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +82 -0
- package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +153 -0
- package/src/lib/composables/atomix-glass/useGlassOverLight.ts +198 -0
- package/src/lib/composables/atomix-glass/useGlassSize.ts +117 -0
- package/src/lib/composables/atomix-glass/useGlassState.ts +112 -0
- package/src/lib/composables/atomix-glass/useGlassTransforms.ts +160 -0
- package/src/lib/composables/glass-styles.ts +302 -0
- package/src/lib/composables/index.ts +0 -4
- package/src/lib/composables/useAtomixGlass.ts +331 -522
- package/src/lib/composables/useAtomixGlassStyles.ts +307 -0
- package/src/lib/composables/useBarChart.ts +1 -1
- package/src/lib/composables/useBreadcrumb.ts +6 -6
- package/src/lib/composables/useChart.ts +104 -21
- package/src/lib/composables/useHeroBackgroundSlider.ts +16 -7
- package/src/lib/composables/useSlider.ts +66 -34
- package/src/lib/theme/devtools/CLI.ts +1 -1
- package/src/lib/theme/utils/__tests__/themeUtils.test.ts +213 -0
- package/src/lib/types/components.ts +13 -21
- package/src/lib/utils/__tests__/dom.test.ts +100 -0
- package/src/lib/utils/__tests__/fontPreloader.test.ts +102 -0
- package/src/styles/02-tools/_tools.breakpoints.scss +1 -1
- package/src/styles/02-tools/_tools.utility-api.scss +6 -6
- package/src/styles/06-components/_components.accordion.scss +0 -2
- package/src/styles/06-components/_components.chart.scss +0 -1
- package/src/styles/06-components/_components.dropdown.scss +0 -1
- package/src/styles/06-components/_components.edge-panel.scss +0 -2
- package/src/styles/06-components/_components.photoviewer.scss +0 -1
- package/src/styles/06-components/_components.river.scss +0 -1
- package/src/styles/06-components/_components.slider.scss +0 -3
- package/src/styles/99-utilities/_utilities.glass-fixes.scss +0 -1
- package/src/styles/99-utilities/_utilities.text.scss +1 -0
package/dist/index.js
CHANGED
|
@@ -1972,7 +1972,7 @@ function useAccordion(initialProps) {
|
|
|
1972
1972
|
};
|
|
1973
1973
|
}
|
|
1974
1974
|
|
|
1975
|
-
const {CONSTANTS: CONSTANTS$
|
|
1975
|
+
const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2) => {
|
|
1976
1976
|
if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
|
|
1977
1977
|
const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
|
|
1978
1978
|
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
@@ -1985,36 +1985,36 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1985
1985
|
}, calculateMouseInfluence = mouseOffset => {
|
|
1986
1986
|
if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
|
|
1987
1987
|
// Bounded calculation — keeps the glass effect subtle and stable
|
|
1988
|
-
const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$
|
|
1988
|
+
const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$2.MOUSE_INFLUENCE_DIVISOR;
|
|
1989
1989
|
return Math.min(.8, influence);
|
|
1990
1990
|
// Tighter cap to prevent blur/filter blow-out
|
|
1991
|
-
}, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$
|
|
1991
|
+
}, 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 => {
|
|
1992
1992
|
if ("number" == typeof value) return Math.max(0, value);
|
|
1993
|
-
if ("string" != typeof value || !value.trim()) return CONSTANTS$
|
|
1993
|
+
if ("string" != typeof value || !value.trim()) return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
1994
1994
|
const trimmedValue = value.trim();
|
|
1995
1995
|
// Handle px values
|
|
1996
1996
|
if (trimmedValue.endsWith("px")) {
|
|
1997
1997
|
const parsed = parseFloat(trimmedValue);
|
|
1998
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
1998
|
+
return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
|
|
1999
1999
|
}
|
|
2000
2000
|
// Handle rem values (assume 16px = 1rem)
|
|
2001
2001
|
if (trimmedValue.endsWith("rem")) {
|
|
2002
2002
|
const parsed = parseFloat(trimmedValue);
|
|
2003
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
2003
|
+
return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
|
|
2004
2004
|
}
|
|
2005
2005
|
// Handle em values (assume 16px = 1em for simplicity)
|
|
2006
2006
|
if (trimmedValue.endsWith("em")) {
|
|
2007
2007
|
const parsed = parseFloat(trimmedValue);
|
|
2008
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
2008
|
+
return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
|
|
2009
2009
|
}
|
|
2010
2010
|
// Handle percentage (convert to approximate px value, assuming 200px container)
|
|
2011
2011
|
if (trimmedValue.endsWith("%")) {
|
|
2012
2012
|
const parsed = parseFloat(trimmedValue);
|
|
2013
|
-
return isNaN(parsed) ? CONSTANTS$
|
|
2013
|
+
return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
|
|
2014
2014
|
}
|
|
2015
2015
|
// Handle unitless numbers
|
|
2016
2016
|
const numValue = parseFloat(trimmedValue);
|
|
2017
|
-
return isNaN(numValue) ? CONSTANTS$
|
|
2017
|
+
return isNaN(numValue) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
|
|
2018
2018
|
}, extractBorderRadiusFromElement = element => {
|
|
2019
2019
|
if (!element || !element.props) return null;
|
|
2020
2020
|
// Check inline styles first (highest priority)
|
|
@@ -2030,11 +2030,11 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2030
2030
|
// If element has children, recursively check them
|
|
2031
2031
|
if (element.props.children) {
|
|
2032
2032
|
const childRadius = extractBorderRadiusFromChildren(element.props.children);
|
|
2033
|
-
if (childRadius > 0 && childRadius !== CONSTANTS$
|
|
2033
|
+
if (childRadius > 0 && childRadius !== CONSTANTS$2.DEFAULT_CORNER_RADIUS) return childRadius;
|
|
2034
2034
|
}
|
|
2035
2035
|
return null;
|
|
2036
2036
|
}, extractBorderRadiusFromChildren = children => {
|
|
2037
|
-
if (!children) return CONSTANTS$
|
|
2037
|
+
if (!children) return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
2038
2038
|
try {
|
|
2039
2039
|
const childArray = React__default.default.Children.toArray(children);
|
|
2040
2040
|
for (let i = 0; i < childArray.length; i++) {
|
|
@@ -2047,7 +2047,7 @@ const {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2047
2047
|
} catch (error) {
|
|
2048
2048
|
// Silently handle errors
|
|
2049
2049
|
}
|
|
2050
|
-
return CONSTANTS$
|
|
2050
|
+
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
2051
2051
|
}, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
2052
2052
|
switch (mode) {
|
|
2053
2053
|
case "standard":
|
|
@@ -2218,10 +2218,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2218
2218
|
}, globalMousePosition: globalMousePosition = {
|
|
2219
2219
|
x: 0,
|
|
2220
2220
|
y: 0
|
|
2221
|
-
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {},
|
|
2221
|
+
}, 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 = {
|
|
2222
2222
|
width: 0,
|
|
2223
2223
|
height: 0
|
|
2224
|
-
}, onClick: onClick, mode: mode = "standard",
|
|
2224
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
|
|
2225
2225
|
// Generate a stable, deterministic ID for SSR compatibility
|
|
2226
2226
|
// Use a module-level counter that's consistent across server and client
|
|
2227
2227
|
const filterId = React.useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = React.useState(""), shaderGeneratorRef = React.useRef(null), shaderUtilsRef = React.useRef(null), shaderDebounceTimeoutRef = React.useRef(null);
|
|
@@ -2333,7 +2333,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2333
2333
|
flowBlur: 1.2 * blurAmount
|
|
2334
2334
|
};
|
|
2335
2335
|
// Enhanced validation for liquid blur
|
|
2336
|
-
if (!
|
|
2336
|
+
if (!withLiquidBlur || !rectCache || !mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y || isNaN(mouseOffset.x) || isNaN(mouseOffset.y)) return defaultBlur;
|
|
2337
2337
|
try {
|
|
2338
2338
|
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);
|
|
2339
2339
|
// NOTE: hover/active multipliers intentionally omitted here —
|
|
@@ -2348,14 +2348,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2348
2348
|
return console.warn("AtomixGlassContainer: Error calculating liquid blur", error),
|
|
2349
2349
|
defaultBlur;
|
|
2350
2350
|
}
|
|
2351
|
-
}), [
|
|
2351
|
+
}), [ withLiquidBlur, blurAmount, mouseOffset, rectCache ]), backdropStyle = React.useMemo((() => {
|
|
2352
2352
|
try {
|
|
2353
2353
|
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;
|
|
2354
2354
|
// Validate blur values before using them
|
|
2355
|
-
return !
|
|
2355
|
+
return !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? {
|
|
2356
2356
|
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})`
|
|
2357
2357
|
} : {
|
|
2358
|
-
backdropFilter: `blur(${clampBlur(.4 * validatedBaseBlur + .25 * validatedEdgeBlur + .15 * validatedCenterBlur + .2 * validatedFlowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1
|
|
2358
|
+
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})`
|
|
2359
2359
|
};
|
|
2360
2360
|
// Single-pass fallback: stronger radius to match perceived blur of multi-pass
|
|
2361
2361
|
} catch (error) {
|
|
@@ -2364,7 +2364,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2364
2364
|
backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
|
|
2365
2365
|
};
|
|
2366
2366
|
}
|
|
2367
|
-
}), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion,
|
|
2367
|
+
}), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveWithoutEffects, withLiquidBlur ]), containerVars = React.useMemo((() => {
|
|
2368
2368
|
try {
|
|
2369
2369
|
// Safe extraction of mouse offset values
|
|
2370
2370
|
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;
|
|
@@ -2372,10 +2372,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2372
2372
|
"--atomix-glass-container-width": `${glassSize?.width}`,
|
|
2373
2373
|
"--atomix-glass-container-height": `${glassSize?.height}`,
|
|
2374
2374
|
"--atomix-glass-container-padding": padding || "0 0",
|
|
2375
|
-
"--atomix-glass-container-radius": `${"number" != typeof
|
|
2375
|
+
"--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`,
|
|
2376
2376
|
"--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
|
|
2377
2377
|
"--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",
|
|
2378
|
-
"--atomix-glass-container-shadow-opacity":
|
|
2378
|
+
"--atomix-glass-container-shadow-opacity": effectiveWithoutEffects ? 0 : 1,
|
|
2379
2379
|
// Background and shadow values use design token-aligned RGB values
|
|
2380
2380
|
"--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",
|
|
2381
2381
|
"--atomix-glass-container-text-shadow": overLight ? "0px 2px 12px rgba(0, 0, 0, 0)" : "0px 2px 12px rgba(0, 0, 0, 0.4)",
|
|
@@ -2393,14 +2393,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2393
2393
|
"--atomix-glass-container-text-shadow": "none"
|
|
2394
2394
|
};
|
|
2395
2395
|
}
|
|
2396
|
-
}), [ glassSize, padding,
|
|
2397
|
-
el && (el.style.setProperty("transition-duration", "0s", "important"), el.style.setProperty("animation-duration", "0s", "important"),
|
|
2398
|
-
el.style.setProperty("transition-delay", "0s", "important"));
|
|
2399
|
-
};
|
|
2396
|
+
}), [ glassSize, padding, borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects ]);
|
|
2400
2397
|
return jsxRuntime.jsx("div", {
|
|
2401
2398
|
ref: el => {
|
|
2402
2399
|
// Apply force no-transition
|
|
2403
|
-
setForceNoTransition(el),
|
|
2404
2400
|
// Handle forwarded ref
|
|
2405
2401
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
2406
2402
|
},
|
|
@@ -2435,7 +2431,10 @@ const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({c
|
|
|
2435
2431
|
aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
|
|
2436
2432
|
shaderMapUrl: shaderMapUrl
|
|
2437
2433
|
}), jsxRuntime.jsx("div", {
|
|
2438
|
-
ref:
|
|
2434
|
+
ref: el => {
|
|
2435
|
+
el && (el.style.setProperty("transition-duration", "0s", "important"), el.style.setProperty("animation-duration", "0s", "important"),
|
|
2436
|
+
el.style.setProperty("transition-delay", "0s", "important"));
|
|
2437
|
+
},
|
|
2439
2438
|
className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
|
|
2440
2439
|
style: {
|
|
2441
2440
|
filter: `url(#${filterId})`,
|
|
@@ -2552,7 +2551,128 @@ class {
|
|
|
2552
2551
|
*/ getSubscriberCount() {
|
|
2553
2552
|
return this.listeners.size;
|
|
2554
2553
|
}
|
|
2555
|
-
},
|
|
2554
|
+
}, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
|
|
2555
|
+
if (!wrapperElement && !containerElement) return;
|
|
2556
|
+
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 = {
|
|
2557
|
+
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
2558
|
+
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
2559
|
+
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
2560
|
+
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
2561
|
+
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
|
|
2562
|
+
saturationBoost: baseOverLightConfig.saturationBoost
|
|
2563
|
+
};
|
|
2564
|
+
// Calculate mouse influence
|
|
2565
|
+
// Calculate elastic translation
|
|
2566
|
+
let elasticTranslation = {
|
|
2567
|
+
x: 0,
|
|
2568
|
+
y: 0
|
|
2569
|
+
};
|
|
2570
|
+
if (!effectiveWithoutEffects && wrapperElement) {
|
|
2571
|
+
const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
|
|
2572
|
+
// Calculate fade in factor
|
|
2573
|
+
let fadeInFactor = 0;
|
|
2574
|
+
if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
|
|
2575
|
+
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({
|
|
2576
|
+
x: edgeDistanceX,
|
|
2577
|
+
y: edgeDistanceY
|
|
2578
|
+
}, {
|
|
2579
|
+
x: 0,
|
|
2580
|
+
y: 0
|
|
2581
|
+
});
|
|
2582
|
+
fadeInFactor = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
|
|
2583
|
+
}
|
|
2584
|
+
elasticTranslation = {
|
|
2585
|
+
x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
|
|
2586
|
+
y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2589
|
+
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}`;
|
|
2590
|
+
// Update Wrapper Styles (glassVars)
|
|
2591
|
+
if (wrapperElement) {
|
|
2592
|
+
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 = {
|
|
2593
|
+
hover1: {
|
|
2594
|
+
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
|
|
2595
|
+
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
|
|
2596
|
+
},
|
|
2597
|
+
hover2: {
|
|
2598
|
+
x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
|
|
2599
|
+
y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2
|
|
2600
|
+
},
|
|
2601
|
+
hover3: {
|
|
2602
|
+
x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
|
|
2603
|
+
y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3
|
|
2604
|
+
}
|
|
2605
|
+
}, basePosition = {
|
|
2606
|
+
x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
|
|
2607
|
+
y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
|
|
2608
|
+
}, opacityValues = {
|
|
2609
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
2610
|
+
hover2: isActive ? .5 : 0,
|
|
2611
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
2612
|
+
base: isOverLight ? overLightConfig.opacity : 0,
|
|
2613
|
+
over: isOverLight ? 1.1 * overLightConfig.opacity : 0
|
|
2614
|
+
}, style = wrapperElement.style;
|
|
2615
|
+
style.setProperty("--atomix-glass-transform", transformStyle || "none"),
|
|
2616
|
+
// Gradients
|
|
2617
|
+
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%)`),
|
|
2618
|
+
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%)`),
|
|
2619
|
+
// Hover gradients
|
|
2620
|
+
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}%)`),
|
|
2621
|
+
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}%)`),
|
|
2622
|
+
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}%)`),
|
|
2623
|
+
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})`),
|
|
2624
|
+
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})`),
|
|
2625
|
+
// Opacities
|
|
2626
|
+
style.setProperty("--atomix-glass-hover-1-opacity", opacityValues.hover1.toString()),
|
|
2627
|
+
style.setProperty("--atomix-glass-hover-2-opacity", opacityValues.hover2.toString()),
|
|
2628
|
+
style.setProperty("--atomix-glass-hover-3-opacity", opacityValues.hover3.toString()),
|
|
2629
|
+
style.setProperty("--atomix-glass-base-opacity", opacityValues.base.toString()),
|
|
2630
|
+
style.setProperty("--atomix-glass-overlay-opacity", opacityValues.over.toString()),
|
|
2631
|
+
style.setProperty("--atomix-glass-overlay-highlight-opacity", (opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER).toString()),
|
|
2632
|
+
// Other
|
|
2633
|
+
style.setProperty("--atomix-glass-blend-mode", isOverLight ? "multiply" : "overlay"),
|
|
2634
|
+
style.setProperty("--atomix-glass-radius", `${effectiveBorderRadius}px`);
|
|
2635
|
+
}
|
|
2636
|
+
// Update Container Styles (containerVars)
|
|
2637
|
+
if (containerElement) {
|
|
2638
|
+
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();
|
|
2639
|
+
let liquidBlur = {
|
|
2640
|
+
baseBlur: blurAmount,
|
|
2641
|
+
edgeBlur: blurAmount * EDGE_BLUR_MULTIPLIER,
|
|
2642
|
+
centerBlur: blurAmount * CENTER_BLUR_MULTIPLIER,
|
|
2643
|
+
flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
|
|
2644
|
+
};
|
|
2645
|
+
if (withLiquidBlur && rect) {
|
|
2646
|
+
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);
|
|
2647
|
+
liquidBlur = {
|
|
2648
|
+
baseBlur: clampBlur(baseBlur),
|
|
2649
|
+
edgeBlur: clampBlur(edgeBlur),
|
|
2650
|
+
centerBlur: clampBlur(centerBlur),
|
|
2651
|
+
flowBlur: clampBlur(flowBlur)
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
// Backdrop filter
|
|
2655
|
+
let backdropFilterString = `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`;
|
|
2656
|
+
const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), area = rect ? rect.width * rect.height : 0;
|
|
2657
|
+
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})`;
|
|
2658
|
+
// Container variables
|
|
2659
|
+
const style = containerElement.style;
|
|
2660
|
+
style.setProperty("--atomix-glass-container-width", `${glassSize.width}`), style.setProperty("--atomix-glass-container-height", `${glassSize.height}`),
|
|
2661
|
+
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2662
|
+
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2663
|
+
// Shadows
|
|
2664
|
+
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"),
|
|
2665
|
+
style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
|
|
2666
|
+
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"),
|
|
2667
|
+
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)"),
|
|
2668
|
+
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)");
|
|
2669
|
+
}
|
|
2670
|
+
}, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
|
|
2671
|
+
|
|
2672
|
+
/**
|
|
2673
|
+
* Updates the styles of the AtomixGlass wrapper and container elements imperatively
|
|
2674
|
+
* to avoid React re-renders on mouse movement.
|
|
2675
|
+
*/ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
|
|
2556
2676
|
parentElement && backgroundDetectionCache.set(parentElement, {
|
|
2557
2677
|
result: result,
|
|
2558
2678
|
timestamp: Date.now(),
|
|
@@ -2565,18 +2685,74 @@ class {
|
|
|
2565
2685
|
* Composable hook for AtomixGlass component logic
|
|
2566
2686
|
* Manages all state, calculations, and event handlers
|
|
2567
2687
|
*/
|
|
2568
|
-
function useAtomixGlass({glassRef: glassRef, contentRef: contentRef,
|
|
2688
|
+
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}) {
|
|
2569
2689
|
// State
|
|
2570
|
-
const [isHovered, setIsHovered] = React.useState(!1), [isActive, setIsActive] = React.useState(!1),
|
|
2571
|
-
width: 270,
|
|
2572
|
-
height: 69
|
|
2573
|
-
}), [internalGlobalMousePosition, setInternalGlobalMousePosition] = React.useState({
|
|
2690
|
+
const [isHovered, setIsHovered] = React.useState(!1), [isActive, setIsActive] = React.useState(!1), cachedRectRef = React.useRef(null), internalGlobalMousePositionRef = React.useRef({
|
|
2574
2691
|
x: 0,
|
|
2575
2692
|
y: 0
|
|
2576
|
-
}),
|
|
2693
|
+
}), internalMouseOffsetRef = React.useRef({
|
|
2577
2694
|
x: 0,
|
|
2578
2695
|
y: 0
|
|
2579
|
-
}), [
|
|
2696
|
+
}), [dynamicBorderRadius, setDynamicCornerRadius] = React.useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = React.useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = React.useState(!1), [detectedOverLight, setDetectedOverLight] = React.useState(!1), effectiveBorderRadius = React.useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
|
|
2697
|
+
const [glassSize, setGlassSize] = React.useState({
|
|
2698
|
+
width: 270,
|
|
2699
|
+
height: 69
|
|
2700
|
+
});
|
|
2701
|
+
return React.useEffect((() => {
|
|
2702
|
+
const isValidElement = element => null !== element && element instanceof HTMLElement && element.isConnected;
|
|
2703
|
+
let rafId = null, lastSize = {
|
|
2704
|
+
width: 0,
|
|
2705
|
+
height: 0
|
|
2706
|
+
}, lastCornerRadius = effectiveBorderRadius;
|
|
2707
|
+
const updateGlassSize = (forceUpdate = !1) => {
|
|
2708
|
+
null !== rafId && cancelAnimationFrame(rafId), rafId = requestAnimationFrame((() => {
|
|
2709
|
+
if (!isValidElement(glassRef.current)) return void (rafId = null);
|
|
2710
|
+
const rect = glassRef.current.getBoundingClientRect();
|
|
2711
|
+
if (rect.width <= 0 || rect.height <= 0) return void (rafId = null);
|
|
2712
|
+
// Measure actual rendered size without artificial offsets to avoid feedback loops
|
|
2713
|
+
const newSize = {
|
|
2714
|
+
width: Math.round(rect.width),
|
|
2715
|
+
height: Math.round(rect.height)
|
|
2716
|
+
}, cornerRadiusChanged = lastCornerRadius !== effectiveBorderRadius, dimensionsChanged = Math.abs(newSize.width - lastSize.width) > 1 || Math.abs(newSize.height - lastSize.height) > 1;
|
|
2717
|
+
var size;
|
|
2718
|
+
(forceUpdate || cornerRadiusChanged || dimensionsChanged) && validateGlassSize(size = newSize) && size.width <= CONSTANTS$1.MAX_SIZE && size.height <= CONSTANTS$1.MAX_SIZE && (lastSize = newSize,
|
|
2719
|
+
lastCornerRadius = effectiveBorderRadius, setGlassSize(newSize)), rafId = null;
|
|
2720
|
+
}));
|
|
2721
|
+
};
|
|
2722
|
+
let resizeTimeoutId = null;
|
|
2723
|
+
const debouncedResizeHandler = () => {
|
|
2724
|
+
resizeTimeoutId && clearTimeout(resizeTimeoutId), resizeTimeoutId = setTimeout((() => updateGlassSize(!1)), 16);
|
|
2725
|
+
}, initialTimeoutId = setTimeout((() => updateGlassSize(!0)), 0);
|
|
2726
|
+
let resizeObserver = null, resizeDebounceTimeout = null;
|
|
2727
|
+
// ResizeObserver has 98%+ browser support, no need for fallback
|
|
2728
|
+
if ("undefined" != typeof ResizeObserver && isValidElement(glassRef.current)) try {
|
|
2729
|
+
resizeObserver = new ResizeObserver((entries => {
|
|
2730
|
+
for (const entry of entries) if (entry.target === glassRef.current) {
|
|
2731
|
+
// Update cached rect when size changes
|
|
2732
|
+
glassRef.current && cachedRectRef && (cachedRectRef.current = glassRef.current.getBoundingClientRect()),
|
|
2733
|
+
// Debounce resize updates to match RAF timing (16ms)
|
|
2734
|
+
resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), resizeDebounceTimeout = setTimeout((() => updateGlassSize(!1)), 16);
|
|
2735
|
+
break;
|
|
2736
|
+
}
|
|
2737
|
+
})), resizeObserver.observe(glassRef.current);
|
|
2738
|
+
} catch (error) {
|
|
2739
|
+
console.warn("AtomixGlass: ResizeObserver not available, using window resize only", error);
|
|
2740
|
+
}
|
|
2741
|
+
return window.addEventListener("resize", debouncedResizeHandler, {
|
|
2742
|
+
passive: !0
|
|
2743
|
+
}), () => {
|
|
2744
|
+
clearTimeout(initialTimeoutId), null !== rafId && cancelAnimationFrame(rafId), resizeTimeoutId && clearTimeout(resizeTimeoutId),
|
|
2745
|
+
resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), window.removeEventListener("resize", debouncedResizeHandler),
|
|
2746
|
+
resizeObserver?.disconnect();
|
|
2747
|
+
};
|
|
2748
|
+
}), [ effectiveBorderRadius, glassRef, cachedRectRef ]), {
|
|
2749
|
+
glassSize: glassSize
|
|
2750
|
+
};
|
|
2751
|
+
}({
|
|
2752
|
+
glassRef: glassRef,
|
|
2753
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
2754
|
+
cachedRectRef: cachedRectRef
|
|
2755
|
+
}), effectiveReducedMotion = React.useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveHighContrast = React.useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = React.useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
|
|
2580
2756
|
// Extract border-radius from children
|
|
2581
2757
|
React.useEffect((() => {
|
|
2582
2758
|
const extractRadius = () => {
|
|
@@ -2607,13 +2783,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
2607
2783
|
}
|
|
2608
2784
|
null !== extractedRadius && extractedRadius > 0 && setDynamicCornerRadius(extractedRadius);
|
|
2609
2785
|
} catch (error) {
|
|
2610
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || !
|
|
2786
|
+
"undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugBorderRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
|
|
2611
2787
|
}
|
|
2612
2788
|
};
|
|
2613
2789
|
extractRadius();
|
|
2614
2790
|
const timeoutId = setTimeout(extractRadius, 100);
|
|
2615
2791
|
return () => clearTimeout(timeoutId);
|
|
2616
|
-
}), [ children,
|
|
2792
|
+
}), [ children, debugBorderRadius, contentRef ]),
|
|
2617
2793
|
// Media query handlers and background detection
|
|
2618
2794
|
React.useEffect((() => {
|
|
2619
2795
|
if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
|
|
@@ -2669,72 +2845,52 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
2669
2845
|
const rgb = bgColor.match(/\d+/g);
|
|
2670
2846
|
if (rgb && rgb.length >= 3) {
|
|
2671
2847
|
const r = Number(rgb[0]), g = Number(rgb[1]), b = Number(rgb[2]);
|
|
2672
|
-
|
|
2673
|
-
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)) {
|
|
2848
|
+
if (!isNaN(r) && !isNaN(g) && !isNaN(b) && (r > 10 || g > 10 || b > 10)) {
|
|
2674
2849
|
const luminance = (.299 * r + .587 * g + .114 * b) / 255;
|
|
2675
2850
|
!isNaN(luminance) && isFinite(luminance) && (totalLuminance += luminance, validSamples++,
|
|
2676
2851
|
hasValidBackground = !0);
|
|
2677
2852
|
}
|
|
2678
2853
|
}
|
|
2679
2854
|
}
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
// For image backgrounds, assume medium luminance
|
|
2683
|
-
totalLuminance += .5, validSamples++, hasValidBackground = !0);
|
|
2855
|
+
bgImage && "none" !== bgImage && "initial" !== bgImage && (totalLuminance += .5,
|
|
2856
|
+
validSamples++, hasValidBackground = !0);
|
|
2684
2857
|
} catch (styleError) {
|
|
2685
|
-
|
|
2858
|
+
// Silently continue
|
|
2686
2859
|
}
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
// Exit loop if currentElement becomes null
|
|
2690
|
-
currentElement = currentElement.parentElement, depth++;
|
|
2860
|
+
if (!currentElement) break;
|
|
2861
|
+
currentElement = currentElement.parentElement, depth++;
|
|
2691
2862
|
}
|
|
2692
|
-
|
|
2693
|
-
if (hasValidBackground && validSamples > 0) {
|
|
2863
|
+
if (hasValidBackground && validSamples > 0) {
|
|
2694
2864
|
const avgLuminance = totalLuminance / validSamples;
|
|
2695
2865
|
if (!isNaN(avgLuminance) && isFinite(avgLuminance)) {
|
|
2696
2866
|
let threshold = .7;
|
|
2697
|
-
|
|
2698
|
-
// If overLight is an object, use its threshold property with validation
|
|
2699
|
-
if ("object" == typeof overLight && null !== overLight) {
|
|
2867
|
+
if ("object" == typeof overLight && null !== overLight) {
|
|
2700
2868
|
const objConfig = overLight;
|
|
2701
2869
|
if (void 0 !== objConfig.threshold) {
|
|
2702
|
-
const configThreshold = "number"
|
|
2870
|
+
const configThreshold = "number" != typeof objConfig.threshold || isNaN(objConfig.threshold) ? .7 : objConfig.threshold;
|
|
2703
2871
|
threshold = Math.min(.9, Math.max(.1, configThreshold));
|
|
2704
2872
|
}
|
|
2705
2873
|
}
|
|
2706
2874
|
const isOverLightDetected = avgLuminance > threshold;
|
|
2707
|
-
|
|
2708
|
-
setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold),
|
|
2875
|
+
setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold),
|
|
2709
2876
|
setDetectedOverLight(isOverLightDetected);
|
|
2710
2877
|
} else {
|
|
2711
|
-
// Invalid luminance calculation, default to false
|
|
2712
2878
|
const result = !1, threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
|
|
2713
2879
|
setCachedBackgroundDetection(element.parentElement, overLight, result, threshold),
|
|
2714
2880
|
setDetectedOverLight(result);
|
|
2715
2881
|
}
|
|
2716
2882
|
} else {
|
|
2717
|
-
// Default to false if no valid background found
|
|
2718
2883
|
const result = !1, threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
|
|
2719
2884
|
setCachedBackgroundDetection(element.parentElement, overLight, result, threshold),
|
|
2720
2885
|
setDetectedOverLight(result);
|
|
2721
2886
|
}
|
|
2722
2887
|
} catch (error) {
|
|
2723
|
-
|
|
2724
|
-
"undefined" != typeof process && "development" !== process.env?.NODE_ENV || console.warn("AtomixGlass: Error detecting background brightness:", error);
|
|
2725
|
-
const result = !1;
|
|
2726
|
-
if (element && element.parentElement) {
|
|
2727
|
-
const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
|
|
2728
|
-
setCachedBackgroundDetection(element.parentElement, overLight, result, threshold);
|
|
2729
|
-
}
|
|
2730
|
-
setDetectedOverLight(result);
|
|
2888
|
+
setDetectedOverLight(!1);
|
|
2731
2889
|
}
|
|
2732
2890
|
}), 150);
|
|
2733
2891
|
return () => clearTimeout(timeoutId);
|
|
2734
2892
|
}
|
|
2735
|
-
if ("boolean" == typeof overLight &&
|
|
2736
|
-
// For boolean values, disable auto-detection
|
|
2737
|
-
setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
|
|
2893
|
+
if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
|
|
2738
2894
|
const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
|
|
2739
2895
|
setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
|
|
2740
2896
|
const handleReducedMotionChange = e => {
|
|
@@ -2745,64 +2901,54 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
2745
2901
|
return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
|
|
2746
2902
|
mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
|
|
2747
2903
|
mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
|
|
2748
|
-
|
|
2749
|
-
mediaQueryReducedMotion.removeEventListener ? (mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
|
|
2750
|
-
mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.removeListener && (mediaQueryReducedMotion.removeListener(handleReducedMotionChange),
|
|
2751
|
-
mediaQueryHighContrast.removeListener(handleHighContrastChange));
|
|
2752
|
-
} catch (cleanupError) {
|
|
2753
|
-
console.error("AtomixGlass: Error cleaning up media query listeners:", cleanupError);
|
|
2754
|
-
}
|
|
2904
|
+
// ignore
|
|
2755
2905
|
};
|
|
2756
2906
|
} catch (error) {
|
|
2757
|
-
return
|
|
2907
|
+
return;
|
|
2758
2908
|
}
|
|
2759
2909
|
}), [ overLight, glassRef, debugOverLight ]);
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
2910
|
+
/**
|
|
2911
|
+
* Get effective overLight value based on configuration
|
|
2912
|
+
*/
|
|
2913
|
+
const getEffectiveOverLight = React.useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = React.useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), baseOverLightConfig = React.useMemo((() => {
|
|
2914
|
+
const isOverLight = getEffectiveOverLight(), baseConfig = {
|
|
2915
|
+
isOverLight: isOverLight,
|
|
2916
|
+
threshold: .7,
|
|
2917
|
+
opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
|
|
2918
|
+
contrast: 1,
|
|
2919
|
+
// Base contrast
|
|
2920
|
+
brightness: 1,
|
|
2921
|
+
// Base brightness
|
|
2922
|
+
saturationBoost: 1.3,
|
|
2923
|
+
shadowIntensity: .9,
|
|
2924
|
+
borderOpacity: .7
|
|
2776
2925
|
};
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
return;
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
2926
|
+
if ("object" == typeof overLight && null !== overLight) {
|
|
2927
|
+
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);
|
|
2928
|
+
return {
|
|
2929
|
+
...baseConfig,
|
|
2930
|
+
threshold: validatedThreshold,
|
|
2931
|
+
opacity: validatedOpacity,
|
|
2932
|
+
contrast: validatedContrast,
|
|
2933
|
+
brightness: validatedBrightness,
|
|
2934
|
+
saturationBoost: validatedSaturationBoost
|
|
2935
|
+
};
|
|
2936
|
+
}
|
|
2937
|
+
return baseConfig;
|
|
2938
|
+
}), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = React.useMemo((() => {
|
|
2939
|
+
const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
|
|
2940
|
+
return {
|
|
2941
|
+
isOverLight: baseOverLightConfig.isOverLight,
|
|
2942
|
+
threshold: baseOverLightConfig.threshold,
|
|
2943
|
+
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
2944
|
+
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
2945
|
+
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
2946
|
+
saturationBoost: baseOverLightConfig.saturationBoost,
|
|
2947
|
+
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
2948
|
+
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
|
|
2801
2949
|
};
|
|
2802
|
-
}), [
|
|
2803
|
-
|
|
2804
|
-
const calculateDirectionalScale = React.useCallback((() => {
|
|
2805
|
-
if (!0 === overLight || "auto" === overLight && detectedOverLight || "object" == typeof overLight && null !== overLight && detectedOverLight) return "scale(1)";
|
|
2950
|
+
}), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = React.useRef(null), calculateDirectionalScale = React.useCallback((() => {
|
|
2951
|
+
if (baseOverLightConfig.isOverLight) return "scale(1)";
|
|
2806
2952
|
if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
|
|
2807
2953
|
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({
|
|
2808
2954
|
x: edgeDistanceX,
|
|
@@ -2816,7 +2962,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
2816
2962
|
if (0 === centerDistance) return "scale(1)";
|
|
2817
2963
|
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;
|
|
2818
2964
|
return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
|
|
2819
|
-
}), [ globalMousePosition, elasticity, glassSize, glassRef,
|
|
2965
|
+
}), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = React.useCallback((() => {
|
|
2820
2966
|
if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
|
|
2821
2967
|
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({
|
|
2822
2968
|
x: edgeDistanceX,
|
|
@@ -2836,122 +2982,110 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
2836
2982
|
x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
|
|
2837
2983
|
y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
|
|
2838
2984
|
};
|
|
2839
|
-
}), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = React.useMemo((() =>
|
|
2985
|
+
}), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = React.useMemo((() => effectiveWithoutEffects ? {
|
|
2840
2986
|
x: 0,
|
|
2841
2987
|
y: 0
|
|
2842
|
-
} : calculateElasticTranslation()), [ calculateElasticTranslation,
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
const
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
if (rect.width <= 0 || rect.height <= 0) return void (rafId = null);
|
|
2855
|
-
// Measure actual rendered size without artificial offsets to avoid feedback loops
|
|
2856
|
-
const newSize = {
|
|
2857
|
-
width: Math.round(rect.width),
|
|
2858
|
-
height: Math.round(rect.height)
|
|
2859
|
-
}, cornerRadiusChanged = lastCornerRadius !== effectiveCornerRadius, dimensionsChanged = Math.abs(newSize.width - lastSize.width) > 1 || Math.abs(newSize.height - lastSize.height) > 1;
|
|
2860
|
-
var size;
|
|
2861
|
-
(forceUpdate || cornerRadiusChanged || dimensionsChanged) && validateGlassSize(size = newSize) && size.width <= CONSTANTS.MAX_SIZE && size.height <= CONSTANTS.MAX_SIZE && (lastSize = newSize,
|
|
2862
|
-
lastCornerRadius = effectiveCornerRadius, setGlassSize(newSize)), rafId = null;
|
|
2863
|
-
}));
|
|
2864
|
-
};
|
|
2865
|
-
let resizeTimeoutId = null;
|
|
2866
|
-
const debouncedResizeHandler = () => {
|
|
2867
|
-
resizeTimeoutId && clearTimeout(resizeTimeoutId), resizeTimeoutId = setTimeout((() => updateGlassSize(!1)), 16);
|
|
2868
|
-
}, initialTimeoutId = setTimeout((() => updateGlassSize(!0)), 0);
|
|
2869
|
-
let resizeObserver = null, resizeDebounceTimeout = null;
|
|
2870
|
-
// ResizeObserver has 98%+ browser support, no need for fallback
|
|
2871
|
-
if ("undefined" != typeof ResizeObserver && isValidElement(glassRef.current)) try {
|
|
2872
|
-
resizeObserver = new ResizeObserver((entries => {
|
|
2873
|
-
for (const entry of entries) if (entry.target === glassRef.current) {
|
|
2874
|
-
// Update cached rect when size changes
|
|
2875
|
-
glassRef.current && (cachedRectRef.current = glassRef.current.getBoundingClientRect()),
|
|
2876
|
-
// Debounce resize updates to match RAF timing (16ms)
|
|
2877
|
-
resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), resizeDebounceTimeout = setTimeout((() => updateGlassSize(!1)), 16);
|
|
2878
|
-
break;
|
|
2879
|
-
}
|
|
2880
|
-
})), resizeObserver.observe(glassRef.current);
|
|
2881
|
-
} catch (error) {
|
|
2882
|
-
console.warn("AtomixGlass: ResizeObserver not available, using window resize only", error);
|
|
2883
|
-
}
|
|
2884
|
-
return window.addEventListener("resize", debouncedResizeHandler, {
|
|
2885
|
-
passive: !0
|
|
2886
|
-
}), () => {
|
|
2887
|
-
clearTimeout(initialTimeoutId), null !== rafId && cancelAnimationFrame(rafId), resizeTimeoutId && clearTimeout(resizeTimeoutId),
|
|
2888
|
-
resizeDebounceTimeout && clearTimeout(resizeDebounceTimeout), window.removeEventListener("resize", debouncedResizeHandler),
|
|
2889
|
-
resizeObserver?.disconnect();
|
|
2988
|
+
} : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveWithoutEffects ]), directionalScale = React.useMemo((() => effectiveWithoutEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveWithoutEffects ]), transformStyle = React.useMemo((() => effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`), [ elasticTranslation, isActive, onClick, directionalScale, effectiveWithoutEffects ]), handleGlobalMousePosition = React.useCallback((globalPos => {
|
|
2989
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2990
|
+
if (effectiveWithoutEffects) return;
|
|
2991
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
2992
|
+
if (!container) return;
|
|
2993
|
+
// Use cached rect if available, otherwise get new one
|
|
2994
|
+
let rect = cachedRectRef.current;
|
|
2995
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
2996
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
2997
|
+
const center = calculateElementCenter(rect), newOffset = {
|
|
2998
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
2999
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
2890
3000
|
};
|
|
2891
|
-
|
|
2892
|
-
|
|
3001
|
+
// Calculate offset relative to this container
|
|
3002
|
+
// Store in refs instead of state
|
|
3003
|
+
internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
|
|
3004
|
+
// Imperative style update
|
|
3005
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3006
|
+
mouseOffset: newOffset,
|
|
3007
|
+
globalMousePosition: globalPos,
|
|
3008
|
+
glassSize: glassSize,
|
|
3009
|
+
isHovered: isHovered,
|
|
3010
|
+
isActive: isActive,
|
|
3011
|
+
isOverLight: baseOverLightConfig.isOverLight,
|
|
3012
|
+
baseOverLightConfig: baseOverLightConfig,
|
|
3013
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
3014
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3015
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
3016
|
+
elasticity: elasticity,
|
|
3017
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
3018
|
+
// Simplified directional scale for fast path
|
|
3019
|
+
onClick: onClick,
|
|
3020
|
+
withLiquidBlur: withLiquidBlur,
|
|
3021
|
+
blurAmount: blurAmount,
|
|
3022
|
+
saturation: saturation,
|
|
3023
|
+
padding: padding
|
|
3024
|
+
});
|
|
3025
|
+
}), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
|
|
2893
3026
|
/**
|
|
2894
|
-
*
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
const
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3027
|
+
* Validate and clamp a numeric config value
|
|
3028
|
+
*/
|
|
3029
|
+
// Subscribe to shared mouse tracker
|
|
3030
|
+
React.useEffect((() => {
|
|
3031
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3032
|
+
if (effectiveWithoutEffects) return;
|
|
3033
|
+
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
|
|
3034
|
+
let resizeObserver = null;
|
|
3035
|
+
return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
|
|
3036
|
+
null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
|
|
3037
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
3038
|
+
container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
|
|
3039
|
+
}));
|
|
3040
|
+
})), resizeObserver.observe(container)), () => {
|
|
3041
|
+
unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
3042
|
+
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
2910
3043
|
};
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
3044
|
+
}), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
|
|
3045
|
+
// Also call updateStyles on other state changes (hover, active, etc)
|
|
3046
|
+
React.useEffect((() => {
|
|
3047
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3048
|
+
mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
|
|
3049
|
+
globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
|
|
3050
|
+
glassSize: glassSize,
|
|
3051
|
+
isHovered: isHovered,
|
|
3052
|
+
isActive: isActive,
|
|
3053
|
+
isOverLight: baseOverLightConfig.isOverLight,
|
|
3054
|
+
baseOverLightConfig: baseOverLightConfig,
|
|
3055
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
3056
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3057
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
3058
|
+
elasticity: elasticity,
|
|
3059
|
+
directionalScale: directionalScale,
|
|
3060
|
+
onClick: onClick,
|
|
3061
|
+
withLiquidBlur: withLiquidBlur,
|
|
3062
|
+
blurAmount: blurAmount,
|
|
3063
|
+
saturation: saturation,
|
|
3064
|
+
padding: padding
|
|
3065
|
+
});
|
|
3066
|
+
}), [ isHovered, isActive, glassSize, baseOverLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, directionalScale, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
|
|
3067
|
+
// Event handlers
|
|
3068
|
+
const handleMouseEnter = React.useCallback((() => setIsHovered(!0)), []), handleMouseLeave = React.useCallback((() => setIsHovered(!1)), []), handleMouseDown = React.useCallback((() => setIsActive(!0)), []), handleMouseUp = React.useCallback((() => setIsActive(!1)), []), handleMouseMove = React.useCallback((_e => {}), []), handleKeyDown = React.useCallback((e => {
|
|
2926
3069
|
!onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
|
|
2927
|
-
}), [ onClick ])
|
|
2928
|
-
|
|
2929
|
-
* Validate and clamp a numeric config value
|
|
2930
|
-
* @param value - The value to validate
|
|
2931
|
-
* @param min - Minimum allowed value
|
|
2932
|
-
* @param max - Maximum allowed value
|
|
2933
|
-
* @param defaultValue - Default value if validation fails
|
|
2934
|
-
* @returns Validated and clamped value
|
|
2935
|
-
*/ return {
|
|
2936
|
-
// State
|
|
3070
|
+
}), [ onClick ]);
|
|
3071
|
+
return {
|
|
2937
3072
|
isHovered: isHovered,
|
|
2938
3073
|
isActive: isActive,
|
|
2939
3074
|
glassSize: glassSize,
|
|
2940
|
-
|
|
2941
|
-
|
|
3075
|
+
dynamicBorderRadius: dynamicBorderRadius,
|
|
3076
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
2942
3077
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2943
3078
|
effectiveHighContrast: effectiveHighContrast,
|
|
2944
|
-
|
|
3079
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2945
3080
|
detectedOverLight: detectedOverLight,
|
|
2946
3081
|
globalMousePosition: globalMousePosition,
|
|
3082
|
+
// This is now static (refs or props) unless prop changes
|
|
2947
3083
|
mouseOffset: mouseOffset,
|
|
2948
|
-
//
|
|
3084
|
+
// This is now static (refs or props) unless prop changes
|
|
2949
3085
|
overLightConfig: overLightConfig,
|
|
2950
|
-
// Transform calculations
|
|
2951
3086
|
elasticTranslation: elasticTranslation,
|
|
2952
3087
|
directionalScale: directionalScale,
|
|
2953
3088
|
transformStyle: transformStyle,
|
|
2954
|
-
// Event handlers
|
|
2955
3089
|
handleMouseEnter: handleMouseEnter,
|
|
2956
3090
|
handleMouseLeave: handleMouseLeave,
|
|
2957
3091
|
handleMouseDown: handleMouseDown,
|
|
@@ -2990,7 +3124,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
2990
3124
|
*
|
|
2991
3125
|
* @example
|
|
2992
3126
|
* // Manual border-radius override
|
|
2993
|
-
* <AtomixGlass
|
|
3127
|
+
* <AtomixGlass borderRadius={20}>
|
|
2994
3128
|
* <div>Content with 20px glass radius</div>
|
|
2995
3129
|
* </AtomixGlass>
|
|
2996
3130
|
*
|
|
@@ -3031,37 +3165,48 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
3031
3165
|
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
3032
3166
|
* <div>Content with debug logging enabled</div>
|
|
3033
3167
|
* </AtomixGlass>
|
|
3034
|
-
*/ 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,
|
|
3035
|
-
const glassRef = React.useRef(null), contentRef = React.useRef(null), {isHovered: isHovered, isActive: isActive, glassSize: glassSize,
|
|
3168
|
+
*/ 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}) {
|
|
3169
|
+
const glassRef = React.useRef(null), contentRef = React.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({
|
|
3036
3170
|
glassRef: glassRef,
|
|
3037
3171
|
contentRef: contentRef,
|
|
3038
|
-
|
|
3172
|
+
borderRadius: borderRadius,
|
|
3039
3173
|
globalMousePosition: externalGlobalMousePosition,
|
|
3040
3174
|
mouseOffset: externalMouseOffset,
|
|
3041
3175
|
mouseContainer: mouseContainer,
|
|
3042
3176
|
overLight: overLight,
|
|
3043
3177
|
reducedMotion: reducedMotion,
|
|
3044
3178
|
highContrast: highContrast,
|
|
3045
|
-
|
|
3179
|
+
withoutEffects: withoutEffects,
|
|
3046
3180
|
elasticity: elasticity,
|
|
3047
3181
|
onClick: onClick,
|
|
3048
|
-
|
|
3182
|
+
debugBorderRadius: debugBorderRadius,
|
|
3049
3183
|
debugOverLight: debugOverLight,
|
|
3050
|
-
|
|
3051
|
-
children: children
|
|
3052
|
-
|
|
3184
|
+
debugPerformance: debugPerformance,
|
|
3185
|
+
children: children,
|
|
3186
|
+
blurAmount: blurAmount,
|
|
3187
|
+
saturation: saturation,
|
|
3188
|
+
withLiquidBlur: withLiquidBlur,
|
|
3189
|
+
padding: padding,
|
|
3190
|
+
style: style
|
|
3191
|
+
}), isOverLight = React.useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
|
|
3053
3192
|
...style,
|
|
3054
|
-
...!
|
|
3193
|
+
...!effectiveWithoutEffects && {
|
|
3055
3194
|
transform: transformStyle
|
|
3056
3195
|
}
|
|
3057
|
-
}, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`,
|
|
3196
|
+
}, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = React.useMemo((() => ({
|
|
3058
3197
|
position: style.position || "absolute",
|
|
3059
3198
|
top: style.top || 0,
|
|
3060
3199
|
left: style.left || 0
|
|
3061
|
-
})), [ style.position, style.top, style.left ]), adjustedSize = React.useMemo((() =>
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3200
|
+
})), [ style.position, style.top, style.left ]), adjustedSize = React.useMemo((() => {
|
|
3201
|
+
const resolveSize = (propValue, styleValue, measuredSize) => {
|
|
3202
|
+
const explicitSize = propValue ?? styleValue;
|
|
3203
|
+
return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
|
|
3204
|
+
};
|
|
3205
|
+
return {
|
|
3206
|
+
width: resolveSize(width, style.width, glassSize.width),
|
|
3207
|
+
height: resolveSize(height, style.height, glassSize.height)
|
|
3208
|
+
};
|
|
3209
|
+
}), [ width, height, style.width, style.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = React.useMemo((() => {
|
|
3065
3210
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
3066
3211
|
return {
|
|
3067
3212
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -3103,13 +3248,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
3103
3248
|
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = React.useMemo((() => {
|
|
3104
3249
|
const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues, configBorderOpacity = overLightConfig?.borderOpacity ?? 1;
|
|
3105
3250
|
return {
|
|
3106
|
-
"--atomix-glass-radius": `${
|
|
3251
|
+
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
3107
3252
|
"--atomix-glass-transform": transformStyle || "none",
|
|
3108
3253
|
"--atomix-glass-position": positionStyles.position,
|
|
3109
3254
|
"--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
|
|
3110
3255
|
"--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
|
|
3111
|
-
"--atomix-glass-width":
|
|
3112
|
-
"--atomix-glass-height":
|
|
3256
|
+
"--atomix-glass-width": adjustedSize.width,
|
|
3257
|
+
"--atomix-glass-height": adjustedSize.height,
|
|
3113
3258
|
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
|
|
3114
3259
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
3115
3260
|
"--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%)`,
|
|
@@ -3125,24 +3270,25 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
3125
3270
|
"--atomix-glass-overlay-opacity": opacityValues.over,
|
|
3126
3271
|
"--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})`
|
|
3127
3272
|
};
|
|
3128
|
-
}), [ gradientValues, opacityValues,
|
|
3273
|
+
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsxRuntime.jsx("div", {
|
|
3129
3274
|
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(" "),
|
|
3130
3275
|
style: {
|
|
3131
3276
|
...positionStyles,
|
|
3132
3277
|
height: adjustedSize.height,
|
|
3133
3278
|
width: adjustedSize.width,
|
|
3134
|
-
borderRadius: `${
|
|
3279
|
+
borderRadius: `${effectiveBorderRadius}px`,
|
|
3135
3280
|
transform: baseStyle.transform
|
|
3136
3281
|
}
|
|
3137
3282
|
});
|
|
3138
3283
|
return jsxRuntime.jsxs("div", {
|
|
3284
|
+
...rest,
|
|
3139
3285
|
className: componentClassName,
|
|
3140
3286
|
style: glassVars,
|
|
3141
3287
|
role: role || (onClick ? "button" : void 0),
|
|
3142
3288
|
tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
|
|
3143
3289
|
"aria-label": ariaLabel,
|
|
3144
3290
|
"aria-describedby": ariaDescribedBy,
|
|
3145
|
-
"aria-disabled": !(!onClick || !
|
|
3291
|
+
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
3146
3292
|
"aria-pressed": !(!onClick || !isActive) || !onClick && void 0,
|
|
3147
3293
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
3148
3294
|
children: [ jsxRuntime.jsx(AtomixGlassContainer, {
|
|
@@ -3150,18 +3296,18 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
3150
3296
|
contentRef: contentRef,
|
|
3151
3297
|
className: className,
|
|
3152
3298
|
style: baseStyle,
|
|
3153
|
-
|
|
3154
|
-
displacementScale:
|
|
3155
|
-
blurAmount:
|
|
3299
|
+
borderRadius: effectiveBorderRadius,
|
|
3300
|
+
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
3301
|
+
blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
|
|
3156
3302
|
saturation: effectiveHighContrast ? ATOMIX_GLASS.CONSTANTS.SATURATION.HIGH_CONTRAST : isOverLight ? saturation * overLightConfig.saturationBoost : saturation,
|
|
3157
|
-
aberrationIntensity:
|
|
3303
|
+
aberrationIntensity: effectiveWithoutEffects ? 0 : "shader" === mode ? aberrationIntensity * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_ABERRATION : aberrationIntensity,
|
|
3158
3304
|
glassSize: glassSize,
|
|
3159
3305
|
padding: padding,
|
|
3160
|
-
mouseOffset:
|
|
3306
|
+
mouseOffset: effectiveWithoutEffects ? {
|
|
3161
3307
|
x: 0,
|
|
3162
3308
|
y: 0
|
|
3163
3309
|
} : mouseOffset,
|
|
3164
|
-
globalMousePosition:
|
|
3310
|
+
globalMousePosition: effectiveWithoutEffects ? {
|
|
3165
3311
|
x: 0,
|
|
3166
3312
|
y: 0
|
|
3167
3313
|
} : globalMousePosition,
|
|
@@ -3181,11 +3327,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
3181
3327
|
onClick: onClick,
|
|
3182
3328
|
mode: mode,
|
|
3183
3329
|
transform: baseStyle.transform,
|
|
3184
|
-
|
|
3330
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3185
3331
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
3186
3332
|
shaderVariant: shaderVariant,
|
|
3187
3333
|
elasticity: elasticity,
|
|
3188
|
-
|
|
3334
|
+
withLiquidBlur: withLiquidBlur,
|
|
3189
3335
|
children: children
|
|
3190
3336
|
}), Boolean(onClick) && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
3191
3337
|
children: [ jsxRuntime.jsx("div", {
|
|
@@ -3207,11 +3353,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
3207
3353
|
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}%)`
|
|
3208
3354
|
}
|
|
3209
3355
|
}) ]
|
|
3210
|
-
}),
|
|
3356
|
+
}), withBorder && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
3211
3357
|
children: [ jsxRuntime.jsx("span", {
|
|
3212
|
-
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
3358
|
+
className: ATOMIX_GLASS.BORDER_1_CLASS,
|
|
3359
|
+
style: {
|
|
3360
|
+
width: glassSize.width,
|
|
3361
|
+
height: glassSize.height
|
|
3362
|
+
}
|
|
3213
3363
|
}), jsxRuntime.jsx("span", {
|
|
3214
|
-
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
3364
|
+
className: ATOMIX_GLASS.BORDER_2_CLASS,
|
|
3365
|
+
style: {
|
|
3366
|
+
width: glassSize.width,
|
|
3367
|
+
height: glassSize.height
|
|
3368
|
+
}
|
|
3215
3369
|
}) ]
|
|
3216
3370
|
}) ]
|
|
3217
3371
|
});
|
|
@@ -3821,7 +3975,7 @@ const Badge = React.memo((({label: label, variant: variant = "primary", size: s
|
|
|
3821
3975
|
// Default glass settings for badges
|
|
3822
3976
|
const defaultGlassProps = {
|
|
3823
3977
|
displacementScale: 20,
|
|
3824
|
-
|
|
3978
|
+
borderRadius: ref.current?.getBoundingClientRect().width ? ref.current?.getBoundingClientRect().width / 2 : 16,
|
|
3825
3979
|
className: "c-badge--glass",
|
|
3826
3980
|
elasticity: 0
|
|
3827
3981
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
@@ -3942,7 +4096,7 @@ const useBlock = () => ({
|
|
|
3942
4096
|
* ```
|
|
3943
4097
|
*/ Block.displayName = "Block";
|
|
3944
4098
|
|
|
3945
|
-
const BreadcrumbItem = React.forwardRef((({children: children, href: href, active: active, icon: icon, onClick: onClick, className: className = "", style: style, linkAs:
|
|
4099
|
+
const BreadcrumbItem = React.forwardRef((({children: children, href: href, active: active, icon: icon, onClick: onClick, className: className = "", style: style, linkAs: linkAs, linkProps: linkProps = {}, ...props}, ref) => {
|
|
3946
4100
|
const itemClasses = [ BREADCRUMB.CLASSES.ITEM, active ? BREADCRUMB.CLASSES.ACTIVE : "", className ].filter(Boolean).join(" "), linkContent = jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
3947
4101
|
children: [ icon && jsxRuntime.jsx("span", {
|
|
3948
4102
|
className: "c-breadcrumb__icon",
|
|
@@ -3954,20 +4108,19 @@ const BreadcrumbItem = React.forwardRef((({children: children, href: href, acti
|
|
|
3954
4108
|
style: style,
|
|
3955
4109
|
// Apply style to the link as per legacy behavior
|
|
3956
4110
|
...linkProps
|
|
3957
|
-
};
|
|
4111
|
+
}, LinkComponent = linkAs;
|
|
3958
4112
|
return jsxRuntime.jsx("li", {
|
|
3959
4113
|
ref: ref,
|
|
3960
4114
|
className: itemClasses,
|
|
3961
4115
|
style: style,
|
|
3962
4116
|
...props,
|
|
3963
|
-
children: href && !active ? LinkComponent ?
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
})() : jsxRuntime.jsx("a", {
|
|
4117
|
+
children: href && !active ? LinkComponent ?
|
|
4118
|
+
// @ts-ignore - Dynamic components are tricky in TS without stricter types
|
|
4119
|
+
jsxRuntime.jsx(LinkComponent, {
|
|
4120
|
+
href: href,
|
|
4121
|
+
...commonLinkProps,
|
|
4122
|
+
children: linkContent
|
|
4123
|
+
}) : jsxRuntime.jsx("a", {
|
|
3971
4124
|
href: href,
|
|
3972
4125
|
...commonLinkProps,
|
|
3973
4126
|
children: linkContent
|
|
@@ -3980,7 +4133,7 @@ const BreadcrumbItem = React.forwardRef((({children: children, href: href, acti
|
|
|
3980
4133
|
|
|
3981
4134
|
BreadcrumbItem.displayName = "BreadcrumbItem";
|
|
3982
4135
|
|
|
3983
|
-
const Breadcrumb = React.memo((({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", LinkComponent: LinkComponent, style: style, children: children})
|
|
4136
|
+
const Breadcrumb = React.memo((function({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", LinkComponent: LinkComponent, style: style, children: children}) {
|
|
3984
4137
|
const breadcrumbClasses = [ BREADCRUMB.CLASSES.BASE, className ].filter(Boolean).join(" ");
|
|
3985
4138
|
let content;
|
|
3986
4139
|
if (items && items.length > 0)
|
|
@@ -4002,12 +4155,12 @@ const Breadcrumb = React.memo((({items: items, divider: divider, className: cla
|
|
|
4002
4155
|
const childrenCount = React.Children.count(children);
|
|
4003
4156
|
content = React.Children.map(children, ((child, index) => {
|
|
4004
4157
|
if ( React.isValidElement(child)) {
|
|
4005
|
-
const isLast = index === childrenCount - 1, childProps = child.props
|
|
4158
|
+
const isLast = index === childrenCount - 1, childProps = child.props, {active: active, linkAs: linkAs, ...otherProps} = childProps, newProps = {
|
|
4159
|
+
active: active ?? (!!isLast || void 0),
|
|
4160
|
+
linkAs: linkAs ?? LinkComponent
|
|
4161
|
+
};
|
|
4006
4162
|
|
|
4007
|
-
return React.cloneElement(child,
|
|
4008
|
-
active: childProps.active ?? (!!isLast || void 0),
|
|
4009
|
-
linkAs: childProps.linkAs ?? LinkComponent
|
|
4010
|
-
});
|
|
4163
|
+
return React.cloneElement(child, newProps);
|
|
4011
4164
|
}
|
|
4012
4165
|
return child;
|
|
4013
4166
|
}));
|
|
@@ -4074,7 +4227,7 @@ const Spinner = React.memo((({size: size = "md", variant: variant = "primary",
|
|
|
4074
4227
|
const defaultGlassProps = {
|
|
4075
4228
|
displacementScale: 20,
|
|
4076
4229
|
blurAmount: 1,
|
|
4077
|
-
|
|
4230
|
+
borderRadius: 999,
|
|
4078
4231
|
mode: "shader"
|
|
4079
4232
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4080
4233
|
...defaultGlassProps,
|
|
@@ -4471,7 +4624,7 @@ const Callout = React.memo((({title: title, children: children, icon: icon, var
|
|
|
4471
4624
|
// Default glass settings for callouts
|
|
4472
4625
|
const defaultGlassProps = {
|
|
4473
4626
|
displacementScale: 30,
|
|
4474
|
-
|
|
4627
|
+
borderRadius: 8,
|
|
4475
4628
|
elasticity: 0
|
|
4476
4629
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
4477
4630
|
...defaultGlassProps,
|
|
@@ -4493,7 +4646,7 @@ const Callout = React.memo((({title: title, children: children, icon: icon, var
|
|
|
4493
4646
|
children: jsxRuntime.jsx("div", {
|
|
4494
4647
|
className: "c-callout__glass-content",
|
|
4495
4648
|
style: {
|
|
4496
|
-
borderRadius: glassProps.
|
|
4649
|
+
borderRadius: glassProps.borderRadius
|
|
4497
4650
|
},
|
|
4498
4651
|
children: calloutContent
|
|
4499
4652
|
})
|
|
@@ -5179,12 +5332,22 @@ function useChart(initialProps) {
|
|
|
5179
5332
|
left: 40
|
|
5180
5333
|
}, config) => {
|
|
5181
5334
|
if (!datasets || 0 === datasets.length) return null;
|
|
5182
|
-
//
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5335
|
+
// Calculate total points and min/max values efficiently avoiding spread operator
|
|
5336
|
+
let totalPoints = 0, minValue = 1 / 0, maxValue = -1 / 0, hasValidData = !1;
|
|
5337
|
+
for (const dataset of datasets) if (dataset.data) {
|
|
5338
|
+
totalPoints += dataset.data.length;
|
|
5339
|
+
const {min: min, max: max, hasValid: hasValid} = getDatasetBounds(dataset.data);
|
|
5340
|
+
hasValid && (min < minValue && (minValue = min), max > maxValue && (maxValue = max),
|
|
5341
|
+
hasValidData = !0);
|
|
5342
|
+
}
|
|
5343
|
+
if (0 === totalPoints) return null;
|
|
5344
|
+
// Handle case with no valid numeric data
|
|
5345
|
+
hasValidData || (minValue = 0, maxValue = 0);
|
|
5346
|
+
const valueRange = maxValue - minValue || 1, innerWidth = width - padding.left - padding.right, innerHeight = height - padding.top - padding.bottom;
|
|
5347
|
+
// Avoid division by zero
|
|
5348
|
+
// Apply padding
|
|
5349
|
+
return {
|
|
5350
|
+
xScale: (index, dataLength = totalPoints) => dataLength <= 1 ? padding.left + innerWidth / 2 : padding.left + index / (dataLength - 1) * innerWidth,
|
|
5188
5351
|
yScale: value => padding.top + innerHeight - (value - minValue) / valueRange * innerHeight,
|
|
5189
5352
|
minValue: minValue,
|
|
5190
5353
|
maxValue: maxValue,
|
|
@@ -5239,6 +5402,29 @@ function useChart(initialProps) {
|
|
|
5239
5402
|
|
|
5240
5403
|
/**
|
|
5241
5404
|
* Hook for chart data processing and transformation
|
|
5405
|
+
*/
|
|
5406
|
+
/**
|
|
5407
|
+
* Helper to calculate min/max values from a dataset efficiently
|
|
5408
|
+
* avoiding spread operator which can cause stack overflow on large arrays
|
|
5409
|
+
*/
|
|
5410
|
+
function getDatasetBounds(data) {
|
|
5411
|
+
let min = 1 / 0, max = -1 / 0, hasValid = !1;
|
|
5412
|
+
if (data && data.length > 0) for (let i = 0; i < data.length; i++) {
|
|
5413
|
+
const point = data[i];
|
|
5414
|
+
if (point && "number" == typeof point.value) {
|
|
5415
|
+
const val = point.value;
|
|
5416
|
+
val < min && (min = val), val > max && (max = val), hasValid = !0;
|
|
5417
|
+
}
|
|
5418
|
+
}
|
|
5419
|
+
return {
|
|
5420
|
+
min: min,
|
|
5421
|
+
max: max,
|
|
5422
|
+
hasValid: hasValid
|
|
5423
|
+
};
|
|
5424
|
+
}
|
|
5425
|
+
|
|
5426
|
+
/**
|
|
5427
|
+
* Hook for managing chart toolbar state and generating chart-specific configurations
|
|
5242
5428
|
*/ const ChartToolbar = React.memo( React.forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
|
|
5243
5429
|
refresh: !0,
|
|
5244
5430
|
export: !0,
|
|
@@ -5659,11 +5845,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
5659
5845
|
onZoomReset: handleZoomReset,
|
|
5660
5846
|
onPanToggle: handlePanToggle,
|
|
5661
5847
|
onReset: handleReset
|
|
5662
|
-
})), [ onRefresh, onExport, handleFullscreenChange, handleZoomIn, handleZoomOut, handleZoomReset, handlePanToggle, handleReset ]), {state: toolbarState, handlers: toolbarHandlers, toolbarGroups: toolbarGroups} =
|
|
5663
|
-
/**
|
|
5664
|
-
* Hook for managing chart toolbar state and generating chart-specific configurations
|
|
5665
|
-
*/
|
|
5666
|
-
function(chartType, config = {}, handlers = {}) {
|
|
5848
|
+
})), [ onRefresh, onExport, handleFullscreenChange, handleZoomIn, handleZoomOut, handleZoomReset, handlePanToggle, handleReset ]), {state: toolbarState, handlers: toolbarHandlers, toolbarGroups: toolbarGroups} = function(chartType, config = {}, handlers = {}) {
|
|
5667
5849
|
const [state, setState] = React.useState({
|
|
5668
5850
|
isFullscreen: !1,
|
|
5669
5851
|
isExporting: !1,
|
|
@@ -6048,16 +6230,16 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
6048
6230
|
aberrationIntensity: 1.5,
|
|
6049
6231
|
elasticity: 0,
|
|
6050
6232
|
// No elastic effect for charts
|
|
6051
|
-
|
|
6233
|
+
withLiquidBlur: !1,
|
|
6052
6234
|
// Keep it simple
|
|
6053
|
-
|
|
6235
|
+
withBorder: !0,
|
|
6054
6236
|
mode: "standard",
|
|
6055
6237
|
mouseContainer: chartContainerRef,
|
|
6056
6238
|
reducedMotion: !1
|
|
6057
6239
|
})), []), glassProps = React.useMemo((() => glass ? !0 === glass ? defaultChartGlassProps : {
|
|
6058
6240
|
...defaultChartGlassProps,
|
|
6059
6241
|
...glass
|
|
6060
|
-
} : null), [ glass, defaultChartGlassProps ]), chartBorderRadius = React.useMemo((() => glassProps?.
|
|
6242
|
+
} : null), [ glass, defaultChartGlassProps ]), chartBorderRadius = React.useMemo((() => glassProps?.borderRadius || void 0), [ glassProps?.borderRadius ]), chartContextValue = React.useMemo((() => ({
|
|
6061
6243
|
zoomLevel: zoomLevel,
|
|
6062
6244
|
panOffset: panOffset,
|
|
6063
6245
|
panEnabled: panEnabled,
|
|
@@ -6188,7 +6370,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
6188
6370
|
}) ]
|
|
6189
6371
|
}), wrappedChart = glassProps ? jsxRuntime.jsx(AtomixGlass, {
|
|
6190
6372
|
...glassProps,
|
|
6191
|
-
|
|
6373
|
+
borderRadius: chartBorderRadius,
|
|
6192
6374
|
style: {
|
|
6193
6375
|
width: "100%",
|
|
6194
6376
|
height: "100%",
|
|
@@ -6241,7 +6423,13 @@ const ChartRenderer = React.memo( React.forwardRef((({datasets: datasets = [],
|
|
|
6241
6423
|
// Get chart context (zoom/pan state from toolbar) - optional
|
|
6242
6424
|
// Always call useContext to maintain consistent hook order
|
|
6243
6425
|
const chartContext = React.useContext(ChartContext), {calculateScales: calculateScales, getChartColors: getChartColors} = useChart(), {processedData: processedData, isProcessing: isProcessing} = function(datasets, options) {
|
|
6244
|
-
const [processedData, setProcessedData] = React.useState(datasets), [isProcessing, setIsProcessing] = React.useState(!1), {enableDecimation: enableDecimation = !1, maxDataPoints: maxDataPoints = 1e3, enableRealTime: enableRealTime = !1, realTimeInterval: realTimeInterval = 1e3} = options || {},
|
|
6426
|
+
const [processedData, setProcessedData] = React.useState(datasets), [isProcessing, setIsProcessing] = React.useState(!1), {enableDecimation: enableDecimation = !1, maxDataPoints: maxDataPoints = 1e3, enableRealTime: enableRealTime = !1, realTimeInterval: realTimeInterval = 1e3} = options || {}, lastDataSignature = React.useRef(""), getDatasetSignature = React.useCallback((data => data.map((d => `${d.label}:${JSON.stringify(d.data)}`)).join("|")), []);
|
|
6427
|
+
// Update signature when processedData changes (e.g. via props)
|
|
6428
|
+
React.useEffect((() => {
|
|
6429
|
+
lastDataSignature.current = getDatasetSignature(processedData);
|
|
6430
|
+
}), [ processedData, getDatasetSignature ]);
|
|
6431
|
+
// Data decimation for performance
|
|
6432
|
+
const decimateData = React.useCallback(((data, maxPoints) => {
|
|
6245
6433
|
if (!enableDecimation || !data.length) return data;
|
|
6246
6434
|
const dataLength = data[0]?.data?.length || 0;
|
|
6247
6435
|
if (dataLength <= maxPoints) return data;
|
|
@@ -6261,10 +6449,17 @@ const ChartRenderer = React.memo( React.forwardRef((({datasets: datasets = [],
|
|
|
6261
6449
|
}), []), calculateTrendLine = React.useCallback((values => {
|
|
6262
6450
|
const n = values.length;
|
|
6263
6451
|
if (n < 2) return values.map((() => null));
|
|
6264
|
-
|
|
6452
|
+
let xSum = 0, ySum = 0, xySum = 0, x2Sum = 0;
|
|
6453
|
+
for (let i = 0; i < n; i++) {
|
|
6454
|
+
const val = values[i], safeVal = "number" == typeof val ? val : 0;
|
|
6455
|
+
// Treat null/undefined as 0 to match original reduce behavior
|
|
6456
|
+
xSum += i, ySum += safeVal, xySum += i * safeVal, x2Sum += i * i;
|
|
6457
|
+
}
|
|
6458
|
+
const slope = (n * xySum - xSum * ySum) / (n * x2Sum - xSum * xSum), intercept = (ySum - slope * xSum) / n;
|
|
6265
6459
|
return values.map(((_, i) => slope * i + intercept));
|
|
6266
6460
|
}), []);
|
|
6267
|
-
//
|
|
6461
|
+
// Moving average calculation
|
|
6462
|
+
// Process data when datasets change
|
|
6268
6463
|
return React.useEffect((() => {
|
|
6269
6464
|
setIsProcessing(!0), (async () => {
|
|
6270
6465
|
let processed = [ ...datasets ];
|
|
@@ -6276,11 +6471,12 @@ const ChartRenderer = React.memo( React.forwardRef((({datasets: datasets = [],
|
|
|
6276
6471
|
React.useEffect((() => {
|
|
6277
6472
|
if (!enableRealTime) return;
|
|
6278
6473
|
const interval = setInterval((() => {
|
|
6279
|
-
setProcessedData((prev =>
|
|
6280
|
-
|
|
6281
|
-
|
|
6474
|
+
setProcessedData((prev =>
|
|
6475
|
+
// Only trigger update if signature changed
|
|
6476
|
+
getDatasetSignature(prev) === lastDataSignature.current ? prev : [ ...prev ]));
|
|
6477
|
+
}), realTimeInterval);
|
|
6282
6478
|
return () => clearInterval(interval);
|
|
6283
|
-
}), [ enableRealTime, realTimeInterval ]), {
|
|
6479
|
+
}), [ enableRealTime, realTimeInterval, getDatasetSignature ]), {
|
|
6284
6480
|
processedData: processedData,
|
|
6285
6481
|
isProcessing: isProcessing,
|
|
6286
6482
|
decimateData: decimateData,
|
|
@@ -6301,12 +6497,12 @@ const ChartRenderer = React.memo( React.forwardRef((({datasets: datasets = [],
|
|
|
6301
6497
|
*/
|
|
6302
6498
|
function(datasets, options) {
|
|
6303
6499
|
const {enableVirtualization: enableVirtualization = !1, enableMemoization: enableMemoization = !0, debounceMs: debounceMs = 100} = options || {}, [isOptimizing, setIsOptimizing] = React.useState(!1), debounceRef = React.useRef(null), memoizedScales = React.useMemo((() => enableMemoization ? datasets.map((dataset => {
|
|
6304
|
-
const
|
|
6500
|
+
const {min: min, max: max, hasValid: hasValid} = getDatasetBounds(dataset.data);
|
|
6305
6501
|
return {
|
|
6306
6502
|
label: dataset.label,
|
|
6307
6503
|
dataLength: dataset.data?.length || 0,
|
|
6308
|
-
minValue:
|
|
6309
|
-
maxValue:
|
|
6504
|
+
minValue: hasValid ? min : 0,
|
|
6505
|
+
maxValue: hasValid ? max : 0
|
|
6310
6506
|
};
|
|
6311
6507
|
})) : null), [ datasets, enableMemoization ]), debouncedUpdate = React.useCallback((callback => {
|
|
6312
6508
|
debounceRef.current && clearTimeout(debounceRef.current), debounceRef.current = setTimeout((() => {
|
|
@@ -6405,8 +6601,8 @@ const ChartRenderer = React.memo( React.forwardRef((({datasets: datasets = [],
|
|
|
6405
6601
|
const getAccessibleDescription = React.useCallback((() => {
|
|
6406
6602
|
if (!datasets.length) return "Empty chart";
|
|
6407
6603
|
const datasetDescriptions = datasets.map(((dataset, i) => {
|
|
6408
|
-
const dataCount = dataset.data?.length || 0,
|
|
6409
|
-
return `Dataset ${i + 1}: ${dataset.label}, ${dataCount} points, range ${
|
|
6604
|
+
const dataCount = dataset.data?.length || 0, {min: min, max: max, hasValid: hasValid} = getDatasetBounds(dataset.data), minVal = hasValid ? min : 0, maxVal = hasValid ? max : 0;
|
|
6605
|
+
return `Dataset ${i + 1}: ${dataset.label}, ${dataCount} points, range ${minVal} to ${maxVal}`;
|
|
6410
6606
|
})).join(". ");
|
|
6411
6607
|
return `Chart with ${datasets.length} datasets. ${datasetDescriptions}`;
|
|
6412
6608
|
}), [ datasets ]);
|
|
@@ -8656,14 +8852,14 @@ const ScatterChart = React.memo( React.forwardRef((({datasets: datasets = [], c
|
|
|
8656
8852
|
|
|
8657
8853
|
ScatterChart.displayName = "ScatterChart";
|
|
8658
8854
|
|
|
8659
|
-
const
|
|
8855
|
+
const DEFAULT_COLOR_CONFIG = {
|
|
8660
8856
|
scheme: "category"
|
|
8661
|
-
},
|
|
8857
|
+
}, DEFAULT_LABEL_CONFIG = {
|
|
8662
8858
|
showLabels: !0,
|
|
8663
8859
|
minSize: 1e3,
|
|
8664
8860
|
fontSize: 12,
|
|
8665
8861
|
textColor: "white"
|
|
8666
|
-
}, onDataPointClick: onDataPointClick, config: config =
|
|
8862
|
+
}, DEFAULT_CONFIG = {}, TreemapChart = React.memo( React.forwardRef((({data: data = [], algorithm: algorithm = "squarified", colorConfig: colorConfig = DEFAULT_COLOR_CONFIG, labelConfig: labelConfig = DEFAULT_LABEL_CONFIG, onDataPointClick: onDataPointClick, config: config = DEFAULT_CONFIG, ...props}, ref) => {
|
|
8667
8863
|
const [hoveredNode, setHoveredNode] = React.useState(null), [selectedNode, setSelectedNode] = React.useState(null);
|
|
8668
8864
|
React.useState({
|
|
8669
8865
|
x: 0,
|
|
@@ -8775,87 +8971,87 @@ const TreemapChart = React.memo( React.forwardRef((({data: data = [], algorithm
|
|
|
8775
8971
|
remainingHeight -= rowHeight), currentRow = [];
|
|
8776
8972
|
}
|
|
8777
8973
|
}
|
|
8778
|
-
}), []),
|
|
8974
|
+
}), []), renderContent = React.useCallback((({scales: scales, colors: colors, datasets: renderedDatasets, handlers: handlers, hoveredPoint: hoveredPoint}) => {
|
|
8975
|
+
if (!data.length) return null;
|
|
8976
|
+
// Calculate available space with padding
|
|
8977
|
+
const availableWidth = scales.width - 40, availableHeight = scales.height - 40, leafNodes = data.filter((item => !item.children || 0 === item.children.length));
|
|
8978
|
+
if (!leafNodes.length) return null;
|
|
8979
|
+
const totalValue = _reduceInstanceProperty(leafNodes).call(leafNodes, ((sum, node) => sum + node.value), 0), treemapNodes = leafNodes.map(((item, index) => ({
|
|
8980
|
+
id: item.id,
|
|
8981
|
+
label: item.label,
|
|
8982
|
+
value: item.value,
|
|
8983
|
+
color: generateColor(item, 0, index) || "transparent",
|
|
8984
|
+
x: 0,
|
|
8985
|
+
// Will be calculated by squarify
|
|
8986
|
+
y: 0,
|
|
8987
|
+
// Will be calculated by squarify
|
|
8988
|
+
width: 0,
|
|
8989
|
+
// Will be calculated by squarify
|
|
8990
|
+
height: 0,
|
|
8991
|
+
// Will be calculated by squarify
|
|
8992
|
+
depth: 0,
|
|
8993
|
+
children: [],
|
|
8994
|
+
originalData: item
|
|
8995
|
+
})));
|
|
8996
|
+
// Create treemap nodes with proper dimensions
|
|
8997
|
+
// Apply squarified algorithm to layout nodes proportionally by value
|
|
8998
|
+
if ("squarified" === algorithm && totalValue > 0) squarify(treemapNodes, 20, 20, availableWidth, availableHeight); else {
|
|
8999
|
+
// Fallback: simple grid layout (equal sizes)
|
|
9000
|
+
const cols = Math.ceil(Math.sqrt(leafNodes.length)), rows = Math.ceil(leafNodes.length / cols), nodeWidth = availableWidth / cols, nodeHeight = availableHeight / rows;
|
|
9001
|
+
treemapNodes.forEach(((node, index) => {
|
|
9002
|
+
const col = index % cols, row = Math.floor(index / cols);
|
|
9003
|
+
node.x = 20 + col * nodeWidth, node.y = 20 + row * nodeHeight, node.width = nodeWidth,
|
|
9004
|
+
node.height = nodeHeight;
|
|
9005
|
+
}));
|
|
9006
|
+
}
|
|
9007
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
9008
|
+
children: treemapNodes.map((node => {
|
|
9009
|
+
const isHovered = hoveredNode === node, isSelected = selectedNode === node, area = node.width * node.height, showLabel = labelConfig.showLabels && area >= (labelConfig.minSize || 1e3);
|
|
9010
|
+
return jsxRuntime.jsxs("g", {
|
|
9011
|
+
children: [ jsxRuntime.jsx("rect", {
|
|
9012
|
+
x: node.x,
|
|
9013
|
+
y: node.y,
|
|
9014
|
+
width: node.width,
|
|
9015
|
+
height: node.height,
|
|
9016
|
+
fill: node.color,
|
|
9017
|
+
className: `c-chart__treemap-node ${isHovered ? "c-chart__treemap-node--hovered" : ""} ${isSelected ? "c-chart__treemap-node--selected" : ""}`,
|
|
9018
|
+
onClick: () => {
|
|
9019
|
+
setSelectedNode(node), handlers.onDataPointClick?.(node.originalData, 0, 0);
|
|
9020
|
+
},
|
|
9021
|
+
onMouseEnter: e => {
|
|
9022
|
+
setHoveredNode(node);
|
|
9023
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
9024
|
+
handlers.onPointHover(0, 0, node.x, node.y, rect.left + rect.width / 2, rect.top + rect.height / 2);
|
|
9025
|
+
},
|
|
9026
|
+
onMouseLeave: () => {
|
|
9027
|
+
setHoveredNode(null), handlers.onPointLeave();
|
|
9028
|
+
}
|
|
9029
|
+
}), showLabel && jsxRuntime.jsx("text", {
|
|
9030
|
+
x: node.x + node.width / 2,
|
|
9031
|
+
y: node.y + node.height / 2,
|
|
9032
|
+
textAnchor: "middle",
|
|
9033
|
+
dominantBaseline: "middle",
|
|
9034
|
+
className: "c-chart__treemap-label",
|
|
9035
|
+
style: {
|
|
9036
|
+
fontSize: labelConfig.fontSize,
|
|
9037
|
+
fill: labelConfig.textColor
|
|
9038
|
+
},
|
|
9039
|
+
children: node.label
|
|
9040
|
+
}) ]
|
|
9041
|
+
}, node.id);
|
|
9042
|
+
}))
|
|
9043
|
+
});
|
|
9044
|
+
}), [ data, algorithm, generateColor, squarify, labelConfig, hoveredNode, selectedNode ]), datasets = React.useMemo((() => [ {
|
|
8779
9045
|
label: "Treemap Data",
|
|
8780
9046
|
data: data
|
|
8781
|
-
} ];
|
|
9047
|
+
} ]), [ data ]);
|
|
8782
9048
|
// Squarified treemap algorithm
|
|
8783
9049
|
return jsxRuntime.jsx(BaseChart, {
|
|
8784
9050
|
ref: ref,
|
|
8785
9051
|
type: "treemap",
|
|
8786
9052
|
datasets: datasets,
|
|
8787
9053
|
config: config,
|
|
8788
|
-
renderContent:
|
|
8789
|
-
if (!data.length) return null;
|
|
8790
|
-
// Calculate available space with padding
|
|
8791
|
-
const availableWidth = scales.width - 40, availableHeight = scales.height - 40, leafNodes = data.filter((item => !item.children || 0 === item.children.length));
|
|
8792
|
-
if (!leafNodes.length) return null;
|
|
8793
|
-
const totalValue = _reduceInstanceProperty(leafNodes).call(leafNodes, ((sum, node) => sum + node.value), 0), treemapNodes = leafNodes.map(((item, index) => ({
|
|
8794
|
-
id: item.id,
|
|
8795
|
-
label: item.label,
|
|
8796
|
-
value: item.value,
|
|
8797
|
-
color: generateColor(item, 0, index) || "transparent",
|
|
8798
|
-
x: 0,
|
|
8799
|
-
// Will be calculated by squarify
|
|
8800
|
-
y: 0,
|
|
8801
|
-
// Will be calculated by squarify
|
|
8802
|
-
width: 0,
|
|
8803
|
-
// Will be calculated by squarify
|
|
8804
|
-
height: 0,
|
|
8805
|
-
// Will be calculated by squarify
|
|
8806
|
-
depth: 0,
|
|
8807
|
-
children: [],
|
|
8808
|
-
originalData: item
|
|
8809
|
-
})));
|
|
8810
|
-
// Create treemap nodes with proper dimensions
|
|
8811
|
-
// Apply squarified algorithm to layout nodes proportionally by value
|
|
8812
|
-
if ("squarified" === algorithm && totalValue > 0) squarify(treemapNodes, 20, 20, availableWidth, availableHeight); else {
|
|
8813
|
-
// Fallback: simple grid layout (equal sizes)
|
|
8814
|
-
const cols = Math.ceil(Math.sqrt(leafNodes.length)), rows = Math.ceil(leafNodes.length / cols), nodeWidth = availableWidth / cols, nodeHeight = availableHeight / rows;
|
|
8815
|
-
treemapNodes.forEach(((node, index) => {
|
|
8816
|
-
const col = index % cols, row = Math.floor(index / cols);
|
|
8817
|
-
node.x = 20 + col * nodeWidth, node.y = 20 + row * nodeHeight, node.width = nodeWidth,
|
|
8818
|
-
node.height = nodeHeight;
|
|
8819
|
-
}));
|
|
8820
|
-
}
|
|
8821
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
8822
|
-
children: treemapNodes.map((node => {
|
|
8823
|
-
const isHovered = hoveredNode === node, isSelected = selectedNode === node, area = node.width * node.height, showLabel = labelConfig.showLabels && area >= (labelConfig.minSize || 1e3);
|
|
8824
|
-
return jsxRuntime.jsxs("g", {
|
|
8825
|
-
children: [ jsxRuntime.jsx("rect", {
|
|
8826
|
-
x: node.x,
|
|
8827
|
-
y: node.y,
|
|
8828
|
-
width: node.width,
|
|
8829
|
-
height: node.height,
|
|
8830
|
-
fill: node.color,
|
|
8831
|
-
className: `c-chart__treemap-node ${isHovered ? "c-chart__treemap-node--hovered" : ""} ${isSelected ? "c-chart__treemap-node--selected" : ""}`,
|
|
8832
|
-
onClick: () => {
|
|
8833
|
-
setSelectedNode(node), handlers.onDataPointClick?.(node.originalData, 0, 0);
|
|
8834
|
-
},
|
|
8835
|
-
onMouseEnter: e => {
|
|
8836
|
-
setHoveredNode(node);
|
|
8837
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
8838
|
-
handlers.onPointHover(0, 0, node.x, node.y, rect.left + rect.width / 2, rect.top + rect.height / 2);
|
|
8839
|
-
},
|
|
8840
|
-
onMouseLeave: () => {
|
|
8841
|
-
setHoveredNode(null), handlers.onPointLeave();
|
|
8842
|
-
}
|
|
8843
|
-
}), showLabel && jsxRuntime.jsx("text", {
|
|
8844
|
-
x: node.x + node.width / 2,
|
|
8845
|
-
y: node.y + node.height / 2,
|
|
8846
|
-
textAnchor: "middle",
|
|
8847
|
-
dominantBaseline: "middle",
|
|
8848
|
-
className: "c-chart__treemap-label",
|
|
8849
|
-
style: {
|
|
8850
|
-
fontSize: labelConfig.fontSize,
|
|
8851
|
-
fill: labelConfig.textColor
|
|
8852
|
-
},
|
|
8853
|
-
children: node.label
|
|
8854
|
-
}) ]
|
|
8855
|
-
}, node.id);
|
|
8856
|
-
}))
|
|
8857
|
-
});
|
|
8858
|
-
},
|
|
9054
|
+
renderContent: renderContent,
|
|
8859
9055
|
onDataPointClick: onDataPointClick,
|
|
8860
9056
|
interactive: !0,
|
|
8861
9057
|
...props
|
|
@@ -9543,7 +9739,7 @@ const range = (start, end) => {
|
|
|
9543
9739
|
blurAmount: 1,
|
|
9544
9740
|
saturation: 160,
|
|
9545
9741
|
aberrationIntensity: .5,
|
|
9546
|
-
|
|
9742
|
+
borderRadius: 8,
|
|
9547
9743
|
mode: "shader"
|
|
9548
9744
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
9549
9745
|
...defaultGlassProps,
|
|
@@ -9614,7 +9810,7 @@ const Checkbox = React__default.default.memo( React.forwardRef((({label: label,
|
|
|
9614
9810
|
blurAmount: 1,
|
|
9615
9811
|
saturation: 160,
|
|
9616
9812
|
aberrationIntensity: .3,
|
|
9617
|
-
|
|
9813
|
+
borderRadius: 6,
|
|
9618
9814
|
mode: "shader"
|
|
9619
9815
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
9620
9816
|
...defaultGlassProps,
|
|
@@ -11296,7 +11492,7 @@ const Input = React.memo( React.forwardRef((({type: type = "text", value: value
|
|
|
11296
11492
|
blurAmount: 1,
|
|
11297
11493
|
saturation: 180,
|
|
11298
11494
|
aberrationIntensity: .2,
|
|
11299
|
-
|
|
11495
|
+
borderRadius: 12,
|
|
11300
11496
|
mode: "shader"
|
|
11301
11497
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
11302
11498
|
...defaultGlassProps,
|
|
@@ -11336,7 +11532,7 @@ function useHero(initialProps) {
|
|
|
11336
11532
|
* @returns Slider state and methods
|
|
11337
11533
|
*/
|
|
11338
11534
|
function(config) {
|
|
11339
|
-
const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = React.useState(0), [isTransitioning, setIsTransitioning] = React.useState(!1), autoplayRef = React.useRef(null), isPausedRef = React.useRef(!1), slideRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides.length ]), videoRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides.length ]), handleSlideTransition = React.useCallback((nextIndex => {
|
|
11535
|
+
const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = React.useState(0), [isTransitioning, setIsTransitioning] = React.useState(!1), autoplayRef = React.useRef(null), isPausedRef = React.useRef(!1), callbackRef = React.useRef(), slideRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides.length ]), videoRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides.length ]), handleSlideTransition = React.useCallback((nextIndex => {
|
|
11340
11536
|
if (nextIndex === currentIndex || isTransitioning) return;
|
|
11341
11537
|
if (nextIndex < 0 || nextIndex >= slides.length) return;
|
|
11342
11538
|
setIsTransitioning(!0),
|
|
@@ -11357,7 +11553,17 @@ function useHero(initialProps) {
|
|
|
11357
11553
|
let nextIndex;
|
|
11358
11554
|
nextIndex = loop ? (currentIndex + 1) % slides.length : Math.min(currentIndex + 1, slides.length - 1),
|
|
11359
11555
|
handleSlideTransition(nextIndex);
|
|
11360
|
-
}), [ currentIndex, slides.length, loop, handleSlideTransition ])
|
|
11556
|
+
}), [ currentIndex, slides.length, loop, handleSlideTransition ]);
|
|
11557
|
+
// Update callbackRef whenever nextSlide or isTransitioning changes
|
|
11558
|
+
React.useEffect((() => {
|
|
11559
|
+
callbackRef.current = () => {
|
|
11560
|
+
isPausedRef.current || isTransitioning || nextSlide();
|
|
11561
|
+
};
|
|
11562
|
+
}), [ nextSlide, isTransitioning ]);
|
|
11563
|
+
/**
|
|
11564
|
+
* Pause autoplay
|
|
11565
|
+
*/
|
|
11566
|
+
const pauseAutoplay = React.useCallback((() => {
|
|
11361
11567
|
isPausedRef.current = !0, autoplayRef.current && (clearInterval(autoplayRef.current),
|
|
11362
11568
|
autoplayRef.current = null);
|
|
11363
11569
|
}), []), resumeAutoplay = React.useCallback((() => {
|
|
@@ -11366,24 +11572,26 @@ function useHero(initialProps) {
|
|
|
11366
11572
|
const delay = "object" == typeof autoplay ? autoplay.delay : 3e3;
|
|
11367
11573
|
// Restart autoplay
|
|
11368
11574
|
autoplayRef.current || (autoplayRef.current = setInterval((() => {
|
|
11369
|
-
|
|
11575
|
+
callbackRef.current && callbackRef.current();
|
|
11370
11576
|
}), delay));
|
|
11371
11577
|
}
|
|
11372
|
-
}), [ autoplay, slides.length
|
|
11578
|
+
}), [ autoplay, slides.length ]);
|
|
11579
|
+
/**
|
|
11580
|
+
* Resume autoplay
|
|
11581
|
+
*/
|
|
11373
11582
|
// Autoplay effect
|
|
11374
11583
|
return React.useEffect((() => {
|
|
11375
11584
|
if (!autoplay || slides.length <= 1) return;
|
|
11376
11585
|
const delay = "object" == typeof autoplay ? autoplay.delay : 3e3;
|
|
11377
|
-
return "object" == typeof autoplay && autoplay.pauseOnHover,
|
|
11378
11586
|
// Clear any existing interval
|
|
11379
|
-
|
|
11587
|
+
return autoplayRef.current && (clearInterval(autoplayRef.current), autoplayRef.current = null),
|
|
11380
11588
|
// Start autoplay if not paused
|
|
11381
11589
|
isPausedRef.current || (autoplayRef.current = setInterval((() => {
|
|
11382
|
-
|
|
11590
|
+
callbackRef.current && callbackRef.current();
|
|
11383
11591
|
}), delay)), () => {
|
|
11384
11592
|
autoplayRef.current && (clearInterval(autoplayRef.current), autoplayRef.current = null);
|
|
11385
11593
|
};
|
|
11386
|
-
}), [ autoplay, slides.length
|
|
11594
|
+
}), [ autoplay, slides.length ]),
|
|
11387
11595
|
// Initialize first video if needed
|
|
11388
11596
|
React.useEffect((() => {
|
|
11389
11597
|
if (slides.length > 0 && "video" === slides[currentIndex]?.type) {
|
|
@@ -12382,7 +12590,14 @@ const DEFAULT_ATOMIX_FONTS = [ {
|
|
|
12382
12590
|
}
|
|
12383
12591
|
|
|
12384
12592
|
function useSlider(options) {
|
|
12385
|
-
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 = React.useRef(null), wrapperRef = React.useRef(null), repositioningRef = React.useRef(!1), autoplayRef = React.useRef(null), [autoplayRunning, setAutoplayRunning] = React.useState(!1),
|
|
12593
|
+
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 = React.useRef(null), wrapperRef = React.useRef(null), repositioningRef = React.useRef(!1), autoplayRef = React.useRef(null), [autoplayRunning, setAutoplayRunning] = React.useState(!1), sliderStateRef = React.useRef({
|
|
12594
|
+
isTransitioning: !1,
|
|
12595
|
+
loop: loop,
|
|
12596
|
+
slides: slides,
|
|
12597
|
+
slidesToShow: slidesToShow,
|
|
12598
|
+
speed: speed,
|
|
12599
|
+
onSlideChange: onSlideChange
|
|
12600
|
+
}), [realIndex, setRealIndex] = React.useState(initialSlide), [internalIndex, setInternalIndex] = React.useState(0), [isTransitioning, setIsTransitioning] = React.useState(!1), [containerSize, setContainerSize] = React.useState(0), [touching, setTouching] = React.useState(!1), [touchStart, setTouchStart] = React.useState(0), [dragOffset, setDragOffset] = React.useState(0), slideWidth = React.useMemo((() => 0 === containerSize ? 0 : (containerSize - spaceBetween * (slidesToShow - 1)) / slidesToShow), [ containerSize, spaceBetween, slidesToShow ]), allSlides = React.useMemo((() => loop && 0 !== slides.length ? [ ...slides.map(((slide, i) => ({
|
|
12386
12601
|
...slide,
|
|
12387
12602
|
id: `set1-${slide.id || i}`
|
|
12388
12603
|
}))), ...slides.map(((slide, i) => ({
|
|
@@ -12392,6 +12607,17 @@ function useSlider(options) {
|
|
|
12392
12607
|
...slide,
|
|
12393
12608
|
id: `set3-${slide.id || i}`
|
|
12394
12609
|
}))) ] : slides), [ slides, loop ]), loopedSlides = slides.length, translateValue = React.useMemo((() => 0 === slideWidth ? 0 : -internalIndex * slideWidth + dragOffset), [ slideWidth, internalIndex, dragOffset ]);
|
|
12610
|
+
// Update the ref whenever the relevant state/props change
|
|
12611
|
+
React.useEffect((() => {
|
|
12612
|
+
sliderStateRef.current = {
|
|
12613
|
+
isTransitioning: isTransitioning,
|
|
12614
|
+
loop: loop,
|
|
12615
|
+
slides: slides,
|
|
12616
|
+
slidesToShow: slidesToShow,
|
|
12617
|
+
speed: speed,
|
|
12618
|
+
onSlideChange: onSlideChange
|
|
12619
|
+
};
|
|
12620
|
+
}), [ isTransitioning, loop, slides, slidesToShow, speed, onSlideChange ]),
|
|
12395
12621
|
// Autoplay effect
|
|
12396
12622
|
React.useEffect((() => {
|
|
12397
12623
|
if (!autoplay) return autoplayRef.current && (clearInterval(autoplayRef.current),
|
|
@@ -12403,32 +12629,34 @@ function useSlider(options) {
|
|
|
12403
12629
|
autoplayRef.current && clearInterval(autoplayRef.current),
|
|
12404
12630
|
// Create new interval
|
|
12405
12631
|
autoplayRef.current = setInterval((() => {
|
|
12632
|
+
// Use ref to get the latest state without resetting the interval
|
|
12633
|
+
const {isTransitioning: currentIsTransitioning, loop: currentLoop, slides: currentSlides, slidesToShow: currentSlidesToShow, speed: currentSpeed, onSlideChange: currentOnSlideChange} = sliderStateRef.current;
|
|
12406
12634
|
// We need to use a functional update to get the latest values
|
|
12407
|
-
|
|
12408
|
-
if (
|
|
12635
|
+
setRealIndex((prevRealIndex => {
|
|
12636
|
+
if (currentIsTransitioning) return prevRealIndex;
|
|
12409
12637
|
// Stop autoplay on interaction if disableOnInteraction is true
|
|
12410
12638
|
let nextIndex;
|
|
12411
12639
|
// Trigger the slide change
|
|
12412
12640
|
if (disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
|
|
12413
|
-
autoplayRef.current = null, setAutoplayRunning(!1)), nextIndex =
|
|
12641
|
+
autoplayRef.current = null, setAutoplayRunning(!1)), nextIndex = currentLoop ? (prevRealIndex + 1) % currentSlides.length : Math.min(prevRealIndex + 1, currentSlides.length - currentSlidesToShow),
|
|
12414
12642
|
reverseDirection) {
|
|
12415
12643
|
// For reverse direction, we would go to previous slide
|
|
12416
|
-
const prevIndex =
|
|
12417
|
-
return setInternalIndex(
|
|
12418
|
-
setDragOffset(0), setTimeout((() => {
|
|
12419
|
-
setIsTransitioning(!1),
|
|
12420
|
-
}),
|
|
12644
|
+
const prevIndex = currentLoop ? 0 === prevRealIndex ? currentSlides.length - 1 : prevRealIndex - 1 : Math.max(prevRealIndex - 1, 0);
|
|
12645
|
+
return setInternalIndex(currentLoop ? currentSlides.length + prevIndex : prevIndex),
|
|
12646
|
+
setIsTransitioning(!0), setDragOffset(0), setTimeout((() => {
|
|
12647
|
+
setIsTransitioning(!1), currentOnSlideChange?.(prevIndex);
|
|
12648
|
+
}), currentSpeed), prevIndex;
|
|
12421
12649
|
}
|
|
12422
12650
|
// Normal direction
|
|
12423
|
-
return setInternalIndex(
|
|
12424
|
-
setDragOffset(0), setTimeout((() => {
|
|
12425
|
-
setIsTransitioning(!1),
|
|
12651
|
+
return setInternalIndex(currentLoop ? currentSlides.length + nextIndex : nextIndex),
|
|
12652
|
+
setIsTransitioning(!0), setDragOffset(0), setTimeout((() => {
|
|
12653
|
+
setIsTransitioning(!1), currentOnSlideChange?.(nextIndex),
|
|
12426
12654
|
// Reposition after transition ends for looped sliders
|
|
12427
|
-
|
|
12428
|
-
setTimeout((() => {
|
|
12655
|
+
currentLoop && nextIndex >= 2 * currentSlides.length && (repositioningRef.current = !0,
|
|
12656
|
+
setInternalIndex(currentSlides.length + nextIndex), setTimeout((() => {
|
|
12429
12657
|
repositioningRef.current = !1;
|
|
12430
12658
|
}), 0));
|
|
12431
|
-
}),
|
|
12659
|
+
}), currentSpeed), nextIndex;
|
|
12432
12660
|
}));
|
|
12433
12661
|
}), delay), setAutoplayRunning(!0);
|
|
12434
12662
|
// Handle pause on mouse enter/leave if enabled
|
|
@@ -12439,17 +12667,18 @@ function useSlider(options) {
|
|
|
12439
12667
|
}, handleMouseLeave = () => {
|
|
12440
12668
|
// Restart autoplay
|
|
12441
12669
|
autoplayRef.current && clearInterval(autoplayRef.current), autoplayRef.current = setInterval((() => {
|
|
12670
|
+
const {isTransitioning: currentIsTransitioning, loop: currentLoop, slides: currentSlides, slidesToShow: currentSlidesToShow, speed: currentSpeed, onSlideChange: currentOnSlideChange} = sliderStateRef.current;
|
|
12442
12671
|
setRealIndex((prevRealIndex => {
|
|
12443
|
-
if (
|
|
12672
|
+
if (currentIsTransitioning) return prevRealIndex;
|
|
12444
12673
|
let nextIndex;
|
|
12445
|
-
return nextIndex =
|
|
12446
|
-
setInternalIndex(
|
|
12674
|
+
return nextIndex = currentLoop ? (prevRealIndex + 1) % currentSlides.length : Math.min(prevRealIndex + 1, currentSlides.length - currentSlidesToShow),
|
|
12675
|
+
setInternalIndex(currentLoop ? currentSlides.length + nextIndex : nextIndex), setIsTransitioning(!0),
|
|
12447
12676
|
setDragOffset(0), setTimeout((() => {
|
|
12448
|
-
setIsTransitioning(!1),
|
|
12449
|
-
setInternalIndex(
|
|
12677
|
+
setIsTransitioning(!1), currentOnSlideChange?.(nextIndex), currentLoop && nextIndex >= 2 * currentSlides.length && (repositioningRef.current = !0,
|
|
12678
|
+
setInternalIndex(currentSlides.length + nextIndex), setTimeout((() => {
|
|
12450
12679
|
repositioningRef.current = !1;
|
|
12451
12680
|
}), 0));
|
|
12452
|
-
}),
|
|
12681
|
+
}), currentSpeed), nextIndex;
|
|
12453
12682
|
}));
|
|
12454
12683
|
}), delay), setAutoplayRunning(!0);
|
|
12455
12684
|
};
|
|
@@ -12461,7 +12690,7 @@ function useSlider(options) {
|
|
|
12461
12690
|
containerElement && (containerElement.removeEventListener("mouseenter", handleMouseEnter),
|
|
12462
12691
|
containerElement.removeEventListener("mouseleave", handleMouseLeave)), setAutoplayRunning(!1);
|
|
12463
12692
|
};
|
|
12464
|
-
}), [ autoplay,
|
|
12693
|
+
}), [ autoplay, repositioningRef ]),
|
|
12465
12694
|
// Initialize
|
|
12466
12695
|
React.useEffect((() => {
|
|
12467
12696
|
setInternalIndex(loop ? slides.length + initialSlide : initialSlide);
|
|
@@ -12921,7 +13150,7 @@ const Select = React.memo((({options: options, value: value, onChange: onChange
|
|
|
12921
13150
|
blurAmount: 1,
|
|
12922
13151
|
saturation: 180,
|
|
12923
13152
|
aberrationIntensity: .2,
|
|
12924
|
-
|
|
13153
|
+
borderRadius: 12,
|
|
12925
13154
|
mode: "shader"
|
|
12926
13155
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
12927
13156
|
...defaultGlassProps,
|
|
@@ -12979,7 +13208,7 @@ const Radio = React.memo((({label: label, checked: checked = !1, onChange: onCh
|
|
|
12979
13208
|
blurAmount: 1,
|
|
12980
13209
|
saturation: 160,
|
|
12981
13210
|
aberrationIntensity: .3,
|
|
12982
|
-
|
|
13211
|
+
borderRadius: 6,
|
|
12983
13212
|
mode: "shader"
|
|
12984
13213
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
12985
13214
|
...defaultGlassProps,
|
|
@@ -13045,7 +13274,7 @@ const Textarea = React.memo( React.forwardRef((({value: value, defaultValue: de
|
|
|
13045
13274
|
blurAmount: 1,
|
|
13046
13275
|
saturation: 180,
|
|
13047
13276
|
aberrationIntensity: 1,
|
|
13048
|
-
|
|
13277
|
+
borderRadius: 8,
|
|
13049
13278
|
mode: "shader"
|
|
13050
13279
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
13051
13280
|
...defaultGlassProps,
|
|
@@ -13886,7 +14115,7 @@ const Hero = ({title: title, subtitle: subtitle, text: text, imageSrc: imageSrc,
|
|
|
13886
14115
|
blurAmount: 3,
|
|
13887
14116
|
saturation: 180,
|
|
13888
14117
|
aberrationIntensity: 0,
|
|
13889
|
-
|
|
14118
|
+
borderRadius: 8,
|
|
13890
14119
|
overLight: !1,
|
|
13891
14120
|
mode: "standard",
|
|
13892
14121
|
children: jsxRuntime.jsxs("div", {
|
|
@@ -14094,7 +14323,7 @@ Hero.Title = ({children: children, className: className, level: level = "h1", ..
|
|
|
14094
14323
|
blurAmount: 3,
|
|
14095
14324
|
saturation: 180,
|
|
14096
14325
|
aberrationIntensity: 0,
|
|
14097
|
-
|
|
14326
|
+
borderRadius: 8,
|
|
14098
14327
|
overLight: !1,
|
|
14099
14328
|
mode: "standard"
|
|
14100
14329
|
} : glass;
|
|
@@ -14208,7 +14437,7 @@ const Messages = ({messages: messages = [], otherAvatar: otherAvatar, selfAvatar
|
|
|
14208
14437
|
onSendMessage: onSendMessage
|
|
14209
14438
|
}), messagesId = id || `messages-${Math.random().toString(36).substr(2, 9)}`, inputId = `${messagesId}-input`, defaultGlassProps = {
|
|
14210
14439
|
displacementScale: 150,
|
|
14211
|
-
|
|
14440
|
+
borderRadius: 12,
|
|
14212
14441
|
elasticity: 0,
|
|
14213
14442
|
aberrationIntensity: 2
|
|
14214
14443
|
}, messagesClasses = `${MESSAGES.CLASSES.BASE} ${glass ? "c-messages--glass" : ""} ${disabled ? "is-disabled" : ""} ${className}`, messagesContent = jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
@@ -14354,7 +14583,7 @@ const Messages = ({messages: messages = [], otherAvatar: otherAvatar, selfAvatar
|
|
|
14354
14583
|
children: jsxRuntime.jsx("div", {
|
|
14355
14584
|
className: "c-messages__glass-content",
|
|
14356
14585
|
style: {
|
|
14357
|
-
borderRadius: glassProps.
|
|
14586
|
+
borderRadius: glassProps.borderRadius
|
|
14358
14587
|
},
|
|
14359
14588
|
children: messagesContent
|
|
14360
14589
|
})
|
|
@@ -14582,7 +14811,7 @@ const Modal = ModalWithSubcomponents, Nav = React.forwardRef((({children: child
|
|
|
14582
14811
|
const defaultGlassProps = {
|
|
14583
14812
|
displacementScale: 60,
|
|
14584
14813
|
blurAmount: 1.5,
|
|
14585
|
-
|
|
14814
|
+
borderRadius: 8,
|
|
14586
14815
|
mode: "shader"
|
|
14587
14816
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
14588
14817
|
...defaultGlassProps,
|
|
@@ -14794,7 +15023,7 @@ const Navbar = React.forwardRef((({brand: brand, children: children, variant: v
|
|
|
14794
15023
|
const defaultGlassProps = {
|
|
14795
15024
|
displacementScale: 30,
|
|
14796
15025
|
blurAmount: 2,
|
|
14797
|
-
|
|
15026
|
+
borderRadius: 0,
|
|
14798
15027
|
elasticity: 0,
|
|
14799
15028
|
mode: "shader",
|
|
14800
15029
|
shaderVariant: "premiumGlass"
|
|
@@ -15175,7 +15404,7 @@ const SideMenu = React.forwardRef((({title: title, children: children, menuItem
|
|
|
15175
15404
|
const defaultGlassProps = {
|
|
15176
15405
|
displacementScale: 70,
|
|
15177
15406
|
blurAmount: 2,
|
|
15178
|
-
|
|
15407
|
+
borderRadius: 12,
|
|
15179
15408
|
mode: "shader"
|
|
15180
15409
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
15181
15410
|
...defaultGlassProps,
|
|
@@ -16754,7 +16983,7 @@ const PopoverContext = React.createContext({
|
|
|
16754
16983
|
blurAmount: 1,
|
|
16755
16984
|
saturation: 160,
|
|
16756
16985
|
aberrationIntensity: .5,
|
|
16757
|
-
|
|
16986
|
+
borderRadius: 8,
|
|
16758
16987
|
mode: "shader"
|
|
16759
16988
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
16760
16989
|
...defaultGlassProps,
|
|
@@ -16805,7 +17034,14 @@ const PopoverContext = React.createContext({
|
|
|
16805
17034
|
/**
|
|
16806
17035
|
* Hook for managing rating component state and interactions
|
|
16807
17036
|
*/
|
|
16808
|
-
const
|
|
17037
|
+
const calculateStarValue = (e, starValue, allowHalf) => {
|
|
17038
|
+
if (!allowHalf) return starValue;
|
|
17039
|
+
// Get the star element's bounding rectangle
|
|
17040
|
+
const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2, adjustedValue = e.clientX < starCenterX ? starValue - .5 : starValue;
|
|
17041
|
+
// Calculate the x position within the star
|
|
17042
|
+
return Math.max(.5, adjustedValue);
|
|
17043
|
+
// Ensure minimum of 0.5
|
|
17044
|
+
}, Rating = React.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) => {
|
|
16809
17045
|
const internalRef = React.useRef(null), ratingInstance = React.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}) => {
|
|
16810
17046
|
// Determine if component is in controlled mode
|
|
16811
17047
|
const isControlled = void 0 !== onChange, [internalValue, setInternalValue] = React.useState(value), [hoverValue, setHoverValue] = React.useState(null), [focusedIndex, setFocusedIndex] = React.useState(null), currentValue = isControlled ? value : internalValue, handleMouseEnter = React.useCallback((starValue => {
|
|
@@ -16867,30 +17103,14 @@ const Rating = React.forwardRef((({value: valueProp = 0, defaultValue: defaultV
|
|
|
16867
17103
|
readOnly: readOnly,
|
|
16868
17104
|
onChange: onChange
|
|
16869
17105
|
}), forkedRef = useForkRef(internalRef, ref), handleMouseEnter = React.useCallback(((e, starValue) => {
|
|
16870
|
-
|
|
16871
|
-
// Get the star element's bounding rectangle
|
|
16872
|
-
const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2, adjustedValue = e.clientX < starCenterX ? starValue - .5 : starValue;
|
|
16873
|
-
// Calculate the x position within the star
|
|
16874
|
-
setHoverValue(Math.max(.5, adjustedValue));
|
|
16875
|
-
} else setHoverValue(starValue);
|
|
17106
|
+
readOnly || setHoverValue(calculateStarValue(e, starValue, !!allowHalf));
|
|
16876
17107
|
}), [ readOnly, allowHalf, setHoverValue ]), handleMouseMove = React.useCallback(((e, starValue) => {
|
|
16877
|
-
|
|
16878
|
-
|
|
16879
|
-
const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2, adjustedValue = e.clientX < starCenterX ? starValue - .5 : starValue;
|
|
16880
|
-
// Calculate the x position within the star
|
|
16881
|
-
setHoverValue(Math.max(.5, adjustedValue));
|
|
16882
|
-
} // Ensure minimum of 0.5
|
|
16883
|
-
), [ readOnly, allowHalf, setHoverValue ]), handleMouseLeave = React.useCallback((() => {
|
|
17108
|
+
!readOnly && allowHalf && setHoverValue(calculateStarValue(e, starValue, !!allowHalf));
|
|
17109
|
+
}), [ readOnly, allowHalf, setHoverValue ]), handleMouseLeave = React.useCallback((() => {
|
|
16884
17110
|
readOnly || setHoverValue(null);
|
|
16885
17111
|
}), [ readOnly, setHoverValue ]), handleClick = React.useCallback(((e, starValue) => {
|
|
16886
17112
|
if (readOnly) return;
|
|
16887
|
-
|
|
16888
|
-
if (allowHalf) {
|
|
16889
|
-
// Get the star element's bounding rectangle
|
|
16890
|
-
const starRect = e.currentTarget.getBoundingClientRect(), starCenterX = starRect.left + starRect.width / 2;
|
|
16891
|
-
// Calculate the x position within the star
|
|
16892
|
-
newValue = e.clientX < starCenterX ? starValue - .5 : starValue, newValue = Math.max(.5, newValue);
|
|
16893
|
-
}
|
|
17113
|
+
const newValue = calculateStarValue(e, starValue, !!allowHalf);
|
|
16894
17114
|
onChange?.(newValue);
|
|
16895
17115
|
}), [ readOnly, onChange, allowHalf ]);
|
|
16896
17116
|
// Use vanilla JS implementation if specified
|
|
@@ -16995,7 +17215,7 @@ const Rating = React.forwardRef((({value: valueProp = 0, defaultValue: defaultV
|
|
|
16995
17215
|
blurAmount: 1,
|
|
16996
17216
|
saturation: 160,
|
|
16997
17217
|
aberrationIntensity: .5,
|
|
16998
|
-
|
|
17218
|
+
borderRadius: 8,
|
|
16999
17219
|
mode: "shader"
|
|
17000
17220
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
17001
17221
|
...defaultGlassProps,
|
|
@@ -17009,21 +17229,8 @@ const Rating = React.forwardRef((({value: valueProp = 0, defaultValue: defaultV
|
|
|
17009
17229
|
return ratingContent;
|
|
17010
17230
|
}));
|
|
17011
17231
|
|
|
17012
|
-
|
|
17013
|
-
|
|
17014
|
-
*
|
|
17015
|
-
* @example
|
|
17016
|
-
* // Basic usage
|
|
17017
|
-
* <Rating value={3} onChange={handleRatingChange} />
|
|
17018
|
-
*
|
|
17019
|
-
* @example
|
|
17020
|
-
* // Read-only with custom variant
|
|
17021
|
-
* <Rating value={4.5} readOnly variant="warning" />
|
|
17022
|
-
*
|
|
17023
|
-
* @example
|
|
17024
|
-
* // With half-star support
|
|
17025
|
-
* <Rating value={3.5} allowHalf maxValue={5} />
|
|
17026
|
-
*/ Rating.displayName = "Rating";
|
|
17232
|
+
// Helper function to calculate star value based on mouse position
|
|
17233
|
+
Rating.displayName = "Rating";
|
|
17027
17234
|
|
|
17028
17235
|
/**
|
|
17029
17236
|
* ProductReview component for collecting user ratings and feedback
|
|
@@ -17168,7 +17375,7 @@ const Progress = React.memo( React.forwardRef((({value: value, variant: variant
|
|
|
17168
17375
|
const defaultGlassProps = {
|
|
17169
17376
|
displacementScale: 30,
|
|
17170
17377
|
blurAmount: .5,
|
|
17171
|
-
|
|
17378
|
+
borderRadius: 8,
|
|
17172
17379
|
mode: "shader"
|
|
17173
17380
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
17174
17381
|
...defaultGlassProps,
|
|
@@ -17572,7 +17779,7 @@ const Steps = ({items: items, activeIndex: activeIndex = 0, vertical: vertical =
|
|
|
17572
17779
|
blurAmount: 1,
|
|
17573
17780
|
saturation: 160,
|
|
17574
17781
|
aberrationIntensity: .5,
|
|
17575
|
-
|
|
17782
|
+
borderRadius: 8,
|
|
17576
17783
|
mode: "shader"
|
|
17577
17784
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
17578
17785
|
...defaultGlassProps,
|
|
@@ -17730,7 +17937,7 @@ const Tabs = React.memo((({items: items, activeIndex: activeIndex = TAB.DEFAULT
|
|
|
17730
17937
|
blurAmount: 1,
|
|
17731
17938
|
saturation: 160,
|
|
17732
17939
|
aberrationIntensity: .5,
|
|
17733
|
-
|
|
17940
|
+
borderRadius: 8,
|
|
17734
17941
|
mode: "shader"
|
|
17735
17942
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
17736
17943
|
...defaultGlassProps,
|
|
@@ -17973,7 +18180,7 @@ const Toggle = ({checked: controlledChecked, defaultChecked: defaultChecked = !1
|
|
|
17973
18180
|
blurAmount: 1,
|
|
17974
18181
|
saturation: 160,
|
|
17975
18182
|
aberrationIntensity: .5,
|
|
17976
|
-
|
|
18183
|
+
borderRadius: 8,
|
|
17977
18184
|
mode: "shader"
|
|
17978
18185
|
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
17979
18186
|
...defaultGlassProps,
|