@shohojdhara/atomix 0.4.0 → 0.4.2

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 (150) hide show
  1. package/dist/atomix.css +0 -14
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +4 -4
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/charts.d.ts +12 -19
  6. package/dist/charts.js +555 -359
  7. package/dist/charts.js.map +1 -1
  8. package/dist/core.d.ts +98 -28
  9. package/dist/core.js +1082 -733
  10. package/dist/core.js.map +1 -1
  11. package/dist/forms.d.ts +26 -21
  12. package/dist/forms.js +937 -350
  13. package/dist/forms.js.map +1 -1
  14. package/dist/heavy.d.ts +14 -21
  15. package/dist/heavy.js +409 -256
  16. package/dist/heavy.js.map +1 -1
  17. package/dist/index.d.ts +518 -284
  18. package/dist/index.esm.js +1993 -1237
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/index.js +1994 -1237
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.min.js +1 -1
  23. package/dist/index.min.js.map +1 -1
  24. package/package.json +2 -2
  25. package/scripts/atomix-cli.js +43 -1
  26. package/scripts/cli/__tests__/utils.test.js +6 -2
  27. package/scripts/cli/migration-tools.js +2 -2
  28. package/scripts/cli/theme-bridge.js +7 -9
  29. package/scripts/cli/utils.js +2 -1
  30. package/src/components/Accordion/Accordion.stories.tsx +40 -0
  31. package/src/components/Accordion/Accordion.tsx +174 -56
  32. package/src/components/Accordion/AccordionCompound.test.tsx +70 -0
  33. package/src/components/AtomixGlass/AtomixGlass.tsx +82 -54
  34. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +17 -18
  35. package/src/components/AtomixGlass/README.md +5 -5
  36. package/src/components/AtomixGlass/stories/Customization.stories.tsx +2 -2
  37. package/src/components/AtomixGlass/stories/Examples.stories.tsx +42 -42
  38. package/src/components/AtomixGlass/stories/Modes.stories.tsx +5 -5
  39. package/src/components/AtomixGlass/stories/Overview.stories.tsx +3 -3
  40. package/src/components/AtomixGlass/stories/Performance.stories.tsx +2 -2
  41. package/src/components/AtomixGlass/stories/Playground.stories.tsx +45 -45
  42. package/src/components/AtomixGlass/stories/Shaders.stories.tsx +3 -3
  43. package/src/components/Badge/Badge.stories.tsx +1 -1
  44. package/src/components/Badge/Badge.tsx +1 -1
  45. package/src/components/Breadcrumb/Breadcrumb.tsx +185 -65
  46. package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +84 -0
  47. package/src/components/Breadcrumb/index.ts +2 -2
  48. package/src/components/Button/Button.stories.tsx +1 -1
  49. package/src/components/Button/README.md +2 -2
  50. package/src/components/Callout/Callout.stories.tsx +166 -1011
  51. package/src/components/Callout/Callout.test.tsx +3 -3
  52. package/src/components/Callout/Callout.tsx +196 -84
  53. package/src/components/Callout/CalloutCompound.test.tsx +72 -0
  54. package/src/components/Callout/README.md +2 -2
  55. package/src/components/Chart/Chart.stories.tsx +1 -1
  56. package/src/components/Chart/Chart.tsx +5 -5
  57. package/src/components/Chart/TreemapChart.tsx +37 -29
  58. package/src/components/DatePicker/readme.md +3 -3
  59. package/src/components/Dropdown/Dropdown.stories.tsx +1 -1
  60. package/src/components/Dropdown/Dropdown.tsx +133 -20
  61. package/src/components/Dropdown/DropdownCompound.test.tsx +64 -0
  62. package/src/components/EdgePanel/EdgePanel.stories.tsx +7 -7
  63. package/src/components/EdgePanel/EdgePanel.tsx +164 -112
  64. package/src/components/EdgePanel/EdgePanelCompound.test.tsx +53 -0
  65. package/src/components/Form/Checkbox.stories.tsx +1 -1
  66. package/src/components/Form/Checkbox.tsx +1 -1
  67. package/src/components/Form/Input.stories.tsx +1 -1
  68. package/src/components/Form/Input.tsx +1 -1
  69. package/src/components/Form/Radio.stories.tsx +1 -1
  70. package/src/components/Form/Radio.tsx +1 -1
  71. package/src/components/Form/Select.stories.tsx +24 -1
  72. package/src/components/Form/Select.test.tsx +99 -0
  73. package/src/components/Form/Select.tsx +145 -94
  74. package/src/components/Form/SelectOption.tsx +88 -0
  75. package/src/components/Form/Textarea.stories.tsx +1 -1
  76. package/src/components/Form/Textarea.tsx +1 -1
  77. package/src/components/Hero/Hero.stories.tsx +39 -2
  78. package/src/components/Hero/Hero.test.tsx +142 -0
  79. package/src/components/Hero/Hero.tsx +143 -4
  80. package/src/components/List/List.test.tsx +62 -0
  81. package/src/components/List/List.tsx +16 -5
  82. package/src/components/List/ListItem.tsx +20 -0
  83. package/src/components/Messages/Messages.stories.tsx +1 -1
  84. package/src/components/Messages/Messages.tsx +2 -2
  85. package/src/components/Modal/Modal.stories.tsx +66 -2
  86. package/src/components/Modal/Modal.tsx +115 -35
  87. package/src/components/Modal/ModalCompound.test.tsx +94 -0
  88. package/src/components/Navigation/Nav/Nav.stories.tsx +2 -2
  89. package/src/components/Navigation/Nav/Nav.tsx +1 -1
  90. package/src/components/Navigation/Navbar/Navbar.stories.tsx +3 -3
  91. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  92. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +2 -2
  93. package/src/components/Navigation/SideMenu/SideMenu.tsx +1 -1
  94. package/src/components/Pagination/Pagination.stories.tsx +1 -1
  95. package/src/components/Pagination/Pagination.tsx +1 -1
  96. package/src/components/Popover/Popover.stories.tsx +1 -1
  97. package/src/components/Popover/Popover.tsx +1 -1
  98. package/src/components/Progress/Progress.tsx +1 -1
  99. package/src/components/Rating/Rating.stories.tsx +1 -1
  100. package/src/components/Rating/Rating.test.tsx +73 -0
  101. package/src/components/Rating/Rating.tsx +25 -37
  102. package/src/components/Spinner/Spinner.tsx +1 -1
  103. package/src/components/Steps/Steps.stories.tsx +1 -1
  104. package/src/components/Steps/Steps.tsx +125 -22
  105. package/src/components/Steps/StepsCompound.test.tsx +81 -0
  106. package/src/components/Tabs/Tabs.stories.tsx +1 -1
  107. package/src/components/Tabs/Tabs.tsx +198 -45
  108. package/src/components/Tabs/TabsCompound.test.tsx +64 -0
  109. package/src/components/Todo/Todo.tsx +0 -1
  110. package/src/components/Toggle/Toggle.stories.tsx +1 -1
  111. package/src/components/Toggle/Toggle.tsx +1 -1
  112. package/src/components/Tooltip/Tooltip.stories.tsx +1 -1
  113. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +2 -2
  114. package/src/lib/composables/__tests__/useAtomixGlassPerf.test.tsx +88 -0
  115. package/src/lib/composables/__tests__/useChart.test.ts +50 -0
  116. package/src/lib/composables/__tests__/useChart.test.tsx +139 -0
  117. package/src/lib/composables/__tests__/useHeroBackgroundSlider.test.tsx +59 -0
  118. package/src/lib/composables/__tests__/useSliderAutoplay.test.tsx +68 -0
  119. package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +329 -0
  120. package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +82 -0
  121. package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +153 -0
  122. package/src/lib/composables/atomix-glass/useGlassOverLight.ts +198 -0
  123. package/src/lib/composables/atomix-glass/useGlassSize.ts +117 -0
  124. package/src/lib/composables/atomix-glass/useGlassState.ts +112 -0
  125. package/src/lib/composables/atomix-glass/useGlassTransforms.ts +160 -0
  126. package/src/lib/composables/glass-styles.ts +302 -0
  127. package/src/lib/composables/index.ts +0 -8
  128. package/src/lib/composables/useAtomixGlass.ts +331 -537
  129. package/src/lib/composables/useAtomixGlassStyles.ts +307 -0
  130. package/src/lib/composables/useBarChart.ts +1 -1
  131. package/src/lib/composables/useBreadcrumb.ts +6 -6
  132. package/src/lib/composables/useChart.ts +104 -21
  133. package/src/lib/composables/useHeroBackgroundSlider.ts +16 -7
  134. package/src/lib/composables/useSlider.ts +66 -34
  135. package/src/lib/theme/devtools/CLI.ts +2 -10
  136. package/src/lib/theme/utils/__tests__/themeUtils.test.ts +213 -0
  137. package/src/lib/types/components.ts +21 -23
  138. package/src/lib/utils/__tests__/componentUtils.test.ts +57 -2
  139. package/src/lib/utils/__tests__/dom.test.ts +100 -0
  140. package/src/lib/utils/__tests__/fontPreloader.test.ts +102 -0
  141. package/src/lib/utils/__tests__/themeNaming.test.ts +117 -0
  142. package/src/lib/utils/themeNaming.ts +1 -1
  143. package/src/styles/06-components/_components.accordion.scss +0 -2
  144. package/src/styles/06-components/_components.chart.scss +0 -1
  145. package/src/styles/06-components/_components.dropdown.scss +0 -1
  146. package/src/styles/06-components/_components.edge-panel.scss +0 -2
  147. package/src/styles/06-components/_components.photoviewer.scss +0 -1
  148. package/src/styles/06-components/_components.river.scss +0 -1
  149. package/src/styles/06-components/_components.slider.scss +0 -3
  150. package/src/styles/99-utilities/_utilities.glass-fixes.scss +0 -1
