@shohojdhara/atomix 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/atomix.css +714 -646
  2. package/dist/atomix.min.css +5 -5
  3. package/dist/index.d.ts +794 -146
  4. package/dist/index.esm.js +12052 -6091
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/index.js +5133 -2674
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.min.js +1 -1
  9. package/dist/index.min.js.map +1 -1
  10. package/dist/themes/boomdevs.css +662 -594
  11. package/dist/themes/boomdevs.min.css +7 -7
  12. package/dist/themes/esrar.css +714 -646
  13. package/dist/themes/esrar.min.css +6 -6
  14. package/dist/themes/mashroom.css +707 -642
  15. package/dist/themes/mashroom.min.css +7 -7
  16. package/dist/themes/shaj-default.css +707 -642
  17. package/dist/themes/shaj-default.min.css +6 -6
  18. package/package.json +66 -15
  19. package/src/components/Accordion/Accordion.stories.tsx +800 -0
  20. package/src/components/Accordion/Accordion.tsx +33 -5
  21. package/src/components/AtomixGlass/AtomixGlass.stories.tsx +1230 -0
  22. package/src/components/AtomixGlass/AtomixGlass.test.tsx +199 -0
  23. package/src/components/AtomixGlass/AtomixGlass.tsx +1343 -0
  24. package/src/components/AtomixGlass/README.md +134 -0
  25. package/src/components/AtomixGlass/index.ts +10 -0
  26. package/src/components/AtomixGlass/shader-utils.ts +696 -0
  27. package/src/components/AtomixGlass/stories/Examples.stories.tsx +5800 -0
  28. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
  29. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1066 -0
  30. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +397 -0
  31. package/src/components/AtomixGlass/stories/shared-components.tsx +310 -0
  32. package/src/components/AtomixGlass/utils.ts +8 -0
  33. package/src/components/Badge/Badge.stories.tsx +170 -0
  34. package/src/components/Badge/Badge.tsx +31 -4
  35. package/src/components/Button/Button.stories.tsx +826 -0
  36. package/src/components/Button/Button.tsx +34 -3
  37. package/src/components/Button/README.md +216 -0
  38. package/src/components/Callout/Callout.stories.tsx +813 -78
  39. package/src/components/Callout/Callout.test.tsx +368 -0
  40. package/src/components/Callout/Callout.tsx +43 -6
  41. package/src/components/Callout/README.md +409 -0
  42. package/src/components/Card/Card.stories.tsx +699 -0
  43. package/src/components/Card/Card.tsx +19 -3
  44. package/src/components/DatePicker/DatePicker copy.tsx +551 -0
  45. package/src/components/DatePicker/DatePicker.stories.tsx +877 -1
  46. package/src/components/DatePicker/DatePicker.tsx +379 -332
  47. package/src/components/DatePicker/readme.md +110 -1
  48. package/src/components/DatePicker/types.ts +8 -0
  49. package/src/components/Dropdown/Dropdown.stories.tsx +145 -0
  50. package/src/components/Dropdown/Dropdown.tsx +34 -5
  51. package/src/components/EdgePanel/EdgePanel.stories.tsx +476 -3
  52. package/src/components/EdgePanel/EdgePanel.tsx +86 -13
  53. package/src/components/Form/Checkbox.stories.tsx +101 -0
  54. package/src/components/Form/Checkbox.tsx +26 -2
  55. package/src/components/Form/Input.stories.tsx +124 -0
  56. package/src/components/Form/Input.tsx +36 -7
  57. package/src/components/Form/Radio.stories.tsx +139 -0
  58. package/src/components/Form/Radio.tsx +26 -2
  59. package/src/components/Form/Select.stories.tsx +110 -0
  60. package/src/components/Form/Select.tsx +26 -2
  61. package/src/components/Form/Textarea.stories.tsx +104 -0
  62. package/src/components/Form/Textarea.tsx +36 -7
  63. package/src/components/Hero/Hero.stories.tsx +54 -1
  64. package/src/components/Hero/Hero.tsx +70 -11
  65. package/src/components/Messages/Messages.stories.tsx +113 -0
  66. package/src/components/Messages/Messages.tsx +51 -9
  67. package/src/components/Modal/Modal.stories.tsx +237 -0
  68. package/src/components/Modal/Modal.tsx +63 -35
  69. package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
  70. package/src/components/Navigation/Nav/Nav.tsx +17 -4
  71. package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
  72. package/src/components/Navigation/Navbar/Navbar.tsx +66 -28
  73. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
  74. package/src/components/Navigation/SideMenu/SideMenu.tsx +28 -2
  75. package/src/components/Pagination/Pagination.stories.tsx +101 -0
  76. package/src/components/Pagination/Pagination.tsx +25 -1
  77. package/src/components/Popover/Popover.stories.tsx +94 -0
  78. package/src/components/Popover/Popover.tsx +30 -4
  79. package/src/components/Progress/Progress.tsx +17 -2
  80. package/src/components/Rating/Rating.stories.tsx +112 -0
  81. package/src/components/Rating/Rating.tsx +25 -1
  82. package/src/components/Spinner/Spinner.tsx +17 -2
  83. package/src/components/Steps/Steps.stories.tsx +119 -0
  84. package/src/components/Steps/Steps.tsx +32 -1
  85. package/src/components/Tab/Tab.stories.tsx +88 -0
  86. package/src/components/Tab/Tab.tsx +32 -1
  87. package/src/components/Toggle/Toggle.stories.tsx +92 -0
  88. package/src/components/Toggle/Toggle.tsx +32 -1
  89. package/src/components/Tooltip/Tooltip.stories.tsx +131 -0
  90. package/src/components/Tooltip/Tooltip.tsx +43 -7
  91. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +1002 -196
  92. package/src/components/VideoPlayer/VideoPlayer.tsx +161 -4
  93. package/src/components/index.ts +1 -0
  94. package/src/lib/composables/index.ts +4 -0
  95. package/src/lib/composables/useAtomixGlass.ts +71 -0
  96. package/src/lib/composables/useBarChart.ts +14 -4
  97. package/src/lib/composables/useButton.ts +3 -1
  98. package/src/lib/composables/useCallout.ts +4 -1
  99. package/src/lib/composables/useChart.ts +223 -370
  100. package/src/lib/composables/useChartToolbar.ts +11 -20
  101. package/src/lib/composables/useEdgePanel.ts +81 -35
  102. package/src/lib/composables/useGlassContainer.ts +168 -0
  103. package/src/lib/composables/useLineChart.ts +4 -2
  104. package/src/lib/composables/usePieChart.ts +4 -14
  105. package/src/lib/constants/components.ts +89 -0
  106. package/src/lib/types/components.ts +448 -14
  107. package/src/lib/utils/displacement-generator.ts +86 -0
  108. package/src/styles/01-settings/_settings.background.scss +8 -7
  109. package/src/styles/01-settings/_settings.callout.scss +7 -7
  110. package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
  111. package/src/styles/02-tools/_tools.animations.scss +19 -0
  112. package/src/styles/02-tools/_tools.background.scss +19 -17
  113. package/src/styles/02-tools/_tools.glass.scss +1 -0
  114. package/src/styles/02-tools/_tools.utility-api.scss +62 -27
  115. package/src/styles/03-generic/_generic.root.scss +3 -2
  116. package/src/styles/04-elements/_elements.body.scss +0 -18
  117. package/src/styles/06-components/_components.accordion.scss +16 -0
  118. package/src/styles/06-components/_components.atomix-glass.scss +72 -0
  119. package/src/styles/06-components/_components.badge.scss +21 -0
  120. package/src/styles/06-components/_components.button.scss +10 -0
  121. package/src/styles/06-components/_components.callout.scss +46 -2
  122. package/src/styles/06-components/_components.card.scss +17 -0
  123. package/src/styles/06-components/_components.chart.scss +1 -1
  124. package/src/styles/06-components/_components.datepicker.scss +18 -0
  125. package/src/styles/06-components/_components.dropdown.scss +7 -1
  126. package/src/styles/06-components/_components.edge-panel.scss +101 -0
  127. package/src/styles/06-components/_components.hero.scss +1 -2
  128. package/src/styles/06-components/_components.input.scss +31 -1
  129. package/src/styles/06-components/_components.messages.scss +176 -0
  130. package/src/styles/06-components/_components.modal.scss +13 -3
  131. package/src/styles/06-components/_components.navbar.scss +12 -1
  132. package/src/styles/06-components/_components.side-menu.scss +5 -0
  133. package/src/styles/06-components/_components.video-player.scss +48 -26
  134. package/src/styles/06-components/_index.scss +1 -0
  135. package/src/styles/99-utilities/_index.scss +1 -0
  136. package/src/styles/99-utilities/_utilities.glass-fixes.scss +49 -0
  137. package/src/styles/99-utilities/_utilities.opacity.scss +1 -1
  138. package/dist/themes/yabai.css +0 -15207
  139. package/dist/themes/yabai.min.css +0 -189
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useState } from 'react';
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { ChartToolbarAction, ChartToolbarGroup } from '../../components/Chart/ChartToolbar';
3
3
  import { ChartType } from '../../components/Chart/types';
