@shohojdhara/atomix 0.3.6 → 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.
Files changed (51) hide show
  1. package/README.md +3 -3
  2. package/dist/charts.js +50 -142
  3. package/dist/charts.js.map +1 -1
  4. package/dist/core.js +179 -274
  5. package/dist/core.js.map +1 -1
  6. package/dist/forms.js +50 -142
  7. package/dist/forms.js.map +1 -1
  8. package/dist/heavy.js +179 -274
  9. package/dist/heavy.js.map +1 -1
  10. package/dist/index.d.ts +669 -703
  11. package/dist/index.esm.js +966 -1649
  12. package/dist/index.esm.js.map +1 -1
  13. package/dist/index.js +1211 -1890
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.min.js +1 -1
  16. package/dist/index.min.js.map +1 -1
  17. package/dist/theme.d.ts +163 -334
  18. package/dist/theme.js +774 -1473
  19. package/dist/theme.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/components/AtomixGlass/AtomixGlass.tsx +128 -356
  22. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +1 -1
  23. package/src/components/Button/Button.tsx +85 -167
  24. package/src/lib/composables/useAtomixGlass.ts +7 -7
  25. package/src/lib/config/loader.ts +2 -3
  26. package/src/lib/constants/components.ts +7 -0
  27. package/src/lib/hooks/usePerformanceMonitor.ts +1 -1
  28. package/src/lib/hooks/useThemeTokens.ts +105 -0
  29. package/src/lib/theme/config/configLoader.ts +60 -219
  30. package/src/lib/theme/config/loader.ts +15 -21
  31. package/src/lib/theme/constants/constants.ts +1 -1
  32. package/src/lib/theme/core/ThemeRegistry.ts +75 -279
  33. package/src/lib/theme/core/composeTheme.ts +14 -64
  34. package/src/lib/theme/core/createTheme.ts +54 -40
  35. package/src/lib/theme/core/createThemeObject.ts +2 -2
  36. package/src/lib/theme/core/index.ts +15 -1
  37. package/src/lib/theme/errors/errors.ts +1 -1
  38. package/src/lib/theme/generators/generateCSSNested.ts +130 -0
  39. package/src/lib/theme/generators/index.ts +6 -0
  40. package/src/lib/theme/index.ts +35 -10
  41. package/src/lib/theme/runtime/ThemeApplicator.ts +1 -1
  42. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +4 -4
  43. package/src/lib/theme/runtime/ThemeProvider.tsx +261 -554
  44. package/src/lib/theme/runtime/index.ts +1 -0
  45. package/src/lib/theme/runtime/useThemeTokens.ts +131 -0
  46. package/src/lib/theme/utils/componentTheming.ts +132 -0
  47. package/src/lib/theme/utils/naming.ts +100 -0
  48. package/src/lib/theme/utils/themeUtils.ts +6 -6
  49. package/src/lib/utils/componentUtils.ts +1 -1
  50. package/src/lib/utils/memoryMonitor.ts +3 -3
  51. package/src/lib/utils/themeNaming.ts +135 -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 = {
@@ -665,7 +663,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
665
663
  timestamp: Date.now()
666
664
  }),
667
665
  // Development mode: log cache size
668
- "production" !== process.env.NODE_ENV && sharedShaderCache.size;
666
+ "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
669
667
  })(cacheKey, url), setShaderMapUrl(url);
670
668
  };
671
669
  "undefined" != typeof requestIdleCallback ? requestIdleCallback(generate, {
@@ -978,9 +976,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
978
976
  childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius,
979
977
  extractionSource = "React children");
980
978
  }
981
- null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : process.env.NODE_ENV;
979
+ null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : "undefined" == typeof process || process.env;
982
980
  } catch (error) {
983
- "production" !== process.env.NODE_ENV && debugCornerRadius && console.error("[AtomixGlass] Error extracting corner radius:", error);
981
+ "undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugCornerRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
984
982
  }
985
983
  };
986
984
  extractRadius();
@@ -1055,7 +1053,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1055
1053
  // For image backgrounds, assume medium luminance
1056
1054
  totalLuminance += .5, validSamples++, hasValidBackground = !0);
