@shohojdhara/atomix 0.4.9 → 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/shader-utils.ts +1 -1
- package/src/components/AtomixGlass/stories/{Phase1-Animation.stories.tsx → AnimationFeatures.stories.tsx} +53 -47
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +573 -236
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +656 -44
- package/src/components/AtomixGlass/stories/argTypes.ts +384 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +82 -3
- package/src/components/AtomixGlass/stories/types.ts +127 -0
- 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/Customization.stories.tsx +0 -131
- 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/Phase1-Test.stories.tsx +0 -95
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +0 -395
- 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/index.js
CHANGED
|
@@ -1718,6 +1718,7 @@ const THEME_COLORS = [ "primary", "secondary", "success", "info", "warning", "er
|
|
|
1718
1718
|
FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
|
|
1719
1719
|
FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
|
|
1720
1720
|
CONTENT_CLASS: "c-atomix-glass__content",
|
|
1721
|
+
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
1721
1722
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
1722
1723
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
1723
1724
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
@@ -2120,7 +2121,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2120
2121
|
default:
|
|
2121
2122
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
2122
2123
|
}
|
|
2123
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsxRuntime.jsx("svg", {
|
|
2124
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsxRuntime.jsx("svg", {
|
|
2124
2125
|
style: {
|
|
2125
2126
|
position: "absolute",
|
|
2126
2127
|
width: "100%",
|
|
@@ -2261,24 +2262,17 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2261
2262
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
2262
2263
|
|
|
2263
2264
|
// Memoize component to prevent unnecessary re-renders
|
|
2264
|
-
const GlassFilter = React.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))
|
|
2265
|
-
|
|
2266
|
-
// Module-level counter for deterministic ID generation
|
|
2267
|
-
let idCounter = 0;
|
|
2268
|
-
|
|
2269
|
-
// Module-level shared shader cache with LRU eviction
|
|
2270
|
-
const sharedShaderCache = new Map, AtomixGlassContainer = React.forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
2265
|
+
const GlassFilter = React.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 = React.forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
2271
2266
|
x: 0,
|
|
2272
2267
|
y: 0
|
|
2273
2268
|
}, 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 = {
|
|
2274
2269
|
width: 0,
|
|
2275
2270
|
height: 0
|
|
2276
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
2271
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
2277
2272
|
// Phase 1: Animation System props
|
|
2278
2273
|
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) => {
|
|
2279
|
-
//
|
|
2280
|
-
|
|
2281
|
-
const filterId = React.useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = React.useState(""), shaderGeneratorRef = React.useRef(null), shaderUtilsRef = React.useRef(null), shaderDebounceTimeoutRef = React.useRef(null), shaderUpdateTimeoutRef = React.useRef(null), animationFrameRef = React.useRef(null);
|
|
2274
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
2275
|
+
const rawId = React.useId(), filterId = React.useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), [shaderMapUrl, setShaderMapUrl] = React.useState(""), shaderGeneratorRef = React.useRef(null), shaderUtilsRef = React.useRef(null), shaderDebounceTimeoutRef = React.useRef(null), shaderUpdateTimeoutRef = React.useRef(null), animationFrameRef = React.useRef(null);
|
|
2282
2276
|
// Lazy load shader utilities only when shader mode is needed
|
|
2283
2277
|
React.useEffect((() => {
|
|
2284
2278
|
"shader" === mode ?
|
|
@@ -2303,9 +2297,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2303
2297
|
// Create cache key from size and variant
|
|
2304
2298
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
2305
2299
|
const entry = sharedShaderCache.get(key);
|
|
2306
|
-
return entry ? (
|
|
2307
|
-
// Update access timestamp for LRU
|
|
2308
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
2300
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
2309
2301
|
})(cacheKey);
|
|
2310
2302
|
// Check shared cache first
|
|
2311
2303
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -2316,29 +2308,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2316
2308
|
if (shaderUtilsRef.current) try {
|
|
2317
2309
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
2318
2310
|
shaderGeneratorRef.current?.destroy();
|
|
2319
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
2311
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
2320
2312
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
2321
2313
|
width: glassSize.width,
|
|
2322
2314
|
height: glassSize.height,
|
|
2323
2315
|
fragment: selectedShader
|
|
2324
2316
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
2325
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
2317
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
2326
2318
|
url && ((key, url) => {
|
|
2327
|
-
// Evict oldest entries if at capacity
|
|
2328
2319
|
if (sharedShaderCache.size >= 15) {
|
|
2329
2320
|
const entries = Array.from(sharedShaderCache.entries());
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
const oldestEntry = entries[0];
|
|
2334
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
2321
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
2322
|
+
const oldest = entries[0];
|
|
2323
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
2335
2324
|
}
|
|
2336
2325
|
sharedShaderCache.set(key, {
|
|
2337
2326
|
url: url,
|
|
2338
2327
|
timestamp: Date.now()
|
|
2339
|
-
}),
|
|
2340
|
-
// Development mode: log cache size
|
|
2341
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
2328
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
2342
2329
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
2343
2330
|
}), 100);
|
|
2344
2331
|
} catch (error) {
|
|
@@ -2407,7 +2394,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2407
2394
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
2408
2395
|
}
|
|
2409
2396
|
}), [ ref, glassSize ]);
|
|
2410
|
-
// Pre-calculate static multipliers outside useMemo
|
|
2411
2397
|
const liquidBlur = React.useMemo((() => {
|
|
2412
2398
|
const defaultBlur = {
|
|
2413
2399
|
baseBlur: blurAmount,
|
|
@@ -2476,7 +2462,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2476
2462
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
2477
2463
|
return jsxRuntime.jsx("div", {
|
|
2478
2464
|
ref: el => {
|
|
2479
|
-
// Apply force no-transition
|
|
2480
2465
|
// Handle forwarded ref
|
|
2481
2466
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
2482
2467
|
},
|
|
@@ -2518,6 +2503,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2518
2503
|
});
|
|
2519
2504
|
}));
|
|
2520
2505
|
|
|
2506
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
2521
2507
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
2522
2508
|
|
|
2523
2509
|
// Singleton instance
|
|
@@ -2718,8 +2704,6 @@ class {
|
|
|
2718
2704
|
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})`;
|
|
2719
2705
|
// Container variables
|
|
2720
2706
|
const style = containerElement.style;
|
|
2721
|
-
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
2722
|
-
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
2723
2707
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2724
2708
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2725
2709
|
// Shadows
|
|
@@ -3180,47 +3164,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3180
3164
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
3181
3165
|
}
|
|
3182
3166
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
3183
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = React.useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = React.useRef(null),
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
if (!container) return;
|
|
3188
|
-
// Use cached rect if available, otherwise get new one
|
|
3189
|
-
let rect = cachedRectRef.current;
|
|
3190
|
-
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
3191
|
-
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
3192
|
-
const center = calculateElementCenter(rect);
|
|
3193
|
-
// Write raw target — the lerp loop will smoothly pursue it
|
|
3194
|
-
targetMouseOffsetRef.current = {
|
|
3195
|
-
x: (globalPos.x - center.x) / rect.width * 100,
|
|
3196
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
3197
|
-
}, targetGlobalMousePositionRef.current = globalPos;
|
|
3198
|
-
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = React.useCallback((() => {
|
|
3167
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = React.useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = React.useRef(null), stopLerpLoop = React.useCallback((() => {
|
|
3168
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
3169
|
+
lerpRafRef.current = null);
|
|
3170
|
+
}), []), startLerpLoop = React.useCallback((() => {
|
|
3199
3171
|
if (lerpActiveRef.current) return;
|
|
3200
3172
|
lerpActiveRef.current = !0;
|
|
3201
3173
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
3202
3174
|
if (!lerpActiveRef.current) return;
|
|
3203
|
-
|
|
3204
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
3175
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
3205
3176
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
3206
3177
|
// If we're close enough, snap and park
|
|
3207
|
-
if (Math.abs(dx) < .
|
|
3178
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
3208
3179
|
...tgt
|
|
3209
3180
|
}, internalGlobalMousePositionRef.current = {
|
|
3210
3181
|
...targetGlobalMousePositionRef.current
|
|
3211
|
-
}
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3182
|
+
},
|
|
3183
|
+
// Final update and stop
|
|
3184
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3185
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
3186
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3187
|
+
glassSize: glassSize,
|
|
3188
|
+
isHovered: isHovered,
|
|
3189
|
+
isActive: isActive,
|
|
3190
|
+
isOverLight: overLightConfig.isOverLight,
|
|
3191
|
+
baseOverLightConfig: overLightConfig,
|
|
3192
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
3193
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3194
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
3195
|
+
elasticity: elasticity,
|
|
3196
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
3197
|
+
onClick: onClick,
|
|
3198
|
+
withLiquidBlur: withLiquidBlur,
|
|
3199
|
+
blurAmount: blurAmount,
|
|
3200
|
+
saturation: saturation,
|
|
3201
|
+
padding: padding,
|
|
3202
|
+
isFixedOrSticky: isFixedOrSticky
|
|
3203
|
+
}), void stopLerpLoop();
|
|
3204
|
+
// Smooth step
|
|
3205
|
+
internalMouseOffsetRef.current = {
|
|
3206
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
3207
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
3208
|
+
};
|
|
3209
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
3210
|
+
internalGlobalMousePositionRef.current = {
|
|
3211
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
3212
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
3213
|
+
},
|
|
3214
|
+
// Imperative style update
|
|
3215
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3224
3216
|
mouseOffset: internalMouseOffsetRef.current,
|
|
3225
3217
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3226
3218
|
glassSize: glassSize,
|
|
@@ -3243,10 +3235,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3243
3235
|
};
|
|
3244
3236
|
// 0.08 – lower = more viscous
|
|
3245
3237
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
3246
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3238
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = React.useCallback((globalPos => {
|
|
3239
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3240
|
+
if (effectiveWithoutEffects) return;
|
|
3241
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
3242
|
+
if (!container) return;
|
|
3243
|
+
// Use cached rect if available, otherwise get new one
|
|
3244
|
+
let rect = cachedRectRef.current;
|
|
3245
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
3246
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
3247
|
+
const center = calculateElementCenter(rect);
|
|
3248
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
3249
|
+
targetMouseOffsetRef.current = {
|
|
3250
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
3251
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
3252
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
3253
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
3254
|
+
lerpActiveRef.current || startLerpLoop();
|
|
3255
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
3250
3256
|
/**
|
|
3251
3257
|
* Validate and clamp a numeric config value
|
|
3252
3258
|
*/
|
|
@@ -3255,7 +3261,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3255
3261
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3256
3262
|
if (effectiveWithoutEffects) return;
|
|
3257
3263
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
3258
|
-
//
|
|
3264
|
+
// Initial start
|
|
3259
3265
|
startLerpLoop();
|
|
3260
3266
|
const container = mouseContainer?.current || glassRef.current;
|
|
3261
3267
|
let resizeObserver = null;
|
|
@@ -3268,7 +3274,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3268
3274
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
3269
3275
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
3270
3276
|
};
|
|
3271
|
-
}), [
|
|
3277
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
3272
3278
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
3273
3279
|
React.useEffect((() => {
|
|
3274
3280
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -3763,183 +3769,146 @@ function usePerformanceMonitor(config = {}) {
|
|
|
3763
3769
|
}
|
|
3764
3770
|
}
|
|
3765
3771
|
|
|
3772
|
+
/** Map an FPS value to a semantic color token string. */ const getQualityColor = quality => {
|
|
3773
|
+
switch (quality) {
|
|
3774
|
+
case "high":
|
|
3775
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
3776
|
+
|
|
3777
|
+
case "medium":
|
|
3778
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
3779
|
+
|
|
3780
|
+
case "low":
|
|
3781
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
3782
|
+
|
|
3783
|
+
default:
|
|
3784
|
+
return "#9ca3af";
|
|
3785
|
+
}
|
|
3786
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
3787
|
+
|
|
3788
|
+
/** Map a quality level string to a semantic color token string. */
|
|
3789
|
+
// Inject keyframes once
|
|
3790
|
+
if ("undefined" != typeof document) {
|
|
3791
|
+
const styleId = "perf-dashboard-keyframes";
|
|
3792
|
+
if (!document.getElementById(styleId)) {
|
|
3793
|
+
const styleEl = document.createElement("style");
|
|
3794
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
3795
|
+
document.head.appendChild(styleEl);
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3766
3799
|
/**
|
|
3767
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
3800
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
3768
3801
|
*
|
|
3769
|
-
* Displays
|
|
3770
|
-
*
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
3787
|
-
fontFamily: "monospace",
|
|
3788
|
-
fontSize: "12px",
|
|
3789
|
-
color: "#fff",
|
|
3790
|
-
zIndex: 9999,
|
|
3791
|
-
minWidth: "200px",
|
|
3792
|
-
backdropFilter: "blur(8px)",
|
|
3793
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3794
|
-
transition: "opacity 0.3s ease",
|
|
3795
|
-
opacity: isVisible ? 1 : 0,
|
|
3796
|
-
pointerEvents: isVisible ? "auto" : "none"
|
|
3797
|
-
})), [ isVisible ]), headerStyle = React.useMemo((() => ({
|
|
3798
|
-
display: "flex",
|
|
3799
|
-
justifyContent: "space-between",
|
|
3800
|
-
alignItems: "center",
|
|
3801
|
-
marginBottom: "8px",
|
|
3802
|
-
paddingBottom: "8px",
|
|
3803
|
-
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
3804
|
-
})), []), titleStyle = React.useMemo((() => ({
|
|
3805
|
-
fontWeight: "bold",
|
|
3806
|
-
fontSize: "13px",
|
|
3807
|
-
color: "#fff"
|
|
3808
|
-
})), []), closeButtonStyle = React.useMemo((() => ({
|
|
3809
|
-
background: "transparent",
|
|
3810
|
-
border: "none",
|
|
3811
|
-
color: "#9ca3af",
|
|
3812
|
-
cursor: "pointer",
|
|
3813
|
-
fontSize: "16px",
|
|
3814
|
-
padding: "0",
|
|
3815
|
-
lineHeight: "1"
|
|
3816
|
-
})), []), metricRowStyle = React.useMemo((() => ({
|
|
3817
|
-
display: "flex",
|
|
3818
|
-
justifyContent: "space-between",
|
|
3819
|
-
alignItems: "center",
|
|
3820
|
-
marginBottom: "6px"
|
|
3821
|
-
})), []), labelStyle = React.useMemo((() => ({
|
|
3822
|
-
color: "#9ca3af",
|
|
3823
|
-
marginRight: "12px"
|
|
3824
|
-
})), []), valueStyle = React.useMemo((() => ({
|
|
3825
|
-
fontWeight: "bold"
|
|
3826
|
-
})), []);
|
|
3827
|
-
// Get quality level badge color
|
|
3828
|
-
return isVisible ? jsxRuntime.jsxs("div", {
|
|
3829
|
-
style: dashboardStyle,
|
|
3802
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
3803
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
3804
|
+
*/ const PerformanceDashboard = React.memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
3805
|
+
if (!isVisible) return null;
|
|
3806
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
3807
|
+
var fps;
|
|
3808
|
+
const isCritical = metrics.fps < 45;
|
|
3809
|
+
return jsxRuntime.jsxs("div", {
|
|
3810
|
+
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",
|
|
3811
|
+
style: {
|
|
3812
|
+
zIndex: 9999,
|
|
3813
|
+
minWidth: "12.5rem",
|
|
3814
|
+
// 200px
|
|
3815
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
3816
|
+
backdropFilter: "blur(8px)",
|
|
3817
|
+
transition: "opacity 0.3s ease"
|
|
3818
|
+
},
|
|
3830
3819
|
children: [ jsxRuntime.jsxs("div", {
|
|
3831
|
-
|
|
3820
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
3832
3821
|
children: [ jsxRuntime.jsx("span", {
|
|
3833
|
-
|
|
3822
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
3834
3823
|
children: "Performance Monitor"
|
|
3835
3824
|
}), onClose && jsxRuntime.jsx("button", {
|
|
3836
|
-
|
|
3825
|
+
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",
|
|
3837
3826
|
onClick: onClose,
|
|
3838
3827
|
"aria-label": "Close performance dashboard",
|
|
3828
|
+
style: {
|
|
3829
|
+
transition: "color 0.2s ease"
|
|
3830
|
+
},
|
|
3839
3831
|
children: "×"
|
|
3840
3832
|
}) ]
|
|
3841
3833
|
}), jsxRuntime.jsxs("div", {
|
|
3842
|
-
|
|
3834
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3843
3835
|
children: [ jsxRuntime.jsx("span", {
|
|
3844
|
-
|
|
3836
|
+
className: "u-text-gray-400 u-me-3",
|
|
3845
3837
|
children: "FPS"
|
|
3846
3838
|
}), jsxRuntime.jsx("span", {
|
|
3839
|
+
className: "u-font-bold",
|
|
3847
3840
|
style: {
|
|
3848
|
-
|
|
3849
|
-
color: getFpsColor(metrics.fps)
|
|
3841
|
+
color: fpsColor
|
|
3850
3842
|
},
|
|
3851
3843
|
children: Math.round(metrics.fps)
|
|
3852
3844
|
}) ]
|
|
3853
3845
|
}), jsxRuntime.jsxs("div", {
|
|
3854
|
-
|
|
3846
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3855
3847
|
children: [ jsxRuntime.jsx("span", {
|
|
3856
|
-
|
|
3848
|
+
className: "u-text-gray-400 u-me-3",
|
|
3857
3849
|
children: "Frame Time"
|
|
3858
3850
|
}), jsxRuntime.jsxs("span", {
|
|
3859
|
-
|
|
3851
|
+
className: "u-font-bold",
|
|
3860
3852
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
3861
3853
|
}) ]
|
|
3862
3854
|
}), jsxRuntime.jsxs("div", {
|
|
3863
|
-
|
|
3855
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3864
3856
|
children: [ jsxRuntime.jsx("span", {
|
|
3865
|
-
|
|
3857
|
+
className: "u-text-gray-400 u-me-3",
|
|
3866
3858
|
children: "Quality"
|
|
3867
3859
|
}), jsxRuntime.jsx("span", {
|
|
3860
|
+
className: "u-font-bold u-text-uppercase",
|
|
3868
3861
|
style: {
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
case "high":
|
|
3873
|
-
return "#4ade80";
|
|
3874
|
-
|
|
3875
|
-
case "medium":
|
|
3876
|
-
return "#fbbf24";
|
|
3877
|
-
|
|
3878
|
-
case "low":
|
|
3879
|
-
return "#ef4444";
|
|
3880
|
-
|
|
3881
|
-
default:
|
|
3882
|
-
return "#9ca3af";
|
|
3883
|
-
}
|
|
3884
|
-
})(metrics.qualityLevel),
|
|
3885
|
-
textTransform: "uppercase",
|
|
3886
|
-
fontSize: "11px"
|
|
3862
|
+
fontSize: "0.6875rem",
|
|
3863
|
+
// 11px
|
|
3864
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
3887
3865
|
},
|
|
3888
3866
|
children: metrics.qualityLevel
|
|
3889
3867
|
}) ]
|
|
3890
3868
|
}), metrics.gpuMemory && jsxRuntime.jsxs("div", {
|
|
3891
|
-
|
|
3869
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3892
3870
|
children: [ jsxRuntime.jsx("span", {
|
|
3893
|
-
|
|
3871
|
+
className: "u-text-gray-400 u-me-3",
|
|
3894
3872
|
children: "GPU Memory"
|
|
3895
3873
|
}), jsxRuntime.jsxs("span", {
|
|
3896
|
-
|
|
3874
|
+
className: "u-font-bold",
|
|
3897
3875
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
3898
3876
|
}) ]
|
|
3899
3877
|
}), metrics.isAutoScaling && jsxRuntime.jsx("div", {
|
|
3878
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
3900
3879
|
style: {
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
fontSize: "10px",
|
|
3905
|
-
color: "#6b7280",
|
|
3906
|
-
textAlign: "center"
|
|
3880
|
+
fontSize: "0.625rem",
|
|
3881
|
+
// 10px
|
|
3882
|
+
color: "#6b7280"
|
|
3907
3883
|
},
|
|
3908
3884
|
children: "Auto-scaling active"
|
|
3909
3885
|
}), jsxRuntime.jsxs("div", {
|
|
3910
|
-
|
|
3911
|
-
marginTop: "8px",
|
|
3912
|
-
paddingTop: "8px",
|
|
3913
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3914
|
-
display: "flex",
|
|
3915
|
-
alignItems: "center",
|
|
3916
|
-
gap: "6px"
|
|
3917
|
-
},
|
|
3886
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
3918
3887
|
children: [ jsxRuntime.jsx("div", {
|
|
3888
|
+
className: "u-rounded-full",
|
|
3919
3889
|
style: {
|
|
3920
|
-
width: "
|
|
3921
|
-
height: "
|
|
3922
|
-
|
|
3923
|
-
backgroundColor:
|
|
3924
|
-
|
|
3890
|
+
width: "0.5rem",
|
|
3891
|
+
height: "0.5rem",
|
|
3892
|
+
flexShrink: 0,
|
|
3893
|
+
backgroundColor: fpsColor,
|
|
3894
|
+
...isCritical && {
|
|
3895
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
3896
|
+
}
|
|
3925
3897
|
}
|
|
3926
3898
|
}), jsxRuntime.jsx("span", {
|
|
3899
|
+
className: "u-text-xs",
|
|
3927
3900
|
style: {
|
|
3928
|
-
fontSize: "
|
|
3929
|
-
|
|
3901
|
+
fontSize: "0.625rem",
|
|
3902
|
+
// 10px
|
|
3903
|
+
color: fpsColor
|
|
3930
3904
|
},
|
|
3931
|
-
children: metrics.fps
|
|
3905
|
+
children: getFpsLabel(metrics.fps)
|
|
3932
3906
|
}) ]
|
|
3933
3907
|
}) ]
|
|
3934
|
-
})
|
|
3935
|
-
};
|
|
3908
|
+
});
|
|
3909
|
+
}));
|
|
3936
3910
|
|
|
3937
|
-
|
|
3938
|
-
if ("undefined" != typeof document) {
|
|
3939
|
-
const styleSheet = document.createElement("style");
|
|
3940
|
-
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
3941
|
-
document.head.appendChild(styleSheet);
|
|
3942
|
-
}
|
|
3911
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
3943
3912
|
|
|
3944
3913
|
/**
|
|
3945
3914
|
* Mobile optimization presets
|
|
@@ -3950,7 +3919,8 @@ if ("undefined" != typeof document) {
|
|
|
3950
3919
|
/**
|
|
3951
3920
|
* Performance preset - Maximum FPS, reduced quality
|
|
3952
3921
|
* Best for low-end devices or when battery saving is priority
|
|
3953
|
-
*/
|
|
3922
|
+
*/
|
|
3923
|
+
const PERFORMANCE_PRESET = {
|
|
3954
3924
|
distortionOctaves: 2,
|
|
3955
3925
|
// Minimal FBM layers
|
|
3956
3926
|
displacementScale: 50,
|
|
@@ -4113,90 +4083,21 @@ function getDevicePreset(presetName) {
|
|
|
4113
4083
|
getPixelRatio: () => "undefined" == typeof window ? 1 : window.devicePixelRatio || 1,
|
|
4114
4084
|
/** Check if device has touch support */
|
|
4115
4085
|
hasTouchSupport: () => "undefined" != typeof window && ("ontouchstart" in window || navigator.maxTouchPoints > 0)
|
|
4116
|
-
}
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
* - Design token integration for consistent theming
|
|
4129
|
-
* - Focus ring support for keyboard navigation
|
|
4130
|
-
* - Responsive breakpoints for mobile optimization
|
|
4131
|
-
* - Enhanced ARIA attributes for screen readers
|
|
4132
|
-
* - Time-based animation system with FBM distortion
|
|
4133
|
-
* - Device preset optimization for performance/quality balance
|
|
4134
|
-
*
|
|
4135
|
-
* Design System Compliance:
|
|
4136
|
-
* - Uses design tokens for opacity, spacing, and colors
|
|
4137
|
-
* - Follows BEM methodology for class naming
|
|
4138
|
-
* - Implements focus-ring mixin for accessibility
|
|
4139
|
-
* - Supports reduced motion and high contrast preferences
|
|
4140
|
-
*
|
|
4141
|
-
* @example
|
|
4142
|
-
* // Basic usage with dynamic border-radius extraction
|
|
4143
|
-
* <AtomixGlass>
|
|
4144
|
-
* <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
|
|
4145
|
-
* </AtomixGlass>
|
|
4146
|
-
*
|
|
4147
|
-
* @example
|
|
4148
|
-
* // Manual border-radius override
|
|
4149
|
-
* <AtomixGlass borderRadius={20}>
|
|
4150
|
-
* <div>Content with 20px glass radius</div>
|
|
4151
|
-
* </AtomixGlass>
|
|
4152
|
-
*
|
|
4153
|
-
* @example
|
|
4154
|
-
* // Interactive glass with click handler
|
|
4155
|
-
* <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
|
|
4156
|
-
* <div>Clickable content</div>
|
|
4157
|
-
* </AtomixGlass>
|
|
4158
|
-
*
|
|
4159
|
-
* @example
|
|
4160
|
-
* // OverLight - Boolean mode (explicit control)
|
|
4161
|
-
* <AtomixGlass overLight={true}>
|
|
4162
|
-
* <div>Content on light background</div>
|
|
4163
|
-
* </AtomixGlass>
|
|
4164
|
-
*
|
|
4165
|
-
* @example
|
|
4166
|
-
* // OverLight - Auto-detection mode
|
|
4167
|
-
* <AtomixGlass overLight="auto">
|
|
4168
|
-
* <div>Content with auto-detected background</div>
|
|
4169
|
-
* </AtomixGlass>
|
|
4170
|
-
*
|
|
4171
|
-
* @example
|
|
4172
|
-
* // OverLight - Object config with custom settings
|
|
4173
|
-
* <AtomixGlass
|
|
4174
|
-
* overLight={{
|
|
4175
|
-
* threshold: 0.8,
|
|
4176
|
-
* opacity: 0.6,
|
|
4177
|
-
* contrast: 1.8,
|
|
4178
|
-
* brightness: 1.0,
|
|
4179
|
-
* saturationBoost: 1.5
|
|
4180
|
-
* }}
|
|
4181
|
-
* >
|
|
4182
|
-
* <div>Content with custom overLight config</div>
|
|
4183
|
-
* </AtomixGlass>
|
|
4184
|
-
*
|
|
4185
|
-
* @example
|
|
4186
|
-
* // Debug mode for overLight detection
|
|
4187
|
-
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
4188
|
-
* <div>Content with debug logging enabled</div>
|
|
4189
|
-
* </AtomixGlass>
|
|
4190
|
-
*
|
|
4191
|
-
* @example
|
|
4192
|
-
* // Performance-optimized for mobile devices
|
|
4193
|
-
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
4194
|
-
* <div>Mobile-optimized glass effect</div>
|
|
4195
|
-
* </AtomixGlass>
|
|
4196
|
-
*/ 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}) {
|
|
4197
|
-
const glassRef = React.useRef(null), contentRef = React.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({
|
|
4086
|
+
}, AtomixGlassInner = React.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) {
|
|
4087
|
+
const glassRef = React.useRef(null), contentRef = React.useRef(null), internalWrapperRef = React.useRef(null), mergedRef = React.useMemo((() =>
|
|
4088
|
+
// Helper to merge refs
|
|
4089
|
+
function(...refs) {
|
|
4090
|
+
return node => {
|
|
4091
|
+
refs.forEach((ref => {
|
|
4092
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
4093
|
+
}));
|
|
4094
|
+
};
|
|
4095
|
+
}
|
|
4096
|
+
// Internal implementation with forwardRef
|
|
4097
|
+
(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({
|
|
4198
4098
|
glassRef: glassRef,
|
|
4199
4099
|
contentRef: contentRef,
|
|
4100
|
+
wrapperRef: internalWrapperRef,
|
|
4200
4101
|
borderRadius: borderRadius,
|
|
4201
4102
|
globalMousePosition: externalGlobalMousePosition,
|
|
4202
4103
|
mouseOffset: externalMouseOffset,
|
|
@@ -4225,7 +4126,6 @@ function getDevicePreset(presetName) {
|
|
|
4225
4126
|
distortionGain: distortionGain,
|
|
4226
4127
|
distortionQuality: distortionQuality
|
|
4227
4128
|
});
|
|
4228
|
-
// Re-calculate only when devicePreset changes
|
|
4229
4129
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
4230
4130
|
useResponsiveGlass({
|
|
4231
4131
|
baseParams: {
|
|
@@ -4240,22 +4140,21 @@ function getDevicePreset(presetName) {
|
|
|
4240
4140
|
},
|
|
4241
4141
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
4242
4142
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
4243
|
-
// Enable unless disabled
|
|
4244
4143
|
debug: !1
|
|
4245
4144
|
});
|
|
4246
4145
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
4247
|
-
const {metrics: performanceMetrics,
|
|
4248
|
-
enabled:
|
|
4249
|
-
//
|
|
4146
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} = usePerformanceMonitor({
|
|
4147
|
+
enabled: debugPerformance,
|
|
4148
|
+
// Enable when debugPerformance is true
|
|
4250
4149
|
debug: !1,
|
|
4251
4150
|
showOverlay: !1
|
|
4252
4151
|
});
|
|
4253
|
-
// Auto-start performance monitoring
|
|
4152
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
4254
4153
|
React__default.default.useEffect((() => {
|
|
4255
|
-
|
|
4154
|
+
debugPerformance && toggleMonitoring();
|
|
4256
4155
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4257
|
-
}), []);
|
|
4258
|
-
//
|
|
4156
|
+
}), [ debugPerformance ]);
|
|
4157
|
+
// Re-run when debugPerformance changes
|
|
4259
4158
|
const isOverLight = React.useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = React.useMemo((() => {
|
|
4260
4159
|
if (!isFixedOrSticky) return {};
|
|
4261
4160
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -4283,34 +4182,30 @@ function getDevicePreset(presetName) {
|
|
|
4283
4182
|
if (isFixedOrSticky) {
|
|
4284
4183
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
4285
4184
|
return {
|
|
4286
|
-
...visualStyle
|
|
4287
|
-
...!effectiveWithoutEffects && {
|
|
4288
|
-
transform: transformStyle
|
|
4289
|
-
}
|
|
4185
|
+
...visualStyle
|
|
4290
4186
|
};
|
|
4291
4187
|
}
|
|
4292
4188
|
return {
|
|
4293
|
-
...restStyle
|
|
4294
|
-
...!effectiveWithoutEffects && {
|
|
4295
|
-
transform: transformStyle
|
|
4296
|
-
}
|
|
4189
|
+
...restStyle
|
|
4297
4190
|
};
|
|
4298
|
-
}), [ isFixedOrSticky, restStyle
|
|
4191
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
4299
4192
|
// Build className with state modifiers
|
|
4300
4193
|
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 = React.useMemo((() => ({
|
|
4301
4194
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
4302
|
-
top: isFixedOrSticky ?
|
|
4303
|
-
left: isFixedOrSticky ?
|
|
4304
|
-
|
|
4195
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
4196
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
4197
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
4198
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
4199
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = React.useMemo((() => {
|
|
4305
4200
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
4306
4201
|
// but sizing is driven by explicit width/height or measured size.
|
|
4307
4202
|
positionStyles.position;
|
|
4308
|
-
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;
|
|
4203
|
+
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;
|
|
4309
4204
|
return {
|
|
4310
4205
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
4311
4206
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
4312
4207
|
};
|
|
4313
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = React.useMemo((() => {
|
|
4208
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = React.useMemo((() => {
|
|
4314
4209
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
4315
4210
|
return {
|
|
4316
4211
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -4340,33 +4235,32 @@ function getDevicePreset(presetName) {
|
|
|
4340
4235
|
absMx: absMx,
|
|
4341
4236
|
absMy: absMy
|
|
4342
4237
|
};
|
|
4343
|
-
}), [ mouseOffset.x, mouseOffset.y ]), opacityValues = React.useMemo((() => {
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
};
|
|
4352
|
-
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = React.useMemo((() => {
|
|
4353
|
-
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;
|
|
4238
|
+
}), [ 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 = React.useMemo((() => ({
|
|
4239
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
4240
|
+
hover2: isActive ? .5 : 0,
|
|
4241
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
4242
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
4243
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
4244
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = React.useMemo((() => {
|
|
4245
|
+
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;
|
|
4354
4246
|
return {
|
|
4355
4247
|
...void 0 !== customZIndex && {
|
|
4356
4248
|
"--atomix-glass-base-z-index": customZIndex
|
|
4357
4249
|
},
|
|
4358
4250
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
4359
4251
|
"--atomix-glass-transform": transformStyle || "none",
|
|
4360
|
-
|
|
4361
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
4362
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
4363
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
4252
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
4253
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
4254
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
4255
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
4256
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
4257
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
4364
4258
|
"--atomix-glass-width": adjustedSize.width,
|
|
4365
4259
|
"--atomix-glass-height": adjustedSize.height,
|
|
4366
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
4260
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
4367
4261
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
4368
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) *
|
|
4369
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) *
|
|
4262
|
+
"--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%)`,
|
|
4263
|
+
"--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%)`,
|
|
4370
4264
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
4371
4265
|
"--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}%)`,
|
|
4372
4266
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -4380,13 +4274,14 @@ function getDevicePreset(presetName) {
|
|
|
4380
4274
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
4381
4275
|
"--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}%)`
|
|
4382
4276
|
};
|
|
4383
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
4277
|
+
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, clampedBorderOpacity, customZIndex, isFixedOrSticky, positionStyles.position, rootLayoutStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), renderBackgroundLayer = layerType => jsxRuntime.jsx("div", {
|
|
4384
4278
|
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(" ")
|
|
4385
4279
|
});
|
|
4386
4280
|
// Calculate position and size styles for internal layers
|
|
4387
4281
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
4388
4282
|
return jsxRuntime.jsxs("div", {
|
|
4389
4283
|
...rest,
|
|
4284
|
+
ref: mergedRef,
|
|
4390
4285
|
className: componentClassName,
|
|
4391
4286
|
style: {
|
|
4392
4287
|
...glassVars
|
|
@@ -4396,17 +4291,14 @@ function getDevicePreset(presetName) {
|
|
|
4396
4291
|
"aria-label": ariaLabel,
|
|
4397
4292
|
"aria-describedby": ariaDescribedBy,
|
|
4398
4293
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
4399
|
-
"aria-pressed":
|
|
4294
|
+
"aria-pressed": void 0,
|
|
4400
4295
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
4401
4296
|
children: [ jsxRuntime.jsx(AtomixGlassContainer, {
|
|
4402
4297
|
ref: glassRef,
|
|
4403
4298
|
contentRef: contentRef,
|
|
4404
4299
|
className: className,
|
|
4405
4300
|
style: {
|
|
4406
|
-
...restStyle
|
|
4407
|
-
...!isFixedOrSticky && {
|
|
4408
|
-
position: "relative"
|
|
4409
|
-
}
|
|
4301
|
+
...restStyle
|
|
4410
4302
|
},
|
|
4411
4303
|
borderRadius: effectiveBorderRadius,
|
|
4412
4304
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -4442,6 +4334,7 @@ function getDevicePreset(presetName) {
|
|
|
4442
4334
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
4443
4335
|
shaderVariant: shaderVariant,
|
|
4444
4336
|
withLiquidBlur: withLiquidBlur,
|
|
4337
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
4445
4338
|
// Phase 1: Animation System props
|
|
4446
4339
|
shaderTime: getShaderTime(),
|
|
4447
4340
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -4470,6 +4363,8 @@ function getDevicePreset(presetName) {
|
|
|
4470
4363
|
}) ]
|
|
4471
4364
|
}), withBorder && jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
4472
4365
|
children: [ jsxRuntime.jsx("span", {
|
|
4366
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
4367
|
+
}), jsxRuntime.jsx("span", {
|
|
4473
4368
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
4474
4369
|
}), jsxRuntime.jsx("span", {
|
|
4475
4370
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -4480,10 +4375,15 @@ function getDevicePreset(presetName) {
|
|
|
4480
4375
|
onClose: () => {}
|
|
4481
4376
|
}) ]
|
|
4482
4377
|
});
|
|
4483
|
-
}
|
|
4378
|
+
}));
|
|
4484
4379
|
|
|
4485
|
-
|
|
4486
|
-
|
|
4380
|
+
AtomixGlassInner.displayName = "AtomixGlass";
|
|
4381
|
+
|
|
4382
|
+
/**
|
|
4383
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
4384
|
+
* Ref is forwarded to the root `<div>` element.
|
|
4385
|
+
*/
|
|
4386
|
+
const AtomixGlass = React.memo(AtomixGlassInner), DefaultIcon = () => jsxRuntime.jsx("i", {
|
|
4487
4387
|
className: "c-accordion__icon",
|
|
4488
4388
|
"aria-hidden": "true",
|
|
4489
4389
|
children: jsxRuntime.jsx("svg", {
|
|
@@ -4517,6 +4417,7 @@ const DefaultIcon = () => jsxRuntime.jsx("i", {
|
|
|
4517
4417
|
});
|
|
4518
4418
|
}));
|
|
4519
4419
|
|
|
4420
|
+
// Default icon
|
|
4520
4421
|
AccordionHeader.displayName = "AccordionHeader";
|
|
4521
4422
|
|
|
4522
4423
|
const AccordionBody = React.forwardRef((({children: children, className: className = "", panelRef: panelRef, contentRef: contentRef, ...props}, ref) => {
|