@shohojdhara/atomix 0.3.6 → 0.3.8

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 (74) hide show
  1. package/README.md +3 -3
  2. package/dist/atomix.css +77 -0
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +77 -0
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.js +50 -142
  7. package/dist/charts.js.map +1 -1
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +179 -274
  10. package/dist/core.js.map +1 -1
  11. package/dist/forms.js +50 -142
  12. package/dist/forms.js.map +1 -1
  13. package/dist/heavy.js +179 -274
  14. package/dist/heavy.js.map +1 -1
  15. package/dist/index.d.ts +1255 -1226
  16. package/dist/index.esm.js +2806 -2958
  17. package/dist/index.esm.js.map +1 -1
  18. package/dist/index.js +3113 -3269
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.min.js +1 -1
  21. package/dist/index.min.js.map +1 -1
  22. package/dist/theme.d.ts +313 -667
  23. package/dist/theme.js +1818 -2589
  24. package/dist/theme.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/components/AtomixGlass/AtomixGlass.tsx +128 -356
  27. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +1 -1
  28. package/src/components/Button/Button.tsx +85 -167
  29. package/src/components/DataTable/DataTable.stories.tsx +238 -0
  30. package/src/components/DataTable/DataTable.test.tsx +450 -0
  31. package/src/components/DataTable/DataTable.tsx +384 -61
  32. package/src/components/DatePicker/DatePicker.tsx +29 -38
  33. package/src/components/Upload/Upload.tsx +539 -40
  34. package/src/lib/composables/useAtomixGlass.ts +7 -7
  35. package/src/lib/composables/useDataTable.ts +355 -15
  36. package/src/lib/composables/useDatePicker.ts +19 -0
  37. package/src/lib/config/loader.ts +2 -3
  38. package/src/lib/constants/components.ts +17 -0
  39. package/src/lib/hooks/usePerformanceMonitor.ts +1 -1
  40. package/src/lib/theme/adapters/cssVariableMapper.ts +29 -14
  41. package/src/lib/theme/adapters/index.ts +1 -4
  42. package/src/lib/theme/config/configLoader.ts +82 -223
  43. package/src/lib/theme/config/loader.ts +15 -21
  44. package/src/lib/theme/constants/constants.ts +1 -1
  45. package/src/lib/theme/core/ThemeRegistry.ts +75 -279
  46. package/src/lib/theme/core/composeTheme.ts +30 -88
  47. package/src/lib/theme/core/createTheme.ts +88 -51
  48. package/src/lib/theme/core/createThemeObject.ts +2 -2
  49. package/src/lib/theme/core/index.ts +15 -2
  50. package/src/lib/theme/errors/errors.ts +1 -1
  51. package/src/lib/theme/generators/generateCSSNested.ts +131 -0
  52. package/src/lib/theme/generators/generateCSSVariables.ts +24 -16
  53. package/src/lib/theme/generators/index.ts +6 -0
  54. package/src/lib/theme/index.ts +45 -27
  55. package/src/lib/theme/runtime/ThemeApplicator.ts +6 -109
  56. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +1 -1
  57. package/src/lib/theme/runtime/ThemeProvider.tsx +393 -544
  58. package/src/lib/theme/runtime/index.ts +1 -0
  59. package/src/lib/theme/runtime/useTheme.ts +1 -1
  60. package/src/lib/theme/runtime/useThemeTokens.ts +122 -0
  61. package/src/lib/theme/test/testTheme.ts +2 -1
  62. package/src/lib/theme/types.ts +14 -14
  63. package/src/lib/theme/utils/componentTheming.ts +140 -0
  64. package/src/lib/theme/utils/domUtils.ts +57 -15
  65. package/src/lib/theme/utils/injectCSS.ts +0 -1
  66. package/src/lib/theme/utils/naming.ts +100 -0
  67. package/src/lib/theme/utils/themeHelpers.ts +1 -39
  68. package/src/lib/theme/utils/themeUtils.ts +1 -170
  69. package/src/lib/types/components.ts +145 -0
  70. package/src/lib/utils/componentUtils.ts +1 -1
  71. package/src/lib/utils/dataTableExport.ts +143 -0
  72. package/src/lib/utils/memoryMonitor.ts +3 -3
  73. package/src/lib/utils/themeNaming.ts +135 -0
  74. package/src/styles/06-components/_components.data-table.scss +95 -0