1057
1055
  } catch (styleError) {
1058
- process.env.NODE_ENV;
1056
+ "undefined" == typeof process || process.env;
1059
1057
  }
1060
1058
  // Move to parent element for next iteration
1061
1059
  if (!currentElement) break;
@@ -1094,7 +1092,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1094
1092
  }
1095
1093
  } catch (error) {
1096
1094
  // Enhanced error logging with context
1097
- "development" === process.env.NODE_ENV && console.warn("AtomixGlass: Error detecting background brightness:", error);
1095
+ "undefined" != typeof process && "development" !== process.env?.NODE_ENV || console.warn("AtomixGlass: Error detecting background brightness:", error);
1098
1096
  const result = !1;
1099
1097
  if (element && element.parentElement) {
1100
1098
  const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
@@ -1151,7 +1149,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1151
1149
  };
1152
1150
  // Calculate offset relative to this container
1153
1151
  // React 18 automatically batches these updates
1154
- setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "production" !== process.env.NODE_ENV && enablePerformanceMonitoring && performance.now();
1152
+ setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "undefined" != typeof process && "production" === process.env?.NODE_ENV || !enablePerformanceMonitoring || performance.now();
1155
1153
  }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects, enablePerformanceMonitoring ]);
1156
1154
  // Subscribe to shared mouse tracker
1157
1155
  useEffect((() => {
@@ -1291,10 +1289,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1291
1289
  saturationBoost: validatedSaturationBoost + .4 * mouseInfluence
1292
1290
  };
1293
1291
  // Validate and apply object config values with proper clamping
1294
- return process.env.NODE_ENV, finalConfig;
1292
+ return "undefined" == typeof process || process.env, finalConfig;
1295
1293
  }
1296
1294
  // Debug logging for non-object configs
1297
- return process.env.NODE_ENV, baseConfig;
1295
+ return "undefined" == typeof process || process.env, baseConfig;
1298
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 => {
1299
1297
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1300
1298
  }), [ onClick ]), handleMouseMove = useCallback((_e => {}), []);
@@ -1405,7 +1403,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1405
1403
  * <div>Content with debug logging enabled</div>
1406
1404
  * </AtomixGlass>
