@shohojdhara/atomix 0.4.4 → 0.4.6
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/dist/atomix.css +50 -11
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.js +184 -189
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/core.js +194 -199
- package/dist/core.js.map +1 -1
- package/dist/forms.js +184 -189
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +189 -194
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +44 -47
- package/dist/index.esm.js +496 -613
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +528 -631
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +60 -39
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +8 -42
- package/src/components/AtomixGlass/glass-utils.ts +27 -14
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +19 -21
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1162 -515
- package/src/components/AtomixGlass/stories/shared-components.tsx +11 -3
- package/src/components/Breadcrumb/Breadcrumb.tsx +5 -5
- package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +2 -2
- package/src/components/Button/Button.tsx +6 -6
- package/src/components/Card/Card.tsx +3 -3
- package/src/components/Dropdown/Dropdown.tsx +5 -3
- package/src/components/Footer/Footer.tsx +124 -166
- package/src/components/Footer/FooterLink.tsx +16 -19
- package/src/components/Footer/FooterSection.tsx +40 -39
- package/src/components/Footer/FooterSocialLink.tsx +59 -58
- package/src/components/Footer/README.md +1 -1
- package/src/components/Hero/Hero.tsx +72 -142
- package/src/components/Navigation/Menu/MegaMenu.tsx +17 -12
- package/src/components/Navigation/Menu/Menu.tsx +49 -24
- package/src/components/Navigation/Nav/NavItem.tsx +5 -3
- package/src/components/Navigation/Navbar/Navbar.tsx +13 -5
- package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -2
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -4
- package/src/components/Slider/Slider.tsx +7 -4
- package/src/lib/composables/index.ts +1 -2
- package/src/lib/composables/useAtomixGlass.ts +246 -222
- package/src/lib/composables/useAtomixGlassStyles.ts +46 -23
- package/src/lib/composables/useFooter.ts +117 -20
- package/src/lib/composables/useSlider.ts +3 -1
- package/src/lib/constants/components.ts +3 -1
- package/src/lib/types/components.ts +44 -12
- package/src/styles/06-components/_components.atomix-glass.scss +72 -14
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +0 -222
- package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +0 -329
- package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +0 -82
- package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +0 -153
- package/src/lib/composables/atomix-glass/useGlassOverLight.ts +0 -198
- package/src/lib/composables/atomix-glass/useGlassState.ts +0 -112
- package/src/lib/composables/atomix-glass/useGlassTransforms.ts +0 -160
- package/src/lib/composables/glass-styles.ts +0 -302
- package/src/lib/composables/useGlassContainer.ts +0 -177
package/dist/core.js
CHANGED
|
@@ -567,7 +567,9 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
567
567
|
ENABLE_OVER_LIGHT_LAYERS: !0
|
|
568
568
|
},
|
|
569
569
|
CONSTANTS: {
|
|
570
|
-
ACTIVATION_ZONE:
|
|
570
|
+
ACTIVATION_ZONE: 350,
|
|
571
|
+
LERP_FACTOR: .08,
|
|
572
|
+
SMOOTHSTEP_POWER: 2.5,
|
|
571
573
|
MIN_BLUR: .1,
|
|
572
574
|
MOUSE_INFLUENCE_DIVISOR: 100,
|
|
573
575
|
EDGE_FADE_PIXELS: 2,
|
|
@@ -803,7 +805,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
|
|
|
803
805
|
// Silently handle errors
|
|
804
806
|
}
|
|
805
807
|
return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
|
|
806
|
-
}, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
808
|
+
}, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
|
|
807
809
|
switch (mode) {
|
|
808
810
|
case "standard":
|
|
809
811
|
return displacementMap;
|
|
@@ -979,7 +981,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
979
981
|
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
|
|
980
982
|
width: 0,
|
|
981
983
|
height: 0
|
|
982
|
-
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1,
|
|
984
|
+
}, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, contentRef: contentRef}, ref) => {
|
|
983
985
|
// Generate a stable, deterministic ID for SSR compatibility
|
|
984
986
|
// Use a module-level counter that's consistent across server and client
|
|
985
987
|
const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
|
|
@@ -1164,21 +1166,12 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1164
1166
|
onClick: onClick,
|
|
1165
1167
|
children: jsxs("div", {
|
|
1166
1168
|
className: ATOMIX_GLASS.INNER_CLASS,
|
|
1167
|
-
style: {
|
|
1168
|
-
padding: "var(--atomix-glass-container-padding)",
|
|
1169
|
-
boxShadow: "var(--atomix-glass-container-box-shadow)"
|
|
1170
|
-
},
|
|
1171
1169
|
onMouseEnter: onMouseEnter,
|
|
1172
1170
|
onMouseLeave: onMouseLeave,
|
|
1173
1171
|
onMouseDown: onMouseDown,
|
|
1174
1172
|
onMouseUp: onMouseUp,
|
|
1175
1173
|
children: [ jsxs("div", {
|
|
1176
1174
|
className: ATOMIX_GLASS.FILTER_CLASS,
|
|
1177
|
-
style: {
|
|
1178
|
-
zIndex: 1,
|
|
1179
|
-
position: "absolute",
|
|
1180
|
-
inset: 0
|
|
1181
|
-
},
|
|
1182
1175
|
children: [ jsx(GlassFilter, {
|
|
1183
1176
|
blurAmount: blurAmount,
|
|
1184
1177
|
mode: mode,
|
|
@@ -1193,28 +1186,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
|
|
|
1193
1186
|
},
|
|
1194
1187
|
className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
|
|
1195
1188
|
style: {
|
|
1196
|
-
filter: `url(#${filterId})
|
|
1197
|
-
backdropFilter: "var(--atomix-glass-container-backdrop)",
|
|
1198
|
-
borderRadius: "var(--atomix-glass-container-radius)"
|
|
1189
|
+
filter: `url(#${filterId})`
|
|
1199
1190
|
}
|
|
1200
1191
|
}), jsx("div", {
|
|
1201
|
-
className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
|
|
1202
|
-
style: {
|
|
1203
|
-
boxShadow: "var(--atomix-glass-container-shadow)",
|
|
1204
|
-
opacity: "var(--atomix-glass-container-shadow-opacity)",
|
|
1205
|
-
background: "var(--atomix-glass-container-bg)",
|
|
1206
|
-
borderRadius: "var(--atomix-glass-container-radius)"
|
|
1207
|
-
}
|
|
1192
|
+
className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
|
|
1208
1193
|
}) ]
|
|
1209
1194
|
}), jsx("div", {
|
|
1210
1195
|
ref: contentRef,
|
|
1211
1196
|
className: ATOMIX_GLASS.CONTENT_CLASS,
|
|
1212
|
-
style: {
|
|
1213
|
-
position: "relative",
|
|
1214
|
-
textShadow: "var(--atomix-glass-container-text-shadow)",
|
|
1215
|
-
// Ensure content is always above the filter layer (zIndex 1)
|
|
1216
|
-
zIndex: elasticity > 0 ? 100 : 2
|
|
1217
|
-
},
|
|
1218
1197
|
children: children
|
|
1219
1198
|
}) ]
|
|
1220
1199
|
})
|
|
@@ -1318,31 +1297,39 @@ class {
|
|
|
1318
1297
|
saturationBoost: baseOverLightConfig.saturationBoost
|
|
1319
1298
|
};
|
|
1320
1299
|
// Calculate mouse influence
|
|
1321
|
-
|
|
1322
|
-
let elasticTranslation = {
|
|
1300
|
+
let computedDirectionalScale = directionalScale, elasticTranslation = {
|
|
1323
1301
|
x: 0,
|
|
1324
1302
|
y: 0
|
|
1325
1303
|
};
|
|
1326
|
-
|
|
1304
|
+
// Calculate elastic translation and directional scale
|
|
1305
|
+
if (!effectiveWithoutEffects && wrapperElement) {
|
|
1327
1306
|
const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
|
|
1328
|
-
//
|
|
1329
|
-
let fadeInFactor = 0;
|
|
1307
|
+
// Mouse presence and edge distance logic
|
|
1330
1308
|
if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
|
|
1331
|
-
const edgeDistanceX = Math.max(0, Math.abs(
|
|
1309
|
+
const deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
|
|
1332
1310
|
x: edgeDistanceX,
|
|
1333
1311
|
y: edgeDistanceY
|
|
1334
1312
|
}, {
|
|
1335
1313
|
x: 0,
|
|
1336
1314
|
y: 0
|
|
1337
|
-
})
|
|
1338
|
-
|
|
1315
|
+
}), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
|
|
1316
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
1317
|
+
return clamped * clamped * (3 - 2 * clamped);
|
|
1318
|
+
})(rawT);
|
|
1319
|
+
// Directional scale
|
|
1320
|
+
if (elasticTranslation = {
|
|
1321
|
+
x: deltaX * elasticity * .1 * fadeInFactor,
|
|
1322
|
+
y: deltaY * elasticity * .1 * fadeInFactor
|
|
1323
|
+
}, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
|
|
1324
|
+
const centerDistance = calculateDistance(globalMousePosition, center);
|
|
1325
|
+
if (centerDistance > 0) {
|
|
1326
|
+
const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15, softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), .2), softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), .2);
|
|
1327
|
+
computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1339
1330
|
}
|
|
1340
|
-
elasticTranslation = {
|
|
1341
|
-
x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
|
|
1342
|
-
y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
|
|
1343
|
-
};
|
|
1344
1331
|
}
|
|
1345
|
-
const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" :
|
|
1332
|
+
const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : computedDirectionalScale}`;
|
|
1346
1333
|
// Update Wrapper Styles (glassVars)
|
|
1347
1334
|
if (wrapperElement) {
|
|
1348
1335
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), 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), borderOpacities = [ GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
|
|
@@ -1449,7 +1436,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1449
1436
|
}), internalMouseOffsetRef = useRef({
|
|
1450
1437
|
x: 0,
|
|
1451
1438
|
y: 0
|
|
1452
|
-
}),
|
|
1439
|
+
}), targetMouseOffsetRef = useRef({
|
|
1440
|
+
x: 0,
|
|
1441
|
+
y: 0
|
|
1442
|
+
}), targetGlobalMousePositionRef = useRef({
|
|
1443
|
+
x: 0,
|
|
1444
|
+
y: 0
|
|
1445
|
+
}), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
|
|
1453
1446
|
const [glassSize, setGlassSize] = useState({
|
|
1454
1447
|
width: 270,
|
|
1455
1448
|
height: 69
|
|
@@ -1546,7 +1539,23 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1546
1539
|
const timeoutId = setTimeout(extractRadius, 100);
|
|
1547
1540
|
return () => clearTimeout(timeoutId);
|
|
1548
1541
|
}), [ children, debugBorderRadius, contentRef ]),
|
|
1549
|
-
// Media query
|
|
1542
|
+
// Media query detection for reduced motion and high contrast
|
|
1543
|
+
useEffect((() => {
|
|
1544
|
+
if ("undefined" == typeof window || "function" != typeof window.matchMedia) return;
|
|
1545
|
+
const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
|
|
1546
|
+
setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
|
|
1547
|
+
const handleReducedMotionChange = e => {
|
|
1548
|
+
setUserPrefersReducedMotion(e.matches);
|
|
1549
|
+
}, handleHighContrastChange = e => {
|
|
1550
|
+
setUserPrefersHighContrast(e.matches);
|
|
1551
|
+
};
|
|
1552
|
+
return mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
|
|
1553
|
+
mediaQueryHighContrast.addEventListener("change", handleHighContrastChange), () => {
|
|
1554
|
+
mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
|
|
1555
|
+
mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange);
|
|
1556
|
+
};
|
|
1557
|
+
}), []),
|
|
1558
|
+
// Background detection for overLight auto-detect
|
|
1550
1559
|
useEffect((() => {
|
|
1551
1560
|
if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
|
|
1552
1561
|
const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
|
|
@@ -1646,102 +1655,36 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1646
1655
|
}), 150);
|
|
1647
1656
|
return () => clearTimeout(timeoutId);
|
|
1648
1657
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
|
|
1652
|
-
const handleReducedMotionChange = e => {
|
|
1653
|
-
setUserPrefersReducedMotion(e.matches);
|
|
1654
|
-
}, handleHighContrastChange = e => {
|
|
1655
|
-
setUserPrefersHighContrast(e.matches);
|
|
1656
|
-
};
|
|
1657
|
-
return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
|
|
1658
|
-
mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
|
|
1659
|
-
mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
|
|
1660
|
-
// ignore
|
|
1661
|
-
};
|
|
1662
|
-
} catch (error) {
|
|
1663
|
-
return;
|
|
1664
|
-
}
|
|
1665
|
-
}), [ overLight, glassRef, debugOverLight ]);
|
|
1658
|
+
"boolean" == typeof overLight && setDetectedOverLight(!1);
|
|
1659
|
+
}), [ overLight, glassRef ]);
|
|
1666
1660
|
/**
|
|
1667
1661
|
* Get effective overLight value based on configuration
|
|
1668
1662
|
*/
|
|
1669
|
-
const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []),
|
|
1670
|
-
const isOverLight = getEffectiveOverLight(), baseConfig = {
|
|
1663
|
+
const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
|
|
1664
|
+
const isOverLight = getEffectiveOverLight(), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
|
|
1671
1665
|
isOverLight: isOverLight,
|
|
1672
1666
|
threshold: .7,
|
|
1673
|
-
opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
|
|
1674
|
-
contrast: 1,
|
|
1675
|
-
|
|
1676
|
-
brightness: 1,
|
|
1677
|
-
// Base brightness
|
|
1667
|
+
opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
|
|
1668
|
+
contrast: 1.4,
|
|
1669
|
+
brightness: .9,
|
|
1678
1670
|
saturationBoost: 1.3,
|
|
1671
|
+
// Fixed value — dynamic saturation amplifies perceived displacement
|
|
1679
1672
|
shadowIntensity: .9,
|
|
1680
1673
|
borderOpacity: .7
|
|
1681
1674
|
};
|
|
1682
1675
|
if ("object" == typeof overLight && null !== overLight) {
|
|
1683
|
-
const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost)
|
|
1684
|
-
return {
|
|
1676
|
+
const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), finalConfig = {
|
|
1685
1677
|
...baseConfig,
|
|
1686
1678
|
threshold: validatedThreshold,
|
|
1687
|
-
opacity: validatedOpacity,
|
|
1679
|
+
opacity: validatedOpacity * hoverIntensity * activeIntensity,
|
|
1688
1680
|
contrast: validatedContrast,
|
|
1689
1681
|
brightness: validatedBrightness,
|
|
1690
1682
|
saturationBoost: validatedSaturationBoost
|
|
1691
1683
|
};
|
|
1684
|
+
return "undefined" == typeof process || process.env, finalConfig;
|
|
1692
1685
|
}
|
|
1693
|
-
return baseConfig;
|
|
1694
|
-
}), [ overLight, getEffectiveOverLight, validateConfigValue ]),
|
|
1695
|
-
const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
|
|
1696
|
-
return {
|
|
1697
|
-
isOverLight: baseOverLightConfig.isOverLight,
|
|
1698
|
-
threshold: baseOverLightConfig.threshold,
|
|
1699
|
-
opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
|
|
1700
|
-
contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
|
|
1701
|
-
brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
|
|
1702
|
-
saturationBoost: baseOverLightConfig.saturationBoost,
|
|
1703
|
-
shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
|
|
1704
|
-
borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
|
|
1705
|
-
};
|
|
1706
|
-
}), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = useRef(null), calculateDirectionalScale = useCallback((() => {
|
|
1707
|
-
if (baseOverLightConfig.isOverLight) return "scale(1)";
|
|
1708
|
-
if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
|
|
1709
|
-
const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
|
|
1710
|
-
x: edgeDistanceX,
|
|
1711
|
-
y: edgeDistanceY
|
|
1712
|
-
}, {
|
|
1713
|
-
x: 0,
|
|
1714
|
-
y: 0
|
|
1715
|
-
});
|
|
1716
|
-
if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
|
|
1717
|
-
const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
|
|
1718
|
-
if (0 === centerDistance) return "scale(1)";
|
|
1719
|
-
const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15;
|
|
1720
|
-
return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
|
|
1721
|
-
}), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = useCallback((() => {
|
|
1722
|
-
if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
|
|
1723
|
-
const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
|
|
1724
|
-
x: edgeDistanceX,
|
|
1725
|
-
y: edgeDistanceY
|
|
1726
|
-
}, {
|
|
1727
|
-
x: 0,
|
|
1728
|
-
y: 0
|
|
1729
|
-
});
|
|
1730
|
-
return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
|
|
1731
|
-
}), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = useCallback((() => {
|
|
1732
|
-
if (!glassRef.current) return {
|
|
1733
|
-
x: 0,
|
|
1734
|
-
y: 0
|
|
1735
|
-
};
|
|
1736
|
-
const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
|
|
1737
|
-
return {
|
|
1738
|
-
x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
|
|
1739
|
-
y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
|
|
1740
|
-
};
|
|
1741
|
-
}), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveWithoutEffects ? {
|
|
1742
|
-
x: 0,
|
|
1743
|
-
y: 0
|
|
1744
|
-
} : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveWithoutEffects ]), directionalScale = useMemo((() => effectiveWithoutEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveWithoutEffects ]), transformStyle = useMemo((() => effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`), [ elasticTranslation, isActive, onClick, directionalScale, effectiveWithoutEffects ]), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1686
|
+
return "undefined" == typeof process || process.env, baseConfig;
|
|
1687
|
+
}), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), handleGlobalMousePosition = useCallback((globalPos => {
|
|
1745
1688
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1746
1689
|
if (effectiveWithoutEffects) return;
|
|
1747
1690
|
const container = mouseContainer?.current || glassRef.current;
|
|
@@ -1750,35 +1693,61 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1750
1693
|
let rect = cachedRectRef.current;
|
|
1751
1694
|
if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
|
|
1752
1695
|
cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
|
|
1753
|
-
const center = calculateElementCenter(rect)
|
|
1696
|
+
const center = calculateElementCenter(rect);
|
|
1697
|
+
// Write raw target — the lerp loop will smoothly pursue it
|
|
1698
|
+
targetMouseOffsetRef.current = {
|
|
1754
1699
|
x: (globalPos.x - center.x) / rect.width * 100,
|
|
1755
1700
|
y: (globalPos.y - center.y) / rect.height * 100
|
|
1701
|
+
}, targetGlobalMousePositionRef.current = globalPos;
|
|
1702
|
+
}), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
|
|
1703
|
+
if (lerpActiveRef.current) return;
|
|
1704
|
+
lerpActiveRef.current = !0;
|
|
1705
|
+
const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
|
|
1706
|
+
if (!lerpActiveRef.current) return;
|
|
1707
|
+
const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
|
|
1708
|
+
// If we're close enough, snap and park
|
|
1709
|
+
if (Math.abs(dx) < .05 && Math.abs(dy) < .05) internalMouseOffsetRef.current = {
|
|
1710
|
+
...tgt
|
|
1711
|
+
}, internalGlobalMousePositionRef.current = {
|
|
1712
|
+
...targetGlobalMousePositionRef.current
|
|
1713
|
+
}; else {
|
|
1714
|
+
internalMouseOffsetRef.current = {
|
|
1715
|
+
x: lerp(cur.x, tgt.x, LERP_T),
|
|
1716
|
+
y: lerp(cur.y, tgt.y, LERP_T)
|
|
1717
|
+
};
|
|
1718
|
+
const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
|
|
1719
|
+
internalGlobalMousePositionRef.current = {
|
|
1720
|
+
x: lerp(curG.x, tgtG.x, LERP_T),
|
|
1721
|
+
y: lerp(curG.y, tgtG.y, LERP_T)
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
// Imperative style update with the smoothed values
|
|
1725
|
+
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
1726
|
+
mouseOffset: internalMouseOffsetRef.current,
|
|
1727
|
+
globalMousePosition: internalGlobalMousePositionRef.current,
|
|
1728
|
+
glassSize: glassSize,
|
|
1729
|
+
isHovered: isHovered,
|
|
1730
|
+
isActive: isActive,
|
|
1731
|
+
isOverLight: overLightConfig.isOverLight,
|
|
1732
|
+
baseOverLightConfig: overLightConfig,
|
|
1733
|
+
effectiveBorderRadius: effectiveBorderRadius,
|
|
1734
|
+
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1735
|
+
effectiveReducedMotion: effectiveReducedMotion,
|
|
1736
|
+
elasticity: elasticity,
|
|
1737
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1738
|
+
onClick: onClick,
|
|
1739
|
+
withLiquidBlur: withLiquidBlur,
|
|
1740
|
+
blurAmount: blurAmount,
|
|
1741
|
+
saturation: saturation,
|
|
1742
|
+
padding: padding
|
|
1743
|
+
}), lerpRafRef.current = requestAnimationFrame(tick);
|
|
1756
1744
|
};
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
globalMousePosition: globalPos,
|
|
1764
|
-
glassSize: glassSize,
|
|
1765
|
-
isHovered: isHovered,
|
|
1766
|
-
isActive: isActive,
|
|
1767
|
-
isOverLight: baseOverLightConfig.isOverLight,
|
|
1768
|
-
baseOverLightConfig: baseOverLightConfig,
|
|
1769
|
-
effectiveBorderRadius: effectiveBorderRadius,
|
|
1770
|
-
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1771
|
-
effectiveReducedMotion: effectiveReducedMotion,
|
|
1772
|
-
elasticity: elasticity,
|
|
1773
|
-
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1774
|
-
// Simplified directional scale for fast path
|
|
1775
|
-
onClick: onClick,
|
|
1776
|
-
withLiquidBlur: withLiquidBlur,
|
|
1777
|
-
blurAmount: blurAmount,
|
|
1778
|
-
saturation: saturation,
|
|
1779
|
-
padding: padding
|
|
1780
|
-
});
|
|
1781
|
-
}), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
|
|
1745
|
+
// 0.08 – lower = more viscous
|
|
1746
|
+
lerpRafRef.current = requestAnimationFrame(tick);
|
|
1747
|
+
}), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]), stopLerpLoop = useCallback((() => {
|
|
1748
|
+
lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
|
|
1749
|
+
lerpRafRef.current = null);
|
|
1750
|
+
}), []);
|
|
1782
1751
|
/**
|
|
1783
1752
|
* Validate and clamp a numeric config value
|
|
1784
1753
|
*/
|
|
@@ -1786,7 +1755,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1786
1755
|
useEffect((() => {
|
|
1787
1756
|
if (externalGlobalMousePosition && externalMouseOffset) return;
|
|
1788
1757
|
if (effectiveWithoutEffects) return;
|
|
1789
|
-
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition)
|
|
1758
|
+
const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
|
|
1759
|
+
// Start the lerp loop — it will smoothly chase the target
|
|
1760
|
+
startLerpLoop();
|
|
1761
|
+
const container = mouseContainer?.current || glassRef.current;
|
|
1790
1762
|
let resizeObserver = null;
|
|
1791
1763
|
return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
|
|
1792
1764
|
null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
|
|
@@ -1794,10 +1766,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1794
1766
|
container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
|
|
1795
1767
|
}));
|
|
1796
1768
|
})), resizeObserver.observe(container)), () => {
|
|
1797
|
-
unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
1769
|
+
unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
|
|
1798
1770
|
updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
|
|
1799
1771
|
};
|
|
1800
|
-
}), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
|
|
1772
|
+
}), [ handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
|
|
1801
1773
|
// Also call updateStyles on other state changes (hover, active, etc)
|
|
1802
1774
|
useEffect((() => {
|
|
1803
1775
|
updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
|
|
@@ -1806,22 +1778,22 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1806
1778
|
glassSize: glassSize,
|
|
1807
1779
|
isHovered: isHovered,
|
|
1808
1780
|
isActive: isActive,
|
|
1809
|
-
isOverLight:
|
|
1810
|
-
baseOverLightConfig:
|
|
1781
|
+
isOverLight: overLightConfig.isOverLight,
|
|
1782
|
+
baseOverLightConfig: overLightConfig,
|
|
1811
1783
|
effectiveBorderRadius: effectiveBorderRadius,
|
|
1812
1784
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
1813
1785
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
1814
1786
|
elasticity: elasticity,
|
|
1815
|
-
directionalScale:
|
|
1787
|
+
directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
|
|
1816
1788
|
onClick: onClick,
|
|
1817
1789
|
withLiquidBlur: withLiquidBlur,
|
|
1818
1790
|
blurAmount: blurAmount,
|
|
1819
1791
|
saturation: saturation,
|
|
1820
1792
|
padding: padding
|
|
1821
1793
|
});
|
|
1822
|
-
}), [ isHovered, isActive, glassSize,
|
|
1794
|
+
}), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
|
|
1823
1795
|
// Event handlers
|
|
1824
|
-
const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []),
|
|
1796
|
+
const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
|
|
1825
1797
|
!onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
|
|
1826
1798
|
}), [ onClick ]);
|
|
1827
1799
|
return {
|
|
@@ -1839,14 +1811,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1839
1811
|
mouseOffset: mouseOffset,
|
|
1840
1812
|
// This is now static (refs or props) unless prop changes
|
|
1841
1813
|
overLightConfig: overLightConfig,
|
|
1842
|
-
elasticTranslation: elasticTranslation,
|
|
1843
|
-
directionalScale: directionalScale,
|
|
1844
1814
|
transformStyle: transformStyle,
|
|
1845
1815
|
handleMouseEnter: handleMouseEnter,
|
|
1846
1816
|
handleMouseLeave: handleMouseLeave,
|
|
1847
1817
|
handleMouseDown: handleMouseDown,
|
|
1848
1818
|
handleMouseUp: handleMouseUp,
|
|
1849
|
-
handleMouseMove: handleMouseMove,
|
|
1850
1819
|
handleKeyDown: handleKeyDown
|
|
1851
1820
|
};
|
|
1852
1821
|
}
|
|
@@ -1944,25 +1913,56 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
1944
1913
|
withLiquidBlur: withLiquidBlur,
|
|
1945
1914
|
padding: padding,
|
|
1946
1915
|
style: style
|
|
1947
|
-
}), isOverLight = useMemo((() => overLightConfig
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1916
|
+
}), isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, rootLayoutStyle = useMemo((() => {
|
|
1917
|
+
if (!isFixedOrSticky) return {};
|
|
1918
|
+
const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
|
|
1919
|
+
return {
|
|
1920
|
+
...p && {
|
|
1921
|
+
position: p
|
|
1922
|
+
},
|
|
1923
|
+
...void 0 !== t && {
|
|
1924
|
+
top: t
|
|
1925
|
+
},
|
|
1926
|
+
...void 0 !== l && {
|
|
1927
|
+
left: l
|
|
1928
|
+
},
|
|
1929
|
+
...void 0 !== r && {
|
|
1930
|
+
right: r
|
|
1931
|
+
},
|
|
1932
|
+
...void 0 !== b && {
|
|
1933
|
+
bottom: b
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
}), [ isFixedOrSticky, restStyle ]), baseStyle = useMemo((() => {
|
|
1937
|
+
if (isFixedOrSticky) {
|
|
1938
|
+
const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
|
|
1939
|
+
return {
|
|
1940
|
+
...visualStyle,
|
|
1941
|
+
...!effectiveWithoutEffects && {
|
|
1942
|
+
transform: transformStyle
|
|
1943
|
+
}
|
|
1944
|
+
};
|
|
1951
1945
|
}
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1946
|
+
return {
|
|
1947
|
+
...restStyle,
|
|
1948
|
+
...!effectiveWithoutEffects && {
|
|
1949
|
+
transform: transformStyle
|
|
1950
|
+
}
|
|
1951
|
+
};
|
|
1952
|
+
}), [ isFixedOrSticky, restStyle, effectiveWithoutEffects, transformStyle ]), componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
|
|
1953
|
+
position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
|
|
1954
|
+
top: isFixedOrSticky ? 0 : restStyle.top || 0,
|
|
1955
|
+
left: isFixedOrSticky ? 0 : restStyle.left || 0
|
|
1956
|
+
})), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left ]), adjustedSize = useMemo((() => {
|
|
1957
1957
|
const resolveSize = (propValue, styleValue, measuredSize) => {
|
|
1958
1958
|
const explicitSize = propValue ?? styleValue;
|
|
1959
1959
|
return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
|
|
1960
1960
|
};
|
|
1961
1961
|
return {
|
|
1962
|
-
width: resolveSize(width,
|
|
1963
|
-
height: resolveSize(height,
|
|
1962
|
+
width: resolveSize(width, restStyle.width, glassSize.width),
|
|
1963
|
+
height: resolveSize(height, restStyle.height, glassSize.height)
|
|
1964
1964
|
};
|
|
1965
|
-
}), [ width, height,
|
|
1965
|
+
}), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
|
|
1966
1966
|
const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
1967
1967
|
return {
|
|
1968
1968
|
borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
|
|
@@ -2004,6 +2004,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2004
2004
|
}), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
|
|
2005
2005
|
const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues, configBorderOpacity = overLightConfig?.borderOpacity ?? 1;
|
|
2006
2006
|
return {
|
|
2007
|
+
...void 0 !== customZIndex && {
|
|
2008
|
+
"--atomix-glass-base-z-index": customZIndex
|
|
2009
|
+
},
|
|
2007
2010
|
"--atomix-glass-radius": `${effectiveBorderRadius}px`,
|
|
2008
2011
|
"--atomix-glass-transform": transformStyle || "none",
|
|
2009
2012
|
"--atomix-glass-position": positionStyles.position,
|
|
@@ -2024,22 +2027,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2024
2027
|
"--atomix-glass-base-opacity": opacityValues.base,
|
|
2025
2028
|
"--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${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(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
|
|
2026
2029
|
"--atomix-glass-overlay-opacity": opacityValues.over,
|
|
2027
|
-
"--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * 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 + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})
|
|
2030
|
+
"--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * 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 + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`,
|
|
2031
|
+
"--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
2032
|
+
"--atomix-glass-overlay-highlight-bg": `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
|
|
2028
2033
|
};
|
|
2029
|
-
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
|
|
2030
|
-
className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" ")
|
|
2031
|
-
style: {
|
|
2032
|
-
...positionStyles,
|
|
2033
|
-
height: adjustedSize.height,
|
|
2034
|
-
width: adjustedSize.width,
|
|
2035
|
-
borderRadius: `${effectiveBorderRadius}px`,
|
|
2036
|
-
transform: baseStyle.transform
|
|
2037
|
-
}
|
|
2034
|
+
}), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity, customZIndex ]), renderBackgroundLayer = layerType => jsx("div", {
|
|
2035
|
+
className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" ")
|
|
2038
2036
|
});
|
|
2039
2037
|
return jsxs("div", {
|
|
2040
2038
|
...rest,
|
|
2041
2039
|
className: componentClassName,
|
|
2042
|
-
style:
|
|
2040
|
+
style: {
|
|
2041
|
+
...glassVars
|
|
2042
|
+
},
|
|
2043
2043
|
role: role || (onClick ? "button" : void 0),
|
|
2044
2044
|
tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
|
|
2045
2045
|
"aria-label": ariaLabel,
|
|
@@ -2051,7 +2051,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2051
2051
|
ref: glassRef,
|
|
2052
2052
|
contentRef: contentRef,
|
|
2053
2053
|
className: className,
|
|
2054
|
-
style:
|
|
2054
|
+
style: rootLayoutStyle,
|
|
2055
2055
|
borderRadius: effectiveBorderRadius,
|
|
2056
2056
|
displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
|
|
2057
2057
|
blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
|
|
@@ -2086,7 +2086,6 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2086
2086
|
effectiveWithoutEffects: effectiveWithoutEffects,
|
|
2087
2087
|
effectiveReducedMotion: effectiveReducedMotion,
|
|
2088
2088
|
shaderVariant: shaderVariant,
|
|
2089
|
-
elasticity: elasticity,
|
|
2090
2089
|
withLiquidBlur: withLiquidBlur,
|
|
2091
2090
|
children: children
|
|
2092
2091
|
}), Boolean(onClick) && jsxs(Fragment, {
|
|
@@ -2103,11 +2102,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
|
|
|
2103
2102
|
}), jsx("div", {
|
|
2104
2103
|
className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
|
|
2105
2104
|
}), jsx("div", {
|
|
2106
|
-
className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
|
|
2107
|
-
style: {
|
|
2108
|
-
opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
|
|
2109
|
-
background: `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
|
|
2110
|
-
}
|
|
2105
|
+
className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
|
|
2111
2106
|
}) ]
|
|
2112
2107
|
}), withBorder && jsxs(Fragment, {
|
|
2113
2108
|
children: [ jsx("span", {
|
|
@@ -2538,7 +2533,7 @@ const BreadcrumbItem = forwardRef((({children: children, href: href, active: ac
|
|
|
2538
2533
|
|
|
2539
2534
|
BreadcrumbItem.displayName = "BreadcrumbItem";
|
|
2540
2535
|
|
|
2541
|
-
const Breadcrumb = memo((function({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb",
|
|
2536
|
+
const Breadcrumb = memo((function({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", linkComponent: linkComponent, style: style, children: children}) {
|
|
2542
2537
|
const breadcrumbClasses = [ BREADCRUMB.CLASSES.BASE, className ].filter(Boolean).join(" ");
|
|
2543
2538
|
let content;
|
|
2544
2539
|
if (items && items.length > 0)
|
|
@@ -2552,7 +2547,7 @@ const Breadcrumb = memo((function({items: items, divider: divider, className: c
|
|
|
2552
2547
|
onClick: item.onClick,
|
|
2553
2548
|
className: item.className,
|
|
2554
2549
|
style: item.style,
|
|
2555
|
-
linkAs:
|
|
2550
|
+
linkAs: linkComponent,
|
|
2556
2551
|
children: item.label
|
|
2557
2552
|
}, index);
|
|
2558
2553
|
})); else {
|
|
@@ -2564,7 +2559,7 @@ const Breadcrumb = memo((function({items: items, divider: divider, className: c
|
|
|
2564
2559
|
|
|
2565
2560
|
return cloneElement(child, {
|
|
2566
2561
|
active: active ?? (!!isLast || void 0),
|
|
2567
|
-
linkAs: linkAs ??
|
|
2562
|
+
linkAs: linkAs ?? linkComponent
|
|
2568
2563
|
});
|
|
2569
2564
|
}
|
|
2570
2565
|
return child;
|
|
@@ -2766,7 +2761,7 @@ class ThemeNaming {
|
|
|
2766
2761
|
|
|
2767
2762
|
ThemeNaming.prefix = "atomix";
|
|
2768
2763
|
|
|
2769
|
-
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, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style,
|
|
2764
|
+
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, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, linkComponent: linkComponent, ...props}, ref) => {
|
|
2770
2765
|
const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
|
|
2771
2766
|
name: iconName,
|
|
2772
2767
|
size: iconSize
|
|
@@ -2817,12 +2812,12 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
|
|
|
2817
2812
|
let content;
|
|
2818
2813
|
// Render as anchor if href is provided
|
|
2819
2814
|
if (shouldRenderAsLink)
|
|
2820
|
-
// Use custom
|
|
2821
|
-
if (
|
|
2822
|
-
const LinkComp =
|
|
2815
|
+
// Use custom linkComponent if provided (e.g., Next.js Link)
|
|
2816
|
+
if (linkComponent) {
|
|
2817
|
+
const LinkComp = linkComponent, linkProps = {
|
|
2823
2818
|
...buttonProps,
|
|
2824
2819
|
ref: ref,
|
|
2825
|
-
//
|
|
2820
|
+
// linkComponent usually forwards ref to anchor
|
|
2826
2821
|
href: href,
|
|
2827
2822
|
to: href,
|
|
2828
2823
|
target: target,
|
|
@@ -2883,7 +2878,7 @@ header: header, image: image, imageAlt: imageAlt = "", title: title, text: text,
|
|
|
2883
2878
|
// Interaction
|
|
2884
2879
|
onClick: onClick, onHover: onHover, onFocus: onFocus, href: href, target: target,
|
|
2885
2880
|
// Custom Link
|
|
2886
|
-
|
|
2881
|
+
linkComponent: linkComponent,
|
|
2887
2882
|
// Glass
|
|
2888
2883
|
glass: glass,
|
|
2889
2884
|
// Accessibility
|
|
@@ -2968,7 +2963,7 @@ className: className = "", style: style, ...rest}, ref) => {
|
|
|
2968
2963
|
// Render as anchor if href is provided
|
|
2969
2964
|
if (href && !isDisabled) {
|
|
2970
2965
|
let anchorElement;
|
|
2971
|
-
return anchorElement =
|
|
2966
|
+
return anchorElement = linkComponent ? jsx(linkComponent, {
|
|
2972
2967
|
...commonProps,
|
|
2973
2968
|
ref: ref,
|
|
2974
2969
|
href: href,
|