4
4
 
@@ -107,10 +107,16 @@ export function useChartToolbar(
107
107
  case 'line':
108
108
  case 'area':
109
109
  case 'bar':
110
+ case 'horizontal-bar':
110
111
  case 'scatter':
112
+ case 'bubble':
113
+ case 'funnel':
114
+ case 'waterfall':
115
+ case 'candlestick':
111
116
  return {
112
117
  ...baseDefaults,
113
118
  zoom: true,
119
+ pan: true,
114
120
  reset: true,
115
121
  };
116
122
 
@@ -132,31 +138,16 @@ export function useChartToolbar(
132
138
  grid: false,
133
139
  };
134
140
 
135
- case 'heatmap':
136
- case 'treemap':
137
- return {
138
- ...baseDefaults,
139
- zoom: true,
140
- pan: true,
141
- grid: false,
142
- };
143
-
144
- case 'candlestick':
145
- return {
146
- ...baseDefaults,
147
- zoom: true,
148
- pan: true,
149
- reset: true,
150
- grid: true,
151
- };
152
141
 
153
142
  default:
154
143
  return baseDefaults;
155
144
  }
156
145
  }, [chartType]);
157
146
 
158
- // Merge configurations
159
- const finalDefaults = { ...getChartDefaults(), ...defaults };
147
+ // Merge configurations with memoization
148
+ const finalDefaults = useMemo(() => {
149
+ return { ...getChartDefaults(), ...defaults };
150
+ }, [getChartDefaults, defaults]);
160
151
 