1407
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}) {
1408
- const glassRef = useRef(null), contentRef = useRef(null), opacityCacheRef = useRef(null), rgbCacheRef = 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({
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({
1409
1407
  glassRef: glassRef,
1410
1408
  contentRef: contentRef,
1411
1409
  cornerRadius: cornerRadius,
@@ -1422,143 +1420,51 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1422
1420
  debugOverLight: debugOverLight,
1423
1421
  enablePerformanceMonitoring: enablePerformanceMonitoring,
1424
1422
  children: children
1425
- }), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight;
1426
- // Read CSS custom properties once on mount and cache them
1427
- useEffect((() => {
1428
- if ("undefined" != typeof window && glassRef.current) try {
1429
- const computedStyle = window.getComputedStyle(glassRef.current);
1430
- // Cache opacity values
1431
- if (!opacityCacheRef.current) {
1432
- const 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) => {
1433
- if (!value) return defaultValue;
1434
- const parsed = parseFloat(value);
1435
- return isNaN(parsed) ? defaultValue : parsed;
1436
- };
1437
- opacityCacheRef.current = {
1438
- opacity50: parseOpacity(opacity50Value, .5),
1439
- opacity40: parseOpacity(opacity40Value, .4),
1440
- opacity80: parseOpacity(opacity80Value, .8),
1441
- opacity0: parseOpacity(opacity0Value, 0)
1442
- };
1443
- }
1444
- // Cache RGB color values from design tokens
1445
- if (!rgbCacheRef.current) {
1446
- // Try to read from design tokens, fallback to defaults
1447
- const whiteRgbValue = computedStyle.getPropertyValue("--atomix-light-rgb").trim() || computedStyle.getPropertyValue("--atomix-white-rgb").trim() || "", blackRgbValue = computedStyle.getPropertyValue("--atomix-dark-rgb").trim() || computedStyle.getPropertyValue("--atomix-black-rgb").trim() || "";
1448
- rgbCacheRef.current = {
1449
- whiteRgb: whiteRgbValue || "255, 255, 255",
1450
- // Fallback to white RGB
1451
- blackRgb: blackRgbValue || "0, 0, 0"
1452
- };
1453
- }
1454
- } catch (error) {
1455
- // Fallback to defaults if reading fails
1456
- opacityCacheRef.current || (opacityCacheRef.current = {
1457
- opacity50: .5,
1458
- opacity40: .4,
1459
- opacity80: .8,
1460
- opacity0: 0
1461
- }), rgbCacheRef.current || (rgbCacheRef.current = {
1462
- whiteRgb: "255, 255, 255",
1463
- blackRgb: "0, 0, 0"
1464
- });
1465
- }
1466
- }), []);
1467
- // Calculate base style with transforms (only dynamic values)
1468
- const baseStyle = useMemo((() => ({
1423
+ }), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
1469
1424
  ...style,
1470
1425
  ...0 !== elasticity && !effectiveDisableEffects && {
1471
1426
  transform: transformStyle
1472
1427
  }
1473
- })), [ style, transformStyle, effectiveDisableEffects, elasticity ]), componentClassName = useMemo((() => [ 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(" ")), [ effectiveReducedMotion, effectiveHighContrast, effectiveDisableEffects, className ]), baseStylePosition = baseStyle.position, baseStyleTop = baseStyle.top, baseStyleLeft = baseStyle.left, positionStyles = useMemo((() => ({
1474
- position: baseStylePosition || "absolute",
1475
- top: baseStyleTop || 0,
1476
- left: baseStyleLeft || 0
1477
- })), [ baseStylePosition, baseStyleTop, baseStyleLeft ]), baseStyleWidth = baseStyle.width, baseStyleHeight = baseStyle.height, glassSizeWidth = glassSize.width, glassSizeHeight = glassSize.height, adjustedSize = useMemo((() => ({
1478
- width: "fixed" !== baseStylePosition ? "100%" : baseStyleWidth || Math.max(glassSizeWidth, 0),
1479
- height: "fixed" !== baseStylePosition ? "100%" : baseStyleHeight || Math.max(glassSizeHeight, 0)
1480
- })), [ baseStylePosition, baseStyleWidth, baseStyleHeight, glassSizeWidth, glassSizeHeight ]), mouseOffsetX = mouseOffset.x, mouseOffsetY = mouseOffset.y, GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, gradientCalculations = useMemo((() => {
1481
- const mx = mouseOffsetX, my = mouseOffsetY, 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;
1482
- return {
1483
- isOverLight: isOverLight,
1484
- mx: mx,
1485
- my: my,
1486
- borderGradientAngle: borderGradientAngle,
1487
- borderStop1: borderStop1,
1488
- borderStop2: borderStop2,
1489
- borderOpacity1: borderOpacity1,
1490
- borderOpacity2: borderOpacity2,
1491
- borderOpacity3: borderOpacity3,
1492
- borderOpacity4: borderOpacity4,
1493
- hover1X: hover1X,
1494
- hover1Y: hover1Y,
1495
- hover2X: hover2X,
1496
- hover2Y: hover2Y,
1497
- hover3X: hover3X,
1498
- hover3Y: hover3Y,
1499
- baseX: baseX,
1500
- baseY: baseY
1501
- };
1502
- }), [ mouseOffsetX, mouseOffsetY, isOverLight ]), overLightOpacity = overLightConfig.opacity, opacityValues = useMemo((() => {
1503
- // Use cached values if available, otherwise fallback to defaults
1504
- const opacity50 = opacityCacheRef.current?.opacity50 ?? .5, opacity40 = opacityCacheRef.current?.opacity40 ?? .4, opacity80 = opacityCacheRef.current?.opacity80 ?? .8, opacity0 = opacityCacheRef.current?.opacity0 ?? 0;
1505
- // Dynamic multiplier for overlay
1506
- return {
1507
- hover1: isHovered || isActive ? opacity50 : opacity0,
1508
- hover2: isActive ? opacity50 : opacity0,
1509
- hover3: isHovered ? opacity40 : isActive ? opacity80 : opacity0,
1510
- base: isOverLight ? overLightOpacity || opacity40 : opacity0,
1511
- over: isOverLight ? 1.1 * (overLightOpacity || opacity40) : opacity0
1512
- };
1513
- }), [ 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((() => {
1514
- // RGB color values for rgba() functions
1515
- // Note: CSS doesn't support rgba(var(--rgb), opacity) syntax - this is a CSS specification
1516
- // limitation, not a browser support issue. We read RGB values from design tokens at mount
1517
- // and cache them for performance. Falls back to defaults if tokens are not available.
1518
- // Uses design tokens: --atomix-light-rgb / --atomix-white-rgb and --atomix-dark-rgb / --atomix-black-rgb
1519
- const whiteColor = rgbCacheRef.current?.whiteRgb || "255, 255, 255", blackColor = rgbCacheRef.current?.blackRgb || "0, 0, 0";
1520
- return {
1521
- // Standard CSS custom properties for dynamic values
1522
- "--atomix-glass-radius": `${effectiveCornerRadius}px`,
1523
- "--atomix-glass-transform": baseStyleTransform || "none",
1524
- "--atomix-glass-position": positionStylesPosition,
1525
- "--atomix-glass-top": "fixed" !== positionStylesTop ? `${positionStylesTop}px` : "0",
1526
- "--atomix-glass-left": "fixed" !== positionStylesLeft ? `${positionStylesLeft}px` : "0",
1527
- "--atomix-glass-width": "fixed" !== baseStylePosition ? adjustedSizeWidth : `${adjustedSizeWidth}px`,
1528
- "--atomix-glass-height": "fixed" !== baseStylePosition ? adjustedSizeHeight : `${adjustedSizeHeight}px`,
1529
- // Border width: Use spacing token for consistency
1530
- "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
1531
- "--atomix-glass-blend-mode": gradientIsOverLight ? "multiply" : "overlay",
1532
- // Dynamic gradients and backgrounds
1533
- // Note: RGB values use design token-aligned constants (white: 255,255,255; black: 0,0,0)
1534
- "--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%)`,
1535
- "--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%)`,
1536
- "--atomix-glass-hover-1-opacity": opacityValuesHover1,
1537
- "--atomix-glass-hover-1-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover1X}% ${gradientHover1Y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${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}%)`,
1538
- "--atomix-glass-hover-2-opacity": opacityValuesHover2,
1539
- "--atomix-glass-hover-2-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover2X}% ${gradientHover2Y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 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}%)`,
1540
- "--atomix-glass-hover-3-opacity": opacityValuesHover3,
1541
- "--atomix-glass-hover-3-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientHover3X}% ${gradientHover3Y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(${blackColor}, 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}%)`,
1542
- "--atomix-glass-base-opacity": opacityValuesBase,
1543
- "--atomix-glass-base-gradient": gradientIsOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + gradientMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${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(${blackColor}, ${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})`,
1544
- "--atomix-glass-overlay-opacity": opacityValuesOver,
1545
- "--atomix-glass-overlay-gradient": gradientIsOverLight ? `radial-gradient(circle at ${gradientBaseX}% ${gradientBaseY}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + Math.abs(gradientMx) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${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})`
1546
- };
1547
- }), [
1548
- // Position styles - only specific properties
1549
- positionStylesPosition, positionStylesTop, positionStylesLeft,
1550
- // Adjusted size - only specific properties
1551
- adjustedSizeWidth, adjustedSizeHeight,
1552
- // Base style - only transform property
1553
- baseStyleTransform, baseStylePosition,
1554
- // Other values
1555
- effectiveCornerRadius, effectiveReducedMotion,
1556
- // Gradient calculations - extracted properties
1557
- gradientIsOverLight, gradientMx, gradientMy, gradientBorderGradientAngle, gradientBorderStop1, gradientBorderStop2, gradientBorderOpacity1, gradientBorderOpacity2, gradientBorderOpacity3, gradientBorderOpacity4, gradientHover1X, gradientHover1Y, gradientHover2X, gradientHover2Y, gradientHover3X, gradientHover3Y, gradientBaseX, gradientBaseY,
1558
- // Opacity values - extracted properties
1559
- opacityValuesHover1, opacityValuesHover2, opacityValuesHover3, opacityValuesBase, opacityValuesOver ]);
1560
- // Build className with state modifiers
1561
- 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", {
1562
1468
  className: componentClassName,
1563
1469
  style: glassVars,
1564
1470
  role: role || (onClick ? "button" : void 0),
@@ -2079,69 +1985,103 @@ const sizeMap = {
2079
1985
  * Icon component that displays a Phosphor icon
2080
1986
  */ Icon.displayName = "Icon";
2081
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
+
2082
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) => {
2083
- const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = useMemo((() => loading ? null : iconName ? jsx(Icon, {
2079
+ const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
2084
2080
  name: iconName,
2085
2081
  size: iconSize
2086
- }) : icon), [ icon, iconName, iconSize, loading ]), {generateButtonClass: generateButtonClass, handleClick: handleClick} =
2087
- /**
2088
- * Button state and functionality
2089
- * @param initialProps - Initial button properties
2090
- * @returns Button state and methods
2091
- */
2092
- function(initialProps) {
2093
- // Default button properties
2094
- const defaultProps = {
2095
- variant: "primary",
2096
- size: "md",
2097
- disabled: !1,
2098
- rounded: !1,
2099
- loading: !1,
2100
- fullWidth: !1,
2101
- block: !1,
2102
- active: !1,
2103
- selected: !1,
2104
- ...initialProps
2105
- };
2106
- /**
2107
- * Generate button class based on properties
2108
- * @param props - Button properties
2109
- * @returns Class string
2110
- */ return {
2111
- defaultProps: defaultProps,
2112
- generateButtonClass: props => {
2113
- 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 : "";
2114
- return [ BUTTON.BASE_CLASS, `c-btn--${variant}`, sizeClass, iconOnlyClass, roundedClass, disabledClass, glassClass, loadingClass, fullWidthClass, blockClass, activeClass, selectedClass, className ].filter(Boolean).join(" ");
2115
- },
2116
- handleClick: handler => event => {
2117
- defaultProps.disabled || defaultProps.loading || !handler || handler(event);
2118
- }
2119
- };
2120
- }({
2121
- variant: variant,
2122
- size: size,
2123
- disabled: isDisabled,
2124
- rounded: rounded,
2125
- glass: glass,
2126
- loading: loading,
2127
- fullWidth: fullWidth,
2128
- block: block,
2129
- active: active,
2130
- selected: selected
2131
- }), buttonClass = useMemo((() => generateButtonClass({
2132
- variant: variant,
2133
- size: size,
2134
- disabled: isDisabled,
2135
- rounded: rounded,
2136
- iconOnly: iconOnly,
2137
- glass: glass,
2138
- loading: loading,
2139
- fullWidth: fullWidth,
2140
- block: block,
2141
- active: active,
2142
- selected: selected,
2143
- className: className
2144
- })), [ 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 => {
2145
2085
  isDisabled ? event.preventDefault() : onClick?.(event);
2146
2086
  }), [ isDisabled, onClick ]), handleMouseEnter = useCallback((event => {
2147
2087
  isDisabled || onHover?.(event);
@@ -2149,28 +2089,23 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
2149
2089
  isDisabled || onFocus?.(event);
2150
2090
  }), [ isDisabled, onFocus ]), handleBlurEvent = useCallback((event => {
2151
2091
  isDisabled || onBlur?.(event);
2152
- }), [ isDisabled, onBlur ]), buttonText = useMemo((() => loading && loadingText ? loadingText : label || children), [ loading, loadingText, label, children ]), spinnerSize = useMemo((() => "sm" === size ? "sm" : "lg" === size ? "md" : "sm"), [ size ]), buttonContent = useMemo((() => {
2153
- const iconSpan = iconElement && jsx("span", {
2154
- className: BUTTON.ICON_CLASS,
2155
- "aria-hidden": "true",
2156
- children: iconElement
2157
- }), spinnerElement = loading && jsx("span", {
2158
- 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"),
2159
2095
  "aria-hidden": "true",
2160
2096
  children: jsx(Spinner, {
2161
2097
  size: spinnerSize,
2162
2098
  variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
2163
2099
  })
2164
- }), labelElement = !iconOnly && buttonText && jsx("span", {
2165
- className: BUTTON.LABEL_CLASS,
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"),
2166
2106
  children: buttonText
2167
- });
2168
- return jsxs(Fragment, "end" === iconPosition ? {
2169
- children: [ labelElement, spinnerElement, iconSpan ]
2170
- } : {
2171
- children: [ spinnerElement, iconSpan, labelElement ]
2172
- });
2173
- }), [ iconElement, iconPosition, iconOnly, buttonText, loading, spinnerSize, variant ]), buttonProps = useMemo((() => ({
2107
+ }) ]
2108
+ }), buttonProps = {
2174
2109
  ref: ref,
2175
2110
  className: buttonClass,
2176
2111
  type: "button" !== Component || shouldRenderAsLink ? void 0 : type,
@@ -2188,8 +2123,16 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
2188
2123
  tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
2189
2124
  style: style,
2190
2125
  ...props
2191
- })), [ ref, buttonClass, Component, type, handleClickEvent, handleMouseEnter, handleFocusEvent, handleBlurEvent, isDisabled, loading, ariaLabel, iconOnly, label, children, ariaDescribedBy, ariaExpanded, ariaControls, tabIndex, style, props ]);
2192
- // Determine if we should render as a link
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
2193
2136
  // Render as anchor if href is provided
2194
2137
  if (shouldRenderAsLink) {
2195
2138
  const {ref: _, ...buttonPropsWithoutRef} = buttonProps, anchorButtonProps = {
@@ -2209,22 +2152,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
2209
2152
  ...linkProps,
2210
2153
  children: buttonContent
2211
2154
  });
2212
- if (glass) {
2213
- const defaultGlassProps = {
2214
- displacementScale: 20,
2215
- blurAmount: 0,
2216
- saturation: 200,
2217
- elasticity: 0
2218
- }, glassProps = !0 === glass ? defaultGlassProps : {
2219
- ...defaultGlassProps,
2220
- ...glass
2221
- };
2222
- return jsx(AtomixGlass, {
2223
- ...glassProps,
2224
- children: linkElement
2225
- });
2226
- }
2227
- return linkElement;
2155
+ return glass ? jsx(AtomixGlass, {
2156
+ ...glassProps,
2157
+ children: linkElement
2158
+ }) : linkElement;
2228
2159
  }
2229
2160
  // Fallback to regular anchor tag
2230
2161
  const anchorElement = jsx("a", {
@@ -2235,46 +2166,20 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
2235
2166
  rel: "_blank" === target ? "noopener noreferrer" : void 0,
2236
2167
  children: buttonContent
2237
2168
  });
2238
- if (glass) {
2239
- const defaultGlassProps = {
2240
- displacementScale: 20,
2241
- blurAmount: 0,
2242
- saturation: 200,
2243
- elasticity: 0
2244
- }, glassProps = !0 === glass ? defaultGlassProps : {
2245
- ...defaultGlassProps,
2246
- ...glass
2247
- };
2248
- return jsx(AtomixGlass, {
2249
- ...glassProps,
2250
- children: anchorElement
2251
- });
2252
- }
2253
- return anchorElement;
2254
- }
2255
- // Default button rendering
2256
- if (glass) {
2257
- const defaultGlassProps = {
2258
- displacementScale: 20,
2259
- blurAmount: 0,
2260
- saturation: 200,
2261
- elasticity: 0
2262
- }, glassProps = !0 === glass ? defaultGlassProps : {
2263
- ...defaultGlassProps,
2264
- ...glass
2265
- };
2266
- return jsx(AtomixGlass, {
2169
+ return glass ? jsx(AtomixGlass, {
2267
2170
  ...glassProps,
2268
- children: jsx(Component, {
2269
- ...buttonProps,
2270
- children: buttonContent
2271
- })
2272
- });
2171
+ children: anchorElement
2172
+ }) : anchorElement;
2273
2173
  }
2274
- return jsx(Component, {
2174
+ // Default button rendering
2175
+ const buttonElement = jsx(Component, {
2275
2176
  ...buttonProps,
2276
2177
  children: buttonContent
2277
2178
  });
2179
+ return glass ? jsx(AtomixGlass, {
2180
+ ...glassProps,
2181
+ children: buttonElement
2182
+ }) : buttonElement;
2278
2183
  })));
2279
2184
 
2280
2185
  Button.displayName = "Button";