package/dist/heavy.js CHANGED
@@ -460,9 +460,7 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
460
460
  })
461
461
  });
462
462
 
463
- /**
464
- * Badge-specific constants
465
- */ GlassFilterComponent.displayName = "GlassFilter";
463
+ GlassFilterComponent.displayName = "GlassFilter";
466
464
 
467
465
  // Memoize component to prevent unnecessary re-renders
468
466
  const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
@@ -539,7 +537,7 @@ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevP
539
537
  timestamp: Date.now()
540
538
  }),
541
539
  // Development mode: log cache size
542
- "production" !== process.env.NODE_ENV && sharedShaderCache.size;
540
+ "undefined" != typeof process && "production" === process.env?.NODE_ENV || sharedShaderCache.size;
543
541
  })(cacheKey, url), setShaderMapUrl(url);
544
542
  };
545
543
  "undefined" != typeof requestIdleCallback ? requestIdleCallback(generate, {
@@ -852,9 +850,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
852
850
  childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius,
853
851
  extractionSource = "React children");
854
852
  }
855
- null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : process.env.NODE_ENV;
853
+ null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : "undefined" == typeof process || process.env;
856
854
  } catch (error) {
857
- "production" !== process.env.NODE_ENV && debugCornerRadius && console.error("[AtomixGlass] Error extracting corner radius:", error);
855
+ "undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugCornerRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
858
856
  }
859
857
  };
860
858
  extractRadius();
@@ -929,7 +927,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
929
927
  // For image backgrounds, assume medium luminance
930
928
  totalLuminance += .5, validSamples++, hasValidBackground = !0);
931
929
  } catch (styleError) {
932
- process.env.NODE_ENV;
930
+ "undefined" == typeof process || process.env;
933
931
  }
934
932
  // Move to parent element for next iteration
935
933
  if (!currentElement) break;
@@ -968,7 +966,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
968
966
  }
969
967
  } catch (error) {
970
968
  // Enhanced error logging with context
971
- "development" === process.env.NODE_ENV && console.warn("AtomixGlass: Error detecting background brightness:", error);
969
+ "undefined" != typeof process && "development" !== process.env?.NODE_ENV || console.warn("AtomixGlass: Error detecting background brightness:", error);
972
970
  const result = !1;
973
971
  if (element && element.parentElement) {
974
972
  const threshold = "object" == typeof overLight && null !== overLight && overLight.threshold || .7;
@@ -1025,7 +1023,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1025
1023
  };
1026
1024
  // Calculate offset relative to this container
1027
1025
  // React 18 automatically batches these updates
1028
- setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "production" !== process.env.NODE_ENV && enablePerformanceMonitoring && performance.now();
1026
+ setInternalMouseOffset(newOffset), setInternalGlobalMousePosition(globalPos), "undefined" != typeof process && "production" === process.env?.NODE_ENV || !enablePerformanceMonitoring || performance.now();
1029
1027
  }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects, enablePerformanceMonitoring ]);
1030
1028
  // Subscribe to shared mouse tracker
1031
1029
  useEffect((() => {
@@ -1165,10 +1163,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1165
1163
  saturationBoost: validatedSaturationBoost + .4 * mouseInfluence
1166
1164
  };
1167
1165
  // Validate and apply object config values with proper clamping
1168
- return process.env.NODE_ENV, finalConfig;
1166
+ return "undefined" == typeof process || process.env, finalConfig;
1169
1167
  }
1170
1168
  // Debug logging for non-object configs
1171
- return process.env.NODE_ENV, baseConfig;
1169
+ return "undefined" == typeof process || process.env, baseConfig;
1172
1170
  }), [ overLight, getEffectiveOverLight, mouseOffset, isHovered, isActive, validateConfigValue, debugOverLight ]), handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1173
1171
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1174
1172
  }), [ onClick ]), handleMouseMove = useCallback((_e => {}), []);
@@ -1279,7 +1277,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1279
1277
  * <div>Content with debug logging enabled</div>
1280
1278
  * </AtomixGlass>
