@shohojdhara/atomix 0.5.0 → 0.5.1
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 +95 -69
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.d.ts +1 -0
- package/dist/charts.js +231 -332
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +1 -0
- package/dist/core.js +232 -333
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +1 -0
- package/dist/forms.js +231 -332
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +11 -2
- package/dist/heavy.js +233 -334
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.esm.js +228 -327
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +227 -326
- 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 +11 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +188 -128
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +62 -90
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +153 -201
- package/src/components/AtomixGlass/glass-utils.ts +50 -0
- package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +52 -46
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +573 -236
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +88 -41
- package/src/components/AtomixGlass/stories/argTypes.ts +19 -19
- package/src/components/AtomixGlass/stories/shared-components.tsx +7 -12
- package/src/components/AtomixGlass/stories/types.ts +3 -3
- package/src/lib/composables/useAtomixGlass.ts +108 -71
- package/src/lib/composables/useAtomixGlassStyles.ts +0 -2
- package/src/lib/constants/components.ts +1 -0
- package/src/lib/types/components.ts +1 -0
- package/src/lib/utils/displacement-generator.ts +1 -1
- package/src/styles/06-components/_components.atomix-glass.scss +158 -97
- package/scripts/cli/__tests__/README.md +0 -81
- package/scripts/cli/__tests__/basic.test.js +0 -116
- package/scripts/cli/__tests__/clean.test.js +0 -278
- package/scripts/cli/__tests__/component-generator.test.js +0 -332
- package/scripts/cli/__tests__/component-validator.test.js +0 -433
- package/scripts/cli/__tests__/generator.test.js +0 -613
- package/scripts/cli/__tests__/glass-motion.test.js +0 -256
- package/scripts/cli/__tests__/integration.test.js +0 -938
- package/scripts/cli/__tests__/migrate.test.js +0 -74
- package/scripts/cli/__tests__/security.test.js +0 -206
- package/scripts/cli/__tests__/test-setup.js +0 -135
- package/scripts/cli/__tests__/theme-bridge.test.js +0 -507
- package/scripts/cli/__tests__/token-manager.test.js +0 -251
- package/scripts/cli/__tests__/token-provider.test.js +0 -361
- package/scripts/cli/__tests__/utils.test.js +0 -165
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +0 -216
- package/src/components/AtomixGlass/stories/AnimationTests.stories.tsx +0 -95
- package/src/components/AtomixGlass/stories/CardExamples.stories.tsx +0 -212
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +0 -131
- package/src/components/AtomixGlass/stories/DashboardExamples.stories.tsx +0 -348
- package/src/components/AtomixGlass/stories/EcommerceExamples.stories.tsx +0 -410
- package/src/components/AtomixGlass/stories/FormExamples.stories.tsx +0 -436
- package/src/components/AtomixGlass/stories/HeroExamples.stories.tsx +0 -264
- package/src/components/AtomixGlass/stories/InteractivePlayground.stories.tsx +0 -247
- package/src/components/AtomixGlass/stories/MobileUIExamples.stories.tsx +0 -418
- package/src/components/AtomixGlass/stories/ModalExamples.stories.tsx +0 -402
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +0 -1082
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +0 -497
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +0 -103
- package/src/components/AtomixGlass/stories/PresetGallery.stories.tsx +0 -335
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +0 -395
- package/src/components/AtomixGlass/stories/WidgetExamples.stories.tsx +0 -441
- package/src/components/TypedButton/TypedButton.stories.tsx +0 -59
- package/src/components/TypedButton/TypedButton.tsx +0 -39
- package/src/components/TypedButton/index.ts +0 -2
- package/src/lib/composables/useTypedButton.ts +0 -66
package/dist/core.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
|
|
3
|
-
import React, { useState, useRef, useEffect, memo, forwardRef, useMemo, useCallback,
|
|
3
|
+
import React, { useState, useRef, useEffect, memo, forwardRef, useId, useMemo, useCallback, Children, isValidElement, cloneElement } from "react";
|
|
4
4
|
|
|
5
5
|
import * as PhosphorIcons from "@phosphor-icons/react";
|
|
6
6
|
|
|
@@ -524,6 +524,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
524
524
|
FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
|
|
525
525
|
FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
|
|
526
526
|
CONTENT_CLASS: "c-atomix-glass__content",
|
|
527
|
+
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
527
528
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
528
529
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
529
530
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
@@ -869,7 +870,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
869
870
|
default:
|
|
870
871
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
871
872
|
}
|
|
872
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
873
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
873
874
|
style: {
|
|
874
875
|
position: "absolute",
|
|
875
876
|
width: "100%",
|
|
@@ -1013,24 +1014,17 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
1013
1014
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
1014
1015
|
|
|
1015
1016
|
// Memoize component to prevent unnecessary re-renders
|
|
1016
|
-
const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount))
|
|
1017
|
-
|
|
1018
|
-
// Module-level counter for deterministic ID generation
|
|
1019
|
-
let idCounter = 0;
|
|
1020
|
-
|
|
1021
|
-
// Module-level shared shader cache with LRU eviction
|
|
1022
|
-
const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
1017
|
+
const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
1023
1018
|
x: 0,
|
|
1024
1019
|
y: 0
|
|
1025
1020
|
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
|
|
1026
1021
|
width: 0,
|
|
1027
1022
|
height: 0
|
|
1028
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
1023
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
1029
1024
|
// Phase 1: Animation System props
|
|
1030
1025
|
shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
|
|
1031
|
-
//
|
|
1032
|
-
|
|
1033
|
-
const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
1026
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
1027
|
+
const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
1034
1028
|
// Lazy load shader utilities only when shader mode is needed
|
|
1035
1029
|
useEffect((() => {
|
|
1036
1030
|
"shader" === mode ?
|
|
@@ -1053,9 +1047,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1053
1047
|
// Create cache key from size and variant
|
|
1054
1048
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
1055
1049
|
const entry = sharedShaderCache.get(key);
|
|
1056
|
-
return entry ? (
|
|
1057
|
-
// Update access timestamp for LRU
|
|
1058
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
1050
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
1059
1051
|
})(cacheKey);
|
|
1060
1052
|
// Check shared cache first
|
|
1061
1053
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -1066,29 +1058,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1066
1058
|
if (shaderUtilsRef.current) try {
|
|
1067
1059
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
1068
1060
|
shaderGeneratorRef.current?.destroy();
|
|
1069
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
1061
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
1070
1062
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
1071
1063
|
width: glassSize.width,
|
|
1072
1064
|
height: glassSize.height,
|
|
1073
1065
|
fragment: selectedShader
|
|
1074
1066
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
1075
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
1067
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
1076
1068
|
url && ((key, url) => {
|
|
1077
|
-
// Evict oldest entries if at capacity
|
|
1078
1069
|
if (sharedShaderCache.size >= 15) {
|
|
1079
1070
|
const entries = Array.from(sharedShaderCache.entries());
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
const oldestEntry = entries[0];
|
|
1084
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
1071
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
1072
|
+
const oldest = entries[0];
|
|
1073
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
1085
1074
|
}
|
|
1086
1075
|
sharedShaderCache.set(key, {
|
|
1087
1076
|
url: url,
|
|
1088
1077
|
timestamp: Date.now()
|
|
1089
|
-
}),
|
|
1090
|
-
// Development mode: log cache size
|
|
1091
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
1078
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
1092
1079
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
1093
1080
|
}), 100);
|
|
1094
1081
|
} catch (error) {
|
|
@@ -1157,7 +1144,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1157
1144
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
1158
1145
|
}
|
|
1159
1146
|
}), [ ref, glassSize ]);
|
|
1160
|
-
// Pre-calculate static multipliers outside useMemo
|
|
1161
1147
|
const liquidBlur = useMemo((() => {
|
|
1162
1148
|
const defaultBlur = {
|
|
1163
1149
|
baseBlur: blurAmount,
|
|
@@ -1226,7 +1212,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1226
1212
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
1227
1213
|
return jsx("div", {
|
|
1228
1214
|
ref: el => {
|
|
1229
|
-
// Apply force no-transition
|
|
1230
1215
|
// Handle forwarded ref
|
|
1231
1216
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
1232
1217
|
},
|
|
@@ -1268,6 +1253,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1268
1253
|
});
|
|
1269
1254
|
}));
|
|
1270
1255
|
|
|
1256
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
1271
1257
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
1272
1258
|
|
|
1273
1259
|
// Singleton instance
|
|
@@ -1468,8 +1454,6 @@ class {
|
|
|
1468
1454
|
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})`;
|
|
1469
1455
|
// Container variables
|
|
1470
1456
|
const style = containerElement.style;
|
|
1471
|
-
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
1472
|
-
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
1473
1457
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
1474
1458
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
1475
1459
|
// Shadows
|
|
@@ -1930,47 +1914,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1930
1914
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
1931
1915
|
}
|
|
1932
1916
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
1933
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null),
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
if (!container) return;
|
|
1938
|
-
// Use cached rect if available, otherwise get new one
|
|
1939
|
-
let rect = cachedRectRef.current;
|
|
1940
|
-
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
1941
|
-
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
1942
|
-
const center = calculateElementCenter(rect);
|
|
1943
|
-
// Write raw target — the lerp loop will smoothly pursue it
|
|
1944
|
-
targetMouseOffsetRef.current = {
|
|
1945
|
-
x: (globalPos.x - center.x) / rect.width * 100,
|
|
1946
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
1947
|
-
}, targetGlobalMousePositionRef.current = globalPos;
|
|
1948
|
-
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
|
|
1917
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), stopLerpLoop = useCallback((() => {
|
|
1918
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
1919
|
+
lerpRafRef.current = null);
|
|
1920
|
+
}), []), startLerpLoop = useCallback((() => {
|
|
1949
1921
|
if (lerpActiveRef.current) return;
|
|
1950
1922
|
lerpActiveRef.current = !0;
|
|
1951
1923
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
1952
1924
|
if (!lerpActiveRef.current) return;
|
|
1953
|
-
|
|
1954
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
1925
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
1955
1926
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
1956
1927
|
// If we're close enough, snap and park
|
|
1957
|
-
if (Math.abs(dx) < .
|
|
1928
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
1958
1929
|
...tgt
|
|
1959
1930
|
}, internalGlobalMousePositionRef.current = {
|
|
1960
1931
|
...targetGlobalMousePositionRef.current
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1932
|
+
},
|
|
1933
|
+
// Final update and stop
|
|
1934
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1935
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
1936
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1937
|
+
glassSize: glassSize,
|
|
1938
|
+
isHovered: isHovered,
|
|
1939
|
+
isActive: isActive,
|
|
1940
|
+
isOverLight: overLightConfig.isOverLight,
|
|
1941
|
+
baseOverLightConfig: overLightConfig,
|
|
1942
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
1943
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1944
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
1945
|
+
elasticity: elasticity,
|
|
1946
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1947
|
+
onClick: onClick,
|
|
1948
|
+
withLiquidBlur: withLiquidBlur,
|
|
1949
|
+
blurAmount: blurAmount,
|
|
1950
|
+
saturation: saturation,
|
|
1951
|
+
padding: padding,
|
|
1952
|
+
isFixedOrSticky: isFixedOrSticky
|
|
1953
|
+
}), void stopLerpLoop();
|
|
1954
|
+
// Smooth step
|
|
1955
|
+
internalMouseOffsetRef.current = {
|
|
1956
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
1957
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
1958
|
+
};
|
|
1959
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1960
|
+
internalGlobalMousePositionRef.current = {
|
|
1961
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
1962
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
1963
|
+
},
|
|
1964
|
+
// Imperative style update
|
|
1965
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1974
1966
|
mouseOffset: internalMouseOffsetRef.current,
|
|
1975
1967
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1976
1968
|
glassSize: glassSize,
|
|
@@ -1993,10 +1985,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1993
1985
|
};
|
|
1994
1986
|
// 0.08 – lower = more viscous
|
|
1995
1987
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1996
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
1988
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1989
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1990
|
+
if (effectiveWithoutEffects) return;
|
|
1991
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
1992
|
+
if (!container) return;
|
|
1993
|
+
// Use cached rect if available, otherwise get new one
|
|
1994
|
+
let rect = cachedRectRef.current;
|
|
1995
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
1996
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
1997
|
+
const center = calculateElementCenter(rect);
|
|
1998
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
1999
|
+
targetMouseOffsetRef.current = {
|
|
2000
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
2001
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
2002
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
2003
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
2004
|
+
lerpActiveRef.current || startLerpLoop();
|
|
2005
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
2000
2006
|
/**
|
|
2001
2007
|
* Validate and clamp a numeric config value
|
|
2002
2008
|
*/
|
|
@@ -2005,7 +2011,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2005
2011
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2006
2012
|
if (effectiveWithoutEffects) return;
|
|
2007
2013
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
2008
|
-
//
|
|
2014
|
+
// Initial start
|
|
2009
2015
|
startLerpLoop();
|
|
2010
2016
|
const container = mouseContainer?.current || glassRef.current;
|
|
2011
2017
|
let resizeObserver = null;
|
|
@@ -2018,7 +2024,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2018
2024
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
2019
2025
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
2020
2026
|
};
|
|
2021
|
-
}), [
|
|
2027
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
2022
2028
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
2023
2029
|
useEffect((() => {
|
|
2024
2030
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -2120,184 +2126,147 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2120
2126
|
*
|
|
2121
2127
|
* @returns Performance tier classification
|
|
2122
2128
|
*/
|
|
2129
|
+
/** Map an FPS value to a semantic color token string. */
|
|
2130
|
+
const getQualityColor = quality => {
|
|
2131
|
+
switch (quality) {
|
|
2132
|
+
case "high":
|
|
2133
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
2134
|
+
|
|
2135
|
+
case "medium":
|
|
2136
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
2137
|
+
|
|
2138
|
+
case "low":
|
|
2139
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
2140
|
+
|
|
2141
|
+
default:
|
|
2142
|
+
return "#9ca3af";
|
|
2143
|
+
}
|
|
2144
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
2145
|
+
|
|
2146
|
+
/** Map a quality level string to a semantic color token string. */
|
|
2147
|
+
// Inject keyframes once
|
|
2148
|
+
if ("undefined" != typeof document) {
|
|
2149
|
+
const styleId = "perf-dashboard-keyframes";
|
|
2150
|
+
if (!document.getElementById(styleId)) {
|
|
2151
|
+
const styleEl = document.createElement("style");
|
|
2152
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
2153
|
+
document.head.appendChild(styleEl);
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2123
2157
|
/**
|
|
2124
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
2158
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
2125
2159
|
*
|
|
2126
|
-
* Displays
|
|
2127
|
-
*
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
borderRadius: "8px",
|
|
2144
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
2145
|
-
fontFamily: "monospace",
|
|
2146
|
-
fontSize: "12px",
|
|
2147
|
-
color: "#fff",
|
|
2148
|
-
zIndex: 9999,
|
|
2149
|
-
minWidth: "200px",
|
|
2150
|
-
backdropFilter: "blur(8px)",
|
|
2151
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
2152
|
-
transition: "opacity 0.3s ease",
|
|
2153
|
-
opacity: isVisible ? 1 : 0,
|
|
2154
|
-
pointerEvents: isVisible ? "auto" : "none"
|
|
2155
|
-
})), [ isVisible ]), headerStyle = useMemo((() => ({
|
|
2156
|
-
display: "flex",
|
|
2157
|
-
justifyContent: "space-between",
|
|
2158
|
-
alignItems: "center",
|
|
2159
|
-
marginBottom: "8px",
|
|
2160
|
-
paddingBottom: "8px",
|
|
2161
|
-
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
2162
|
-
})), []), titleStyle = useMemo((() => ({
|
|
2163
|
-
fontWeight: "bold",
|
|
2164
|
-
fontSize: "13px",
|
|
2165
|
-
color: "#fff"
|
|
2166
|
-
})), []), closeButtonStyle = useMemo((() => ({
|
|
2167
|
-
background: "transparent",
|
|
2168
|
-
border: "none",
|
|
2169
|
-
color: "#9ca3af",
|
|
2170
|
-
cursor: "pointer",
|
|
2171
|
-
fontSize: "16px",
|
|
2172
|
-
padding: "0",
|
|
2173
|
-
lineHeight: "1"
|
|
2174
|
-
})), []), metricRowStyle = useMemo((() => ({
|
|
2175
|
-
display: "flex",
|
|
2176
|
-
justifyContent: "space-between",
|
|
2177
|
-
alignItems: "center",
|
|
2178
|
-
marginBottom: "6px"
|
|
2179
|
-
})), []), labelStyle = useMemo((() => ({
|
|
2180
|
-
color: "#9ca3af",
|
|
2181
|
-
marginRight: "12px"
|
|
2182
|
-
})), []), valueStyle = useMemo((() => ({
|
|
2183
|
-
fontWeight: "bold"
|
|
2184
|
-
})), []);
|
|
2185
|
-
// Get quality level badge color
|
|
2186
|
-
return isVisible ? jsxs("div", {
|
|
2187
|
-
style: dashboardStyle,
|
|
2160
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
2161
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
2162
|
+
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
2163
|
+
if (!isVisible) return null;
|
|
2164
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
2165
|
+
var fps;
|
|
2166
|
+
const isCritical = metrics.fps < 45;
|
|
2167
|
+
return jsxs("div", {
|
|
2168
|
+
className: "c-perf-dashboard u-position-fixed u-top-4 u-end-4 u-p-3 u-px-4 u-text-xs u-font-mono u-text-white u-rounded-md u-border u-border-white-alpha-10 u-shadow-lg",
|
|
2169
|
+
style: {
|
|
2170
|
+
zIndex: 9999,
|
|
2171
|
+
minWidth: "12.5rem",
|
|
2172
|
+
// 200px
|
|
2173
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
2174
|
+
backdropFilter: "blur(8px)",
|
|
2175
|
+
transition: "opacity 0.3s ease"
|
|
2176
|
+
},
|
|
2188
2177
|
children: [ jsxs("div", {
|
|
2189
|
-
|
|
2178
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
2190
2179
|
children: [ jsx("span", {
|
|
2191
|
-
|
|
2180
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
2192
2181
|
children: "Performance Monitor"
|
|
2193
2182
|
}), onClose && jsx("button", {
|
|
2194
|
-
|
|
2183
|
+
className: "u-bg-transparent u-border-none u-p-0 u-line-height-1 u-text-base u-text-gray-400 u-cursor-pointer hover:u-text-white",
|
|
2195
2184
|
onClick: onClose,
|
|
2196
2185
|
"aria-label": "Close performance dashboard",
|
|
2186
|
+
style: {
|
|
2187
|
+
transition: "color 0.2s ease"
|
|
2188
|
+
},
|
|
2197
2189
|
children: "×"
|
|
2198
2190
|
}) ]
|
|
2199
2191
|
}), jsxs("div", {
|
|
2200
|
-
|
|
2192
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2201
2193
|
children: [ jsx("span", {
|
|
2202
|
-
|
|
2194
|
+
className: "u-text-gray-400 u-me-3",
|
|
2203
2195
|
children: "FPS"
|
|
2204
2196
|
}), jsx("span", {
|
|
2197
|
+
className: "u-font-bold",
|
|
2205
2198
|
style: {
|
|
2206
|
-
|
|
2207
|
-
color: getFpsColor(metrics.fps)
|
|
2199
|
+
color: fpsColor
|
|
2208
2200
|
},
|
|
2209
2201
|
children: Math.round(metrics.fps)
|
|
2210
2202
|
}) ]
|
|
2211
2203
|
}), jsxs("div", {
|
|
2212
|
-
|
|
2204
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2213
2205
|
children: [ jsx("span", {
|
|
2214
|
-
|
|
2206
|
+
className: "u-text-gray-400 u-me-3",
|
|
2215
2207
|
children: "Frame Time"
|
|
2216
2208
|
}), jsxs("span", {
|
|
2217
|
-
|
|
2209
|
+
className: "u-font-bold",
|
|
2218
2210
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
2219
2211
|
}) ]
|
|
2220
2212
|
}), jsxs("div", {
|
|
2221
|
-
|
|
2213
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2222
2214
|
children: [ jsx("span", {
|
|
2223
|
-
|
|
2215
|
+
className: "u-text-gray-400 u-me-3",
|
|
2224
2216
|
children: "Quality"
|
|
2225
2217
|
}), jsx("span", {
|
|
2218
|
+
className: "u-font-bold u-text-uppercase",
|
|
2226
2219
|
style: {
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
case "high":
|
|
2231
|
-
return "#4ade80";
|
|
2232
|
-
|
|
2233
|
-
case "medium":
|
|
2234
|
-
return "#fbbf24";
|
|
2235
|
-
|
|
2236
|
-
case "low":
|
|
2237
|
-
return "#ef4444";
|
|
2238
|
-
|
|
2239
|
-
default:
|
|
2240
|
-
return "#9ca3af";
|
|
2241
|
-
}
|
|
2242
|
-
})(metrics.qualityLevel),
|
|
2243
|
-
textTransform: "uppercase",
|
|
2244
|
-
fontSize: "11px"
|
|
2220
|
+
fontSize: "0.6875rem",
|
|
2221
|
+
// 11px
|
|
2222
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
2245
2223
|
},
|
|
2246
2224
|
children: metrics.qualityLevel
|
|
2247
2225
|
}) ]
|
|
2248
2226
|
}), metrics.gpuMemory && jsxs("div", {
|
|
2249
|
-
|
|
2227
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2250
2228
|
children: [ jsx("span", {
|
|
2251
|
-
|
|
2229
|
+
className: "u-text-gray-400 u-me-3",
|
|
2252
2230
|
children: "GPU Memory"
|
|
2253
2231
|
}), jsxs("span", {
|
|
2254
|
-
|
|
2232
|
+
className: "u-font-bold",
|
|
2255
2233
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
2256
2234
|
}) ]
|
|
2257
2235
|
}), metrics.isAutoScaling && jsx("div", {
|
|
2236
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
2258
2237
|
style: {
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
fontSize: "10px",
|
|
2263
|
-
color: "#6b7280",
|
|
2264
|
-
textAlign: "center"
|
|
2238
|
+
fontSize: "0.625rem",
|
|
2239
|
+
// 10px
|
|
2240
|
+
color: "#6b7280"
|
|
2265
2241
|
},
|
|
2266
2242
|
children: "Auto-scaling active"
|
|
2267
2243
|
}), jsxs("div", {
|
|
2268
|
-
|
|
2269
|
-
marginTop: "8px",
|
|
2270
|
-
paddingTop: "8px",
|
|
2271
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
2272
|
-
display: "flex",
|
|
2273
|
-
alignItems: "center",
|
|
2274
|
-
gap: "6px"
|
|
2275
|
-
},
|
|
2244
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
2276
2245
|
children: [ jsx("div", {
|
|
2246
|
+
className: "u-rounded-full",
|
|
2277
2247
|
style: {
|
|
2278
|
-
width: "
|
|
2279
|
-
height: "
|
|
2280
|
-
|
|
2281
|
-
backgroundColor:
|
|
2282
|
-
|
|
2248
|
+
width: "0.5rem",
|
|
2249
|
+
height: "0.5rem",
|
|
2250
|
+
flexShrink: 0,
|
|
2251
|
+
backgroundColor: fpsColor,
|
|
2252
|
+
...isCritical && {
|
|
2253
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
2254
|
+
}
|
|
2283
2255
|
}
|
|
2284
2256
|
}), jsx("span", {
|
|
2257
|
+
className: "u-text-xs",
|
|
2285
2258
|
style: {
|
|
2286
|
-
fontSize: "
|
|
2287
|
-
|
|
2259
|
+
fontSize: "0.625rem",
|
|
2260
|
+
// 10px
|
|
2261
|
+
color: fpsColor
|
|
2288
2262
|
},
|
|
2289
|
-
children: metrics.fps
|
|
2263
|
+
children: getFpsLabel(metrics.fps)
|
|
2290
2264
|
}) ]
|
|
2291
2265
|
}) ]
|
|
2292
|
-
})
|
|
2293
|
-
};
|
|
2266
|
+
});
|
|
2267
|
+
}));
|
|
2294
2268
|
|
|
2295
|
-
|
|
2296
|
-
if ("undefined" != typeof document) {
|
|
2297
|
-
const styleSheet = document.createElement("style");
|
|
2298
|
-
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
2299
|
-
document.head.appendChild(styleSheet);
|
|
2300
|
-
}
|
|
2269
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
2301
2270
|
|
|
2302
2271
|
/**
|
|
2303
2272
|
* Mobile optimization presets
|
|
@@ -2308,7 +2277,8 @@ if ("undefined" != typeof document) {
|
|
|
2308
2277
|
/**
|
|
2309
2278
|
* Performance preset - Maximum FPS, reduced quality
|
|
2310
2279
|
* Best for low-end devices or when battery saving is priority
|
|
2311
|
-
*/
|
|
2280
|
+
*/
|
|
2281
|
+
const PERFORMANCE_PRESET = {
|
|
2312
2282
|
distortionOctaves: 2,
|
|
2313
2283
|
// Minimal FBM layers
|
|
2314
2284
|
displacementScale: 50,
|
|
@@ -2417,95 +2387,21 @@ if ("undefined" != typeof document) {
|
|
|
2417
2387
|
saturation: 70
|
|
2418
2388
|
}
|
|
2419
2389
|
}
|
|
2420
|
-
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
* - Dynamic border-radius extraction from children CSS properties
|
|
2433
|
-
* - Automatic light/dark theme detection via overLight prop
|
|
2434
|
-
* - Accessibility and performance optimizations
|
|
2435
|
-
* - Multiple displacement modes (standard, polar, prominent, shader)
|
|
2436
|
-
* - Design token integration for consistent theming
|
|
2437
|
-
* - Focus ring support for keyboard navigation
|
|
2438
|
-
* - Responsive breakpoints for mobile optimization
|
|
2439
|
-
* - Enhanced ARIA attributes for screen readers
|
|
2440
|
-
* - Time-based animation system with FBM distortion
|
|
2441
|
-
* - Device preset optimization for performance/quality balance
|
|
2442
|
-
*
|
|
2443
|
-
* Design System Compliance:
|
|
2444
|
-
* - Uses design tokens for opacity, spacing, and colors
|
|
2445
|
-
* - Follows BEM methodology for class naming
|
|
2446
|
-
* - Implements focus-ring mixin for accessibility
|
|
2447
|
-
* - Supports reduced motion and high contrast preferences
|
|
2448
|
-
*
|
|
2449
|
-
* @example
|
|
2450
|
-
* // Basic usage with dynamic border-radius extraction
|
|
2451
|
-
* <AtomixGlass>
|
|
2452
|
-
* <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
|
|
2453
|
-
* </AtomixGlass>
|
|
2454
|
-
*
|
|
2455
|
-
* @example
|
|
2456
|
-
* // Manual border-radius override
|
|
2457
|
-
* <AtomixGlass borderRadius={20}>
|
|
2458
|
-
* <div>Content with 20px glass radius</div>
|
|
2459
|
-
* </AtomixGlass>
|
|
2460
|
-
*
|
|
2461
|
-
* @example
|
|
2462
|
-
* // Interactive glass with click handler
|
|
2463
|
-
* <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
|
|
2464
|
-
* <div>Clickable content</div>
|
|
2465
|
-
* </AtomixGlass>
|
|
2466
|
-
*
|
|
2467
|
-
* @example
|
|
2468
|
-
* // OverLight - Boolean mode (explicit control)
|
|
2469
|
-
* <AtomixGlass overLight={true}>
|
|
2470
|
-
* <div>Content on light background</div>
|
|
2471
|
-
* </AtomixGlass>
|
|
2472
|
-
*
|
|
2473
|
-
* @example
|
|
2474
|
-
* // OverLight - Auto-detection mode
|
|
2475
|
-
* <AtomixGlass overLight="auto">
|
|
2476
|
-
* <div>Content with auto-detected background</div>
|
|
2477
|
-
* </AtomixGlass>
|
|
2478
|
-
*
|
|
2479
|
-
* @example
|
|
2480
|
-
* // OverLight - Object config with custom settings
|
|
2481
|
-
* <AtomixGlass
|
|
2482
|
-
* overLight={{
|
|
2483
|
-
* threshold: 0.8,
|
|
2484
|
-
* opacity: 0.6,
|
|
2485
|
-
* contrast: 1.8,
|
|
2486
|
-
* brightness: 1.0,
|
|
2487
|
-
* saturationBoost: 1.5
|
|
2488
|
-
* }}
|
|
2489
|
-
* >
|
|
2490
|
-
* <div>Content with custom overLight config</div>
|
|
2491
|
-
* </AtomixGlass>
|
|
2492
|
-
*
|
|
2493
|
-
* @example
|
|
2494
|
-
* // Debug mode for overLight detection
|
|
2495
|
-
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
2496
|
-
* <div>Content with debug logging enabled</div>
|
|
2497
|
-
* </AtomixGlass>
|
|
2498
|
-
*
|
|
2499
|
-
* @example
|
|
2500
|
-
* // Performance-optimized for mobile devices
|
|
2501
|
-
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
2502
|
-
* <div>Mobile-optimized glass effect</div>
|
|
2503
|
-
* </AtomixGlass>
|
|
2504
|
-
*/
|
|
2505
|
-
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, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, ...rest}) {
|
|
2506
|
-
const glassRef = useRef(null), contentRef = useRef(null), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, getShaderTime: getShaderTime, applyTimeBasedDistortion: applyTimeBasedDistortion, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
2390
|
+
}, AtomixGlassInner = forwardRef((function({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, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, isFixedOrSticky: propsIsFixedOrSticky, ...rest}, ref) {
|
|
2391
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
|
|
2392
|
+
// Helper to merge refs
|
|
2393
|
+
function(...refs) {
|
|
2394
|
+
return node => {
|
|
2395
|
+
refs.forEach((ref => {
|
|
2396
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
2397
|
+
}));
|
|
2398
|
+
};
|
|
2399
|
+
}
|
|
2400
|
+
// Internal implementation with forwardRef
|
|
2401
|
+
(ref, internalWrapperRef)), [ ref ]), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = propsIsFixedOrSticky || "fixed" === restStyle.position || "sticky" === restStyle.position, {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, getShaderTime: getShaderTime, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
2507
2402
|
glassRef: glassRef,
|
|
2508
2403
|
contentRef: contentRef,
|
|
2404
|
+
wrapperRef: internalWrapperRef,
|
|
2509
2405
|
borderRadius: borderRadius,
|
|
2510
2406
|
globalMousePosition: externalGlobalMousePosition,
|
|
2511
2407
|
mouseOffset: externalMouseOffset,
|
|
@@ -2534,7 +2430,6 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2534
2430
|
distortionGain: distortionGain,
|
|
2535
2431
|
distortionQuality: distortionQuality
|
|
2536
2432
|
});
|
|
2537
|
-
// Re-calculate only when devicePreset changes
|
|
2538
2433
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
2539
2434
|
!
|
|
2540
2435
|
/**
|
|
@@ -2727,11 +2622,10 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2727
2622
|
},
|
|
2728
2623
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
2729
2624
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
2730
|
-
// Enable unless disabled
|
|
2731
2625
|
debug: !1
|
|
2732
2626
|
});
|
|
2733
2627
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
2734
|
-
const {metrics: performanceMetrics,
|
|
2628
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
|
|
2735
2629
|
/**
|
|
2736
2630
|
* Performance Monitor Hook
|
|
2737
2631
|
*
|
|
@@ -2895,17 +2789,17 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2895
2789
|
toggleMonitoring: toggleMonitoring
|
|
2896
2790
|
};
|
|
2897
2791
|
}({
|
|
2898
|
-
enabled:
|
|
2899
|
-
//
|
|
2792
|
+
enabled: debugPerformance,
|
|
2793
|
+
// Enable when debugPerformance is true
|
|
2900
2794
|
debug: !1,
|
|
2901
2795
|
showOverlay: !1
|
|
2902
2796
|
});
|
|
2903
|
-
// Auto-start performance monitoring
|
|
2797
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
2904
2798
|
React.useEffect((() => {
|
|
2905
|
-
|
|
2799
|
+
debugPerformance && toggleMonitoring();
|
|
2906
2800
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2907
|
-
}), []);
|
|
2908
|
-
//
|
|
2801
|
+
}), [ debugPerformance ]);
|
|
2802
|
+
// Re-run when debugPerformance changes
|
|
2909
2803
|
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
2910
2804
|
if (!isFixedOrSticky) return {};
|
|
2911
2805
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -2933,34 +2827,30 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2933
2827
|
if (isFixedOrSticky) {
|
|
2934
2828
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
2935
2829
|
return {
|
|
2936
|
-
...visualStyle
|
|
2937
|
-
...!effectiveWithoutEffects && {
|
|
2938
|
-
transform: transformStyle
|
|
2939
|
-
}
|
|
2830
|
+
...visualStyle
|
|
2940
2831
|
};
|
|
2941
2832
|
}
|
|
2942
2833
|
return {
|
|
2943
|
-
...restStyle
|
|
2944
|
-
...!effectiveWithoutEffects && {
|
|
2945
|
-
transform: transformStyle
|
|
2946
|
-
}
|
|
2834
|
+
...restStyle
|
|
2947
2835
|
};
|
|
2948
|
-
}), [ isFixedOrSticky, restStyle
|
|
2836
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
2949
2837
|
// Build className with state modifiers
|
|
2950
2838
|
const componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
|
|
2951
2839
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
2952
|
-
top: isFixedOrSticky ?
|
|
2953
|
-
left: isFixedOrSticky ?
|
|
2954
|
-
|
|
2840
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
2841
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
2842
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
2843
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
2844
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
2955
2845
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
2956
2846
|
// but sizing is driven by explicit width/height or measured size.
|
|
2957
2847
|
positionStyles.position;
|
|
2958
|
-
const resolveLength = (value, measured) => void 0 !== value ? "number" == typeof value ? `${value}px` : value : measured > 0 ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
2848
|
+
const resolveLength = (value, measured) => void 0 !== value && isFixedOrSticky ? "number" == typeof value ? `${value}px` : value : measured > 0 && isFixedOrSticky ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
2959
2849
|
return {
|
|
2960
2850
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
2961
2851
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
2962
2852
|
};
|
|
2963
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
2853
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
|
|
2964
2854
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
2965
2855
|
return {
|
|
2966
2856
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -2990,33 +2880,32 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2990
2880
|
absMx: absMx,
|
|
2991
2881
|
absMy: absMy
|
|
2992
2882
|
};
|
|
2993
|
-
}), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
};
|
|
3002
|
-
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
|
|
3003
|
-
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;
|
|
2883
|
+
}), [ mouseOffset.x, mouseOffset.y ]), clampedOverLightOpacity = Math.max(0, Math.min(1, overLightConfig?.opacity ?? .4)), clampedBorderOpacity = Math.max(0, Math.min(1, overLightConfig?.borderOpacity ?? 1)), opacityValues = useMemo((() => ({
|
|
2884
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
2885
|
+
hover2: isActive ? .5 : 0,
|
|
2886
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
2887
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
2888
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
2889
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
|
|
2890
|
+
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;
|
|
3004
2891
|
return {
|
|
3005
2892
|
...void 0 !== customZIndex && {
|
|
3006
2893
|
"--atomix-glass-base-z-index": customZIndex
|
|
3007
2894
|
},
|
|
3008
2895
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
3009
2896
|
"--atomix-glass-transform": transformStyle || "none",
|
|
3010
|
-
|
|
3011
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
3012
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
3013
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
2897
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
2898
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
2899
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
2900
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
2901
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
2902
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
3014
2903
|
"--atomix-glass-width": adjustedSize.width,
|
|
3015
2904
|
"--atomix-glass-height": adjustedSize.height,
|
|
3016
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
2905
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
3017
2906
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
3018
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) *
|
|
3019
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) *
|
|
2907
|
+
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * clampedBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * clampedBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
2908
|
+
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * clampedBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * clampedBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
3020
2909
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
3021
2910
|
"--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}%)`,
|
|
3022
2911
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -3030,13 +2919,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3030
2919
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
3031
2920
|
"--atomix-glass-overlay-highlight-bg": `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
|
|
3032
2921
|
};
|
|
3033
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
2922
|
+
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, clampedBorderOpacity, customZIndex, isFixedOrSticky, positionStyles.position, rootLayoutStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), renderBackgroundLayer = layerType => jsx("div", {
|
|
3034
2923
|
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(" ")
|
|
3035
2924
|
});
|
|
3036
2925
|
// Calculate position and size styles for internal layers
|
|
3037
2926
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
3038
2927
|
return jsxs("div", {
|
|
3039
2928
|
...rest,
|
|
2929
|
+
ref: mergedRef,
|
|
3040
2930
|
className: componentClassName,
|
|
3041
2931
|
style: {
|
|
3042
2932
|
...glassVars
|
|
@@ -3046,17 +2936,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3046
2936
|
"aria-label": ariaLabel,
|
|
3047
2937
|
"aria-describedby": ariaDescribedBy,
|
|
3048
2938
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
3049
|
-
"aria-pressed":
|
|
2939
|
+
"aria-pressed": void 0,
|
|
3050
2940
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
3051
2941
|
children: [ jsx(AtomixGlassContainer, {
|
|
3052
2942
|
ref: glassRef,
|
|
3053
2943
|
contentRef: contentRef,
|
|
3054
2944
|
className: className,
|
|
3055
2945
|
style: {
|
|
3056
|
-
...restStyle
|
|
3057
|
-
...!isFixedOrSticky && {
|
|
3058
|
-
position: "relative"
|
|
3059
|
-
}
|
|
2946
|
+
...restStyle
|
|
3060
2947
|
},
|
|
3061
2948
|
borderRadius: effectiveBorderRadius,
|
|
3062
2949
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -3092,6 +2979,7 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3092
2979
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
3093
2980
|
shaderVariant: shaderVariant,
|
|
3094
2981
|
withLiquidBlur: withLiquidBlur,
|
|
2982
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
3095
2983
|
// Phase 1: Animation System props
|
|
3096
2984
|
shaderTime: getShaderTime(),
|
|
3097
2985
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -3120,6 +3008,8 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3120
3008
|
}) ]
|
|
3121
3009
|
}), withBorder && jsxs(Fragment, {
|
|
3122
3010
|
children: [ jsx("span", {
|
|
3011
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
3012
|
+
}), jsx("span", {
|
|
3123
3013
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
3124
3014
|
}), jsx("span", {
|
|
3125
3015
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -3130,10 +3020,18 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3130
3020
|
onClose: () => {}
|
|
3131
3021
|
}) ]
|
|
3132
3022
|
});
|
|
3133
|
-
}
|
|
3023
|
+
}));
|
|
3134
3024
|
|
|
3135
|
-
|
|
3136
|
-
|
|
3025
|
+
/**
|
|
3026
|
+
* Balanced preset - Good quality with reasonable performance
|
|
3027
|
+
* Default preset for most mobile devices
|
|
3028
|
+
*/ AtomixGlassInner.displayName = "AtomixGlass";
|
|
3029
|
+
|
|
3030
|
+
/**
|
|
3031
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
3032
|
+
* Ref is forwarded to the root `<div>` element.
|
|
3033
|
+
*/
|
|
3034
|
+
const AtomixGlass = memo(AtomixGlassInner), DefaultIcon = () => jsx("i", {
|
|
3137
3035
|
className: "c-accordion__icon",
|
|
3138
3036
|
"aria-hidden": "true",
|
|
3139
3037
|
children: jsx("svg", {
|
|
@@ -3167,6 +3065,7 @@ const DefaultIcon = () => jsx("i", {
|
|
|
3167
3065
|
});
|
|
3168
3066
|
}));
|
|
3169
3067
|
|
|
3068
|
+
// Default icon
|
|
3170
3069
|
AccordionHeader.displayName = "AccordionHeader";
|
|
3171
3070
|
|
|
3172
3071
|
const AccordionBody = forwardRef((({children: children, className: className = "", panelRef: panelRef, contentRef: contentRef, ...props}, ref) => {
|