@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.esm.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, createContext, useContext, useImperativeHandle, Component } from "react";
|
|
4
4
|
|
|
5
5
|
import * as PhosphorIcons from "@phosphor-icons/react";
|
|
6
6
|
|
|
@@ -1695,6 +1695,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
1695
1695
|
FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
|
|
1696
1696
|
FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
|
|
1697
1697
|
CONTENT_CLASS: "c-atomix-glass__content",
|
|
1698
|
+
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
1698
1699
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
1699
1700
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
1700
1701
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
@@ -2097,7 +2098,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2097
2098
|
default:
|
|
2098
2099
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
2099
2100
|
}
|
|
2100
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
2101
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
2101
2102
|
style: {
|
|
2102
2103
|
position: "absolute",
|
|
2103
2104
|
width: "100%",
|
|
@@ -2238,24 +2239,17 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2238
2239
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
2239
2240
|
|
|
2240
2241
|
// Memoize component to prevent unnecessary re-renders
|
|
2241
|
-
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))
|
|
2242
|
-
|
|
2243
|
-
// Module-level counter for deterministic ID generation
|
|
2244
|
-
let idCounter = 0;
|
|
2245
|
-
|
|
2246
|
-
// Module-level shared shader cache with LRU eviction
|
|
2247
|
-
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 = {
|
|
2242
|
+
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 = {
|
|
2248
2243
|
x: 0,
|
|
2249
2244
|
y: 0
|
|
2250
2245
|
}, 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 = {
|
|
2251
2246
|
width: 0,
|
|
2252
2247
|
height: 0
|
|
2253
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
2248
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
2254
2249
|
// Phase 1: Animation System props
|
|
2255
2250
|
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) => {
|
|
2256
|
-
//
|
|
2257
|
-
|
|
2258
|
-
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);
|
|
2251
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
2252
|
+
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);
|
|
2259
2253
|
// Lazy load shader utilities only when shader mode is needed
|
|
2260
2254
|
useEffect((() => {
|
|
2261
2255
|
"shader" === mode ?
|
|
@@ -2278,9 +2272,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2278
2272
|
// Create cache key from size and variant
|
|
2279
2273
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
2280
2274
|
const entry = sharedShaderCache.get(key);
|
|
2281
|
-
return entry ? (
|
|
2282
|
-
// Update access timestamp for LRU
|
|
2283
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
2275
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
2284
2276
|
})(cacheKey);
|
|
2285
2277
|
// Check shared cache first
|
|
2286
2278
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -2291,29 +2283,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2291
2283
|
if (shaderUtilsRef.current) try {
|
|
2292
2284
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
2293
2285
|
shaderGeneratorRef.current?.destroy();
|
|
2294
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
2286
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
2295
2287
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
2296
2288
|
width: glassSize.width,
|
|
2297
2289
|
height: glassSize.height,
|
|
2298
2290
|
fragment: selectedShader
|
|
2299
2291
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
2300
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
2292
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
2301
2293
|
url && ((key, url) => {
|
|
2302
|
-
// Evict oldest entries if at capacity
|
|
2303
2294
|
if (sharedShaderCache.size >= 15) {
|
|
2304
2295
|
const entries = Array.from(sharedShaderCache.entries());
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
const oldestEntry = entries[0];
|
|
2309
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
2296
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
2297
|
+
const oldest = entries[0];
|
|
2298
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
2310
2299
|
}
|
|
2311
2300
|
sharedShaderCache.set(key, {
|
|
2312
2301
|
url: url,
|
|
2313
2302
|
timestamp: Date.now()
|
|
2314
|
-
}),
|
|
2315
|
-
// Development mode: log cache size
|
|
2316
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
2303
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
2317
2304
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
2318
2305
|
}), 100);
|
|
2319
2306
|
} catch (error) {
|
|
@@ -2382,7 +2369,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2382
2369
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
2383
2370
|
}
|
|
2384
2371
|
}), [ ref, glassSize ]);
|
|
2385
|
-
// Pre-calculate static multipliers outside useMemo
|
|
2386
2372
|
const liquidBlur = useMemo((() => {
|
|
2387
2373
|
const defaultBlur = {
|
|
2388
2374
|
baseBlur: blurAmount,
|
|
@@ -2451,7 +2437,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2451
2437
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
2452
2438
|
return jsx("div", {
|
|
2453
2439
|
ref: el => {
|
|
2454
|
-
// Apply force no-transition
|
|
2455
2440
|
// Handle forwarded ref
|
|
2456
2441
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
2457
2442
|
},
|
|
@@ -2493,6 +2478,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2493
2478
|
});
|
|
2494
2479
|
}));
|
|
2495
2480
|
|
|
2481
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
2496
2482
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
2497
2483
|
|
|
2498
2484
|
// Singleton instance
|
|
@@ -2693,8 +2679,6 @@ class {
|
|
|
2693
2679
|
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})`;
|
|
2694
2680
|
// Container variables
|
|
2695
2681
|
const style = containerElement.style;
|
|
2696
|
-
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
2697
|
-
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
2698
2682
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2699
2683
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2700
2684
|
// Shadows
|
|
@@ -3155,47 +3139,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3155
3139
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
3156
3140
|
}
|
|
3157
3141
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
3158
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null),
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
if (!container) return;
|
|
3163
|
-
// Use cached rect if available, otherwise get new one
|
|
3164
|
-
let rect = cachedRectRef.current;
|
|
3165
|
-
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
3166
|
-
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
3167
|
-
const center = calculateElementCenter(rect);
|
|
3168
|
-
// Write raw target — the lerp loop will smoothly pursue it
|
|
3169
|
-
targetMouseOffsetRef.current = {
|
|
3170
|
-
x: (globalPos.x - center.x) / rect.width * 100,
|
|
3171
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
3172
|
-
}, targetGlobalMousePositionRef.current = globalPos;
|
|
3173
|
-
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
|
|
3142
|
+
}), [ 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((() => {
|
|
3143
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
3144
|
+
lerpRafRef.current = null);
|
|
3145
|
+
}), []), startLerpLoop = useCallback((() => {
|
|
3174
3146
|
if (lerpActiveRef.current) return;
|
|
3175
3147
|
lerpActiveRef.current = !0;
|
|
3176
3148
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
3177
3149
|
if (!lerpActiveRef.current) return;
|
|
3178
|
-
|
|
3179
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
3150
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
3180
3151
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
3181
3152
|
// If we're close enough, snap and park
|
|
3182
|
-
if (Math.abs(dx) < .
|
|
3153
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
3183
3154
|
...tgt
|
|
3184
3155
|
}, internalGlobalMousePositionRef.current = {
|
|
3185
3156
|
...targetGlobalMousePositionRef.current
|
|
3186
|
-
}
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3157
|
+
},
|
|
3158
|
+
// Final update and stop
|
|
3159
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3160
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
3161
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3162
|
+
glassSize: glassSize,
|
|
3163
|
+
isHovered: isHovered,
|
|
3164
|
+
isActive: isActive,
|
|
3165
|
+
isOverLight: overLightConfig.isOverLight,
|
|
3166
|
+
baseOverLightConfig: overLightConfig,
|
|
3167
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
3168
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3169
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
3170
|
+
elasticity: elasticity,
|
|
3171
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
3172
|
+
onClick: onClick,
|
|
3173
|
+
withLiquidBlur: withLiquidBlur,
|
|
3174
|
+
blurAmount: blurAmount,
|
|
3175
|
+
saturation: saturation,
|
|
3176
|
+
padding: padding,
|
|
3177
|
+
isFixedOrSticky: isFixedOrSticky
|
|
3178
|
+
}), void stopLerpLoop();
|
|
3179
|
+
// Smooth step
|
|
3180
|
+
internalMouseOffsetRef.current = {
|
|
3181
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
3182
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
3183
|
+
};
|
|
3184
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
3185
|
+
internalGlobalMousePositionRef.current = {
|
|
3186
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
3187
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
3188
|
+
},
|
|
3189
|
+
// Imperative style update
|
|
3190
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3199
3191
|
mouseOffset: internalMouseOffsetRef.current,
|
|
3200
3192
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3201
3193
|
glassSize: glassSize,
|
|
@@ -3218,10 +3210,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3218
3210
|
};
|
|
3219
3211
|
// 0.08 – lower = more viscous
|
|
3220
3212
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
3221
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3213
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
3214
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3215
|
+
if (effectiveWithoutEffects) return;
|
|
3216
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
3217
|
+
if (!container) return;
|
|
3218
|
+
// Use cached rect if available, otherwise get new one
|
|
3219
|
+
let rect = cachedRectRef.current;
|
|
3220
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
3221
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
3222
|
+
const center = calculateElementCenter(rect);
|
|
3223
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
3224
|
+
targetMouseOffsetRef.current = {
|
|
3225
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
3226
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
3227
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
3228
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
3229
|
+
lerpActiveRef.current || startLerpLoop();
|
|
3230
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
3225
3231
|
/**
|
|
3226
3232
|
* Validate and clamp a numeric config value
|
|
3227
3233
|
*/
|
|
@@ -3230,7 +3236,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3230
3236
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3231
3237
|
if (effectiveWithoutEffects) return;
|
|
3232
3238
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
3233
|
-
//
|
|
3239
|
+
// Initial start
|
|
3234
3240
|
startLerpLoop();
|
|
3235
3241
|
const container = mouseContainer?.current || glassRef.current;
|
|
3236
3242
|
let resizeObserver = null;
|
|
@@ -3243,7 +3249,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3243
3249
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
3244
3250
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
3245
3251
|
};
|
|
3246
|
-
}), [
|
|
3252
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
3247
3253
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
3248
3254
|
useEffect((() => {
|
|
3249
3255
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -3738,183 +3744,146 @@ function usePerformanceMonitor(config = {}) {
|
|
|
3738
3744
|
}
|
|
3739
3745
|
}
|
|
3740
3746
|
|
|
3747
|
+
/** Map an FPS value to a semantic color token string. */ const getQualityColor = quality => {
|
|
3748
|
+
switch (quality) {
|
|
3749
|
+
case "high":
|
|
3750
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
3751
|
+
|
|
3752
|
+
case "medium":
|
|
3753
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
3754
|
+
|
|
3755
|
+
case "low":
|
|
3756
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
3757
|
+
|
|
3758
|
+
default:
|
|
3759
|
+
return "#9ca3af";
|
|
3760
|
+
}
|
|
3761
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
3762
|
+
|
|
3763
|
+
/** Map a quality level string to a semantic color token string. */
|
|
3764
|
+
// Inject keyframes once
|
|
3765
|
+
if ("undefined" != typeof document) {
|
|
3766
|
+
const styleId = "perf-dashboard-keyframes";
|
|
3767
|
+
if (!document.getElementById(styleId)) {
|
|
3768
|
+
const styleEl = document.createElement("style");
|
|
3769
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
3770
|
+
document.head.appendChild(styleEl);
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
|
|
3741
3774
|
/**
|
|
3742
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
3775
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
3743
3776
|
*
|
|
3744
|
-
* Displays
|
|
3745
|
-
*
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
3762
|
-
fontFamily: "monospace",
|
|
3763
|
-
fontSize: "12px",
|
|
3764
|
-
color: "#fff",
|
|
3765
|
-
zIndex: 9999,
|
|
3766
|
-
minWidth: "200px",
|
|
3767
|
-
backdropFilter: "blur(8px)",
|
|
3768
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3769
|
-
transition: "opacity 0.3s ease",
|
|
3770
|
-
opacity: isVisible ? 1 : 0,
|
|
3771
|
-
pointerEvents: isVisible ? "auto" : "none"
|
|
3772
|
-
})), [ isVisible ]), headerStyle = useMemo((() => ({
|
|
3773
|
-
display: "flex",
|
|
3774
|
-
justifyContent: "space-between",
|
|
3775
|
-
alignItems: "center",
|
|
3776
|
-
marginBottom: "8px",
|
|
3777
|
-
paddingBottom: "8px",
|
|
3778
|
-
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
3779
|
-
})), []), titleStyle = useMemo((() => ({
|
|
3780
|
-
fontWeight: "bold",
|
|
3781
|
-
fontSize: "13px",
|
|
3782
|
-
color: "#fff"
|
|
3783
|
-
})), []), closeButtonStyle = useMemo((() => ({
|
|
3784
|
-
background: "transparent",
|
|
3785
|
-
border: "none",
|
|
3786
|
-
color: "#9ca3af",
|
|
3787
|
-
cursor: "pointer",
|
|
3788
|
-
fontSize: "16px",
|
|
3789
|
-
padding: "0",
|
|
3790
|
-
lineHeight: "1"
|
|
3791
|
-
})), []), metricRowStyle = useMemo((() => ({
|
|
3792
|
-
display: "flex",
|
|
3793
|
-
justifyContent: "space-between",
|
|
3794
|
-
alignItems: "center",
|
|
3795
|
-
marginBottom: "6px"
|
|
3796
|
-
})), []), labelStyle = useMemo((() => ({
|
|
3797
|
-
color: "#9ca3af",
|
|
3798
|
-
marginRight: "12px"
|
|
3799
|
-
})), []), valueStyle = useMemo((() => ({
|
|
3800
|
-
fontWeight: "bold"
|
|
3801
|
-
})), []);
|
|
3802
|
-
// Get quality level badge color
|
|
3803
|
-
return isVisible ? jsxs("div", {
|
|
3804
|
-
style: dashboardStyle,
|
|
3777
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
3778
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
3779
|
+
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
3780
|
+
if (!isVisible) return null;
|
|
3781
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
3782
|
+
var fps;
|
|
3783
|
+
const isCritical = metrics.fps < 45;
|
|
3784
|
+
return jsxs("div", {
|
|
3785
|
+
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",
|
|
3786
|
+
style: {
|
|
3787
|
+
zIndex: 9999,
|
|
3788
|
+
minWidth: "12.5rem",
|
|
3789
|
+
// 200px
|
|
3790
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
3791
|
+
backdropFilter: "blur(8px)",
|
|
3792
|
+
transition: "opacity 0.3s ease"
|
|
3793
|
+
},
|
|
3805
3794
|
children: [ jsxs("div", {
|
|
3806
|
-
|
|
3795
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
3807
3796
|
children: [ jsx("span", {
|
|
3808
|
-
|
|
3797
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
3809
3798
|
children: "Performance Monitor"
|
|
3810
3799
|
}), onClose && jsx("button", {
|
|
3811
|
-
|
|
3800
|
+
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",
|
|
3812
3801
|
onClick: onClose,
|
|
3813
3802
|
"aria-label": "Close performance dashboard",
|
|
3803
|
+
style: {
|
|
3804
|
+
transition: "color 0.2s ease"
|
|
3805
|
+
},
|
|
3814
3806
|
children: "×"
|
|
3815
3807
|
}) ]
|
|
3816
3808
|
}), jsxs("div", {
|
|
3817
|
-
|
|
3809
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3818
3810
|
children: [ jsx("span", {
|
|
3819
|
-
|
|
3811
|
+
className: "u-text-gray-400 u-me-3",
|
|
3820
3812
|
children: "FPS"
|
|
3821
3813
|
}), jsx("span", {
|
|
3814
|
+
className: "u-font-bold",
|
|
3822
3815
|
style: {
|
|
3823
|
-
|
|
3824
|
-
color: getFpsColor(metrics.fps)
|
|
3816
|
+
color: fpsColor
|
|
3825
3817
|
},
|
|
3826
3818
|
children: Math.round(metrics.fps)
|
|
3827
3819
|
}) ]
|
|
3828
3820
|
}), jsxs("div", {
|
|
3829
|
-
|
|
3821
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3830
3822
|
children: [ jsx("span", {
|
|
3831
|
-
|
|
3823
|
+
className: "u-text-gray-400 u-me-3",
|
|
3832
3824
|
children: "Frame Time"
|
|
3833
3825
|
}), jsxs("span", {
|
|
3834
|
-
|
|
3826
|
+
className: "u-font-bold",
|
|
3835
3827
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
3836
3828
|
}) ]
|
|
3837
3829
|
}), jsxs("div", {
|
|
3838
|
-
|
|
3830
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3839
3831
|
children: [ jsx("span", {
|
|
3840
|
-
|
|
3832
|
+
className: "u-text-gray-400 u-me-3",
|
|
3841
3833
|
children: "Quality"
|
|
3842
3834
|
}), jsx("span", {
|
|
3835
|
+
className: "u-font-bold u-text-uppercase",
|
|
3843
3836
|
style: {
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
case "high":
|
|
3848
|
-
return "#4ade80";
|
|
3849
|
-
|
|
3850
|
-
case "medium":
|
|
3851
|
-
return "#fbbf24";
|
|
3852
|
-
|
|
3853
|
-
case "low":
|
|
3854
|
-
return "#ef4444";
|
|
3855
|
-
|
|
3856
|
-
default:
|
|
3857
|
-
return "#9ca3af";
|
|
3858
|
-
}
|
|
3859
|
-
})(metrics.qualityLevel),
|
|
3860
|
-
textTransform: "uppercase",
|
|
3861
|
-
fontSize: "11px"
|
|
3837
|
+
fontSize: "0.6875rem",
|
|
3838
|
+
// 11px
|
|
3839
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
3862
3840
|
},
|
|
3863
3841
|
children: metrics.qualityLevel
|
|
3864
3842
|
}) ]
|
|
3865
3843
|
}), metrics.gpuMemory && jsxs("div", {
|
|
3866
|
-
|
|
3844
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3867
3845
|
children: [ jsx("span", {
|
|
3868
|
-
|
|
3846
|
+
className: "u-text-gray-400 u-me-3",
|
|
3869
3847
|
children: "GPU Memory"
|
|
3870
3848
|
}), jsxs("span", {
|
|
3871
|
-
|
|
3849
|
+
className: "u-font-bold",
|
|
3872
3850
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
3873
3851
|
}) ]
|
|
3874
3852
|
}), metrics.isAutoScaling && jsx("div", {
|
|
3853
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
3875
3854
|
style: {
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
fontSize: "10px",
|
|
3880
|
-
color: "#6b7280",
|
|
3881
|
-
textAlign: "center"
|
|
3855
|
+
fontSize: "0.625rem",
|
|
3856
|
+
// 10px
|
|
3857
|
+
color: "#6b7280"
|
|
3882
3858
|
},
|
|
3883
3859
|
children: "Auto-scaling active"
|
|
3884
3860
|
}), jsxs("div", {
|
|
3885
|
-
|
|
3886
|
-
marginTop: "8px",
|
|
3887
|
-
paddingTop: "8px",
|
|
3888
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3889
|
-
display: "flex",
|
|
3890
|
-
alignItems: "center",
|
|
3891
|
-
gap: "6px"
|
|
3892
|
-
},
|
|
3861
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
3893
3862
|
children: [ jsx("div", {
|
|
3863
|
+
className: "u-rounded-full",
|
|
3894
3864
|
style: {
|
|
3895
|
-
width: "
|
|
3896
|
-
height: "
|
|
3897
|
-
|
|
3898
|
-
backgroundColor:
|
|
3899
|
-
|
|
3865
|
+
width: "0.5rem",
|
|
3866
|
+
height: "0.5rem",
|
|
3867
|
+
flexShrink: 0,
|
|
3868
|
+
backgroundColor: fpsColor,
|
|
3869
|
+
...isCritical && {
|
|
3870
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
3871
|
+
}
|
|
3900
3872
|
}
|
|
3901
3873
|
}), jsx("span", {
|
|
3874
|
+
className: "u-text-xs",
|
|
3902
3875
|
style: {
|
|
3903
|
-
fontSize: "
|
|
3904
|
-
|
|
3876
|
+
fontSize: "0.625rem",
|
|
3877
|
+
// 10px
|
|
3878
|
+
color: fpsColor
|
|
3905
3879
|
},
|
|
3906
|
-
children: metrics.fps
|
|
3880
|
+
children: getFpsLabel(metrics.fps)
|
|
3907
3881
|
}) ]
|
|
3908
3882
|
}) ]
|
|
3909
|
-
})
|
|
3910
|
-
};
|
|
3883
|
+
});
|
|
3884
|
+
}));
|
|
3911
3885
|
|
|
3912
|
-
|
|
3913
|
-
if ("undefined" != typeof document) {
|
|
3914
|
-
const styleSheet = document.createElement("style");
|
|
3915
|
-
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
3916
|
-
document.head.appendChild(styleSheet);
|
|
3917
|
-
}
|
|
3886
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
3918
3887
|
|
|
3919
3888
|
/**
|
|
3920
3889
|
* Mobile optimization presets
|
|
@@ -3925,7 +3894,8 @@ if ("undefined" != typeof document) {
|
|
|
3925
3894
|
/**
|
|
3926
3895
|
* Performance preset - Maximum FPS, reduced quality
|
|
3927
3896
|
* Best for low-end devices or when battery saving is priority
|
|
3928
|
-
*/
|
|
3897
|
+
*/
|
|
3898
|
+
const PERFORMANCE_PRESET = {
|
|
3929
3899
|
distortionOctaves: 2,
|
|
3930
3900
|
// Minimal FBM layers
|
|
3931
3901
|
displacementScale: 50,
|
|
@@ -4088,90 +4058,21 @@ function getDevicePreset(presetName) {
|
|
|
4088
4058
|
getPixelRatio: () => "undefined" == typeof window ? 1 : window.devicePixelRatio || 1,
|
|
4089
4059
|
/** Check if device has touch support */
|
|
4090
4060
|
hasTouchSupport: () => "undefined" != typeof window && ("ontouchstart" in window || navigator.maxTouchPoints > 0)
|
|
4091
|
-
}
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
* - Design token integration for consistent theming
|
|
4104
|
-
* - Focus ring support for keyboard navigation
|
|
4105
|
-
* - Responsive breakpoints for mobile optimization
|
|
4106
|
-
* - Enhanced ARIA attributes for screen readers
|
|
4107
|
-
* - Time-based animation system with FBM distortion
|
|
4108
|
-
* - Device preset optimization for performance/quality balance
|
|
4109
|
-
*
|
|
4110
|
-
* Design System Compliance:
|
|
4111
|
-
* - Uses design tokens for opacity, spacing, and colors
|
|
4112
|
-
* - Follows BEM methodology for class naming
|
|
4113
|
-
* - Implements focus-ring mixin for accessibility
|
|
4114
|
-
* - Supports reduced motion and high contrast preferences
|
|
4115
|
-
*
|
|
4116
|
-
* @example
|
|
4117
|
-
* // Basic usage with dynamic border-radius extraction
|
|
4118
|
-
* <AtomixGlass>
|
|
4119
|
-
* <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
|
|
4120
|
-
* </AtomixGlass>
|
|
4121
|
-
*
|
|
4122
|
-
* @example
|
|
4123
|
-
* // Manual border-radius override
|
|
4124
|
-
* <AtomixGlass borderRadius={20}>
|
|
4125
|
-
* <div>Content with 20px glass radius</div>
|
|
4126
|
-
* </AtomixGlass>
|
|
4127
|
-
*
|
|
4128
|
-
* @example
|
|
4129
|
-
* // Interactive glass with click handler
|
|
4130
|
-
* <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
|
|
4131
|
-
* <div>Clickable content</div>
|
|
4132
|
-
* </AtomixGlass>
|
|
4133
|
-
*
|
|
4134
|
-
* @example
|
|
4135
|
-
* // OverLight - Boolean mode (explicit control)
|
|
4136
|
-
* <AtomixGlass overLight={true}>
|
|
4137
|
-
* <div>Content on light background</div>
|
|
4138
|
-
* </AtomixGlass>
|
|
4139
|
-
*
|
|
4140
|
-
* @example
|
|
4141
|
-
* // OverLight - Auto-detection mode
|
|
4142
|
-
* <AtomixGlass overLight="auto">
|
|
4143
|
-
* <div>Content with auto-detected background</div>
|
|
4144
|
-
* </AtomixGlass>
|
|
4145
|
-
*
|
|
4146
|
-
* @example
|
|
4147
|
-
* // OverLight - Object config with custom settings
|
|
4148
|
-
* <AtomixGlass
|
|
4149
|
-
* overLight={{
|
|
4150
|
-
* threshold: 0.8,
|
|
4151
|
-
* opacity: 0.6,
|
|
4152
|
-
* contrast: 1.8,
|
|
4153
|
-
* brightness: 1.0,
|
|
4154
|
-
* saturationBoost: 1.5
|
|
4155
|
-
* }}
|
|
4156
|
-
* >
|
|
4157
|
-
* <div>Content with custom overLight config</div>
|
|
4158
|
-
* </AtomixGlass>
|
|
4159
|
-
*
|
|
4160
|
-
* @example
|
|
4161
|
-
* // Debug mode for overLight detection
|
|
4162
|
-
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
4163
|
-
* <div>Content with debug logging enabled</div>
|
|
4164
|
-
* </AtomixGlass>
|
|
4165
|
-
*
|
|
4166
|
-
* @example
|
|
4167
|
-
* // Performance-optimized for mobile devices
|
|
4168
|
-
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
4169
|
-
* <div>Mobile-optimized glass effect</div>
|
|
4170
|
-
* </AtomixGlass>
|
|
4171
|
-
*/ 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}) {
|
|
4172
|
-
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({
|
|
4061
|
+
}, 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) {
|
|
4062
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
|
|
4063
|
+
// Helper to merge refs
|
|
4064
|
+
function(...refs) {
|
|
4065
|
+
return node => {
|
|
4066
|
+
refs.forEach((ref => {
|
|
4067
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
4068
|
+
}));
|
|
4069
|
+
};
|
|
4070
|
+
}
|
|
4071
|
+
// Internal implementation with forwardRef
|
|
4072
|
+
(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({
|
|
4173
4073
|
glassRef: glassRef,
|
|
4174
4074
|
contentRef: contentRef,
|
|
4075
|
+
wrapperRef: internalWrapperRef,
|
|
4175
4076
|
borderRadius: borderRadius,
|
|
4176
4077
|
globalMousePosition: externalGlobalMousePosition,
|
|
4177
4078
|
mouseOffset: externalMouseOffset,
|
|
@@ -4200,7 +4101,6 @@ function getDevicePreset(presetName) {
|
|
|
4200
4101
|
distortionGain: distortionGain,
|
|
4201
4102
|
distortionQuality: distortionQuality
|
|
4202
4103
|
});
|
|
4203
|
-
// Re-calculate only when devicePreset changes
|
|
4204
4104
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
4205
4105
|
useResponsiveGlass({
|
|
4206
4106
|
baseParams: {
|
|
@@ -4215,22 +4115,21 @@ function getDevicePreset(presetName) {
|
|
|
4215
4115
|
},
|
|
4216
4116
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
4217
4117
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
4218
|
-
// Enable unless disabled
|
|
4219
4118
|
debug: !1
|
|
4220
4119
|
});
|
|
4221
4120
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
4222
|
-
const {metrics: performanceMetrics,
|
|
4223
|
-
enabled:
|
|
4224
|
-
//
|
|
4121
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} = usePerformanceMonitor({
|
|
4122
|
+
enabled: debugPerformance,
|
|
4123
|
+
// Enable when debugPerformance is true
|
|
4225
4124
|
debug: !1,
|
|
4226
4125
|
showOverlay: !1
|
|
4227
4126
|
});
|
|
4228
|
-
// Auto-start performance monitoring
|
|
4127
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
4229
4128
|
React.useEffect((() => {
|
|
4230
|
-
|
|
4129
|
+
debugPerformance && toggleMonitoring();
|
|
4231
4130
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4232
|
-
}), []);
|
|
4233
|
-
//
|
|
4131
|
+
}), [ debugPerformance ]);
|
|
4132
|
+
// Re-run when debugPerformance changes
|
|
4234
4133
|
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
4235
4134
|
if (!isFixedOrSticky) return {};
|
|
4236
4135
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -4258,34 +4157,30 @@ function getDevicePreset(presetName) {
|
|
|
4258
4157
|
if (isFixedOrSticky) {
|
|
4259
4158
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
4260
4159
|
return {
|
|
4261
|
-
...visualStyle
|
|
4262
|
-
...!effectiveWithoutEffects && {
|
|
4263
|
-
transform: transformStyle
|
|
4264
|
-
}
|
|
4160
|
+
...visualStyle
|
|
4265
4161
|
};
|
|
4266
4162
|
}
|
|
4267
4163
|
return {
|
|
4268
|
-
...restStyle
|
|
4269
|
-
...!effectiveWithoutEffects && {
|
|
4270
|
-
transform: transformStyle
|
|
4271
|
-
}
|
|
4164
|
+
...restStyle
|
|
4272
4165
|
};
|
|
4273
|
-
}), [ isFixedOrSticky, restStyle
|
|
4166
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
4274
4167
|
// Build className with state modifiers
|
|
4275
4168
|
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((() => ({
|
|
4276
4169
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
4277
|
-
top: isFixedOrSticky ?
|
|
4278
|
-
left: isFixedOrSticky ?
|
|
4279
|
-
|
|
4170
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
4171
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
4172
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
4173
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
4174
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
4280
4175
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
4281
4176
|
// but sizing is driven by explicit width/height or measured size.
|
|
4282
4177
|
positionStyles.position;
|
|
4283
|
-
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;
|
|
4178
|
+
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;
|
|
4284
4179
|
return {
|
|
4285
4180
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
4286
4181
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
4287
4182
|
};
|
|
4288
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
4183
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
|
|
4289
4184
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
4290
4185
|
return {
|
|
4291
4186
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -4315,33 +4210,32 @@ function getDevicePreset(presetName) {
|
|
|
4315
4210
|
absMx: absMx,
|
|
4316
4211
|
absMy: absMy
|
|
4317
4212
|
};
|
|
4318
|
-
}), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
};
|
|
4327
|
-
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
|
|
4328
|
-
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;
|
|
4213
|
+
}), [ 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((() => ({
|
|
4214
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
4215
|
+
hover2: isActive ? .5 : 0,
|
|
4216
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
4217
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
4218
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
4219
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
|
|
4220
|
+
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;
|
|
4329
4221
|
return {
|
|
4330
4222
|
...void 0 !== customZIndex && {
|
|
4331
4223
|
"--atomix-glass-base-z-index": customZIndex
|
|
4332
4224
|
},
|
|
4333
4225
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
4334
4226
|
"--atomix-glass-transform": transformStyle || "none",
|
|
4335
|
-
|
|
4336
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
4337
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
4338
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
4227
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
4228
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
4229
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
4230
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
4231
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
4232
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
4339
4233
|
"--atomix-glass-width": adjustedSize.width,
|
|
4340
4234
|
"--atomix-glass-height": adjustedSize.height,
|
|
4341
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
4235
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
4342
4236
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
4343
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) *
|
|
4344
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) *
|
|
4237
|
+
"--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%)`,
|
|
4238
|
+
"--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%)`,
|
|
4345
4239
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
4346
4240
|
"--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}%)`,
|
|
4347
4241
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -4355,13 +4249,14 @@ function getDevicePreset(presetName) {
|
|
|
4355
4249
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
4356
4250
|
"--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}%)`
|
|
4357
4251
|
};
|
|
4358
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
4252
|
+
}), [ 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", {
|
|
4359
4253
|
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(" ")
|
|
4360
4254
|
});
|
|
4361
4255
|
// Calculate position and size styles for internal layers
|
|
4362
4256
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
4363
4257
|
return jsxs("div", {
|
|
4364
4258
|
...rest,
|
|
4259
|
+
ref: mergedRef,
|
|
4365
4260
|
className: componentClassName,
|
|
4366
4261
|
style: {
|
|
4367
4262
|
...glassVars
|
|
@@ -4371,17 +4266,14 @@ function getDevicePreset(presetName) {
|
|
|
4371
4266
|
"aria-label": ariaLabel,
|
|
4372
4267
|
"aria-describedby": ariaDescribedBy,
|
|
4373
4268
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
4374
|
-
"aria-pressed":
|
|
4269
|
+
"aria-pressed": void 0,
|
|
4375
4270
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
4376
4271
|
children: [ jsx(AtomixGlassContainer, {
|
|
4377
4272
|
ref: glassRef,
|
|
4378
4273
|
contentRef: contentRef,
|
|
4379
4274
|
className: className,
|
|
4380
4275
|
style: {
|
|
4381
|
-
...restStyle
|
|
4382
|
-
...!isFixedOrSticky && {
|
|
4383
|
-
position: "relative"
|
|
4384
|
-
}
|
|
4276
|
+
...restStyle
|
|
4385
4277
|
},
|
|
4386
4278
|
borderRadius: effectiveBorderRadius,
|
|
4387
4279
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -4417,6 +4309,7 @@ function getDevicePreset(presetName) {
|
|
|
4417
4309
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
4418
4310
|
shaderVariant: shaderVariant,
|
|
4419
4311
|
withLiquidBlur: withLiquidBlur,
|
|
4312
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
4420
4313
|
// Phase 1: Animation System props
|
|
4421
4314
|
shaderTime: getShaderTime(),
|
|
4422
4315
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -4445,6 +4338,8 @@ function getDevicePreset(presetName) {
|
|
|
4445
4338
|
}) ]
|
|
4446
4339
|
}), withBorder && jsxs(Fragment, {
|
|
4447
4340
|
children: [ jsx("span", {
|
|
4341
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
4342
|
+
}), jsx("span", {
|
|
4448
4343
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
4449
4344
|
}), jsx("span", {
|
|
4450
4345
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -4455,10 +4350,15 @@ function getDevicePreset(presetName) {
|
|
|
4455
4350
|
onClose: () => {}
|
|
4456
4351
|
}) ]
|
|
4457
4352
|
});
|
|
4458
|
-
}
|
|
4353
|
+
}));
|
|
4459
4354
|
|
|
4460
|
-
|
|
4461
|
-
|
|
4355
|
+
AtomixGlassInner.displayName = "AtomixGlass";
|
|
4356
|
+
|
|
4357
|
+
/**
|
|
4358
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
4359
|
+
* Ref is forwarded to the root `<div>` element.
|
|
4360
|
+
*/
|
|
4361
|
+
const AtomixGlass = memo(AtomixGlassInner), DefaultIcon = () => jsx("i", {
|
|
4462
4362
|
className: "c-accordion__icon",
|
|
4463
4363
|
"aria-hidden": "true",
|
|
4464
4364
|
children: jsx("svg", {
|
|
@@ -4492,6 +4392,7 @@ const DefaultIcon = () => jsx("i", {
|
|
|
4492
4392
|
});
|
|
4493
4393
|
}));
|
|
4494
4394
|
|
|
4395
|
+
// Default icon
|
|
4495
4396
|
AccordionHeader.displayName = "AccordionHeader";
|
|
4496
4397
|
|
|
4497
4398
|
const AccordionBody = forwardRef((({children: children, className: className = "", panelRef: panelRef, contentRef: contentRef, ...props}, ref) => {
|