1281
1279
  */ function AtomixGlass({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, cornerRadius: cornerRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, disableEffects: disableEffects = !1, enableLiquidBlur: enableLiquidBlur = !1, enableBorderEffect: enableBorderEffect = !0, enableOverLightLayers: enableOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, enablePerformanceMonitoring: enablePerformanceMonitoring = !1, debugCornerRadius: debugCornerRadius = !1, debugOverLight: debugOverLight = !1}) {
1282
- 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({
1280
+ const glassRef = useRef(null), contentRef = useRef(null), {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveCornerRadius: effectiveCornerRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveDisableEffects: effectiveDisableEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
1283
1281
  glassRef: glassRef,
1284
1282
  contentRef: contentRef,
1285
1283
  cornerRadius: cornerRadius,
@@ -1296,143 +1294,51 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1296
1294
  debugOverLight: debugOverLight,
1297
1295
  enablePerformanceMonitoring: enablePerformanceMonitoring,
1298
1296
  children: children
1299
- }), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight;
1300
- // Read CSS custom properties once on mount and cache them
1301
- useEffect((() => {
1302
- if ("undefined" != typeof window && glassRef.current) try {
1303
- const computedStyle = window.getComputedStyle(glassRef.current);
1304
- // Cache opacity values
1305
- if (!opacityCacheRef.current) {
1306
- 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) => {
1307
- if (!value) return defaultValue;
1308
- const parsed = parseFloat(value);
1309
- return isNaN(parsed) ? defaultValue : parsed;
1310
- };
1311
- opacityCacheRef.current = {
1312
- opacity50: parseOpacity(opacity50Value, .5),
1313
- opacity40: parseOpacity(opacity40Value, .4),
1314
- opacity80: parseOpacity(opacity80Value, .8),
1315
- opacity0: parseOpacity(opacity0Value, 0)
1316
- };
1317
- }
1318
- // Cache RGB color values from design tokens
1319
- if (!rgbCacheRef.current) {
1320
- // Try to read from design tokens, fallback to defaults
1321
- 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() || "";
1322
- rgbCacheRef.current = {
1323
- whiteRgb: whiteRgbValue || "255, 255, 255",
1324
- // Fallback to white RGB
1325
- blackRgb: blackRgbValue || "0, 0, 0"
1326
- };
1327
- }
1328
- } catch (error) {
1329
- // Fallback to defaults if reading fails
1330
- opacityCacheRef.current || (opacityCacheRef.current = {
1331
- opacity50: .5,
1332
- opacity40: .4,
1333
- opacity80: .8,
1334
- opacity0: 0
1335
- }), rgbCacheRef.current || (rgbCacheRef.current = {
1336
- whiteRgb: "255, 255, 255",
1337
- blackRgb: "0, 0, 0"
1338
- });
1339
- }
1340
- }), []);
1341
- // Calculate base style with transforms (only dynamic values)
1342
- const baseStyle = useMemo((() => ({
1297
+ }), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
1343
1298
  ...style,
1344
1299
  ...0 !== elasticity && !effectiveDisableEffects && {
1345
1300
  transform: transformStyle
1346
1301
  }
1347
- })), [ 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((() => ({
1348
- position: baseStylePosition || "absolute",
1349
- top: baseStyleTop || 0,
1350
- left: baseStyleLeft || 0
1351
- })), [ baseStylePosition, baseStyleTop, baseStyleLeft ]), baseStyleWidth = baseStyle.width, baseStyleHeight = baseStyle.height, glassSizeWidth = glassSize.width, glassSizeHeight = glassSize.height, adjustedSize = useMemo((() => ({
1352
- width: "fixed" !== baseStylePosition ? "100%" : baseStyleWidth || Math.max(glassSizeWidth, 0),
1353
- height: "fixed" !== baseStylePosition ? "100%" : baseStyleHeight || Math.max(glassSizeHeight, 0)
1354
- })), [ baseStylePosition, baseStyleWidth, baseStyleHeight, glassSizeWidth, glassSizeHeight ]), mouseOffsetX = mouseOffset.x, mouseOffsetY = mouseOffset.y, GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, gradientCalculations = useMemo((() => {
1355
- 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;
1356
- return {
1357
- isOverLight: isOverLight,
1358
- mx: mx,
1359
- my: my,
1360
- borderGradientAngle: borderGradientAngle,
1361
- borderStop1: borderStop1,
1362
- borderStop2: borderStop2,
1363
- borderOpacity1: borderOpacity1,
1364
- borderOpacity2: borderOpacity2,
1365
- borderOpacity3: borderOpacity3,
1366
- borderOpacity4: borderOpacity4,
1367
- hover1X: hover1X,
1368
- hover1Y: hover1Y,
1369
- hover2X: hover2X,
1370
- hover2Y: hover2Y,
1371
- hover3X: hover3X,
1372
- hover3Y: hover3Y,
1373
- baseX: baseX,
1374
- baseY: baseY
1375
- };
1376
- }), [ mouseOffsetX, mouseOffsetY, isOverLight ]), overLightOpacity = overLightConfig.opacity, opacityValues = useMemo((() => {
1377
- // Use cached values if available, otherwise fallback to defaults
1378
- const opacity50 = opacityCacheRef.current?.opacity50 ?? .5, opacity40 = opacityCacheRef.current?.opacity40 ?? .4, opacity80 = opacityCacheRef.current?.opacity80 ?? .8, opacity0 = opacityCacheRef.current?.opacity0 ?? 0;
1379
- // Dynamic multiplier for overlay
1380
- return {
1381
- hover1: isHovered || isActive ? opacity50 : opacity0,
1382
- hover2: isActive ? opacity50 : opacity0,
1383
- hover3: isHovered ? opacity40 : isActive ? opacity80 : opacity0,
1384
- base: isOverLight ? overLightOpacity || opacity40 : opacity0,
1385
- over: isOverLight ? 1.1 * (overLightOpacity || opacity40) : opacity0
1386
- };
1387
- }), [ 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((() => {
1388
- // RGB color values for rgba() functions
1389
- // Note: CSS doesn't support rgba(var(--rgb), opacity) syntax - this is a CSS specification
1390
- // limitation, not a browser support issue. We read RGB values from design tokens at mount
1391
- // and cache them for performance. Falls back to defaults if tokens are not available.
1392
- // Uses design tokens: --atomix-light-rgb / --atomix-white-rgb and --atomix-dark-rgb / --atomix-black-rgb
1393
- const whiteColor = rgbCacheRef.current?.whiteRgb || "255, 255, 255", blackColor = rgbCacheRef.current?.blackRgb || "0, 0, 0";
1394
- return {
1395
- // Standard CSS custom properties for dynamic values
1396
- "--atomix-glass-radius": `${effectiveCornerRadius}px`,
1397
- "--atomix-glass-transform": baseStyleTransform || "none",
1398
- "--atomix-glass-position": positionStylesPosition,
1399
- "--atomix-glass-top": "fixed" !== positionStylesTop ? `${positionStylesTop}px` : "0",
1400
- "--atomix-glass-left": "fixed" !== positionStylesLeft ? `${positionStylesLeft}px` : "0",
1401
- "--atomix-glass-width": "fixed" !== baseStylePosition ? adjustedSizeWidth : `${adjustedSizeWidth}px`,
1402
- "--atomix-glass-height": "fixed" !== baseStylePosition ? adjustedSizeHeight : `${adjustedSizeHeight}px`,
1403
- // Border width: Use spacing token for consistency
1404
- "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
1405
- "--atomix-glass-blend-mode": gradientIsOverLight ? "multiply" : "overlay",
1406
- // Dynamic gradients and backgrounds
1407
- // Note: RGB values use design token-aligned constants (white: 255,255,255; black: 0,0,0)
1408
- "--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%)`,
1409
- "--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%)`,
1410
- "--atomix-glass-hover-1-opacity": opacityValuesHover1,
1411
- "--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}%)`,
1412
- "--atomix-glass-hover-2-opacity": opacityValuesHover2,
1413
- "--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}%)`,
1414
- "--atomix-glass-hover-3-opacity": opacityValuesHover3,
1415
- "--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}%)`,
1416
- "--atomix-glass-base-opacity": opacityValuesBase,
1417
- "--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})`,
1418
- "--atomix-glass-overlay-opacity": opacityValuesOver,
1419
- "--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})`
1420
- };
1421
- }), [
1422
- // Position styles - only specific properties
1423
- positionStylesPosition, positionStylesTop, positionStylesLeft,
1424
- // Adjusted size - only specific properties
1425
- adjustedSizeWidth, adjustedSizeHeight,
1426
- // Base style - only transform property
1427
- baseStyleTransform, baseStylePosition,
1428
- // Other values
1429
- effectiveCornerRadius, effectiveReducedMotion,
1430
- // Gradient calculations - extracted properties
1431
- gradientIsOverLight, gradientMx, gradientMy, gradientBorderGradientAngle, gradientBorderStop1, gradientBorderStop2, gradientBorderOpacity1, gradientBorderOpacity2, gradientBorderOpacity3, gradientBorderOpacity4, gradientHover1X, gradientHover1Y, gradientHover2X, gradientHover2Y, gradientHover3X, gradientHover3Y, gradientBaseX, gradientBaseY,
1432
- // Opacity values - extracted properties
1433
- opacityValuesHover1, opacityValuesHover2, opacityValuesHover3, opacityValuesBase, opacityValuesOver ]);
1434
- // Build className with state modifiers
1435
- return jsxs("div", {
1302
+ }, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveDisableEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = {
1303
+ position: style.position || "absolute",
1304
+ top: style.top || 0,
1305
+ left: style.left || 0
1306
+ }, adjustedSize = {
1307
+ width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
1308
+ height: "fixed" !== style.position ? "100%" : style.height ? style.height : Math.max(glassSize.height, 0)
1309
+ }, mx = mouseOffset.x, my = mouseOffset.y, GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), borderOpacity1 = GRADIENT.BORDER_OPACITY.BASE_1 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity2 = GRADIENT.BORDER_OPACITY.BASE_2 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, borderOpacity3 = GRADIENT.BORDER_OPACITY.BASE_3 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, borderOpacity4 = GRADIENT.BORDER_OPACITY.BASE_4 + Math.abs(mx) * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, hover1X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1, hover1Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1, hover2X = GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2, hover2Y = GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2, hover3X = GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3, hover3Y = GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3, baseX = GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER, baseY = GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER, overLightOpacity = overLightConfig.opacity, opacityValues = {
1310
+ hover1: isHovered || isActive ? .5 : 0,
1311
+ hover2: isActive ? .5 : 0,
1312
+ hover3: isHovered ? .4 : isActive ? .8 : 0,
1313
+ base: isOverLight ? overLightOpacity || .4 : 0,
1314
+ over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
1315
+ }, whiteColor = "255, 255, 255", glassVars = {
1316
+ // Standard CSS custom properties for dynamic values
1317
+ "--atomix-glass-radius": `${effectiveCornerRadius}px`,
1318
+ "--atomix-glass-transform": transformStyle || "none",
1319
+ "--atomix-glass-position": positionStyles.position,
1320
+ "--atomix-glass-top": "fixed" !== positionStyles.top ? `${positionStyles.top}px` : "0",
1321
+ "--atomix-glass-left": "fixed" !== positionStyles.left ? `${positionStyles.left}px` : "0",
1322
+ "--atomix-glass-width": "fixed" !== style.position ? adjustedSize.width : `${adjustedSize.width}px`,
1323
+ "--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
1324
+ // Border width: Use spacing token for consistency
1325
+ "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
1326
+ "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
1327
+ // Dynamic gradients and backgrounds
1328
+ "--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacity1}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacity2}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
1329
+ "--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacity3}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacity4}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
1330
+ "--atomix-glass-hover-1-opacity": opacityValues.hover1,
1331
+ "--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hover1X}% ${hover1Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hover1X}% ${hover1Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
1332
+ "--atomix-glass-hover-2-opacity": opacityValues.hover2,
1333
+ "--atomix-glass-hover-2-gradient": isOverLight ? `radial-gradient(circle at ${hover2X}% ${hover2Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hover2X}% ${hover2Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
1334
+ "--atomix-glass-hover-3-opacity": opacityValues.hover3,
1335
+ "--atomix-glass-hover-3-gradient": isOverLight ? `radial-gradient(circle at ${hover3X}% ${hover3Y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${hover3X}% ${hover3Y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
1336
+ "--atomix-glass-base-opacity": opacityValues.base,
1337
+ "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + Math.abs(mx) * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
1338
+ "--atomix-glass-overlay-opacity": opacityValues.over,
1339
+ "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${baseX}% ${baseY}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + Math.abs(mx) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + Math.abs(my) * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
1340
+ };
1341
+ return jsxs("div", {
1436
1342
  className: componentClassName,
1437
1343
  style: glassVars,
1438
1344
  role: role || (onClick ? "button" : void 0),
@@ -3235,69 +3141,103 @@ const sizeMap = {
3235
3141
  * Icon component that displays a Phosphor icon
3236
3142
  */ Icon.displayName = "Icon";
3237
3143
 
3144
+ /**
3145
+ * Theme Naming Utility
3146
+ *
3147
+ * Provides consistent naming conventions for CSS classes, CSS variables,
3148
+ * and JavaScript properties throughout the theme system.
3149
+ */
3150
+ class ThemeNaming {
3151
+ /**
3152
+ * Set the global prefix for all theme tokens
3153
+ * @param newPrefix - New prefix to use
3154
+ */
3155
+ static setPrefix(newPrefix) {
3156
+ this.prefix = newPrefix;
3157
+ }
3158
+ /**
3159
+ * Get the current prefix
3160
+ */ static getPrefix() {
3161
+ return this.prefix;
3162
+ }
3163
+ /**
3164
+ * Convert camelCase to kebab-case for CSS variables
3165
+ * @param str - String to convert
3166
+ */ static camelToKebab(str) {
3167
+ return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
3168
+ }
3169
+ /**
3170
+ * Convert kebab-case to camelCase for JavaScript properties
3171
+ * @param str - String to convert
3172
+ */ static kebabToCamel(str) {
3173
+ return str.replace(/-([a-z])/g, (g => g[1].toUpperCase()));
3174
+ }
3175
+ /**
3176
+ * Create a CSS variable name
3177
+ * @param token - Token name in camelCase
3178
+ */ static cssVar(token) {
3179
+ return `--${this.prefix}-${this.camelToKebab(token)}`;
3180
+ }
3181
+ /**
3182
+ * Create a BEM CSS class name
3183
+ * @param block - Block name
3184
+ * @param element - Element name (optional)
3185
+ * @param modifier - Modifier name (optional)
3186
+ */ static bemClass(block, element, modifier) {
3187
+ let className = `c-${block}`;
3188
+ return element && (className += `__${element}`), modifier && (className += `--${modifier}`),
3189
+ className;
3190
+ }
3191
+ /**
3192
+ * Create a variant class name
3193
+ * @param component - Component name
3194
+ * @param variant - Variant name
3195
+ */ static variantClass(component, variant) {
3196
+ return `c-${component}--${variant}`;
3197
+ }
3198
+ /**
3199
+ * Create a size class name
3200
+ * @param component - Component name
3201
+ * @param size - Size name
3202
+ */ static sizeClass(component, size) {
3203
+ return `c-${component}--${size}`;
3204
+ }
3205
+ /**
3206
+ * Create a state class name
3207
+ * @param component - Component name
3208
+ * @param state - State name
3209
+ */ static stateClass(component, state) {
3210
+ return `c-${component}--${state}`;
3211
+ }
3212
+ /**
3213
+ * Create a utility class name
3214
+ * @param utility - Utility name
3215
+ */ static utilityClass(utility) {
3216
+ return `u-${utility}`;
3217
+ }
3218
+ /**
3219
+ * Create a layout class name
3220
+ * @param layout - Layout name
3221
+ */ static layoutClass(layout) {
3222
+ return `l-${layout}`;
3223
+ }
3224
+ /**
3225
+ * Create an object class name
3226
+ * @param object - Object name
3227
+ */ static objectClass(object) {
3228
+ return `o-${object}`;
3229
+ }
3230
+ }
3231
+
3232
+ ThemeNaming.prefix = "atomix";
3233
+
3238
3234
  const Button = React.memo( forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, ariaExpanded: ariaExpanded, ariaControls: ariaControls, tabIndex: tabIndex, style: style, LinkComponent: LinkComponent, ...props}, ref) => {
3239
- const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = useMemo((() => loading ? null : iconName ? jsx(Icon, {
3235
+ const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
3240
3236
  name: iconName,
3241
3237
  size: iconSize
3242
- }) : icon), [ icon, iconName, iconSize, loading ]), {generateButtonClass: generateButtonClass, handleClick: handleClick} =
3243
- /**
3244
- * Button state and functionality
3245
- * @param initialProps - Initial button properties
3246
- * @returns Button state and methods
3247
- */
3248
- function(initialProps) {
3249
- // Default button properties
3250
- const defaultProps = {
3251
- variant: "primary",
3252
- size: "md",
3253
- disabled: !1,
3254
- rounded: !1,
3255
- loading: !1,
3256
- fullWidth: !1,
3257
- block: !1,
3258
- active: !1,
3259
- selected: !1,
3260
- ...initialProps
3261
- };
3262
- /**
3263
- * Generate button class based on properties
3264
- * @param props - Button properties
3265
- * @returns Class string
3266
- */ return {
3267
- defaultProps: defaultProps,
3268
- generateButtonClass: props => {
3269
- 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 : "";
3270
- return [ BUTTON.BASE_CLASS, `c-btn--${variant}`, sizeClass, iconOnlyClass, roundedClass, disabledClass, glassClass, loadingClass, fullWidthClass, blockClass, activeClass, selectedClass, className ].filter(Boolean).join(" ");
3271
- },
3272
- handleClick: handler => event => {
3273
- defaultProps.disabled || defaultProps.loading || !handler || handler(event);
3274
- }
3275
- };
3276
- }({
3277
- variant: variant,
3278
- size: size,
3279
- disabled: isDisabled,
3280
- rounded: rounded,
3281
- glass: glass,
3282
- loading: loading,
3283
- fullWidth: fullWidth,
3284
- block: block,
3285
- active: active,
3286
- selected: selected
3287
- }), buttonClass = useMemo((() => generateButtonClass({
3288
- variant: variant,
3289
- size: size,
3290
- disabled: isDisabled,
3291
- rounded: rounded,
3292
- iconOnly: iconOnly,
3293
- glass: glass,
3294
- loading: loading,
3295
- fullWidth: fullWidth,
3296
- block: block,
3297
- active: active,
3298
- selected: selected,
3299
- className: className
3300
- })), [ variant, size, isDisabled, rounded, iconOnly, glass, loading, fullWidth, block, active, selected, className, generateButtonClass ]), handleClickEvent = useCallback((event => {
3238
+ }) : icon;
3239
+ // Determine if we should render as a link
3240
+ const buttonClass = [ BUTTON.BASE_CLASS, ThemeNaming.variantClass("btn", variant), "md" !== size ? ThemeNaming.sizeClass("btn", size) : "", iconOnly ? ThemeNaming.stateClass("btn", "icon") : "", rounded ? ThemeNaming.stateClass("btn", "rounded") : "", isDisabled ? ThemeNaming.stateClass("btn", "disabled") : "", glass ? ThemeNaming.stateClass("btn", "glass") : "", loading ? BUTTON.CLASSES.LOADING : "", fullWidth ? BUTTON.CLASSES.FULL_WIDTH : "", block ? BUTTON.CLASSES.BLOCK : "", active ? BUTTON.CLASSES.ACTIVE : "", selected ? BUTTON.CLASSES.SELECTED : "", className ].filter(Boolean).join(" "), handleClickEvent = useCallback((event => {
3301
3241
  isDisabled ? event.preventDefault() : onClick?.(event);
3302
3242
  }), [ isDisabled, onClick ]), handleMouseEnter = useCallback((event => {
3303
3243
  isDisabled || onHover?.(event);
@@ -3305,28 +3245,23 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3305
3245
  isDisabled || onFocus?.(event);
3306
3246
  }), [ isDisabled, onFocus ]), handleBlurEvent = useCallback((event => {
3307
3247
  isDisabled || onBlur?.(event);
3308
- }), [ 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((() => {
3309
- const iconSpan = iconElement && jsx("span", {
3310
- className: BUTTON.ICON_CLASS,
3311
- "aria-hidden": "true",
3312
- children: iconElement
3313
- }), spinnerElement = loading && jsx("span", {
3314
- className: BUTTON.SPINNER_CLASS,
3248
+ }), [ isDisabled, onBlur ]), buttonText = loading && loadingText ? loadingText : label || children, spinnerSize = "sm" === size ? "sm" : "lg" === size ? "md" : "sm", buttonContent = jsxs(Fragment, {
3249
+ children: [ loading && jsx("span", {
3250
+ className: ThemeNaming.bemClass("btn", "spinner"),
3315
3251
  "aria-hidden": "true",
3316
3252
  children: jsx(Spinner, {
3317
3253
  size: spinnerSize,
3318
3254
  variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
3319
3255
  })
3320
- }), labelElement = !iconOnly && buttonText && jsx("span", {
3321
- className: BUTTON.LABEL_CLASS,
3256
+ }), iconElement && !loading && jsx("span", {
3257
+ className: ThemeNaming.bemClass("btn", "icon"),
3258
+ "aria-hidden": "true",
3259
+ children: iconElement
3260
+ }), !iconOnly && buttonText && jsx("span", {
3261
+ className: ThemeNaming.bemClass("btn", "label"),
3322
3262
  children: buttonText
3323
- });
3324
- return jsxs(Fragment, "end" === iconPosition ? {
3325
- children: [ labelElement, spinnerElement, iconSpan ]
3326
- } : {
3327
- children: [ spinnerElement, iconSpan, labelElement ]
3328
- });
3329
- }), [ iconElement, iconPosition, iconOnly, buttonText, loading, spinnerSize, variant ]), buttonProps = useMemo((() => ({
3263
+ }) ]
3264
+ }), buttonProps = {
3330
3265
  ref: ref,
3331
3266
  className: buttonClass,
3332
3267
  type: "button" !== Component || shouldRenderAsLink ? void 0 : type,
@@ -3344,8 +3279,16 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3344
3279
  tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
3345
3280
  style: style,
3346
3281
  ...props
3347
- })), [ ref, buttonClass, Component, type, handleClickEvent, handleMouseEnter, handleFocusEvent, handleBlurEvent, isDisabled, loading, ariaLabel, iconOnly, label, children, ariaDescribedBy, ariaExpanded, ariaControls, tabIndex, style, props ]);
3348
- // Determine if we should render as a link
3282
+ }, defaultGlassProps = {
3283
+ displacementScale: 20,
3284
+ blurAmount: 0,
3285
+ saturation: 200,
3286
+ elasticity: 0
3287
+ }, glassProps = !0 === glass ? defaultGlassProps : {
3288
+ ...defaultGlassProps,
3289
+ ...glass
3290
+ };
3291
+ // Handle click with loading check
3349
3292
  // Render as anchor if href is provided
3350
3293
  if (shouldRenderAsLink) {
3351
3294
  const {ref: _, ...buttonPropsWithoutRef} = buttonProps, anchorButtonProps = {
@@ -3365,22 +3308,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3365
3308
  ...linkProps,
3366
3309
  children: buttonContent
3367
3310
  });
3368
- if (glass) {
3369
- const defaultGlassProps = {
3370
- displacementScale: 20,
3371
- blurAmount: 0,
3372
- saturation: 200,
3373
- elasticity: 0
3374
- }, glassProps = !0 === glass ? defaultGlassProps : {
3375
- ...defaultGlassProps,
3376
- ...glass
3377
- };
3378
- return jsx(AtomixGlass, {
3379
- ...glassProps,
3380
- children: linkElement
3381
- });
3382
- }
3383
- return linkElement;
3311
+ return glass ? jsx(AtomixGlass, {
3312
+ ...glassProps,
3313
+ children: linkElement
3314
+ }) : linkElement;
3384
3315
  }
3385
3316
  // Fallback to regular anchor tag
3386
3317
  const anchorElement = jsx("a", {
@@ -3391,46 +3322,20 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3391
3322
  rel: "_blank" === target ? "noopener noreferrer" : void 0,
3392
3323
  children: buttonContent
3393
3324
  });
3394
- if (glass) {
3395
- const defaultGlassProps = {
3396
- displacementScale: 20,
3397
- blurAmount: 0,
3398
- saturation: 200,
3399
- elasticity: 0
3400
- }, glassProps = !0 === glass ? defaultGlassProps : {
3401
- ...defaultGlassProps,
3402
- ...glass
3403
- };
3404
- return jsx(AtomixGlass, {
3405
- ...glassProps,
3406
- children: anchorElement
3407
- });
3408
- }
3409
- return anchorElement;
3410
- }
3411
- // Default button rendering
3412
- if (glass) {
3413
- const defaultGlassProps = {
3414
- displacementScale: 20,
3415
- blurAmount: 0,
3416
- saturation: 200,
3417
- elasticity: 0
3418
- }, glassProps = !0 === glass ? defaultGlassProps : {
3419
- ...defaultGlassProps,
3420
- ...glass
3421
- };
3422
- return jsx(AtomixGlass, {
3325
+ return glass ? jsx(AtomixGlass, {
3423
3326
  ...glassProps,
3424
- children: jsx(Component, {
3425
- ...buttonProps,
3426
- children: buttonContent
3427
- })
3428
- });
3327
+ children: anchorElement
3328
+ }) : anchorElement;
3429
3329
  }
3430
- return jsx(Component, {
3330
+ // Default button rendering
3331
+ const buttonElement = jsx(Component, {
3431
3332
  ...buttonProps,
3432
3333
  children: buttonContent
3433
3334
  });
3335
+ return glass ? jsx(AtomixGlass, {
3336
+ ...glassProps,
3337
+ children: buttonElement
3338
+ }) : buttonElement;
3434
3339
  })));
3435
3340
 
3436
3341
  Button.displayName = "Button";