@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.
- package/dist/atomix.css +0 -14
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +4 -4
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.d.ts +12 -19
- package/dist/charts.js +555 -359
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +98 -28
- package/dist/core.js +1082 -733
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +26 -21
- package/dist/forms.js +937 -350
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +14 -21
- package/dist/heavy.js +409 -256
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +518 -284
- package/dist/index.esm.js +1993 -1237
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1994 -1237
- 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 +2 -2
- package/scripts/atomix-cli.js +43 -1
- package/scripts/cli/__tests__/utils.test.js +6 -2
- package/scripts/cli/migration-tools.js +2 -2
- package/scripts/cli/theme-bridge.js +7 -9
- package/scripts/cli/utils.js +2 -1
- package/src/components/Accordion/Accordion.stories.tsx +40 -0
- package/src/components/Accordion/Accordion.tsx +174 -56
- package/src/components/Accordion/AccordionCompound.test.tsx +70 -0
- package/src/components/AtomixGlass/AtomixGlass.tsx +82 -54
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +17 -18
- package/src/components/AtomixGlass/README.md +5 -5
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +2 -2
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +42 -42
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +5 -5
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +3 -3
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +2 -2
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +45 -45
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +3 -3
- package/src/components/Badge/Badge.stories.tsx +1 -1
- package/src/components/Badge/Badge.tsx +1 -1
- package/src/components/Breadcrumb/Breadcrumb.tsx +185 -65
- package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +84 -0
- package/src/components/Breadcrumb/index.ts +2 -2
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Button/README.md +2 -2
- package/src/components/Callout/Callout.stories.tsx +166 -1011
- package/src/components/Callout/Callout.test.tsx +3 -3
- package/src/components/Callout/Callout.tsx +196 -84
- package/src/components/Callout/CalloutCompound.test.tsx +72 -0
- package/src/components/Callout/README.md +2 -2
- package/src/components/Chart/Chart.stories.tsx +1 -1
- package/src/components/Chart/Chart.tsx +5 -5
- package/src/components/Chart/TreemapChart.tsx +37 -29
- package/src/components/DatePicker/readme.md +3 -3
- package/src/components/Dropdown/Dropdown.stories.tsx +1 -1
- package/src/components/Dropdown/Dropdown.tsx +133 -20
- package/src/components/Dropdown/DropdownCompound.test.tsx +64 -0
- package/src/components/EdgePanel/EdgePanel.stories.tsx +7 -7
- package/src/components/EdgePanel/EdgePanel.tsx +164 -112
- package/src/components/EdgePanel/EdgePanelCompound.test.tsx +53 -0
- package/src/components/Form/Checkbox.stories.tsx +1 -1
- package/src/components/Form/Checkbox.tsx +1 -1
- package/src/components/Form/Input.stories.tsx +1 -1
- package/src/components/Form/Input.tsx +1 -1
- package/src/components/Form/Radio.stories.tsx +1 -1
- package/src/components/Form/Radio.tsx +1 -1
- package/src/components/Form/Select.stories.tsx +24 -1
- package/src/components/Form/Select.test.tsx +99 -0
- package/src/components/Form/Select.tsx +145 -94
- package/src/components/Form/SelectOption.tsx +88 -0
- package/src/components/Form/Textarea.stories.tsx +1 -1
- package/src/components/Form/Textarea.tsx +1 -1
- package/src/components/Hero/Hero.stories.tsx +39 -2
- package/src/components/Hero/Hero.test.tsx +142 -0
- package/src/components/Hero/Hero.tsx +143 -4
- package/src/components/List/List.test.tsx +62 -0
- package/src/components/List/List.tsx +16 -5
- package/src/components/List/ListItem.tsx +20 -0
- package/src/components/Messages/Messages.stories.tsx +1 -1
- package/src/components/Messages/Messages.tsx +2 -2
- package/src/components/Modal/Modal.stories.tsx +66 -2
- package/src/components/Modal/Modal.tsx +115 -35
- package/src/components/Modal/ModalCompound.test.tsx +94 -0
- package/src/components/Navigation/Nav/Nav.stories.tsx +2 -2
- package/src/components/Navigation/Nav/Nav.tsx +1 -1
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +3 -3
- package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +2 -2
- package/src/components/Navigation/SideMenu/SideMenu.tsx +1 -1
- package/src/components/Pagination/Pagination.stories.tsx +1 -1
- package/src/components/Pagination/Pagination.tsx +1 -1
- package/src/components/Popover/Popover.stories.tsx +1 -1
- package/src/components/Popover/Popover.tsx +1 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/Rating/Rating.stories.tsx +1 -1
- package/src/components/Rating/Rating.test.tsx +73 -0
- package/src/components/Rating/Rating.tsx +25 -37
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Steps/Steps.stories.tsx +1 -1
- package/src/components/Steps/Steps.tsx +125 -22
- package/src/components/Steps/StepsCompound.test.tsx +81 -0
- package/src/components/Tabs/Tabs.stories.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +198 -45
- package/src/components/Tabs/TabsCompound.test.tsx +64 -0
- package/src/components/Todo/Todo.tsx +0 -1
- package/src/components/Toggle/Toggle.stories.tsx +1 -1
- package/src/components/Toggle/Toggle.tsx +1 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +1 -1
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +2 -2
- package/src/lib/composables/__tests__/useAtomixGlassPerf.test.tsx +88 -0
- package/src/lib/composables/__tests__/useChart.test.ts +50 -0
- package/src/lib/composables/__tests__/useChart.test.tsx +139 -0
- package/src/lib/composables/__tests__/useHeroBackgroundSlider.test.tsx +59 -0
- package/src/lib/composables/__tests__/useSliderAutoplay.test.tsx +68 -0
- package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +329 -0
- package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +82 -0
- package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +153 -0
- package/src/lib/composables/atomix-glass/useGlassOverLight.ts +198 -0
- package/src/lib/composables/atomix-glass/useGlassSize.ts +117 -0
- package/src/lib/composables/atomix-glass/useGlassState.ts +112 -0
- package/src/lib/composables/atomix-glass/useGlassTransforms.ts +160 -0
- package/src/lib/composables/glass-styles.ts +302 -0
- package/src/lib/composables/index.ts +0 -8
- package/src/lib/composables/useAtomixGlass.ts +331 -537
- package/src/lib/composables/useAtomixGlassStyles.ts +307 -0
- package/src/lib/composables/useBarChart.ts +1 -1
- package/src/lib/composables/useBreadcrumb.ts +6 -6
- package/src/lib/composables/useChart.ts +104 -21
- package/src/lib/composables/useHeroBackgroundSlider.ts +16 -7
- package/src/lib/composables/useSlider.ts +66 -34
- package/src/lib/theme/devtools/CLI.ts +2 -10
- package/src/lib/theme/utils/__tests__/themeUtils.test.ts +213 -0
- package/src/lib/types/components.ts +21 -23
- package/src/lib/utils/__tests__/componentUtils.test.ts +57 -2
- package/src/lib/utils/__tests__/dom.test.ts +100 -0
- package/src/lib/utils/__tests__/fontPreloader.test.ts +102 -0
- package/src/lib/utils/__tests__/themeNaming.test.ts +117 -0
- package/src/lib/utils/themeNaming.ts +1 -1
- package/src/styles/06-components/_components.accordion.scss +0 -2
- package/src/styles/06-components/_components.chart.scss +0 -1
- package/src/styles/06-components/_components.dropdown.scss +0 -1
- package/src/styles/06-components/_components.edge-panel.scss +0 -2
- package/src/styles/06-components/_components.photoviewer.scss +0 -1
- package/src/styles/06-components/_components.river.scss +0 -1
- package/src/styles/06-components/_components.slider.scss +0 -3
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
variant,
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<div className="c-
|
|
59
|
-
{
|
|
60
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
116
|
+
borderRadius: 8,
|
|
117
117
|
overLight: false,
|
|
118
118
|
mode: 'standard'
|
|
119
119
|
}
|
|
@@ -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
|
-
|
|
282
|
-
|
|
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?.
|
|
304
|
-
}, [glassProps?.
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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
|
-
|
|
478
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
| `
|
|
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
|
|