@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/forms.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
|
|
3
|
-
import React, { memo, forwardRef, useMemo, useState, useRef, useEffect, useCallback, useImperativeHandle, useContext, createContext } from "react";
|
|
3
|
+
import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, useCallback, useImperativeHandle, useContext, createContext } from "react";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Default theme colors for components
|
|
@@ -15,6 +15,7 @@ import React, { memo, forwardRef, useMemo, useState, useRef, useEffect, useCallb
|
|
|
15
15
|
FILTER_OVERLAY_CLASS: "c-atomix-glass__filter-overlay",
|
|
16
16
|
FILTER_SHADOW_CLASS: "c-atomix-glass__filter-shadow",
|
|
17
17
|
CONTENT_CLASS: "c-atomix-glass__content",
|
|
18
|
+
BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
|
|
18
19
|
BORDER_1_CLASS: "c-atomix-glass__border-1",
|
|
19
20
|
BORDER_2_CLASS: "c-atomix-glass__border-2",
|
|
20
21
|
HOVER_1_CLASS: "c-atomix-glass__hover-1",
|
|
@@ -360,7 +361,7 @@ import React, { memo, forwardRef, useMemo, useState, useRef, useEffect, useCallb
|
|
|
360
361
|
default:
|
|
361
362
|
return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
|
|
362
363
|
}
|
|
363
|
-
}, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
364
|
+
}, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
|
|
364
365
|
style: {
|
|
365
366
|
position: "absolute",
|
|
366
367
|
width: "100%",
|
|
@@ -501,24 +502,17 @@ import React, { memo, forwardRef, useMemo, useState, useRef, useEffect, useCallb
|
|
|
501
502
|
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
502
503
|
|
|
503
504
|
// Memoize component to prevent unnecessary re-renders
|
|
504
|
-
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))
|
|
505
|
-
|
|
506
|
-
// Module-level counter for deterministic ID generation
|
|
507
|
-
let idCounter = 0;
|
|
508
|
-
|
|
509
|
-
// Module-level shared shader cache with LRU eviction
|
|
510
|
-
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 = {
|
|
505
|
+
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 = {
|
|
511
506
|
x: 0,
|
|
512
507
|
y: 0
|
|
513
508
|
}, 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 = {
|
|
514
509
|
width: 0,
|
|
515
510
|
height: 0
|
|
516
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
511
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
|
|
517
512
|
// Phase 1: Animation System props
|
|
518
513
|
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) => {
|
|
519
|
-
//
|
|
520
|
-
|
|
521
|
-
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);
|
|
514
|
+
// React 18 useId — stable, unique, and SSR-safe (no module-level counter)
|
|
515
|
+
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);
|
|
522
516
|
// Lazy load shader utilities only when shader mode is needed
|
|
523
517
|
useEffect((() => {
|
|
524
518
|
"shader" === mode ?
|
|
@@ -541,9 +535,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
541
535
|
// Create cache key from size and variant
|
|
542
536
|
const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`, cachedUrl = (key => {
|
|
543
537
|
const entry = sharedShaderCache.get(key);
|
|
544
|
-
return entry ? (
|
|
545
|
-
// Update access timestamp for LRU
|
|
546
|
-
entry.timestamp = Date.now(), entry.url) : null;
|
|
538
|
+
return entry ? (entry.timestamp = Date.now(), entry.url) : null;
|
|
547
539
|
})(cacheKey);
|
|
548
540
|
// Check shared cache first
|
|
549
541
|
if (cachedUrl) return void setShaderMapUrl(cachedUrl);
|
|
@@ -554,29 +546,24 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
554
546
|
if (shaderUtilsRef.current) try {
|
|
555
547
|
const {ShaderDisplacementGenerator: ShaderDisplacementGenerator, fragmentShaders: fragmentShaders} = shaderUtilsRef.current;
|
|
556
548
|
shaderGeneratorRef.current?.destroy();
|
|
557
|
-
const selectedShader = fragmentShaders[shaderVariant]
|
|
549
|
+
const selectedShader = fragmentShaders[shaderVariant] ?? fragmentShaders.liquidGlass;
|
|
558
550
|
shaderGeneratorRef.current = new ShaderDisplacementGenerator({
|
|
559
551
|
width: glassSize.width,
|
|
560
552
|
height: glassSize.height,
|
|
561
553
|
fragment: selectedShader
|
|
562
554
|
}), shaderUpdateTimeoutRef.current = setTimeout((() => {
|
|
563
|
-
const url = shaderGeneratorRef.current?.updateShader()
|
|
555
|
+
const url = shaderGeneratorRef.current?.updateShader() ?? "";
|
|
564
556
|
url && ((key, url) => {
|
|
565
|
-
// Evict oldest entries if at capacity
|
|
566
557
|
if (sharedShaderCache.size >= 15) {
|
|
567
558
|
const entries = Array.from(sharedShaderCache.entries());
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const oldestEntry = entries[0];
|
|
572
|
-
oldestEntry && sharedShaderCache.delete(oldestEntry[0]);
|
|
559
|
+
entries.sort(((a, b) => a[1].timestamp - b[1].timestamp));
|
|
560
|
+
const oldest = entries[0];
|
|
561
|
+
oldest && sharedShaderCache.delete(oldest[0]);
|
|
573
562
|
}
|
|
574
563
|
sharedShaderCache.set(key, {
|
|
575
564
|
url: url,
|
|
576
565
|
timestamp: Date.now()
|
|
577
|
-
}),
|
|
578
|
-
// Development mode: log cache size
|
|
579
|
-
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
566
|
+
}), "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
580
567
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
581
568
|
}), 100);
|
|
582
569
|
} catch (error) {
|
|
@@ -645,7 +632,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
645
632
|
console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
|
|
646
633
|
}
|
|
647
634
|
}), [ ref, glassSize ]);
|
|
648
|
-
// Pre-calculate static multipliers outside useMemo
|
|
649
635
|
const liquidBlur = useMemo((() => {
|
|
650
636
|
const defaultBlur = {
|
|
651
637
|
baseBlur: blurAmount,
|
|
@@ -714,7 +700,6 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
714
700
|
}), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
|
|
715
701
|
return jsx("div", {
|
|
716
702
|
ref: el => {
|
|
717
|
-
// Apply force no-transition
|
|
718
703
|
// Handle forwarded ref
|
|
719
704
|
"function" == typeof ref ? ref(el) : ref && (ref.current = el);
|
|
720
705
|
},
|
|
@@ -756,6 +741,7 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
|
|
|
756
741
|
});
|
|
757
742
|
}));
|
|
758
743
|
|
|
744
|
+
// ─── Blur multiplier constants (module-level, never change at runtime) ────────
|
|
759
745
|
AtomixGlassContainer.displayName = "AtomixGlassContainer";
|
|
760
746
|
|
|
761
747
|
// Singleton instance
|
|
@@ -956,8 +942,6 @@ class {
|
|
|
956
942
|
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})`;
|
|
957
943
|
// Container variables
|
|
958
944
|
const style = containerElement.style;
|
|
959
|
-
style.setProperty("--atomix-glass-container-width", isFixedOrSticky ? `${glassSize.width}` : "100%"),
|
|
960
|
-
style.setProperty("--atomix-glass-container-height", isFixedOrSticky ? `${glassSize.height}` : "100%"),
|
|
961
945
|
style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
|
|
962
946
|
style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
|
|
963
947
|
// Shadows
|
|
@@ -1418,47 +1402,55 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1418
1402
|
return "undefined" == typeof process || process.env, finalConfig;
|
|
1419
1403
|
}
|
|
1420
1404
|
return "undefined" == typeof process || process.env, baseConfig;
|
|
1421
|
-
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null),
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (!container) return;
|
|
1426
|
-
// Use cached rect if available, otherwise get new one
|
|
1427
|
-
let rect = cachedRectRef.current;
|
|
1428
|
-
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
1429
|
-
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
1430
|
-
const center = calculateElementCenter(rect);
|
|
1431
|
-
// Write raw target — the lerp loop will smoothly pursue it
|
|
1432
|
-
targetMouseOffsetRef.current = {
|
|
1433
|
-
x: (globalPos.x - center.x) / rect.width * 100,
|
|
1434
|
-
y: (globalPos.y - center.y) / rect.height * 100
|
|
1435
|
-
}, targetGlobalMousePositionRef.current = globalPos;
|
|
1436
|
-
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
|
|
1405
|
+
}), [ 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((() => {
|
|
1406
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
1407
|
+
lerpRafRef.current = null);
|
|
1408
|
+
}), []), startLerpLoop = useCallback((() => {
|
|
1437
1409
|
if (lerpActiveRef.current) return;
|
|
1438
1410
|
lerpActiveRef.current = !0;
|
|
1439
1411
|
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
1440
1412
|
if (!lerpActiveRef.current) return;
|
|
1441
|
-
|
|
1442
|
-
if (!glassRef.current || !wrapperRef?.current) return void (lerpActiveRef.current = !1);
|
|
1413
|
+
if (!glassRef.current) return void (lerpActiveRef.current = !1);
|
|
1443
1414
|
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
1444
1415
|
// If we're close enough, snap and park
|
|
1445
|
-
if (Math.abs(dx) < .
|
|
1416
|
+
if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
|
|
1446
1417
|
...tgt
|
|
1447
1418
|
}, internalGlobalMousePositionRef.current = {
|
|
1448
1419
|
...targetGlobalMousePositionRef.current
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1420
|
+
},
|
|
1421
|
+
// Final update and stop
|
|
1422
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1423
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
1424
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1425
|
+
glassSize: glassSize,
|
|
1426
|
+
isHovered: isHovered,
|
|
1427
|
+
isActive: isActive,
|
|
1428
|
+
isOverLight: overLightConfig.isOverLight,
|
|
1429
|
+
baseOverLightConfig: overLightConfig,
|
|
1430
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
1431
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1432
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
1433
|
+
elasticity: elasticity,
|
|
1434
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1435
|
+
onClick: onClick,
|
|
1436
|
+
withLiquidBlur: withLiquidBlur,
|
|
1437
|
+
blurAmount: blurAmount,
|
|
1438
|
+
saturation: saturation,
|
|
1439
|
+
padding: padding,
|
|
1440
|
+
isFixedOrSticky: isFixedOrSticky
|
|
1441
|
+
}), void stopLerpLoop();
|
|
1442
|
+
// Smooth step
|
|
1443
|
+
internalMouseOffsetRef.current = {
|
|
1444
|
+
x: lerp$1(cur.x, tgt.x, LERP_T),
|
|
1445
|
+
y: lerp$1(cur.y, tgt.y, LERP_T)
|
|
1446
|
+
};
|
|
1447
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1448
|
+
internalGlobalMousePositionRef.current = {
|
|
1449
|
+
x: lerp$1(curG.x, tgtG.x, LERP_T),
|
|
1450
|
+
y: lerp$1(curG.y, tgtG.y, LERP_T)
|
|
1451
|
+
},
|
|
1452
|
+
// Imperative style update
|
|
1453
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1462
1454
|
mouseOffset: internalMouseOffsetRef.current,
|
|
1463
1455
|
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1464
1456
|
glassSize: glassSize,
|
|
@@ -1481,10 +1473,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1481
1473
|
};
|
|
1482
1474
|
// 0.08 – lower = more viscous
|
|
1483
1475
|
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1484
|
-
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky ]),
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1476
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1477
|
+
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1478
|
+
if (effectiveWithoutEffects) return;
|
|
1479
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
1480
|
+
if (!container) return;
|
|
1481
|
+
// Use cached rect if available, otherwise get new one
|
|
1482
|
+
let rect = cachedRectRef.current;
|
|
1483
|
+
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
1484
|
+
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
1485
|
+
const center = calculateElementCenter(rect);
|
|
1486
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
1487
|
+
targetMouseOffsetRef.current = {
|
|
1488
|
+
x: (globalPos.x - center.x) / rect.width * 100,
|
|
1489
|
+
y: (globalPos.y - center.y) / rect.height * 100
|
|
1490
|
+
}, targetGlobalMousePositionRef.current = globalPos,
|
|
1491
|
+
// Ensure the lerp loop is running to smoothly chase the new target
|
|
1492
|
+
lerpActiveRef.current || startLerpLoop();
|
|
1493
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, startLerpLoop ]);
|
|
1488
1494
|
/**
|
|
1489
1495
|
* Validate and clamp a numeric config value
|
|
1490
1496
|
*/
|
|
@@ -1493,7 +1499,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1493
1499
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1494
1500
|
if (effectiveWithoutEffects) return;
|
|
1495
1501
|
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
1496
|
-
//
|
|
1502
|
+
// Initial start
|
|
1497
1503
|
startLerpLoop();
|
|
1498
1504
|
const container = mouseContainer?.current || glassRef.current;
|
|
1499
1505
|
let resizeObserver = null;
|
|
@@ -1506,7 +1512,7 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
|
|
|
1506
1512
|
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
1507
1513
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
1508
1514
|
};
|
|
1509
|
-
}), [
|
|
1515
|
+
}), [ externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef ]),
|
|
1510
1516
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
1511
1517
|
useEffect((() => {
|
|
1512
1518
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -1982,184 +1988,147 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
1982
1988
|
/**
|
|
1983
1989
|
* Get GPU memory info if available (Chrome DevTools only)
|
|
1984
1990
|
*/
|
|
1991
|
+
/** Map an FPS value to a semantic color token string. */
|
|
1992
|
+
const getQualityColor = quality => {
|
|
1993
|
+
switch (quality) {
|
|
1994
|
+
case "high":
|
|
1995
|
+
return "var(--atomix-color-success, #4ade80)";
|
|
1996
|
+
|
|
1997
|
+
case "medium":
|
|
1998
|
+
return "var(--atomix-color-warning, #fbbf24)";
|
|
1999
|
+
|
|
2000
|
+
case "low":
|
|
2001
|
+
return "var(--atomix-color-danger, #ef4444)";
|
|
2002
|
+
|
|
2003
|
+
default:
|
|
2004
|
+
return "#9ca3af";
|
|
2005
|
+
}
|
|
2006
|
+
}, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
|
|
2007
|
+
|
|
2008
|
+
/** Map a quality level string to a semantic color token string. */
|
|
2009
|
+
// Inject keyframes once
|
|
2010
|
+
if ("undefined" != typeof document) {
|
|
2011
|
+
const styleId = "perf-dashboard-keyframes";
|
|
2012
|
+
if (!document.getElementById(styleId)) {
|
|
2013
|
+
const styleEl = document.createElement("style");
|
|
2014
|
+
styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
|
|
2015
|
+
document.head.appendChild(styleEl);
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
|
|
1985
2019
|
/**
|
|
1986
|
-
* PerformanceDashboard - Real-time performance monitoring overlay
|
|
2020
|
+
* PerformanceDashboard - Real-time performance monitoring overlay.
|
|
1987
2021
|
*
|
|
1988
|
-
* Displays
|
|
1989
|
-
*
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
borderRadius: "8px",
|
|
2006
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
2007
|
-
fontFamily: "monospace",
|
|
2008
|
-
fontSize: "12px",
|
|
2009
|
-
color: "#fff",
|
|
2010
|
-
zIndex: 9999,
|
|
2011
|
-
minWidth: "200px",
|
|
2012
|
-
backdropFilter: "blur(8px)",
|
|
2013
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
2014
|
-
transition: "opacity 0.3s ease",
|
|
2015
|
-
opacity: isVisible ? 1 : 0,
|
|
2016
|
-
pointerEvents: isVisible ? "auto" : "none"
|
|
2017
|
-
})), [ isVisible ]), headerStyle = useMemo((() => ({
|
|
2018
|
-
display: "flex",
|
|
2019
|
-
justifyContent: "space-between",
|
|
2020
|
-
alignItems: "center",
|
|
2021
|
-
marginBottom: "8px",
|
|
2022
|
-
paddingBottom: "8px",
|
|
2023
|
-
borderBottom: "1px solid rgba(255, 255, 255, 0.1)"
|
|
2024
|
-
})), []), titleStyle = useMemo((() => ({
|
|
2025
|
-
fontWeight: "bold",
|
|
2026
|
-
fontSize: "13px",
|
|
2027
|
-
color: "#fff"
|
|
2028
|
-
})), []), closeButtonStyle = useMemo((() => ({
|
|
2029
|
-
background: "transparent",
|
|
2030
|
-
border: "none",
|
|
2031
|
-
color: "#9ca3af",
|
|
2032
|
-
cursor: "pointer",
|
|
2033
|
-
fontSize: "16px",
|
|
2034
|
-
padding: "0",
|
|
2035
|
-
lineHeight: "1"
|
|
2036
|
-
})), []), metricRowStyle = useMemo((() => ({
|
|
2037
|
-
display: "flex",
|
|
2038
|
-
justifyContent: "space-between",
|
|
2039
|
-
alignItems: "center",
|
|
2040
|
-
marginBottom: "6px"
|
|
2041
|
-
})), []), labelStyle = useMemo((() => ({
|
|
2042
|
-
color: "#9ca3af",
|
|
2043
|
-
marginRight: "12px"
|
|
2044
|
-
})), []), valueStyle = useMemo((() => ({
|
|
2045
|
-
fontWeight: "bold"
|
|
2046
|
-
})), []);
|
|
2047
|
-
// Get quality level badge color
|
|
2048
|
-
return isVisible ? jsxs("div", {
|
|
2049
|
-
style: dashboardStyle,
|
|
2022
|
+
* Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
|
|
2023
|
+
* Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
|
|
2024
|
+
*/ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
|
|
2025
|
+
if (!isVisible) return null;
|
|
2026
|
+
const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
|
|
2027
|
+
var fps;
|
|
2028
|
+
const isCritical = metrics.fps < 45;
|
|
2029
|
+
return jsxs("div", {
|
|
2030
|
+
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",
|
|
2031
|
+
style: {
|
|
2032
|
+
zIndex: 9999,
|
|
2033
|
+
minWidth: "12.5rem",
|
|
2034
|
+
// 200px
|
|
2035
|
+
backgroundColor: "rgba(17, 24, 39, 0.95)",
|
|
2036
|
+
backdropFilter: "blur(8px)",
|
|
2037
|
+
transition: "opacity 0.3s ease"
|
|
2038
|
+
},
|
|
2050
2039
|
children: [ jsxs("div", {
|
|
2051
|
-
|
|
2040
|
+
className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
|
|
2052
2041
|
children: [ jsx("span", {
|
|
2053
|
-
|
|
2042
|
+
className: "u-text-sm u-font-bold u-text-white",
|
|
2054
2043
|
children: "Performance Monitor"
|
|
2055
2044
|
}), onClose && jsx("button", {
|
|
2056
|
-
|
|
2045
|
+
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",
|
|
2057
2046
|
onClick: onClose,
|
|
2058
2047
|
"aria-label": "Close performance dashboard",
|
|
2048
|
+
style: {
|
|
2049
|
+
transition: "color 0.2s ease"
|
|
2050
|
+
},
|
|
2059
2051
|
children: "×"
|
|
2060
2052
|
}) ]
|
|
2061
2053
|
}), jsxs("div", {
|
|
2062
|
-
|
|
2054
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2063
2055
|
children: [ jsx("span", {
|
|
2064
|
-
|
|
2056
|
+
className: "u-text-gray-400 u-me-3",
|
|
2065
2057
|
children: "FPS"
|
|
2066
2058
|
}), jsx("span", {
|
|
2059
|
+
className: "u-font-bold",
|
|
2067
2060
|
style: {
|
|
2068
|
-
|
|
2069
|
-
color: getFpsColor(metrics.fps)
|
|
2061
|
+
color: fpsColor
|
|
2070
2062
|
},
|
|
2071
2063
|
children: Math.round(metrics.fps)
|
|
2072
2064
|
}) ]
|
|
2073
2065
|
}), jsxs("div", {
|
|
2074
|
-
|
|
2066
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2075
2067
|
children: [ jsx("span", {
|
|
2076
|
-
|
|
2068
|
+
className: "u-text-gray-400 u-me-3",
|
|
2077
2069
|
children: "Frame Time"
|
|
2078
2070
|
}), jsxs("span", {
|
|
2079
|
-
|
|
2071
|
+
className: "u-font-bold",
|
|
2080
2072
|
children: [ metrics.frameTime.toFixed(2), "ms" ]
|
|
2081
2073
|
}) ]
|
|
2082
2074
|
}), jsxs("div", {
|
|
2083
|
-
|
|
2075
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2084
2076
|
children: [ jsx("span", {
|
|
2085
|
-
|
|
2077
|
+
className: "u-text-gray-400 u-me-3",
|
|
2086
2078
|
children: "Quality"
|
|
2087
2079
|
}), jsx("span", {
|
|
2080
|
+
className: "u-font-bold u-text-uppercase",
|
|
2088
2081
|
style: {
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
case "high":
|
|
2093
|
-
return "#4ade80";
|
|
2094
|
-
|
|
2095
|
-
case "medium":
|
|
2096
|
-
return "#fbbf24";
|
|
2097
|
-
|
|
2098
|
-
case "low":
|
|
2099
|
-
return "#ef4444";
|
|
2100
|
-
|
|
2101
|
-
default:
|
|
2102
|
-
return "#9ca3af";
|
|
2103
|
-
}
|
|
2104
|
-
})(metrics.qualityLevel),
|
|
2105
|
-
textTransform: "uppercase",
|
|
2106
|
-
fontSize: "11px"
|
|
2082
|
+
fontSize: "0.6875rem",
|
|
2083
|
+
// 11px
|
|
2084
|
+
color: getQualityColor(metrics.qualityLevel)
|
|
2107
2085
|
},
|
|
2108
2086
|
children: metrics.qualityLevel
|
|
2109
2087
|
}) ]
|
|
2110
2088
|
}), metrics.gpuMemory && jsxs("div", {
|
|
2111
|
-
|
|
2089
|
+
className: "u-flex u-items-center u-justify-between u-mb-1-5",
|
|
2112
2090
|
children: [ jsx("span", {
|
|
2113
|
-
|
|
2091
|
+
className: "u-text-gray-400 u-me-3",
|
|
2114
2092
|
children: "GPU Memory"
|
|
2115
2093
|
}), jsxs("span", {
|
|
2116
|
-
|
|
2094
|
+
className: "u-font-bold",
|
|
2117
2095
|
children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
|
|
2118
2096
|
}) ]
|
|
2119
2097
|
}), metrics.isAutoScaling && jsx("div", {
|
|
2098
|
+
className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
|
|
2120
2099
|
style: {
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
fontSize: "10px",
|
|
2125
|
-
color: "#6b7280",
|
|
2126
|
-
textAlign: "center"
|
|
2100
|
+
fontSize: "0.625rem",
|
|
2101
|
+
// 10px
|
|
2102
|
+
color: "#6b7280"
|
|
2127
2103
|
},
|
|
2128
2104
|
children: "Auto-scaling active"
|
|
2129
2105
|
}), jsxs("div", {
|
|
2130
|
-
|
|
2131
|
-
marginTop: "8px",
|
|
2132
|
-
paddingTop: "8px",
|
|
2133
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.1)",
|
|
2134
|
-
display: "flex",
|
|
2135
|
-
alignItems: "center",
|
|
2136
|
-
gap: "6px"
|
|
2137
|
-
},
|
|
2106
|
+
className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
|
|
2138
2107
|
children: [ jsx("div", {
|
|
2108
|
+
className: "u-rounded-full",
|
|
2139
2109
|
style: {
|
|
2140
|
-
width: "
|
|
2141
|
-
height: "
|
|
2142
|
-
|
|
2143
|
-
backgroundColor:
|
|
2144
|
-
|
|
2110
|
+
width: "0.5rem",
|
|
2111
|
+
height: "0.5rem",
|
|
2112
|
+
flexShrink: 0,
|
|
2113
|
+
backgroundColor: fpsColor,
|
|
2114
|
+
...isCritical && {
|
|
2115
|
+
animation: "perf-dashboard-pulse 1s infinite"
|
|
2116
|
+
}
|
|
2145
2117
|
}
|
|
2146
2118
|
}), jsx("span", {
|
|
2119
|
+
className: "u-text-xs",
|
|
2147
2120
|
style: {
|
|
2148
|
-
fontSize: "
|
|
2149
|
-
|
|
2121
|
+
fontSize: "0.625rem",
|
|
2122
|
+
// 10px
|
|
2123
|
+
color: fpsColor
|
|
2150
2124
|
},
|
|
2151
|
-
children: metrics.fps
|
|
2125
|
+
children: getFpsLabel(metrics.fps)
|
|
2152
2126
|
}) ]
|
|
2153
2127
|
}) ]
|
|
2154
|
-
})
|
|
2155
|
-
};
|
|
2128
|
+
});
|
|
2129
|
+
}));
|
|
2156
2130
|
|
|
2157
|
-
|
|
2158
|
-
if ("undefined" != typeof document) {
|
|
2159
|
-
const styleSheet = document.createElement("style");
|
|
2160
|
-
styleSheet.textContent = "\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n ",
|
|
2161
|
-
document.head.appendChild(styleSheet);
|
|
2162
|
-
}
|
|
2131
|
+
PerformanceDashboard.displayName = "PerformanceDashboard";
|
|
2163
2132
|
|
|
2164
2133
|
/**
|
|
2165
2134
|
* Mobile optimization presets
|
|
@@ -2170,7 +2139,8 @@ if ("undefined" != typeof document) {
|
|
|
2170
2139
|
/**
|
|
2171
2140
|
* Performance preset - Maximum FPS, reduced quality
|
|
2172
2141
|
* Best for low-end devices or when battery saving is priority
|
|
2173
|
-
*/
|
|
2142
|
+
*/
|
|
2143
|
+
const PERFORMANCE_PRESET = {
|
|
2174
2144
|
distortionOctaves: 2,
|
|
2175
2145
|
// Minimal FBM layers
|
|
2176
2146
|
displacementScale: 50,
|
|
@@ -2279,95 +2249,21 @@ if ("undefined" != typeof document) {
|
|
|
2279
2249
|
saturation: 70
|
|
2280
2250
|
}
|
|
2281
2251
|
}
|
|
2282
|
-
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
* - Dynamic border-radius extraction from children CSS properties
|
|
2295
|
-
* - Automatic light/dark theme detection via overLight prop
|
|
2296
|
-
* - Accessibility and performance optimizations
|
|
2297
|
-
* - Multiple displacement modes (standard, polar, prominent, shader)
|
|
2298
|
-
* - Design token integration for consistent theming
|
|
2299
|
-
* - Focus ring support for keyboard navigation
|
|
2300
|
-
* - Responsive breakpoints for mobile optimization
|
|
2301
|
-
* - Enhanced ARIA attributes for screen readers
|
|
2302
|
-
* - Time-based animation system with FBM distortion
|
|
2303
|
-
* - Device preset optimization for performance/quality balance
|
|
2304
|
-
*
|
|
2305
|
-
* Design System Compliance:
|
|
2306
|
-
* - Uses design tokens for opacity, spacing, and colors
|
|
2307
|
-
* - Follows BEM methodology for class naming
|
|
2308
|
-
* - Implements focus-ring mixin for accessibility
|
|
2309
|
-
* - Supports reduced motion and high contrast preferences
|
|
2310
|
-
*
|
|
2311
|
-
* @example
|
|
2312
|
-
* // Basic usage with dynamic border-radius extraction
|
|
2313
|
-
* <AtomixGlass>
|
|
2314
|
-
* <div style={{ borderRadius: '12px' }}>Content with 12px radius</div>
|
|
2315
|
-
* </AtomixGlass>
|
|
2316
|
-
*
|
|
2317
|
-
* @example
|
|
2318
|
-
* // Manual border-radius override
|
|
2319
|
-
* <AtomixGlass borderRadius={20}>
|
|
2320
|
-
* <div>Content with 20px glass radius</div>
|
|
2321
|
-
* </AtomixGlass>
|
|
2322
|
-
*
|
|
2323
|
-
* @example
|
|
2324
|
-
* // Interactive glass with click handler
|
|
2325
|
-
* <AtomixGlass onClick={() => console.log('Clicked')} aria-label="Glass card">
|
|
2326
|
-
* <div>Clickable content</div>
|
|
2327
|
-
* </AtomixGlass>
|
|
2328
|
-
*
|
|
2329
|
-
* @example
|
|
2330
|
-
* // OverLight - Boolean mode (explicit control)
|
|
2331
|
-
* <AtomixGlass overLight={true}>
|
|
2332
|
-
* <div>Content on light background</div>
|
|
2333
|
-
* </AtomixGlass>
|
|
2334
|
-
*
|
|
2335
|
-
* @example
|
|
2336
|
-
* // OverLight - Auto-detection mode
|
|
2337
|
-
* <AtomixGlass overLight="auto">
|
|
2338
|
-
* <div>Content with auto-detected background</div>
|
|
2339
|
-
* </AtomixGlass>
|
|
2340
|
-
*
|
|
2341
|
-
* @example
|
|
2342
|
-
* // OverLight - Object config with custom settings
|
|
2343
|
-
* <AtomixGlass
|
|
2344
|
-
* overLight={{
|
|
2345
|
-
* threshold: 0.8,
|
|
2346
|
-
* opacity: 0.6,
|
|
2347
|
-
* contrast: 1.8,
|
|
2348
|
-
* brightness: 1.0,
|
|
2349
|
-
* saturationBoost: 1.5
|
|
2350
|
-
* }}
|
|
2351
|
-
* >
|
|
2352
|
-
* <div>Content with custom overLight config</div>
|
|
2353
|
-
* </AtomixGlass>
|
|
2354
|
-
*
|
|
2355
|
-
* @example
|
|
2356
|
-
* // Debug mode for overLight detection
|
|
2357
|
-
* <AtomixGlass overLight="auto" debugOverLight={true}>
|
|
2358
|
-
* <div>Content with debug logging enabled</div>
|
|
2359
|
-
* </AtomixGlass>
|
|
2360
|
-
*
|
|
2361
|
-
* @example
|
|
2362
|
-
* // Performance-optimized for mobile devices
|
|
2363
|
-
* <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
|
|
2364
|
-
* <div>Mobile-optimized glass effect</div>
|
|
2365
|
-
* </AtomixGlass>
|
|
2366
|
-
*/
|
|
2367
|
-
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}) {
|
|
2368
|
-
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({
|
|
2252
|
+
}, 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) {
|
|
2253
|
+
const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
|
|
2254
|
+
// Helper to merge refs
|
|
2255
|
+
function(...refs) {
|
|
2256
|
+
return node => {
|
|
2257
|
+
refs.forEach((ref => {
|
|
2258
|
+
"function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
|
|
2259
|
+
}));
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2262
|
+
// Internal implementation with forwardRef
|
|
2263
|
+
(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({
|
|
2369
2264
|
glassRef: glassRef,
|
|
2370
2265
|
contentRef: contentRef,
|
|
2266
|
+
wrapperRef: internalWrapperRef,
|
|
2371
2267
|
borderRadius: borderRadius,
|
|
2372
2268
|
globalMousePosition: externalGlobalMousePosition,
|
|
2373
2269
|
mouseOffset: externalMouseOffset,
|
|
@@ -2396,7 +2292,6 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2396
2292
|
distortionGain: distortionGain,
|
|
2397
2293
|
distortionQuality: distortionQuality
|
|
2398
2294
|
});
|
|
2399
|
-
// Re-calculate only when devicePreset changes
|
|
2400
2295
|
// Responsive breakpoint system - automatically adjusts parameters based on viewport
|
|
2401
2296
|
!
|
|
2402
2297
|
/**
|
|
@@ -2586,11 +2481,10 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2586
2481
|
},
|
|
2587
2482
|
breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
|
|
2588
2483
|
enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
|
|
2589
|
-
// Enable unless disabled
|
|
2590
2484
|
debug: !1
|
|
2591
2485
|
});
|
|
2592
2486
|
// Performance monitoring - tracks FPS, frame time, memory usage
|
|
2593
|
-
const {metrics: performanceMetrics,
|
|
2487
|
+
const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
|
|
2594
2488
|
/**
|
|
2595
2489
|
* Performance Monitor Hook
|
|
2596
2490
|
*
|
|
@@ -2754,17 +2648,17 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2754
2648
|
toggleMonitoring: toggleMonitoring
|
|
2755
2649
|
};
|
|
2756
2650
|
}({
|
|
2757
|
-
enabled:
|
|
2758
|
-
//
|
|
2651
|
+
enabled: debugPerformance,
|
|
2652
|
+
// Enable when debugPerformance is true
|
|
2759
2653
|
debug: !1,
|
|
2760
2654
|
showOverlay: !1
|
|
2761
2655
|
});
|
|
2762
|
-
// Auto-start performance monitoring
|
|
2656
|
+
// Auto-start performance monitoring when debugPerformance is enabled
|
|
2763
2657
|
React.useEffect((() => {
|
|
2764
|
-
|
|
2658
|
+
debugPerformance && toggleMonitoring();
|
|
2765
2659
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2766
|
-
}), []);
|
|
2767
|
-
//
|
|
2660
|
+
}), [ debugPerformance ]);
|
|
2661
|
+
// Re-run when debugPerformance changes
|
|
2768
2662
|
const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
|
|
2769
2663
|
if (!isFixedOrSticky) return {};
|
|
2770
2664
|
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
@@ -2792,34 +2686,30 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2792
2686
|
if (isFixedOrSticky) {
|
|
2793
2687
|
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
2794
2688
|
return {
|
|
2795
|
-
...visualStyle
|
|
2796
|
-
...!effectiveWithoutEffects && {
|
|
2797
|
-
transform: transformStyle
|
|
2798
|
-
}
|
|
2689
|
+
...visualStyle
|
|
2799
2690
|
};
|
|
2800
2691
|
}
|
|
2801
2692
|
return {
|
|
2802
|
-
...restStyle
|
|
2803
|
-
...!effectiveWithoutEffects && {
|
|
2804
|
-
transform: transformStyle
|
|
2805
|
-
}
|
|
2693
|
+
...restStyle
|
|
2806
2694
|
};
|
|
2807
|
-
}), [ isFixedOrSticky, restStyle
|
|
2695
|
+
}), [ isFixedOrSticky, restStyle ]);
|
|
2808
2696
|
// Build className with state modifiers
|
|
2809
2697
|
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((() => ({
|
|
2810
2698
|
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
2811
|
-
top: isFixedOrSticky ?
|
|
2812
|
-
left: isFixedOrSticky ?
|
|
2813
|
-
|
|
2699
|
+
top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
|
|
2700
|
+
left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
|
|
2701
|
+
right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
2702
|
+
bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
|
|
2703
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
|
|
2814
2704
|
// Keep a reference to positionStyles to avoid unused-variable lint,
|
|
2815
2705
|
// but sizing is driven by explicit width/height or measured size.
|
|
2816
2706
|
positionStyles.position;
|
|
2817
|
-
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;
|
|
2707
|
+
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;
|
|
2818
2708
|
return {
|
|
2819
2709
|
width: resolveLength(effectiveWidth, glassSize.width),
|
|
2820
2710
|
height: resolveLength(effectiveHeight, glassSize.height)
|
|
2821
2711
|
};
|
|
2822
|
-
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
2712
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
|
|
2823
2713
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
2824
2714
|
return {
|
|
2825
2715
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -2849,33 +2739,32 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2849
2739
|
absMx: absMx,
|
|
2850
2740
|
absMy: absMy
|
|
2851
2741
|
};
|
|
2852
|
-
}), [ mouseOffset.x, mouseOffset.y ]), opacityValues = useMemo((() => {
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
};
|
|
2861
|
-
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
|
|
2862
|
-
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;
|
|
2742
|
+
}), [ 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((() => ({
|
|
2743
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
2744
|
+
hover2: isActive ? .5 : 0,
|
|
2745
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
2746
|
+
base: isOverLight ? clampedOverLightOpacity || .4 : 0,
|
|
2747
|
+
over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
|
|
2748
|
+
})), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
|
|
2749
|
+
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;
|
|
2863
2750
|
return {
|
|
2864
2751
|
...void 0 !== customZIndex && {
|
|
2865
2752
|
"--atomix-glass-base-z-index": customZIndex
|
|
2866
2753
|
},
|
|
2867
2754
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
2868
2755
|
"--atomix-glass-transform": transformStyle || "none",
|
|
2869
|
-
|
|
2870
|
-
"--atomix-glass-position": rootLayoutStyle.position
|
|
2871
|
-
"--atomix-glass-top": `${isFixedOrSticky ?
|
|
2872
|
-
"--atomix-glass-left": `${isFixedOrSticky ?
|
|
2756
|
+
"--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
2757
|
+
"--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
|
|
2758
|
+
"--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
|
|
2759
|
+
"--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
|
|
2760
|
+
"--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
|
|
2761
|
+
"--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
|
|
2873
2762
|
"--atomix-glass-width": adjustedSize.width,
|
|
2874
2763
|
"--atomix-glass-height": adjustedSize.height,
|
|
2875
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.
|
|
2764
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
|
|
2876
2765
|
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
2877
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) *
|
|
2878
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) *
|
|
2766
|
+
"--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%)`,
|
|
2767
|
+
"--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%)`,
|
|
2879
2768
|
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
2880
2769
|
"--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}%)`,
|
|
2881
2770
|
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
@@ -2889,13 +2778,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2889
2778
|
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
2890
2779
|
"--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}%)`
|
|
2891
2780
|
};
|
|
2892
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight,
|
|
2781
|
+
}), [ 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", {
|
|
2893
2782
|
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(" ")
|
|
2894
2783
|
});
|
|
2895
2784
|
// Calculate position and size styles for internal layers
|
|
2896
2785
|
// When root is fixed/sticky, internal layers use absolute (relative to root)
|
|
2897
2786
|
return jsxs("div", {
|
|
2898
2787
|
...rest,
|
|
2788
|
+
ref: mergedRef,
|
|
2899
2789
|
className: componentClassName,
|
|
2900
2790
|
style: {
|
|
2901
2791
|
...glassVars
|
|
@@ -2905,17 +2795,14 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2905
2795
|
"aria-label": ariaLabel,
|
|
2906
2796
|
"aria-describedby": ariaDescribedBy,
|
|
2907
2797
|
"aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
|
|
2908
|
-
"aria-pressed":
|
|
2798
|
+
"aria-pressed": void 0,
|
|
2909
2799
|
onKeyDown: onClick ? handleKeyDown : void 0,
|
|
2910
2800
|
children: [ jsx(AtomixGlassContainer, {
|
|
2911
2801
|
ref: glassRef,
|
|
2912
2802
|
contentRef: contentRef,
|
|
2913
2803
|
className: className,
|
|
2914
2804
|
style: {
|
|
2915
|
-
...restStyle
|
|
2916
|
-
...!isFixedOrSticky && {
|
|
2917
|
-
position: "relative"
|
|
2918
|
-
}
|
|
2805
|
+
...restStyle
|
|
2919
2806
|
},
|
|
2920
2807
|
borderRadius: effectiveBorderRadius,
|
|
2921
2808
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
@@ -2951,6 +2838,7 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2951
2838
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2952
2839
|
shaderVariant: shaderVariant,
|
|
2953
2840
|
withLiquidBlur: withLiquidBlur,
|
|
2841
|
+
isFixedOrSticky: isFixedOrSticky,
|
|
2954
2842
|
// Phase 1: Animation System props
|
|
2955
2843
|
shaderTime: getShaderTime(),
|
|
2956
2844
|
withTimeAnimation: withTimeAnimation,
|
|
@@ -2979,6 +2867,8 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2979
2867
|
}) ]
|
|
2980
2868
|
}), withBorder && jsxs(Fragment, {
|
|
2981
2869
|
children: [ jsx("span", {
|
|
2870
|
+
className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
|
|
2871
|
+
}), jsx("span", {
|
|
2982
2872
|
className: ATOMIX_GLASS.BORDER_1_CLASS
|
|
2983
2873
|
}), jsx("span", {
|
|
2984
2874
|
className: ATOMIX_GLASS.BORDER_2_CLASS
|
|
@@ -2989,9 +2879,18 @@ function AtomixGlass({children: children, displacementScale: displacementScale =
|
|
|
2989
2879
|
onClose: () => {}
|
|
2990
2880
|
}) ]
|
|
2991
2881
|
});
|
|
2992
|
-
}
|
|
2882
|
+
}));
|
|
2883
|
+
|
|
2884
|
+
/**
|
|
2885
|
+
* Balanced preset - Good quality with reasonable performance
|
|
2886
|
+
* Default preset for most mobile devices
|
|
2887
|
+
*/ AtomixGlassInner.displayName = "AtomixGlass";
|
|
2993
2888
|
|
|
2994
|
-
|
|
2889
|
+
/**
|
|
2890
|
+
* AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
|
|
2891
|
+
* Ref is forwarded to the root `<div>` element.
|
|
2892
|
+
*/
|
|
2893
|
+
const AtomixGlass = memo(AtomixGlassInner), Checkbox = React.memo( forwardRef((({label: label, checked: checked, onChange: onChange, className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, value: value, invalid: invalid = !1, valid: valid = !1, indeterminate: indeterminate = !1, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, onClick: onClick, glass: glass, ...props}, ref) => {
|
|
2995
2894
|
// Local ref to handle indeterminate state
|
|
2996
2895
|
const localRef = useRef(null);
|
|
2997
2896
|
// Merge refs
|
|
@@ -3422,7 +3321,7 @@ SelectOption.displayName = "SelectOption";
|
|
|
3422
3321
|
/**
|
|
3423
3322
|
* Select - A component for dropdown selection
|
|
3424
3323
|
*/
|
|
3425
|
-
const
|
|
3324
|
+
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}) => {
|
|
3426
3325
|
const {generateSelectClass: generateSelectClass} =
|
|
3427
3326
|
/**
|
|
3428
3327
|
* Select state and functionality
|
|
@@ -3646,7 +3545,7 @@ const Select = memo((({options: options, value: value, onChange: onChange, onBl
|
|
|
3646
3545
|
});
|
|
3647
3546
|
}
|
|
3648
3547
|
return selectContent;
|
|
3649
|
-
})
|
|
3548
|
+
}, Select = memo(SelectComponentBase);
|
|
3650
3549
|
|
|
3651
3550
|
Select.displayName = "Select", Select.Option = SelectOption;
|
|
3652
3551
|
|