@@ -152,7 +152,7 @@ describe('Callout Component', () => {
152
152
 
153
153
  expect(glassProps).toMatchObject({
154
154
  displacementScale: 30,
155
- cornerRadius: 8,
155
+ borderRadius: 8,
156
156
  elasticity: 0,
157
157
  });
158
158
  });
@@ -162,7 +162,7 @@ describe('Callout Component', () => {
162
162
  displacementScale: 60,
163
163
  blurAmount: 2,
164
164
  saturation: 180,
165
- cornerRadius: 12,
165
+ borderRadius: 12,
166
166
  };
167
167
 
168
168
  render(
@@ -179,7 +179,7 @@ describe('Callout Component', () => {
179
179
  displacementScale: 60,
180
180
  blurAmount: 2,
181
181
  saturation: 180,
182
- cornerRadius: 12,
182
+ borderRadius: 12,
183
183
  // Default values from Callout
184
184
  elasticity: 0,
185
185
  });
@@ -1,85 +1,206 @@
1
- import React from 'react';
1
+ import React, { memo, forwardRef } 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
5
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
6
6
 
7
+ // Subcomponents
8
+ export const CalloutIcon = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
9
+ ({ children, className = '', ...props }, ref) => (
10
+ <div ref={ref} className={`c-callout__icon ${className}`.trim()} {...props}>
11
+ {children}
12
+ </div>
13
+ )
14
+ );
15
+ CalloutIcon.displayName = 'CalloutIcon';
16
+
17
+ export const CalloutMessage = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
18
+ ({ children, className = '', ...props }, ref) => (
19
+ <div ref={ref} className={`c-callout__message ${className}`.trim()} {...props}>
20
+ {children}
21
+ </div>
22
+ )
23
+ );
24
+ CalloutMessage.displayName = 'CalloutMessage';
25
+
26
+ export const CalloutTitle = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
27
+ ({ children, className = '', ...props }, ref) => (
28
+ <div ref={ref} className={`c-callout__title ${className}`.trim()} {...props}>
29
+ {children}
30
+ </div>
31
+ )
32
+ );
33
+ CalloutTitle.displayName = 'CalloutTitle';
34
+
35
+ export const CalloutText = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
36
+ ({ children, className = '', ...props }, ref) => (
37
+ <div ref={ref} className={`c-callout__text ${className}`.trim()} {...props}>
38
+ {children}
39
+ </div>
40
+ )
41
+ );
42
+ CalloutText.displayName = 'CalloutText';
43
+
44
+ export const CalloutActions = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
45
+ ({ children, className = '', ...props }, ref) => (
46
+ <div ref={ref} className={`c-callout__actions ${className}`.trim()} {...props}>
47
+ {children}
48
+ </div>
49
+ )
50
+ );
51
+ CalloutActions.displayName = 'CalloutActions';
52
+
53
+ export interface CalloutCloseButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}
54
+ export const CalloutCloseButton = forwardRef<HTMLButtonElement, CalloutCloseButtonProps>(
55
+ ({ onClick, className = '', ...props }, ref) => (
56
+ <button
57
+ ref={ref}
58
+ className={`c-callout__close-btn ${className}`.trim()}
59
+ onClick={onClick}
60
+ aria-label="Close"
61
+ {...props}
62
+ >
63
+ <Icon name="X" size="md" />
64
+ </button>
65
+ )
66
+ );
67
+ CalloutCloseButton.displayName = 'CalloutCloseButton';
68
+
69
+ // Wrapper for content (icon + message)
70
+ export const CalloutContent = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
71
+ ({ children, className = '', ...props }, ref) => (
72
+ <div ref={ref} className={`c-callout__content ${className}`.trim()} {...props}>
73
+ {children}
74
+ </div>
75
+ )
76
+ );
77
+ CalloutContent.displayName = 'CalloutContent';
78
+
7
79
  /**
8
80
  * Callout component for displaying important messages, notifications, or alerts
9
81
  */
