@shohojdhara/atomix 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/atomix.config.ts +12 -0
- package/build-tools/webpack-loader.js +5 -4
- package/dist/atomix.css +230 -83
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/webpack-loader.js +5 -4
- package/dist/charts.d.ts +24 -23
- package/dist/charts.js +271 -369
- package/dist/charts.js.map +1 -1
- package/dist/config.d.ts +624 -0
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +3 -2
- package/dist/core.js +342 -382
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +4 -6
- package/dist/forms.js +233 -334
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +11 -2
- package/dist/heavy.js +406 -445
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +109 -65
- package/dist/index.esm.js +654 -748
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +621 -717
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.js +59 -60
- package/dist/layout.js.map +1 -1
- package/dist/theme.js +4 -4
- package/dist/theme.js.map +1 -1
- package/package.json +24 -9
- package/scripts/atomix-cli.js +15 -1
- package/scripts/cli/__tests__/complexity-utils.test.js +24 -0
- package/scripts/cli/__tests__/detector.test.js +50 -0
- package/scripts/cli/__tests__/template-engine.test.js +23 -0
- package/scripts/cli/__tests__/test-setup.js +1 -133
- package/scripts/cli/commands/doctor.js +15 -3
- package/scripts/cli/commands/generate.js +113 -51
- package/scripts/cli/internal/ai-engine.js +30 -10
- package/scripts/cli/internal/complexity-utils.js +60 -0
- package/scripts/cli/internal/component-validator.js +49 -16
- package/scripts/cli/internal/generator.js +89 -36
- package/scripts/cli/internal/hook-generator.js +5 -2
- package/scripts/cli/internal/itcss-generator.js +16 -12
- package/scripts/cli/templates/next-templates.js +81 -30
- package/scripts/cli/templates/storybook-templates.js +12 -2
- package/scripts/cli/utils/detector.js +45 -7
- package/scripts/cli/utils/diagnostics.js +78 -0
- package/scripts/cli/utils/telemetry.js +13 -0
- package/src/components/Accordion/Accordion.stories.tsx +4 -0
- package/src/components/AtomixGlass/AtomixGlass.tsx +188 -128
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +63 -91
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +153 -201
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +9 -6
- package/src/components/AtomixGlass/glass-utils.ts +51 -1
- 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/components/Button/Button.tsx +114 -57
- package/src/components/Callout/Callout.tsx +4 -4
- package/src/components/Chart/ChartRenderer.tsx +1 -1
- package/src/components/Chart/DonutChart.tsx +11 -8
- package/src/components/EdgePanel/EdgePanel.tsx +119 -115
- package/src/components/Form/Select.tsx +4 -4
- package/src/components/List/List.tsx +4 -4
- package/src/components/Navigation/SideMenu/SideMenu.tsx +6 -6
- package/src/components/PhotoViewer/PhotoViewerImage.tsx +1 -1
- package/src/components/ProductReview/ProductReview.tsx +4 -2
- package/src/components/Rating/Rating.tsx +4 -2
- package/src/components/SectionIntro/SectionIntro.tsx +4 -2
- package/src/components/Steps/Steps.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +5 -5
- package/src/components/Testimonial/Testimonial.tsx +4 -2
- package/src/components/VideoPlayer/VideoPlayer.tsx +4 -2
- package/src/layouts/CssGrid/CssGrid.stories.tsx +464 -0
- package/src/layouts/CssGrid/CssGrid.tsx +215 -0
- package/src/layouts/CssGrid/index.ts +8 -0
- package/src/layouts/CssGrid/scripts/CssGrid.js +284 -0
- package/src/layouts/CssGrid/scripts/index.js +43 -0
- package/src/layouts/Grid/scripts/Container.js +139 -0
- package/src/layouts/Grid/scripts/Grid.js +184 -0
- package/src/layouts/Grid/scripts/GridCol.js +273 -0
- package/src/layouts/Grid/scripts/Row.js +154 -0
- package/src/layouts/Grid/scripts/index.js +48 -0
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +71 -59
- package/src/lib/composables/atomix-glass/useGlassSize.ts +1 -1
- package/src/lib/composables/useAccordion.ts +5 -5
- package/src/lib/composables/useAtomixGlass.ts +111 -74
- package/src/lib/composables/useAtomixGlassStyles.ts +0 -2
- package/src/lib/composables/useBarChart.ts +2 -2
- package/src/lib/composables/useChart.ts +3 -2
- package/src/lib/composables/useChartToolbar.ts +48 -66
- package/src/lib/composables/useDataTable.ts +1 -1
- package/src/lib/composables/useDatePicker.ts +2 -2
- package/src/lib/composables/useEdgePanel.ts +45 -54
- package/src/lib/composables/useHeroBackgroundSlider.ts +5 -5
- package/src/lib/composables/usePhotoViewer.ts +2 -3
- package/src/lib/composables/usePieChart.ts +1 -1
- package/src/lib/composables/usePopover.ts +151 -139
- package/src/lib/composables/useSideMenu.ts +28 -41
- package/src/lib/composables/useSlider.ts +2 -6
- package/src/lib/composables/useTooltip.ts +2 -2
- package/src/lib/config/index.ts +39 -0
- package/src/lib/constants/components.ts +1 -0
- package/src/lib/theme/devtools/Comparator.tsx +1 -1
- package/src/lib/theme/devtools/Inspector.tsx +1 -1
- package/src/lib/theme/devtools/LiveEditor.tsx +1 -1
- package/src/lib/theme/runtime/ThemeProvider.tsx +1 -1
- package/src/lib/types/components.ts +1 -0
- package/src/styles/01-settings/_index.scss +1 -0
- package/src/styles/01-settings/_settings.atomix-glass.scss +174 -0
- package/src/styles/01-settings/_settings.masonry-grid.scss +42 -6
- package/src/styles/02-tools/_tools.glass.scss +6 -0
- package/src/styles/05-objects/_objects.masonry-grid.scss +162 -24
- package/src/styles/06-components/_components.atomix-glass.scss +160 -99
- 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__/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/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/useBreadcrumb.ts +0 -81
- package/src/lib/composables/useChartInteractions.ts +0 -123
- package/src/lib/composables/useChartPerformance.ts +0 -347
- package/src/lib/composables/useDropdown.ts +0 -338
- package/src/lib/composables/useModal.ts +0 -110
- package/src/lib/composables/useTypedButton.ts +0 -66
- package/src/lib/hooks/usePerformanceMonitor.ts +0 -148
- package/src/lib/utils/displacement-generator.ts +0 -92
- package/src/lib/utils/memoryMonitor.ts +0 -191
- package/src/styles/01-settings/_settings.testtypecheck.scss +0 -53
- package/src/styles/01-settings/_settings.typedbutton.scss +0 -53
- package/src/styles/06-components/_components.testbutton.scss +0 -212
- package/src/styles/06-components/_components.testtypecheck.scss +0 -212
- package/src/styles/06-components/_components.typedbutton.scss +0 -212
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",
|
|
@@ -767,8 +768,11 @@ function useChart(initialProps) {
|
|
|
767
768
|
}), animationFrameRef = useRef(null);
|
|
768
769
|
// Default chart properties
|
|
769
770
|
// Cleanup animation frame on unmount
|
|
770
|
-
useEffect((() =>
|
|
771
|
-
|
|
771
|
+
useEffect((() => {
|
|
772
|
+
const currentRef = animationFrameRef.current;
|
|
773
|
+
return () => {
|
|
774
|
+
currentRef && cancelAnimationFrame(currentRef);
|
|
775
|
+
};
|
|
772
776
|
}), []);
|
|
773
777
|
/**
|
|
774
778
|
* Point interaction handlers
|
|
@@ -1669,7 +1673,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1669
1673
|
default:
|
|
1670
1674
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
1671
1675
|
}
|
|
1672
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
1676
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
1673
1677
|
style: {
|
|
1674
1678
|
position: "absolute",
|
|
1675
1679
|
width: "100%",
|
|
@@ -1810,24 +1814,17 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
1810
1814
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
1811
1815
|
|
|
1812
1816
|
// 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 = {
|
|
1817
|
+
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
1818
|
x: 0,
|
|
1821
1819
|
y: 0
|
|
1822
1820
|
}, 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
1821
|
width: 0,
|
|
1824
1822
|
height: 0
|
|
1825
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
1823
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
1826
1824
|
// Phase 1: Animation System props
|
|
1827
1825
|
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);
|
|
1826
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
1827
|
+
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
1828
|
// Lazy load shader utilities only when shader mode is needed
|
|
1832
1829
|
useEffect((() => {
|
|
1833
1830
|
"shader" === mode ?
|
|
@@ -1850,9 +1847,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1850
1847
|
// Create cache key from size and variant
|
|
1851
1848
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
1852
1849
|
const entry = sharedShaderCache.get(key);
|
|
1853
|
-
return entry ? (
|
|
1854
|
-
// Update access timestamp for LRU
|
|
1855
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
1850
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
1856
1851
|
})(cacheKey);
|
|
1857
1852
|
// Check shared cache first
|
|
1858
1853
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -1863,29 +1858,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1863
1858
|
if (shaderUtilsRef.current) try {
|
|
1864
1859
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
1865
1860
|
shaderGeneratorRef.current?.destroy();
|
|
1866
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
1861
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
1867
1862
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
1868
1863
|
width: glassSize.width,
|
|
1869
1864
|
height: glassSize.height,
|
|
1870
1865
|
fragment: selectedShader
|
|
1871
1866
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
1872
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
1867
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
1873
1868
|
url && ((key, url) => {
|
|
1874
|
-
// Evict oldest entries if at capacity
|
|
1875
1869
|
if (sharedShaderCache.size >= 15) {
|
|
1876
1870
|
const entries = Array.from(sharedShaderCache.entries());
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
const oldestEntry = entries[0];
|
|
1881
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
1871
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
1872
|
+
const oldest = entries[0];
|
|
1873
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
1882
1874
|
}
|
|
1883
1875
|
sharedShaderCache.set(key, {
|
|
1884
1876
|
url: url,
|
|
1885
1877
|
timestamp: Date.now()
|
|
1886
|
-
}),
|
|
1887
|
-
// Development mode: log cache size
|
|
1888
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
1878
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
1889
1879
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
1890
1880
|
}), 100);
|
|
1891
1881
|
} catch (error) {
|
|
@@ -1954,7 +1944,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
1954
1944
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
1955
1945
|
}
|
|
1956
1946
|
}), [ ref, glassSize ]);
|
|
1957
|
-
// Pre-calculate static multipliers outside useMemo
|
|
1958
1947
|
const liquidBlur = useMemo((() => {
|
|
1959
1948
|
const defaultBlur = {
|
|
1960
1949
|
baseBlur: blurAmount,
|
|
@@ -2023,7 +2012,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2023
2012
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
2024
2013
|
return jsx("div", {
|
|
2025
2014
|
ref: el => {
|
|
2026
|
-
// Apply force no-transition
|
|
2027
2015
|
// Handle forwarded ref
|
|
2028
2016
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
2029
2017
|
},
|
|
@@ -2065,6 +2053,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2065
2053
|
});
|
|
2066
2054
|
}));
|
|
2067
2055
|
|
|
2056
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
2068
2057
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
2069
2058
|
|
|
2070
2059
|
// Singleton instance
|
|
@@ -2265,8 +2254,6 @@ class {
|
|
|
2265
2254
|
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
2255
|
// Container variables
|
|
2267
2256
|
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
2257
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2271
2258
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2272
2259
|
// Shadows
|
|
@@ -2727,47 +2714,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2727
2714
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
2728
2715
|
}
|
|
2729
2716
|
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((() => {
|
|
2717
|
+
}), [ 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((() => {
|
|
2718
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
2719
|
+
lerpRafRef.current = null);
|
|
2720
|
+
}), []), startLerpLoop = useCallback((() => {
|
|
2746
2721
|
if (lerpActiveRef.current) return;
|
|
2747
2722
|
lerpActiveRef.current = !0;
|
|
2748
2723
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
2749
2724
|
if (!lerpActiveRef.current) return;
|
|
2750
|
-
|
|
2751
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
2725
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
2752
2726
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
2753
2727
|
// If we're close enough, snap and park
|
|
2754
|
-
if (Math.abs(dx) < .
|
|
2728
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
2755
2729
|
...tgt
|
|
2756
2730
|
}, internalGlobalMousePositionRef.current = {
|
|
2757
2731
|
...targetGlobalMousePositionRef.current
|
|
2758
|
-
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2732
|
+
},
|
|
2733
|
+
// Final update and stop
|
|
2734
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2735
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
2736
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2737
|
+
glassSize: glassSize,
|
|
2738
|
+
isHovered: isHovered,
|
|
2739
|
+
isActive: isActive,
|
|
2740
|
+
isOverLight: overLightConfig.isOverLight,
|
|
2741
|
+
baseOverLightConfig: overLightConfig,
|
|
2742
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
2743
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2744
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
2745
|
+
elasticity: elasticity,
|
|
2746
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
2747
|
+
onClick: onClick,
|
|
2748
|
+
withLiquidBlur: withLiquidBlur,
|
|
2749
|
+
blurAmount: blurAmount,
|
|
2750
|
+
saturation: saturation,
|
|
2751
|
+
padding: padding,
|
|
2752
|
+
isFixedOrSticky: isFixedOrSticky
|
|
2753
|
+
}), void stopLerpLoop();
|
|
2754
|
+
// Smooth step
|
|
2755
|
+
internalMouseOffsetRef.current = {
|
|
2756
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
2757
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
2758
|
+
};
|
|
2759
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
2760
|
+
internalGlobalMousePositionRef.current = {
|
|
2761
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
2762
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
2763
|
+
},
|
|
2764
|
+
// Imperative style update
|
|
2765
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
2771
2766
|
mouseOffset: internalMouseOffsetRef.current,
|
|
2772
2767
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
2773
2768
|
glassSize: glassSize,
|
|
@@ -2790,10 +2785,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2790
2785
|
};
|
|
2791
2786
|
// 0.08 – lower = more viscous
|
|
2792
2787
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
2793
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2788
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
2789
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2790
|
+
if (effectiveWithoutEffects) return;
|
|
2791
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
2792
|
+
if (!container) return;
|
|
2793
|
+
// Use cached rect if available, otherwise get new one
|
|
2794
|
+
let rect = cachedRectRef.current;
|
|
2795
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
2796
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
2797
|
+
const center = calculateElementCenter(rect);
|
|
2798
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
2799
|
+
targetMouseOffsetRef.current = {
|
|
2800
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
2801
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
2802
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
2803
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
2804
|
+
lerpActiveRef.current || startLerpLoop();
|
|
2805
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
2797
2806
|
/**
|
|
2798
2807
|
* Validate and clamp a numeric config value
|
|
2799
2808
|
*/
|
|
@@ -2802,7 +2811,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2802
2811
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
2803
2812
|
if (effectiveWithoutEffects) return;
|
|
2804
2813
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
2805
|
-
//
|
|
2814
|
+
// Initial start
|
|
2806
2815
|
startLerpLoop();
|
|
2807
2816
|
const container = mouseContainer?.current || glassRef.current;
|
|
2808
2817
|
let resizeObserver = null;
|
|
@@ -2815,7 +2824,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
2815
2824
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
2816
2825
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
2817
2826
|
};
|
|
2818
|
-
}), [
|
|
2827
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
2819
2828
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
2820
2829
|
useEffect((() => {
|
|
2821
2830
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -3007,184 +3016,147 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
3007
3016
|
/**
|
|
3008
3017
|
* Get GPU memory info if available (Chrome DevTools only)
|
|
3009
3018
|
*/
|
|
3019
|
+
/** Map an FPS value to a semantic color token string. */
|
|
3020
|
+
const getQualityColor = quality => {
|
|
3021
|
+
switch (quality) {
|
|
3022
|
+
case "high":
|
|
3023
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
3024
|
+
|
|
3025
|
+
case "medium":
|
|
3026
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
3027
|
+
|
|
3028
|
+
case "low":
|
|
3029
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
3030
|
+
|
|
3031
|
+
default:
|
|
3032
|
+
return "#9ca3af";
|
|
3033
|
+
}
|
|
3034
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
3035
|
+
|
|
3036
|
+
/** Map a quality level string to a semantic color token string. */
|
|
3037
|
+
// Inject keyframes once
|
|
3038
|
+
if ("undefined" != typeof document) {
|
|
3039
|
+
const styleId = "perf-dashboard-keyframes";
|
|
3040
|
+
if (!document.getElementById(styleId)) {
|
|
3041
|
+
const styleEl = document.createElement("style");
|
|
3042
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
3043
|
+
document.head.appendChild(styleEl);
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3010
3047
|
/**
|
|
3011
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
3048
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
3012
3049
|
*
|
|
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,
|
|
3050
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
3051
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
3052
|
+
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
3053
|
+
if (!isVisible) return null;
|
|
3054
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
3055
|
+
var fps;
|
|
3056
|
+
const isCritical = metrics.fps < 45;
|
|
3057
|
+
return jsxs("div", {
|
|
3058
|
+
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",
|
|
3059
|
+
style: {
|
|
3060
|
+
zIndex: 9999,
|
|
3061
|
+
minWidth: "12.5rem",
|
|
3062
|
+
// 200px
|
|
3063
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
3064
|
+
backdropFilter: "blur(8px)",
|
|
3065
|
+
transition: "opacity 0.3s ease"
|
|
3066
|
+
},
|
|
3075
3067
|
children: [ jsxs("div", {
|
|
3076
|
-
|
|
3068
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
3077
3069
|
children: [ jsx("span", {
|
|
3078
|
-
|
|
3070
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
3079
3071
|
children: "Performance Monitor"
|
|
3080
3072
|
}), onClose && jsx("button", {
|
|
3081
|
-
|
|
3073
|
+
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
3074
|
onClick: onClose,
|
|
3083
3075
|
"aria-label": "Close performance dashboard",
|
|
3076
|
+
style: {
|
|
3077
|
+
transition: "color 0.2s ease"
|
|
3078
|
+
},
|
|
3084
3079
|
children: "×"
|
|
3085
3080
|
}) ]
|
|
3086
3081
|
}), jsxs("div", {
|
|
3087
|
-
|
|
3082
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3088
3083
|
children: [ jsx("span", {
|
|
3089
|
-
|
|
3084
|
+
className: "u-text-gray-400 u-me-3",
|
|
3090
3085
|
children: "FPS"
|
|
3091
3086
|
}), jsx("span", {
|
|
3087
|
+
className: "u-font-bold",
|
|
3092
3088
|
style: {
|
|
3093
|
-
|
|
3094
|
-
color: getFpsColor(metrics.fps)
|
|
3089
|
+
color: fpsColor
|
|
3095
3090
|
},
|
|
3096
3091
|
children: Math.round(metrics.fps)
|
|
3097
3092
|
}) ]
|
|
3098
3093
|
}), jsxs("div", {
|
|
3099
|
-
|
|
3094
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3100
3095
|
children: [ jsx("span", {
|
|
3101
|
-
|
|
3096
|
+
className: "u-text-gray-400 u-me-3",
|
|
3102
3097
|
children: "Frame Time"
|
|
3103
3098
|
}), jsxs("span", {
|
|
3104
|
-
|
|
3099
|
+
className: "u-font-bold",
|
|
3105
3100
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
3106
3101
|
}) ]
|
|
3107
3102
|
}), jsxs("div", {
|
|
3108
|
-
|
|
3103
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3109
3104
|
children: [ jsx("span", {
|
|
3110
|
-
|
|
3105
|
+
className: "u-text-gray-400 u-me-3",
|
|
3111
3106
|
children: "Quality"
|
|
3112
3107
|
}), jsx("span", {
|
|
3108
|
+
className: "u-font-bold u-text-uppercase",
|
|
3113
3109
|
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"
|
|
3110
|
+
fontSize: "0.6875rem",
|
|
3111
|
+
// 11px
|
|
3112
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
3132
3113
|
},
|
|
3133
3114
|
children: metrics.qualityLevel
|
|
3134
3115
|
}) ]
|
|
3135
3116
|
}), metrics.gpuMemory && jsxs("div", {
|
|
3136
|
-
|
|
3117
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3137
3118
|
children: [ jsx("span", {
|
|
3138
|
-
|
|
3119
|
+
className: "u-text-gray-400 u-me-3",
|
|
3139
3120
|
children: "GPU Memory"
|
|
3140
3121
|
}), jsxs("span", {
|
|
3141
|
-
|
|
3122
|
+
className: "u-font-bold",
|
|
3142
3123
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
3143
3124
|
}) ]
|
|
3144
3125
|
}), metrics.isAutoScaling && jsx("div", {
|
|
3126
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
3145
3127
|
style: {
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
fontSize: "10px",
|
|
3150
|
-
color: "#6b7280",
|
|
3151
|
-
textAlign: "center"
|
|
3128
|
+
fontSize: "0.625rem",
|
|
3129
|
+
// 10px
|
|
3130
|
+
color: "#6b7280"
|
|
3152
3131
|
},
|
|
3153
3132
|
children: "Auto-scaling active"
|
|
3154
3133
|
}), 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
|
-
},
|
|
3134
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
3163
3135
|
children: [ jsx("div", {
|
|
3136
|
+
className: "u-rounded-full",
|
|
3164
3137
|
style: {
|
|
3165
|
-
width: "
|
|
3166
|
-
height: "
|
|
3167
|
-
|
|
3168
|
-
backgroundColor:
|
|
3169
|
-
|
|
3138
|
+
width: "0.5rem",
|
|
3139
|
+
height: "0.5rem",
|
|
3140
|
+
flexShrink: 0,
|
|
3141
|
+
backgroundColor: fpsColor,
|
|
3142
|
+
...isCritical && {
|
|
3143
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
3144
|
+
}
|
|
3170
3145
|
}
|
|
3171
3146
|
}), jsx("span", {
|
|
3147
|
+
className: "u-text-xs",
|
|
3172
3148
|
style: {
|
|
3173
|
-
fontSize: "
|
|
3174
|
-
|
|
3149
|
+
fontSize: "0.625rem",
|
|
3150
|
+
// 10px
|
|
3151
|
+
color: fpsColor
|
|
3175
3152
|
},
|
|
3176
|
-
children: metrics.fps
|
|
3153
|
+
children: getFpsLabel(metrics.fps)
|
|
3177
3154
|
}) ]
|
|
3178
3155
|
}) ]
|
|
3179
|
-
})
|
|
3180
|
-
};
|
|
3156
|
+
});
|
|
3157
|
+
}));
|
|
3181
3158
|
|
|
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
|
-
}
|
|
3159
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
3188
3160
|
|
|
3189
3161
|
/**
|
|
3190
3162
|
* Mobile optimization presets
|
|
@@ -3195,7 +3167,8 @@ if ("undefined" != typeof document) {
|
|
|
3195
3167
|
/**
|
|
3196
3168
|
* Performance preset - Maximum FPS, reduced quality
|
|
3197
3169
|
* Best for low-end devices or when battery saving is priority
|
|
3198
|
-
*/
|
|
3170
|
+
*/
|
|
3171
|
+
const PERFORMANCE_PRESET = {
|
|
3199
3172
|
distortionOctaves: 2,
|
|
3200
3173
|
// Minimal FBM layers
|
|
3201
3174
|
displacementScale: 50,
|
|
@@ -3304,95 +3277,21 @@ if ("undefined" != typeof document) {
|
|
|
3304
3277
|
saturation: 70
|
|
3305
3278
|
}
|
|
3306
3279
|
}
|
|
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({
|
|
3280
|
+
}, 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) {
|
|
3281
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
|
|
3282
|
+
// Helper to merge refs
|
|
3283
|
+
function(...refs) {
|
|
3284
|
+
return node => {
|
|
3285
|
+
refs.forEach((ref => {
|
|
3286
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
3287
|
+
}));
|
|
3288
|
+
};
|
|
3289
|
+
}
|
|
3290
|
+
// Internal implementation with forwardRef
|
|
3291
|
+
(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
3292
|
glassRef: glassRef,
|
|
3395
3293
|
contentRef: contentRef,
|
|
3294
|
+
wrapperRef: internalWrapperRef,
|
|
3396
3295
|
borderRadius: borderRadius,
|
|
3397
3296
|
globalMousePosition: externalGlobalMousePosition,
|
|
3398
3297
|
mouseOffset: externalMouseOffset,
|
|
@@ -3421,7 +3320,6 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3421
3320
|
distortionGain: distortionGain,
|
|
3422
3321
|
distortionQuality: distortionQuality
|
|
3423
3322
|
});
|
|
3424
|
-
// Re-calculate only when devicePreset changes
|
|
3425
3323
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
3426
3324
|
!
|
|
3427
3325
|
/**
|
|
@@ -3611,11 +3509,10 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3611
3509
|
},
|
|
3612
3510
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
3613
3511
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
3614
|
-
// Enable unless disabled
|
|
3615
3512
|
debug: !1
|
|
3616
3513
|
});
|
|
3617
3514
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
3618
|
-
const {metrics: performanceMetrics,
|
|
3515
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
|
|
3619
3516
|
/**
|
|
3620
3517
|
* Performance Monitor Hook
|
|
3621
3518
|
*
|
|
@@ -3779,17 +3676,17 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3779
3676
|
toggleMonitoring: toggleMonitoring
|
|
3780
3677
|
};
|
|
3781
3678
|
}({
|
|
3782
|
-
enabled:
|
|
3783
|
-
//
|
|
3679
|
+
enabled: debugPerformance,
|
|
3680
|
+
// Enable when debugPerformance is true
|
|
3784
3681
|
debug: !1,
|
|
3785
3682
|
showOverlay: !1
|
|
3786
3683
|
});
|
|
3787
|
-
// Auto-start performance monitoring
|
|
3684
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
3788
3685
|
React.useEffect((() => {
|
|
3789
|
-
|
|
3686
|
+
debugPerformance && toggleMonitoring();
|
|
3790
3687
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3791
|
-
}), []);
|
|
3792
|
-
//
|
|
3688
|
+
}), [ debugPerformance ]);
|
|
3689
|
+
// Re-run when debugPerformance changes
|
|
3793
3690
|
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
3794
3691
|
if (!isFixedOrSticky) return {};
|
|
3795
3692
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -3817,34 +3714,30 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3817
3714
|
if (isFixedOrSticky) {
|
|
3818
3715
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
3819
3716
|
return {
|
|
3820
|
-
...visualStyle
|
|
3821
|
-
...!effectiveWithoutEffects && {
|
|
3822
|
-
transform: transformStyle
|
|
3823
|
-
}
|
|
3717
|
+
...visualStyle
|
|
3824
3718
|
};
|
|
3825
3719
|
}
|
|
3826
3720
|
return {
|
|
3827
|
-
...restStyle
|
|
3828
|
-
...!effectiveWithoutEffects && {
|
|
3829
|
-
transform: transformStyle
|
|
3830
|
-
}
|
|
3721
|
+
...restStyle
|
|
3831
3722
|
};
|
|
3832
|
-
}), [ isFixedOrSticky, restStyle
|
|
3723
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
3833
3724
|
// Build className with state modifiers
|
|
3834
3725
|
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
3726
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
3836
|
-
top: isFixedOrSticky ?
|
|
3837
|
-
left: isFixedOrSticky ?
|
|
3838
|
-
|
|
3727
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
3728
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
3729
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
3730
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
3731
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
3839
3732
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
3840
3733
|
// but sizing is driven by explicit width/height or measured size.
|
|
3841
3734
|
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;
|
|
3735
|
+
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
3736
|
return {
|
|
3844
3737
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
3845
3738
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
3846
3739
|
};
|
|
3847
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
3740
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
|
|
3848
3741
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
3849
3742
|
return {
|
|
3850
3743
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -3874,33 +3767,32 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3874
3767
|
absMx: absMx,
|
|
3875
3768
|
absMy: absMy
|
|
3876
3769
|
};
|
|
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;
|
|
3770
|
+
}), [ 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((() => ({
|
|
3771
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
3772
|
+
hover2: isActive ? .5 : 0,
|
|
3773
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
3774
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
3775
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
3776
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
|
|
3777
|
+
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
3778
|
return {
|
|
3889
3779
|
...void 0 !== customZIndex && {
|
|
3890
3780
|
"--atomix-glass-base-z-index": customZIndex
|
|
3891
3781
|
},
|
|
3892
3782
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
3893
3783
|
"--atomix-glass-transform": transformStyle || "none",
|
|
3894
|
-
|
|
3895
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
3896
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
3897
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
3784
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
3785
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
3786
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
3787
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
3788
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
3789
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
3898
3790
|
"--atomix-glass-width": adjustedSize.width,
|
|
3899
3791
|
"--atomix-glass-height": adjustedSize.height,
|
|
3900
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
3792
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
3901
3793
|
"--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) *
|
|
3794
|
+
"--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%)`,
|
|
3795
|
+
"--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
3796
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
3905
3797
|
"--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
3798
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -3914,13 +3806,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3914
3806
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
3915
3807
|
"--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
3808
|
};
|
|
3917
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
3809
|
+
}), [ 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
3810
|
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
3811
|
});
|
|
3920
3812
|
// Calculate position and size styles for internal layers
|
|
3921
3813
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
3922
3814
|
return jsxs("div", {
|
|
3923
3815
|
...rest,
|
|
3816
|
+
ref: mergedRef,
|
|
3924
3817
|
className: componentClassName,
|
|
3925
3818
|
style: {
|
|
3926
3819
|
...glassVars
|
|
@@ -3930,17 +3823,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3930
3823
|
"aria-label": ariaLabel,
|
|
3931
3824
|
"aria-describedby": ariaDescribedBy,
|
|
3932
3825
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
3933
|
-
"aria-pressed":
|
|
3826
|
+
"aria-pressed": void 0,
|
|
3934
3827
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
3935
3828
|
children: [ jsx(AtomixGlassContainer, {
|
|
3936
3829
|
ref: glassRef,
|
|
3937
3830
|
contentRef: contentRef,
|
|
3938
3831
|
className: className,
|
|
3939
3832
|
style: {
|
|
3940
|
-
...restStyle
|
|
3941
|
-
...!isFixedOrSticky && {
|
|
3942
|
-
position: "relative"
|
|
3943
|
-
}
|
|
3833
|
+
...restStyle
|
|
3944
3834
|
},
|
|
3945
3835
|
borderRadius: effectiveBorderRadius,
|
|
3946
3836
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -3976,6 +3866,7 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
3976
3866
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
3977
3867
|
shaderVariant: shaderVariant,
|
|
3978
3868
|
withLiquidBlur: withLiquidBlur,
|
|
3869
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
3979
3870
|
// Phase 1: Animation System props
|
|
3980
3871
|
shaderTime: getShaderTime(),
|
|
3981
3872
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -4004,6 +3895,8 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
4004
3895
|
}) ]
|
|
4005
3896
|
}), withBorder && jsxs(Fragment, {
|
|
4006
3897
|
children: [ jsx("span", {
|
|
3898
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
3899
|
+
}), jsx("span", {
|
|
4007
3900
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
4008
3901
|
}), jsx("span", {
|
|
4009
3902
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -4014,9 +3907,18 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
4014
3907
|
onClose: () => {}
|
|
4015
3908
|
}) ]
|
|
4016
3909
|
});
|
|
4017
|
-
}
|
|
3910
|
+
}));
|
|
4018
3911
|
|
|
4019
|
-
|
|
3912
|
+
/**
|
|
3913
|
+
* Balanced preset - Good quality with reasonable performance
|
|
3914
|
+
* Default preset for most mobile devices
|
|
3915
|
+
*/ AtomixGlassInner.displayName = "AtomixGlass";
|
|
3916
|
+
|
|
3917
|
+
/**
|
|
3918
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
3919
|
+
* Ref is forwarded to the root `<div>` element.
|
|
3920
|
+
*/
|
|
3921
|
+
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
3922
|
// Destructure non-DOM props to prevent passing to DOM element
|
|
4021
3923
|
toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, customToolbarGroups: customToolbarGroups, data: data, showLegend: showLegend, interactive: interactive, fullscreen: fullscreen, onDataPointClick: onDataPointClick, onLegendItemClick: onLegendItemClick, glass: glass, ...props}, ref) => {
|
|
4022
3924
|
const [isFullscreen, setIsFullscreen] = useState(!1), [isExporting, setIsExporting] = useState(!1), chartContainerRef = useRef(null), [zoomLevel, setZoomLevel] = useState(1), [panOffset, setPanOffset] = useState({
|
|
@@ -4119,8 +4021,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
4119
4021
|
}), [ chartType ]), finalDefaults = useMemo((() => ({
|
|
4120
4022
|
...getChartDefaults(),
|
|
4121
4023
|
...defaults
|
|
4122
|
-
})), [ getChartDefaults, defaults ]), enhancedHandlers = {
|
|
4123
|
-
onRefresh:
|
|
4024
|
+
})), [ getChartDefaults, defaults ]), enhancedHandlers = useMemo((() => ({
|
|
4025
|
+
onRefresh: () => {
|
|
4124
4026
|
setState((prev => ({
|
|
4125
4027
|
...prev,
|
|
4126
4028
|
isRefreshing: !0
|
|
@@ -4130,8 +4032,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
4130
4032
|
isRefreshing: !1
|
|
4131
4033
|
})));
|
|
4132
4034
|
}), 1e3);
|
|
4133
|
-
}
|
|
4134
|
-
onExport:
|
|
4035
|
+
},
|
|
4036
|
+
onExport: async format => {
|
|
4135
4037
|
setState((prev => ({
|
|
4136
4038
|
...prev,
|
|
4137
4039
|
isExporting: !0
|
|
@@ -4144,70 +4046,70 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
4144
4046
|
isExporting: !1
|
|
4145
4047
|
})));
|
|
4146
4048
|
}
|
|
4147
|
-
}
|
|
4148
|
-
onFullscreen:
|
|
4049
|
+
},
|
|
4050
|
+
onFullscreen: isFullscreen => {
|
|
4149
4051
|
setState((prev => ({
|
|
4150
4052
|
...prev,
|
|
4151
4053
|
isFullscreen: isFullscreen
|
|
4152
4054
|
}))), handlers.onFullscreen?.(isFullscreen);
|
|
4153
|
-
}
|
|
4154
|
-
onZoomIn:
|
|
4055
|
+
},
|
|
4056
|
+
onZoomIn: () => {
|
|
4155
4057
|
setState((prev => ({
|
|
4156
4058
|
...prev,
|
|
4157
4059
|
zoomLevel: Math.min(1.2 * prev.zoomLevel, 5)
|
|
4158
4060
|
}))), handlers.onZoomIn?.();
|
|
4159
|
-
}
|
|
4160
|
-
onZoomOut:
|
|
4061
|
+
},
|
|
4062
|
+
onZoomOut: () => {
|
|
4161
4063
|
setState((prev => ({
|
|
4162
4064
|
...prev,
|
|
4163
4065
|
zoomLevel: Math.max(prev.zoomLevel / 1.2, .2)
|
|
4164
4066
|
}))), handlers.onZoomOut?.();
|
|
4165
|
-
}
|
|
4166
|
-
onZoomReset:
|
|
4067
|
+
},
|
|
4068
|
+
onZoomReset: () => {
|
|
4167
4069
|
setState((prev => ({
|
|
4168
4070
|
...prev,
|
|
4169
4071
|
zoomLevel: 1
|
|
4170
4072
|
}))), handlers.onZoomReset?.();
|
|
4171
|
-
}
|
|
4172
|
-
onPanToggle:
|
|
4073
|
+
},
|
|
4074
|
+
onPanToggle: enabled => {
|
|
4173
4075
|
setState((prev => ({
|
|
4174
4076
|
...prev,
|
|
4175
4077
|
panEnabled: enabled
|
|
4176
4078
|
}))), handlers.onPanToggle?.(enabled);
|
|
4177
|
-
}
|
|
4178
|
-
onReset:
|
|
4079
|
+
},
|
|
4080
|
+
onReset: () => {
|
|
4179
4081
|
setState((prev => ({
|
|
4180
4082
|
...prev,
|
|
4181
4083
|
zoomLevel: 1,
|
|
4182
4084
|
panEnabled: !1
|
|
4183
4085
|
}))), handlers.onReset?.();
|
|
4184
|
-
}
|
|
4185
|
-
onGridToggle:
|
|
4086
|
+
},
|
|
4087
|
+
onGridToggle: show => {
|
|
4186
4088
|
setState((prev => ({
|
|
4187
4089
|
...prev,
|
|
4188
4090
|
showGrid: show
|
|
4189
4091
|
}))), handlers.onGridToggle?.(show);
|
|
4190
|
-
}
|
|
4191
|
-
onLegendToggle:
|
|
4092
|
+
},
|
|
4093
|
+
onLegendToggle: show => {
|
|
4192
4094
|
setState((prev => ({
|
|
4193
4095
|
...prev,
|
|
4194
4096
|
showLegend: show
|
|
4195
4097
|
}))), handlers.onLegendToggle?.(show);
|
|
4196
|
-
}
|
|
4197
|
-
onTooltipsToggle:
|
|
4098
|
+
},
|
|
4099
|
+
onTooltipsToggle: show => {
|
|
4198
4100
|
setState((prev => ({
|
|
4199
4101
|
...prev,
|
|
4200
4102
|
showTooltips: show
|
|
4201
4103
|
}))), handlers.onTooltipsToggle?.(show);
|
|
4202
|
-
}
|
|
4203
|
-
onAnimationsToggle:
|
|
4104
|
+
},
|
|
4105
|
+
onAnimationsToggle: enabled => {
|
|
4204
4106
|
setState((prev => ({
|
|
4205
4107
|
...prev,
|
|
4206
4108
|
animationsEnabled: enabled
|
|
4207
4109
|
}))), handlers.onAnimationsToggle?.(enabled);
|
|
4208
|
-
}
|
|
4209
|
-
onSettings:
|
|
4210
|
-
}, generateToolbarGroups = useCallback((() => {
|
|
4110
|
+
},
|
|
4111
|
+
onSettings: () => {}
|
|
4112
|
+
})), [ handlers ]), generateToolbarGroups = useCallback((() => {
|
|
4211
4113
|
const groups = [], dataActions = [];
|
|
4212
4114
|
// Data actions group
|
|
4213
4115
|
finalDefaults.refresh && dataActions.push({
|
|
@@ -4332,7 +4234,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
4332
4234
|
actions: customActions
|
|
4333
4235
|
});
|
|
4334
4236
|
return groups;
|
|
4335
|
-
}), [
|
|
4237
|
+
}), [ finalDefaults, state, enhancedHandlers, customActions, customGroups ]);
|
|
4336
4238
|
// Keyboard shortcuts
|
|
4337
4239
|
return useEffect((() => {
|
|
4338
4240
|
const handleKeyDown = event => {
|
|
@@ -4924,7 +4826,7 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
|
|
|
4924
4826
|
announcement: announcement,
|
|
4925
4827
|
focusedPoint: focusedPoint,
|
|
4926
4828
|
getAccessibleDescription: () => "Chart description"
|
|
4927
|
-
})), [ announcement, focusedPoint ]), transform = useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext
|
|
4829
|
+
})), [ announcement, focusedPoint ]), transform = useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext ]), chartData = useMemo((() => {
|
|
4928
4830
|
// Return null if dimensions not ready to prevent calculation with invalid dimensions
|
|
4929
4831
|
if (!isInitialized || 0 === dimensions.width || 0 === dimensions.height) return null;
|
|
4930
4832
|
const scales = calculateScales(processedData, dimensions.width, dimensions.height, void 0, config);
|
|
@@ -5341,7 +5243,7 @@ const BarChart = memo( forwardRef((({datasets: datasets = [], config: config =
|
|
|
5341
5243
|
opacity: .4
|
|
5342
5244
|
} ]
|
|
5343
5245
|
};
|
|
5344
|
-
})) : []), [ options.useGradients ]), formatValue = useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options
|
|
5246
|
+
})) : []), [ options.useGradients ]), formatValue = useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options ]);
|
|
5345
5247
|
return {
|
|
5346
5248
|
// State
|
|
5347
5249
|
hoveredBar: hoveredBar,
|
|
@@ -5367,7 +5269,7 @@ const BarChart = memo( forwardRef((({datasets: datasets = [], config: config =
|
|
|
5367
5269
|
y: horizontal ? y + height / 2 : y - 5
|
|
5368
5270
|
};
|
|
5369
5271
|
}
|
|
5370
|
-
}), [ options
|
|
5272
|
+
}), [ options ]),
|
|
5371
5273
|
// Handlers
|
|
5372
5274
|
handleBarHover: handleBarHover,
|
|
5373
5275
|
handleBarLeave: handleBarLeave,
|
|
@@ -5671,13 +5573,13 @@ const DonutChart = memo( forwardRef((({datasets: datasets = [], config: config
|
|
|
5671
5573
|
roundedCorners: !0
|
|
5672
5574
|
}, onDataPointClick: onDataPointClick, ...props}, ref) => {
|
|
5673
5575
|
// Use the first dataset for donut chart
|
|
5674
|
-
const dataset = datasets.length > 0 ? datasets[0] : {
|
|
5576
|
+
const dataset = useMemo((() => datasets.length > 0 ? datasets[0] : {
|
|
5675
5577
|
label: "",
|
|
5676
5578
|
data: []
|
|
5677
|
-
}, chartData = useMemo((() => {
|
|
5579
|
+
}), [ datasets ]), chartData = useMemo((() => {
|
|
5678
5580
|
if (!dataset?.data?.length) return null;
|
|
5679
5581
|
// Filter out invalid data points
|
|
5680
|
-
const validDataPoints = dataset?.data
|
|
5582
|
+
const validDataPoints = (dataset?.data || []).filter((point => "number" == typeof point.value && !isNaN(point.value) && isFinite(point.value) && point.value > 0));
|
|
5681
5583
|
return validDataPoints.length ? {
|
|
5682
5584
|
validDataPoints: validDataPoints
|
|
5683
5585
|
} : null;
|
|
@@ -6636,7 +6538,7 @@ const PieChart = memo( forwardRef((({datasets: datasets = [], config: config =
|
|
|
6636
6538
|
const parts = [];
|
|
6637
6539
|
return !1 !== options.showLabels && parts.push(slice.label), options.showPercentages && parts.push(`${Math.round(slice.percentage)}%`),
|
|
6638
6540
|
options.showValues && parts.push(slice.value.toString()), parts.join(" - ");
|
|
6639
|
-
}), [ options
|
|
6541
|
+
}), [ options ]), getSliceTransform = useCallback(((slice, isHovered) => isHovered && options.enableHoverEffects && options.hoverOffset ? `translate(${Math.cos(slice.midAngle) * options.hoverOffset}, ${Math.sin(slice.midAngle) * options.hoverOffset})` : ""), [ options.enableHoverEffects, options.hoverOffset ]), isSliceSelected = useCallback((index => selectedSlices.has(index)), [ selectedSlices ]);
|
|
6640
6542
|
return {
|
|
6641
6543
|
// Data
|
|
6642
6544
|
processedData: processedData,
|