@shohojdhara/atomix 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atomix.css +95 -69
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.d.ts +1 -0
- package/dist/charts.js +231 -332
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +1 -0
- package/dist/core.js +232 -333
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +1 -0
- package/dist/forms.js +231 -332
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +11 -2
- package/dist/heavy.js +233 -334
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.esm.js +228 -327
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +227 -326
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +11 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +188 -128
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +62 -90
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +153 -201
- package/src/components/AtomixGlass/glass-utils.ts +50 -0
- package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +52 -46
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +573 -236
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +88 -41
- package/src/components/AtomixGlass/stories/argTypes.ts +19 -19
- package/src/components/AtomixGlass/stories/shared-components.tsx +7 -12
- package/src/components/AtomixGlass/stories/types.ts +3 -3
- package/src/lib/composables/useAtomixGlass.ts +108 -71
- package/src/lib/composables/useAtomixGlassStyles.ts +0 -2
- package/src/lib/constants/components.ts +1 -0
- package/src/lib/types/components.ts +1 -0
- package/src/lib/utils/displacement-generator.ts +1 -1
- package/src/styles/06-components/_components.atomix-glass.scss +158 -97
- package/scripts/cli/__tests__/README.md +0 -81
- package/scripts/cli/__tests__/basic.test.js +0 -116
- package/scripts/cli/__tests__/clean.test.js +0 -278
- package/scripts/cli/__tests__/component-generator.test.js +0 -332
- package/scripts/cli/__tests__/component-validator.test.js +0 -433
- package/scripts/cli/__tests__/generator.test.js +0 -613
- package/scripts/cli/__tests__/glass-motion.test.js +0 -256
- package/scripts/cli/__tests__/integration.test.js +0 -938
- package/scripts/cli/__tests__/migrate.test.js +0 -74
- package/scripts/cli/__tests__/security.test.js +0 -206
- package/scripts/cli/__tests__/test-setup.js +0 -135
- package/scripts/cli/__tests__/theme-bridge.test.js +0 -507
- package/scripts/cli/__tests__/token-manager.test.js +0 -251
- package/scripts/cli/__tests__/token-provider.test.js +0 -361
- package/scripts/cli/__tests__/utils.test.js +0 -165
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +0 -216
- package/src/components/AtomixGlass/stories/AnimationTests.stories.tsx +0 -95
- package/src/components/AtomixGlass/stories/CardExamples.stories.tsx +0 -212
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +0 -131
- package/src/components/AtomixGlass/stories/DashboardExamples.stories.tsx +0 -348
- package/src/components/AtomixGlass/stories/EcommerceExamples.stories.tsx +0 -410
- package/src/components/AtomixGlass/stories/FormExamples.stories.tsx +0 -436
- package/src/components/AtomixGlass/stories/HeroExamples.stories.tsx +0 -264
- package/src/components/AtomixGlass/stories/InteractivePlayground.stories.tsx +0 -247
- package/src/components/AtomixGlass/stories/MobileUIExamples.stories.tsx +0 -418
- package/src/components/AtomixGlass/stories/ModalExamples.stories.tsx +0 -402
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +0 -1082
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +0 -497
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +0 -103
- package/src/components/AtomixGlass/stories/PresetGallery.stories.tsx +0 -335
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +0 -395
- package/src/components/AtomixGlass/stories/WidgetExamples.stories.tsx +0 -441
- package/src/components/TypedButton/TypedButton.stories.tsx +0 -59
- package/src/components/TypedButton/TypedButton.tsx +0 -39
- package/src/components/TypedButton/index.ts +0 -2
- package/src/lib/composables/useTypedButton.ts +0 -66
package/dist/charts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
|
|
3
|
-
import React, { useState, useRef, useEffect, useCallback, useMemo, memo, forwardRef, createContext, useContext } from "react";
|
|
3
|
+
import React, { useState, useRef, useEffect, useCallback, useMemo, memo, forwardRef, useId, createContext, useContext } from "react";
|
|
4
4
|
|
|
5
5
|
import * as PhosphorIcons from "@phosphor-icons/react";
|
|
6
6
|
|
|
@@ -470,6 +470,7 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
470
470
|
FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
|
|
471
471
|
FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
|
|
472
472
|
CONTENT_CLASS: "c-atomix-glass__content",
|
|
473
|
+
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
473
474
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
474
475
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
475
476
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
@@ -1669,7 +1670,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1669
1670
|
default:
|
|
1670
1671
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
1671
1672
|
}
|
|
1672
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
1673
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
1673
1674
|
style: {
|
|
1674
1675
|
position: "absolute",
|
|
1675
1676
|
width: "100%",
|
|
@@ -1810,24 +1811,17 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1810
1811
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
1811
1812
|
|
|
1812
1813
|
// Memoize component to prevent unnecessary re-renders
|
|
1813
|
-
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))
|
|
1814
|
-
|
|
1815
|
-
// Module-level counter for deterministic ID generation
|
|
1816
|
-
let idCounter = 0;
|
|
1817
|
-
|
|
1818
|
-
// Module-level shared shader cache with LRU eviction
|
|
1819
|
-
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 = {
|
|
1814
|
+
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 = {
|
|
1820
1815
|
x: 0,
|
|
1821
1816
|
y: 0
|
|
1822
1817
|
}, 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 = {
|
|
1823
1818
|
width: 0,
|
|
1824
1819
|
height: 0
|
|
1825
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
1820
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
1826
1821
|
// Phase 1: Animation System props
|
|
1827
1822
|
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) => {
|
|
1828
|
-
//
|
|
1829
|
-
|
|
1830
|
-
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);
|
|
1823
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
1824
|
+
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);
|
|
1831
1825
|
// Lazy load shader utilities only when shader mode is needed
|
|
1832
1826
|
useEffect((() => {
|
|
1833
1827
|
"shader" === mode ?
|
|
@@ -1850,9 +1844,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1850
1844
|
// Create cache key from size and variant
|
|
1851
1845
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
1852
1846
|
const entry = sharedShaderCache.get(key);
|
|
1853
|
-
return entry ? (
|
|
1854
|
-
// Update access timestamp for LRU
|
|
1855
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
1847
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
1856
1848
|
})(cacheKey);
|
|
1857
1849
|
// Check shared cache first
|
|
1858
1850
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -1863,29 +1855,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1863
1855
|
if (shaderUtilsRef.current) try {
|
|
1864
1856
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
1865
1857
|
shaderGeneratorRef.current?.destroy();
|
|
1866
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
1858
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
1867
1859
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
1868
1860
|
width: glassSize.width,
|
|
1869
1861
|
height: glassSize.height,
|
|
1870
1862
|
fragment: selectedShader
|
|
1871
1863
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
1872
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
1864
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
1873
1865
|
url && ((key, url) => {
|
|
1874
|
-
// Evict oldest entries if at capacity
|
|
1875
1866
|
if (sharedShaderCache.size >= 15) {
|
|
1876
1867
|
const entries = Array.from(sharedShaderCache.entries());
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
const oldestEntry = entries[0];
|
|
1881
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
1868
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
1869
|
+
const oldest = entries[0];
|
|
1870
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
1882
1871
|
}
|
|
1883
1872
|
sharedShaderCache.set(key, {
|
|
1884
1873
|
url: url,
|
|
1885
1874
|
timestamp: Date.now()
|
|
1886
|
-
}),
|
|
1887
|
-
// Development mode: log cache size
|
|
1888
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
1875
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
1889
1876
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
1890
1877
|
}), 100);
|
|
1891
1878
|
} catch (error) {
|
|
@@ -1954,7 +1941,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1954
1941
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
1955
1942
|
}
|
|
1956
1943
|
}), [ ref, glassSize ]);
|
|
1957
|
-
// Pre-calculate static multipliers outside useMemo
|
|
1958
1944
|
const liquidBlur = useMemo((() => {
|
|
1959
1945
|
const defaultBlur = {
|
|
1960
1946
|
baseBlur: blurAmount,
|
|
@@ -2023,7 +2009,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2023
2009
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
2024
2010
|
return jsx("div", {
|
|
2025
2011
|
ref: el => {
|
|
2026
|
-
// Apply force no-transition
|
|
2027
2012
|
// Handle forwarded ref
|
|
2028
2013
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
2029
2014
|
},
|
|
@@ -2065,6 +2050,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2065
2050
|
});
|
|
2066
2051
|
}));
|
|
2067
2052
|
|
|
2053
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
2068
2054
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
2069
2055
|
|
|
2070
2056
|
// Singleton instance
|
|
@@ -2265,8 +2251,6 @@ class {
|
|
|
2265
2251
|
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})`;
|
|
2266
2252
|
// Container variables
|
|
2267
2253
|
const style = containerElement.style;
|
|
2268
|
-
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
2269
|
-
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
2270
2254
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2271
2255
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2272
2256
|
// Shadows
|
|
@@ -2727,47 +2711,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2727
2711
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
2728
2712
|
}
|
|
2729
2713
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
2730
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null),
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
if (!container) return;
|
|
2735
|
-
// Use cached rect if available, otherwise get new one
|
|
2736
|
-
let rect = cachedRectRef.current;
|
|
2737
|
-
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
2738
|
-
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
2739
|
-
const center = calculateElementCenter(rect);
|
|
2740
|
-
// Write raw target — the lerp loop will smoothly pursue it
|
|
2741
|
-
targetMouseOffsetRef.current = {
|
|
2742
|
-
x: (globalPos.x - center.x) / rect.width * 100,
|
|
2743
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
2744
|
-
}, targetGlobalMousePositionRef.current = globalPos;
|
|
2745
|
-
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
|
|
2714
|
+
}), [ 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((() => {
|
|
2715
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
2716
|
+
lerpRafRef.current = null);
|
|
2717
|
+
}), []), startLerpLoop = useCallback((() => {
|
|
2746
2718
|
if (lerpActiveRef.current) return;
|
|
2747
2719
|
lerpActiveRef.current = !0;
|
|
2748
2720
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
2749
2721
|
if (!lerpActiveRef.current) return;
|
|
2750
|
-
|
|
2751
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
2722
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
2752
2723
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
2753
2724
|
// If we're close enough, snap and park
|
|
2754
|
-
if (Math.abs(dx) < .
|
|
2725
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
2755
2726
|
...tgt
|
|
2756
2727
|
}, internalGlobalMousePositionRef.current = {
|
|
2757
2728
|
...targetGlobalMousePositionRef.current
|
|
2758
|
-
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2729
|
+
},
|
|
2730
|
+
// Final update and stop
|
|
2731
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2732
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
2733
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2734
|
+
glassSize: glassSize,
|
|
2735
|
+
isHovered: isHovered,
|
|
2736
|
+
isActive: isActive,
|
|
2737
|
+
isOverLight: overLightConfig.isOverLight,
|
|
2738
|
+
baseOverLightConfig: overLightConfig,
|
|
2739
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
2740
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2741
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
2742
|
+
elasticity: elasticity,
|
|
2743
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
2744
|
+
onClick: onClick,
|
|
2745
|
+
withLiquidBlur: withLiquidBlur,
|
|
2746
|
+
blurAmount: blurAmount,
|
|
2747
|
+
saturation: saturation,
|
|
2748
|
+
padding: padding,
|
|
2749
|
+
isFixedOrSticky: isFixedOrSticky
|
|
2750
|
+
}), void stopLerpLoop();
|
|
2751
|
+
// Smooth step
|
|
2752
|
+
internalMouseOffsetRef.current = {
|
|
2753
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
2754
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
2755
|
+
};
|
|
2756
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
2757
|
+
internalGlobalMousePositionRef.current = {
|
|
2758
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
2759
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
2760
|
+
},
|
|
2761
|
+
// Imperative style update
|
|
2762
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2771
2763
|
mouseOffset: internalMouseOffsetRef.current,
|
|
2772
2764
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2773
2765
|
glassSize: glassSize,
|
|
@@ -2790,10 +2782,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2790
2782
|
};
|
|
2791
2783
|
// 0.08 – lower = more viscous
|
|
2792
2784
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
2793
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2785
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
2786
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2787
|
+
if (effectiveWithoutEffects) return;
|
|
2788
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
2789
|
+
if (!container) return;
|
|
2790
|
+
// Use cached rect if available, otherwise get new one
|
|
2791
|
+
let rect = cachedRectRef.current;
|
|
2792
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
2793
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
2794
|
+
const center = calculateElementCenter(rect);
|
|
2795
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
2796
|
+
targetMouseOffsetRef.current = {
|
|
2797
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
2798
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
2799
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
2800
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
2801
|
+
lerpActiveRef.current || startLerpLoop();
|
|
2802
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
2797
2803
|
/**
|
|
2798
2804
|
* Validate and clamp a numeric config value
|
|
2799
2805
|
*/
|
|
@@ -2802,7 +2808,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2802
2808
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2803
2809
|
if (effectiveWithoutEffects) return;
|
|
2804
2810
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
2805
|
-
//
|
|
2811
|
+
// Initial start
|
|
2806
2812
|
startLerpLoop();
|
|
2807
2813
|
const container = mouseContainer?.current || glassRef.current;
|
|
2808
2814
|
let resizeObserver = null;
|
|
@@ -2815,7 +2821,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2815
2821
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
2816
2822
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
2817
2823
|
};
|
|
2818
|
-
}), [
|
|
2824
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
2819
2825
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
2820
2826
|
useEffect((() => {
|
|
2821
2827
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -3007,184 +3013,147 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
3007
3013
|
/**
|
|
3008
3014
|
* Get GPU memory info if available (Chrome DevTools only)
|
|
3009
3015
|
*/
|
|
3016
|
+
/** Map an FPS value to a semantic color token string. */
|
|
3017
|
+
const getQualityColor = quality => {
|
|
3018
|
+
switch (quality) {
|
|
3019
|
+
case "high":
|
|
3020
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
3021
|
+
|
|
3022
|
+
case "medium":
|
|
3023
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
3024
|
+
|
|
3025
|
+
case "low":
|
|
3026
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
3027
|
+
|
|
3028
|
+
default:
|
|
3029
|
+
return "#9ca3af";
|
|
3030
|
+
}
|
|
3031
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
3032
|
+
|
|
3033
|
+
/** Map a quality level string to a semantic color token string. */
|
|
3034
|
+
// Inject keyframes once
|
|
3035
|
+
if ("undefined" != typeof document) {
|
|
3036
|
+
const styleId = "perf-dashboard-keyframes";
|
|
3037
|
+
if (!document.getElementById(styleId)) {
|
|
3038
|
+
const styleEl = document.createElement("style");
|
|
3039
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
3040
|
+
document.head.appendChild(styleEl);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3010
3044
|
/**
|
|
3011
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
3045
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
3012
3046
|
*
|
|
3013
|
-
* Displays
|
|
3014
|
-
*
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
borderRadius: "8px",
|
|
3031
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
3032
|
-
fontFamily: "monospace",
|
|
3033
|
-
fontSize: "12px",
|
|
3034
|
-
color: "#fff",
|
|
3035
|
-
zIndex: 9999,
|
|
3036
|
-
minWidth: "200px",
|
|
3037
|
-
backdropFilter: "blur(8px)",
|
|
3038
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3039
|
-
transition: "opacity 0.3s ease",
|
|
3040
|
-
opacity: isVisible ? 1 : 0,
|
|
3041
|
-
pointerEvents: isVisible ? "auto" : "none"
|
|
3042
|
-
})), [ isVisible ]), headerStyle = useMemo((() => ({
|
|
3043
|
-
display: "flex",
|
|
3044
|
-
justifyContent: "space-between",
|
|
3045
|
-
alignItems: "center",
|
|
3046
|
-
marginBottom: "8px",
|
|
3047
|
-
paddingBottom: "8px",
|
|
3048
|
-
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
3049
|
-
})), []), titleStyle = useMemo((() => ({
|
|
3050
|
-
fontWeight: "bold",
|
|
3051
|
-
fontSize: "13px",
|
|
3052
|
-
color: "#fff"
|
|
3053
|
-
})), []), closeButtonStyle = useMemo((() => ({
|
|
3054
|
-
background: "transparent",
|
|
3055
|
-
border: "none",
|
|
3056
|
-
color: "#9ca3af",
|
|
3057
|
-
cursor: "pointer",
|
|
3058
|
-
fontSize: "16px",
|
|
3059
|
-
padding: "0",
|
|
3060
|
-
lineHeight: "1"
|
|
3061
|
-
})), []), metricRowStyle = useMemo((() => ({
|
|
3062
|
-
display: "flex",
|
|
3063
|
-
justifyContent: "space-between",
|
|
3064
|
-
alignItems: "center",
|
|
3065
|
-
marginBottom: "6px"
|
|
3066
|
-
})), []), labelStyle = useMemo((() => ({
|
|
3067
|
-
color: "#9ca3af",
|
|
3068
|
-
marginRight: "12px"
|
|
3069
|
-
})), []), valueStyle = useMemo((() => ({
|
|
3070
|
-
fontWeight: "bold"
|
|
3071
|
-
})), []);
|
|
3072
|
-
// Get quality level badge color
|
|
3073
|
-
return isVisible ? jsxs("div", {
|
|
3074
|
-
style: dashboardStyle,
|
|
3047
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
3048
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
3049
|
+
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
3050
|
+
if (!isVisible) return null;
|
|
3051
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
3052
|
+
var fps;
|
|
3053
|
+
const isCritical = metrics.fps < 45;
|
|
3054
|
+
return jsxs("div", {
|
|
3055
|
+
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",
|
|
3056
|
+
style: {
|
|
3057
|
+
zIndex: 9999,
|
|
3058
|
+
minWidth: "12.5rem",
|
|
3059
|
+
// 200px
|
|
3060
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
3061
|
+
backdropFilter: "blur(8px)",
|
|
3062
|
+
transition: "opacity 0.3s ease"
|
|
3063
|
+
},
|
|
3075
3064
|
children: [ jsxs("div", {
|
|
3076
|
-
|
|
3065
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
3077
3066
|
children: [ jsx("span", {
|
|
3078
|
-
|
|
3067
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
3079
3068
|
children: "Performance Monitor"
|
|
3080
3069
|
}), onClose && jsx("button", {
|
|
3081
|
-
|
|
3070
|
+
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",
|
|
3082
3071
|
onClick: onClose,
|
|
3083
3072
|
"aria-label": "Close performance dashboard",
|
|
3073
|
+
style: {
|
|
3074
|
+
transition: "color 0.2s ease"
|
|
3075
|
+
},
|
|
3084
3076
|
children: "×"
|
|
3085
3077
|
}) ]
|
|
3086
3078
|
}), jsxs("div", {
|
|
3087
|
-
|
|
3079
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3088
3080
|
children: [ jsx("span", {
|
|
3089
|
-
|
|
3081
|
+
className: "u-text-gray-400 u-me-3",
|
|
3090
3082
|
children: "FPS"
|
|
3091
3083
|
}), jsx("span", {
|
|
3084
|
+
className: "u-font-bold",
|
|
3092
3085
|
style: {
|
|
3093
|
-
|
|
3094
|
-
color: getFpsColor(metrics.fps)
|
|
3086
|
+
color: fpsColor
|
|
3095
3087
|
},
|
|
3096
3088
|
children: Math.round(metrics.fps)
|
|
3097
3089
|
}) ]
|
|
3098
3090
|
}), jsxs("div", {
|
|
3099
|
-
|
|
3091
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3100
3092
|
children: [ jsx("span", {
|
|
3101
|
-
|
|
3093
|
+
className: "u-text-gray-400 u-me-3",
|
|
3102
3094
|
children: "Frame Time"
|
|
3103
3095
|
}), jsxs("span", {
|
|
3104
|
-
|
|
3096
|
+
className: "u-font-bold",
|
|
3105
3097
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
3106
3098
|
}) ]
|
|
3107
3099
|
}), jsxs("div", {
|
|
3108
|
-
|
|
3100
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3109
3101
|
children: [ jsx("span", {
|
|
3110
|
-
|
|
3102
|
+
className: "u-text-gray-400 u-me-3",
|
|
3111
3103
|
children: "Quality"
|
|
3112
3104
|
}), jsx("span", {
|
|
3105
|
+
className: "u-font-bold u-text-uppercase",
|
|
3113
3106
|
style: {
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
case "high":
|
|
3118
|
-
return "#4ade80";
|
|
3119
|
-
|
|
3120
|
-
case "medium":
|
|
3121
|
-
return "#fbbf24";
|
|
3122
|
-
|
|
3123
|
-
case "low":
|
|
3124
|
-
return "#ef4444";
|
|
3125
|
-
|
|
3126
|
-
default:
|
|
3127
|
-
return "#9ca3af";
|
|
3128
|
-
}
|
|
3129
|
-
})(metrics.qualityLevel),
|
|
3130
|
-
textTransform: "uppercase",
|
|
3131
|
-
fontSize: "11px"
|
|
3107
|
+
fontSize: "0.6875rem",
|
|
3108
|
+
// 11px
|
|
3109
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
3132
3110
|
},
|
|
3133
3111
|
children: metrics.qualityLevel
|
|
3134
3112
|
}) ]
|
|
3135
3113
|
}), metrics.gpuMemory && jsxs("div", {
|
|
3136
|
-
|
|
3114
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3137
3115
|
children: [ jsx("span", {
|
|
3138
|
-
|
|
3116
|
+
className: "u-text-gray-400 u-me-3",
|
|
3139
3117
|
children: "GPU Memory"
|
|
3140
3118
|
}), jsxs("span", {
|
|
3141
|
-
|
|
3119
|
+
className: "u-font-bold",
|
|
3142
3120
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
3143
3121
|
}) ]
|
|
3144
3122
|
}), metrics.isAutoScaling && jsx("div", {
|
|
3123
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
3145
3124
|
style: {
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
fontSize: "10px",
|
|
3150
|
-
color: "#6b7280",
|
|
3151
|
-
textAlign: "center"
|
|
3125
|
+
fontSize: "0.625rem",
|
|
3126
|
+
// 10px
|
|
3127
|
+
color: "#6b7280"
|
|
3152
3128
|
},
|
|
3153
3129
|
children: "Auto-scaling active"
|
|
3154
3130
|
}), jsxs("div", {
|
|
3155
|
-
|
|
3156
|
-
marginTop: "8px",
|
|
3157
|
-
paddingTop: "8px",
|
|
3158
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3159
|
-
display: "flex",
|
|
3160
|
-
alignItems: "center",
|
|
3161
|
-
gap: "6px"
|
|
3162
|
-
},
|
|
3131
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
3163
3132
|
children: [ jsx("div", {
|
|
3133
|
+
className: "u-rounded-full",
|
|
3164
3134
|
style: {
|
|
3165
|
-
width: "
|
|
3166
|
-
height: "
|
|
3167
|
-
|
|
3168
|
-
backgroundColor:
|
|
3169
|
-
|
|
3135
|
+
width: "0.5rem",
|
|
3136
|
+
height: "0.5rem",
|
|
3137
|
+
flexShrink: 0,
|
|
3138
|
+
backgroundColor: fpsColor,
|
|
3139
|
+
...isCritical && {
|
|
3140
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
3141
|
+
}
|
|
3170
3142
|
}
|
|
3171
3143
|
}), jsx("span", {
|
|
3144
|
+
className: "u-text-xs",
|
|
3172
3145
|
style: {
|
|
3173
|
-
fontSize: "
|
|
3174
|
-
|
|
3146
|
+
fontSize: "0.625rem",
|
|
3147
|
+
// 10px
|
|
3148
|
+
color: fpsColor
|
|
3175
3149
|
},
|
|
3176
|
-
children: metrics.fps
|
|
3150
|
+
children: getFpsLabel(metrics.fps)
|
|
3177
3151
|
}) ]
|
|
3178
3152
|
}) ]
|
|
3179
|
-
})
|
|
3180
|
-
};
|
|
3153
|
+
});
|
|
3154
|
+
}));
|
|
3181
3155
|
|
|
3182
|
-
|
|
3183
|
-
if ("undefined" != typeof document) {
|
|
3184
|
-
const styleSheet = document.createElement("style");
|
|
3185
|
-
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
3186
|
-
document.head.appendChild(styleSheet);
|
|
3187
|
-
}
|
|
3156
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
3188
3157
|
|
|
3189
3158
|
/**
|
|
3190
3159
|
* Mobile optimization presets
|
|
@@ -3195,7 +3164,8 @@ if ("undefined" != typeof document) {
|
|
|
3195
3164
|
/**
|
|
3196
3165
|
* Performance preset - Maximum FPS, reduced quality
|
|
3197
3166
|
* Best for low-end devices or when battery saving is priority
|
|
3198
|
-
*/
|
|
3167
|
+
*/
|
|
3168
|
+
const PERFORMANCE_PRESET = {
|
|
3199
3169
|
distortionOctaves: 2,
|
|
3200
3170
|
// Minimal FBM layers
|
|
3201
3171
|
displacementScale: 50,
|
|
@@ -3304,95 +3274,21 @@ if ("undefined" != typeof document) {
|
|
|
3304
3274
|
saturation: 70
|
|
3305
3275
|
}
|
|
3306
3276
|
}
|
|
3307
|
-
}
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
* - Dynamic border-radius extraction from children CSS properties
|
|
3320
|
-
* - Automatic light/dark theme detection via overLight prop
|
|
3321
|
-
* - Accessibility and performance optimizations
|
|
3322
|
-
* - Multiple displacement modes (standard, polar, prominent, shader)
|
|
3323
|
-
* - Design token integration for consistent theming
|
|
3324
|
-
* - Focus ring support for keyboard navigation
|
|
3325
|
-
* - Responsive breakpoints for mobile optimization
|
|
3326
|
-
* - Enhanced ARIA attributes for screen readers
|
|
3327
|
-
* - Time-based animation system with FBM distortion
|
|
3328
|
-
* - Device preset optimization for performance/quality balance
|
|
3329
|
-
*
|
|
3330
|
-
* Design System Compliance:
|
|
3331
|
-
* - Uses design tokens for opacity, spacing, and colors
|
|
3332
|
-
* - Follows BEM methodology for class naming
|
|
3333
|
-
* - Implements focus-ring mixin for accessibility
|
|
3334
|
-
* - Supports reduced motion and high contrast preferences
|
|
3335
|
-
*
|
|
3336
|
-
* @example
|
|
3337
|
-
* // Basic usage with dynamic border-radius extraction
|
|
3338
|
-
* <AtomixGlass>
|
|
3339
|
-
* <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
|
|
3340
|
-
* </AtomixGlass>
|
|
3341
|
-
*
|
|
3342
|
-
* @example
|
|
3343
|
-
* // Manual border-radius override
|
|
3344
|
-
* <AtomixGlass borderRadius={20}>
|
|
3345
|
-
* <div>Content with 20px glass radius</div>
|
|
3346
|
-
* </AtomixGlass>
|
|
3347
|
-
*
|
|
3348
|
-
* @example
|
|
3349
|
-
* // Interactive glass with click handler
|
|
3350
|
-
* <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
|
|
3351
|
-
* <div>Clickable content</div>
|
|
3352
|
-
* </AtomixGlass>
|
|
3353
|
-
*
|
|
3354
|
-
* @example
|
|
3355
|
-
* // OverLight - Boolean mode (explicit control)
|
|
3356
|
-
* <AtomixGlass overLight={true}>
|
|
3357
|
-
* <div>Content on light background</div>
|
|
3358
|
-
* </AtomixGlass>
|
|
3359
|
-
*
|
|
3360
|
-
* @example
|
|
3361
|
-
* // OverLight - Auto-detection mode
|
|
3362
|
-
* <AtomixGlass overLight="auto">
|
|
3363
|
-
* <div>Content with auto-detected background</div>
|
|
3364
|
-
* </AtomixGlass>
|
|
3365
|
-
*
|
|
3366
|
-
* @example
|
|
3367
|
-
* // OverLight - Object config with custom settings
|
|
3368
|
-
* <AtomixGlass
|
|
3369
|
-
* overLight={{
|
|
3370
|
-
* threshold: 0.8,
|
|
3371
|
-
* opacity: 0.6,
|
|
3372
|
-
* contrast: 1.8,
|
|
3373
|
-
* brightness: 1.0,
|
|
3374
|
-
* saturationBoost: 1.5
|
|
3375
|
-
* }}
|
|
3376
|
-
* >
|
|
3377
|
-
* <div>Content with custom overLight config</div>
|
|
3378
|
-
* </AtomixGlass>
|
|
3379
|
-
*
|
|
3380
|
-
* @example
|
|
3381
|
-
* // Debug mode for overLight detection
|
|
3382
|
-
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
3383
|
-
* <div>Content with debug logging enabled</div>
|
|
3384
|
-
* </AtomixGlass>
|
|
3385
|
-
*
|
|
3386
|
-
* @example
|
|
3387
|
-
* // Performance-optimized for mobile devices
|
|
3388
|
-
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
3389
|
-
* <div>Mobile-optimized glass effect</div>
|
|
3390
|
-
* </AtomixGlass>
|
|
3391
|
-
*/
|
|
3392
|
-
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}) {
|
|
3393
|
-
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({
|
|
3277
|
+
}, 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) {
|
|
3278
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
|
|
3279
|
+
// Helper to merge refs
|
|
3280
|
+
function(...refs) {
|
|
3281
|
+
return node => {
|
|
3282
|
+
refs.forEach((ref => {
|
|
3283
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
3284
|
+
}));
|
|
3285
|
+
};
|
|
3286
|
+
}
|
|
3287
|
+
// Internal implementation with forwardRef
|
|
3288
|
+
(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({
|
|
3394
3289
|
glassRef: glassRef,
|
|
3395
3290
|
contentRef: contentRef,
|
|
3291
|
+
wrapperRef: internalWrapperRef,
|
|
3396
3292
|
borderRadius: borderRadius,
|
|
3397
3293
|
globalMousePosition: externalGlobalMousePosition,
|
|
3398
3294
|
mouseOffset: externalMouseOffset,
|
|
@@ -3421,7 +3317,6 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3421
3317
|
distortionGain: distortionGain,
|
|
3422
3318
|
distortionQuality: distortionQuality
|
|
3423
3319
|
});
|
|
3424
|
-
// Re-calculate only when devicePreset changes
|
|
3425
3320
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
3426
3321
|
!
|
|
3427
3322
|
/**
|
|
@@ -3611,11 +3506,10 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3611
3506
|
},
|
|
3612
3507
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
3613
3508
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
3614
|
-
// Enable unless disabled
|
|
3615
3509
|
debug: !1
|
|
3616
3510
|
});
|
|
3617
3511
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
3618
|
-
const {metrics: performanceMetrics,
|
|
3512
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
|
|
3619
3513
|
/**
|
|
3620
3514
|
* Performance Monitor Hook
|
|
3621
3515
|
*
|
|
@@ -3779,17 +3673,17 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3779
3673
|
toggleMonitoring: toggleMonitoring
|
|
3780
3674
|
};
|
|
3781
3675
|
}({
|
|
3782
|
-
enabled:
|
|
3783
|
-
//
|
|
3676
|
+
enabled: debugPerformance,
|
|
3677
|
+
// Enable when debugPerformance is true
|
|
3784
3678
|
debug: !1,
|
|
3785
3679
|
showOverlay: !1
|
|
3786
3680
|
});
|
|
3787
|
-
// Auto-start performance monitoring
|
|
3681
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
3788
3682
|
React.useEffect((() => {
|
|
3789
|
-
|
|
3683
|
+
debugPerformance && toggleMonitoring();
|
|
3790
3684
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3791
|
-
}), []);
|
|
3792
|
-
//
|
|
3685
|
+
}), [ debugPerformance ]);
|
|
3686
|
+
// Re-run when debugPerformance changes
|
|
3793
3687
|
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
3794
3688
|
if (!isFixedOrSticky) return {};
|
|
3795
3689
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -3817,34 +3711,30 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3817
3711
|
if (isFixedOrSticky) {
|
|
3818
3712
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
3819
3713
|
return {
|
|
3820
|
-
...visualStyle
|
|
3821
|
-
...!effectiveWithoutEffects && {
|
|
3822
|
-
transform: transformStyle
|
|
3823
|
-
}
|
|
3714
|
+
...visualStyle
|
|
3824
3715
|
};
|
|
3825
3716
|
}
|
|
3826
3717
|
return {
|
|
3827
|
-
...restStyle
|
|
3828
|
-
...!effectiveWithoutEffects && {
|
|
3829
|
-
transform: transformStyle
|
|
3830
|
-
}
|
|
3718
|
+
...restStyle
|
|
3831
3719
|
};
|
|
3832
|
-
}), [ isFixedOrSticky, restStyle
|
|
3720
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
3833
3721
|
// Build className with state modifiers
|
|
3834
3722
|
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((() => ({
|
|
3835
3723
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
3836
|
-
top: isFixedOrSticky ?
|
|
3837
|
-
left: isFixedOrSticky ?
|
|
3838
|
-
|
|
3724
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
3725
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
3726
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
3727
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
3728
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
3839
3729
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
3840
3730
|
// but sizing is driven by explicit width/height or measured size.
|
|
3841
3731
|
positionStyles.position;
|
|
3842
|
-
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;
|
|
3732
|
+
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;
|
|
3843
3733
|
return {
|
|
3844
3734
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
3845
3735
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
3846
3736
|
};
|
|
3847
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
3737
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
|
|
3848
3738
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
3849
3739
|
return {
|
|
3850
3740
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -3874,33 +3764,32 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3874
3764
|
absMx: absMx,
|
|
3875
3765
|
absMy: absMy
|
|
3876
3766
|
};
|
|
3877
|
-
}), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
};
|
|
3886
|
-
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
|
|
3887
|
-
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;
|
|
3767
|
+
}), [ 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((() => ({
|
|
3768
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
3769
|
+
hover2: isActive ? .5 : 0,
|
|
3770
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
3771
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
3772
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
3773
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
|
|
3774
|
+
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;
|
|
3888
3775
|
return {
|
|
3889
3776
|
...void 0 !== customZIndex && {
|
|
3890
3777
|
"--atomix-glass-base-z-index": customZIndex
|
|
3891
3778
|
},
|
|
3892
3779
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
3893
3780
|
"--atomix-glass-transform": transformStyle || "none",
|
|
3894
|
-
|
|
3895
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
3896
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
3897
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
3781
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
3782
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
3783
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
3784
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
3785
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
3786
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
3898
3787
|
"--atomix-glass-width": adjustedSize.width,
|
|
3899
3788
|
"--atomix-glass-height": adjustedSize.height,
|
|
3900
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
3789
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
3901
3790
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
3902
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) *
|
|
3903
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) *
|
|
3791
|
+
"--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%)`,
|
|
3792
|
+
"--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%)`,
|
|
3904
3793
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
3905
3794
|
"--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}%)`,
|
|
3906
3795
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -3914,13 +3803,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3914
3803
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
3915
3804
|
"--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}%)`
|
|
3916
3805
|
};
|
|
3917
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
3806
|
+
}), [ 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", {
|
|
3918
3807
|
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(" ")
|
|
3919
3808
|
});
|
|
3920
3809
|
// Calculate position and size styles for internal layers
|
|
3921
3810
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
3922
3811
|
return jsxs("div", {
|
|
3923
3812
|
...rest,
|
|
3813
|
+
ref: mergedRef,
|
|
3924
3814
|
className: componentClassName,
|
|
3925
3815
|
style: {
|
|
3926
3816
|
...glassVars
|
|
@@ -3930,17 +3820,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3930
3820
|
"aria-label": ariaLabel,
|
|
3931
3821
|
"aria-describedby": ariaDescribedBy,
|
|
3932
3822
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
3933
|
-
"aria-pressed":
|
|
3823
|
+
"aria-pressed": void 0,
|
|
3934
3824
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
3935
3825
|
children: [ jsx(AtomixGlassContainer, {
|
|
3936
3826
|
ref: glassRef,
|
|
3937
3827
|
contentRef: contentRef,
|
|
3938
3828
|
className: className,
|
|
3939
3829
|
style: {
|
|
3940
|
-
...restStyle
|
|
3941
|
-
...!isFixedOrSticky && {
|
|
3942
|
-
position: "relative"
|
|
3943
|
-
}
|
|
3830
|
+
...restStyle
|
|
3944
3831
|
},
|
|
3945
3832
|
borderRadius: effectiveBorderRadius,
|
|
3946
3833
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -3976,6 +3863,7 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3976
3863
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
3977
3864
|
shaderVariant: shaderVariant,
|
|
3978
3865
|
withLiquidBlur: withLiquidBlur,
|
|
3866
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
3979
3867
|
// Phase 1: Animation System props
|
|
3980
3868
|
shaderTime: getShaderTime(),
|
|
3981
3869
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -4004,6 +3892,8 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
4004
3892
|
}) ]
|
|
4005
3893
|
}), withBorder && jsxs(Fragment, {
|
|
4006
3894
|
children: [ jsx("span", {
|
|
3895
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
3896
|
+
}), jsx("span", {
|
|
4007
3897
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
4008
3898
|
}), jsx("span", {
|
|
4009
3899
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -4014,9 +3904,18 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
4014
3904
|
onClose: () => {}
|
|
4015
3905
|
}) ]
|
|
4016
3906
|
});
|
|
4017
|
-
}
|
|
3907
|
+
}));
|
|
3908
|
+
|
|
3909
|
+
/**
|
|
3910
|
+
* Balanced preset - Good quality with reasonable performance
|
|
3911
|
+
* Default preset for most mobile devices
|
|
3912
|
+
*/ AtomixGlassInner.displayName = "AtomixGlass";
|
|
4018
3913
|
|
|
4019
|
-
|
|
3914
|
+
/**
|
|
3915
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
3916
|
+
* Ref is forwarded to the root `<div>` element.
|
|
3917
|
+
*/
|
|
3918
|
+
const AtomixGlass = memo(AtomixGlassInner), ChartContext = createContext(null), Chart = memo( forwardRef((({children: children, type: type = "line", size: size = "md", variant: variant = "primary", title: title, subtitle: subtitle, loading: loading = !1, error: error, className: className = "", "aria-label": ariaLabel, onFullscreen: onFullscreen, onExport: onExport, onRefresh: onRefresh, showToolbar: showToolbar = !1, enableFullscreen: enableFullscreen = !1, enableExport: enableExport = !1, enableRefresh: enableRefresh = !1, exportFormats: exportFormats = [ "png", "svg", "csv" ], datasets: datasets, config: config,
|
|
4020
3919
|
// Destructure non-DOM props to prevent passing to DOM element
|
|
4021
3920
|
toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, customToolbarGroups: customToolbarGroups, data: data, showLegend: showLegend, interactive: interactive, fullscreen: fullscreen, onDataPointClick: onDataPointClick, onLegendItemClick: onLegendItemClick, glass: glass, ...props}, ref) => {
|
|
4022
3921
|
const [isFullscreen, setIsFullscreen] = useState(!1), [isExporting, setIsExporting] = useState(!1), chartContainerRef = useRef(null), [zoomLevel, setZoomLevel] = useState(1), [panOffset, setPanOffset] = useState({
|