@shohojdhara/atomix 0.2.1 → 0.2.3

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 (201) hide show
  1. package/README.md +1 -28
  2. package/dist/atomix.css +1500 -241
  3. package/dist/atomix.min.css +6 -6
  4. package/dist/index.d.ts +1052 -194
  5. package/dist/index.esm.js +12201 -6066
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +5481 -2827
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.js +1 -1
  10. package/dist/index.min.js.map +1 -1
  11. package/dist/themes/boomdevs.css +1500 -301
  12. package/dist/themes/boomdevs.min.css +60 -8
  13. package/dist/themes/esrar.css +1500 -241
  14. package/dist/themes/esrar.min.css +6 -6
  15. package/dist/themes/mashroom.css +1496 -237
  16. package/dist/themes/mashroom.min.css +8 -8
  17. package/dist/themes/shaj-default.css +1451 -192
  18. package/dist/themes/shaj-default.min.css +6 -6
  19. package/package.json +66 -15
  20. package/src/components/Accordion/Accordion.stories.tsx +137 -0
  21. package/src/components/Accordion/Accordion.tsx +33 -3
  22. package/src/components/AtomixGlass/AtomixGlass.stories.tsx +3011 -0
  23. package/src/components/AtomixGlass/AtomixGlass.test.tsx +199 -0
  24. package/src/components/AtomixGlass/AtomixGlass.tsx +1281 -0
  25. package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +1369 -0
  26. package/src/components/AtomixGlass/README.md +134 -0
  27. package/src/components/AtomixGlass/index.ts +10 -0
  28. package/src/components/AtomixGlass/shader-utils.ts +140 -0
  29. package/src/components/AtomixGlass/utils.ts +8 -0
  30. package/src/components/Badge/Badge.stories.tsx +169 -0
  31. package/src/components/Badge/Badge.tsx +27 -2
  32. package/src/components/Button/Button.stories.tsx +345 -0
  33. package/src/components/Button/Button.tsx +35 -3
  34. package/src/components/Button/README.md +216 -0
  35. package/src/components/Callout/Callout.stories.tsx +813 -78
  36. package/src/components/Callout/Callout.test.tsx +368 -0
  37. package/src/components/Callout/Callout.tsx +26 -7
  38. package/src/components/Callout/README.md +409 -0
  39. package/src/components/Card/Card.stories.tsx +140 -0
  40. package/src/components/Card/Card.tsx +19 -3
  41. package/src/components/DatePicker/DatePicker copy.tsx +551 -0
  42. package/src/components/DatePicker/DatePicker.stories.tsx +188 -0
  43. package/src/components/DatePicker/DatePicker.tsx +379 -332
  44. package/src/components/DatePicker/readme.md +110 -1
  45. package/src/components/DatePicker/types.ts +8 -0
  46. package/src/components/Dropdown/Dropdown.stories.tsx +145 -0
  47. package/src/components/Dropdown/Dropdown.tsx +34 -5
  48. package/src/components/Footer/Footer.stories.tsx +388 -0
  49. package/src/components/Footer/Footer.tsx +197 -0
  50. package/src/components/Footer/FooterLink.tsx +72 -0
  51. package/src/components/Footer/FooterSection.tsx +87 -0
  52. package/src/components/Footer/FooterSocialLink.tsx +117 -0
  53. package/src/components/Footer/README.md +261 -0
  54. package/src/components/Footer/index.ts +13 -0
  55. package/src/components/Form/Checkbox.stories.tsx +101 -0
  56. package/src/components/Form/Checkbox.tsx +26 -2
  57. package/src/components/Form/Input.stories.tsx +124 -0
  58. package/src/components/Form/Input.tsx +36 -7
  59. package/src/components/Form/Radio.stories.tsx +139 -0
  60. package/src/components/Form/Radio.tsx +26 -2
  61. package/src/components/Form/Select.stories.tsx +110 -0
  62. package/src/components/Form/Select.tsx +26 -2
  63. package/src/components/Form/Textarea.stories.tsx +104 -0
  64. package/src/components/Form/Textarea.tsx +36 -7
  65. package/src/components/Hero/Hero.stories.tsx +54 -1
  66. package/src/components/Hero/Hero.tsx +70 -11
  67. package/src/components/Modal/Modal.stories.tsx +235 -0
  68. package/src/components/Modal/Modal.tsx +64 -35
  69. package/src/components/Pagination/Pagination.stories.tsx +101 -0
  70. package/src/components/Pagination/Pagination.tsx +25 -1
  71. package/src/components/Popover/Popover.stories.tsx +94 -0
  72. package/src/components/Popover/Popover.tsx +30 -4
  73. package/src/components/Rating/Rating.stories.tsx +112 -0
  74. package/src/components/Rating/Rating.tsx +25 -1
  75. package/src/components/SectionIntro/SectionIntro.tsx +9 -11
  76. package/src/components/Slider/Slider.stories.tsx +634 -50
  77. package/src/components/Slider/Slider.tsx +5 -3
  78. package/src/components/Steps/Steps.stories.tsx +119 -0
  79. package/src/components/Steps/Steps.tsx +32 -1
  80. package/src/components/Tab/Tab.stories.tsx +88 -0
  81. package/src/components/Tab/Tab.tsx +32 -1
  82. package/src/components/Toggle/Toggle.stories.tsx +92 -0
  83. package/src/components/Toggle/Toggle.tsx +32 -1
  84. package/src/components/Tooltip/Tooltip.stories.tsx +131 -0
  85. package/src/components/Tooltip/Tooltip.tsx +43 -7
  86. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +1002 -196
  87. package/src/components/VideoPlayer/VideoPlayer.tsx +161 -4
  88. package/src/components/index.ts +14 -0
  89. package/src/layouts/Grid/Grid.stories.tsx +226 -159
  90. package/src/lib/composables/index.ts +4 -0
  91. package/src/lib/composables/useAtomixGlass.ts +71 -0
  92. package/src/lib/composables/useButton.ts +3 -1
  93. package/src/lib/composables/useCallout.ts +4 -1
  94. package/src/lib/composables/useFooter.ts +85 -0
  95. package/src/lib/composables/useGlassContainer.ts +168 -0
  96. package/src/lib/composables/useSlider.ts +191 -4
  97. package/src/lib/constants/components.ts +173 -0
  98. package/src/lib/types/components.ts +622 -0
  99. package/src/lib/utils/displacement-generator.ts +86 -0
  100. package/src/styles/01-settings/_index.scss +1 -0
  101. package/src/styles/01-settings/_settings.accordion.scss +20 -19
  102. package/src/styles/01-settings/_settings.animations.scss +5 -5
  103. package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
  104. package/src/styles/01-settings/_settings.avatar.scss +17 -18
  105. package/src/styles/01-settings/_settings.background.scss +10 -0
  106. package/src/styles/01-settings/_settings.badge.scss +1 -1
  107. package/src/styles/01-settings/_settings.breadcrumb.scss +8 -2
  108. package/src/styles/01-settings/_settings.callout.scss +7 -7
  109. package/src/styles/01-settings/_settings.card.scss +2 -2
  110. package/src/styles/01-settings/_settings.chart.scss +7 -7
  111. package/src/styles/01-settings/_settings.checkbox-group.scss +5 -2
  112. package/src/styles/01-settings/_settings.checkbox.scss +10 -4
  113. package/src/styles/01-settings/_settings.countdown.scss +6 -4
  114. package/src/styles/01-settings/_settings.dropdown.scss +9 -7
  115. package/src/styles/01-settings/_settings.edge-panel.scss +3 -2
  116. package/src/styles/01-settings/_settings.footer.scss +125 -0
  117. package/src/styles/01-settings/_settings.form-group.scss +3 -1
  118. package/src/styles/01-settings/_settings.form.scss +4 -2
  119. package/src/styles/01-settings/_settings.hero.scss +9 -7
  120. package/src/styles/01-settings/_settings.input.scss +9 -7
  121. package/src/styles/01-settings/_settings.list-group.scss +4 -2
  122. package/src/styles/01-settings/_settings.list.scss +4 -2
  123. package/src/styles/01-settings/_settings.menu.scss +10 -8
  124. package/src/styles/01-settings/_settings.messages.scss +19 -17
  125. package/src/styles/01-settings/_settings.modal.scss +6 -4
  126. package/src/styles/01-settings/_settings.nav.scss +6 -4
  127. package/src/styles/01-settings/_settings.navbar.scss +8 -5
  128. package/src/styles/01-settings/_settings.pagination.scss +5 -3
  129. package/src/styles/01-settings/_settings.popover.scss +6 -4
  130. package/src/styles/01-settings/_settings.rating.scss +5 -3
  131. package/src/styles/01-settings/_settings.river.scss +8 -6
  132. package/src/styles/01-settings/_settings.sectionintro.scss +8 -6
  133. package/src/styles/01-settings/_settings.select.scss +7 -5
  134. package/src/styles/01-settings/_settings.side-menu.scss +15 -13
  135. package/src/styles/01-settings/_settings.spacing.scss +4 -0
  136. package/src/styles/01-settings/_settings.steps.scss +7 -5
  137. package/src/styles/01-settings/_settings.tabs.scss +7 -5
  138. package/src/styles/01-settings/_settings.testimonials.scss +6 -4
  139. package/src/styles/01-settings/_settings.toggle.scss +3 -1
  140. package/src/styles/01-settings/_settings.tooltip.scss +5 -3
  141. package/src/styles/01-settings/_settings.upload.scss +22 -20
  142. package/src/styles/02-tools/_tools.animations.scss +19 -0
  143. package/src/styles/02-tools/_tools.background.scss +87 -0
  144. package/src/styles/02-tools/_tools.glass.scss +1 -0
  145. package/src/styles/02-tools/_tools.rem.scss +18 -5
  146. package/src/styles/02-tools/_tools.utility-api.scss +32 -26
  147. package/src/styles/03-generic/_generic.root.scss +15 -2
  148. package/src/styles/04-elements/_elements.body.scss +6 -0
  149. package/src/styles/06-components/_components.accordion.scss +24 -4
  150. package/src/styles/06-components/_components.atomix-glass.scss +0 -0
  151. package/src/styles/06-components/_components.avatar-group.scss +2 -1
  152. package/src/styles/06-components/_components.avatar.scss +2 -1
  153. package/src/styles/06-components/_components.badge.scss +36 -1
  154. package/src/styles/06-components/_components.breadcrumb.scss +2 -1
  155. package/src/styles/06-components/_components.button.scss +14 -3
  156. package/src/styles/06-components/_components.callout.scss +44 -4
  157. package/src/styles/06-components/_components.card.scss +21 -2
  158. package/src/styles/06-components/_components.chart.scss +3 -2
  159. package/src/styles/06-components/_components.checkbox.scss +2 -1
  160. package/src/styles/06-components/_components.color-mode-toggle.scss +3 -2
  161. package/src/styles/06-components/_components.countdown.scss +2 -1
  162. package/src/styles/06-components/_components.data-table.scss +7 -6
  163. package/src/styles/06-components/_components.datepicker.scss +20 -1
  164. package/src/styles/06-components/_components.dropdown.scss +11 -4
  165. package/src/styles/06-components/_components.edge-panel.scss +4 -3
  166. package/src/styles/06-components/_components.footer.scss +825 -0
  167. package/src/styles/06-components/_components.form-group.scss +1 -0
  168. package/src/styles/06-components/_components.hero.scss +4 -4
  169. package/src/styles/06-components/_components.image-gallery.scss +1 -0
  170. package/src/styles/06-components/_components.input.scss +33 -2
  171. package/src/styles/06-components/_components.list-group.scss +3 -2
  172. package/src/styles/06-components/_components.list.scss +2 -1
  173. package/src/styles/06-components/_components.menu.scss +5 -4
  174. package/src/styles/06-components/_components.messages.scss +8 -7
  175. package/src/styles/06-components/_components.modal.scss +3 -2
  176. package/src/styles/06-components/_components.nav.scss +6 -5
  177. package/src/styles/06-components/_components.navbar.scss +4 -3
  178. package/src/styles/06-components/_components.pagination.scss +2 -1
  179. package/src/styles/06-components/_components.photoviewer.scss +4 -3
  180. package/src/styles/06-components/_components.popover.scss +3 -2
  181. package/src/styles/06-components/_components.product-review.scss +3 -2
  182. package/src/styles/06-components/_components.progress.scss +3 -2
  183. package/src/styles/06-components/_components.river.scss +3 -2
  184. package/src/styles/06-components/_components.sectionintro.scss +2 -1
  185. package/src/styles/06-components/_components.select.scss +5 -4
  186. package/src/styles/06-components/_components.side-menu.scss +8 -7
  187. package/src/styles/06-components/_components.skeleton.scss +3 -2
  188. package/src/styles/06-components/_components.slider.scss +7 -6
  189. package/src/styles/06-components/_components.spinner.scss +1 -0
  190. package/src/styles/06-components/_components.steps.scss +3 -2
  191. package/src/styles/06-components/_components.tabs.scss +4 -3
  192. package/src/styles/06-components/_components.testimonials.scss +2 -1
  193. package/src/styles/06-components/_components.todo.scss +3 -2
  194. package/src/styles/06-components/_components.toggle.scss +5 -4
  195. package/src/styles/06-components/_components.tooltip.scss +3 -2
  196. package/src/styles/06-components/_components.upload.scss +4 -3
  197. package/src/styles/06-components/_components.video-player.scss +50 -27
  198. package/src/styles/06-components/_index.scss +2 -0
  199. package/src/styles/99-utilities/_utilities.glass-fixes.scss +48 -0
  200. package/dist/themes/yabai.css +0 -13711
  201. package/dist/themes/yabai.min.css +0 -189