161
152
  const enhancedHandlers = {
162
153
  onRefresh: useCallback(() => {
@@ -16,6 +16,7 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
16
16
  backdrop: true,
17
17
  closeOnBackdropClick: true,
18
18
  closeOnEscape: true,
19
+ glass: undefined,
19
20
  ...initialProps,
20
21
  };
21
22
 
@@ -97,7 +98,7 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
97
98
  /**
98
99
  * Open the panel
99
100
  */
100
- const openPanel = useCallback(() => {
101
+ const openPanel = useCallback((useFadeAnimation = false) => {
101
102
  setIsOpen(true);
102
103
  document.body.classList.add('is-edgepanel-open');
103
104
 
@@ -106,23 +107,44 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
106
107
 
107
108
  // Only add animation if not in 'none' mode
108
109
  if (mode !== 'none') {
109
- // Add animation class first
110
- containerRef.current.classList.add('is-animating');
111
-
112
- // Force a reflow before starting the animation
113
- void containerRef.current.offsetHeight;
114
-
115
- // Remove animation class after animation completes
116
- const container = containerRef.current;
117
- setTimeout(() => {
118
- if (container) {
119
- container.classList.remove('is-animating');
120
- }
121
- }, EDGE_PANEL.ANIMATION_DURATION);
110
+ if (useFadeAnimation) {
111
+ // Add fade animation class
112
+ containerRef.current.classList.add('is-fade-animating');
113
+
114
+ // Force a reflow before starting the animation
115
+ void containerRef.current.offsetHeight;
116
+
117
+ // Remove animation class after animation completes
118
+ const container = containerRef.current;
119
+ setTimeout(() => {
120
+ if (container) {
121
+ container.classList.remove('is-fade-animating');
122
+ }
123
+ }, EDGE_PANEL.ANIMATION_DURATION);
124
+ } else {
125
+ // Add transform animation class
126
+ containerRef.current.classList.add('is-animating');
127
+
128
+ // Force a reflow before starting the animation
129
+ void containerRef.current.offsetHeight;
130
+
131
+ // Remove animation class after animation completes
132
+ const container = containerRef.current;
133
+ setTimeout(() => {
134
+ if (container) {
135
+ container.classList.remove('is-animating');
136
+ }
137
+ }, EDGE_PANEL.ANIMATION_DURATION);
138
+ }
122
139
  }
123
140
 
124
- // Then set transform
125
- containerRef.current.style.transform = 'translate(0)';
141
+ // Set transform or opacity based on animation type
142
+ if (useFadeAnimation) {
143
+ containerRef.current.style.opacity = '1';
144
+ containerRef.current.style.transform = ''; // Remove transform for fade
145
+ } else {
146
+ containerRef.current.style.transform = 'translate(0)';
147
+ }
126
148
 
127
149
  // If push mode, adjust body padding
128
150
  if (defaultProps.mode === 'push') {
@@ -138,27 +160,47 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
138
160
  /**
139
161
  * Close the panel
140
162
  */
141
- const closePanel = useCallback(() => {
163
+ const closePanel = useCallback((useFadeAnimation = false) => {
142
164
  if (containerRef.current) {
143
165
  const { position, mode } = defaultProps;
144
166
 
145
167
  // Only add animation if not in 'none' mode
146
168
  if (mode !== 'none') {
147
- // Add animation class first
148
- containerRef.current.classList.add('is-animating-out');
149
-
150
- // Capture container for setTimeout
151
- const container = containerRef.current;
152
-
153
- setTimeout(() => {
154
- if (container) {
155
- container.classList.remove('is-animating-out');
156
- }
157
- }, EDGE_PANEL.ANIMATION_DURATION);
169
+ if (useFadeAnimation) {
170
+ // Add fade out animation class
171
+ containerRef.current.classList.add('is-fade-animating-out');
172
+
173
+ // Capture container for setTimeout
174
+ const container = containerRef.current;
175
+
176
+ setTimeout(() => {
177
+ if (container) {
178
+ container.classList.remove('is-fade-animating-out');
179
+ }
180
+ }, EDGE_PANEL.ANIMATION_DURATION);
181
+ } else {
182
+ // Add transform animation class
183
+ containerRef.current.classList.add('is-animating-out');
184
+
185
+ // Capture container for setTimeout
186
+ const container = containerRef.current;
187
+
188
+ setTimeout(() => {
189
+ if (container) {
190
+ container.classList.remove('is-animating-out');
191
+ }
192
+ }, EDGE_PANEL.ANIMATION_DURATION);
193
+ }
158
194
  }
159
195
 
160
- // Then set transform
161
- containerRef.current.style.transform = position ? EDGE_PANEL.TRANSFORM_VALUES[position] : '';
196
+ // Set transform or opacity based on animation type
197
+ if (useFadeAnimation) {
198
+ containerRef.current.style.opacity = '0';
199
+ containerRef.current.style.transform = ''; // Remove transform for fade
200
+ } else {
201
+ // Then set transform
202
+ containerRef.current.style.transform = position ? EDGE_PANEL.TRANSFORM_VALUES[position] : '';
203
+ }
162
204
 
163
205
  // Reset body padding if push mode
164
206
  if (defaultProps.mode === 'push') {
@@ -232,9 +274,13 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
232
274
 
233
275
  if (!isOpen && (mode === 'slide' || mode === 'push') && position) {
234
276
  containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position];
277
+ // Set initial opacity for fade animations
278
+ if (defaultProps.glass) {
279
+ containerRef.current.style.opacity = '0';
280
+ }
235
281
  }
236
282
  }
237
- }, [defaultProps.mode, defaultProps.position, isOpen]);
283
+ }, [defaultProps.mode, defaultProps.position, defaultProps.glass, isOpen]);
238
284
 
239
285
  /**
240
286
  * Sync with prop changes
@@ -242,12 +288,12 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
242
288
  useEffect(() => {
243
289
  if (defaultProps.isOpen !== undefined && defaultProps.isOpen !== isOpen) {
244
290
  if (defaultProps.isOpen) {
245
- openPanel();
291
+ openPanel(!!defaultProps.glass);
246
292
  } else {
247
- closePanel();
293
+ closePanel(!!defaultProps.glass);
248
294
  }
249
295
  }
250
- }, [defaultProps.isOpen, closePanel, isOpen, openPanel]);
296
+ }, [defaultProps.isOpen, closePanel, isOpen, openPanel, defaultProps.glass]);
251
297
 
252
298
  return {
253
299
  isOpen,
@@ -258,4 +304,4 @@ export function useEdgePanel(initialProps?: Partial<EdgePanelProps>) {
258
304
  closePanel,
259
305
  handleBackdropClick,
260
306
  };
261
- }
307
+ }
@@ -0,0 +1,168 @@
1
+ import { useCallback, useEffect, useId, useRef, useState } from 'react';
2
+ import { GlassContainerProps, MousePosition } from '../types/components';
3
+
4
+ /**
5
+ * Custom hook for managing GlassContainer state and interactions
6
+ */
7
+ export function useGlassContainer(props: GlassContainerProps) {
8
+ const {
9
+ glassSize = { width: 270, height: 69 },
10
+ elasticity = 0.15,
11
+ mouseContainer,
12
+ globalMousePos: externalGlobalMousePos,
13
+ mouseOffset: externalMouseOffset,
14
+ } = props;
15
+
16
+ const filterId = useId();
17
+ const glassRef = useRef<HTMLDivElement>(null);
18
+ const [isHovered, setIsHovered] = useState(false);
19
+ const [isActive, setIsActive] = useState(false);
20
+ const [currentGlassSize, setCurrentGlassSize] = useState(glassSize);
21
+ const [internalGlobalMousePos, setInternalGlobalMousePos] = useState<MousePosition>({ x: 0, y: 0 });
22
+ const [internalMouseOffset, setInternalMouseOffset] = useState<MousePosition>({ x: 0, y: 0 });
23
+
24
+ // Use external mouse position if provided, otherwise use internal
25
+ const globalMousePos = externalGlobalMousePos || internalGlobalMousePos;
26
+ const mouseOffset = externalMouseOffset || internalMouseOffset;
27
+
28
+ // Internal mouse tracking
29
+ const handleMouseMove = useCallback(
30
+ (e: MouseEvent) => {
31
+ const container = mouseContainer?.current || glassRef.current;
32
+ if (!container) return;
33
+
34
+ const rect = container.getBoundingClientRect();
35
+ const centerX = rect.left + rect.width / 2;
36
+ const centerY = rect.top + rect.height / 2;
37
+
38
+ setInternalMouseOffset({
39
+ x: ((e.clientX - centerX) / rect.width) * 100,
40
+ y: ((e.clientY - centerY) / rect.height) * 100,
41
+ });
42
+
43
+ setInternalGlobalMousePos({
44
+ x: e.clientX,
45
+ y: e.clientY,
46
+ });
47
+ },
48
+ [mouseContainer]
49
+ );
50
+
51
+ // Set up mouse tracking if no external mouse position is provided
52
+ useEffect(() => {
53
+ if (externalGlobalMousePos && externalMouseOffset) return;
54
+
55
+ const container = mouseContainer?.current || glassRef.current;
56
+ if (!container) return;
57
+
58
+ container.addEventListener('mousemove', handleMouseMove);
59
+ return () => container.removeEventListener('mousemove', handleMouseMove);
60
+ }, [handleMouseMove, mouseContainer, externalGlobalMousePos, externalMouseOffset]);
61
+
62
+ // Calculate directional scaling based on mouse position
63
+ const calculateDirectionalScale = useCallback(() => {
64
+ if (!globalMousePos.x || !globalMousePos.y || !glassRef.current) {
65
+ return 'scale(1)';
66
+ }
67
+
68
+ const rect = glassRef.current.getBoundingClientRect();
69
+ const pillCenterX = rect.left + rect.width / 2;
70
+ const pillCenterY = rect.top + rect.height / 2;
71
+ const pillWidth = currentGlassSize.width;
72
+ const pillHeight = currentGlassSize.height;
73
+
74
+ const deltaX = globalMousePos.x - pillCenterX;
75
+ const deltaY = globalMousePos.y - pillCenterY;
76
+
77
+ const edgeDistanceX = Math.max(0, Math.abs(deltaX) - pillWidth / 2);
78
+ const edgeDistanceY = Math.max(0, Math.abs(deltaY) - pillHeight / 2);
79
+ const edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY);
80
+
81
+ const activationZone = 200;
82
+ if (edgeDistance > activationZone) return 'scale(1)';
83
+
84
+ const fadeInFactor = 1 - edgeDistance / activationZone;
85
+ const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
86
+ if (centerDistance === 0) return 'scale(1)';
87
+
88
+ const normalizedX = deltaX / centerDistance;
89
+ const normalizedY = deltaY / centerDistance;
90
+ const stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor;
91
+
92
+ const scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * 0.3 - Math.abs(normalizedY) * stretchIntensity * 0.15;
93
+ const scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * 0.3 - Math.abs(normalizedX) * stretchIntensity * 0.15;
94
+
95
+ return `scaleX(${Math.max(0.8, scaleX)}) scaleY(${Math.max(0.8, scaleY)})`;
96
+ }, [globalMousePos, elasticity, currentGlassSize]);
97
+
98
+ // Calculate elastic translation
99
+ const calculateElasticTranslation = useCallback(() => {
100
+ if (!glassRef.current) return { x: 0, y: 0 };
101
+
102
+ const rect = glassRef.current.getBoundingClientRect();
103
+ const pillCenterX = rect.left + rect.width / 2;
104
+ const pillCenterY = rect.top + rect.height / 2;
105
+ const pillWidth = currentGlassSize.width;
106
+ const pillHeight = currentGlassSize.height;
107
+
108
+ const edgeDistanceX = Math.max(0, Math.abs(globalMousePos.x - pillCenterX) - pillWidth / 2);
109
+ const edgeDistanceY = Math.max(0, Math.abs(globalMousePos.y - pillCenterY) - pillHeight / 2);
110
+ const edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY);
111
+
112
+ const activationZone = 200;
113
+ const fadeInFactor = edgeDistance > activationZone ? 0 : 1 - edgeDistance / activationZone;
114
+
115
+ return {
116
+ x: (globalMousePos.x - pillCenterX) * elasticity * 0.1 * fadeInFactor,
117
+ y: (globalMousePos.y - pillCenterY) * elasticity * 0.1 * fadeInFactor,
118
+ };
119
+ }, [globalMousePos, elasticity, currentGlassSize]);
120
+
121
+ // Update glass size
122
+ useEffect(() => {
123
+ const updateGlassSize = () => {
124
+ if (glassRef.current) {
125
+ const rect = glassRef.current.getBoundingClientRect();
126
+ setCurrentGlassSize({ width: rect.width, height: rect.height });
127
+ }
128
+ };
129
+
130
+ updateGlassSize();
131
+ window.addEventListener('resize', updateGlassSize);
132
+ return () => window.removeEventListener('resize', updateGlassSize);
133
+ }, []);
134
+
135
+ const handleMouseEnter = useCallback(() => {
136
+ setIsHovered(true);
137
+ }, []);
138
+
139
+ const handleMouseLeave = useCallback(() => {
140
+ setIsHovered(false);
141
+ }, []);
142
+
143
+ const handleMouseDown = useCallback(() => {
144
+ setIsActive(true);
145
+ }, []);
146
+
147
+ const handleMouseUp = useCallback(() => {
148
+ setIsActive(false);
149
+ }, []);
150
+
151
+ return {
152
+ filterId,
153
+ glassRef,
154
+ isHovered,
155
+ isActive,
156
+ currentGlassSize,
157
+ globalMousePos,
158
+ mouseOffset,
159
+ calculateDirectionalScale,
160
+ calculateElasticTranslation,
161
+ handleMouseEnter,
162
+ handleMouseLeave,
163
+ handleMouseDown,
164
+ handleMouseUp,
165
+ };
166
+ }
167
+
168
+ export default useGlassContainer;
@@ -122,6 +122,8 @@ export function useLineChart(datasets: ChartDataset[], options: LineChartOptions
122
122
  pointIndex: number;
123
123
  x: number;
124
124
  y: number;
125
+ clientX?: number;
126
+ clientY?: number;
125
127
  } | null>(null);
126
128
 
127
129
  // Calculate moving averages
@@ -251,8 +253,8 @@ export function useLineChart(datasets: ChartDataset[], options: LineChartOptions
251
253
 
252
254
  // Point hover handlers
253
255
  const handlePointHover = useCallback(
254
- (datasetIndex: number, pointIndex: number, x: number, y: number) => {
255
- setHoveredPoint({ datasetIndex, pointIndex, x, y });
256
+ (datasetIndex: number, pointIndex: number, x: number, y: number, clientX: number, clientY: number) => {
257
+ setHoveredPoint({ datasetIndex, pointIndex, x, y, clientX, clientY });
256
258
  },
257
259
  []
258
260
  );
@@ -245,20 +245,10 @@ export function usePieChart(data: ChartDataPoint[], options: PieChartOptions = {
245
245
  requestAnimationFrame(animate);
246
246
  }, [options.enableAnimations, options.animationDuration]);
247
247
 
248
- // Slice interaction handlers
249
- const handleSliceHover = useCallback(
250
- (index: number, clientX?: number, clientY?: number) => {
251
- if (!options.enableHoverEffects) return;
252
- setHoveredSlice(index);
253
-
254
- // Store client coordinates for tooltip positioning
255
- if (clientX !== undefined && clientY !== undefined && slices[index]) {
256
- slices[index].clientX = clientX;
257
- slices[index].clientY = clientY;
258
- }
259
- },
260
- [options.enableHoverEffects, slices]
261
- );
248
+ // Slice hover handlers
249
+ const handleSliceHover = useCallback((index: number, clientX: number, clientY: number) => {
250
+ setHoveredSlice(index);
251
+ }, []);
262
252
 
263
253
  const handleSliceLeave = useCallback(() => {
264
254
  setHoveredSlice(null);
@@ -1081,6 +1081,9 @@ export const VIDEO_PLAYER = {
1081
1081
  SETTINGS_OPTION_ACTIVE: 'c-video-player__settings-option--active',
1082
1082
  AMBIENT: 'c-video-player--ambient',
1083
1083
  AMBIENT_CANVAS: 'c-video-player__ambient-canvas',
1084
+ GLASS: 'c-video-player--glass',
1085
+ GLASS_OVERLAY: 'c-video-player__glass-overlay',
1086
+ GLASS_CONTENT: 'c-video-player__glass-content',
1084
1087
  },
1085
1088
  DEFAULTS: {
1086
1089
  CONTROLS_TIMEOUT: 3000,
@@ -1211,6 +1214,7 @@ export const CHART = {
1211
1214
  EXPORT_GROUP_CLASS: 'c-chart__export-group',
1212
1215
  EXPORT_DROPDOWN_CLASS: 'c-chart__export-dropdown',
1213
1216
  EXPORT_OPTION_CLASS: 'c-chart__export-option',
1217
+ SETTINGS_MENU_CLASS: 'c-chart__settings-menu',
1214
1218
  TOOLBAR_GROUP_CLASS: 'c-chart__toolbar-group',
1215
1219
  TOOLBAR_SEPARATOR_CLASS: 'c-chart__toolbar-separator',
1216
1220
  TOOLBAR_LABEL_CLASS: 'c-chart__toolbar-label',
@@ -1432,6 +1436,37 @@ export const BLOCK = {
1432
1436
  },
1433
1437
  };
1434
1438
 
1439
+ /**
1440
+ * GlassContainer-specific constants
1441
+ */
1442
+ export const GLASS_CONTAINER = {
1443
+ CLASSES: {
1444
+ BASE: 'c-glass-container',
1445
+ GLASS: 'c-glass-container__glass',
1446
+ WARP: 'c-glass-container__warp',
1447
+ CONTENT: 'c-glass-container__content',
1448
+ OVERLAY: 'c-glass-container__overlay',
1449
+ OVERLAY_VISIBLE: 'c-glass-container__overlay--visible',
1450
+ OVERLAY_HIDDEN: 'c-glass-container__overlay--hidden',
1451
+ OVERLAY_BLEND: 'c-glass-container__overlay-blend',
1452
+ BORDER: 'c-glass-container__border',
1453
+ BORDER_OVERLAY: 'c-glass-container__border-overlay',
1454
+ HOVER_EFFECT: 'c-glass-container__hover-effect',
1455
+ ACTIVE_EFFECT: 'c-glass-container__active-effect',
1456
+ INTERACTION_EFFECT: 'c-glass-container__interaction-effect',
1457
+ ACTIVE: 'c-glass-container--active',
1458
+ CLICKABLE: 'c-glass-container--clickable',
1459
+ },
1460
+ DISPLACEMENT_MAPS: {
1461
+ STANDARD:
1462
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjcwIiBoZWlnaHQ9IjY5IiB2aWV3Qm94PSIwIDAgMjcwIDY5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxyYWRpYWxHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGN4PSI1MCUiIGN5PSI1MCUiIHI9IjUwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzgwODA4MCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzgwODA4MCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZGllbnQpIi8+PC9zdmc+',
1463
+ POLAR:
1464
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjcwIiBoZWlnaHQ9IjY5IiB2aWV3Qm94PSIwIDAgMjcwIDY5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxyYWRpYWxHcmFkaWVudCBpZD0icG9sYXIiIGN4PSI1MCUiIGN5PSI1MCUiIHI9IjUwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzQwNDA0MCIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjODA4MDgwIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjNDA0MDQwIi8+PC9yYWRpYWxHcmFkaWVudD48L2RlZnM+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNwb2xhcikiLz48L3N2Zz4=',
1465
+ PROMINENT:
1466
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjcwIiBoZWlnaHQ9IjY5IiB2aWV3Qm94PSIwIDAgMjcwIDY5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0icHJvbWluZW50IiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjNDA0MDQwIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNjMGMwYzAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM0MDQwNDAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI3Byb21pbmVudCkiLz48L3N2Zz4=',
1467
+ },
1468
+ };
1469
+
1435
1470
  /**
1436
1471
  * Footer-specific constants
1437
1472
  */
@@ -1516,3 +1551,57 @@ export const FOOTER = {
1516
1551
  BACK_TO_TOP_TEXT: 'Back to Top',
1517
1552
  },
1518
1553
  };
1554
+
1555
+ /**
1556
+ * AtomixGlass-specific constants
1557
+ */
1558
+ export const ATOMIX_GLASS = {
1559
+ BASE_CLASS: 'c-atomix-glass',
1560
+ WARP_CLASS: 'c-atomix-glass__warp',
1561
+ CONTENT_CLASS: 'c-atomix-glass__content',
1562
+ BORDER_CLASS: 'c-atomix-glass__border',
1563
+ OVER_LIGHT_CLASS: 'c-atomix-glass__over-light',
1564
+ HOVER_EFFECT_CLASS: 'c-atomix-glass__hover-effect',
1565
+ ACTIVE_EFFECT_CLASS: 'c-atomix-glass__active-effect',
1566
+ GLOW_EFFECT_CLASS: 'c-atomix-glass__glow-effect',
1567
+ VARIANT_PREFIX: 'c-atomix-glass--',
1568
+ MODE_PREFIX: 'c-atomix-glass--',
1569
+ CLASSES: {
1570
+ BASE: 'c-atomix-glass',
1571
+ WARP: 'c-atomix-glass__warp',
1572
+ CONTENT: 'c-atomix-glass__content',
1573
+ BORDER: 'c-atomix-glass__border',
1574
+ BORDER_OVERLAY: 'c-atomix-glass__border--overlay',
1575
+ OVER_LIGHT: 'c-atomix-glass__over-light',
1576
+ OVER_LIGHT_ACTIVE: 'c-atomix-glass__over-light--active',
1577
+ OVER_LIGHT_OVERLAY: 'c-atomix-glass__over-light--overlay',
1578
+ OVER_LIGHT_OVERLAY_ACTIVE: 'c-atomix-glass__over-light--overlay-active',
1579
+ HOVER_EFFECT: 'c-atomix-glass__hover-effect',
1580
+ HOVER_EFFECT_ACTIVE: 'c-atomix-glass__hover-effect--active',
1581
+ ACTIVE_EFFECT: 'c-atomix-glass__active-effect',
1582
+ ACTIVE_EFFECT_ACTIVE: 'c-atomix-glass__active-effect--active',
1583
+ GLOW_EFFECT: 'c-atomix-glass__glow-effect',
1584
+ GLOW_EFFECT_HOVER: 'c-atomix-glass__glow-effect--hover',
1585
+ GLOW_EFFECT_ACTIVE: 'c-atomix-glass__glow-effect--active',
1586
+ // Modifiers
1587
+ CLICKABLE: 'c-atomix-glass--clickable',
1588
+ ACTIVE: 'c-atomix-glass--active',
1589
+ // Mode variants
1590
+ STANDARD: 'c-atomix-glass--standard',
1591
+ POLAR: 'c-atomix-glass--polar',
1592
+ PROMINENT: 'c-atomix-glass--prominent',
1593
+ SHADER: 'c-atomix-glass--shader',
1594
+ },
1595
+ DEFAULTS: {
1596
+ DISPLACEMENT_SCALE: 70,
1597
+ BLUR_AMOUNT: 0.0625,
1598
+ SATURATION: 140,
1599
+ ABERRATION_INTENSITY: 2,
1600
+ ELASTICITY: 0.15,
1601
+ CORNER_RADIUS: 999,
1602
+ PADDING: '24px 32px',
1603
+ MODE: 'standard',
1604
+ OVER_LIGHT: false,
1605
+ SIZE: 'md',
1606
+ },
1607
+ };