@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/core.js
CHANGED
|
@@ -586,9 +586,7 @@ import * as PhosphorIcons from "@phosphor-icons/react";
|
|
|
586
586
|
})
|
|
587
587
|
});
|
|
588
588
|
|
|
589
|
-
|
|
590
|
-
* Accordion-specific constants
|
|
591
|
-
*/ GlassFilterComponent.displayName = "GlassFilter";
|
|
589
|
+
GlassFilterComponent.displayName = "GlassFilter";
|
|
592
590
|
|
|
593
591
|
// Memoize component to prevent unnecessary re-renders
|
|
594
592
|
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 = {
|
|
@@ -601,10 +599,11 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
|
|
|
601
599
|
width: 0,
|
|
602
600
|
height: 0
|
|
603
601
|
}, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
|
|
604
|
-
//
|
|
605
|
-
//
|
|
606
|
-
//
|
|
607
|
-
|
|
602
|
+
// Generate a stable, deterministic ID for SSR compatibility
|
|
603
|
+
// React's useId() should produce the same ID on server and client for the same
|
|
604
|
+
// component position in the tree. We use useState to ensure the ID is only
|
|
605
|
+
// generated once and remains stable across renders.
|
|
606
|
+
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);
|
|
608
607
|
// Lazy load shader utilities only when shader mode is needed
|
|
609
608
|
useEffect((() => {
|
|
610
609
|
"shader" === mode ?
|
|
@@ -664,7 +663,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
|
|
|
664
663
|
timestamp: Date.now()
|
|
665
664
|
}),
|
|
666
665
|
// Development mode: log cache size
|
|
667
|
-
"production"
|
|
666
|
+
"undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
|
|
668
667
|
})(cacheKey, url), setShaderMapUrl(url);
|
|
669
668
|
};
|
|
670
669
|
"undefined" != typeof requestIdleCallback ? requestIdleCallback(generate, {
|
|
@@ -977,9 +976,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
977
976
|
childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius,
|
|
978
977
|
extractionSource = "React children");
|
|
979
978
|
}
|
|
980
|
-
null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : process.env
|
|
979
|
+
null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : "undefined" == typeof process || process.env;
|
|
981
980
|
} catch (error) {
|
|
982
|
-
"production"
|
|
981
|
+
"undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugCornerRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
|
|
983
982
|
}
|
|
984
983
|
};
|
|
985
984
|
extractRadius();
|
|
@@ -1054,7 +1053,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1054
1053
|
// For image backgrounds, assume medium luminance
|
|
1055
1054
|
totalLuminance += .5, validSamples++, hasValidBackground = !0);
|
|
1056
1055
|
} catch (styleError) {
|
|
1057
|
-
process.env
|
|
1056
|
+
"undefined" == typeof process || process.env;
|
|
1058
1057
|
}
|
|
1059
1058
|
// Move to parent element for next iteration
|
|
1060
1059
|
if (!currentElement) break;
|
|
@@ -1093,7 +1092,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1093
1092
|
}
|
|
1094
1093
|
} catch (error) {
|
|
1095
1094
|
// Enhanced error logging with context
|
|
1096
|
-
"development"
|
|
1095
|
+
"undefined" != typeof process && "development" !== process.env?.NODE_ENV || console.warn("AtomixGlass: Error detecting background brightness:", error);
|
|
1097
1096
|
const result = !1;
|
|
1098
1097
|
if (element && element.parentElement) {
|
|
1099
1098
|
const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
|
|
@@ -1150,7 +1149,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1150
1149
|
};
|
|
1151
1150
|
// Calculate offset relative to this container
|
|
1152
1151
|
// React 18 automatically batches these updates
|
|
1153
|
-
setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "production"
|
|
1152
|
+
setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "undefined" != typeof process && "production" === process.env?.NODE_ENV || !enablePerformanceMonitoring || performance.now();
|
|
1154
1153
|
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects, enablePerformanceMonitoring ]);
|
|
1155
1154
|
// Subscribe to shared mouse tracker
|
|
1156
1155
|
useEffect((() => {
|
|
@@ -1290,10 +1289,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1290
1289
|
saturationBoost: validatedSaturationBoost + .4 * mouseInfluence
|
|
1291
1290
|
};
|
|
1292
1291
|
// Validate and apply object config values with proper clamping
|
|
1293
|
-
return process.env
|
|
1292
|
+
return "undefined" == typeof process || process.env, finalConfig;
|
|
1294
1293
|
}
|
|
1295
1294
|
// Debug logging for non-object configs
|
|
1296
|
-
return process.env
|
|
1295
|
+
return "undefined" == typeof process || process.env, baseConfig;
|
|
1297
1296
|
}), [ 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 => {
|
|
1298
1297
|
!onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
|
|
1299
1298
|
}), [ onClick ]), handleMouseMove = useCallback((_e => {}), []);
|
|
@@ -1404,7 +1403,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1404
1403
|
* <div>Content with debug logging enabled</div>
|
|
1405
1404
|
* </AtomixGlass>
|
|
1406
1405
|
*/ 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}) {
|
|
1407
|
-
const glassRef = useRef(null), contentRef = useRef(null),
|
|
1406
|
+
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({
|
|
1408
1407
|
glassRef: glassRef,
|
|
1409
1408
|
contentRef: contentRef,
|
|
1410
1409
|
cornerRadius: cornerRadius,
|
|
@@ -1421,128 +1420,51 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
|
|
|
1421
1420
|
debugOverLight: debugOverLight,
|
|
1422
1421
|
enablePerformanceMonitoring: enablePerformanceMonitoring,
|
|
1423
1422
|
children: children
|
|
1424
|
-
}), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight
|
|
1425
|
-
// Read CSS custom properties once on mount and cache them
|
|
1426
|
-
useEffect((() => {
|
|
1427
|
-
if ("undefined" != typeof window && glassRef.current && !opacityCacheRef.current) try {
|
|
1428
|
-
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) => {
|
|
1429
|
-
if (!value) return defaultValue;
|
|
1430
|
-
const parsed = parseFloat(value);
|
|
1431
|
-
return isNaN(parsed) ? defaultValue : parsed;
|
|
1432
|
-
};
|
|
1433
|
-
opacityCacheRef.current = {
|
|
1434
|
-
opacity50: parseOpacity(opacity50Value, .5),
|
|
1435
|
-
opacity40: parseOpacity(opacity40Value, .4),
|
|
1436
|
-
opacity80: parseOpacity(opacity80Value, .8),
|
|
1437
|
-
opacity0: parseOpacity(opacity0Value, 0)
|
|
1438
|
-
};
|
|
1439
|
-
} catch (error) {
|
|
1440
|
-
// Fallback to defaults if reading fails
|
|
1441
|
-
opacityCacheRef.current = {
|
|
1442
|
-
opacity50: .5,
|
|
1443
|
-
opacity40: .4,
|
|
1444
|
-
opacity80: .8,
|
|
1445
|
-
opacity0: 0
|
|
1446
|
-
};
|
|
1447
|
-
}
|
|
1448
|
-
}), []);
|
|
1449
|
-
// Calculate base style with transforms (only dynamic values)
|
|
1450
|
-
const baseStyle = useMemo((() => ({
|
|
1423
|
+
}), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
|
|
1451
1424
|
...style,
|
|
1452
1425
|
...0 !== elasticity && !effectiveDisableEffects && {
|
|
1453
1426
|
transform: transformStyle
|
|
1454
1427
|
}
|
|
1455
|
-
}
|
|
1456
|
-
position:
|
|
1457
|
-
top:
|
|
1458
|
-
left:
|
|
1459
|
-
}
|
|
1460
|
-
width: "fixed" !==
|
|
1461
|
-
height: "fixed" !==
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
}), [ 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((() => {
|
|
1496
|
-
// RGB color values for rgba() functions
|
|
1497
|
-
// Note: CSS doesn't support rgba(var(--rgb), opacity) syntax, so we use direct values
|
|
1498
|
-
// These values align with design tokens: --atomix-white-rgb and --atomix-black-rgb
|
|
1499
|
-
// The actual RGB values are defined in SCSS and should match these fallbacks
|
|
1500
|
-
// TODO: Consider reading from CSS custom properties if browser support improves
|
|
1501
|
-
const whiteColor = "255, 255, 255";
|
|
1502
|
-
// Matches --atomix-white-rgb design token
|
|
1503
|
-
// Matches --atomix-black-rgb design token
|
|
1504
|
-
return {
|
|
1505
|
-
// Standard CSS custom properties for dynamic values
|
|
1506
|
-
"--atomix-glass-radius": `${effectiveCornerRadius}px`,
|
|
1507
|
-
"--atomix-glass-transform": baseStyleTransform || "none",
|
|
1508
|
-
"--atomix-glass-position": positionStylesPosition,
|
|
1509
|
-
"--atomix-glass-top": "fixed" !== positionStylesTop ? `${positionStylesTop}px` : "0",
|
|
1510
|
-
"--atomix-glass-left": "fixed" !== positionStylesLeft ? `${positionStylesLeft}px` : "0",
|
|
1511
|
-
"--atomix-glass-width": "fixed" !== baseStylePosition ? adjustedSizeWidth : `${adjustedSizeWidth}px`,
|
|
1512
|
-
"--atomix-glass-height": "fixed" !== baseStylePosition ? adjustedSizeHeight : `${adjustedSizeHeight}px`,
|
|
1513
|
-
// Border width: Use spacing token for consistency
|
|
1514
|
-
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
|
|
1515
|
-
"--atomix-glass-blend-mode": gradientIsOverLight ? "multiply" : "overlay",
|
|
1516
|
-
// Dynamic gradients and backgrounds
|
|
1517
|
-
// Note: RGB values use design token-aligned constants (white: 255,255,255; black: 0,0,0)
|
|
1518
|
-
"--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%)`,
|
|
1519
|
-
"--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%)`,
|
|
1520
|
-
"--atomix-glass-hover-1-opacity": opacityValuesHover1,
|
|
1521
|
-
"--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}%)`,
|
|
1522
|
-
"--atomix-glass-hover-2-opacity": opacityValuesHover2,
|
|
1523
|
-
"--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}%)`,
|
|
1524
|
-
"--atomix-glass-hover-3-opacity": opacityValuesHover3,
|
|
1525
|
-
"--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}%)`,
|
|
1526
|
-
"--atomix-glass-base-opacity": opacityValuesBase,
|
|
1527
|
-
"--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})`,
|
|
1528
|
-
"--atomix-glass-overlay-opacity": opacityValuesOver,
|
|
1529
|
-
"--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})`
|
|
1530
|
-
};
|
|
1531
|
-
}), [
|
|
1532
|
-
// Position styles - only specific properties
|
|
1533
|
-
positionStylesPosition, positionStylesTop, positionStylesLeft,
|
|
1534
|
-
// Adjusted size - only specific properties
|
|
1535
|
-
adjustedSizeWidth, adjustedSizeHeight,
|
|
1536
|
-
// Base style - only transform property
|
|
1537
|
-
baseStyleTransform, baseStylePosition,
|
|
1538
|
-
// Other values
|
|
1539
|
-
effectiveCornerRadius, effectiveReducedMotion,
|
|
1540
|
-
// Gradient calculations - extracted properties
|
|
1541
|
-
gradientIsOverLight, gradientMx, gradientMy, gradientBorderGradientAngle, gradientBorderStop1, gradientBorderStop2, gradientBorderOpacity1, gradientBorderOpacity2, gradientBorderOpacity3, gradientBorderOpacity4, gradientHover1X, gradientHover1Y, gradientHover2X, gradientHover2Y, gradientHover3X, gradientHover3Y, gradientBaseX, gradientBaseY,
|
|
1542
|
-
// Opacity values - extracted properties
|
|
1543
|
-
opacityValuesHover1, opacityValuesHover2, opacityValuesHover3, opacityValuesBase, opacityValuesOver ]);
|
|
1544
|
-
// Build className with state modifiers
|
|
1545
|
-
return jsxs("div", {
|
|
1428
|
+
}, 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 = {
|
|
1429
|
+
position: style.position || "absolute",
|
|
1430
|
+
top: style.top || 0,
|
|
1431
|
+
left: style.left || 0
|
|
1432
|
+
}, adjustedSize = {
|
|
1433
|
+
width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
|
|
1434
|
+
height: "fixed" !== style.position ? "100%" : style.height ? style.height : Math.max(glassSize.height, 0)
|
|
1435
|
+
}, 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 = {
|
|
1436
|
+
hover1: isHovered || isActive ? .5 : 0,
|
|
1437
|
+
hover2: isActive ? .5 : 0,
|
|
1438
|
+
hover3: isHovered ? .4 : isActive ? .8 : 0,
|
|
1439
|
+
base: isOverLight ? overLightOpacity || .4 : 0,
|
|
1440
|
+
over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
|
|
1441
|
+
}, whiteColor = "255, 255, 255", glassVars = {
|
|
1442
|
+
// Standard CSS custom properties for dynamic values
|
|
1443
|
+
"--atomix-glass-radius": `${effectiveCornerRadius}px`,
|
|
1444
|
+
"--atomix-glass-transform": transformStyle || "none",
|
|
1445
|
+
"--atomix-glass-position": positionStyles.position,
|
|
1446
|
+
"--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
|
|
1447
|
+
"--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
|
|
1448
|
+
"--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
|
|
1449
|
+
"--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
|
|
1450
|
+
// Border width: Use spacing token for consistency
|
|
1451
|
+
"--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
|
|
1452
|
+
"--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
|
|
1453
|
+
// Dynamic gradients and backgrounds
|
|
1454
|
+
"--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%)`,
|
|
1455
|
+
"--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%)`,
|
|
1456
|
+
"--atomix-glass-hover-1-opacity": opacityValues.hover1,
|
|
1457
|
+
"--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}%)`,
|
|
1458
|
+
"--atomix-glass-hover-2-opacity": opacityValues.hover2,
|
|
1459
|
+
"--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}%)`,
|
|
1460
|
+
"--atomix-glass-hover-3-opacity": opacityValues.hover3,
|
|
1461
|
+
"--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}%)`,
|
|
1462
|
+
"--atomix-glass-base-opacity": opacityValues.base,
|
|
1463
|
+
"--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})`,
|
|
1464
|
+
"--atomix-glass-overlay-opacity": opacityValues.over,
|
|
1465
|
+
"--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})`
|
|
1466
|
+
};
|
|
1467
|
+
return jsxs("div", {
|
|
1546
1468
|
className: componentClassName,
|
|
1547
1469
|
style: glassVars,
|
|
1548
1470
|
role: role || (onClick ? "button" : void 0),
|
|
@@ -2063,69 +1985,103 @@ const sizeMap = {
|
|
|
2063
1985
|
* Icon component that displays a Phosphor icon
|
|
2064
1986
|
*/ Icon.displayName = "Icon";
|
|
2065
1987
|
|
|
1988
|
+
/**
|
|
1989
|
+
* Theme Naming Utility
|
|
1990
|
+
*
|
|
1991
|
+
* Provides consistent naming conventions for CSS classes, CSS variables,
|
|
1992
|
+
* and JavaScript properties throughout the theme system.
|
|
1993
|
+
*/
|
|
1994
|
+
class ThemeNaming {
|
|
1995
|
+
/**
|
|
1996
|
+
* Set the global prefix for all theme tokens
|
|
1997
|
+
* @param newPrefix - New prefix to use
|
|
1998
|
+
*/
|
|
1999
|
+
static setPrefix(newPrefix) {
|
|
2000
|
+
this.prefix = newPrefix;
|
|
2001
|
+
}
|
|
2002
|
+
/**
|
|
2003
|
+
* Get the current prefix
|
|
2004
|
+
*/ static getPrefix() {
|
|
2005
|
+
return this.prefix;
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Convert camelCase to kebab-case for CSS variables
|
|
2009
|
+
* @param str - String to convert
|
|
2010
|
+
*/ static camelToKebab(str) {
|
|
2011
|
+
return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
|
|
2012
|
+
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Convert kebab-case to camelCase for JavaScript properties
|
|
2015
|
+
* @param str - String to convert
|
|
2016
|
+
*/ static kebabToCamel(str) {
|
|
2017
|
+
return str.replace(/-([a-z])/g, (g => g[1].toUpperCase()));
|
|
2018
|
+
}
|
|
2019
|
+
/**
|
|
2020
|
+
* Create a CSS variable name
|
|
2021
|
+
* @param token - Token name in camelCase
|
|
2022
|
+
*/ static cssVar(token) {
|
|
2023
|
+
return `--${this.prefix}-${this.camelToKebab(token)}`;
|
|
2024
|
+
}
|
|
2025
|
+
/**
|
|
2026
|
+
* Create a BEM CSS class name
|
|
2027
|
+
* @param block - Block name
|
|
2028
|
+
* @param element - Element name (optional)
|
|
2029
|
+
* @param modifier - Modifier name (optional)
|
|
2030
|
+
*/ static bemClass(block, element, modifier) {
|
|
2031
|
+
let className = `c-${block}`;
|
|
2032
|
+
return element && (className += `__${element}`), modifier && (className += `--${modifier}`),
|
|
2033
|
+
className;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Create a variant class name
|
|
2037
|
+
* @param component - Component name
|
|
2038
|
+
* @param variant - Variant name
|
|
2039
|
+
*/ static variantClass(component, variant) {
|
|
2040
|
+
return `c-${component}--${variant}`;
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Create a size class name
|
|
2044
|
+
* @param component - Component name
|
|
2045
|
+
* @param size - Size name
|
|
2046
|
+
*/ static sizeClass(component, size) {
|
|
2047
|
+
return `c-${component}--${size}`;
|
|
2048
|
+
}
|
|
2049
|
+
/**
|
|
2050
|
+
* Create a state class name
|
|
2051
|
+
* @param component - Component name
|
|
2052
|
+
* @param state - State name
|
|
2053
|
+
*/ static stateClass(component, state) {
|
|
2054
|
+
return `c-${component}--${state}`;
|
|
2055
|
+
}
|
|
2056
|
+
/**
|
|
2057
|
+
* Create a utility class name
|
|
2058
|
+
* @param utility - Utility name
|
|
2059
|
+
*/ static utilityClass(utility) {
|
|
2060
|
+
return `u-${utility}`;
|
|
2061
|
+
}
|
|
2062
|
+
/**
|
|
2063
|
+
* Create a layout class name
|
|
2064
|
+
* @param layout - Layout name
|
|
2065
|
+
*/ static layoutClass(layout) {
|
|
2066
|
+
return `l-${layout}`;
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Create an object class name
|
|
2070
|
+
* @param object - Object name
|
|
2071
|
+
*/ static objectClass(object) {
|
|
2072
|
+
return `o-${object}`;
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
ThemeNaming.prefix = "atomix";
|
|
2077
|
+
|
|
2066
2078
|
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) => {
|
|
2067
|
-
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement =
|
|
2079
|
+
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
|
|
2068
2080
|
name: iconName,
|
|
2069
2081
|
size: iconSize
|
|
2070
|
-
}) : icon
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
* @param initialProps - Initial button properties
|
|
2074
|
-
* @returns Button state and methods
|
|
2075
|
-
*/
|
|
2076
|
-
function(initialProps) {
|
|
2077
|
-
// Default button properties
|
|
2078
|
-
const defaultProps = {
|
|
2079
|
-
variant: "primary",
|
|
2080
|
-
size: "md",
|
|
2081
|
-
disabled: !1,
|
|
2082
|
-
rounded: !1,
|
|
2083
|
-
loading: !1,
|
|
2084
|
-
fullWidth: !1,
|
|
2085
|
-
block: !1,
|
|
2086
|
-
active: !1,
|
|
2087
|
-
selected: !1,
|
|
2088
|
-
...initialProps
|
|
2089
|
-
};
|
|
2090
|
-
/**
|
|
2091
|
-
* Generate button class based on properties
|
|
2092
|
-
* @param props - Button properties
|
|
2093
|
-
* @returns Class string
|
|
2094
|
-
*/ return {
|
|
2095
|
-
defaultProps: defaultProps,
|
|
2096
|
-
generateButtonClass: props => {
|
|
2097
|
-
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 : "";
|
|
2098
|
-
return [ BUTTON.BASE_CLASS, `c-btn--${variant}`, sizeClass, iconOnlyClass, roundedClass, disabledClass, glassClass, loadingClass, fullWidthClass, blockClass, activeClass, selectedClass, className ].filter(Boolean).join(" ");
|
|
2099
|
-
},
|
|
2100
|
-
handleClick: handler => event => {
|
|
2101
|
-
defaultProps.disabled || defaultProps.loading || !handler || handler(event);
|
|
2102
|
-
}
|
|
2103
|
-
};
|
|
2104
|
-
}({
|
|
2105
|
-
variant: variant,
|
|
2106
|
-
size: size,
|
|
2107
|
-
disabled: isDisabled,
|
|
2108
|
-
rounded: rounded,
|
|
2109
|
-
glass: glass,
|
|
2110
|
-
loading: loading,
|
|
2111
|
-
fullWidth: fullWidth,
|
|
2112
|
-
block: block,
|
|
2113
|
-
active: active,
|
|
2114
|
-
selected: selected
|
|
2115
|
-
}), buttonClass = useMemo((() => generateButtonClass({
|
|
2116
|
-
variant: variant,
|
|
2117
|
-
size: size,
|
|
2118
|
-
disabled: isDisabled,
|
|
2119
|
-
rounded: rounded,
|
|
2120
|
-
iconOnly: iconOnly,
|
|
2121
|
-
glass: glass,
|
|
2122
|
-
loading: loading,
|
|
2123
|
-
fullWidth: fullWidth,
|
|
2124
|
-
block: block,
|
|
2125
|
-
active: active,
|
|
2126
|
-
selected: selected,
|
|
2127
|
-
className: className
|
|
2128
|
-
})), [ variant, size, isDisabled, rounded, iconOnly, glass, loading, fullWidth, block, active, selected, className, generateButtonClass ]), handleClickEvent = useCallback((event => {
|
|
2082
|
+
}) : icon;
|
|
2083
|
+
// Determine if we should render as a link
|
|
2084
|
+
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 => {
|
|
2129
2085
|
isDisabled ? event.preventDefault() : onClick?.(event);
|
|
2130
2086
|
}), [ isDisabled, onClick ]), handleMouseEnter = useCallback((event => {
|
|
2131
2087
|
isDisabled || onHover?.(event);
|
|
@@ -2133,28 +2089,23 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
2133
2089
|
isDisabled || onFocus?.(event);
|
|
2134
2090
|
}), [ isDisabled, onFocus ]), handleBlurEvent = useCallback((event => {
|
|
2135
2091
|
isDisabled || onBlur?.(event);
|
|
2136
|
-
}), [ isDisabled, onBlur ]), buttonText =
|
|
2137
|
-
|
|
2138
|
-
className:
|
|
2139
|
-
"aria-hidden": "true",
|
|
2140
|
-
children: iconElement
|
|
2141
|
-
}), spinnerElement = loading && jsx("span", {
|
|
2142
|
-
className: BUTTON.SPINNER_CLASS,
|
|
2092
|
+
}), [ isDisabled, onBlur ]), buttonText = loading && loadingText ? loadingText : label || children, spinnerSize = "sm" === size ? "sm" : "lg" === size ? "md" : "sm", buttonContent = jsxs(Fragment, {
|
|
2093
|
+
children: [ loading && jsx("span", {
|
|
2094
|
+
className: ThemeNaming.bemClass("btn", "spinner"),
|
|
2143
2095
|
"aria-hidden": "true",
|
|
2144
2096
|
children: jsx(Spinner, {
|
|
2145
2097
|
size: spinnerSize,
|
|
2146
2098
|
variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
|
|
2147
2099
|
})
|
|
2148
|
-
}),
|
|
2149
|
-
className:
|
|
2100
|
+
}), iconElement && !loading && jsx("span", {
|
|
2101
|
+
className: ThemeNaming.bemClass("btn", "icon"),
|
|
2102
|
+
"aria-hidden": "true",
|
|
2103
|
+
children: iconElement
|
|
2104
|
+
}), !iconOnly && buttonText && jsx("span", {
|
|
2105
|
+
className: ThemeNaming.bemClass("btn", "label"),
|
|
2150
2106
|
children: buttonText
|
|
2151
|
-
})
|
|
2152
|
-
|
|
2153
|
-
children: [ labelElement, spinnerElement, iconSpan ]
|
|
2154
|
-
} : {
|
|
2155
|
-
children: [ spinnerElement, iconSpan, labelElement ]
|
|
2156
|
-
});
|
|
2157
|
-
}), [ iconElement, iconPosition, iconOnly, buttonText, loading, spinnerSize, variant ]), buttonProps = useMemo((() => ({
|
|
2107
|
+
}) ]
|
|
2108
|
+
}), buttonProps = {
|
|
2158
2109
|
ref: ref,
|
|
2159
2110
|
className: buttonClass,
|
|
2160
2111
|
type: "button" !== Component || shouldRenderAsLink ? void 0 : type,
|
|
@@ -2172,8 +2123,16 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
2172
2123
|
tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
|
|
2173
2124
|
style: style,
|
|
2174
2125
|
...props
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2126
|
+
}, defaultGlassProps = {
|
|
2127
|
+
displacementScale: 20,
|
|
2128
|
+
blurAmount: 0,
|
|
2129
|
+
saturation: 200,
|
|
2130
|
+
elasticity: 0
|
|
2131
|
+
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
2132
|
+
...defaultGlassProps,
|
|
2133
|
+
...glass
|
|
2134
|
+
};
|
|
2135
|
+
// Handle click with loading check
|
|
2177
2136
|
// Render as anchor if href is provided
|
|
2178
2137
|
if (shouldRenderAsLink) {
|
|
2179
2138
|
const {ref: _, ...buttonPropsWithoutRef} = buttonProps, anchorButtonProps = {
|
|
@@ -2193,22 +2152,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
2193
2152
|
...linkProps,
|
|
2194
2153
|
children: buttonContent
|
|
2195
2154
|
});
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
saturation: 200,
|
|
2201
|
-
elasticity: 0
|
|
2202
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
2203
|
-
...defaultGlassProps,
|
|
2204
|
-
...glass
|
|
2205
|
-
};
|
|
2206
|
-
return jsx(AtomixGlass, {
|
|
2207
|
-
...glassProps,
|
|
2208
|
-
children: linkElement
|
|
2209
|
-
});
|
|
2210
|
-
}
|
|
2211
|
-
return linkElement;
|
|
2155
|
+
return glass ? jsx(AtomixGlass, {
|
|
2156
|
+
...glassProps,
|
|
2157
|
+
children: linkElement
|
|
2158
|
+
}) : linkElement;
|
|
2212
2159
|
}
|
|
2213
2160
|
// Fallback to regular anchor tag
|
|
2214
2161
|
const anchorElement = jsx("a", {
|
|
@@ -2219,46 +2166,20 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
2219
2166
|
rel: "_blank" === target ? "noopener noreferrer" : void 0,
|
|
2220
2167
|
children: buttonContent
|
|
2221
2168
|
});
|
|
2222
|
-
|
|
2223
|
-
const defaultGlassProps = {
|
|
2224
|
-
displacementScale: 20,
|
|
2225
|
-
blurAmount: 0,
|
|
2226
|
-
saturation: 200,
|
|
2227
|
-
elasticity: 0
|
|
2228
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
2229
|
-
...defaultGlassProps,
|
|
2230
|
-
...glass
|
|
2231
|
-
};
|
|
2232
|
-
return jsx(AtomixGlass, {
|
|
2233
|
-
...glassProps,
|
|
2234
|
-
children: anchorElement
|
|
2235
|
-
});
|
|
2236
|
-
}
|
|
2237
|
-
return anchorElement;
|
|
2238
|
-
}
|
|
2239
|
-
// Default button rendering
|
|
2240
|
-
if (glass) {
|
|
2241
|
-
const defaultGlassProps = {
|
|
2242
|
-
displacementScale: 20,
|
|
2243
|
-
blurAmount: 0,
|
|
2244
|
-
saturation: 200,
|
|
2245
|
-
elasticity: 0
|
|
2246
|
-
}, glassProps = !0 === glass ? defaultGlassProps : {
|
|
2247
|
-
...defaultGlassProps,
|
|
2248
|
-
...glass
|
|
2249
|
-
};
|
|
2250
|
-
return jsx(AtomixGlass, {
|
|
2169
|
+
return glass ? jsx(AtomixGlass, {
|
|
2251
2170
|
...glassProps,
|
|
2252
|
-
children:
|
|
2253
|
-
|
|
2254
|
-
children: buttonContent
|
|
2255
|
-
})
|
|
2256
|
-
});
|
|
2171
|
+
children: anchorElement
|
|
2172
|
+
}) : anchorElement;
|
|
2257
2173
|
}
|
|
2258
|
-
|
|
2174
|
+
// Default button rendering
|
|
2175
|
+
const buttonElement = jsx(Component, {
|
|
2259
2176
|
...buttonProps,
|
|
2260
2177
|
children: buttonContent
|
|
2261
2178
|
});
|
|
2179
|
+
return glass ? jsx(AtomixGlass, {
|
|
2180
|
+
...glassProps,
|
|
2181
|
+
children: buttonElement
|
|
2182
|
+
}) : buttonElement;
|
|
2262
2183
|
})));
|
|
2263
2184
|
|
|
2264
2185
|
Button.displayName = "Button";
|