@@ -0,0 +1,368 @@
1
+ import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { Callout } from './Callout';
4
+
5
+ // Mock AtomixGlass component since it has complex WebGL dependencies
6
+ vi.mock('../AtomixGlass/AtomixGlass', () => ({
7
+ AtomixGlass: ({ children, ...props }: any) => (
8
+ <div data-testid="atomix-glass" data-glass-props={JSON.stringify(props)}>
9
+ {children}
10
+ </div>
11
+ ),
12
+ }));
13
+
14
+ describe('Callout Component', () => {
15
+ describe('Basic functionality', () => {
16
+ it('renders with title and content', () => {
17
+ render(
18
+ <Callout title="Test Title" variant="primary">
19
+ Test content
20
+ </Callout>
21
+ );
22
+
23
+ expect(screen.getByText('Test Title')).toBeInTheDocument();
24
+ expect(screen.getByText('Test content')).toBeInTheDocument();
25
+ });
26
+
27
+ it('renders with icon', () => {
28
+ const TestIcon = () => <div data-testid="test-icon">Icon</div>;
29
+
30
+ render(
31
+ <Callout title="Test" variant="primary" icon={<TestIcon />}>
32
+ Content
33
+ </Callout>
34
+ );
35
+
36
+ expect(screen.getByTestId('test-icon')).toBeInTheDocument();
37
+ });
38
+
39
+ it('applies correct variant class', () => {
40
+ const { container } = render(
41
+ <Callout title="Test" variant="success">
42
+ Content
43
+ </Callout>
44
+ );
45
+
46
+ expect(container.firstChild).toHaveClass('c-callout--success');
47
+ });
48
+
49
+ it('applies oneLine class when enabled', () => {
50
+ const { container } = render(
51
+ <Callout title="Test" variant="primary" oneLine>
52
+ Content
53
+ </Callout>
54
+ );
55
+
56
+ expect(container.firstChild).toHaveClass('c-callout--oneline');
57
+ });
58
+
59
+ it('applies toast class when enabled', () => {
60
+ const { container } = render(
61
+ <Callout title="Test" variant="primary" toast>
62
+ Content
63
+ </Callout>
64
+ );
65
+
66
+ expect(container.firstChild).toHaveClass('c-callout--toast');
67
+ });
68
+
69
+ it('renders close button when onClose is provided', () => {
70
+ const handleClose = vi.fn();
71
+
72
+ render(
73
+ <Callout title="Test" variant="primary" onClose={handleClose}>
74
+ Content
75
+ </Callout>
76
+ );
77
+
78
+ const closeButton = screen.getByRole('button', { name: 'Close' });
79
+ expect(closeButton).toBeInTheDocument();
80
+ });
81
+
82
+ it('calls onClose when close button is clicked', () => {
83
+ const handleClose = vi.fn();
84
+
85
+ render(
86
+ <Callout title="Test" variant="primary" onClose={handleClose}>
87
+ Content
88
+ </Callout>
89
+ );
90
+
91
+ const closeButton = screen.getByRole('button', { name: 'Close' });
92
+ fireEvent.click(closeButton);
93
+
94
+ expect(handleClose).toHaveBeenCalledTimes(1);
95
+ });
96
+
97
+ it('renders action buttons', () => {
98
+ const actions = <button data-testid="action-button">Action</button>;
99
+
100
+ render(
101
+ <Callout title="Test" variant="primary" actions={actions}>
102
+ Content
103
+ </Callout>
104
+ );
105
+
106
+ expect(screen.getByTestId('action-button')).toBeInTheDocument();
107
+ });
108
+ });
109
+
110
+ describe('Glass functionality', () => {
111
+ it('does not render AtomixGlass when glass is false', () => {
112
+ render(
113
+ <Callout title="Test" variant="primary" glass={false}>
114
+ Content
115
+ </Callout>
116
+ );
117
+
118
+ expect(screen.queryByTestId('atomix-glass')).not.toBeInTheDocument();
119
+ });
120
+
121
+ it('renders AtomixGlass when glass is true', () => {
122
+ render(
123
+ <Callout title="Test" variant="primary" glass={true}>
124
+ Content
125
+ </Callout>
126
+ );
127
+
128
+ expect(screen.getByTestId('atomix-glass')).toBeInTheDocument();
129
+ });
130
+
131
+ it('applies glass class when glass is enabled', () => {
132
+ const { container } = render(
133
+ <Callout title="Test" variant="primary" glass={true}>
134
+ Content
135
+ </Callout>
136
+ );
137
+
138
+ // The glass class should be applied to the inner callout element
139
+ const calloutElement = container.querySelector('.c-callout');
140
+ expect(calloutElement).toHaveClass('c-callout--glass');
141
+ });
142
+
143
+ it('uses default glass settings when glass is true', () => {
144
+ render(
145
+ <Callout title="Test" variant="primary" glass={true}>
146
+ Content
147
+ </Callout>
148
+ );
149
+
150
+ const glassElement = screen.getByTestId('atomix-glass');
151
+ const glassProps = JSON.parse(glassElement.getAttribute('data-glass-props') || '{}');
152
+
153
+ expect(glassProps).toMatchObject({
154
+ displacementScale: 40,
155
+ blurAmount: 0,
156
+ saturation: 160,
157
+ aberrationIntensity: 1,
158
+ cornerRadius: 8,
159
+ overLight: false,
160
+ mode: 'standard',
161
+ });
162
+ });
163
+
164
+ it('uses custom glass settings when glass is an object', () => {
165
+ const customGlass = {
166
+ displacementScale: 60,
167
+ blurAmount: 2,
168
+ saturation: 180,
169
+ cornerRadius: 12,
170
+ };
171
+
172
+ render(
173
+ <Callout title="Test" variant="primary" glass={customGlass}>
174
+ Content
175
+ </Callout>
176
+ );
177
+
178
+ const glassElement = screen.getByTestId('atomix-glass');
179
+ const glassProps = JSON.parse(glassElement.getAttribute('data-glass-props') || '{}');
180
+
181
+ expect(glassProps).toMatchObject({
182
+ // Custom values
183
+ displacementScale: 60,
184
+ blurAmount: 2,
185
+ saturation: 180,
186
+ cornerRadius: 12,
187
+ // Default values that weren't overridden
188
+ aberrationIntensity: 1,
189
+ overLight: false,
190
+ mode: 'standard',
191
+ });
192
+ });
193
+
194
+ it('maintains all functionality with glass enabled', () => {
195
+ const handleClose = vi.fn();
196
+ const TestIcon = () => <div data-testid="test-icon">Icon</div>;
197
+ const actions = <button data-testid="action-button">Action</button>;
198
+
199
+ render(
200
+ <Callout
201
+ title="Glass Test"
202
+ variant="success"
203
+ icon={<TestIcon />}
204
+ glass={true}
205
+ onClose={handleClose}
206
+ actions={actions}
207
+ oneLine
208
+ toast
209
+ >
210
+ Glass content
211
+ </Callout>
212
+ );
213
+
214
+ // Check that all functionality is preserved
215
+ expect(screen.getByText('Glass Test')).toBeInTheDocument();
216
+ expect(screen.getByText('Glass content')).toBeInTheDocument();
217
+ expect(screen.getByTestId('test-icon')).toBeInTheDocument();
218
+ expect(screen.getByTestId('action-button')).toBeInTheDocument();
219
+
220
+ const closeButton = screen.getByRole('button', { name: 'Close' });
221
+ expect(closeButton).toBeInTheDocument();
222
+
223
+ // Check that glass wrapper is present
224
+ expect(screen.getByTestId('atomix-glass')).toBeInTheDocument();
225
+
226
+ // Check that all classes are applied
227
+ const calloutElement = screen.getByTestId('atomix-glass').firstChild;
228
+ expect(calloutElement).toHaveClass(
229
+ 'c-callout',
230
+ 'c-callout--success',
231
+ 'c-callout--oneline',
232
+ 'c-callout--toast',
233
+ 'c-callout--glass'
234
+ );
235
+
236
+ // Test close functionality
237
+ fireEvent.click(closeButton);
238
+ expect(handleClose).toHaveBeenCalledTimes(1);
239
+ });
240
+ });
241
+
242
+ describe('Accessibility', () => {
243
+ it('applies correct ARIA role for different variants', () => {
244
+ // Test alert role for error
245
+ const { rerender } = render(
246
+ <Callout title="Error" variant="error">
247
+ Error message
248
+ </Callout>
249
+ );
250
+ expect(screen.getByRole('alert')).toBeInTheDocument();
251
+
252
+ // Test alert role for warning
253
+ rerender(
254
+ <Callout title="Warning" variant="warning">
255
+ Warning message
256
+ </Callout>
257
+ );
258
+ expect(screen.getByRole('alert')).toBeInTheDocument();
259
+
260
+ // Test status role for info
261
+ rerender(
262
+ <Callout title="Info" variant="info">
263
+ Info message
264
+ </Callout>
265
+ );
266
+ expect(screen.getByRole('status')).toBeInTheDocument();
267
+
268
+ // Test status role for success
269
+ rerender(
270
+ <Callout title="Success" variant="success">
271
+ Success message
272
+ </Callout>
273
+ );
274
+ expect(screen.getByRole('status')).toBeInTheDocument();
275
+ });
276
+
277
+ it('applies alert role and assertive live region for toast alerts', () => {
278
+ render(
279
+ <Callout title="Toast Error" variant="error" toast>
280
+ Toast error message
281
+ </Callout>
282
+ );
283
+
284
+ const callout = screen.getByRole('alert');
285
+ expect(callout).toHaveAttribute('aria-live', 'polite');
286
+ });
287
+
288
+ it('applies polite live region for toast notifications', () => {
289
+ render(
290
+ <Callout title="Toast Info" variant="info" toast>
291
+ Toast info message
292
+ </Callout>
293
+ );
294
+
295
+ const callout = screen.getByRole('alert');
296
+ expect(callout).toHaveAttribute('aria-live', 'polite');
297
+ });
298
+
299
+ it('maintains accessibility with glass effect', () => {
300
+ render(
301
+ <Callout title="Glass Error" variant="error" glass={true} toast>
302
+ Glass error message
303
+ </Callout>
304
+ );
305
+
306
+ // Should still have proper ARIA attributes
307
+ const callout = screen.getByRole('alert');
308
+ expect(callout).toHaveAttribute('aria-live', 'polite');
309
+
310
+ // Should be wrapped in glass but maintain accessibility
311
+ expect(screen.getByTestId('atomix-glass')).toBeInTheDocument();
312
+ });
313
+ });
314
+
315
+ describe('Custom className', () => {
316
+ it('applies custom className', () => {
317
+ const { container } = render(
318
+ <Callout title="Test" variant="primary" className="custom-class">
319
+ Content
320
+ </Callout>
321
+ );
322
+
323
+ expect(container.firstChild).toHaveClass('custom-class');
324
+ });
325
+
326
+ it('applies custom className with glass effect', () => {
327
+ const { container } = render(
328
+ <Callout title="Test" variant="primary" glass={true} className="custom-glass">
329
+ Content
330
+ </Callout>
331
+ );
332
+
333
+ const calloutElement = container.querySelector('.c-callout');
334
+ expect(calloutElement).toHaveClass('custom-glass');
335
+ });
336
+ });
337
+
338
+ describe('Content flexibility', () => {
339
+ it('renders without title', () => {
340
+ render(<Callout variant="primary">Content only</Callout>);
341
+
342
+ expect(screen.getByText('Content only')).toBeInTheDocument();
343
+ expect(screen.queryByRole('heading')).not.toBeInTheDocument();
344
+ });
345
+
346
+ it('renders with complex content', () => {
347
+ const complexContent = (
348
+ <div>
349
+ <p>Paragraph content</p>
350
+ <ul>
351
+ <li>List item 1</li>
352
+ <li>List item 2</li>
353
+ </ul>
354
+ </div>
355
+ );
356
+
357
+ render(
358
+ <Callout title="Complex" variant="primary" glass={true}>
359
+ {complexContent}
360
+ </Callout>
361
+ );
362
+
363
+ expect(screen.getByText('Paragraph content')).toBeInTheDocument();
364
+ expect(screen.getByText('List item 1')).toBeInTheDocument();
365
+ expect(screen.getByText('List item 2')).toBeInTheDocument();
366
+ });
367
+ });
368
+ });
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { CalloutProps } from '../../lib/types/components';
3
3
  import { useCallout } from '../../lib/composables/useCallout';
