@shohojdhara/atomix 0.6.4 → 0.6.5
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 +117 -38
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/atomix.umd.js +1 -1
- package/dist/atomix.umd.js.map +1 -1
- package/dist/atomix.umd.min.js +1 -1
- package/dist/charts.d.ts +30 -1
- package/dist/charts.js +566 -597
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +30 -1
- package/dist/core.js +600 -624
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +30 -1
- package/dist/forms.js +1122 -1163
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +31 -89
- package/dist/heavy.js +1015 -1045
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +378 -104
- package/dist/index.esm.js +10959 -10837
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +10935 -10812
- 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/Accordion/Accordion.tsx +2 -5
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +14 -16
- package/src/components/AtomixGlass/AtomixGlass.tsx +137 -355
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +32 -249
- package/src/components/AtomixGlass/GlassFilter.tsx +62 -68
- package/src/components/AtomixGlass/README.md +2 -1
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +19 -18
- package/src/components/AtomixGlass/glass-border-styles.test.ts +58 -0
- package/src/components/AtomixGlass/glass-border-styles.ts +136 -0
- package/src/components/AtomixGlass/glass-utils.ts +411 -6
- package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +158 -537
- package/src/components/AtomixGlass/stories/Border.stories.tsx +149 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +229 -89
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +29 -340
- package/src/components/AtomixGlass/stories/argTypes.ts +30 -13
- package/src/components/AtomixGlass/stories/premium-presets.ts +206 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +52 -8
- package/src/components/Badge/Badge.tsx +4 -4
- package/src/components/Button/Button.tsx +2 -6
- package/src/components/Callout/Callout.test.tsx +4 -3
- package/src/components/Callout/Callout.tsx +2 -5
- package/src/components/Dropdown/Dropdown.tsx +3 -7
- package/src/components/Form/Checkbox.tsx +2 -8
- package/src/components/Form/Input.tsx +2 -9
- package/src/components/Form/Radio.tsx +2 -9
- package/src/components/Form/Select.tsx +2 -7
- package/src/components/Form/Textarea.tsx +2 -9
- package/src/components/Messages/Messages.tsx +2 -8
- package/src/components/Modal/Modal.tsx +4 -5
- package/src/components/Navigation/Nav/Nav.tsx +2 -6
- package/src/components/Navigation/Navbar/Navbar.tsx +2 -9
- package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -6
- package/src/components/Pagination/Pagination.tsx +2 -10
- package/src/components/Popover/Popover.tsx +2 -9
- package/src/components/Progress/Progress.tsx +2 -7
- package/src/components/Rating/Rating.tsx +2 -10
- package/src/components/Spinner/Spinner.tsx +2 -7
- package/src/components/Steps/Steps.tsx +2 -10
- package/src/components/Tabs/Tabs.tsx +2 -9
- package/src/components/Toggle/Toggle.tsx +2 -10
- package/src/components/Tooltip/Tooltip.tsx +2 -5
- package/src/lib/composables/useAtomixGlass.ts +41 -10
- package/src/lib/composables/useAtomixGlassStyles.ts +59 -75
- package/src/lib/composables/usePerformanceMonitor.ts +5 -0
- package/src/lib/constants/components.ts +358 -46
- package/src/lib/types/components.ts +33 -1
- package/src/styles/01-settings/_settings.atomix-glass.scss +66 -28
- package/src/styles/02-tools/_tools.glass.scss +45 -3
- package/src/styles/06-components/_components.atomix-glass.scss +114 -77
- package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +0 -390
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { ReactNode, forwardRef, createContext } from 'react';
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
|
-
import { POPOVER } from '../../lib/constants/components';
|
|
3
|
+
import { POPOVER, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
4
4
|
import { usePopover } from '../../lib/composables/usePopover';
|
|
5
5
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
6
6
|
import type { PopoverProps, PopoverTriggerProps } from '../../lib/types/components';
|
|
@@ -81,14 +81,7 @@ export const Popover: React.FC<PopoverProps> = ({
|
|
|
81
81
|
{glass ? (
|
|
82
82
|
// Default glass settings for popovers
|
|
83
83
|
(() => {
|
|
84
|
-
const defaultGlassProps =
|
|
85
|
-
displacementScale: 50,
|
|
86
|
-
blurAmount: 1,
|
|
87
|
-
saturation: 160,
|
|
88
|
-
aberrationIntensity: 0.5,
|
|
89
|
-
borderRadius: 8,
|
|
90
|
-
mode: 'shader' as const,
|
|
91
|
-
};
|
|
84
|
+
const defaultGlassProps = GLASS_DEFAULTS.POPOVER;
|
|
92
85
|
|
|
93
86
|
const glassProps =
|
|
94
87
|
glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef, memo } from 'react';
|
|
2
2
|
import { ProgressProps } from '../../lib/types/components';
|
|
3
3
|
import { useProgress } from '../../lib/composables/useProgress';
|
|
4
|
-
import { PROGRESS } from '../../lib/constants/components';
|
|
4
|
+
import { PROGRESS, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
5
5
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
6
6
|
|
|
7
7
|
export const Progress = memo(
|
|
@@ -43,12 +43,7 @@ export const Progress = memo(
|
|
|
43
43
|
);
|
|
44
44
|
|
|
45
45
|
if (glass) {
|
|
46
|
-
const defaultGlassProps =
|
|
47
|
-
displacementScale: 30,
|
|
48
|
-
blurAmount: 0.5,
|
|
49
|
-
borderRadius: 8,
|
|
50
|
-
mode: 'shader' as const,
|
|
51
|
-
};
|
|
46
|
+
const defaultGlassProps = GLASS_DEFAULTS.PROGRESS;
|
|
52
47
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
53
48
|
return <AtomixGlass {...glassProps}>{progressContent}</AtomixGlass>;
|
|
54
49
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useRef, useEffect, useCallback, forwardRef } from 'react';
|
|
2
|
-
import { THEME_COLORS, SIZES, RATING } from '../../lib/constants/components';
|
|
2
|
+
import { THEME_COLORS, SIZES, RATING, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
3
3
|
import { useRating } from '../../lib/composables/useRating';
|
|
4
4
|
import type { RatingProps } from '../../lib/types/components';
|
|
5
5
|
import useForkRef from '../../lib/utils/useForkRef';
|
|
@@ -275,15 +275,7 @@ export const Rating = forwardRef<HTMLDivElement, RatingProps>(
|
|
|
275
275
|
);
|
|
276
276
|
|
|
277
277
|
if (glass) {
|
|
278
|
-
|
|
279
|
-
const defaultGlassProps = {
|
|
280
|
-
displacementScale: 60,
|
|
281
|
-
blurAmount: 1,
|
|
282
|
-
saturation: 160,
|
|
283
|
-
aberrationIntensity: 0.5,
|
|
284
|
-
borderRadius: 8,
|
|
285
|
-
mode: 'shader' as const,
|
|
286
|
-
};
|
|
278
|
+
const defaultGlassProps = GLASS_DEFAULTS.RATING;
|
|
287
279
|
|
|
288
280
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
289
281
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { memo, forwardRef } from 'react';
|
|
2
2
|
import { SpinnerProps } from '../../lib/types/components';
|
|
3
3
|
import { useSpinner } from '../../lib/composables/useSpinner';
|
|
4
|
-
import { SPINNER } from '../../lib/constants/components';
|
|
4
|
+
import { SPINNER, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
5
5
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
6
6
|
|
|
7
7
|
export const Spinner = memo(
|
|
@@ -51,12 +51,7 @@ export const Spinner = memo(
|
|
|
51
51
|
);
|
|
52
52
|
|
|
53
53
|
if (glass) {
|
|
54
|
-
const defaultGlassProps =
|
|
55
|
-
displacementScale: 20,
|
|
56
|
-
blurAmount: 1,
|
|
57
|
-
borderRadius: 999,
|
|
58
|
-
mode: 'shader' as const,
|
|
59
|
-
};
|
|
54
|
+
const defaultGlassProps = GLASS_DEFAULTS.SPINNER;
|
|
60
55
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
61
56
|
return <AtomixGlass {...glassProps}>{spinnerContent}</AtomixGlass>;
|
|
62
57
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState, ReactNode, forwardRef, Children, cloneElement, isValidElement } from 'react';
|
|
2
|
-
import { STEPS } from '../../lib/constants/components';
|
|
2
|
+
import { STEPS, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
3
3
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
4
4
|
import { AtomixGlassProps } from '../../lib/types/components';
|
|
5
5
|
|
|
@@ -225,15 +225,7 @@ const StepsComp: React.FC<StepsProps> = ({
|
|
|
225
225
|
);
|
|
226
226
|
|
|
227
227
|
if (glass) {
|
|
228
|
-
|
|
229
|
-
const defaultGlassProps = {
|
|
230
|
-
displacementScale: 60,
|
|
231
|
-
blurAmount: 1,
|
|
232
|
-
saturation: 160,
|
|
233
|
-
aberrationIntensity: 0.5,
|
|
234
|
-
borderRadius: 8,
|
|
235
|
-
mode: 'shader' as const,
|
|
236
|
-
};
|
|
228
|
+
const defaultGlassProps = GLASS_DEFAULTS.STEPS;
|
|
237
229
|
|
|
238
230
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
239
231
|
|
|
@@ -7,7 +7,7 @@ import React, {
|
|
|
7
7
|
forwardRef,
|
|
8
8
|
ComponentType,
|
|
9
9
|
} from 'react';
|
|
10
|
-
import { TAB } from '../../lib/constants/components';
|
|
10
|
+
import { TAB, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
11
11
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
12
12
|
import { AtomixGlassProps } from '../../lib/types/components';
|
|
13
13
|
|
|
@@ -354,14 +354,7 @@ const TabsComponentBase = ({
|
|
|
354
354
|
|
|
355
355
|
if (glass) {
|
|
356
356
|
// Default glass settings for tabs
|
|
357
|
-
const defaultGlassProps =
|
|
358
|
-
displacementScale: 60,
|
|
359
|
-
blurAmount: 1,
|
|
360
|
-
saturation: 160,
|
|
361
|
-
aberrationIntensity: 0.5,
|
|
362
|
-
borderRadius: 8,
|
|
363
|
-
mode: 'shader' as const,
|
|
364
|
-
};
|
|
357
|
+
const defaultGlassProps = GLASS_DEFAULTS.TABS;
|
|
365
358
|
|
|
366
359
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
367
360
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
import { TOGGLE } from '../../lib/constants/components';
|
|
2
|
+
import { TOGGLE, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
3
3
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
4
4
|
import { AtomixGlassProps, BaseComponentProps } from '../../lib/types/components';
|
|
5
5
|
|
|
@@ -115,15 +115,7 @@ export const Toggle: React.FC<ToggleProps> = ({
|
|
|
115
115
|
);
|
|
116
116
|
|
|
117
117
|
if (glass) {
|
|
118
|
-
|
|
119
|
-
const defaultGlassProps = {
|
|
120
|
-
displacementScale: 60,
|
|
121
|
-
blurAmount: 1,
|
|
122
|
-
saturation: 160,
|
|
123
|
-
aberrationIntensity: 0.5,
|
|
124
|
-
borderRadius: 8,
|
|
125
|
-
mode: 'shader' as const,
|
|
126
|
-
};
|
|
118
|
+
const defaultGlassProps = GLASS_DEFAULTS.TOGGLE;
|
|
127
119
|
|
|
128
120
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
129
121
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { ReactNode, memo } from 'react';
|
|
2
|
-
import { TOOLTIP } from '../../lib/constants/components';
|
|
2
|
+
import { TOOLTIP, GLASS_DEFAULTS } from '../../lib/constants/components';
|
|
3
3
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
4
4
|
import { AtomixGlassProps } from '../../lib/types/components';
|
|
5
5
|
import {
|
|
@@ -118,10 +118,7 @@ export const Tooltip: React.FC<TooltipProps> = memo(
|
|
|
118
118
|
);
|
|
119
119
|
|
|
120
120
|
if (glass) {
|
|
121
|
-
const defaultGlassProps =
|
|
122
|
-
displacementScale: 100,
|
|
123
|
-
blurAmount: 3,
|
|
124
|
-
};
|
|
121
|
+
const defaultGlassProps = GLASS_DEFAULTS.TOOLTIP;
|
|
125
122
|
|
|
126
123
|
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
127
124
|
|
|
@@ -19,6 +19,10 @@ import {
|
|
|
19
19
|
calculateVelocity,
|
|
20
20
|
smoothstep,
|
|
21
21
|
} from '../../components/AtomixGlass/glass-utils';
|
|
22
|
+
import {
|
|
23
|
+
normalizeBorderConfig,
|
|
24
|
+
type ResolvedGlassBorderConfig,
|
|
25
|
+
} from '../../components/AtomixGlass/glass-border-styles';
|
|
22
26
|
import { updateAtomixGlassStyles } from './useAtomixGlassStyles';
|
|
23
27
|
// Phase 1: Time-Based Animation System
|
|
24
28
|
import {
|
|
@@ -191,6 +195,9 @@ interface UseAtomixGlassReturn {
|
|
|
191
195
|
// Transform calculations
|
|
192
196
|
transformStyle: string;
|
|
193
197
|
|
|
198
|
+
/** Resolved liquid glass rim configuration */
|
|
199
|
+
resolvedBorder: ResolvedGlassBorderConfig;
|
|
200
|
+
|
|
194
201
|
// Phase 1: Animation System - Shader time control
|
|
195
202
|
getShaderTime: () => number;
|
|
196
203
|
applyTimeBasedDistortion: (uv: { x: number; y: number }) => { x: number; y: number };
|
|
@@ -221,6 +228,8 @@ export function useAtomixGlass({
|
|
|
221
228
|
reducedMotion = false,
|
|
222
229
|
highContrast = false,
|
|
223
230
|
withoutEffects = false,
|
|
231
|
+
border,
|
|
232
|
+
withBorder = true,
|
|
224
233
|
elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY,
|
|
225
234
|
onClick,
|
|
226
235
|
debugBorderRadius = false,
|
|
@@ -228,7 +237,7 @@ export function useAtomixGlass({
|
|
|
228
237
|
children,
|
|
229
238
|
blurAmount,
|
|
230
239
|
saturation,
|
|
231
|
-
|
|
240
|
+
|
|
232
241
|
withLiquidBlur,
|
|
233
242
|
isFixedOrSticky = false,
|
|
234
243
|
priority = 1, // Default priority
|
|
@@ -245,6 +254,11 @@ export function useAtomixGlass({
|
|
|
245
254
|
const [isHovered, setIsHovered] = useState(false);
|
|
246
255
|
const [isActive, setIsActive] = useState(false);
|
|
247
256
|
|
|
257
|
+
const resolvedBorder = useMemo(
|
|
258
|
+
() => normalizeBorderConfig(border, withBorder),
|
|
259
|
+
[border, withBorder]
|
|
260
|
+
);
|
|
261
|
+
|
|
248
262
|
// Mouse tracking refs
|
|
249
263
|
const cachedRectRef = useRef<DOMRect | null>(null);
|
|
250
264
|
const internalGlobalMousePositionRef = useRef<MousePosition>({ x: 0, y: 0 });
|
|
@@ -678,11 +692,14 @@ export function useAtomixGlass({
|
|
|
678
692
|
isOverLight,
|
|
679
693
|
threshold: 0.7,
|
|
680
694
|
opacity: baseOpacity,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
695
|
+
// Dark UI (Apple Music): neutral contrast + slight brightness lift
|
|
696
|
+
contrast: isOverLight ? 1.4 : 1.02,
|
|
697
|
+
brightness: isOverLight ? 0.9 : 1.02,
|
|
698
|
+
saturationBoost: isOverLight ? 1.3 : 1.0,
|
|
699
|
+
shadowIntensity: isOverLight ? 0.9 : 1.0,
|
|
700
|
+
borderOpacity: isOverLight
|
|
701
|
+
? ATOMIX_GLASS.BORDER.OVER_LIGHT.opacity
|
|
702
|
+
: ATOMIX_GLASS.BORDER.DARK.opacity,
|
|
686
703
|
};
|
|
687
704
|
|
|
688
705
|
if (typeof overLight === 'object' && overLight !== null) {
|
|
@@ -713,6 +730,12 @@ export function useAtomixGlass({
|
|
|
713
730
|
3.0,
|
|
714
731
|
baseConfig.saturationBoost
|
|
715
732
|
);
|
|
733
|
+
const validatedBorderOpacity = validateConfigValue(
|
|
734
|
+
objConfig.borderOpacity,
|
|
735
|
+
0.1,
|
|
736
|
+
1.0,
|
|
737
|
+
baseConfig.borderOpacity
|
|
738
|
+
);
|
|
716
739
|
|
|
717
740
|
const finalConfig = {
|
|
718
741
|
...baseConfig,
|
|
@@ -721,6 +744,7 @@ export function useAtomixGlass({
|
|
|
721
744
|
contrast: validatedContrast,
|
|
722
745
|
brightness: validatedBrightness,
|
|
723
746
|
saturationBoost: validatedSaturationBoost,
|
|
747
|
+
borderOpacity: validatedBorderOpacity,
|
|
724
748
|
};
|
|
725
749
|
|
|
726
750
|
if (
|
|
@@ -958,8 +982,10 @@ export function useAtomixGlass({
|
|
|
958
982
|
withLiquidBlur,
|
|
959
983
|
blurAmount,
|
|
960
984
|
saturation,
|
|
961
|
-
|
|
985
|
+
|
|
962
986
|
isFixedOrSticky,
|
|
987
|
+
borderAnimated: resolvedBorder.animated,
|
|
988
|
+
borderOpacityMultiplier: resolvedBorder.opacityMultiplier,
|
|
963
989
|
});
|
|
964
990
|
|
|
965
991
|
// ── Stop check ──────────────────────────────────────────────────
|
|
@@ -1000,8 +1026,10 @@ export function useAtomixGlass({
|
|
|
1000
1026
|
withLiquidBlur,
|
|
1001
1027
|
blurAmount,
|
|
1002
1028
|
saturation,
|
|
1003
|
-
|
|
1029
|
+
|
|
1004
1030
|
isFixedOrSticky,
|
|
1031
|
+
resolvedBorder.animated,
|
|
1032
|
+
resolvedBorder.opacityMultiplier,
|
|
1005
1033
|
stopLerpLoop,
|
|
1006
1034
|
]);
|
|
1007
1035
|
|
|
@@ -1140,7 +1168,8 @@ export function useAtomixGlass({
|
|
|
1140
1168
|
withLiquidBlur,
|
|
1141
1169
|
blurAmount,
|
|
1142
1170
|
saturation,
|
|
1143
|
-
|
|
1171
|
+
borderAnimated: resolvedBorder.animated,
|
|
1172
|
+
borderOpacityMultiplier: resolvedBorder.opacityMultiplier,
|
|
1144
1173
|
});
|
|
1145
1174
|
}, [
|
|
1146
1175
|
isHovered,
|
|
@@ -1158,7 +1187,8 @@ export function useAtomixGlass({
|
|
|
1158
1187
|
withLiquidBlur,
|
|
1159
1188
|
blurAmount,
|
|
1160
1189
|
saturation,
|
|
1161
|
-
|
|
1190
|
+
resolvedBorder.animated,
|
|
1191
|
+
resolvedBorder.opacityMultiplier,
|
|
1162
1192
|
onClick,
|
|
1163
1193
|
]);
|
|
1164
1194
|
|
|
@@ -1191,6 +1221,7 @@ export function useAtomixGlass({
|
|
|
1191
1221
|
globalMousePosition, // This is now static (refs or props) unless prop changes
|
|
1192
1222
|
mouseOffset, // This is now static (refs or props) unless prop changes
|
|
1193
1223
|
overLightConfig,
|
|
1224
|
+
resolvedBorder,
|
|
1194
1225
|
transformStyle,
|
|
1195
1226
|
getShaderTime,
|
|
1196
1227
|
applyTimeBasedDistortion,
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { ATOMIX_GLASS } from '../constants/components';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
buildGlassBorderCssVars,
|
|
4
|
+
computeBorderTensionFactor,
|
|
5
|
+
} from '../../components/AtomixGlass/glass-border-styles';
|
|
6
|
+
import {
|
|
4
7
|
calculateMouseInfluence,
|
|
5
8
|
validateGlassSize,
|
|
6
9
|
clampBlur,
|
|
7
10
|
smoothstep,
|
|
8
11
|
softClamp,
|
|
9
12
|
} from '../../components/AtomixGlass/glass-utils';
|
|
10
|
-
import type { GlassSize, MousePosition
|
|
13
|
+
import type { GlassSize, MousePosition } from '../types/components';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* Updates the styles of the AtomixGlass wrapper and container elements imperatively
|
|
@@ -44,8 +47,10 @@ export const updateAtomixGlassStyles = (
|
|
|
44
47
|
withLiquidBlur?: boolean;
|
|
45
48
|
blurAmount?: number;
|
|
46
49
|
saturation?: number;
|
|
47
|
-
|
|
50
|
+
|
|
48
51
|
isFixedOrSticky?: boolean;
|
|
52
|
+
borderAnimated?: boolean;
|
|
53
|
+
borderOpacityMultiplier?: number;
|
|
49
54
|
}
|
|
50
55
|
) => {
|
|
51
56
|
if (!wrapperElement && !containerElement) return;
|
|
@@ -71,8 +76,10 @@ export const updateAtomixGlassStyles = (
|
|
|
71
76
|
withLiquidBlur,
|
|
72
77
|
blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT,
|
|
73
78
|
saturation = ATOMIX_GLASS.DEFAULTS.SATURATION,
|
|
74
|
-
|
|
79
|
+
|
|
75
80
|
isFixedOrSticky = false,
|
|
81
|
+
borderAnimated = true,
|
|
82
|
+
borderOpacityMultiplier = 1,
|
|
76
83
|
} = params;
|
|
77
84
|
|
|
78
85
|
// Calculate mouse influence
|
|
@@ -104,8 +111,7 @@ export const updateAtomixGlassStyles = (
|
|
|
104
111
|
: `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`;
|
|
105
112
|
|
|
106
113
|
// ── Apple Liquid Depth Refinements ───────────────────────────────
|
|
107
|
-
const
|
|
108
|
-
const tensionFactor = smoothstep(stretchMagnitude / 80);
|
|
114
|
+
const tensionFactor = computeBorderTensionFactor(elasticTranslation);
|
|
109
115
|
|
|
110
116
|
// Subtle lighting boost on stretch
|
|
111
117
|
const lightingContrast = Math.min(1.8, overLightConfig.contrast + tensionFactor * 0.2);
|
|
@@ -118,42 +124,6 @@ export const updateAtomixGlassStyles = (
|
|
|
118
124
|
const absMx = Math.abs(mx);
|
|
119
125
|
const absMy = Math.abs(my);
|
|
120
126
|
const GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
|
|
121
|
-
|
|
122
|
-
// ── Velocity-Based Rotation ─────────────────────────────────────
|
|
123
|
-
// Combine mouse offset with velocity for dynamic rotation
|
|
124
|
-
const velocityRotation =
|
|
125
|
-
(mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5);
|
|
126
|
-
const borderGradientAngle =
|
|
127
|
-
GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation;
|
|
128
|
-
|
|
129
|
-
// Chromatic offsets for depth
|
|
130
|
-
const chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5;
|
|
131
|
-
const angleR = borderGradientAngle - chromaticOffset;
|
|
132
|
-
const angleB = borderGradientAngle + chromaticOffset;
|
|
133
|
-
|
|
134
|
-
const borderStop1 = Math.max(
|
|
135
|
-
GRADIENT.BORDER_STOP_1.MIN,
|
|
136
|
-
GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER
|
|
137
|
-
);
|
|
138
|
-
const borderStop2 = Math.min(
|
|
139
|
-
GRADIENT.BORDER_STOP_2.MAX,
|
|
140
|
-
GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
// Modulate border opacity by tension (glow on stretch)
|
|
144
|
-
const tensionGlow = 1 + tensionFactor * 0.5;
|
|
145
|
-
const borderOpacities = [
|
|
146
|
-
(GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) *
|
|
147
|
-
tensionGlow,
|
|
148
|
-
(GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) *
|
|
149
|
-
tensionGlow,
|
|
150
|
-
(GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) *
|
|
151
|
-
tensionGlow,
|
|
152
|
-
(GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) *
|
|
153
|
-
tensionGlow,
|
|
154
|
-
];
|
|
155
|
-
|
|
156
|
-
const configBorderOpacity = overLightConfig.borderOpacity;
|
|
157
127
|
const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE;
|
|
158
128
|
const blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK;
|
|
159
129
|
|
|
@@ -177,12 +147,19 @@ export const updateAtomixGlassStyles = (
|
|
|
177
147
|
y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER,
|
|
178
148
|
};
|
|
179
149
|
|
|
150
|
+
// Opacity is either 0 (hidden) or 1 (visible) — actual visual intensity is
|
|
151
|
+
// encoded in each gradient's rgba alpha. The typed @property CSS vars
|
|
152
|
+
// transition these 0→1 values smoothly via CSS (no JS animation needed).
|
|
180
153
|
const opacityValues = {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
154
|
+
// hover-1: ambient highlight glow — present on hover and during press
|
|
155
|
+
hover1: isHovered || isActive ? 1 : 0,
|
|
156
|
+
// hover-2: press depth shadow — only fires on active (mousedown)
|
|
157
|
+
hover2: isActive ? 1 : 0,
|
|
158
|
+
// hover-3: global soft-light surface shift — half-strength on hover, full on press
|
|
159
|
+
hover3: isActive ? 1 : isHovered ? 0.55 : 0,
|
|
160
|
+
// Dark chrome: faint smoky tint; over-light keeps stronger fill
|
|
161
|
+
base: isOverLight ? overLightConfig.opacity : 0.14,
|
|
162
|
+
over: isOverLight ? overLightConfig.opacity * 1.1 : 0.1,
|
|
186
163
|
};
|
|
187
164
|
|
|
188
165
|
const style = wrapperElement.style;
|
|
@@ -199,51 +176,56 @@ export const updateAtomixGlassStyles = (
|
|
|
199
176
|
style.setProperty('--atomix-glass-brightness', lightingBrightness.toString());
|
|
200
177
|
|
|
201
178
|
// ── Chromatic Rim Lighting ──────────────────────────────────────
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
179
|
+
const borderVars = ATOMIX_GLASS.BORDER.GRADIENT_CSS_VARS;
|
|
180
|
+
if (borderAnimated && !effectiveWithoutEffects) {
|
|
181
|
+
const borderCssVars = buildGlassBorderCssVars({
|
|
182
|
+
mouseOffset,
|
|
183
|
+
mouseVelocity,
|
|
184
|
+
elasticVelocity,
|
|
185
|
+
borderOpacity: overLightConfig.borderOpacity,
|
|
186
|
+
opacityMultiplier: borderOpacityMultiplier,
|
|
187
|
+
tensionFactor,
|
|
188
|
+
});
|
|
189
|
+
style.setProperty(borderVars.GRADIENT_1, borderCssVars[borderVars.GRADIENT_1] ?? '');
|
|
190
|
+
style.setProperty(borderVars.GRADIENT_2, borderCssVars[borderVars.GRADIENT_2] ?? '');
|
|
191
|
+
} else {
|
|
192
|
+
style.removeProperty(borderVars.GRADIENT_1);
|
|
193
|
+
style.removeProperty(borderVars.GRADIENT_2);
|
|
194
|
+
}
|
|
212
195
|
|
|
213
|
-
// Hover gradients
|
|
196
|
+
// Hover gradients — cursor-relative radial positions for realistic light tracking.
|
|
197
|
+
// hover-1: white overlay highlight following cursor (works on both dark + light)
|
|
214
198
|
style.setProperty(
|
|
215
199
|
'--atomix-glass-hover-1-gradient',
|
|
216
|
-
|
|
217
|
-
? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, 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}%)`
|
|
218
|
-
: `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`
|
|
200
|
+
`radial-gradient(65% 55% at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, 0.24) 0%, rgba(${whiteColor}, 0.06) 45%, rgba(${whiteColor}, 0) 72%)`
|
|
219
201
|
);
|
|
220
202
|
|
|
203
|
+
// hover-2: press depth — darkens at cursor with multiply blend, isOverLight uses stronger black
|
|
221
204
|
style.setProperty(
|
|
222
205
|
'--atomix-glass-hover-2-gradient',
|
|
223
206
|
isOverLight
|
|
224
|
-
? `radial-gradient(
|
|
225
|
-
: `radial-gradient(
|
|
207
|
+
? `radial-gradient(60% 50% at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, 0.22) 0%, rgba(${blackColor}, 0.06) 50%, rgba(${blackColor}, 0) 72%)`
|
|
208
|
+
: `radial-gradient(60% 50% at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, 0.18) 0%, rgba(${blackColor}, 0.04) 50%, rgba(${blackColor}, 0) 72%)`
|
|
226
209
|
);
|
|
227
210
|
|
|
211
|
+
// hover-3: full-surface soft-light tint; linear gradient angled with cursor X
|
|
228
212
|
style.setProperty(
|
|
229
213
|
'--atomix-glass-hover-3-gradient',
|
|
230
|
-
isOverLight
|
|
231
|
-
? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, 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}%)`
|
|
232
|
-
: `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`
|
|
214
|
+
`linear-gradient(${150 + mx * 0.3}deg, rgba(${whiteColor}, ${isOverLight ? 0.08 : 0.12}) 0%, rgba(${whiteColor}, 0.04) 55%, rgba(${whiteColor}, 0) 100%)`
|
|
233
215
|
);
|
|
234
216
|
|
|
235
217
|
style.setProperty(
|
|
236
218
|
'--atomix-glass-base-gradient',
|
|
237
219
|
isOverLight
|
|
238
220
|
? `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%)`
|
|
239
|
-
: `rgba(${
|
|
221
|
+
: `linear-gradient(180deg, rgba(${blackColor}, 0.42) 0%, rgba(${blackColor}, 0.22) 55%, rgba(${blackColor}, 0.12) 100%)`
|
|
240
222
|
);
|
|
241
223
|
|
|
242
224
|
style.setProperty(
|
|
243
225
|
'--atomix-glass-overlay-gradient',
|
|
244
226
|
isOverLight
|
|
245
227
|
? `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%)`
|
|
246
|
-
: `rgba(${whiteColor}, ${
|
|
228
|
+
: `radial-gradient(120% 80% at 50% 0%, rgba(${whiteColor}, 0.14) 0%, rgba(${whiteColor}, 0) 55%)`
|
|
247
229
|
);
|
|
248
230
|
|
|
249
231
|
// Opacities
|
|
@@ -339,7 +321,7 @@ export const updateAtomixGlassStyles = (
|
|
|
339
321
|
// Container variables
|
|
340
322
|
const style = containerElement.style;
|
|
341
323
|
|
|
342
|
-
|
|
324
|
+
|
|
343
325
|
style.setProperty('--atomix-glass-container-radius', `${effectiveBorderRadius}px`);
|
|
344
326
|
|
|
345
327
|
style.setProperty('--atomix-glass-container-backdrop', backdropFilterString);
|
|
@@ -349,12 +331,12 @@ export const updateAtomixGlassStyles = (
|
|
|
349
331
|
'--atomix-glass-container-shadow',
|
|
350
332
|
isOverLight
|
|
351
333
|
? [
|
|
352
|
-
`inset 0 1px 0 rgba(255, 255, 255, ${(0.
|
|
353
|
-
`inset 0 -1px 0 rgba(0, 0, 0, ${(0.
|
|
354
|
-
`inset 0 0 20px rgba(0, 0, 0, ${(0.
|
|
355
|
-
`0 2px 12px rgba(0, 0, 0, ${(0.
|
|
334
|
+
`inset 0 1px 0 rgba(255, 255, 255, ${(0.35 + mx * 0.002) * (overLightConfig.shadowIntensity || 1)})`,
|
|
335
|
+
`inset 0 -1px 0 rgba(0, 0, 0, ${(0.15 + Math.abs(my) * 0.001) * (overLightConfig.shadowIntensity || 1)})`,
|
|
336
|
+
`inset 0 0 20px rgba(0, 0, 0, ${(0.06 + Math.abs(mx + my) * 0.001) * (overLightConfig.shadowIntensity || 1)})`,
|
|
337
|
+
`0 2px 12px rgba(0, 0, 0, ${(0.08 + Math.abs(my) * 0.002) * (overLightConfig.shadowIntensity || 1)})`,
|
|
356
338
|
].join(', ')
|
|
357
|
-
:
|
|
339
|
+
: ATOMIX_GLASS.CONSTANTS.CONTAINER_SHADOW.LIGHT
|
|
358
340
|
);
|
|
359
341
|
|
|
360
342
|
style.setProperty(
|
|
@@ -376,7 +358,9 @@ export const updateAtomixGlassStyles = (
|
|
|
376
358
|
|
|
377
359
|
style.setProperty(
|
|
378
360
|
'--atomix-glass-container-box-shadow',
|
|
379
|
-
isOverLight
|
|
361
|
+
isOverLight
|
|
362
|
+
? '0px 16px 70px rgba(0, 0, 0, 0.75)'
|
|
363
|
+
: '0 8px 32px rgba(0, 0, 0, 0.32), 0 2px 8px rgba(0, 0, 0, 0.18)'
|
|
380
364
|
);
|
|
381
365
|
}
|
|
382
366
|
};
|
|
@@ -181,6 +181,11 @@ export function usePerformanceMonitor(
|
|
|
181
181
|
const [manualOverride, setManualOverride] = useState(false);
|
|
182
182
|
const [isEnabled, setIsEnabled] = useState(enabled);
|
|
183
183
|
|
|
184
|
+
// Sync external `enabled` prop changes into internal state
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
setIsEnabled(enabled ?? true);
|
|
187
|
+
}, [enabled]);
|
|
188
|
+
|
|
184
189
|
// Refs for frame tracking
|
|
185
190
|
const frameCountRef = useRef(0);
|
|
186
191
|
const lastFpsUpdateRef = useRef(0);
|