@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.
- package/README.md +3 -3
- package/dist/charts.js +50 -142
- package/dist/charts.js.map +1 -1
- package/dist/core.js +179 -274
- package/dist/core.js.map +1 -1
- package/dist/forms.js +50 -142
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +179 -274
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +669 -703
- package/dist/index.esm.js +966 -1649
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1211 -1890
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +163 -334
- package/dist/theme.js +774 -1473
- package/dist/theme.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +128 -356
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +1 -1
- package/src/components/Button/Button.tsx +85 -167
- package/src/lib/composables/useAtomixGlass.ts +7 -7
- package/src/lib/config/loader.ts +2 -3
- package/src/lib/constants/components.ts +7 -0
- package/src/lib/hooks/usePerformanceMonitor.ts +1 -1
- package/src/lib/hooks/useThemeTokens.ts +105 -0
- package/src/lib/theme/config/configLoader.ts +60 -219
- package/src/lib/theme/config/loader.ts +15 -21
- package/src/lib/theme/constants/constants.ts +1 -1
- package/src/lib/theme/core/ThemeRegistry.ts +75 -279
- package/src/lib/theme/core/composeTheme.ts +14 -64
- package/src/lib/theme/core/createTheme.ts +54 -40
- package/src/lib/theme/core/createThemeObject.ts +2 -2
- package/src/lib/theme/core/index.ts +15 -1
- package/src/lib/theme/errors/errors.ts +1 -1
- package/src/lib/theme/generators/generateCSSNested.ts +130 -0
- package/src/lib/theme/generators/index.ts +6 -0
- package/src/lib/theme/index.ts +35 -10
- package/src/lib/theme/runtime/ThemeApplicator.ts +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +4 -4
- package/src/lib/theme/runtime/ThemeProvider.tsx +261 -554
- package/src/lib/theme/runtime/index.ts +1 -0
- package/src/lib/theme/runtime/useThemeTokens.ts +131 -0
- package/src/lib/theme/utils/componentTheming.ts +132 -0
- package/src/lib/theme/utils/naming.ts +100 -0
- package/src/lib/theme/utils/themeUtils.ts +6 -6
- package/src/lib/utils/componentUtils.ts +1 -1
- package/src/lib/utils/memoryMonitor.ts +3 -3
- 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"
|
|
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
|
|
979
|
+
null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : "undefined" == typeof process || process.env;
|
|
982
980
|
} catch (error) {
|
|
983
|
-
"production"
|
|
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
|
|
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"
|
|
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"
|
|
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
|
|
1292
|
+
return "undefined" == typeof process || process.env, finalConfig;
|
|
1295
1293
|
}
|
|
1296
1294
|
// Debug logging for non-object configs
|
|
1297
|
-
return process.env
|
|
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),
|
|
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
|
-
}
|
|
1474
|
-
position:
|
|
1475
|
-
top:
|
|
1476
|
-
left:
|
|
1477
|
-
}
|
|
1478
|
-
width: "fixed" !==
|
|
1479
|
-
height: "fixed" !==
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
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 =
|
|
2079
|
+
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
|
|
2084
2080
|
name: iconName,
|
|
2085
2081
|
size: iconSize
|
|
2086
|
-
}) : icon
|
|
2087
|
-
|
|
2088
|
-
|
|
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 =
|
|
2153
|
-
|
|
2154
|
-
className:
|
|
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
|
-
}),
|
|
2165
|
-
className:
|
|
2100
|
+
}), iconElement && !loading && jsx("span", {
|
|
2101
|
+
className: ThemeNaming.bemClass("btn", "icon"),
|
|
2102
|
+
"aria-hidden": "true",
|
|
2103
|
+
children: iconElement
|
|
2104
|
+
}), !iconOnly && buttonText && jsx("span", {
|
|
2105
|
+
className: ThemeNaming.bemClass("btn", "label"),
|
|
2166
2106
|
children: buttonText
|
|
2167
|
-
})
|
|
2168
|
-
|
|
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
|
-
}
|
|
2192
|
-
|
|
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
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
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
|
-
|
|
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:
|
|
2269
|
-
|
|
2270
|
-
children: buttonContent
|
|
2271
|
-
})
|
|
2272
|
-
});
|
|
2171
|
+
children: anchorElement
|
|
2172
|
+
}) : anchorElement;
|
|
2273
2173
|
}
|
|
2274
|
-
|
|
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";
|