4
4
  import { Icon } from '../Icon/Icon';
5
+ import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
5
6
 
6
7
  /**
7
8
  * Callout component for displaying important messages, notifications, or alerts
@@ -15,6 +16,7 @@ export const Callout: React.FC<CalloutProps> = ({
15
16
  actions,
16
17
  oneLine = false,
17
18
  toast = false,
19
+ glass,
18
20
  className,
19
21
  ...props
20
22
  }) => {
@@ -22,6 +24,7 @@ export const Callout: React.FC<CalloutProps> = ({
22
24
  variant,
23
25
  oneLine,
24
26
  toast,
27
+ glass,
25
28
  className,
26
29
  });
27
30
 
@@ -46,12 +49,8 @@ export const Callout: React.FC<CalloutProps> = ({
46
49
  return baseAttributes;
47
50
  };
48
51
 
49
- return (
50
- <div
51
- className={generateCalloutClass({ variant, oneLine, toast, className })}
52
- {...getAriaAttributes()}
53
- {...props}
54
- >
52
+ const calloutContent = (
53
+ <>
55
54
  <div className="c-callout__content">
56
55
  {icon && <div className="c-callout__icon">{icon}</div>}
57
56
  <div className="c-callout__message">
@@ -67,8 +66,28 @@ export const Callout: React.FC<CalloutProps> = ({
67
66
  <Icon name="X" size="md" />
68
67
  </button>
69
68
  )}
70
- </div>
69
+ </>
71
70
  );
71
+
72
+ if (glass) {
73
+ // Default glass settings for callouts
74
+ const defaultGlassProps = {
75
+ displacementScale: 20,
76
+ blurAmount: 2,
77
+ saturation: 70,
78
+ aberrationIntensity: 1,
79
+ cornerRadius: 8,
80
+ overLight: false,
81
+ elasticity: 0,
82
+ mode: 'shader' as const,
83
+ };
84
+
85
+ const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
86
+
87
+ return <div className={generateCalloutClass({ variant, oneLine, toast, glass, className })} {...getAriaAttributes()} {...props}><AtomixGlass {...glassProps}><div className="c-callout__glass-content">{calloutContent}</div></AtomixGlass></div>;
88
+ }
89
+
90
+ return <div className={generateCalloutClass({ variant, oneLine, toast, glass, className })} {...getAriaAttributes()} {...props}>{calloutContent}</div>;
72
91
  };
73
92
 
74
93
  Callout.displayName = 'Callout';