@shohojdhara/atomix 0.3.5 → 0.3.7
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/README.md +101 -199
- package/atomix.config.ts +241 -0
- package/dist/atomix.css +260 -179
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +250 -179
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.js +69 -166
- package/dist/charts.js.map +1 -1
- package/dist/core.js +184 -263
- package/dist/core.js.map +1 -1
- package/dist/forms.js +55 -131
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +184 -263
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +1831 -1657
- package/dist/index.esm.js +4497 -4318
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +4510 -4328
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +1431 -1472
- package/dist/theme.js +4175 -4138
- package/dist/theme.js.map +1 -1
- package/package.json +6 -20
- package/src/components/Accordion/Accordion.stories.tsx +50 -17
- package/src/components/AtomixGlass/AtomixGlass.tsx +128 -322
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +12 -5
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -32
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +2 -2
- package/src/components/AtomixGlass/stories/shared-components.tsx +0 -31
- package/src/components/Avatar/Avatar.stories.tsx +7 -0
- package/src/components/Badge/Badge.stories.tsx +91 -13
- package/src/components/Block/Block.stories.tsx +7 -23
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +7 -0
- package/src/components/Button/Button.stories.tsx +141 -22
- package/src/components/Button/Button.tsx +85 -167
- package/src/components/Button/ButtonGroup.stories.tsx +315 -0
- package/src/components/Button/ButtonGroup.tsx +67 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Callout/Callout.stories.tsx +8 -6
- package/src/components/Card/Card.stories.tsx +82 -28
- package/src/components/Chart/AnimatedChart.tsx +0 -1
- package/src/components/Chart/AreaChart.tsx +0 -1
- package/src/components/Chart/BarChart.tsx +0 -1
- package/src/components/Chart/BubbleChart.tsx +0 -1
- package/src/components/Chart/CandlestickChart.tsx +0 -1
- package/src/components/Chart/Chart.stories.tsx +5 -7
- package/src/components/Chart/Chart.tsx +0 -16
- package/src/components/Chart/ChartRenderer.tsx +1 -1
- package/src/components/Chart/DonutChart.tsx +0 -1
- package/src/components/Chart/FunnelChart.tsx +0 -1
- package/src/components/Chart/GaugeChart.tsx +0 -1
- package/src/components/Chart/HeatmapChart.tsx +0 -1
- package/src/components/Chart/LineChart.tsx +0 -1
- package/src/components/Chart/MultiAxisChart.tsx +0 -1
- package/src/components/Chart/PieChart.tsx +0 -1
- package/src/components/Chart/RadarChart.tsx +0 -1
- package/src/components/Chart/ScatterChart.tsx +0 -1
- package/src/components/Chart/WaterfallChart.tsx +0 -1
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +7 -0
- package/src/components/DataTable/DataTable.stories.tsx +23 -16
- package/src/components/DatePicker/DatePicker.stories.tsx +27 -19
- package/src/components/Dropdown/Dropdown.stories.tsx +11 -19
- package/src/components/EdgePanel/EdgePanel.stories.tsx +1 -0
- package/src/components/Footer/Footer.stories.tsx +8 -6
- package/src/components/Footer/FooterLink.tsx +9 -2
- package/src/components/Form/Checkbox.stories.tsx +7 -0
- package/src/components/Form/Form.stories.tsx +7 -0
- package/src/components/Form/FormGroup.stories.tsx +9 -1
- package/src/components/Form/Input.stories.tsx +69 -16
- package/src/components/Form/Radio.stories.tsx +9 -1
- package/src/components/Form/Select.stories.tsx +9 -1
- package/src/components/Form/Textarea.stories.tsx +10 -2
- package/src/components/Hero/Hero.stories.tsx +7 -0
- package/src/components/List/List.stories.tsx +7 -0
- package/src/components/Messages/Messages.stories.tsx +8 -7
- package/src/components/Modal/Modal.stories.tsx +17 -6
- package/src/components/Navigation/Menu/Menu.stories.tsx +7 -0
- package/src/components/Navigation/Nav/Nav.stories.tsx +7 -0
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +1 -0
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +1 -1
- package/src/components/Pagination/Pagination.stories.tsx +188 -111
- package/src/components/Pagination/Pagination.tsx +83 -3
- package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -5
- package/src/components/Popover/Popover.stories.tsx +191 -115
- package/src/components/ProductReview/ProductReview.stories.tsx +80 -58
- package/src/components/Progress/Progress.stories.tsx +79 -49
- package/src/components/Rating/Rating.stories.tsx +109 -84
- package/src/components/River/River.stories.tsx +194 -114
- package/src/components/SectionIntro/SectionIntro.stories.tsx +19 -9
- package/src/components/Slider/Slider.stories.tsx +7 -0
- package/src/components/Spinner/Spinner.stories.tsx +15 -11
- package/src/components/Steps/Steps.stories.tsx +132 -98
- package/src/components/Tabs/Tabs.stories.tsx +163 -112
- package/src/components/Testimonial/Testimonial.stories.tsx +114 -68
- package/src/components/Todo/Todo.stories.tsx +38 -12
- package/src/components/Toggle/Toggle.stories.tsx +61 -28
- package/src/components/Tooltip/Tooltip.stories.tsx +318 -200
- package/src/components/Upload/Upload.stories.tsx +122 -84
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +7 -24
- package/src/components/index.ts +1 -0
- package/src/lib/composables/useAtomixGlass.ts +9 -10
- package/src/lib/composables/useNavbar.ts +0 -10
- package/src/lib/config/loader.ts +4 -4
- package/src/lib/constants/components.ts +17 -0
- package/src/lib/hooks/useComponentCustomization.ts +1 -1
- package/src/lib/hooks/usePerformanceMonitor.ts +1 -1
- package/src/lib/hooks/useThemeTokens.ts +105 -0
- package/src/lib/theme/README.md +174 -0
- package/src/lib/theme/adapters/index.ts +31 -0
- package/src/lib/theme/adapters/themeAdapter.ts +287 -0
- package/src/lib/theme/config/__tests__/configLoader.test.ts +207 -0
- package/src/lib/theme/config/configLoader.ts +95 -0
- package/src/lib/theme/config/loader.ts +37 -54
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +15 -91
- package/src/lib/theme/{constants.ts → constants/constants.ts} +1 -19
- package/src/lib/theme/constants/index.ts +8 -0
- package/src/lib/theme/core/ThemeRegistry.ts +75 -266
- package/src/lib/theme/core/__tests__/createTheme.test.ts +132 -0
- package/src/lib/theme/core/composeTheme.ts +105 -0
- package/src/lib/theme/core/createTheme.ts +108 -0
- package/src/lib/theme/{createTheme.ts → core/createThemeObject.ts} +12 -8
- package/src/lib/theme/core/index.ts +19 -19
- package/src/lib/theme/devtools/Comparator.tsx +346 -22
- package/src/lib/theme/devtools/IMPROVEMENTS.md +139 -38
- package/src/lib/theme/devtools/Inspector.tsx +335 -51
- package/src/lib/theme/devtools/LiveEditor.tsx +478 -107
- package/src/lib/theme/devtools/Preview.tsx +471 -221
- package/src/lib/theme/{core → devtools}/ThemeValidator.ts +1 -1
- package/src/lib/theme/devtools/index.ts +14 -4
- package/src/lib/theme/devtools/useHistory.ts +130 -0
- package/src/lib/theme/{errors.ts → errors/errors.ts} +1 -1
- package/src/lib/theme/errors/index.ts +12 -0
- package/src/lib/theme/generators/cssFile.ts +79 -0
- package/src/lib/theme/generators/generateCSS.ts +89 -0
- package/src/lib/theme/generators/generateCSSNested.ts +130 -0
- package/src/lib/theme/{generateCSSVariables.ts → generators/generateCSSVariables.ts} +3 -13
- package/src/lib/theme/generators/index.ts +25 -0
- package/src/lib/theme/i18n/rtl.ts +5 -6
- package/src/lib/theme/index.ts +149 -19
- package/src/lib/theme/runtime/ThemeApplicator.ts +53 -112
- package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +5 -5
- package/src/lib/theme/runtime/ThemeProvider.tsx +266 -282
- package/src/lib/theme/runtime/index.ts +2 -2
- package/src/lib/theme/runtime/useTheme.ts +1 -2
- package/src/lib/theme/runtime/useThemeTokens.ts +131 -0
- package/src/lib/theme/test/testTheme.ts +385 -0
- package/src/lib/theme/tokens/index.ts +12 -0
- package/src/lib/theme/tokens/tokens.ts +721 -0
- package/src/lib/theme/types.ts +6 -42
- package/src/lib/theme/utils/componentTheming.ts +132 -0
- package/src/lib/theme/{utils.ts → utils/domUtils.ts} +2 -2
- package/src/lib/theme/utils/index.ts +11 -0
- package/src/lib/theme/utils/injectCSS.ts +90 -0
- package/src/lib/theme/utils/naming.ts +100 -0
- package/src/lib/theme/utils/themeHelpers.ts +78 -0
- package/src/lib/theme/{themeUtils.ts → utils/themeUtils.ts} +7 -7
- package/src/lib/theme-tools.ts +7 -8
- package/src/lib/types/components.ts +40 -130
- package/src/lib/utils/componentUtils.ts +2 -2
- package/src/lib/utils/memoryMonitor.ts +3 -3
- package/src/lib/utils/themeNaming.ts +135 -0
- package/src/styles/01-settings/_settings.design-tokens.scss +4 -1
- package/src/styles/02-tools/_tools.button.scss +66 -79
- package/src/styles/06-components/_components.atomix-glass.scss +13 -3
- package/src/styles/06-components/_components.pagination.scss +88 -0
- package/scripts/sync-theme-config.js +0 -309
- package/src/lib/theme/composeTheme.ts +0 -370
- package/src/lib/theme/core/ThemeCache.ts +0 -283
- package/src/lib/theme/core/ThemeEngine.test.ts +0 -146
- package/src/lib/theme/core/ThemeEngine.ts +0 -665
- package/src/lib/theme/createThemeFromConfig.ts +0 -132
- package/src/lib/theme/devtools/CLI.ts +0 -364
- package/src/lib/theme/runtime/ThemeManager.test.ts +0 -192
- package/src/lib/theme/runtime/ThemeManager.ts +0 -446
- package/src/styles/03-generic/_generated-root.css +0 -26
- package/src/themes/README.md +0 -442
- package/src/themes/themes.config.js +0 -68
- /package/src/lib/theme/{cssVariableMapper.ts → adapters/cssVariableMapper.ts} +0 -0
package/dist/heavy.js
CHANGED
|
@@ -460,9 +460,7 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
|
|
|
460
460
|
})
|
|
461
461
|
});
|
|
462
462
|
|
|
463
|
-
|
|
464
|
-
* Badge-specific constants
|
|
465
|
-
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
463
|
+
GlassFilterComponent.displayName = "GlassFilter";
|
|
466
464
|
|
|
467
465
|
// Memoize component to prevent unnecessary re-renders
|
|
468
466
|
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)), 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 = {
|
|
@@ -475,10 +473,11 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
|
|
|
475
473
|
width: 0,
|
|
476
474
|
height: 0
|
|
477
475
|
}, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
|
|
478
|
-
//
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
|
|
476
|
+
// Generate a stable, deterministic ID for SSR compatibility
|
|
477
|
+
// React's useId() should produce the same ID on server and client for the same
|
|
478
|
+
// component position in the tree. We use useState to ensure the ID is only
|
|
479
|
+
// generated once and remains stable across renders.
|
|
480
|
+
const baseId = useId(), [filterId] = useState((() => `atomix-glass-filter-${baseId.replace(/:/g, "-").replace(/^[^a-z]/i, "atomix-")}`)), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
|
|
482
481
|
// Lazy load shader utilities only when shader mode is needed
|
|
483
482
|
useEffect((() => {
|
|
484
483
|
"shader" === mode ?
|
|
@@ -538,7 +537,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
|
|
|
538
537
|
timestamp: Date.now()
|
|
539
538
|
}),
|
|
540
539
|
// Development mode: log cache size
|
|
541
|
-
"production"
|
|
540
|
+
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
542
541
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
543
542
|
};
|
|
544
543
|
"undefined" != typeof requestIdleCallback ? requestIdleCallback(generate, {
|
|
@@ -851,9 +850,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
851
850
|
childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius,
|
|
852
851
|
extractionSource = "React children");
|
|
853
852
|
}
|
|
854
|
-
null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : process.env
|
|
853
|
+
null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : "undefined" == typeof process || process.env;
|
|
855
854
|
} catch (error) {
|
|
856
|
-
"production"
|
|
855
|
+
"undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugCornerRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
|
|
857
856
|
}
|
|
858
857
|
};
|
|
859
858
|
extractRadius();
|
|
@@ -928,7 +927,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
928
927
|
// For image backgrounds, assume medium luminance
|
|
929
928
|
totalLuminance += .5, validSamples++, hasValidBackground = !0);
|
|
930
929
|
} catch (styleError) {
|
|
931
|
-
process.env
|
|
930
|
+
"undefined" == typeof process || process.env;
|
|
932
931
|
}
|
|
933
932
|
// Move to parent element for next iteration
|
|
934
933
|
if (!currentElement) break;
|
|
@@ -967,7 +966,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
967
966
|
}
|
|
968
967
|
} catch (error) {
|
|
969
968
|
// Enhanced error logging with context
|
|
970
|
-
"development"
|
|
969
|
+
"undefined" != typeof process && "development" !== process.env?.NODE_ENV || console.warn("AtomixGlass: Error detecting background brightness:", error);
|
|
971
970
|
const result = !1;
|
|
972
971
|
if (element && element.parentElement) {
|
|
973
972
|
const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
|
|
@@ -1024,7 +1023,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1024
1023
|
};
|
|
1025
1024
|
// Calculate offset relative to this container
|
|
1026
1025
|
// React 18 automatically batches these updates
|
|
1027
|
-
setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "production"
|
|
1026
|
+
setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "undefined" != typeof process && "production" === process.env?.NODE_ENV || !enablePerformanceMonitoring || performance.now();
|
|
1028
1027
|
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects, enablePerformanceMonitoring ]);
|
|
1029
1028
|
// Subscribe to shared mouse tracker
|
|
1030
1029
|
useEffect((() => {
|
|
@@ -1164,10 +1163,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1164
1163
|
saturationBoost: validatedSaturationBoost + .4 * mouseInfluence
|
|
1165
1164
|
};
|
|
1166
1165
|
// Validate and apply object config values with proper clamping
|
|
1167
|
-
return process.env
|
|
1166
|
+
return "undefined" == typeof process || process.env, finalConfig;
|
|
1168
1167
|
}
|
|
1169
1168
|
// Debug logging for non-object configs
|
|
1170
|
-
return process.env
|
|
1169
|
+
return "undefined" == typeof process || process.env, baseConfig;
|
|
1171
1170
|
}), [ overLight, getEffectiveOverLight, mouseOffset, isHovered, isActive, validateConfigValue, debugOverLight ]), handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
|
|
1172
1171
|
!onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
|
|
1173
1172
|
}), [ onClick ]), handleMouseMove = useCallback((_e => {}), []);
|
|
@@ -1278,7 +1277,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1278
1277
|
* <div>Content with debug logging enabled</div>
|
|
1279
1278
|
* </AtomixGlass>
|
|
1280
1279
|
*/ 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, cornerRadius: cornerRadius, 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, disableEffects: disableEffects = !1, enableLiquidBlur: enableLiquidBlur = !1, enableBorderEffect: enableBorderEffect = !0, enableOverLightLayers: enableOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, enablePerformanceMonitoring: enablePerformanceMonitoring = !1, debugCornerRadius: debugCornerRadius = !1, debugOverLight: debugOverLight = !1}) {
|
|
1281
|
-
const glassRef = useRef(null), contentRef = useRef(null),
|
|
1280
|
+
const glassRef = useRef(null), contentRef = useRef(null), {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveCornerRadius: effectiveCornerRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveDisableEffects: effectiveDisableEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
|
|
1282
1281
|
glassRef: glassRef,
|
|
1283
1282
|
contentRef: contentRef,
|
|
1284
1283
|
cornerRadius: cornerRadius,
|
|
@@ -1295,128 +1294,51 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1295
1294
|
debugOverLight: debugOverLight,
|
|
1296
1295
|
enablePerformanceMonitoring: enablePerformanceMonitoring,
|
|
1297
1296
|
children: children
|
|
1298
|
-
}), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight
|
|
1299
|
-
// Read CSS custom properties once on mount and cache them
|
|
1300
|
-
useEffect((() => {
|
|
1301
|
-
if ("undefined" != typeof window && glassRef.current && !opacityCacheRef.current) try {
|
|
1302
|
-
const computedStyle = window.getComputedStyle(glassRef.current), opacity50Value = computedStyle.getPropertyValue("--atomix-opacity-50").trim(), opacity40Value = computedStyle.getPropertyValue("--atomix-opacity-40").trim(), opacity80Value = computedStyle.getPropertyValue("--atomix-opacity-80").trim(), opacity0Value = computedStyle.getPropertyValue("--atomix-opacity-0").trim(), parseOpacity = (value, defaultValue) => {
|
|
1303
|
-
if (!value) return defaultValue;
|
|
1304
|
-
const parsed = parseFloat(value);
|
|
1305
|
-
return isNaN(parsed) ? defaultValue : parsed;
|
|
1306
|
-
};
|
|
1307
|
-
opacityCacheRef.current = {
|
|
1308
|
-
opacity50: parseOpacity(opacity50Value, .5),
|
|
1309
|
-
opacity40: parseOpacity(opacity40Value, .4),
|
|
1310
|
-
opacity80: parseOpacity(opacity80Value, .8),
|
|
1311
|
-
opacity0: parseOpacity(opacity0Value, 0)
|
|
1312
|
-
};
|
|
1313
|
-
} catch (error) {
|
|
1314
|
-
// Fallback to defaults if reading fails
|
|
1315
|
-
opacityCacheRef.current = {
|
|
1316
|
-
opacity50: .5,
|
|
1317
|
-
opacity40: .4,
|
|
1318
|
-
opacity80: .8,
|
|
1319
|
-
opacity0: 0
|
|
1320
|
-
};
|
|
1321
|
-
}
|
|
1322
|
-
}), []);
|
|
1323
|
-
// Calculate base style with transforms (only dynamic values)
|
|
1324
|
-
const baseStyle = useMemo((() => ({
|
|
1297
|
+
}), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
|
|
1325
1298
|
...style,
|
|
1326
1299
|
...0 !== elasticity && !effectiveDisableEffects && {
|
|
1327
1300
|
transform: transformStyle
|
|
1328
1301
|
}
|
|
1329
|
-
}
|
|
1330
|
-
position:
|
|
1331
|
-
top:
|
|
1332
|
-
left:
|
|
1333
|
-
}
|
|
1334
|
-
width: "fixed" !==
|
|
1335
|
-
height: "fixed" !==
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
}), [ isHovered, isActive, isOverLight, overLightOpacity ]), gradientIsOverLight = gradientCalculations.isOverLight, gradientMx = gradientCalculations.mx, gradientMy = gradientCalculations.my, gradientBorderGradientAngle = gradientCalculations.borderGradientAngle, gradientBorderStop1 = gradientCalculations.borderStop1, gradientBorderStop2 = gradientCalculations.borderStop2, gradientBorderOpacity1 = gradientCalculations.borderOpacity1, gradientBorderOpacity2 = gradientCalculations.borderOpacity2, gradientBorderOpacity3 = gradientCalculations.borderOpacity3, gradientBorderOpacity4 = gradientCalculations.borderOpacity4, gradientHover1X = gradientCalculations.hover1X, gradientHover1Y = gradientCalculations.hover1Y, gradientHover2X = gradientCalculations.hover2X, gradientHover2Y = gradientCalculations.hover2Y, gradientHover3X = gradientCalculations.hover3X, gradientHover3Y = gradientCalculations.hover3Y, gradientBaseX = gradientCalculations.baseX, gradientBaseY = gradientCalculations.baseY, positionStylesPosition = positionStyles.position, positionStylesTop = positionStyles.top, positionStylesLeft = positionStyles.left, adjustedSizeWidth = adjustedSize.width, adjustedSizeHeight = adjustedSize.height, baseStyleTransform = baseStyle.transform, opacityValuesHover1 = opacityValues.hover1, opacityValuesHover2 = opacityValues.hover2, opacityValuesHover3 = opacityValues.hover3, opacityValuesBase = opacityValues.base, opacityValuesOver = opacityValues.over, glassVars = useMemo((() => {
|
|
1370
|
-
// RGB color values for rgba() functions
|
|
1371
|
-
// Note: CSS doesn't support rgba(var(--rgb), opacity) syntax, so we use direct values
|
|
1372
|
-
// These values align with design tokens: --atomix-white-rgb and --atomix-black-rgb
|
|
1373
|
-
// The actual RGB values are defined in SCSS and should match these fallbacks
|
|
1374
|
-
// TODO: Consider reading from CSS custom properties if browser support improves
|
|
1375
|
-
const whiteColor = "255, 255, 255";
|
|
1376
|
-
// Matches --atomix-white-rgb design token
|
|
1377
|
-
// Matches --atomix-black-rgb design token
|
|
1378
|
-
return {
|
|
1379
|
-
// Standard CSS custom properties for dynamic values
|
|
1380
|
-
"--atomix-glass-radius": `${effectiveCornerRadius}px`,
|
|
1381
|
-
"--atomix-glass-transform": baseStyleTransform || "none",
|
|
1382
|
-
"--atomix-glass-position": positionStylesPosition,
|
|
1383
|
-
"--atomix-glass-top": "fixed" !== positionStylesTop ? `${positionStylesTop}px` : "0",
|
|
1384
|
-
"--atomix-glass-left": "fixed" !== positionStylesLeft ? `${positionStylesLeft}px` : "0",
|
|
1385
|
-
"--atomix-glass-width": "fixed" !== baseStylePosition ? adjustedSizeWidth : `${adjustedSizeWidth}px`,
|
|
1386
|
-
"--atomix-glass-height": "fixed" !== baseStylePosition ? adjustedSizeHeight : `${adjustedSizeHeight}px`,
|
|
1387
|
-
// Border width: Use spacing token for consistency
|
|
1388
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
|
|
1389
|
-
"--atomix-glass-blend-mode": gradientIsOverLight ? "multiply" : "overlay",
|
|
1390
|
-
// Dynamic gradients and backgrounds
|
|
1391
|
-
// Note: RGB values use design token-aligned constants (white: 255,255,255; black: 0,0,0)
|
|
1392
|
-
"--atomix-glass-border-gradient-1": `linear-gradient(${gradientBorderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${gradientBorderOpacity1}) ${gradientBorderStop1}%, rgba(${whiteColor}, ${gradientBorderOpacity2}) ${gradientBorderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
1393
|
-
"--atomix-glass-border-gradient-2": `linear-gradient(${gradientBorderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${gradientBorderOpacity3}) ${gradientBorderStop1}%, rgba(${whiteColor}, ${gradientBorderOpacity4}) ${gradientBorderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
1394
|
-
"--atomix-glass-hover-1-opacity": opacityValuesHover1,
|
|
1395
|
-
"--atomix-glass-hover-1-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover1X}% ${gradientHover1Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${gradientHover1X}% ${gradientHover1Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
|
|
1396
|
-
"--atomix-glass-hover-2-opacity": opacityValuesHover2,
|
|
1397
|
-
"--atomix-glass-hover-2-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover2X}% ${gradientHover2Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${gradientHover2X}% ${gradientHover2Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
|
|
1398
|
-
"--atomix-glass-hover-3-opacity": opacityValuesHover3,
|
|
1399
|
-
"--atomix-glass-hover-3-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover3X}% ${gradientHover3Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${gradientHover3X}% ${gradientHover3Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
|
|
1400
|
-
"--atomix-glass-base-opacity": opacityValuesBase,
|
|
1401
|
-
"--atomix-glass-base-gradient": gradientIsOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + gradientMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + gradientMy * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + Math.abs(gradientMx) * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
|
|
1402
|
-
"--atomix-glass-overlay-opacity": opacityValuesOver,
|
|
1403
|
-
"--atomix-glass-overlay-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientBaseX}% ${gradientBaseY}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + Math.abs(gradientMx) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + Math.abs(gradientMy) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
|
|
1404
|
-
};
|
|
1405
|
-
}), [
|
|
1406
|
-
// Position styles - only specific properties
|
|
1407
|
-
positionStylesPosition, positionStylesTop, positionStylesLeft,
|
|
1408
|
-
// Adjusted size - only specific properties
|
|
1409
|
-
adjustedSizeWidth, adjustedSizeHeight,
|
|
1410
|
-
// Base style - only transform property
|
|
1411
|
-
baseStyleTransform, baseStylePosition,
|
|
1412
|
-
// Other values
|
|
1413
|
-
effectiveCornerRadius, effectiveReducedMotion,
|
|
1414
|
-
// Gradient calculations - extracted properties
|
|
1415
|
-
gradientIsOverLight, gradientMx, gradientMy, gradientBorderGradientAngle, gradientBorderStop1, gradientBorderStop2, gradientBorderOpacity1, gradientBorderOpacity2, gradientBorderOpacity3, gradientBorderOpacity4, gradientHover1X, gradientHover1Y, gradientHover2X, gradientHover2Y, gradientHover3X, gradientHover3Y, gradientBaseX, gradientBaseY,
|
|
1416
|
-
// Opacity values - extracted properties
|
|
1417
|
-
opacityValuesHover1, opacityValuesHover2, opacityValuesHover3, opacityValuesBase, opacityValuesOver ]);
|
|
1418
|
-
// Build className with state modifiers
|
|
1419
|
-
return jsxs("div", {
|
|
1302
|
+
}, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveDisableEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = {
|
|
1303
|
+
position: style.position || "absolute",
|
|
1304
|
+
top: style.top || 0,
|
|
1305
|
+
left: style.left || 0
|
|
1306
|
+
}, adjustedSize = {
|
|
1307
|
+
width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
|
|
1308
|
+
height: "fixed" !== style.position ? "100%" : style.height ? style.height : Math.max(glassSize.height, 0)
|
|
1309
|
+
}, mx = mouseOffset.x, my = mouseOffset.y, GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), borderOpacity1 = GRADIENT.BORDER_OPACITY.BASE_1 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity2 = GRADIENT.BORDER_OPACITY.BASE_2 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, borderOpacity3 = GRADIENT.BORDER_OPACITY.BASE_3 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity4 = GRADIENT.BORDER_OPACITY.BASE_4 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, hover1X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1, hover1Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1, hover2X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2, hover2Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2, hover3X = GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3, hover3Y = GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3, baseX = GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER, baseY = GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER, overLightOpacity = overLightConfig.opacity, opacityValues = {
|
|
1310
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
1311
|
+
hover2: isActive ? .5 : 0,
|
|
1312
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
1313
|
+
base: isOverLight ? overLightOpacity || .4 : 0,
|
|
1314
|
+
over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
|
|
1315
|
+
}, whiteColor = "255, 255, 255", glassVars = {
|
|
1316
|
+
// Standard CSS custom properties for dynamic values
|
|
1317
|
+
"--atomix-glass-radius": `${effectiveCornerRadius}px`,
|
|
1318
|
+
"--atomix-glass-transform": transformStyle || "none",
|
|
1319
|
+
"--atomix-glass-position": positionStyles.position,
|
|
1320
|
+
"--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
|
|
1321
|
+
"--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
|
|
1322
|
+
"--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
|
|
1323
|
+
"--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
|
|
1324
|
+
// Border width: Use spacing token for consistency
|
|
1325
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
|
|
1326
|
+
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
1327
|
+
// Dynamic gradients and backgrounds
|
|
1328
|
+
"--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacity1}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacity2}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
1329
|
+
"--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacity3}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacity4}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
|
|
1330
|
+
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
1331
|
+
"--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hover1X}% ${hover1Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hover1X}% ${hover1Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
|
|
1332
|
+
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
1333
|
+
"--atomix-glass-hover-2-gradient": isOverLight ? `radial-gradient(circle at ${hover2X}% ${hover2Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hover2X}% ${hover2Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
|
|
1334
|
+
"--atomix-glass-hover-3-opacity": opacityValues.hover3,
|
|
1335
|
+
"--atomix-glass-hover-3-gradient": isOverLight ? `radial-gradient(circle at ${hover3X}% ${hover3Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${hover3X}% ${hover3Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
|
|
1336
|
+
"--atomix-glass-base-opacity": opacityValues.base,
|
|
1337
|
+
"--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + Math.abs(mx) * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
|
|
1338
|
+
"--atomix-glass-overlay-opacity": opacityValues.over,
|
|
1339
|
+
"--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${baseX}% ${baseY}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + Math.abs(mx) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + Math.abs(my) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
|
|
1340
|
+
};
|
|
1341
|
+
return jsxs("div", {
|
|
1420
1342
|
className: componentClassName,
|
|
1421
1343
|
style: glassVars,
|
|
1422
1344
|
role: role || (onClick ? "button" : void 0),
|
|
@@ -3219,69 +3141,103 @@ const sizeMap = {
|
|
|
3219
3141
|
* Icon component that displays a Phosphor icon
|
|
3220
3142
|
*/ Icon.displayName = "Icon";
|
|
3221
3143
|
|
|
3144
|
+
/**
|
|
3145
|
+
* Theme Naming Utility
|
|
3146
|
+
*
|
|
3147
|
+
* Provides consistent naming conventions for CSS classes, CSS variables,
|
|
3148
|
+
* and JavaScript properties throughout the theme system.
|
|
3149
|
+
*/
|
|
3150
|
+
class ThemeNaming {
|
|
3151
|
+
/**
|
|
3152
|
+
* Set the global prefix for all theme tokens
|
|
3153
|
+
* @param newPrefix - New prefix to use
|
|
3154
|
+
*/
|
|
3155
|
+
static setPrefix(newPrefix) {
|
|
3156
|
+
this.prefix = newPrefix;
|
|
3157
|
+
}
|
|
3158
|
+
/**
|
|
3159
|
+
* Get the current prefix
|
|
3160
|
+
*/ static getPrefix() {
|
|
3161
|
+
return this.prefix;
|
|
3162
|
+
}
|
|
3163
|
+
/**
|
|
3164
|
+
* Convert camelCase to kebab-case for CSS variables
|
|
3165
|
+
* @param str - String to convert
|
|
3166
|
+
*/ static camelToKebab(str) {
|
|
3167
|
+
return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
|
|
3168
|
+
}
|
|
3169
|
+
/**
|
|
3170
|
+
* Convert kebab-case to camelCase for JavaScript properties
|
|
3171
|
+
* @param str - String to convert
|
|
3172
|
+
*/ static kebabToCamel(str) {
|
|
3173
|
+
return str.replace(/-([a-z])/g, (g => g[1].toUpperCase()));
|
|
3174
|
+
}
|
|
3175
|
+
/**
|
|
3176
|
+
* Create a CSS variable name
|
|
3177
|
+
* @param token - Token name in camelCase
|
|
3178
|
+
*/ static cssVar(token) {
|
|
3179
|
+
return `--${this.prefix}-${this.camelToKebab(token)}`;
|
|
3180
|
+
}
|
|
3181
|
+
/**
|
|
3182
|
+
* Create a BEM CSS class name
|
|
3183
|
+
* @param block - Block name
|
|
3184
|
+
* @param element - Element name (optional)
|
|
3185
|
+
* @param modifier - Modifier name (optional)
|
|
3186
|
+
*/ static bemClass(block, element, modifier) {
|
|
3187
|
+
let className = `c-${block}`;
|
|
3188
|
+
return element && (className += `__${element}`), modifier && (className += `--${modifier}`),
|
|
3189
|
+
className;
|
|
3190
|
+
}
|
|
3191
|
+
/**
|
|
3192
|
+
* Create a variant class name
|
|
3193
|
+
* @param component - Component name
|
|
3194
|
+
* @param variant - Variant name
|
|
3195
|
+
*/ static variantClass(component, variant) {
|
|
3196
|
+
return `c-${component}--${variant}`;
|
|
3197
|
+
}
|
|
3198
|
+
/**
|
|
3199
|
+
* Create a size class name
|
|
3200
|
+
* @param component - Component name
|
|
3201
|
+
* @param size - Size name
|
|
3202
|
+
*/ static sizeClass(component, size) {
|
|
3203
|
+
return `c-${component}--${size}`;
|
|
3204
|
+
}
|
|
3205
|
+
/**
|
|
3206
|
+
* Create a state class name
|
|
3207
|
+
* @param component - Component name
|
|
3208
|
+
* @param state - State name
|
|
3209
|
+
*/ static stateClass(component, state) {
|
|
3210
|
+
return `c-${component}--${state}`;
|
|
3211
|
+
}
|
|
3212
|
+
/**
|
|
3213
|
+
* Create a utility class name
|
|
3214
|
+
* @param utility - Utility name
|
|
3215
|
+
*/ static utilityClass(utility) {
|
|
3216
|
+
return `u-${utility}`;
|
|
3217
|
+
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Create a layout class name
|
|
3220
|
+
* @param layout - Layout name
|
|
3221
|
+
*/ static layoutClass(layout) {
|
|
3222
|
+
return `l-${layout}`;
|
|
3223
|
+
}
|
|
3224
|
+
/**
|
|
3225
|
+
* Create an object class name
|
|
3226
|
+
* @param object - Object name
|
|
3227
|
+
*/ static objectClass(object) {
|
|
3228
|
+
return `o-${object}`;
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
ThemeNaming.prefix = "atomix";
|
|
3233
|
+
|
|
3222
3234
|
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, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, ariaExpanded: ariaExpanded, ariaControls: ariaControls, tabIndex: tabIndex, style: style, LinkComponent: LinkComponent, ...props}, ref) => {
|
|
3223
|
-
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement =
|
|
3235
|
+
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
|
|
3224
3236
|
name: iconName,
|
|
3225
3237
|
size: iconSize
|
|
3226
|
-
}) : icon
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
* @param initialProps - Initial button properties
|
|
3230
|
-
* @returns Button state and methods
|
|
3231
|
-
*/
|
|
3232
|
-
function(initialProps) {
|
|
3233
|
-
// Default button properties
|
|
3234
|
-
const defaultProps = {
|
|
3235
|
-
variant: "primary",
|
|
3236
|
-
size: "md",
|
|
3237
|
-
disabled: !1,
|
|
3238
|
-
rounded: !1,
|
|
3239
|
-
loading: !1,
|
|
3240
|
-
fullWidth: !1,
|
|
3241
|
-
block: !1,
|
|
3242
|
-
active: !1,
|
|
3243
|
-
selected: !1,
|
|
3244
|
-
...initialProps
|
|
3245
|
-
};
|
|
3246
|
-
/**
|
|
3247
|
-
* Generate button class based on properties
|
|
3248
|
-
* @param props - Button properties
|
|
3249
|
-
* @returns Class string
|
|
3250
|
-
*/ return {
|
|
3251
|
-
defaultProps: defaultProps,
|
|
3252
|
-
generateButtonClass: props => {
|
|
3253
|
-
const {variant: variant = defaultProps.variant, size: size = defaultProps.size, disabled: disabled = defaultProps.disabled, rounded: rounded = defaultProps.rounded, iconOnly: iconOnly = !1, glass: glass = defaultProps.glass, loading: loading = defaultProps.loading, fullWidth: fullWidth = defaultProps.fullWidth, block: block = defaultProps.block, active: active = defaultProps.active, selected: selected = defaultProps.selected, className: className = ""} = props, sizeClass = "md" === size ? "" : `c-btn--${size}`, iconOnlyClass = iconOnly ? "c-btn--icon" : "", roundedClass = rounded ? "c-btn--rounded" : "", disabledClass = disabled ? "c-btn--disabled" : "", glassClass = glass ? "c-btn--glass" : "", loadingClass = loading ? BUTTON.CLASSES.LOADING : "", fullWidthClass = fullWidth ? BUTTON.CLASSES.FULL_WIDTH : "", blockClass = block ? BUTTON.CLASSES.BLOCK : "", activeClass = active ? BUTTON.CLASSES.ACTIVE : "", selectedClass = selected ? BUTTON.CLASSES.SELECTED : "";
|
|
3254
|
-
return [ BUTTON.BASE_CLASS, `c-btn--${variant}`, sizeClass, iconOnlyClass, roundedClass, disabledClass, glassClass, loadingClass, fullWidthClass, blockClass, activeClass, selectedClass, className ].filter(Boolean).join(" ");
|
|
3255
|
-
},
|
|
3256
|
-
handleClick: handler => event => {
|
|
3257
|
-
defaultProps.disabled || defaultProps.loading || !handler || handler(event);
|
|
3258
|
-
}
|
|
3259
|
-
};
|
|
3260
|
-
}({
|
|
3261
|
-
variant: variant,
|
|
3262
|
-
size: size,
|
|
3263
|
-
disabled: isDisabled,
|
|
3264
|
-
rounded: rounded,
|
|
3265
|
-
glass: glass,
|
|
3266
|
-
loading: loading,
|
|
3267
|
-
fullWidth: fullWidth,
|
|
3268
|
-
block: block,
|
|
3269
|
-
active: active,
|
|
3270
|
-
selected: selected
|
|
3271
|
-
}), buttonClass = useMemo((() => generateButtonClass({
|
|
3272
|
-
variant: variant,
|
|
3273
|
-
size: size,
|
|
3274
|
-
disabled: isDisabled,
|
|
3275
|
-
rounded: rounded,
|
|
3276
|
-
iconOnly: iconOnly,
|
|
3277
|
-
glass: glass,
|
|
3278
|
-
loading: loading,
|
|
3279
|
-
fullWidth: fullWidth,
|
|
3280
|
-
block: block,
|
|
3281
|
-
active: active,
|
|
3282
|
-
selected: selected,
|
|
3283
|
-
className: className
|
|
3284
|
-
})), [ variant, size, isDisabled, rounded, iconOnly, glass, loading, fullWidth, block, active, selected, className, generateButtonClass ]), handleClickEvent = useCallback((event => {
|
|
3238
|
+
}) : icon;
|
|
3239
|
+
// Determine if we should render as a link
|
|
3240
|
+
const buttonClass = [ BUTTON.BASE_CLASS, ThemeNaming.variantClass("btn", variant), "md" !== size ? ThemeNaming.sizeClass("btn", size) : "", iconOnly ? ThemeNaming.stateClass("btn", "icon") : "", rounded ? ThemeNaming.stateClass("btn", "rounded") : "", isDisabled ? ThemeNaming.stateClass("btn", "disabled") : "", glass ? ThemeNaming.stateClass("btn", "glass") : "", loading ? BUTTON.CLASSES.LOADING : "", fullWidth ? BUTTON.CLASSES.FULL_WIDTH : "", block ? BUTTON.CLASSES.BLOCK : "", active ? BUTTON.CLASSES.ACTIVE : "", selected ? BUTTON.CLASSES.SELECTED : "", className ].filter(Boolean).join(" "), handleClickEvent = useCallback((event => {
|
|
3285
3241
|
isDisabled ? event.preventDefault() : onClick?.(event);
|
|
3286
3242
|
}), [ isDisabled, onClick ]), handleMouseEnter = useCallback((event => {
|
|
3287
3243
|
isDisabled || onHover?.(event);
|
|
@@ -3289,28 +3245,23 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
3289
3245
|
isDisabled || onFocus?.(event);
|
|
3290
3246
|
}), [ isDisabled, onFocus ]), handleBlurEvent = useCallback((event => {
|
|
3291
3247
|
isDisabled || onBlur?.(event);
|
|
3292
|
-
}), [ isDisabled, onBlur ]), buttonText =
|
|
3293
|
-
|
|
3294
|
-
className:
|
|
3295
|
-
"aria-hidden": "true",
|
|
3296
|
-
children: iconElement
|
|
3297
|
-
}), spinnerElement = loading && jsx("span", {
|
|
3298
|
-
className: BUTTON.SPINNER_CLASS,
|
|
3248
|
+
}), [ isDisabled, onBlur ]), buttonText = loading && loadingText ? loadingText : label || children, spinnerSize = "sm" === size ? "sm" : "lg" === size ? "md" : "sm", buttonContent = jsxs(Fragment, {
|
|
3249
|
+
children: [ loading && jsx("span", {
|
|
3250
|
+
className: ThemeNaming.bemClass("btn", "spinner"),
|
|
3299
3251
|
"aria-hidden": "true",
|
|
3300
3252
|
children: jsx(Spinner, {
|
|
3301
3253
|
size: spinnerSize,
|
|
3302
3254
|
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
|
|
3303
3255
|
})
|
|
3304
|
-
}),
|
|
3305
|
-
className:
|
|
3256
|
+
}), iconElement && !loading && jsx("span", {
|
|
3257
|
+
className: ThemeNaming.bemClass("btn", "icon"),
|
|
3258
|
+
"aria-hidden": "true",
|
|
3259
|
+
children: iconElement
|
|
3260
|
+
}), !iconOnly && buttonText && jsx("span", {
|
|
3261
|
+
className: ThemeNaming.bemClass("btn", "label"),
|
|
3306
3262
|
children: buttonText
|
|
3307
|
-
})
|
|
3308
|
-
|
|
3309
|
-
children: [ labelElement, spinnerElement, iconSpan ]
|
|
3310
|
-
} : {
|
|
3311
|
-
children: [ spinnerElement, iconSpan, labelElement ]
|
|
3312
|
-
});
|
|
3313
|
-
}), [ iconElement, iconPosition, iconOnly, buttonText, loading, spinnerSize, variant ]), buttonProps = useMemo((() => ({
|
|
3263
|
+
}) ]
|
|
3264
|
+
}), buttonProps = {
|
|
3314
3265
|
ref: ref,
|
|
3315
3266
|
className: buttonClass,
|
|
3316
3267
|
type: "button" !== Component || shouldRenderAsLink ? void 0 : type,
|
|
@@ -3328,8 +3279,16 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
3328
3279
|
tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
|
|
3329
3280
|
style: style,
|
|
3330
3281
|
...props
|
|
3331
|
-
}
|
|
3332
|
-
|
|
3282
|
+
}, defaultGlassProps = {
|
|
3283
|
+
displacementScale: 20,
|
|
3284
|
+
blurAmount: 0,
|
|
3285
|
+
saturation: 200,
|
|
3286
|
+
elasticity: 0
|
|
3287
|
+
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
3288
|
+
...defaultGlassProps,
|
|
3289
|
+
...glass
|
|
3290
|
+
};
|
|
3291
|
+
// Handle click with loading check
|
|
3333
3292
|
// Render as anchor if href is provided
|
|
3334
3293
|
if (shouldRenderAsLink) {
|
|
3335
3294
|
const {ref: _, ...buttonPropsWithoutRef} = buttonProps, anchorButtonProps = {
|
|
@@ -3349,22 +3308,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
3349
3308
|
...linkProps,
|
|
3350
3309
|
children: buttonContent
|
|
3351
3310
|
});
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
saturation: 200,
|
|
3357
|
-
elasticity: 0
|
|
3358
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
3359
|
-
...defaultGlassProps,
|
|
3360
|
-
...glass
|
|
3361
|
-
};
|
|
3362
|
-
return jsx(AtomixGlass, {
|
|
3363
|
-
...glassProps,
|
|
3364
|
-
children: linkElement
|
|
3365
|
-
});
|
|
3366
|
-
}
|
|
3367
|
-
return linkElement;
|
|
3311
|
+
return glass ? jsx(AtomixGlass, {
|
|
3312
|
+
...glassProps,
|
|
3313
|
+
children: linkElement
|
|
3314
|
+
}) : linkElement;
|
|
3368
3315
|
}
|
|
3369
3316
|
// Fallback to regular anchor tag
|
|
3370
3317
|
const anchorElement = jsx("a", {
|
|
@@ -3375,46 +3322,20 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
3375
3322
|
rel: "_blank" === target ? "noopener noreferrer" : void 0,
|
|
3376
3323
|
children: buttonContent
|
|
3377
3324
|
});
|
|
3378
|
-
|
|
3379
|
-
const defaultGlassProps = {
|
|
3380
|
-
displacementScale: 20,
|
|
3381
|
-
blurAmount: 0,
|
|
3382
|
-
saturation: 200,
|
|
3383
|
-
elasticity: 0
|
|
3384
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
3385
|
-
...defaultGlassProps,
|
|
3386
|
-
...glass
|
|
3387
|
-
};
|
|
3388
|
-
return jsx(AtomixGlass, {
|
|
3389
|
-
...glassProps,
|
|
3390
|
-
children: anchorElement
|
|
3391
|
-
});
|
|
3392
|
-
}
|
|
3393
|
-
return anchorElement;
|
|
3394
|
-
}
|
|
3395
|
-
// Default button rendering
|
|
3396
|
-
if (glass) {
|
|
3397
|
-
const defaultGlassProps = {
|
|
3398
|
-
displacementScale: 20,
|
|
3399
|
-
blurAmount: 0,
|
|
3400
|
-
saturation: 200,
|
|
3401
|
-
elasticity: 0
|
|
3402
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
3403
|
-
...defaultGlassProps,
|
|
3404
|
-
...glass
|
|
3405
|
-
};
|
|
3406
|
-
return jsx(AtomixGlass, {
|
|
3325
|
+
return glass ? jsx(AtomixGlass, {
|
|
3407
3326
|
...glassProps,
|
|
3408
|
-
children:
|
|
3409
|
-
|
|
3410
|
-
children: buttonContent
|
|
3411
|
-
})
|
|
3412
|
-
});
|
|
3327
|
+
children: anchorElement
|
|
3328
|
+
}) : anchorElement;
|
|
3413
3329
|
}
|
|
3414
|
-
|
|
3330
|
+
// Default button rendering
|
|
3331
|
+
const buttonElement = jsx(Component, {
|
|
3415
3332
|
...buttonProps,
|
|
3416
3333
|
children: buttonContent
|
|
3417
3334
|
});
|
|
3335
|
+
return glass ? jsx(AtomixGlass, {
|
|
3336
|
+
...glassProps,
|
|
3337
|
+
children: buttonElement
|
|
3338
|
+
}) : buttonElement;
|
|
3418
3339
|
})));
|
|
3419
3340
|
|
|
3420
3341
|
Button.displayName = "Button";
|