10
- export const Callout: React.FC<CalloutProps> = ({
11
- title,
12
- children,
13
- icon,
14
- variant = 'primary',
15
- onClose,
16
- actions,
17
- compact = false,
18
- isToast = false,
19
- glass,
20
- className,
21
- style,
22
- ...props
23
- }) => {
24
- const { generateCalloutClass, handleClose } = useCallout({
25
- variant,
26
- compact,
27
- isToast,
82
+ type CalloutComponent = React.FC<CalloutProps> & {
83
+ Icon: typeof CalloutIcon;
84
+ Message: typeof CalloutMessage;
85
+ Title: typeof CalloutTitle;
86
+ Text: typeof CalloutText;
87
+ Actions: typeof CalloutActions;
88
+ CloseButton: typeof CalloutCloseButton;
89
+ Content: typeof CalloutContent;
90
+ };
91
+
92
+ export const Callout: CalloutComponent = memo(
93
+ ({
94
+ title,
95
+ children,
96
+ icon,
97
+ variant = 'primary',
98
+ onClose,
99
+ actions,
100
+ compact = false,
101
+ isToast = false,
28
102
  glass,
29
103
  className,
30
104
  style,
31
- });
105
+ ...props
106
+ }: CalloutProps) => {
107
+ const { generateCalloutClass, handleClose } = useCallout({
108
+ variant,
109
+ compact,
110
+ isToast,
111
+ glass,
112
+ className,
113
+ style,
114
+ });
32
115
 
33
- // Determine appropriate ARIA attributes based on variant
34
- const getAriaAttributes = () => {
35
- const baseAttributes: Record<string, string> = {
36
- role: 'region',
37
- };
116
+ // Determine appropriate ARIA attributes based on variant
117
+ const getAriaAttributes = () => {
118
+ const baseAttributes: Record<string, string> = {
119
+ role: 'region',
120
+ };
38
121
 
39
- // For toast notifications or alerts, use appropriate role and live region
40
- if (isToast) {
41
- baseAttributes.role = 'alert';
42
- baseAttributes['aria-live'] = 'polite';
43
- } else if (['warning', 'error'].includes(variant)) {
44
- baseAttributes.role = 'alert';
45
- baseAttributes['aria-live'] = 'assertive';
46
- } else if (['info', 'success'].includes(variant)) {
47
- baseAttributes.role = 'status';
48
- baseAttributes['aria-live'] = 'polite';
49
- }
122
+ // For toast notifications or alerts, use appropriate role and live region
123
+ if (isToast) {
124
+ baseAttributes.role = 'alert';
125
+ baseAttributes['aria-live'] = 'polite';
126
+ } else if (['warning', 'error'].includes(variant)) {
127
+ baseAttributes.role = 'alert';
128
+ baseAttributes['aria-live'] = 'assertive';
129
+ } else if (['info', 'success'].includes(variant)) {
130
+ baseAttributes.role = 'status';
131
+ baseAttributes['aria-live'] = 'polite';
132
+ }
133
+
134
+ return baseAttributes;
135
+ };
50
136
 
51
- return baseAttributes;
52
- };
137
+ // Check for compound usage
138
+ const hasCompoundComponents = React.Children.toArray(children).some((child) =>
139
+ React.isValidElement(child) &&
140
+ [
141
+ 'CalloutIcon',
142
+ 'CalloutMessage',
143
+ 'CalloutTitle',
144
+ 'CalloutText',
145
+ 'CalloutActions',
146
+ 'CalloutContent',
147
+ ].includes((child.type as any).displayName)
148
+ );
53
149
 
54
- const calloutContent = (
55
- <>
56
- <div className="c-callout__content">
57
- {icon && <div className="c-callout__icon">{icon}</div>}
58
- <div className="c-callout__message">
59
- {title && <div className="c-callout__title">{title}</div>}
60
- {children && <div className="c-callout__text">{children}</div>}
150
+ const calloutContent = hasCompoundComponents ? (
151
+ children
152
+ ) : (
153
+ <>
154
+ <div className="c-callout__content">
155
+ {icon && <div className="c-callout__icon">{icon}</div>}
156
+ <div className="c-callout__message">
157
+ {title && <div className="c-callout__title">{title}</div>}
158
+ {children && <div className="c-callout__text">{children}</div>}
159
+ </div>
61
160
  </div>
62
- </div>
63
161
 
64
- {actions && <div className="c-callout__actions">{actions}</div>}
65
-
66
- {onClose && (
67
- <button className="c-callout__close-btn" onClick={handleClose(onClose)} aria-label="Close">
68
- <Icon name="X" size="md" />
69
- </button>
70
- )}
71
- </>
72
- );
73
-
74
- if (glass) {
75
- // Default glass settings for callouts
76
- const defaultGlassProps = {
77
- displacementScale: 30,
78
- cornerRadius: 8,
79
- elasticity: 0,
80
- };
162
+ {actions && <div className="c-callout__actions">{actions}</div>}
163
+
164
+ {onClose && (
165
+ <button
166
+ className="c-callout__close-btn"
167
+ onClick={handleClose(onClose)}
168
+ aria-label="Close"
169
+ >
170
+ <Icon name="X" size="md" />
171
+ </button>
172
+ )}
173
+ </>
174
+ );
175
+
176
+ if (glass) {
177
+ // Default glass settings for callouts
178
+ const defaultGlassProps = {
179
+ displacementScale: 30,
180
+ borderRadius: 8,
181
+ elasticity: 0,
182
+ };
183
+
184
+ const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
81
185
 
82
- const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
186
+ return (
187
+ <div
188
+ className={generateCalloutClass({ variant, compact, isToast, glass, className })}
189
+ {...getAriaAttributes()}
190
+ {...props}
191
+ style={style}
192
+ >
193
+ <AtomixGlass {...glassProps}>
194
+ <div
195
+ className="c-callout__glass-content"
196
+ style={{ borderRadius: glassProps.borderRadius }}
197
+ >
198
+ {calloutContent}
199
+ </div>
200
+ </AtomixGlass>
201
+ </div>
202
+ );
203
+ }
83
204
 
84
205
  return (
85
206
  <div
@@ -88,32 +209,23 @@ export const Callout: React.FC<CalloutProps> = ({
88
209
  {...props}
89
210
  style={style}
90
211
  >
91
- <AtomixGlass {...glassProps}>
92
- <div
93
- className="c-callout__glass-content"
94
- style={{ borderRadius: glassProps.cornerRadius }}
95
- >
96
- {calloutContent}
97
- </div>
98
- </AtomixGlass>
212
+ {calloutContent}
99
213
  </div>
100
214
  );
101
215
  }
102
-
103
- return (
104
- <div
105
- className={generateCalloutClass({ variant, compact, isToast, glass, className })}
106
- {...getAriaAttributes()}
107
- {...props}
108
- style={style}
109
- >
110
- {calloutContent}
111
- </div>
112
- );
113
- };
216
+ ) as unknown as CalloutComponent;
114
217
 
115
218
  Callout.displayName = 'Callout';
116
219
 
220
+ // Attach subcomponents
221
+ Callout.Icon = CalloutIcon;
222
+ Callout.Message = CalloutMessage;
223
+ Callout.Title = CalloutTitle;
224
+ Callout.Text = CalloutText;
225
+ Callout.Actions = CalloutActions;
226
+ Callout.CloseButton = CalloutCloseButton;
227
+ Callout.Content = CalloutContent;
228
+
117
229
  export type { CalloutProps };
118
230
 
119
231
  export default Callout;
@@ -0,0 +1,72 @@
1
+ import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { Callout } from './Callout';
4
+ import React from 'react';
5
+
6
+ describe('Callout Component', () => {
7
+ it('renders correctly with legacy props', () => {
8
+ render(
9
+ <Callout title="Legacy Title" icon={<span>Icon</span>}>
10
+ Legacy Content
11
+ </Callout>
12
+ );
13
+
14
+ expect(screen.getByText('Legacy Title')).toBeInTheDocument();
15
+ expect(screen.getByText('Legacy Content')).toBeInTheDocument();
16
+ expect(screen.getByText('Icon')).toBeInTheDocument();
17
+ });
18
+
19
+ it('renders correctly with compound components', () => {
20
+ render(
21
+ <Callout>
22
+ <Callout.Content>
23
+ <Callout.Icon>
24
+ <span>Compound Icon</span>
25
+ </Callout.Icon>
26
+ <Callout.Message>
27
+ <Callout.Title>Compound Title</Callout.Title>
28
+ <Callout.Text>Compound Text</Callout.Text>
29
+ </Callout.Message>
30
+ </Callout.Content>
31
+ <Callout.Actions>
32
+ <button>Action</button>
33
+ </Callout.Actions>
34
+ <Callout.CloseButton onClick={() => {}} />
35
+ </Callout>
36
+ );
37
+
38
+ expect(screen.getByText('Compound Icon')).toBeInTheDocument();
39
+ expect(screen.getByText('Compound Title')).toBeInTheDocument();
40
+ expect(screen.getByText('Compound Text')).toBeInTheDocument();
41
+ expect(screen.getByText('Action')).toBeInTheDocument();
42
+ expect(screen.getByLabelText('Close')).toBeInTheDocument();
43
+ });
44
+
45
+ it('prioritizes compound components over legacy props', () => {
46
+ render(
47
+ <Callout title="Legacy Title">
48
+ <Callout.Content>
49
+ <Callout.Message>
50
+ <Callout.Text>Compound Text</Callout.Text>
51
+ </Callout.Message>
52
+ </Callout.Content>
53
+ </Callout>
54
+ );
55
+
56
+ expect(screen.getByText('Compound Text')).toBeInTheDocument();
57
+ expect(screen.queryByText('Legacy Title')).not.toBeInTheDocument();
58
+ });
59
+
60
+ it('renders close button when used as compound', () => {
61
+ const onClose = vi.fn();
62
+ render(
63
+ <Callout>
64
+ <Callout.CloseButton onClick={onClose} />
65
+ </Callout>
66
+ );
67
+
68
+ const button = screen.getByLabelText('Close');
69
+ fireEvent.click(button);
70
+ expect(onClose).toHaveBeenCalled();
71
+ });
72
+ });
@@ -94,7 +94,7 @@ Glass morphism adds a modern, translucent appearance with backdrop blur effects:
94
94
  blurAmount: 2,
95
95
  saturation: 180,
96
96
  aberrationIntensity: 1.5,
97
- cornerRadius: 12
97
+ borderRadius: 12
98
98
  }}
99
99
  title="Custom Glass"
100
100
  variant="success"
@@ -113,7 +113,7 @@ When `glass={true}`, these default settings are used:
113
113
  blurAmount: 0,
114
114
  saturation: 160,
115
115
  aberrationIntensity: 1,
116
- cornerRadius: 8,
116
+ borderRadius: 8,
117
117
  overLight: false,
118
118
  mode: 'standard'
119
119
  }
