@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/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
|
|
3
|
-
import React, { useState, useRef, useEffect, memo, forwardRef,
|
|
3
|
+
import React, { useState, useRef, useCallback, useEffect, memo, forwardRef, useId, useMemo, Children, isValidElement, cloneElement, createContext, useContext, useImperativeHandle, Component } from "react";
|
|
4
4
|
|
|
5
5
|
import * as PhosphorIcons from "@phosphor-icons/react";
|
|
6
6
|
|
|
@@ -1695,6 +1695,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
1695
1695
|
FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
|
|
1696
1696
|
FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
|
|
1697
1697
|
CONTENT_CLASS: "c-atomix-glass__content",
|
|
1698
|
+
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
1698
1699
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
1699
1700
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
1700
1701
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
@@ -1964,19 +1965,19 @@ function useAccordion(initialProps) {
|
|
|
1964
1965
|
disabled: !1,
|
|
1965
1966
|
iconPosition: "right",
|
|
1966
1967
|
...initialProps
|
|
1967
|
-
}, isControlled = "boolean" == typeof defaultProps.isOpen, [internalOpen, setInternalOpen] = useState(defaultProps.defaultOpen || !1), isOpen = isControlled ? defaultProps.isOpen : internalOpen, [panelHeight, setPanelHeight] = useState(isOpen ? "auto" : "0px"), panelRef = useRef(null), contentRef = useRef(null), updatePanelHeight = () => {
|
|
1968
|
+
}, isControlled = "boolean" == typeof defaultProps.isOpen, [internalOpen, setInternalOpen] = useState(defaultProps.defaultOpen || !1), isOpen = isControlled ? defaultProps.isOpen : internalOpen, [panelHeight, setPanelHeight] = useState(isOpen ? "auto" : "0px"), panelRef = useRef(null), contentRef = useRef(null), updatePanelHeight = useCallback((() => {
|
|
1968
1969
|
if (contentRef.current && panelRef.current) {
|
|
1969
1970
|
const height = isOpen ? `${contentRef.current.clientHeight}px` : "0px";
|
|
1970
1971
|
panelRef.current.style.setProperty(ACCORDION.CSS_VARS.PANEL_HEIGHT, height), setPanelHeight(height);
|
|
1971
1972
|
}
|
|
1972
|
-
};
|
|
1973
|
+
}), [ isOpen ]);
|
|
1973
1974
|
// Controlled/uncontrolled open state
|
|
1974
1975
|
/**
|
|
1975
1976
|
* Effect to update panel height when open state changes
|
|
1976
1977
|
*/
|
|
1977
1978
|
return useEffect((() => {
|
|
1978
1979
|
updatePanelHeight();
|
|
1979
|
-
}), [ isOpen ]),
|
|
1980
|
+
}), [ isOpen, updatePanelHeight ]),
|
|
1980
1981
|
/**
|
|
1981
1982
|
* Effect to handle window resize and update panel height
|
|
1982
1983
|
*/
|
|
@@ -1985,7 +1986,7 @@ function useAccordion(initialProps) {
|
|
|
1985
1986
|
isOpen && updatePanelHeight();
|
|
1986
1987
|
};
|
|
1987
1988
|
return window.addEventListener("resize", handleResize), () => window.removeEventListener("resize", handleResize);
|
|
1988
|
-
}), [ isOpen ]), {
|
|
1989
|
+
}), [ isOpen, updatePanelHeight ]), {
|
|
1989
1990
|
state: {
|
|
1990
1991
|
isOpen: isOpen,
|
|
1991
1992
|
panelHeight: panelHeight
|
|
@@ -2097,7 +2098,7 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2097
2098
|
default:
|
|
2098
2099
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
2099
2100
|
}
|
|
2100
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
2101
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
2101
2102
|
style: {
|
|
2102
2103
|
position: "absolute",
|
|
2103
2104
|
width: "100%",
|
|
@@ -2238,24 +2239,17 @@ const {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2)
|
|
|
2238
2239
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
2239
2240
|
|
|
2240
2241
|
// Memoize component to prevent unnecessary re-renders
|
|
2241
|
-
const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount))
|
|
2242
|
-
|
|
2243
|
-
// Module-level counter for deterministic ID generation
|
|
2244
|
-
let idCounter = 0;
|
|
2245
|
-
|
|
2246
|
-
// Module-level shared shader cache with LRU eviction
|
|
2247
|
-
const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
2242
|
+
const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
|
|
2248
2243
|
x: 0,
|
|
2249
2244
|
y: 0
|
|
2250
2245
|
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
|
|
2251
2246
|
width: 0,
|
|
2252
2247
|
height: 0
|
|
2253
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
2248
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
2254
2249
|
// Phase 1: Animation System props
|
|
2255
2250
|
shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
|
|
2256
|
-
//
|
|
2257
|
-
|
|
2258
|
-
const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
2251
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
2252
|
+
const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
|
|
2259
2253
|
// Lazy load shader utilities only when shader mode is needed
|
|
2260
2254
|
useEffect((() => {
|
|
2261
2255
|
"shader" === mode ?
|
|
@@ -2278,9 +2272,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2278
2272
|
// Create cache key from size and variant
|
|
2279
2273
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
2280
2274
|
const entry = sharedShaderCache.get(key);
|
|
2281
|
-
return entry ? (
|
|
2282
|
-
// Update access timestamp for LRU
|
|
2283
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
2275
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
2284
2276
|
})(cacheKey);
|
|
2285
2277
|
// Check shared cache first
|
|
2286
2278
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -2291,29 +2283,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2291
2283
|
if (shaderUtilsRef.current) try {
|
|
2292
2284
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
2293
2285
|
shaderGeneratorRef.current?.destroy();
|
|
2294
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
2286
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
2295
2287
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
2296
2288
|
width: glassSize.width,
|
|
2297
2289
|
height: glassSize.height,
|
|
2298
2290
|
fragment: selectedShader
|
|
2299
2291
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
2300
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
2292
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
2301
2293
|
url && ((key, url) => {
|
|
2302
|
-
// Evict oldest entries if at capacity
|
|
2303
2294
|
if (sharedShaderCache.size >= 15) {
|
|
2304
2295
|
const entries = Array.from(sharedShaderCache.entries());
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
const oldestEntry = entries[0];
|
|
2309
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
2296
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
2297
|
+
const oldest = entries[0];
|
|
2298
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
2310
2299
|
}
|
|
2311
2300
|
sharedShaderCache.set(key, {
|
|
2312
2301
|
url: url,
|
|
2313
2302
|
timestamp: Date.now()
|
|
2314
|
-
}),
|
|
2315
|
-
// Development mode: log cache size
|
|
2316
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
2303
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
2317
2304
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
2318
2305
|
}), 100);
|
|
2319
2306
|
} catch (error) {
|
|
@@ -2382,7 +2369,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2382
2369
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
2383
2370
|
}
|
|
2384
2371
|
}), [ ref, glassSize ]);
|
|
2385
|
-
// Pre-calculate static multipliers outside useMemo
|
|
2386
2372
|
const liquidBlur = useMemo((() => {
|
|
2387
2373
|
const defaultBlur = {
|
|
2388
2374
|
baseBlur: blurAmount,
|
|
@@ -2451,7 +2437,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2451
2437
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
2452
2438
|
return jsx("div", {
|
|
2453
2439
|
ref: el => {
|
|
2454
|
-
// Apply force no-transition
|
|
2455
2440
|
// Handle forwarded ref
|
|
2456
2441
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
2457
2442
|
},
|
|
@@ -2493,6 +2478,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
2493
2478
|
});
|
|
2494
2479
|
}));
|
|
2495
2480
|
|
|
2481
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
2496
2482
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
2497
2483
|
|
|
2498
2484
|
// Singleton instance
|
|
@@ -2693,8 +2679,6 @@ class {
|
|
|
2693
2679
|
backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})`;
|
|
2694
2680
|
// Container variables
|
|
2695
2681
|
const style = containerElement.style;
|
|
2696
|
-
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
2697
|
-
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
2698
2682
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
2699
2683
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
2700
2684
|
// Shadows
|
|
@@ -3155,47 +3139,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3155
3139
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
3156
3140
|
}
|
|
3157
3141
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
3158
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null),
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
if (!container) return;
|
|
3163
|
-
// Use cached rect if available, otherwise get new one
|
|
3164
|
-
let rect = cachedRectRef.current;
|
|
3165
|
-
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
3166
|
-
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
3167
|
-
const center = calculateElementCenter(rect);
|
|
3168
|
-
// Write raw target — the lerp loop will smoothly pursue it
|
|
3169
|
-
targetMouseOffsetRef.current = {
|
|
3170
|
-
x: (globalPos.x - center.x) / rect.width * 100,
|
|
3171
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
3172
|
-
}, targetGlobalMousePositionRef.current = globalPos;
|
|
3173
|
-
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
|
|
3142
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), stopLerpLoop = useCallback((() => {
|
|
3143
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
3144
|
+
lerpRafRef.current = null);
|
|
3145
|
+
}), []), startLerpLoop = useCallback((() => {
|
|
3174
3146
|
if (lerpActiveRef.current) return;
|
|
3175
3147
|
lerpActiveRef.current = !0;
|
|
3176
3148
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
3177
3149
|
if (!lerpActiveRef.current) return;
|
|
3178
|
-
|
|
3179
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
3150
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
3180
3151
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
3181
3152
|
// If we're close enough, snap and park
|
|
3182
|
-
if (Math.abs(dx) < .
|
|
3153
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
3183
3154
|
...tgt
|
|
3184
3155
|
}, internalGlobalMousePositionRef.current = {
|
|
3185
3156
|
...targetGlobalMousePositionRef.current
|
|
3186
|
-
}
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3157
|
+
},
|
|
3158
|
+
// Final update and stop
|
|
3159
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3160
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
3161
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3162
|
+
glassSize: glassSize,
|
|
3163
|
+
isHovered: isHovered,
|
|
3164
|
+
isActive: isActive,
|
|
3165
|
+
isOverLight: overLightConfig.isOverLight,
|
|
3166
|
+
baseOverLightConfig: overLightConfig,
|
|
3167
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
3168
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
3169
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
3170
|
+
elasticity: elasticity,
|
|
3171
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
3172
|
+
onClick: onClick,
|
|
3173
|
+
withLiquidBlur: withLiquidBlur,
|
|
3174
|
+
blurAmount: blurAmount,
|
|
3175
|
+
saturation: saturation,
|
|
3176
|
+
padding: padding,
|
|
3177
|
+
isFixedOrSticky: isFixedOrSticky
|
|
3178
|
+
}), void stopLerpLoop();
|
|
3179
|
+
// Smooth step
|
|
3180
|
+
internalMouseOffsetRef.current = {
|
|
3181
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
3182
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
3183
|
+
};
|
|
3184
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
3185
|
+
internalGlobalMousePositionRef.current = {
|
|
3186
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
3187
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
3188
|
+
},
|
|
3189
|
+
// Imperative style update
|
|
3190
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
3199
3191
|
mouseOffset: internalMouseOffsetRef.current,
|
|
3200
3192
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
3201
3193
|
glassSize: glassSize,
|
|
@@ -3218,10 +3210,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3218
3210
|
};
|
|
3219
3211
|
// 0.08 – lower = more viscous
|
|
3220
3212
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
3221
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3213
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
3214
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3215
|
+
if (effectiveWithoutEffects) return;
|
|
3216
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
3217
|
+
if (!container) return;
|
|
3218
|
+
// Use cached rect if available, otherwise get new one
|
|
3219
|
+
let rect = cachedRectRef.current;
|
|
3220
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
3221
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
3222
|
+
const center = calculateElementCenter(rect);
|
|
3223
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
3224
|
+
targetMouseOffsetRef.current = {
|
|
3225
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
3226
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
3227
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
3228
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
3229
|
+
lerpActiveRef.current || startLerpLoop();
|
|
3230
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
3225
3231
|
/**
|
|
3226
3232
|
* Validate and clamp a numeric config value
|
|
3227
3233
|
*/
|
|
@@ -3230,7 +3236,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3230
3236
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
3231
3237
|
if (effectiveWithoutEffects) return;
|
|
3232
3238
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
3233
|
-
//
|
|
3239
|
+
// Initial start
|
|
3234
3240
|
startLerpLoop();
|
|
3235
3241
|
const container = mouseContainer?.current || glassRef.current;
|
|
3236
3242
|
let resizeObserver = null;
|
|
@@ -3243,7 +3249,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
3243
3249
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
3244
3250
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
3245
3251
|
};
|
|
3246
|
-
}), [
|
|
3252
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
3247
3253
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
3248
3254
|
useEffect((() => {
|
|
3249
3255
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -3738,183 +3744,146 @@ function usePerformanceMonitor(config = {}) {
|
|
|
3738
3744
|
}
|
|
3739
3745
|
}
|
|
3740
3746
|
|
|
3747
|
+
/** Map an FPS value to a semantic color token string. */ const getQualityColor = quality => {
|
|
3748
|
+
switch (quality) {
|
|
3749
|
+
case "high":
|
|
3750
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
3751
|
+
|
|
3752
|
+
case "medium":
|
|
3753
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
3754
|
+
|
|
3755
|
+
case "low":
|
|
3756
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
3757
|
+
|
|
3758
|
+
default:
|
|
3759
|
+
return "#9ca3af";
|
|
3760
|
+
}
|
|
3761
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
3762
|
+
|
|
3763
|
+
/** Map a quality level string to a semantic color token string. */
|
|
3764
|
+
// Inject keyframes once
|
|
3765
|
+
if ("undefined" != typeof document) {
|
|
3766
|
+
const styleId = "perf-dashboard-keyframes";
|
|
3767
|
+
if (!document.getElementById(styleId)) {
|
|
3768
|
+
const styleEl = document.createElement("style");
|
|
3769
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
3770
|
+
document.head.appendChild(styleEl);
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
|
|
3741
3774
|
/**
|
|
3742
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
3775
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
3743
3776
|
*
|
|
3744
|
-
* Displays
|
|
3745
|
-
*
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
3762
|
-
fontFamily: "monospace",
|
|
3763
|
-
fontSize: "12px",
|
|
3764
|
-
color: "#fff",
|
|
3765
|
-
zIndex: 9999,
|
|
3766
|
-
minWidth: "200px",
|
|
3767
|
-
backdropFilter: "blur(8px)",
|
|
3768
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3769
|
-
transition: "opacity 0.3s ease",
|
|
3770
|
-
opacity: isVisible ? 1 : 0,
|
|
3771
|
-
pointerEvents: isVisible ? "auto" : "none"
|
|
3772
|
-
})), [ isVisible ]), headerStyle = useMemo((() => ({
|
|
3773
|
-
display: "flex",
|
|
3774
|
-
justifyContent: "space-between",
|
|
3775
|
-
alignItems: "center",
|
|
3776
|
-
marginBottom: "8px",
|
|
3777
|
-
paddingBottom: "8px",
|
|
3778
|
-
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
3779
|
-
})), []), titleStyle = useMemo((() => ({
|
|
3780
|
-
fontWeight: "bold",
|
|
3781
|
-
fontSize: "13px",
|
|
3782
|
-
color: "#fff"
|
|
3783
|
-
})), []), closeButtonStyle = useMemo((() => ({
|
|
3784
|
-
background: "transparent",
|
|
3785
|
-
border: "none",
|
|
3786
|
-
color: "#9ca3af",
|
|
3787
|
-
cursor: "pointer",
|
|
3788
|
-
fontSize: "16px",
|
|
3789
|
-
padding: "0",
|
|
3790
|
-
lineHeight: "1"
|
|
3791
|
-
})), []), metricRowStyle = useMemo((() => ({
|
|
3792
|
-
display: "flex",
|
|
3793
|
-
justifyContent: "space-between",
|
|
3794
|
-
alignItems: "center",
|
|
3795
|
-
marginBottom: "6px"
|
|
3796
|
-
})), []), labelStyle = useMemo((() => ({
|
|
3797
|
-
color: "#9ca3af",
|
|
3798
|
-
marginRight: "12px"
|
|
3799
|
-
})), []), valueStyle = useMemo((() => ({
|
|
3800
|
-
fontWeight: "bold"
|
|
3801
|
-
})), []);
|
|
3802
|
-
// Get quality level badge color
|
|
3803
|
-
return isVisible ? jsxs("div", {
|
|
3804
|
-
style: dashboardStyle,
|
|
3777
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
3778
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
3779
|
+
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
3780
|
+
if (!isVisible) return null;
|
|
3781
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
3782
|
+
var fps;
|
|
3783
|
+
const isCritical = metrics.fps < 45;
|
|
3784
|
+
return jsxs("div", {
|
|
3785
|
+
className: "c-perf-dashboard u-position-fixed u-top-4 u-end-4 u-p-3 u-px-4 u-text-xs u-font-mono u-text-white u-rounded-md u-border u-border-white-alpha-10 u-shadow-lg",
|
|
3786
|
+
style: {
|
|
3787
|
+
zIndex: 9999,
|
|
3788
|
+
minWidth: "12.5rem",
|
|
3789
|
+
// 200px
|
|
3790
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
3791
|
+
backdropFilter: "blur(8px)",
|
|
3792
|
+
transition: "opacity 0.3s ease"
|
|
3793
|
+
},
|
|
3805
3794
|
children: [ jsxs("div", {
|
|
3806
|
-
|
|
3795
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
3807
3796
|
children: [ jsx("span", {
|
|
3808
|
-
|
|
3797
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
3809
3798
|
children: "Performance Monitor"
|
|
3810
3799
|
}), onClose && jsx("button", {
|
|
3811
|
-
|
|
3800
|
+
className: "u-bg-transparent u-border-none u-p-0 u-line-height-1 u-text-base u-text-gray-400 u-cursor-pointer hover:u-text-white",
|
|
3812
3801
|
onClick: onClose,
|
|
3813
3802
|
"aria-label": "Close performance dashboard",
|
|
3803
|
+
style: {
|
|
3804
|
+
transition: "color 0.2s ease"
|
|
3805
|
+
},
|
|
3814
3806
|
children: "×"
|
|
3815
3807
|
}) ]
|
|
3816
3808
|
}), jsxs("div", {
|
|
3817
|
-
|
|
3809
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3818
3810
|
children: [ jsx("span", {
|
|
3819
|
-
|
|
3811
|
+
className: "u-text-gray-400 u-me-3",
|
|
3820
3812
|
children: "FPS"
|
|
3821
3813
|
}), jsx("span", {
|
|
3814
|
+
className: "u-font-bold",
|
|
3822
3815
|
style: {
|
|
3823
|
-
|
|
3824
|
-
color: getFpsColor(metrics.fps)
|
|
3816
|
+
color: fpsColor
|
|
3825
3817
|
},
|
|
3826
3818
|
children: Math.round(metrics.fps)
|
|
3827
3819
|
}) ]
|
|
3828
3820
|
}), jsxs("div", {
|
|
3829
|
-
|
|
3821
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3830
3822
|
children: [ jsx("span", {
|
|
3831
|
-
|
|
3823
|
+
className: "u-text-gray-400 u-me-3",
|
|
3832
3824
|
children: "Frame Time"
|
|
3833
3825
|
}), jsxs("span", {
|
|
3834
|
-
|
|
3826
|
+
className: "u-font-bold",
|
|
3835
3827
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
3836
3828
|
}) ]
|
|
3837
3829
|
}), jsxs("div", {
|
|
3838
|
-
|
|
3830
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3839
3831
|
children: [ jsx("span", {
|
|
3840
|
-
|
|
3832
|
+
className: "u-text-gray-400 u-me-3",
|
|
3841
3833
|
children: "Quality"
|
|
3842
3834
|
}), jsx("span", {
|
|
3835
|
+
className: "u-font-bold u-text-uppercase",
|
|
3843
3836
|
style: {
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
case "high":
|
|
3848
|
-
return "#4ade80";
|
|
3849
|
-
|
|
3850
|
-
case "medium":
|
|
3851
|
-
return "#fbbf24";
|
|
3852
|
-
|
|
3853
|
-
case "low":
|
|
3854
|
-
return "#ef4444";
|
|
3855
|
-
|
|
3856
|
-
default:
|
|
3857
|
-
return "#9ca3af";
|
|
3858
|
-
}
|
|
3859
|
-
})(metrics.qualityLevel),
|
|
3860
|
-
textTransform: "uppercase",
|
|
3861
|
-
fontSize: "11px"
|
|
3837
|
+
fontSize: "0.6875rem",
|
|
3838
|
+
// 11px
|
|
3839
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
3862
3840
|
},
|
|
3863
3841
|
children: metrics.qualityLevel
|
|
3864
3842
|
}) ]
|
|
3865
3843
|
}), metrics.gpuMemory && jsxs("div", {
|
|
3866
|
-
|
|
3844
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
3867
3845
|
children: [ jsx("span", {
|
|
3868
|
-
|
|
3846
|
+
className: "u-text-gray-400 u-me-3",
|
|
3869
3847
|
children: "GPU Memory"
|
|
3870
3848
|
}), jsxs("span", {
|
|
3871
|
-
|
|
3849
|
+
className: "u-font-bold",
|
|
3872
3850
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
3873
3851
|
}) ]
|
|
3874
3852
|
}), metrics.isAutoScaling && jsx("div", {
|
|
3853
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
3875
3854
|
style: {
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
fontSize: "10px",
|
|
3880
|
-
color: "#6b7280",
|
|
3881
|
-
textAlign: "center"
|
|
3855
|
+
fontSize: "0.625rem",
|
|
3856
|
+
// 10px
|
|
3857
|
+
color: "#6b7280"
|
|
3882
3858
|
},
|
|
3883
3859
|
children: "Auto-scaling active"
|
|
3884
3860
|
}), jsxs("div", {
|
|
3885
|
-
|
|
3886
|
-
marginTop: "8px",
|
|
3887
|
-
paddingTop: "8px",
|
|
3888
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
3889
|
-
display: "flex",
|
|
3890
|
-
alignItems: "center",
|
|
3891
|
-
gap: "6px"
|
|
3892
|
-
},
|
|
3861
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
3893
3862
|
children: [ jsx("div", {
|
|
3863
|
+
className: "u-rounded-full",
|
|
3894
3864
|
style: {
|
|
3895
|
-
width: "
|
|
3896
|
-
height: "
|
|
3897
|
-
|
|
3898
|
-
backgroundColor:
|
|
3899
|
-
|
|
3865
|
+
width: "0.5rem",
|
|
3866
|
+
height: "0.5rem",
|
|
3867
|
+
flexShrink: 0,
|
|
3868
|
+
backgroundColor: fpsColor,
|
|
3869
|
+
...isCritical && {
|
|
3870
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
3871
|
+
}
|
|
3900
3872
|
}
|
|
3901
3873
|
}), jsx("span", {
|
|
3874
|
+
className: "u-text-xs",
|
|
3902
3875
|
style: {
|
|
3903
|
-
fontSize: "
|
|
3904
|
-
|
|
3876
|
+
fontSize: "0.625rem",
|
|
3877
|
+
// 10px
|
|
3878
|
+
color: fpsColor
|
|
3905
3879
|
},
|
|
3906
|
-
children: metrics.fps
|
|
3880
|
+
children: getFpsLabel(metrics.fps)
|
|
3907
3881
|
}) ]
|
|
3908
3882
|
}) ]
|
|
3909
|
-
})
|
|
3910
|
-
};
|
|
3883
|
+
});
|
|
3884
|
+
}));
|
|
3911
3885
|
|
|
3912
|
-
|
|
3913
|
-
if ("undefined" != typeof document) {
|
|
3914
|
-
const styleSheet = document.createElement("style");
|
|
3915
|
-
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
3916
|
-
document.head.appendChild(styleSheet);
|
|
3917
|
-
}
|
|
3886
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
3918
3887
|
|
|
3919
3888
|
/**
|
|
3920
3889
|
* Mobile optimization presets
|
|
@@ -3925,7 +3894,8 @@ if ("undefined" != typeof document) {
|
|
|
3925
3894
|
/**
|
|
3926
3895
|
* Performance preset - Maximum FPS, reduced quality
|
|
3927
3896
|
* Best for low-end devices or when battery saving is priority
|
|
3928
|
-
*/
|
|
3897
|
+
*/
|
|
3898
|
+
const PERFORMANCE_PRESET = {
|
|
3929
3899
|
distortionOctaves: 2,
|
|
3930
3900
|
// Minimal FBM layers
|
|
3931
3901
|
displacementScale: 50,
|
|
@@ -4088,90 +4058,21 @@ function getDevicePreset(presetName) {
|
|
|
4088
4058
|
getPixelRatio: () => "undefined" == typeof window ? 1 : window.devicePixelRatio || 1,
|
|
4089
4059
|
/** Check if device has touch support */
|
|
4090
4060
|
hasTouchSupport: () => "undefined" != typeof window && ("ontouchstart" in window || navigator.maxTouchPoints > 0)
|
|
4091
|
-
}
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
* - Design token integration for consistent theming
|
|
4104
|
-
* - Focus ring support for keyboard navigation
|
|
4105
|
-
* - Responsive breakpoints for mobile optimization
|
|
4106
|
-
* - Enhanced ARIA attributes for screen readers
|
|
4107
|
-
* - Time-based animation system with FBM distortion
|
|
4108
|
-
* - Device preset optimization for performance/quality balance
|
|
4109
|
-
*
|
|
4110
|
-
* Design System Compliance:
|
|
4111
|
-
* - Uses design tokens for opacity, spacing, and colors
|
|
4112
|
-
* - Follows BEM methodology for class naming
|
|
4113
|
-
* - Implements focus-ring mixin for accessibility
|
|
4114
|
-
* - Supports reduced motion and high contrast preferences
|
|
4115
|
-
*
|
|
4116
|
-
* @example
|
|
4117
|
-
* // Basic usage with dynamic border-radius extraction
|
|
4118
|
-
* <AtomixGlass>
|
|
4119
|
-
* <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
|
|
4120
|
-
* </AtomixGlass>
|
|
4121
|
-
*
|
|
4122
|
-
* @example
|
|
4123
|
-
* // Manual border-radius override
|
|
4124
|
-
* <AtomixGlass borderRadius={20}>
|
|
4125
|
-
* <div>Content with 20px glass radius</div>
|
|
4126
|
-
* </AtomixGlass>
|
|
4127
|
-
*
|
|
4128
|
-
* @example
|
|
4129
|
-
* // Interactive glass with click handler
|
|
4130
|
-
* <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
|
|
4131
|
-
* <div>Clickable content</div>
|
|
4132
|
-
* </AtomixGlass>
|
|
4133
|
-
*
|
|
4134
|
-
* @example
|
|
4135
|
-
* // OverLight - Boolean mode (explicit control)
|
|
4136
|
-
* <AtomixGlass overLight={true}>
|
|
4137
|
-
* <div>Content on light background</div>
|
|
4138
|
-
* </AtomixGlass>
|
|
4139
|
-
*
|
|
4140
|
-
* @example
|
|
4141
|
-
* // OverLight - Auto-detection mode
|
|
4142
|
-
* <AtomixGlass overLight="auto">
|
|
4143
|
-
* <div>Content with auto-detected background</div>
|
|
4144
|
-
* </AtomixGlass>
|
|
4145
|
-
*
|
|
4146
|
-
* @example
|
|
4147
|
-
* // OverLight - Object config with custom settings
|
|
4148
|
-
* <AtomixGlass
|
|
4149
|
-
* overLight={{
|
|
4150
|
-
* threshold: 0.8,
|
|
4151
|
-
* opacity: 0.6,
|
|
4152
|
-
* contrast: 1.8,
|
|
4153
|
-
* brightness: 1.0,
|
|
4154
|
-
* saturationBoost: 1.5
|
|
4155
|
-
* }}
|
|
4156
|
-
* >
|
|
4157
|
-
* <div>Content with custom overLight config</div>
|
|
4158
|
-
* </AtomixGlass>
|
|
4159
|
-
*
|
|
4160
|
-
* @example
|
|
4161
|
-
* // Debug mode for overLight detection
|
|
4162
|
-
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
4163
|
-
* <div>Content with debug logging enabled</div>
|
|
4164
|
-
* </AtomixGlass>
|
|
4165
|
-
*
|
|
4166
|
-
* @example
|
|
4167
|
-
* // Performance-optimized for mobile devices
|
|
4168
|
-
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
4169
|
-
* <div>Mobile-optimized glass effect</div>
|
|
4170
|
-
* </AtomixGlass>
|
|
4171
|
-
*/ function AtomixGlass({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, withLiquidBlur: withLiquidBlur = !1, withBorder: withBorder = !0, withOverLightLayers: withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, debugPerformance: debugPerformance = !1, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, ...rest}) {
|
|
4172
|
-
const glassRef = useRef(null), contentRef = useRef(null), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, getShaderTime: getShaderTime, applyTimeBasedDistortion: applyTimeBasedDistortion, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
4061
|
+
}, AtomixGlassInner = forwardRef((function({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, withLiquidBlur: withLiquidBlur = !1, withBorder: withBorder = !0, withOverLightLayers: withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, debugPerformance: debugPerformance = !1, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, isFixedOrSticky: propsIsFixedOrSticky, ...rest}, ref) {
|
|
4062
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
|
|
4063
|
+
// Helper to merge refs
|
|
4064
|
+
function(...refs) {
|
|
4065
|
+
return node => {
|
|
4066
|
+
refs.forEach((ref => {
|
|
4067
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
4068
|
+
}));
|
|
4069
|
+
};
|
|
4070
|
+
}
|
|
4071
|
+
// Internal implementation with forwardRef
|
|
4072
|
+
(ref, internalWrapperRef)), [ ref ]), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = propsIsFixedOrSticky || "fixed" === restStyle.position || "sticky" === restStyle.position, {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, getShaderTime: getShaderTime, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
4173
4073
|
glassRef: glassRef,
|
|
4174
4074
|
contentRef: contentRef,
|
|
4075
|
+
wrapperRef: internalWrapperRef,
|
|
4175
4076
|
borderRadius: borderRadius,
|
|
4176
4077
|
globalMousePosition: externalGlobalMousePosition,
|
|
4177
4078
|
mouseOffset: externalMouseOffset,
|
|
@@ -4200,7 +4101,6 @@ function getDevicePreset(presetName) {
|
|
|
4200
4101
|
distortionGain: distortionGain,
|
|
4201
4102
|
distortionQuality: distortionQuality
|
|
4202
4103
|
});
|
|
4203
|
-
// Re-calculate only when devicePreset changes
|
|
4204
4104
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
4205
4105
|
useResponsiveGlass({
|
|
4206
4106
|
baseParams: {
|
|
@@ -4215,22 +4115,21 @@ function getDevicePreset(presetName) {
|
|
|
4215
4115
|
},
|
|
4216
4116
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
4217
4117
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
4218
|
-
// Enable unless disabled
|
|
4219
4118
|
debug: !1
|
|
4220
4119
|
});
|
|
4221
4120
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
4222
|
-
const {metrics: performanceMetrics,
|
|
4223
|
-
enabled:
|
|
4224
|
-
//
|
|
4121
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} = usePerformanceMonitor({
|
|
4122
|
+
enabled: debugPerformance,
|
|
4123
|
+
// Enable when debugPerformance is true
|
|
4225
4124
|
debug: !1,
|
|
4226
4125
|
showOverlay: !1
|
|
4227
4126
|
});
|
|
4228
|
-
// Auto-start performance monitoring
|
|
4127
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
4229
4128
|
React.useEffect((() => {
|
|
4230
|
-
|
|
4129
|
+
debugPerformance && toggleMonitoring();
|
|
4231
4130
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4232
|
-
}), []);
|
|
4233
|
-
//
|
|
4131
|
+
}), [ debugPerformance ]);
|
|
4132
|
+
// Re-run when debugPerformance changes
|
|
4234
4133
|
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
4235
4134
|
if (!isFixedOrSticky) return {};
|
|
4236
4135
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -4258,34 +4157,30 @@ function getDevicePreset(presetName) {
|
|
|
4258
4157
|
if (isFixedOrSticky) {
|
|
4259
4158
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
4260
4159
|
return {
|
|
4261
|
-
...visualStyle
|
|
4262
|
-
...!effectiveWithoutEffects && {
|
|
4263
|
-
transform: transformStyle
|
|
4264
|
-
}
|
|
4160
|
+
...visualStyle
|
|
4265
4161
|
};
|
|
4266
4162
|
}
|
|
4267
4163
|
return {
|
|
4268
|
-
...restStyle
|
|
4269
|
-
...!effectiveWithoutEffects && {
|
|
4270
|
-
transform: transformStyle
|
|
4271
|
-
}
|
|
4164
|
+
...restStyle
|
|
4272
4165
|
};
|
|
4273
|
-
}), [ isFixedOrSticky, restStyle
|
|
4166
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
4274
4167
|
// Build className with state modifiers
|
|
4275
4168
|
const componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
|
|
4276
4169
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
4277
|
-
top: isFixedOrSticky ?
|
|
4278
|
-
left: isFixedOrSticky ?
|
|
4279
|
-
|
|
4170
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
4171
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
4172
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
4173
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
4174
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
4280
4175
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
4281
4176
|
// but sizing is driven by explicit width/height or measured size.
|
|
4282
4177
|
positionStyles.position;
|
|
4283
|
-
const resolveLength = (value, measured) => void 0 !== value ? "number" == typeof value ? `${value}px` : value : measured > 0 ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
4178
|
+
const resolveLength = (value, measured) => void 0 !== value && isFixedOrSticky ? "number" == typeof value ? `${value}px` : value : measured > 0 && isFixedOrSticky ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
|
|
4284
4179
|
return {
|
|
4285
4180
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
4286
4181
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
4287
4182
|
};
|
|
4288
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
4183
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
|
|
4289
4184
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
4290
4185
|
return {
|
|
4291
4186
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -4315,33 +4210,32 @@ function getDevicePreset(presetName) {
|
|
|
4315
4210
|
absMx: absMx,
|
|
4316
4211
|
absMy: absMy
|
|
4317
4212
|
};
|
|
4318
|
-
}), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
};
|
|
4327
|
-
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
|
|
4328
|
-
const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues, configBorderOpacity = overLightConfig?.borderOpacity ?? 1;
|
|
4213
|
+
}), [ mouseOffset.x, mouseOffset.y ]), clampedOverLightOpacity = Math.max(0, Math.min(1, overLightConfig?.opacity ?? .4)), clampedBorderOpacity = Math.max(0, Math.min(1, overLightConfig?.borderOpacity ?? 1)), opacityValues = useMemo((() => ({
|
|
4214
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
4215
|
+
hover2: isActive ? .5 : 0,
|
|
4216
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
4217
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
4218
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
4219
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
|
|
4220
|
+
const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues;
|
|
4329
4221
|
return {
|
|
4330
4222
|
...void 0 !== customZIndex && {
|
|
4331
4223
|
"--atomix-glass-base-z-index": customZIndex
|
|
4332
4224
|
},
|
|
4333
4225
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
4334
4226
|
"--atomix-glass-transform": transformStyle || "none",
|
|
4335
|
-
|
|
4336
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
4337
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
4338
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
4227
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
4228
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
4229
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
4230
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
4231
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
4232
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
4339
4233
|
"--atomix-glass-width": adjustedSize.width,
|
|
4340
4234
|
"--atomix-glass-height": adjustedSize.height,
|
|
4341
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
4235
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
4342
4236
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
4343
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) *
|
|
4344
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) *
|
|
4237
|
+
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * clampedBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * clampedBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
4238
|
+
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * clampedBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * clampedBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
4345
4239
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
4346
4240
|
"--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
|
|
4347
4241
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -4355,13 +4249,14 @@ function getDevicePreset(presetName) {
|
|
|
4355
4249
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
4356
4250
|
"--atomix-glass-overlay-highlight-bg": `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
|
|
4357
4251
|
};
|
|
4358
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
4252
|
+
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, clampedBorderOpacity, customZIndex, isFixedOrSticky, positionStyles.position, rootLayoutStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), renderBackgroundLayer = layerType => jsx("div", {
|
|
4359
4253
|
className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" ")
|
|
4360
4254
|
});
|
|
4361
4255
|
// Calculate position and size styles for internal layers
|
|
4362
4256
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
4363
4257
|
return jsxs("div", {
|
|
4364
4258
|
...rest,
|
|
4259
|
+
ref: mergedRef,
|
|
4365
4260
|
className: componentClassName,
|
|
4366
4261
|
style: {
|
|
4367
4262
|
...glassVars
|
|
@@ -4371,17 +4266,14 @@ function getDevicePreset(presetName) {
|
|
|
4371
4266
|
"aria-label": ariaLabel,
|
|
4372
4267
|
"aria-describedby": ariaDescribedBy,
|
|
4373
4268
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
4374
|
-
"aria-pressed":
|
|
4269
|
+
"aria-pressed": void 0,
|
|
4375
4270
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
4376
4271
|
children: [ jsx(AtomixGlassContainer, {
|
|
4377
4272
|
ref: glassRef,
|
|
4378
4273
|
contentRef: contentRef,
|
|
4379
4274
|
className: className,
|
|
4380
4275
|
style: {
|
|
4381
|
-
...restStyle
|
|
4382
|
-
...!isFixedOrSticky && {
|
|
4383
|
-
position: "relative"
|
|
4384
|
-
}
|
|
4276
|
+
...restStyle
|
|
4385
4277
|
},
|
|
4386
4278
|
borderRadius: effectiveBorderRadius,
|
|
4387
4279
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -4417,6 +4309,7 @@ function getDevicePreset(presetName) {
|
|
|
4417
4309
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
4418
4310
|
shaderVariant: shaderVariant,
|
|
4419
4311
|
withLiquidBlur: withLiquidBlur,
|
|
4312
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
4420
4313
|
// Phase 1: Animation System props
|
|
4421
4314
|
shaderTime: getShaderTime(),
|
|
4422
4315
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -4445,6 +4338,8 @@ function getDevicePreset(presetName) {
|
|
|
4445
4338
|
}) ]
|
|
4446
4339
|
}), withBorder && jsxs(Fragment, {
|
|
4447
4340
|
children: [ jsx("span", {
|
|
4341
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
4342
|
+
}), jsx("span", {
|
|
4448
4343
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
4449
4344
|
}), jsx("span", {
|
|
4450
4345
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -4455,10 +4350,15 @@ function getDevicePreset(presetName) {
|
|
|
4455
4350
|
onClose: () => {}
|
|
4456
4351
|
}) ]
|
|
4457
4352
|
});
|
|
4458
|
-
}
|
|
4353
|
+
}));
|
|
4459
4354
|
|
|
4460
|
-
|
|
4461
|
-
|
|
4355
|
+
AtomixGlassInner.displayName = "AtomixGlass";
|
|
4356
|
+
|
|
4357
|
+
/**
|
|
4358
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
4359
|
+
* Ref is forwarded to the root `<div>` element.
|
|
4360
|
+
*/
|
|
4361
|
+
const AtomixGlass = memo(AtomixGlassInner), DefaultIcon = () => jsx("i", {
|
|
4462
4362
|
className: "c-accordion__icon",
|
|
4463
4363
|
"aria-hidden": "true",
|
|
4464
4364
|
children: jsx("svg", {
|
|
@@ -4492,6 +4392,7 @@ const DefaultIcon = () => jsx("i", {
|
|
|
4492
4392
|
});
|
|
4493
4393
|
}));
|
|
4494
4394
|
|
|
4395
|
+
// Default icon
|
|
4495
4396
|
AccordionHeader.displayName = "AccordionHeader";
|
|
4496
4397
|
|
|
4497
4398
|
const AccordionBody = forwardRef((({children: children, className: className = "", panelRef: panelRef, contentRef: contentRef, ...props}, ref) => {
|
|
@@ -5410,7 +5311,152 @@ class ThemeNaming {
|
|
|
5410
5311
|
|
|
5411
5312
|
ThemeNaming.prefix = "atomix";
|
|
5412
5313
|
|
|
5413
|
-
|
|
5314
|
+
var aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike = lengthOfArrayLike$2, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
|
|
5315
|
+
return function(that, callbackfn, argumentsLength, memo) {
|
|
5316
|
+
var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
|
|
5317
|
+
if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
|
|
5318
|
+
var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
|
|
5319
|
+
if (argumentsLength < 2) for (;;) {
|
|
5320
|
+
if (index in self) {
|
|
5321
|
+
memo = self[index], index += i;
|
|
5322
|
+
break;
|
|
5323
|
+
}
|
|
5324
|
+
if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
|
|
5325
|
+
}
|
|
5326
|
+
for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
|
|
5327
|
+
return memo;
|
|
5328
|
+
};
|
|
5329
|
+
}, arrayReduce = {
|
|
5330
|
+
// `Array.prototype.reduce` method
|
|
5331
|
+
// https://tc39.es/ecma262/#sec-array.prototype.reduce
|
|
5332
|
+
left: createMethod(!1),
|
|
5333
|
+
// `Array.prototype.reduceRight` method
|
|
5334
|
+
// https://tc39.es/ecma262/#sec-array.prototype.reduceright
|
|
5335
|
+
right: createMethod(!0)
|
|
5336
|
+
}, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
|
|
5337
|
+
return userAgent.slice(0, string.length) === string;
|
|
5338
|
+
}, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$1.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$1.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$1.process) ? "NODE" : globalThis$1.window && globalThis$1.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
|
|
5339
|
+
|
|
5340
|
+
// `Array.prototype.reduce` method
|
|
5341
|
+
// https://tc39.es/ecma262/#sec-array.prototype.reduce
|
|
5342
|
+
_export({
|
|
5343
|
+
target: "Array",
|
|
5344
|
+
proto: !0,
|
|
5345
|
+
forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
|
|
5346
|
+
var method = [][METHOD_NAME];
|
|
5347
|
+
return !!method && fails((function() {
|
|
5348
|
+
// eslint-disable-next-line no-useless-call -- required for testing
|
|
5349
|
+
method.call(null, argument || function() {
|
|
5350
|
+
return 1;
|
|
5351
|
+
}, 1);
|
|
5352
|
+
}));
|
|
5353
|
+
}("reduce")
|
|
5354
|
+
}, {
|
|
5355
|
+
reduce: function(callbackfn /* , initialValue */) {
|
|
5356
|
+
var length = arguments.length;
|
|
5357
|
+
return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
|
|
5358
|
+
}
|
|
5359
|
+
});
|
|
5360
|
+
|
|
5361
|
+
var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
|
|
5362
|
+
|
|
5363
|
+
const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
5364
|
+
var own = it.reduce;
|
|
5365
|
+
return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
|
|
5366
|
+
}));
|
|
5367
|
+
|
|
5368
|
+
/**
|
|
5369
|
+
* Render a slot with the given props
|
|
5370
|
+
*
|
|
5371
|
+
* Priority order:
|
|
5372
|
+
* 1. render function
|
|
5373
|
+
* 2. component
|
|
5374
|
+
* 3. children
|
|
5375
|
+
* 4. fallback
|
|
5376
|
+
*
|
|
5377
|
+
* @example
|
|
5378
|
+
* renderSlot(
|
|
5379
|
+
* { render: (props) => <CustomButton {...props} /> },
|
|
5380
|
+
* { onClick: handleClick, children: 'Click me' }
|
|
5381
|
+
* )
|
|
5382
|
+
*/ function renderSlot(slot, props, fallback) {
|
|
5383
|
+
// No slot provided, use fallback
|
|
5384
|
+
if (!slot) return fallback;
|
|
5385
|
+
// Slot is a plain React node
|
|
5386
|
+
if ( React.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
|
|
5387
|
+
// Slot is an object with rendering options
|
|
5388
|
+
if ("object" == typeof slot && null !== slot) {
|
|
5389
|
+
const slotObj = slot;
|
|
5390
|
+
// Priority 1: render function
|
|
5391
|
+
if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
|
|
5392
|
+
// Priority 2: component
|
|
5393
|
+
if (slotObj.component) {
|
|
5394
|
+
const Component = slotObj.component;
|
|
5395
|
+
return jsx(Component, {
|
|
5396
|
+
...props
|
|
5397
|
+
});
|
|
5398
|
+
}
|
|
5399
|
+
// Priority 3: children
|
|
5400
|
+
if (void 0 !== slotObj.children) return slotObj.children;
|
|
5401
|
+
}
|
|
5402
|
+
// Fallback
|
|
5403
|
+
return fallback;
|
|
5404
|
+
}
|
|
5405
|
+
|
|
5406
|
+
/**
|
|
5407
|
+
* Check if a value is a slot configuration
|
|
5408
|
+
*/ function isSlot(value) {
|
|
5409
|
+
return "object" == typeof value && null !== value && ("render" in value || "component" in value || "children" in value);
|
|
5410
|
+
}
|
|
5411
|
+
|
|
5412
|
+
/**
|
|
5413
|
+
* Merge multiple slot configurations
|
|
5414
|
+
* Later slots override earlier ones
|
|
5415
|
+
*/ function mergeSlots(...slots) {
|
|
5416
|
+
const filtered = slots.filter((s => void 0 !== s));
|
|
5417
|
+
if (0 !== filtered.length) return 1 === filtered.length ? filtered[0] : _reduceInstanceProperty(filtered).call(filtered, ((acc, slot) => ({
|
|
5418
|
+
...acc,
|
|
5419
|
+
...slot
|
|
5420
|
+
})));
|
|
5421
|
+
}
|
|
5422
|
+
|
|
5423
|
+
/**
|
|
5424
|
+
* Create a slot wrapper component
|
|
5425
|
+
*
|
|
5426
|
+
* @example
|
|
5427
|
+
* const ButtonSlot = createSlotComponent<ButtonSlotProps>('button')
|
|
5428
|
+
*
|
|
5429
|
+
* <ButtonSlot slot={customSlot} {...props}>
|
|
5430
|
+
* Default content
|
|
5431
|
+
* </ButtonSlot>
|
|
5432
|
+
*/ function createSlotComponent(defaultElement = "div") {
|
|
5433
|
+
return function({slot: slot, children: children, ...props}) {
|
|
5434
|
+
const slotProps = props;
|
|
5435
|
+
return slot ? jsx(Fragment, {
|
|
5436
|
+
children: renderSlot(slot, slotProps, children)
|
|
5437
|
+
}) : jsx(defaultElement, "string" == typeof defaultElement ? {
|
|
5438
|
+
...props,
|
|
5439
|
+
children: children
|
|
5440
|
+
} : {
|
|
5441
|
+
...slotProps,
|
|
5442
|
+
children: children
|
|
5443
|
+
});
|
|
5444
|
+
};
|
|
5445
|
+
}
|
|
5446
|
+
|
|
5447
|
+
/**
|
|
5448
|
+
* Utility to create typed slot props
|
|
5449
|
+
*/ function createSlotProps(props) {
|
|
5450
|
+
return props;
|
|
5451
|
+
}
|
|
5452
|
+
|
|
5453
|
+
/**
|
|
5454
|
+
* Hook to manage slot rendering
|
|
5455
|
+
*/ function useSlot(slot, props, fallback) {
|
|
5456
|
+
return React.useMemo((() => renderSlot(slot, props, fallback)), [ slot, props, fallback ]);
|
|
5457
|
+
}
|
|
5458
|
+
|
|
5459
|
+
const Button = React.memo( forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, linkComponent: linkComponent, slots: slots, ...props}, ref) => {
|
|
5414
5460
|
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href), iconElement = iconName ? jsx(Icon, {
|
|
5415
5461
|
name: iconName,
|
|
5416
5462
|
size: iconSize
|
|
@@ -5426,17 +5472,28 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
5426
5472
|
children: [ loading && jsx("span", {
|
|
5427
5473
|
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
|
|
5428
5474
|
"aria-hidden": "true",
|
|
5429
|
-
children:
|
|
5475
|
+
children: renderSlot(slots?.spinner, {
|
|
5476
|
+
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
|
|
5430
5477
|
size: spinnerSize,
|
|
5431
5478
|
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
|
|
5432
|
-
}
|
|
5479
|
+
}, jsx(Spinner, {
|
|
5480
|
+
size: spinnerSize,
|
|
5481
|
+
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
|
|
5482
|
+
}))
|
|
5433
5483
|
}), iconElement && !loading && jsx("span", {
|
|
5434
5484
|
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
|
|
5435
5485
|
"aria-hidden": "true",
|
|
5436
|
-
children:
|
|
5486
|
+
children: renderSlot(slots?.icon, {
|
|
5487
|
+
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
|
|
5488
|
+
children: iconElement,
|
|
5489
|
+
size: iconSize
|
|
5490
|
+
}, iconElement)
|
|
5437
5491
|
}), !iconOnly && buttonText && jsx("span", {
|
|
5438
5492
|
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.LABEL_ELEMENT),
|
|
5439
|
-
children:
|
|
5493
|
+
children: renderSlot(slots?.label, {
|
|
5494
|
+
className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.LABEL_ELEMENT),
|
|
5495
|
+
children: buttonText
|
|
5496
|
+
}, buttonText)
|
|
5440
5497
|
}) ]
|
|
5441
5498
|
}), buttonProps = {
|
|
5442
5499
|
className: buttonClass,
|
|
@@ -5453,48 +5510,59 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
5453
5510
|
tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
|
|
5454
5511
|
style: style,
|
|
5455
5512
|
...props
|
|
5456
|
-
}
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5513
|
+
}, buttonChildren = renderSlot(slots?.root, {
|
|
5514
|
+
className: buttonClass,
|
|
5515
|
+
children: buttonContent,
|
|
5516
|
+
disabled: isDisabled,
|
|
5517
|
+
loading: loading,
|
|
5518
|
+
onClick: handleClickEvent,
|
|
5519
|
+
type: type,
|
|
5520
|
+
"aria-label": safeAriaLabel,
|
|
5521
|
+
"aria-disabled": isDisabled,
|
|
5522
|
+
"aria-busy": loading
|
|
5523
|
+
}, (() => {
|
|
5524
|
+
// Render as anchor if href is provided
|
|
5525
|
+
if (shouldRenderAsLink) {
|
|
5526
|
+
// Use custom linkComponent if provided (e.g., Next.js Link)
|
|
5527
|
+
if (linkComponent) {
|
|
5528
|
+
const LinkComp = linkComponent, linkProps = {
|
|
5529
|
+
...buttonProps,
|
|
5530
|
+
ref: ref,
|
|
5531
|
+
// linkComponent usually forwards ref to anchor
|
|
5532
|
+
href: isDisabled ? void 0 : href,
|
|
5533
|
+
to: isDisabled ? void 0 : href,
|
|
5534
|
+
target: target,
|
|
5535
|
+
rel: "_blank" === target ? "noopener noreferrer" : void 0
|
|
5536
|
+
};
|
|
5537
|
+
return jsx(LinkComp, {
|
|
5538
|
+
...linkProps,
|
|
5539
|
+
children: buttonContent
|
|
5540
|
+
});
|
|
5541
|
+
}
|
|
5542
|
+
// Fallback to regular anchor tag
|
|
5543
|
+
return jsx("a", {
|
|
5544
|
+
...buttonProps,
|
|
5545
|
+
ref: ref,
|
|
5546
|
+
href: isDisabled ? void 0 : href,
|
|
5547
|
+
target: target,
|
|
5548
|
+
rel: "_blank" === target ? "noopener noreferrer" : void 0,
|
|
5549
|
+
children: buttonContent
|
|
5550
|
+
});
|
|
5551
|
+
}
|
|
5552
|
+
// Default button rendering
|
|
5553
|
+
return jsx(Component, {
|
|
5467
5554
|
...buttonProps,
|
|
5468
5555
|
ref: ref,
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
to: isDisabled ? void 0 : href,
|
|
5472
|
-
target: target,
|
|
5473
|
-
rel: "_blank" === target ? "noopener noreferrer" : void 0
|
|
5474
|
-
};
|
|
5475
|
-
content = jsx(LinkComp, {
|
|
5476
|
-
...linkProps,
|
|
5556
|
+
type: "button" === Component ? type : void 0,
|
|
5557
|
+
disabled: isDisabled,
|
|
5477
5558
|
children: buttonContent
|
|
5478
5559
|
});
|
|
5479
|
-
}
|
|
5480
|
-
//
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
target: target,
|
|
5486
|
-
rel: "_blank" === target ? "noopener noreferrer" : void 0,
|
|
5487
|
-
children: buttonContent
|
|
5488
|
-
}); else
|
|
5489
|
-
// Default button rendering
|
|
5490
|
-
content = jsx(Component, {
|
|
5491
|
-
...buttonProps,
|
|
5492
|
-
ref: ref,
|
|
5493
|
-
type: "button" === Component ? type : void 0,
|
|
5494
|
-
disabled: isDisabled,
|
|
5495
|
-
children: buttonContent
|
|
5496
|
-
});
|
|
5497
|
-
if (glass) {
|
|
5560
|
+
})());
|
|
5561
|
+
// Determine if we should render as a link
|
|
5562
|
+
// If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
|
|
5563
|
+
// The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
|
|
5564
|
+
// This is a safe fallback for disabled links.
|
|
5565
|
+
if (glass) {
|
|
5498
5566
|
// Default glass props
|
|
5499
5567
|
const defaultGlassProps = {
|
|
5500
5568
|
displacementScale: 20,
|
|
@@ -5507,10 +5575,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
5507
5575
|
};
|
|
5508
5576
|
return jsx(AtomixGlass, {
|
|
5509
5577
|
...glassProps,
|
|
5510
|
-
children:
|
|
5578
|
+
children: buttonChildren
|
|
5511
5579
|
});
|
|
5512
5580
|
}
|
|
5513
|
-
return
|
|
5581
|
+
return buttonChildren;
|
|
5514
5582
|
})));
|
|
5515
5583
|
|
|
5516
5584
|
Button.displayName = "Button";
|
|
@@ -6022,67 +6090,12 @@ const ElevationCard = ({elevationClass: elevationClass = "is-elevated", classNam
|
|
|
6022
6090
|
});
|
|
6023
6091
|
};
|
|
6024
6092
|
|
|
6025
|
-
ElevationCard.displayName = "ElevationCard";
|
|
6026
|
-
|
|
6027
|
-
var aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike = lengthOfArrayLike$2, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
|
|
6028
|
-
return function(that, callbackfn, argumentsLength, memo) {
|
|
6029
|
-
var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
|
|
6030
|
-
if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
|
|
6031
|
-
var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
|
|
6032
|
-
if (argumentsLength < 2) for (;;) {
|
|
6033
|
-
if (index in self) {
|
|
6034
|
-
memo = self[index], index += i;
|
|
6035
|
-
break;
|
|
6036
|
-
}
|
|
6037
|
-
if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
|
|
6038
|
-
}
|
|
6039
|
-
for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
|
|
6040
|
-
return memo;
|
|
6041
|
-
};
|
|
6042
|
-
}, arrayReduce = {
|
|
6043
|
-
// `Array.prototype.reduce` method
|
|
6044
|
-
// https://tc39.es/ecma262/#sec-array.prototype.reduce
|
|
6045
|
-
left: createMethod(!1),
|
|
6046
|
-
// `Array.prototype.reduceRight` method
|
|
6047
|
-
// https://tc39.es/ecma262/#sec-array.prototype.reduceright
|
|
6048
|
-
right: createMethod(!0)
|
|
6049
|
-
}, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
|
|
6050
|
-
return userAgent.slice(0, string.length) === string;
|
|
6051
|
-
}, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$1.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$1.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$1.process) ? "NODE" : globalThis$1.window && globalThis$1.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
|
|
6052
|
-
|
|
6053
|
-
// `Array.prototype.reduce` method
|
|
6054
|
-
// https://tc39.es/ecma262/#sec-array.prototype.reduce
|
|
6055
|
-
_export({
|
|
6056
|
-
target: "Array",
|
|
6057
|
-
proto: !0,
|
|
6058
|
-
forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
|
|
6059
|
-
var method = [][METHOD_NAME];
|
|
6060
|
-
return !!method && fails((function() {
|
|
6061
|
-
// eslint-disable-next-line no-useless-call -- required for testing
|
|
6062
|
-
method.call(null, argument || function() {
|
|
6063
|
-
return 1;
|
|
6064
|
-
}, 1);
|
|
6065
|
-
}));
|
|
6066
|
-
}("reduce")
|
|
6067
|
-
}, {
|
|
6068
|
-
reduce: function(callbackfn /* , initialValue */) {
|
|
6069
|
-
var length = arguments.length;
|
|
6070
|
-
return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
|
|
6071
|
-
}
|
|
6072
|
-
});
|
|
6073
|
-
|
|
6074
|
-
var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
|
|
6075
|
-
|
|
6076
|
-
const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
6077
|
-
var own = it.reduce;
|
|
6078
|
-
return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
|
|
6079
|
-
}));
|
|
6080
|
-
|
|
6081
6093
|
/**
|
|
6082
6094
|
* Comprehensive chart hook with shared functionality
|
|
6083
6095
|
* @param initialProps - Initial chart properties
|
|
6084
6096
|
* @returns Chart state and methods
|
|
6085
|
-
*/
|
|
6097
|
+
*/
|
|
6098
|
+
function useChart(initialProps) {
|
|
6086
6099
|
const [interactionState, setInteractionState] = useState({
|
|
6087
6100
|
hoveredPoint: null,
|
|
6088
6101
|
selectedPoints: [],
|
|
@@ -6114,8 +6127,11 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
6114
6127
|
}), animationFrameRef = useRef(null);
|
|
6115
6128
|
// Default chart properties
|
|
6116
6129
|
// Cleanup animation frame on unmount
|
|
6117
|
-
useEffect((() =>
|
|
6118
|
-
|
|
6130
|
+
useEffect((() => {
|
|
6131
|
+
const currentRef = animationFrameRef.current;
|
|
6132
|
+
return () => {
|
|
6133
|
+
currentRef && cancelAnimationFrame(currentRef);
|
|
6134
|
+
};
|
|
6119
6135
|
}), []);
|
|
6120
6136
|
/**
|
|
6121
6137
|
* Point interaction handlers
|
|
@@ -6506,7 +6522,9 @@ function getDatasetBounds(data) {
|
|
|
6506
6522
|
|
|
6507
6523
|
/**
|
|
6508
6524
|
* Hook for managing chart toolbar state and generating chart-specific configurations
|
|
6509
|
-
*/
|
|
6525
|
+
*/ ElevationCard.displayName = "ElevationCard";
|
|
6526
|
+
|
|
6527
|
+
const ChartToolbar = memo( forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
|
|
6510
6528
|
refresh: !0,
|
|
6511
6529
|
export: !0,
|
|
6512
6530
|
fullscreen: !0,
|
|
@@ -6996,8 +7014,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
6996
7014
|
}), [ chartType ]), finalDefaults = useMemo((() => ({
|
|
6997
7015
|
...getChartDefaults(),
|
|
6998
7016
|
...defaults
|
|
6999
|
-
})), [ getChartDefaults, defaults ]), enhancedHandlers = {
|
|
7000
|
-
onRefresh:
|
|
7017
|
+
})), [ getChartDefaults, defaults ]), enhancedHandlers = useMemo((() => ({
|
|
7018
|
+
onRefresh: () => {
|
|
7001
7019
|
setState((prev => ({
|
|
7002
7020
|
...prev,
|
|
7003
7021
|
isRefreshing: !0
|
|
@@ -7007,8 +7025,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
7007
7025
|
isRefreshing: !1
|
|
7008
7026
|
})));
|
|
7009
7027
|
}), 1e3);
|
|
7010
|
-
}
|
|
7011
|
-
onExport:
|
|
7028
|
+
},
|
|
7029
|
+
onExport: async format => {
|
|
7012
7030
|
setState((prev => ({
|
|
7013
7031
|
...prev,
|
|
7014
7032
|
isExporting: !0
|
|
@@ -7021,70 +7039,70 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
7021
7039
|
isExporting: !1
|
|
7022
7040
|
})));
|
|
7023
7041
|
}
|
|
7024
|
-
}
|
|
7025
|
-
onFullscreen:
|
|
7042
|
+
},
|
|
7043
|
+
onFullscreen: isFullscreen => {
|
|
7026
7044
|
setState((prev => ({
|
|
7027
7045
|
...prev,
|
|
7028
7046
|
isFullscreen: isFullscreen
|
|
7029
7047
|
}))), handlers.onFullscreen?.(isFullscreen);
|
|
7030
|
-
}
|
|
7031
|
-
onZoomIn:
|
|
7048
|
+
},
|
|
7049
|
+
onZoomIn: () => {
|
|
7032
7050
|
setState((prev => ({
|
|
7033
7051
|
...prev,
|
|
7034
7052
|
zoomLevel: Math.min(1.2 * prev.zoomLevel, 5)
|
|
7035
7053
|
}))), handlers.onZoomIn?.();
|
|
7036
|
-
}
|
|
7037
|
-
onZoomOut:
|
|
7054
|
+
},
|
|
7055
|
+
onZoomOut: () => {
|
|
7038
7056
|
setState((prev => ({
|
|
7039
7057
|
...prev,
|
|
7040
7058
|
zoomLevel: Math.max(prev.zoomLevel / 1.2, .2)
|
|
7041
7059
|
}))), handlers.onZoomOut?.();
|
|
7042
|
-
}
|
|
7043
|
-
onZoomReset:
|
|
7060
|
+
},
|
|
7061
|
+
onZoomReset: () => {
|
|
7044
7062
|
setState((prev => ({
|
|
7045
7063
|
...prev,
|
|
7046
7064
|
zoomLevel: 1
|
|
7047
7065
|
}))), handlers.onZoomReset?.();
|
|
7048
|
-
}
|
|
7049
|
-
onPanToggle:
|
|
7066
|
+
},
|
|
7067
|
+
onPanToggle: enabled => {
|
|
7050
7068
|
setState((prev => ({
|
|
7051
7069
|
...prev,
|
|
7052
7070
|
panEnabled: enabled
|
|
7053
7071
|
}))), handlers.onPanToggle?.(enabled);
|
|
7054
|
-
}
|
|
7055
|
-
onReset:
|
|
7072
|
+
},
|
|
7073
|
+
onReset: () => {
|
|
7056
7074
|
setState((prev => ({
|
|
7057
7075
|
...prev,
|
|
7058
7076
|
zoomLevel: 1,
|
|
7059
7077
|
panEnabled: !1
|
|
7060
7078
|
}))), handlers.onReset?.();
|
|
7061
|
-
}
|
|
7062
|
-
onGridToggle:
|
|
7079
|
+
},
|
|
7080
|
+
onGridToggle: show => {
|
|
7063
7081
|
setState((prev => ({
|
|
7064
7082
|
...prev,
|
|
7065
7083
|
showGrid: show
|
|
7066
7084
|
}))), handlers.onGridToggle?.(show);
|
|
7067
|
-
}
|
|
7068
|
-
onLegendToggle:
|
|
7085
|
+
},
|
|
7086
|
+
onLegendToggle: show => {
|
|
7069
7087
|
setState((prev => ({
|
|
7070
7088
|
...prev,
|
|
7071
7089
|
showLegend: show
|
|
7072
7090
|
}))), handlers.onLegendToggle?.(show);
|
|
7073
|
-
}
|
|
7074
|
-
onTooltipsToggle:
|
|
7091
|
+
},
|
|
7092
|
+
onTooltipsToggle: show => {
|
|
7075
7093
|
setState((prev => ({
|
|
7076
7094
|
...prev,
|
|
7077
7095
|
showTooltips: show
|
|
7078
7096
|
}))), handlers.onTooltipsToggle?.(show);
|
|
7079
|
-
}
|
|
7080
|
-
onAnimationsToggle:
|
|
7097
|
+
},
|
|
7098
|
+
onAnimationsToggle: enabled => {
|
|
7081
7099
|
setState((prev => ({
|
|
7082
7100
|
...prev,
|
|
7083
7101
|
animationsEnabled: enabled
|
|
7084
7102
|
}))), handlers.onAnimationsToggle?.(enabled);
|
|
7085
|
-
}
|
|
7086
|
-
onSettings:
|
|
7087
|
-
}, generateToolbarGroups = useCallback((() => {
|
|
7103
|
+
},
|
|
7104
|
+
onSettings: () => {}
|
|
7105
|
+
})), [ handlers ]), generateToolbarGroups = useCallback((() => {
|
|
7088
7106
|
const groups = [], dataActions = [];
|
|
7089
7107
|
// Data actions group
|
|
7090
7108
|
finalDefaults.refresh && dataActions.push({
|
|
@@ -7209,7 +7227,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
|
|
|
7209
7227
|
actions: customActions
|
|
7210
7228
|
});
|
|
7211
7229
|
return groups;
|
|
7212
|
-
}), [
|
|
7230
|
+
}), [ finalDefaults, state, enhancedHandlers, customActions, customGroups ]);
|
|
7213
7231
|
// Keyboard shortcuts
|
|
7214
7232
|
return useEffect((() => {
|
|
7215
7233
|
const handleKeyDown = event => {
|
|
@@ -7801,7 +7819,7 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
|
|
|
7801
7819
|
announcement: announcement,
|
|
7802
7820
|
focusedPoint: focusedPoint,
|
|
7803
7821
|
getAccessibleDescription: () => "Chart description"
|
|
7804
|
-
})), [ announcement, focusedPoint ]), transform = useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext
|
|
7822
|
+
})), [ announcement, focusedPoint ]), transform = useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext ]), chartData = useMemo((() => {
|
|
7805
7823
|
// Return null if dimensions not ready to prevent calculation with invalid dimensions
|
|
7806
7824
|
if (!isInitialized || 0 === dimensions.width || 0 === dimensions.height) return null;
|
|
7807
7825
|
const scales = calculateScales(processedData, dimensions.width, dimensions.height, void 0, config);
|
|
@@ -8214,7 +8232,7 @@ function useBarChart(datasets, options = {}) {
|
|
|
8214
8232
|
opacity: .4
|
|
8215
8233
|
} ]
|
|
8216
8234
|
};
|
|
8217
|
-
})) : []), [ options.useGradients ]), formatValue = useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options
|
|
8235
|
+
})) : []), [ options.useGradients ]), formatValue = useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options ]);
|
|
8218
8236
|
return {
|
|
8219
8237
|
// State
|
|
8220
8238
|
hoveredBar: hoveredBar,
|
|
@@ -8240,7 +8258,7 @@ function useBarChart(datasets, options = {}) {
|
|
|
8240
8258
|
y: horizontal ? y + height / 2 : y - 5
|
|
8241
8259
|
};
|
|
8242
8260
|
}
|
|
8243
|
-
}), [ options
|
|
8261
|
+
}), [ options ]),
|
|
8244
8262
|
// Handlers
|
|
8245
8263
|
handleBarHover: handleBarHover,
|
|
8246
8264
|
handleBarLeave: handleBarLeave,
|
|
@@ -8549,13 +8567,13 @@ const DonutChart = memo( forwardRef((({datasets: datasets = [], config: config
|
|
|
8549
8567
|
roundedCorners: !0
|
|
8550
8568
|
}, onDataPointClick: onDataPointClick, ...props}, ref) => {
|
|
8551
8569
|
// Use the first dataset for donut chart
|
|
8552
|
-
const dataset = datasets.length > 0 ? datasets[0] : {
|
|
8570
|
+
const dataset = useMemo((() => datasets.length > 0 ? datasets[0] : {
|
|
8553
8571
|
label: "",
|
|
8554
8572
|
data: []
|
|
8555
|
-
}, chartData = useMemo((() => {
|
|
8573
|
+
}), [ datasets ]), chartData = useMemo((() => {
|
|
8556
8574
|
if (!dataset?.data?.length) return null;
|
|
8557
8575
|
// Filter out invalid data points
|
|
8558
|
-
const validDataPoints = dataset?.data
|
|
8576
|
+
const validDataPoints = (dataset?.data || []).filter((point => "number" == typeof point.value && !isNaN(point.value) && isFinite(point.value) && point.value > 0));
|
|
8559
8577
|
return validDataPoints.length ? {
|
|
8560
8578
|
validDataPoints: validDataPoints
|
|
8561
8579
|
} : null;
|
|
@@ -9511,7 +9529,7 @@ function usePieChart(data, options = {}) {
|
|
|
9511
9529
|
const parts = [];
|
|
9512
9530
|
return !1 !== options.showLabels && parts.push(slice.label), options.showPercentages && parts.push(`${Math.round(slice.percentage)}%`),
|
|
9513
9531
|
options.showValues && parts.push(slice.value.toString()), parts.join(" - ");
|
|
9514
|
-
}), [ options
|
|
9532
|
+
}), [ 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 ]);
|
|
9515
9533
|
return {
|
|
9516
9534
|
// Data
|
|
9517
9535
|
processedData: processedData,
|
|
@@ -10938,7 +10956,7 @@ const DataTable = memo((({data: data, columns: columns, className: className, s
|
|
|
10938
10956
|
const newOrder = columns.map((col => col.key)), currentOrderSet = new Set(columnOrder), newOrderSet = new Set(newOrder);
|
|
10939
10957
|
// Only update if there are actual differences
|
|
10940
10958
|
newOrder.length === columnOrder.length && newOrder.every((key => currentOrderSet.has(key))) && columnOrder.every((key => newOrderSet.has(key))) || setColumnOrder(newOrder);
|
|
10941
|
-
}), [ columns ]),
|
|
10959
|
+
}), [ columns, columnOrder ]),
|
|
10942
10960
|
// Update column visibility when columns prop changes
|
|
10943
10961
|
useEffect((() => {
|
|
10944
10962
|
setColumnVisibility((prev => {
|
|
@@ -11483,7 +11501,7 @@ function formatDate(date, format) {
|
|
|
11483
11501
|
/**
|
|
11484
11502
|
* Check if a date is within a min and max range
|
|
11485
11503
|
*/ function useDatePicker({value: value, onChange: onChange, selectionMode: selectionMode = "single", startDate: startDate, endDate: endDate, onRangeChange: onRangeChange, format: format = "MM/dd/yyyy", minDate: minDate, maxDate: maxDate, inline: inline = !1} = {}) {
|
|
11486
|
-
const [isOpen, setIsOpen] = useState(inline), [inputValue, setInputValue] = useState(value ? formatDate(value, format) : ""), [rangeInputValue, setRangeInputValue] = useState(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""), [viewDate, setViewDate] = useState(value || startDate || new Date), [viewMode, setViewMode] = useState("days"), [rangeSelectionState, setRangeSelectionState] = useState(!startDate || startDate && endDate ? "start" : "end"), datePickerRef = useRef(null), inputRef = useRef(null), today = new Date, currentMonth = viewDate.getMonth(), currentYear = viewDate.getFullYear(), daysInMonth = getDaysInMonth(currentYear, currentMonth), firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
|
|
11504
|
+
const [isOpen, setIsOpen] = useState(inline), [inputValue, setInputValue] = useState(value ? formatDate(value, format) : ""), [rangeInputValue, setRangeInputValue] = useState(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""), [viewDate, setViewDate] = useState(value || startDate || new Date), [viewMode, setViewMode] = useState("days"), [rangeSelectionState, setRangeSelectionState] = useState(!startDate || startDate && endDate ? "start" : "end"), datePickerRef = useRef(null), inputRef = useRef(null), today = useMemo((() => new Date), []), currentMonth = viewDate.getMonth(), currentYear = viewDate.getFullYear(), daysInMonth = getDaysInMonth(currentYear, currentMonth), firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
|
|
11487
11505
|
// Update input value when value or range dates change externally
|
|
11488
11506
|
useEffect((() => {
|
|
11489
11507
|
"single" === selectionMode ? setInputValue(value ? formatDate(value, format) : "") : (setRangeInputValue(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""),
|
|
@@ -12006,21 +12024,11 @@ const DatePicker = forwardRef((({value: value, onChange: onChange, selectionMod
|
|
|
12006
12024
|
* @returns EdgePanel state and methods
|
|
12007
12025
|
*/
|
|
12008
12026
|
function useEdgePanel(initialProps) {
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
position
|
|
12012
|
-
mode: "slide",
|
|
12013
|
-
isOpen: !1,
|
|
12014
|
-
backdrop: !0,
|
|
12015
|
-
closeOnBackdropClick: !0,
|
|
12016
|
-
closeOnEscape: !0,
|
|
12017
|
-
glass: void 0,
|
|
12018
|
-
...initialProps
|
|
12019
|
-
}, [isOpen, setIsOpen] = useState(defaultProps.isOpen || !1), containerRef = useRef(null), backdropRef = useRef(null), adjustBodyPadding = useCallback((() => {
|
|
12020
|
-
if (!containerRef.current || "push" !== defaultProps.mode) return;
|
|
12021
|
-
const {position: position} = defaultProps, size = "top" === position || "bottom" === position ? containerRef.current.clientHeight : containerRef.current.clientWidth;
|
|
12027
|
+
const {position: position = "start", mode: mode = "slide", isOpen: propIsOpen = !1, backdrop: backdrop = !0, closeOnBackdropClick: closeOnBackdropClick = !0, closeOnEscape: closeOnEscape = !0, glass: glass, onOpenChange: onOpenChange, className: className = ""} = initialProps || {}, [isOpen, setIsOpen] = useState(propIsOpen || !1), containerRef = useRef(null), backdropRef = useRef(null), adjustBodyPadding = useCallback((() => {
|
|
12028
|
+
if (!containerRef.current || "push" !== mode) return;
|
|
12029
|
+
const size = "top" === position || "bottom" === position ? containerRef.current.clientHeight : containerRef.current.clientWidth;
|
|
12022
12030
|
// Map position to CSS padding property
|
|
12023
|
-
|
|
12031
|
+
let paddingProperty;
|
|
12024
12032
|
switch (position) {
|
|
12025
12033
|
case "start":
|
|
12026
12034
|
paddingProperty = "paddingLeft";
|
|
@@ -12035,9 +12043,8 @@ function useEdgePanel(initialProps) {
|
|
|
12035
12043
|
paddingProperty = `padding${position.charAt(0).toUpperCase() + position.slice(1)}`;
|
|
12036
12044
|
}
|
|
12037
12045
|
document.body.style[paddingProperty] = `${size}px`, document.body.classList.add("is-pushed");
|
|
12038
|
-
}), [
|
|
12039
|
-
if ("push" !==
|
|
12040
|
-
const {position: position} = defaultProps;
|
|
12046
|
+
}), [ mode, position ]), resetBodyPadding = useCallback((() => {
|
|
12047
|
+
if ("push" !== mode) return;
|
|
12041
12048
|
// Map position to CSS padding property
|
|
12042
12049
|
let paddingProperty;
|
|
12043
12050
|
switch (position) {
|
|
@@ -12054,11 +12061,10 @@ function useEdgePanel(initialProps) {
|
|
|
12054
12061
|
paddingProperty = `padding${position.charAt(0).toUpperCase() + position.slice(1)}`;
|
|
12055
12062
|
}
|
|
12056
12063
|
document.body.style[paddingProperty] = "", document.body.classList.remove("is-pushed");
|
|
12057
|
-
}), [
|
|
12064
|
+
}), [ mode, position ]), openPanel = useCallback(((useFadeAnimation = !1) => {
|
|
12058
12065
|
if (setIsOpen(!0), document.body.classList.add("is-edgepanel-open"), containerRef.current) {
|
|
12059
|
-
const {mode: mode} = defaultProps;
|
|
12060
12066
|
// Only add animation if not in 'none' mode
|
|
12061
|
-
|
|
12067
|
+
if ("none" !== mode) if (useFadeAnimation) {
|
|
12062
12068
|
// Add fade animation class
|
|
12063
12069
|
containerRef.current.classList.add("is-fade-animating"), containerRef.current.offsetHeight;
|
|
12064
12070
|
// Remove animation class after animation completes
|
|
@@ -12078,14 +12084,13 @@ function useEdgePanel(initialProps) {
|
|
|
12078
12084
|
// Set transform or opacity based on animation type
|
|
12079
12085
|
useFadeAnimation ? (containerRef.current.style.opacity = "1", containerRef.current.style.transform = "") : containerRef.current.style.transform = "translate(0)",
|
|
12080
12086
|
// If push mode, adjust body padding
|
|
12081
|
-
"push" ===
|
|
12087
|
+
"push" === mode && adjustBodyPadding();
|
|
12082
12088
|
}
|
|
12083
|
-
|
|
12084
|
-
}), [
|
|
12089
|
+
onOpenChange && onOpenChange(!0);
|
|
12090
|
+
}), [ mode, adjustBodyPadding, onOpenChange ]), closePanel = useCallback(((useFadeAnimation = !1) => {
|
|
12085
12091
|
if (containerRef.current) {
|
|
12086
|
-
const {position: position, mode: mode} = defaultProps;
|
|
12087
12092
|
// Only add animation if not in 'none' mode
|
|
12088
|
-
|
|
12093
|
+
if ("none" !== mode) if (useFadeAnimation) {
|
|
12089
12094
|
// Add fade out animation class
|
|
12090
12095
|
containerRef.current.classList.add("is-fade-animating-out");
|
|
12091
12096
|
// Capture container for setTimeout
|
|
@@ -12107,46 +12112,42 @@ function useEdgePanel(initialProps) {
|
|
|
12107
12112
|
// Then set transform
|
|
12108
12113
|
containerRef.current.style.transform = position ? EDGE_PANEL.TRANSFORM_VALUES[position] : "",
|
|
12109
12114
|
// Reset body padding if push mode
|
|
12110
|
-
"push" ===
|
|
12111
|
-
setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"),
|
|
12115
|
+
"push" === mode && resetBodyPadding(), setTimeout((() => {
|
|
12116
|
+
setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), onOpenChange && onOpenChange(!1);
|
|
12112
12117
|
}), "none" === mode ? 0 : EDGE_PANEL.ANIMATION_DURATION);
|
|
12113
|
-
} else setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"),
|
|
12114
|
-
}), [
|
|
12115
|
-
|
|
12116
|
-
}), [ closePanel,
|
|
12117
|
-
|
|
12118
|
-
}), [ closePanel,
|
|
12118
|
+
} else setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), onOpenChange && onOpenChange(!1);
|
|
12119
|
+
}), [ mode, position, onOpenChange, resetBodyPadding ]), handleEscapeKey = useCallback((event => {
|
|
12120
|
+
closeOnEscape && "Escape" === event.key && isOpen && closePanel();
|
|
12121
|
+
}), [ closePanel, closeOnEscape, isOpen ]), handleBackdropClick = useCallback((event => {
|
|
12122
|
+
closeOnBackdropClick && event.target === event.currentTarget && closePanel();
|
|
12123
|
+
}), [ closePanel, closeOnBackdropClick ]);
|
|
12119
12124
|
/**
|
|
12120
12125
|
* Set up event listeners for keyboard events
|
|
12121
12126
|
*/
|
|
12122
|
-
return useEffect((() => (isOpen &&
|
|
12127
|
+
return useEffect((() => (isOpen && closeOnEscape && document.addEventListener("keydown", handleEscapeKey),
|
|
12123
12128
|
() => {
|
|
12124
12129
|
document.removeEventListener("keydown", handleEscapeKey);
|
|
12125
|
-
})), [ isOpen, handleEscapeKey,
|
|
12130
|
+
})), [ isOpen, handleEscapeKey, closeOnEscape ]),
|
|
12126
12131
|
/**
|
|
12127
12132
|
* Set initial transform values
|
|
12128
12133
|
*/
|
|
12129
12134
|
useEffect((() => {
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
defaultProps.glass && (containerRef.current.style.opacity = "0"));
|
|
12135
|
-
}
|
|
12136
|
-
}), [ defaultProps.mode, defaultProps.position, defaultProps.glass, isOpen ]),
|
|
12135
|
+
containerRef.current && (isOpen || "slide" !== mode && "push" !== mode || !position || (containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position],
|
|
12136
|
+
// Set initial opacity for fade animations
|
|
12137
|
+
glass && (containerRef.current.style.opacity = "0")));
|
|
12138
|
+
}), [ mode, position, glass, isOpen ]),
|
|
12137
12139
|
/**
|
|
12138
12140
|
* Sync with prop changes
|
|
12139
12141
|
*/
|
|
12140
12142
|
useEffect((() => {
|
|
12141
|
-
void 0 !==
|
|
12142
|
-
}), [
|
|
12143
|
-
{
|
|
12143
|
+
void 0 !== propIsOpen && propIsOpen !== isOpen && (propIsOpen ? openPanel(!!glass) : closePanel(!!glass));
|
|
12144
|
+
}), [ propIsOpen, closePanel, isOpen, openPanel, glass ]), {
|
|
12144
12145
|
isOpen: isOpen,
|
|
12145
12146
|
containerRef: containerRef,
|
|
12146
12147
|
backdropRef: backdropRef,
|
|
12147
12148
|
generateEdgePanelClass: props => {
|
|
12148
|
-
const {position:
|
|
12149
|
-
return `${baseClass} ${
|
|
12149
|
+
const {position: propPosition = position, className: propClassName = className, isOpen: argIsOpen} = props, baseClass = EDGE_PANEL.CLASSES.BASE;
|
|
12150
|
+
return `${baseClass} ${propPosition ? `${baseClass}--${propPosition}` : ""} ${argIsOpen ?? isOpen ? EDGE_PANEL.CLASSES.IS_OPEN : ""} ${propClassName}`.trim();
|
|
12150
12151
|
},
|
|
12151
12152
|
openPanel: openPanel,
|
|
12152
12153
|
closePanel: closePanel,
|
|
@@ -12528,7 +12529,7 @@ function useHero(initialProps) {
|
|
|
12528
12529
|
* @returns Slider state and methods
|
|
12529
12530
|
*/
|
|
12530
12531
|
function(config) {
|
|
12531
|
-
const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), autoplayRef = useRef(null), isPausedRef = useRef(!1), callbackRef = useRef(), slideRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides
|
|
12532
|
+
const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), autoplayRef = useRef(null), isPausedRef = useRef(!1), callbackRef = useRef(void 0), slideRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides ]), videoRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides ]), handleSlideTransition = useCallback((nextIndex => {
|
|
12532
12533
|
if (nextIndex === currentIndex || isTransitioning) return;
|
|
12533
12534
|
if (nextIndex < 0 || nextIndex >= slides.length) return;
|
|
12534
12535
|
setIsTransitioning(!0),
|
|
@@ -12847,22 +12848,15 @@ function useHero(initialProps) {
|
|
|
12847
12848
|
* @param initialProps - Initial side menu properties
|
|
12848
12849
|
* @returns SideMenu state and methods
|
|
12849
12850
|
*/ function useSideMenu(initialProps) {
|
|
12850
|
-
|
|
12851
|
-
const defaultProps = {
|
|
12852
|
-
collapsible: !0,
|
|
12853
|
-
collapsibleDesktop: !1,
|
|
12854
|
-
defaultCollapsedDesktop: !1,
|
|
12855
|
-
isOpen: !1,
|
|
12856
|
-
...initialProps
|
|
12857
|
-
}, [isOpenState, setIsOpenState] = useState(void 0 !== defaultProps.defaultCollapsedDesktop ? !defaultProps.defaultCollapsedDesktop : defaultProps.isOpen || !1), wrapperRef = useRef(null), innerRef = useRef(null), sideMenuRef = useRef(null);
|
|
12851
|
+
const {collapsible: collapsible = !0, collapsibleDesktop: collapsibleDesktop = !1, defaultCollapsedDesktop: defaultCollapsedDesktop = !1, isOpen: isOpen, onToggle: onToggle, disabled: disabled = !1} = initialProps || {}, [isOpenState, setIsOpenState] = useState(void 0 !== defaultCollapsedDesktop ? !defaultCollapsedDesktop : isOpen || !1), wrapperRef = useRef(null), innerRef = useRef(null), sideMenuRef = useRef(null);
|
|
12858
12852
|
// Local open state for when not controlled externally
|
|
12859
12853
|
// Update local state when external state changes
|
|
12860
12854
|
useEffect((() => {
|
|
12861
|
-
void 0 !==
|
|
12862
|
-
}), [
|
|
12855
|
+
void 0 !== isOpen ? setIsOpenState(isOpen) : void 0 !== defaultCollapsedDesktop && setIsOpenState(!defaultCollapsedDesktop);
|
|
12856
|
+
}), [ isOpen, defaultCollapsedDesktop ]),
|
|
12863
12857
|
// Set initial height on mount
|
|
12864
12858
|
useEffect((() => {
|
|
12865
|
-
const shouldCollapse = window.innerWidth < 768 ?
|
|
12859
|
+
const shouldCollapse = window.innerWidth < 768 ? collapsible : collapsibleDesktop, currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
|
|
12866
12860
|
if (shouldCollapse && wrapperRef.current && innerRef.current) {
|
|
12867
12861
|
// Use setTimeout to ensure DOM is fully rendered
|
|
12868
12862
|
const timeoutId = setTimeout((() => {
|
|
@@ -12871,14 +12865,14 @@ function useHero(initialProps) {
|
|
|
12871
12865
|
return () => clearTimeout(timeoutId);
|
|
12872
12866
|
}
|
|
12873
12867
|
!shouldCollapse && wrapperRef.current && (wrapperRef.current.style.height = "auto");
|
|
12874
|
-
}), [
|
|
12868
|
+
}), [ collapsible, collapsibleDesktop, isOpen, isOpenState ]),
|
|
12875
12869
|
// Handle responsive behavior - vertical collapse for both mobile and desktop
|
|
12876
12870
|
useEffect((() => {
|
|
12877
12871
|
const handleResize = () => {
|
|
12878
|
-
if (window.innerWidth < 768 ?
|
|
12872
|
+
if (window.innerWidth < 768 ? collapsible : collapsibleDesktop) {
|
|
12879
12873
|
if (wrapperRef.current && innerRef.current) {
|
|
12880
12874
|
// Set proper height for vertical animation (both mobile and desktop)
|
|
12881
|
-
const currentOpen = void 0 !==
|
|
12875
|
+
const currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
|
|
12882
12876
|
// Use requestAnimationFrame to ensure DOM is ready
|
|
12883
12877
|
requestAnimationFrame((() => {
|
|
12884
12878
|
wrapperRef.current && innerRef.current && (wrapperRef.current.style.height = currentOpen ? `${innerRef.current.scrollHeight}px` : "0px");
|
|
@@ -12892,12 +12886,12 @@ function useHero(initialProps) {
|
|
|
12892
12886
|
return window.addEventListener("resize", handleResize), () => {
|
|
12893
12887
|
clearTimeout(timeoutId), window.removeEventListener("resize", handleResize);
|
|
12894
12888
|
};
|
|
12895
|
-
}), [
|
|
12889
|
+
}), [ collapsible, collapsibleDesktop, isOpen, onToggle, isOpenState ]),
|
|
12896
12890
|
// Update wrapper height when open state changes (both mobile and desktop)
|
|
12897
12891
|
useEffect((() => {
|
|
12898
|
-
const shouldCollapse = window.innerWidth < 768 ?
|
|
12892
|
+
const shouldCollapse = window.innerWidth < 768 ? collapsible : collapsibleDesktop;
|
|
12899
12893
|
if (shouldCollapse && wrapperRef.current && innerRef.current) {
|
|
12900
|
-
const currentOpen = void 0 !==
|
|
12894
|
+
const currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
|
|
12901
12895
|
// Use requestAnimationFrame to ensure DOM is ready
|
|
12902
12896
|
requestAnimationFrame((() => {
|
|
12903
12897
|
wrapperRef.current && innerRef.current && (wrapperRef.current.style.height = currentOpen ? `${innerRef.current.scrollHeight}px` : "0px");
|
|
@@ -12905,26 +12899,25 @@ function useHero(initialProps) {
|
|
|
12905
12899
|
} else !shouldCollapse && wrapperRef.current && (
|
|
12906
12900
|
// Not collapsible - always show content
|
|
12907
12901
|
wrapperRef.current.style.height = "auto");
|
|
12908
|
-
}), [
|
|
12902
|
+
}), [ isOpen, isOpenState, collapsible, collapsibleDesktop ]);
|
|
12909
12903
|
/**
|
|
12910
12904
|
* Generate side menu class based on properties
|
|
12911
12905
|
* @param props - Side menu properties
|
|
12912
12906
|
* @returns Class string
|
|
12913
12907
|
*/
|
|
12914
12908
|
const handleToggle = () => {
|
|
12915
|
-
if (
|
|
12916
|
-
const newState = void 0 !==
|
|
12917
|
-
"function" == typeof
|
|
12909
|
+
if (disabled) return;
|
|
12910
|
+
const newState = void 0 !== isOpen ? !isOpen : !isOpenState;
|
|
12911
|
+
"function" == typeof onToggle ?
|
|
12918
12912
|
// Controlled component
|
|
12919
|
-
|
|
12913
|
+
onToggle(newState) :
|
|
12920
12914
|
// Uncontrolled component
|
|
12921
12915
|
setIsOpenState(newState);
|
|
12922
|
-
}, getCurrentOpenState = () => void 0 !==
|
|
12916
|
+
}, getCurrentOpenState = () => void 0 !== isOpen ? isOpen : isOpenState;
|
|
12923
12917
|
/**
|
|
12924
12918
|
* Generate wrapper class
|
|
12925
12919
|
* @returns Class string
|
|
12926
12920
|
*/ return {
|
|
12927
|
-
defaultProps: defaultProps,
|
|
12928
12921
|
isOpenState: getCurrentOpenState(),
|
|
12929
12922
|
wrapperRef: wrapperRef,
|
|
12930
12923
|
innerRef: innerRef,
|
|
@@ -13629,7 +13622,7 @@ SelectOption.displayName = "SelectOption";
|
|
|
13629
13622
|
/**
|
|
13630
13623
|
* Select - A component for dropdown selection
|
|
13631
13624
|
*/
|
|
13632
|
-
const
|
|
13625
|
+
const SelectComponentBase = ({options: options, value: value, onChange: onChange, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder = "Select an option", className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, size: size = "md", invalid: invalid = !1, valid: valid = !1, multiple: multiple = !1, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, glass: glass, children: children}) => {
|
|
13633
13626
|
const {generateSelectClass: generateSelectClass} = useSelect({
|
|
13634
13627
|
size: size,
|
|
13635
13628
|
disabled: disabled,
|
|
@@ -13820,7 +13813,7 @@ const Select = memo((({options: options, value: value, onChange: onChange, onBl
|
|
|
13820
13813
|
});
|
|
13821
13814
|
}
|
|
13822
13815
|
return selectContent;
|
|
13823
|
-
})
|
|
13816
|
+
}, Select = memo(SelectComponentBase);
|
|
13824
13817
|
|
|
13825
13818
|
Select.displayName = "Select", Select.Option = SelectOption;
|
|
13826
13819
|
|
|
@@ -14387,7 +14380,7 @@ Footer.displayName = "Footer";
|
|
|
14387
14380
|
*/
|
|
14388
14381
|
const MasonryGrid = forwardRef((({children: children, className: className = "", xs: xs = 1, sm: sm, md: md, lg: lg, xl: xl, xxl: xxl, gap: gap = 16, animate: animate = !0, imagesLoaded: imagesLoaded = !0, onLayoutComplete: onLayoutComplete, onImageLoad: onImageLoad, ...props}, ref) => {
|
|
14389
14382
|
// === REFS & STATE ===
|
|
14390
|
-
const [columns, setColumns] = useState(xs), [positions, setPositions] = useState([]), [
|
|
14383
|
+
const [columns, setColumns] = useState(xs), [positions, setPositions] = useState([]), [, setLayoutComplete] = useState(!1), [loadingImages, setLoadingImages] = useState(!1), containerRef = useRef(null), columnHeights = useRef([]), imagesLoadedCount = useRef(0), totalImagesCount = useRef(0), imageElements = useRef(new Map);
|
|
14391
14384
|
useEffect((() => {
|
|
14392
14385
|
setLoadingImages(!!imagesLoaded);
|
|
14393
14386
|
}), [ columns, imagesLoaded ]),
|
|
@@ -14416,34 +14409,45 @@ const MasonryGrid = forwardRef((({children: children, className: className = ""
|
|
|
14416
14409
|
});
|
|
14417
14410
|
})), setItems(newItems);
|
|
14418
14411
|
}), [ children ]);
|
|
14419
|
-
// ===
|
|
14420
|
-
const
|
|
14421
|
-
if (!
|
|
14422
|
-
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14412
|
+
// === MANAGE ITEM LAYOUT ===
|
|
14413
|
+
const calculateLayout = useCallback((() => {
|
|
14414
|
+
if (!containerRef.current || 0 === items.length) return;
|
|
14415
|
+
const colWidth = (containerRef.current.offsetWidth - gap * (columns - 1)) / columns;
|
|
14416
|
+
columnHeights.current = Array(columns).fill(0);
|
|
14417
|
+
const newPositions = [];
|
|
14418
|
+
items.forEach(((item, index) => {
|
|
14419
|
+
if (item.ref.current) {
|
|
14420
|
+
// Find the shortest column
|
|
14421
|
+
const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current)), left = shortestCol * (colWidth + gap), top = columnHeights.current[shortestCol] ?? 0, height = item.ref.current.offsetHeight;
|
|
14422
|
+
columnHeights.current[shortestCol] = top + height + gap, newPositions[index] = {
|
|
14423
|
+
left: left,
|
|
14424
|
+
top: top,
|
|
14425
|
+
width: colWidth,
|
|
14426
|
+
height: height
|
|
14427
|
+
};
|
|
14427
14428
|
}
|
|
14428
|
-
|
|
14429
|
-
|
|
14430
|
-
|
|
14431
|
-
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
setLoadingImages(!1), // This ensures the loading class is removed *immediately* after images load
|
|
14437
|
-
// Force a double requestAnimationFrame for final layout calculation after all images are loaded (guarantees DOM paint)
|
|
14438
|
-
requestAnimationFrame((() => {
|
|
14439
|
-
requestAnimationFrame((() => {
|
|
14440
|
-
calculateLayout(),
|
|
14441
|
-
// As a failsafe, if still present for some render lag, force another setLoadingImages(false)
|
|
14442
|
-
setLoadingImages(!1);
|
|
14443
|
-
}));
|
|
14444
|
-
})), onLayoutComplete?.());
|
|
14429
|
+
})), setPositions(newPositions);
|
|
14430
|
+
}), [ items, columns, gap ]), handleImageLoad = useCallback((img => {
|
|
14431
|
+
if (imageElements.current.get(img)) return;
|
|
14432
|
+
// Add loaded class for animation
|
|
14433
|
+
if (imageElements.current.set(img, !0), imagesLoadedCount.current += 1, containerRef.current && imagesLoaded) {
|
|
14434
|
+
const itemElement = img.closest(".o-masonry-grid > div");
|
|
14435
|
+
itemElement && (itemElement.offsetHeight, itemElement.classList.add("o-masonry-grid__item-loaded"),
|
|
14436
|
+
itemElement.classList.remove("o-masonry-grid__item-loading"));
|
|
14445
14437
|
}
|
|
14446
|
-
|
|
14438
|
+
// Schedule layout recalculation after next paint to prevent overlap
|
|
14439
|
+
const scheduleLayoutUpdate = () => {
|
|
14440
|
+
const frameId = requestAnimationFrame((() => {
|
|
14441
|
+
onImageLoad?.(imagesLoadedCount.current, totalImagesCount.current), calculateLayout();
|
|
14442
|
+
}));
|
|
14443
|
+
return () => cancelAnimationFrame(frameId);
|
|
14444
|
+
}, cleanup = scheduleLayoutUpdate();
|
|
14445
|
+
// Clean up previous scheduled updates
|
|
14446
|
+
// If all images have loaded, update loading state and complete layout
|
|
14447
|
+
imagesLoadedCount.current >= totalImagesCount.current && totalImagesCount.current > 0 && (setLayoutComplete(!0),
|
|
14448
|
+
setLoadingImages(!1), setTimeout((() => cleanup()), 0), // Clean up after current execution
|
|
14449
|
+
scheduleLayoutUpdate(), onLayoutComplete?.());
|
|
14450
|
+
}), [ onImageLoad, onLayoutComplete, imagesLoaded, calculateLayout ]), trackImages = useCallback((() => {
|
|
14447
14451
|
if (!imagesLoaded || !containerRef.current) return;
|
|
14448
14452
|
imageElements.current.clear(), imagesLoadedCount.current = 0;
|
|
14449
14453
|
const images = containerRef.current.querySelectorAll("img");
|
|
@@ -14462,30 +14466,21 @@ const MasonryGrid = forwardRef((({children: children, className: className = ""
|
|
|
14462
14466
|
img.removeEventListener("error", masonryImg._masonryLoadHandler), delete masonryImg._masonryLoadHandler);
|
|
14463
14467
|
}));
|
|
14464
14468
|
});
|
|
14465
|
-
}), [ imagesLoaded, handleImageLoad, onLayoutComplete ])
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
columnHeights.current = Array(columns).fill(0);
|
|
14469
|
-
const newPositions = [];
|
|
14470
|
-
items.forEach(((item, index) => {
|
|
14471
|
-
if (item.ref.current) {
|
|
14472
|
-
// Find the shortest column
|
|
14473
|
-
const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current)), left = shortestCol * (colWidth + gap), top = columnHeights.current[shortestCol] ?? 0, height = item.ref.current.offsetHeight;
|
|
14474
|
-
columnHeights.current[shortestCol] = top + height + gap, newPositions[index] = {
|
|
14475
|
-
left: left,
|
|
14476
|
-
top: top,
|
|
14477
|
-
width: colWidth,
|
|
14478
|
-
height: height
|
|
14479
|
-
};
|
|
14480
|
-
}
|
|
14481
|
-
})), setPositions(newPositions);
|
|
14482
|
-
}), [ items, columns, gap ]);
|
|
14483
|
-
// === OBSERVE CONTAINER RESIZE ===
|
|
14469
|
+
}), [ imagesLoaded, handleImageLoad, onLayoutComplete ]);
|
|
14470
|
+
// === TRACK & MANAGE IMAGES ===
|
|
14471
|
+
// === OBSERVE CONTAINER RESIZE ===
|
|
14484
14472
|
useEffect((() => {
|
|
14485
14473
|
if (!containerRef.current) return;
|
|
14486
|
-
let animationFrame = null;
|
|
14487
|
-
const observer = new ResizeObserver((
|
|
14488
|
-
|
|
14474
|
+
let animationFrame = null, lastWidth = 0;
|
|
14475
|
+
const observer = new ResizeObserver((entries => {
|
|
14476
|
+
const entry = entries[0];
|
|
14477
|
+
if (!entry) return;
|
|
14478
|
+
const currentWidth = entry.contentRect.width;
|
|
14479
|
+
// Only recalculate if width actually changed (prevents excessive calculations)
|
|
14480
|
+
Math.abs(currentWidth - lastWidth) > 1 && (animationFrame && cancelAnimationFrame(animationFrame),
|
|
14481
|
+
animationFrame = requestAnimationFrame((() => {
|
|
14482
|
+
calculateLayout(), lastWidth = currentWidth;
|
|
14483
|
+
})));
|
|
14489
14484
|
}));
|
|
14490
14485
|
return observer.observe(containerRef.current), () => {
|
|
14491
14486
|
observer.disconnect(), animationFrame && cancelAnimationFrame(animationFrame);
|
|
@@ -14496,24 +14491,21 @@ const MasonryGrid = forwardRef((({children: children, className: className = ""
|
|
|
14496
14491
|
setLayoutComplete(!0), void setLoadingImages(!1))
|
|
14497
14492
|
// Only reset layoutComplete when items or columns change
|
|
14498
14493
|
), [ items, columns, calculateLayout, imagesLoaded, trackImages ]),
|
|
14499
|
-
// ===
|
|
14494
|
+
// === ADD RESIZEOBSERVERS TO GRID ITEMS FOR DYNAMIC CONTENT MEASUREMENT ===
|
|
14500
14495
|
React.useEffect((() => {
|
|
14501
|
-
// Clean up old observers if items ever change
|
|
14502
14496
|
const observers = [];
|
|
14497
|
+
let animationFrame = null;
|
|
14498
|
+
// Debounced layout calculation for item resize events
|
|
14499
|
+
const debouncedCalculateLayout = () => {
|
|
14500
|
+
animationFrame && cancelAnimationFrame(animationFrame), animationFrame = requestAnimationFrame(calculateLayout);
|
|
14501
|
+
};
|
|
14503
14502
|
return items.forEach((item => {
|
|
14504
14503
|
if (item.ref.current) {
|
|
14505
|
-
const obs = new ResizeObserver(
|
|
14506
|
-
// Double rAF: ensures layout only runs after DOM/paint/async renders
|
|
14507
|
-
requestAnimationFrame((() => {
|
|
14508
|
-
requestAnimationFrame((() => {
|
|
14509
|
-
calculateLayout();
|
|
14510
|
-
}));
|
|
14511
|
-
}));
|
|
14512
|
-
}));
|
|
14504
|
+
const obs = new ResizeObserver(debouncedCalculateLayout);
|
|
14513
14505
|
obs.observe(item.ref.current), observers.push(obs);
|
|
14514
14506
|
}
|
|
14515
14507
|
})), () => {
|
|
14516
|
-
observers.forEach((obs => obs.disconnect()));
|
|
14508
|
+
observers.forEach((obs => obs.disconnect())), animationFrame && cancelAnimationFrame(animationFrame);
|
|
14517
14509
|
};
|
|
14518
14510
|
}), [ items, calculateLayout ]);
|
|
14519
14511
|
// Ensure loadingImages state resets when items/columns/imagesLoaded change
|
|
@@ -15950,12 +15942,12 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
|
|
|
15950
15942
|
const index = Number(key);
|
|
15951
15943
|
index >= currentLength && (delete nestedWrapperRefs.current[index], delete nestedInnerRefs.current[index]);
|
|
15952
15944
|
})));
|
|
15953
|
-
}), [ menuItems
|
|
15945
|
+
}), [ menuItems ]);
|
|
15954
15946
|
// Helper function to update nested wrapper height
|
|
15955
|
-
const updateNestedHeight = (index, isOpen) => {
|
|
15947
|
+
const updateNestedHeight = useCallback(((index, isOpen) => {
|
|
15956
15948
|
const wrapper = nestedWrapperRefs.current[index], inner = nestedInnerRefs.current[index];
|
|
15957
15949
|
wrapper && inner && (wrapper.style.height = isOpen ? `${inner.scrollHeight}px` : "0px");
|
|
15958
|
-
};
|
|
15950
|
+
}), []);
|
|
15959
15951
|
// Set initial heights for nested wrappers on mount and when menuItems change
|
|
15960
15952
|
useEffect((() => {
|
|
15961
15953
|
if (!menuItems?.length) return;
|
|
@@ -15969,7 +15961,7 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
|
|
|
15969
15961
|
// Only run when menuItems change, nestedItemStates is read but not in deps to avoid loops
|
|
15970
15962
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15971
15963
|
;
|
|
15972
|
-
}), [ menuItems
|
|
15964
|
+
}), [ menuItems, updateNestedHeight ]),
|
|
15973
15965
|
// Update nested wrapper heights when state changes
|
|
15974
15966
|
useEffect((() => {
|
|
15975
15967
|
if (!menuItems?.length) return;
|
|
@@ -15982,7 +15974,7 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
|
|
|
15982
15974
|
})), () => {
|
|
15983
15975
|
frameIds.forEach((id => cancelAnimationFrame(id)));
|
|
15984
15976
|
};
|
|
15985
|
-
}), [ nestedItemStates, menuItems
|
|
15977
|
+
}), [ nestedItemStates, menuItems, updateNestedHeight ]);
|
|
15986
15978
|
// Combine refs using utility
|
|
15987
15979
|
const combinedRef = useForkRef(sideMenuRef, ref), sideMenuClass = generateSideMenuClass({
|
|
15988
15980
|
className: className,
|
|
@@ -16869,7 +16861,7 @@ useEffect((() => {
|
|
|
16869
16861
|
}
|
|
16870
16862
|
};
|
|
16871
16863
|
}));
|
|
16872
|
-
}), [
|
|
16864
|
+
}), [ currentIndex, calculateBounds, constrainPosition ]), setImagePosition = useCallback((position => {
|
|
16873
16865
|
setImageStates((prev => {
|
|
16874
16866
|
const currentState = prev[currentIndex] || {
|
|
16875
16867
|
zoomLevel: 1,
|
|
@@ -16919,7 +16911,7 @@ useEffect((() => {
|
|
|
16919
16911
|
}
|
|
16920
16912
|
};
|
|
16921
16913
|
}));
|
|
16922
|
-
}), [
|
|
16914
|
+
}), [ currentIndex, calculateBounds, constrainPosition ]), handleWheel = useCallback((event => {
|
|
16923
16915
|
var _context;
|
|
16924
16916
|
if (!isMounted || !event || !event.currentTarget) return;
|
|
16925
16917
|
// Additional safety check for the target element
|
|
@@ -17276,7 +17268,7 @@ useEffect((() => {
|
|
|
17276
17268
|
}
|
|
17277
17269
|
return prev;
|
|
17278
17270
|
}));
|
|
17279
|
-
}), [
|
|
17271
|
+
}), [ enableGestures, isDragging, startDragPosition, currentIndex, constrainPosition, calculateBounds ]), handleTouchEnd = useCallback((() => {
|
|
17280
17272
|
setIsDragging(!1), lastDistanceRef.current = null, lastMidpointRef.current = null;
|
|
17281
17273
|
}), []), currentState = imageStates[currentIndex] || {
|
|
17282
17274
|
zoomLevel: 1,
|
|
@@ -17480,9 +17472,9 @@ const PopoverContext = createContext({
|
|
|
17480
17472
|
triggerType: "click"
|
|
17481
17473
|
}), Popover = ({content: content, position: position = "top", trigger: trigger = "click", className: className = "", style: style, delay: delay = 0, offset: offset = 12, defaultOpen: defaultOpen = !1, isOpen: controlledIsOpen, onOpenChange: onOpenChange, closeOnClickOutside: closeOnClickOutside = !0, closeOnEscape: closeOnEscape = !0, id: id, children: children, glass: glass}) => {
|
|
17482
17474
|
const {isOpen: isOpen, setIsOpen: setIsOpen, triggerRef: triggerRef, popoverRef: popoverRef, arrowRef: arrowRef, popoverId: popoverId, currentPosition: currentPosition, updatePosition: updatePosition} = (({position: position = "top", trigger: trigger = "click", offset: offset = 12, delay: delay = 0, defaultOpen: defaultOpen = !1, isOpen: controlledIsOpen, onOpenChange: onOpenChange, closeOnClickOutside: closeOnClickOutside = !0, closeOnEscape: closeOnEscape = !0, id: id}) => {
|
|
17483
|
-
const [isOpen, setIsOpenState] = useState(defaultOpen), [currentPosition, setCurrentPosition] = useState("auto" === position ? "top" : position), triggerRef = useRef(null), popoverRef = useRef(null), arrowRef = useRef(null), timeoutRef = useRef(null), popoverId = id || `popover-${Math.random().toString(36).slice(2, 11)}`, isControlled = void 0 !== controlledIsOpen, isOpenState = isControlled ? controlledIsOpen : isOpen, setIsOpen = newIsOpen => {
|
|
17475
|
+
const [isOpen, setIsOpenState] = useState(defaultOpen), [currentPosition, setCurrentPosition] = useState("auto" === position ? "top" : position), triggerRef = useRef(null), popoverRef = useRef(null), arrowRef = useRef(null), timeoutRef = useRef(null), popoverId = id || `popover-${Math.random().toString(36).slice(2, 11)}`, isControlled = void 0 !== controlledIsOpen, isOpenState = isControlled ? controlledIsOpen : isOpen, setIsOpen = useCallback((newIsOpen => {
|
|
17484
17476
|
isControlled || setIsOpenState(newIsOpen), onOpenChange && onOpenChange(newIsOpen);
|
|
17485
|
-
};
|
|
17477
|
+
}), [ isControlled, onOpenChange ]);
|
|
17486
17478
|
// Handle hover events if trigger is hover
|
|
17487
17479
|
useEffect((() => {
|
|
17488
17480
|
if ("hover" !== trigger || !triggerRef.current || !popoverRef.current) return;
|
|
@@ -17502,17 +17494,16 @@ const PopoverContext = createContext({
|
|
|
17502
17494
|
setIsOpen(!1);
|
|
17503
17495
|
};
|
|
17504
17496
|
// Add hover event listeners
|
|
17505
|
-
|
|
17506
|
-
|
|
17507
|
-
|
|
17508
|
-
|
|
17509
|
-
|
|
17510
|
-
|
|
17511
|
-
|
|
17512
|
-
null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
|
|
17497
|
+
triggerRef.current.addEventListener("mouseenter", handleTriggerMouseEnter), triggerRef.current.addEventListener("mouseleave", handleTriggerMouseLeave),
|
|
17498
|
+
popoverRef.current.addEventListener("mouseenter", handlePopoverMouseEnter), popoverRef.current.addEventListener("mouseleave", handlePopoverMouseLeave);
|
|
17499
|
+
const currentTrigger = triggerRef.current, currentPopover = popoverRef.current;
|
|
17500
|
+
return () => {
|
|
17501
|
+
currentTrigger && (currentTrigger.removeEventListener("mouseenter", handleTriggerMouseEnter),
|
|
17502
|
+
currentTrigger.removeEventListener("mouseleave", handleTriggerMouseLeave)), currentPopover && (currentPopover.removeEventListener("mouseenter", handlePopoverMouseEnter),
|
|
17503
|
+
currentPopover.removeEventListener("mouseleave", handlePopoverMouseLeave)), null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
|
|
17513
17504
|
};
|
|
17514
|
-
}), [ trigger, delay, isOpenState ]);
|
|
17515
|
-
const updatePosition = event => {
|
|
17505
|
+
}), [ trigger, delay, isOpenState, setIsOpen ]);
|
|
17506
|
+
const updatePosition = useCallback((event => {
|
|
17516
17507
|
if (!triggerRef.current || !popoverRef.current) return;
|
|
17517
17508
|
const triggerRect = triggerRef.current.getBoundingClientRect(), popoverRect = popoverRef.current.getBoundingClientRect(), viewportWidth = window.innerWidth, viewportHeight = window.innerHeight, isNearViewportEdge = triggerRect.top < 50 || triggerRect.bottom > viewportHeight - 50 || triggerRect.left < 50 || triggerRect.right > viewportWidth - 50;
|
|
17518
17509
|
// If this is a scroll update and trigger isn't near edges, skip repositioning
|
|
@@ -17573,9 +17564,9 @@ const PopoverContext = createContext({
|
|
|
17573
17564
|
// Add scroll position to convert viewport coordinates to absolute position
|
|
17574
17565
|
const absoluteTop = top + window.scrollY, absoluteLeft = left + window.scrollX;
|
|
17575
17566
|
// Apply position using absolute positioning to follow when scrolling
|
|
17576
|
-
popoverRef.current.style.position = "absolute", popoverRef.current.style.top = `${absoluteTop}px`,
|
|
17577
|
-
popoverRef.current.style.left = `${absoluteLeft}px
|
|
17578
|
-
};
|
|
17567
|
+
popoverRef.current && (popoverRef.current.style.position = "absolute", popoverRef.current.style.top = `${absoluteTop}px`,
|
|
17568
|
+
popoverRef.current.style.left = `${absoluteLeft}px`);
|
|
17569
|
+
}), [ position, offset ]);
|
|
17579
17570
|
// Position the popover
|
|
17580
17571
|
return useEffect((() => {
|
|
17581
17572
|
if (!isOpenState || !triggerRef.current || !popoverRef.current) return;
|
|
@@ -17601,7 +17592,7 @@ const PopoverContext = createContext({
|
|
|
17601
17592
|
window.removeEventListener("resize", updatePosition), window.removeEventListener("scroll", handleScroll),
|
|
17602
17593
|
scrollTimeout && clearTimeout(scrollTimeout), clearInterval(intervalId);
|
|
17603
17594
|
};
|
|
17604
|
-
}), [ isOpenState,
|
|
17595
|
+
}), [ isOpenState, updatePosition ]),
|
|
17605
17596
|
// Handle click outside to close popover
|
|
17606
17597
|
useEffect((() => {
|
|
17607
17598
|
if (!isOpenState || !closeOnClickOutside) return;
|
|
@@ -17611,7 +17602,7 @@ const PopoverContext = createContext({
|
|
|
17611
17602
|
return document.addEventListener("mousedown", handleClickOutside), () => {
|
|
17612
17603
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
17613
17604
|
};
|
|
17614
|
-
}), [ isOpenState, closeOnClickOutside ]),
|
|
17605
|
+
}), [ isOpenState, closeOnClickOutside, setIsOpen ]),
|
|
17615
17606
|
// Handle escape key to close popover
|
|
17616
17607
|
useEffect((() => {
|
|
17617
17608
|
if (!isOpenState || !closeOnEscape) return;
|
|
@@ -17621,7 +17612,7 @@ const PopoverContext = createContext({
|
|
|
17621
17612
|
return document.addEventListener("keydown", handleEscapeKey), () => {
|
|
17622
17613
|
document.removeEventListener("keydown", handleEscapeKey);
|
|
17623
17614
|
};
|
|
17624
|
-
}), [ isOpenState, closeOnEscape ]),
|
|
17615
|
+
}), [ isOpenState, closeOnEscape, setIsOpen ]),
|
|
17625
17616
|
// Clean up on unmount
|
|
17626
17617
|
useEffect((() => () => {
|
|
17627
17618
|
null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
|
|
@@ -17802,10 +17793,11 @@ const calculateStarValue = (e, starValue, allowHalf) => {
|
|
|
17802
17793
|
}), [ readOnly, onChange, allowHalf ]);
|
|
17803
17794
|
// Use vanilla JS implementation if specified
|
|
17804
17795
|
useEffect((() => {
|
|
17805
|
-
if (useVanillaJS
|
|
17796
|
+
if (!useVanillaJS || "undefined" == typeof window || !internalRef.current) return;
|
|
17797
|
+
const currentInstance = ratingInstance.current;
|
|
17806
17798
|
// Cleanup on unmount
|
|
17807
|
-
|
|
17808
|
-
|
|
17799
|
+
return () => {
|
|
17800
|
+
currentInstance && currentInstance.destroy();
|
|
17809
17801
|
};
|
|
17810
17802
|
}), [ useVanillaJS, valueProp, defaultValue, maxValue, allowHalf, readOnly, size, variant, onChange ]),
|
|
17811
17803
|
// Update vanilla JS implementation when props change
|
|
@@ -17926,10 +17918,11 @@ const ProductReview = ({productName: productName, productImage: productImage, in
|
|
|
17926
17918
|
const [rating, setRating] = useState(initialRating), [comment, setComment] = useState(""), [submitted, setSubmitted] = useState(!1), reviewRef = useRef(null), reviewInstance = useRef(null);
|
|
17927
17919
|
useEffect((() => {
|
|
17928
17920
|
// Only run on client-side
|
|
17929
|
-
if ("undefined"
|
|
17921
|
+
if ("undefined" == typeof window || !reviewRef.current) return;
|
|
17922
|
+
const currentInstance = reviewInstance.current;
|
|
17930
17923
|
// Cleanup on unmount
|
|
17931
|
-
|
|
17932
|
-
|
|
17924
|
+
return () => {
|
|
17925
|
+
currentInstance && currentInstance.destroy();
|
|
17933
17926
|
};
|
|
17934
17927
|
}), [ productName, productImage, initialRating, maxRating, allowHalf, ratingColor, onSubmit ]);
|
|
17935
17928
|
const handleSubmit = e => {
|
|
@@ -18174,10 +18167,11 @@ const SectionIntro = ({title: title, label: label, text: text, actions: actions,
|
|
|
18174
18167
|
const sectionIntroRef = useRef(null), sectionIntroInstance = useRef(null);
|
|
18175
18168
|
useEffect((() => {
|
|
18176
18169
|
// Only run on client-side
|
|
18177
|
-
if ("undefined"
|
|
18170
|
+
if ("undefined" == typeof window || !sectionIntroRef.current) return;
|
|
18171
|
+
const currentInstance = sectionIntroInstance.current;
|
|
18178
18172
|
// Cleanup on unmount
|
|
18179
|
-
|
|
18180
|
-
|
|
18173
|
+
return () => {
|
|
18174
|
+
currentInstance && currentInstance.destroy();
|
|
18181
18175
|
};
|
|
18182
18176
|
}), [ alignment, backgroundImageSrc, showOverlay, size, skeleton ]);
|
|
18183
18177
|
// Determine CSS classes
|
|
@@ -18261,7 +18255,7 @@ SectionIntro.displayName = "SectionIntro";
|
|
|
18261
18255
|
|
|
18262
18256
|
const Slider = forwardRef(((props, ref) => {
|
|
18263
18257
|
const {slides: slides = [], height: height = 300, width: width = "100%", slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, grabCursor: grabCursor = !0, autoplay: autoplay, navigation: navigation, pagination: pagination, className: className, style: style, onSlideChange: onSlideChange, ...rest} = props, validSlides = Array.isArray(slides) ? slides : [], slider = function(options) {
|
|
18264
|
-
const {slides: rawSlides, slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, autoplay: autoplay, onSlideChange: onSlideChange} = options, slides = Array.isArray(rawSlides) ? rawSlides : [], containerRef = useRef(null), wrapperRef = useRef(null), repositioningRef = useRef(!1), autoplayRef = useRef(null), [autoplayRunning, setAutoplayRunning] = useState(!1), sliderStateRef = useRef({
|
|
18258
|
+
const {slides: rawSlides, slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, autoplay: autoplay, onSlideChange: onSlideChange} = options, slides = useMemo((() => Array.isArray(rawSlides) ? rawSlides : []), [ rawSlides ]), containerRef = useRef(null), wrapperRef = useRef(null), repositioningRef = useRef(!1), autoplayRef = useRef(null), [autoplayRunning, setAutoplayRunning] = useState(!1), sliderStateRef = useRef({
|
|
18265
18259
|
isTransitioning: !1,
|
|
18266
18260
|
loop: loop,
|
|
18267
18261
|
slides: slides,
|
|
@@ -18396,7 +18390,7 @@ const Slider = forwardRef(((props, ref) => {
|
|
|
18396
18390
|
setIsTransitioning(!1), onSlideChange?.(nextIndex);
|
|
18397
18391
|
}), speed);
|
|
18398
18392
|
}
|
|
18399
|
-
}), [ realIndex, internalIndex, slides.length, slidesToShow, loop, isTransitioning, speed, onSlideChange,
|
|
18393
|
+
}), [ realIndex, internalIndex, slides.length, slidesToShow, loop, isTransitioning, speed, onSlideChange, autoplay ]), slidePrev = useCallback((() => {
|
|
18400
18394
|
if (!isTransitioning) if (
|
|
18401
18395
|
// Stop autoplay on interaction if disableOnInteraction is true
|
|
18402
18396
|
autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
|
|
@@ -18418,7 +18412,7 @@ const Slider = forwardRef(((props, ref) => {
|
|
|
18418
18412
|
setIsTransitioning(!1), onSlideChange?.(prevIndex);
|
|
18419
18413
|
}), speed);
|
|
18420
18414
|
}
|
|
18421
|
-
}), [ realIndex, internalIndex, slides.length, loop, isTransitioning, speed, onSlideChange,
|
|
18415
|
+
}), [ realIndex, internalIndex, slides.length, loop, isTransitioning, speed, onSlideChange, autoplay ]), goToSlide = useCallback((index => {
|
|
18422
18416
|
isTransitioning || index === realIndex || (
|
|
18423
18417
|
// Stop autoplay on interaction if disableOnInteraction is true
|
|
18424
18418
|
autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
|
|
@@ -18426,7 +18420,7 @@ const Slider = forwardRef(((props, ref) => {
|
|
|
18426
18420
|
setRealIndex(index), setInternalIndex(loop ? slides.length + index : index), setTimeout((() => {
|
|
18427
18421
|
setIsTransitioning(!1), onSlideChange?.(index);
|
|
18428
18422
|
}), speed));
|
|
18429
|
-
}), [ realIndex, isTransitioning, speed, onSlideChange, loop,
|
|
18423
|
+
}), [ realIndex, isTransitioning, speed, onSlideChange, loop, slides.length, autoplay ]), handleTouchStart = useCallback((e => {
|
|
18430
18424
|
if (!allowTouchMove) return;
|
|
18431
18425
|
// Stop autoplay on interaction if disableOnInteraction is true
|
|
18432
18426
|
autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
|
|
@@ -18681,7 +18675,7 @@ const Steps = ({items: items, activeIndex: activeIndex = 0, vertical: vertical =
|
|
|
18681
18675
|
let content;
|
|
18682
18676
|
useEffect((() => {
|
|
18683
18677
|
currentStep !== activeIndex && setCurrentStep(activeIndex);
|
|
18684
|
-
}), [ activeIndex ]),
|
|
18678
|
+
}), [ activeIndex, currentStep ]),
|
|
18685
18679
|
// Legacy rendering
|
|
18686
18680
|
content = items && items.length > 0 ? items.map(((item, index) => jsx(StepsItem, {
|
|
18687
18681
|
index: index,
|
|
@@ -18953,10 +18947,11 @@ const Testimonial = ({quote: quote, author: author, size: size = "", skeleton: s
|
|
|
18953
18947
|
const testimonialRef = useRef(null), testimonialInstance = useRef(null);
|
|
18954
18948
|
useEffect((() => {
|
|
18955
18949
|
// Only run on client-side
|
|
18956
|
-
if ("undefined"
|
|
18950
|
+
if ("undefined" == typeof window || !testimonialRef.current) return;
|
|
18951
|
+
const currentInstance = testimonialInstance.current;
|
|
18957
18952
|
// Cleanup on unmount
|
|
18958
|
-
|
|
18959
|
-
|
|
18953
|
+
return () => {
|
|
18954
|
+
currentInstance && currentInstance.destroy();
|
|
18960
18955
|
};
|
|
18961
18956
|
}), [ size, skeleton ]);
|
|
18962
18957
|
// Determine CSS classes
|
|
@@ -20097,11 +20092,13 @@ const VideoPlayer = forwardRef((({src: src, type: type = "video", youtubeId: yo
|
|
|
20097
20092
|
detectBorderRadius();
|
|
20098
20093
|
// Create ResizeObserver to watch for style changes
|
|
20099
20094
|
let resizeObserver = null;
|
|
20100
|
-
|
|
20095
|
+
"undefined" != typeof ResizeObserver && containerRef.current && (resizeObserver = new ResizeObserver(detectBorderRadius),
|
|
20101
20096
|
resizeObserver.observe(containerRef.current)),
|
|
20102
20097
|
// Also listen for window resize (in case styles change)
|
|
20103
|
-
window.addEventListener("resize", detectBorderRadius)
|
|
20104
|
-
|
|
20098
|
+
window.addEventListener("resize", detectBorderRadius);
|
|
20099
|
+
const currentContainer = containerRef.current;
|
|
20100
|
+
return () => {
|
|
20101
|
+
window.removeEventListener("resize", detectBorderRadius), resizeObserver && currentContainer && (resizeObserver.unobserve(currentContainer),
|
|
20105
20102
|
resizeObserver.disconnect());
|
|
20106
20103
|
};
|
|
20107
20104
|
}), []);
|
|
@@ -22441,7 +22438,7 @@ const logger = getLogger(), ThemeProvider = ({children: children, defaultTheme:
|
|
|
22441
22438
|
// If defaultTheme is provided, use it
|
|
22442
22439
|
return null != defaultTheme ? defaultTheme : "default";
|
|
22443
22440
|
// Default fallback
|
|
22444
|
-
}), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() => {
|
|
22441
|
+
}), [ defaultTheme, enablePersistence, storageKey, storageAdapter ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() => {
|
|
22445
22442
|
// If defaultTheme is DesignTokens, validate and store them
|
|
22446
22443
|
if (defaultTheme && "string" != typeof defaultTheme) {
|
|
22447
22444
|
const {tokens: tokens, validation: validation} = validateAndMergeTokens(defaultTheme);
|
|
@@ -23742,7 +23739,7 @@ class ThemeValidator {
|
|
|
23742
23739
|
*
|
|
23743
23740
|
* Provides detailed inspection and debugging information for themes
|
|
23744
23741
|
*/ const ThemeInspector = ({theme: theme, showValidation: showValidation = !0, showCSSVariables: showCSSVariables = !0, showStructure: showStructure = !0, className: className, style: style}) => {
|
|
23745
|
-
const [activeTab, setActiveTab] = useState("overview"), [expandedSections, setExpandedSections] = useState(new Set([ "palette" ])), [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [copiedPath, setCopiedPath] = useState(null), searchTimeoutRef = useRef();
|
|
23742
|
+
const [activeTab, setActiveTab] = useState("overview"), [expandedSections, setExpandedSections] = useState(new Set([ "palette" ])), [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [copiedPath, setCopiedPath] = useState(null), searchTimeoutRef = useRef(void 0);
|
|
23746
23743
|
// Debounce search query
|
|
23747
23744
|
useEffect((() => (searchTimeoutRef.current && clearTimeout(searchTimeoutRef.current),
|
|
23748
23745
|
searchTimeoutRef.current = setTimeout((() => {
|
|
@@ -24148,7 +24145,7 @@ class ThemeValidator {
|
|
|
24148
24145
|
}) ]
|
|
24149
24146
|
});
|
|
24150
24147
|
}, ThemeComparator = ({themeA: themeA, themeB: themeB, showOnlyDifferences: showOnlyDifferences = !1, className: className, style: style}) => {
|
|
24151
|
-
const [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [filterType, setFilterType] = useState("all"), [filterCategory, setFilterCategory] = useState("all"), searchTimeoutRef = useRef();
|
|
24148
|
+
const [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [filterType, setFilterType] = useState("all"), [filterCategory, setFilterCategory] = useState("all"), searchTimeoutRef = useRef(void 0);
|
|
24152
24149
|
// Debounce search query
|
|
24153
24150
|
useEffect((() => (searchTimeoutRef.current && clearTimeout(searchTimeoutRef.current),
|
|
24154
24151
|
searchTimeoutRef.current = setTimeout((() => {
|
|
@@ -24944,7 +24941,7 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
|
|
|
24944
24941
|
} catch (err) {
|
|
24945
24942
|
setError(err instanceof Error ? err.message : "Invalid JSON");
|
|
24946
24943
|
}
|
|
24947
|
-
}), [ updateTheme ]), jsonUpdateTimeoutRef = useRef();
|
|
24944
|
+
}), [ updateTheme ]), jsonUpdateTimeoutRef = useRef(void 0);
|
|
24948
24945
|
// Debounced JSON update to history
|
|
24949
24946
|
useEffect((() => {
|
|
24950
24947
|
if (!error) {
|
|
@@ -26151,97 +26148,6 @@ function getComponentCSSVars(component) {
|
|
|
26151
26148
|
} : base : override;
|
|
26152
26149
|
}
|
|
26153
26150
|
|
|
26154
|
-
/**
|
|
26155
|
-
* Render a slot with the given props
|
|
26156
|
-
*
|
|
26157
|
-
* Priority order:
|
|
26158
|
-
* 1. render function
|
|
26159
|
-
* 2. component
|
|
26160
|
-
* 3. children
|
|
26161
|
-
* 4. fallback
|
|
26162
|
-
*
|
|
26163
|
-
* @example
|
|
26164
|
-
* renderSlot(
|
|
26165
|
-
* { render: (props) => <CustomButton {...props} /> },
|
|
26166
|
-
* { onClick: handleClick, children: 'Click me' }
|
|
26167
|
-
* )
|
|
26168
|
-
*/ function renderSlot(slot, props, fallback) {
|
|
26169
|
-
// No slot provided, use fallback
|
|
26170
|
-
if (!slot) return fallback;
|
|
26171
|
-
// Slot is a plain React node
|
|
26172
|
-
if ( React.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
|
|
26173
|
-
// Slot is an object with rendering options
|
|
26174
|
-
if ("object" == typeof slot && null !== slot) {
|
|
26175
|
-
const slotObj = slot;
|
|
26176
|
-
// Priority 1: render function
|
|
26177
|
-
if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
|
|
26178
|
-
// Priority 2: component
|
|
26179
|
-
if (slotObj.component) {
|
|
26180
|
-
const Component = slotObj.component;
|
|
26181
|
-
return jsx(Component, {
|
|
26182
|
-
...props
|
|
26183
|
-
});
|
|
26184
|
-
}
|
|
26185
|
-
// Priority 3: children
|
|
26186
|
-
if (void 0 !== slotObj.children) return slotObj.children;
|
|
26187
|
-
}
|
|
26188
|
-
// Fallback
|
|
26189
|
-
return fallback;
|
|
26190
|
-
}
|
|
26191
|
-
|
|
26192
|
-
/**
|
|
26193
|
-
* Check if a value is a slot configuration
|
|
26194
|
-
*/ function isSlot(value) {
|
|
26195
|
-
return "object" == typeof value && null !== value && ("render" in value || "component" in value || "children" in value);
|
|
26196
|
-
}
|
|
26197
|
-
|
|
26198
|
-
/**
|
|
26199
|
-
* Merge multiple slot configurations
|
|
26200
|
-
* Later slots override earlier ones
|
|
26201
|
-
*/ function mergeSlots(...slots) {
|
|
26202
|
-
const filtered = slots.filter((s => void 0 !== s));
|
|
26203
|
-
if (0 !== filtered.length) return 1 === filtered.length ? filtered[0] : _reduceInstanceProperty(filtered).call(filtered, ((acc, slot) => ({
|
|
26204
|
-
...acc,
|
|
26205
|
-
...slot
|
|
26206
|
-
})));
|
|
26207
|
-
}
|
|
26208
|
-
|
|
26209
|
-
/**
|
|
26210
|
-
* Create a slot wrapper component
|
|
26211
|
-
*
|
|
26212
|
-
* @example
|
|
26213
|
-
* const ButtonSlot = createSlotComponent<ButtonSlotProps>('button')
|
|
26214
|
-
*
|
|
26215
|
-
* <ButtonSlot slot={customSlot} {...props}>
|
|
26216
|
-
* Default content
|
|
26217
|
-
* </ButtonSlot>
|
|
26218
|
-
*/ function createSlotComponent(defaultElement = "div") {
|
|
26219
|
-
return function({slot: slot, children: children, ...props}) {
|
|
26220
|
-
const slotProps = props;
|
|
26221
|
-
return slot ? jsx(Fragment, {
|
|
26222
|
-
children: renderSlot(slot, slotProps, children)
|
|
26223
|
-
}) : jsx(defaultElement, "string" == typeof defaultElement ? {
|
|
26224
|
-
...props,
|
|
26225
|
-
children: children
|
|
26226
|
-
} : {
|
|
26227
|
-
...slotProps,
|
|
26228
|
-
children: children
|
|
26229
|
-
});
|
|
26230
|
-
};
|
|
26231
|
-
}
|
|
26232
|
-
|
|
26233
|
-
/**
|
|
26234
|
-
* Utility to create typed slot props
|
|
26235
|
-
*/ function createSlotProps(props) {
|
|
26236
|
-
return props;
|
|
26237
|
-
}
|
|
26238
|
-
|
|
26239
|
-
/**
|
|
26240
|
-
* Hook to manage slot rendering
|
|
26241
|
-
*/ function useSlot(slot, props, fallback) {
|
|
26242
|
-
return React.useMemo((() => renderSlot(slot, props, fallback)), [ slot, props, fallback ]);
|
|
26243
|
-
}
|
|
26244
|
-
|
|
26245
26151
|
/**
|
|
26246
26152
|
* Hook to merge theme overrides with component props
|
|
26247
26153
|
*
|