@@ -250,7 +250,7 @@ export const GlassVariant: Story = {
250
250
  glass={{
251
251
  blurAmount: 0,
252
252
  saturation: 180,
253
- enableBorderEffect: true,
253
+ withBorder: true,
254
254
  }}
255
255
  showToolbar={true}
256
256
  />
@@ -278,8 +278,8 @@ const Chart = memo(
278
278
  saturation: 180,
279
279
  aberrationIntensity: 1.5,
280
280
  elasticity: 0, // No elastic effect for charts
281
- enableLiquidBlur: false, // Keep it simple
282
- enableBorderEffect: true,
281
+ withLiquidBlur: false, // Keep it simple
282
+ withBorder: true,
283
283
  mode: 'standard' as const,
284
284
  mouseContainer: chartContainerRef,
285
285
  reducedMotion: false,
@@ -300,8 +300,8 @@ const Chart = memo(
300
300
  const chartBorderRadius = useMemo(() => {
301
301
  // Use chart border-radius design token (typically 12px from $border-radius-lg)
302
302
  // AtomixGlass will extract from children if not provided
303
- return glassProps?.cornerRadius || undefined;
304
- }, [glassProps?.cornerRadius]);
303
+ return glassProps?.borderRadius || undefined;
304
+ }, [glassProps?.borderRadius]);
305
305
 
306
306
  // Create context value
307
307
  const chartContextValue = useMemo<ChartContextValue>(
@@ -404,7 +404,7 @@ const Chart = memo(
404
404
  const wrappedChart = glassProps ? (
405
405
  <AtomixGlass
406
406
  {...glassProps}
407
- cornerRadius={chartBorderRadius}
407
+ borderRadius={chartBorderRadius}
408
408
  style={{
409
409
  width: '100%',
410
410
  height: '100%',
@@ -98,21 +98,25 @@ interface TreemapChartProps extends Omit<ChartProps, 'type' | 'datasets'> {
98
98
  };
99
99
  }
100
100
 
101
+ const DEFAULT_COLOR_CONFIG: NonNullable<TreemapChartProps['colorConfig']> = { scheme: 'category' };
102
+ const DEFAULT_LABEL_CONFIG = {
103
+ showLabels: true,
104
+ minSize: 1000,
105
+ fontSize: 12,
106
+ textColor: 'white',
107
+ };
108
+ const DEFAULT_CONFIG = {};
109
+
101
110
  const TreemapChart = memo(
102
111
  forwardRef<HTMLDivElement, TreemapChartProps>(
103
112
  (
104
113
  {
105
114
  data = [],
106
115
  algorithm = 'squarified',
107
- colorConfig = { scheme: 'category' },
108
- labelConfig = {
109
- showLabels: true,
110
- minSize: 1000,
111
- fontSize: 12,
112
- textColor: 'white',
113
- },
116
+ colorConfig = DEFAULT_COLOR_CONFIG,
117
+ labelConfig = DEFAULT_LABEL_CONFIG,
114
118
  onDataPointClick,
115
- config = {},
119
+ config = DEFAULT_CONFIG,
116
120
  ...props
117
121
  },
118
122
  ref
@@ -122,9 +126,7 @@ const TreemapChart = memo(
122
126
  const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
123
127
 
124
128
  const treeData = useMemo(() => {
125
- console.log('TreemapChart data:', data);
126
129
  if (!data.length) {
127
- console.log('No data provided to TreemapChart');
128
130
  return null;
129
131
  }
130
132
 
@@ -357,16 +359,17 @@ const TreemapChart = memo(
357
359
  []
358
360
  );
359
361
 
360
- const renderContent = ({
361
- scales,
362
- colors,
363
- datasets: renderedDatasets,
364
- handlers,
365
- hoveredPoint,
366
- }: ChartRenderContentParams) => {
367
- if (!data.length) return null;
368
-
369
- // Calculate available space with padding
362
+ const renderContent = useCallback(
363
+ ({
364
+ scales,
365
+ colors,
366
+ datasets: renderedDatasets,
367
+ handlers,
368
+ hoveredPoint,
369
+ }: ChartRenderContentParams) => {
370
+ if (!data.length) return null;
371
+
372
+ // Calculate available space with padding
370
373
  const padding = 20;
371
374
  const availableWidth = scales.width - padding * 2;
372
375
  const availableHeight = scales.height - padding * 2;
@@ -467,17 +470,22 @@ const TreemapChart = memo(
467
470
  </g>
468
471
  );
469
472
  })}
470
- </>
471
- );
472
- };
473
+ </>
474
+ );
475
+ },
476
+ [data, algorithm, generateColor, squarify, labelConfig, hoveredNode, selectedNode]
477
+ );
473
478
 
474
479
  // Convert data to datasets format for BaseChart
475
- const datasets = [
476
- {
477
- label: 'Treemap Data',
478
- data: data,
479
- },
480
- ];
480
+ const datasets = useMemo(
481
+ () => [
482
+ {
483
+ label: 'Treemap Data',
484
+ data: data,
485
+ },
486
+ ],
487
+ [data]
488
+ );
481
489
 
482
490
  return (
483
491
  <BaseChart
@@ -152,7 +152,7 @@ const CustomGlassExample = () => {
152
152
  blurAmount: 0,
153
153
  saturation: 180,
154
154
  aberrationIntensity: 2,
155
- cornerRadius: 16,
155
+ borderRadius: 16,
156
156
  overLight: false,
157
157
  mode: 'polar',
158
158
  }}
@@ -184,7 +184,7 @@ const GlassRangeExample = () => {
184
184
  blurAmount: 0,
185
185
  saturation: 160,
186
186
  aberrationIntensity: 1.5,
187
- cornerRadius: 14,
187
+ borderRadius: 14,
188
188
  mode: 'prominent',
189
189
  }}
190
190
  />
@@ -203,7 +203,7 @@ When `glass` is an object, it accepts the same props as the `AtomixGlass` compon
203
203
  | `blurAmount` | `number` | `0` | Blur amount for the backdrop |
204
204
  | `saturation` | `number` | `160` | Saturation percentage for the backdrop |
205
205
  | `aberrationIntensity` | `number` | `1.5` | Chromatic aberration intensity |
206
- | `cornerRadius` | `number` | `12` | Corner radius in pixels |
206
+ | `borderRadius` | `number` | `12` | Corner radius in pixels |
207
207
  | `overLight` | `boolean` | `false` | Whether the glass is over a light background |
208
208
  | `mode` | `'standard' \| 'polar' \| 'prominent' \| 'shader'` | `'standard'` | Glass effect mode |
209
209
 
@@ -505,7 +505,7 @@ export const GlassDropdownCustom: Story = {
505
505
  blurAmount: 2,
506
506
  saturation: 200,
507
507
  aberrationIntensity: 1,
508
- cornerRadius: 16,
508
+ borderRadius: 16,
509
509
  mode: 'polar',
510
510
  },
511
511
  },