@shohojdhara/atomix 0.3.15 → 0.4.0
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/build-tools/index.d.ts +31 -30
- package/build-tools/package.json +4 -21
- package/dist/atomix.css +20924 -2611
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +76 -2
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/index.d.ts +31 -30
- package/dist/build-tools/package.json +4 -21
- package/dist/charts.js.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +144 -18
- package/dist/index.esm.js +110 -55
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +110 -55
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.js.map +1 -1
- package/dist/theme.d.ts +9 -9
- package/dist/theme.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +32 -23
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +99 -94
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
- package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
- package/src/components/AtomixGlass/glass-utils.ts +4 -3
- package/src/components/AtomixGlass/shader-utils.ts +128 -52
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +1 -1
- package/src/components/Avatar/Avatar.stories.tsx +45 -62
- package/src/components/Avatar/Avatar.tsx +58 -56
- package/src/components/Badge/Badge.stories.tsx +20 -9
- package/src/components/Badge/Badge.test.tsx +41 -41
- package/src/components/Badge/Badge.tsx +64 -62
- package/src/components/Block/Block.stories.tsx +14 -4
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +9 -8
- package/src/components/Breadcrumb/Breadcrumb.tsx +62 -60
- package/src/components/Button/Button.stories.tsx +13 -22
- package/src/components/Button/Button.test.tsx +97 -81
- package/src/components/Button/Button.tsx +46 -14
- package/src/components/Button/ButtonGroup.stories.tsx +37 -32
- package/src/components/Button/ButtonGroup.tsx +4 -15
- package/src/components/Callout/Callout.stories.tsx +109 -16
- package/src/components/Card/Card.stories.tsx +67 -36
- package/src/components/Card/Card.tsx +30 -14
- package/src/components/Chart/AreaChart.tsx +1 -1
- package/src/components/Chart/CandlestickChart.tsx +23 -16
- package/src/components/Chart/Chart.stories.tsx +4 -9
- package/src/components/Chart/Chart.tsx +40 -44
- package/src/components/Chart/ChartRenderer.tsx +39 -12
- package/src/components/Chart/ChartToolbar.tsx +21 -5
- package/src/components/Chart/DonutChart.tsx +1 -1
- package/src/components/Chart/FunnelChart.tsx +4 -1
- package/src/components/Chart/GaugeChart.tsx +3 -1
- package/src/components/Chart/HeatmapChart.tsx +50 -37
- package/src/components/Chart/LineChart.tsx +3 -2
- package/src/components/Chart/MultiAxisChart.tsx +24 -16
- package/src/components/Chart/RadarChart.tsx +19 -17
- package/src/components/Chart/ScatterChart.tsx +29 -21
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +6 -2
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
- package/src/components/Countdown/Countdown.stories.tsx +7 -7
- package/src/components/DataTable/DataTable.stories.tsx +43 -38
- package/src/components/DataTable/DataTable.test.tsx +26 -148
- package/src/components/DataTable/DataTable.tsx +485 -456
- package/src/components/DatePicker/DatePicker.stories.tsx +32 -47
- package/src/components/DatePicker/DatePicker.tsx +31 -26
- package/src/components/Dropdown/Dropdown.stories.tsx +2 -5
- package/src/components/Dropdown/Dropdown.tsx +313 -299
- package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Footer/Footer.stories.tsx +21 -16
- package/src/components/Footer/Footer.tsx +130 -128
- package/src/components/Footer/FooterLink.tsx +2 -2
- package/src/components/Form/Checkbox.test.tsx +49 -49
- package/src/components/Form/Checkbox.tsx +108 -100
- package/src/components/Form/Form.stories.tsx +2 -10
- package/src/components/Form/Input.stories.tsx +22 -39
- package/src/components/Form/Input.test.tsx +38 -44
- package/src/components/Form/Radio.stories.tsx +6 -12
- package/src/components/Form/Radio.tsx +68 -66
- package/src/components/Form/Select.tsx +184 -182
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +56 -23
- package/src/components/Hero/Hero.tsx +201 -55
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.tsx +19 -23
- package/src/components/Modal/Modal.stories.tsx +2 -1
- package/src/components/Modal/Modal.tsx +130 -127
- package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
- package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
- package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
- package/src/components/Pagination/Pagination.stories.tsx +7 -4
- package/src/components/Pagination/Pagination.tsx +199 -202
- package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
- package/src/components/Popover/Popover.stories.tsx +99 -192
- package/src/components/Popover/Popover.tsx +41 -37
- package/src/components/Progress/Progress.stories.tsx +35 -44
- package/src/components/River/River.stories.tsx +2 -1
- package/src/components/SectionIntro/SectionIntro.stories.tsx +71 -71
- package/src/components/Slider/Slider.stories.tsx +12 -4
- package/src/components/Spinner/Spinner.stories.tsx +3 -1
- package/src/components/Spinner/Spinner.test.tsx +23 -23
- package/src/components/Spinner/Spinner.tsx +43 -46
- package/src/components/Steps/Steps.stories.tsx +8 -6
- package/src/components/Tabs/Tabs.stories.tsx +12 -9
- package/src/components/Tabs/Tabs.tsx +74 -72
- package/src/components/Toggle/Toggle.stories.tsx +27 -13
- package/src/components/Toggle/Toggle.test.tsx +65 -70
- package/src/components/Toggle/Toggle.tsx +4 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +24 -20
- package/src/components/Tooltip/Tooltip.tsx +104 -106
- package/src/components/Upload/Upload.stories.tsx +129 -127
- package/src/components/Upload/Upload.tsx +287 -283
- package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
- package/src/components/index.ts +13 -2
- package/src/layouts/Grid/Grid.stories.tsx +9 -3
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
- package/src/lib/__tests__/theme-tools.test.ts +32 -6
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +106 -49
- package/src/lib/composables/useChartExport.ts +1 -1
- package/src/lib/composables/useDataTable.ts +29 -17
- package/src/lib/composables/useHero.ts +58 -14
- package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
- package/src/lib/composables/useInput.ts +10 -8
- package/src/lib/composables/useSideMenu.ts +6 -5
- package/src/lib/composables/useTooltip.ts +1 -2
- package/src/lib/composables/useVideoPlayer.ts +44 -35
- package/src/lib/config/index.ts +154 -154
- package/src/lib/constants/cssVariables.ts +29 -29
- package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
- package/src/lib/hooks/index.ts +1 -1
- package/src/lib/hooks/useComponentCustomization.ts +11 -17
- package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
- package/src/lib/patterns/__tests__/slots.test.ts +1 -1
- package/src/lib/patterns/index.ts +1 -1
- package/src/lib/patterns/slots.tsx +8 -13
- package/src/lib/storybook/InteractiveDemo.tsx +13 -18
- package/src/lib/storybook/PreviewContainer.tsx +1 -1
- package/src/lib/storybook/VariantsGrid.tsx +3 -7
- package/src/lib/storybook/index.ts +1 -1
- package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
- package/src/lib/theme/adapters/index.ts +3 -9
- package/src/lib/theme/adapters/themeAdapter.ts +41 -26
- package/src/lib/theme/config/index.ts +1 -1
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +10 -5
- package/src/lib/theme/constants/constants.ts +2 -2
- package/src/lib/theme/constants/index.ts +1 -2
- package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
- package/src/lib/theme/core/composeTheme.ts +32 -26
- package/src/lib/theme/core/createTheme.ts +1 -1
- package/src/lib/theme/core/createThemeObject.ts +308 -301
- package/src/lib/theme/core/index.ts +3 -3
- package/src/lib/theme/devtools/CLI.ts +106 -104
- package/src/lib/theme/devtools/Comparator.tsx +50 -32
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
- package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
- package/src/lib/theme/devtools/Inspector.tsx +75 -60
- package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
- package/src/lib/theme/devtools/Preview.tsx +150 -106
- package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
- package/src/lib/theme/devtools/index.ts +3 -9
- package/src/lib/theme/devtools/useHistory.ts +23 -21
- package/src/lib/theme/errors/errors.ts +12 -11
- package/src/lib/theme/errors/index.ts +2 -7
- package/src/lib/theme/generators/generateCSS.ts +9 -13
- package/src/lib/theme/generators/generateCSSNested.ts +1 -6
- package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
- package/src/lib/theme/generators/index.ts +1 -4
- package/src/lib/theme/i18n/index.ts +1 -1
- package/src/lib/theme/i18n/rtl.ts +13 -13
- package/src/lib/theme/index.ts +7 -16
- package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
- package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
- package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
- package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
- package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
- package/src/lib/theme/runtime/index.ts +2 -5
- package/src/lib/theme/runtime/useTheme.ts +18 -18
- package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
- package/src/lib/theme/test/testTheme.ts +15 -16
- package/src/lib/theme/tokens/index.ts +2 -7
- package/src/lib/theme/tokens/tokens.ts +25 -24
- package/src/lib/theme/types.ts +428 -411
- package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
- package/src/lib/theme/utils/componentTheming.ts +18 -18
- package/src/lib/theme/utils/domUtils.ts +277 -289
- package/src/lib/theme/utils/index.ts +1 -2
- package/src/lib/theme/utils/injectCSS.ts +10 -14
- package/src/lib/theme/utils/naming.ts +20 -16
- package/src/lib/theme/utils/themeHelpers.ts +10 -12
- package/src/lib/theme/utils/themeUtils.ts +85 -86
- package/src/lib/theme/utils/themeValidation.ts +82 -33
- package/src/lib/theme-tools.ts +8 -6
- package/src/lib/types/components.ts +172 -71
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/csv.test.ts +1 -1
- package/src/lib/utils/componentUtils.ts +8 -12
- package/src/lib/utils/csv.ts +3 -1
- package/src/lib/utils/dataTableExport.ts +1 -5
- package/src/lib/utils/fontPreloader.ts +10 -19
- package/src/lib/utils/icons.ts +4 -1
- package/src/lib/utils/index.ts +2 -6
- package/src/lib/utils/memoryMonitor.ts +10 -8
- package/src/lib/utils/themeNaming.ts +2 -2
- package/src/styles/01-settings/_index.scss +0 -1
- package/src/styles/01-settings/_settings.colors.scss +8 -8
- package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
- package/src/styles/01-settings/_settings.navbar.scss +1 -1
- package/src/styles/01-settings/_settings.spacing.scss +3 -4
- package/src/styles/01-settings/_settings.tooltip.scss +1 -1
- package/src/styles/01-settings/_settings.typography.scss +1 -1
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +30 -18
- package/src/styles/03-generic/_generic.root.scss +4 -3
- package/src/styles/06-components/_components.atomix-glass.scss +13 -9
- package/src/styles/06-components/_components.button.scss +16 -4
- package/src/styles/06-components/_components.callout.scss +27 -21
- package/src/styles/06-components/_components.card.scss +5 -14
- package/src/styles/06-components/_components.chart.scss +22 -19
- package/src/styles/06-components/_components.checkbox.scss +3 -1
- package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
- package/src/styles/06-components/_components.edge-panel.scss +9 -2
- package/src/styles/06-components/_components.footer.scss +1 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -5
- package/src/styles/06-components/_components.toggle.scss +18 -0
- package/src/styles/06-components/_index.scss +1 -1
- package/src/styles/06-components/old.chart.styles.scss +0 -2
- package/src/styles/99-utilities/_utilities.border.scss +69 -27
- package/src/styles/99-utilities/_utilities.display.scss +1 -1
- package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
- package/src/styles/99-utilities/_utilities.position.scss +16 -9
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
- package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
- package/src/styles/99-utilities/_utilities.text-gradient.scss +30 -30
- package/src/styles/99-utilities/_utilities.text.scss +67 -46
|
@@ -39,7 +39,7 @@ const smoothStep = (a: number, b: number, t: number): number => {
|
|
|
39
39
|
if (typeof a !== 'number' || typeof b !== 'number' || typeof t !== 'number') {
|
|
40
40
|
return 0;
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
|
|
44
44
|
return clamped * clamped * (3 - 2 * clamped);
|
|
45
45
|
};
|
|
@@ -49,11 +49,11 @@ const calculateLength = (x: number, y: number): number => {
|
|
|
49
49
|
if (typeof x !== 'number' || typeof y !== 'number' || isNaN(x) || isNaN(y)) {
|
|
50
50
|
return 0;
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
// Prevent potential overflow
|
|
54
54
|
const maxX = Math.max(Math.abs(x), Math.abs(y));
|
|
55
55
|
if (maxX === 0) return 0;
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
const scaledX = x / maxX;
|
|
58
58
|
const scaledY = y / maxX;
|
|
59
59
|
return maxX * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
|
|
@@ -67,12 +67,16 @@ const roundedRectSDF = (
|
|
|
67
67
|
radius: number
|
|
68
68
|
): number => {
|
|
69
69
|
// Add input validation
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
if (
|
|
71
|
+
typeof x !== 'number' ||
|
|
72
|
+
typeof y !== 'number' ||
|
|
73
|
+
typeof width !== 'number' ||
|
|
74
|
+
typeof height !== 'number' ||
|
|
75
|
+
typeof radius !== 'number'
|
|
76
|
+
) {
|
|
73
77
|
return 0;
|
|
74
78
|
}
|
|
75
|
-
|
|
79
|
+
|
|
76
80
|
const qx = Math.abs(x) - width + radius;
|
|
77
81
|
const qy = Math.abs(y) - height + radius;
|
|
78
82
|
return Math.min(Math.max(qx, qy), 0) + calculateLength(Math.max(qx, 0), Math.max(qy, 0)) - radius;
|
|
@@ -97,11 +101,11 @@ const clampValue = (value: number, min: number, max: number): number => {
|
|
|
97
101
|
if (typeof value !== 'number' || typeof min !== 'number' || typeof max !== 'number') {
|
|
98
102
|
return min;
|
|
99
103
|
}
|
|
100
|
-
|
|
104
|
+
|
|
101
105
|
if (isNaN(value)) return min;
|
|
102
106
|
if (isNaN(min)) return 0;
|
|
103
107
|
if (isNaN(max)) return 1;
|
|
104
|
-
|
|
108
|
+
|
|
105
109
|
return Math.max(min, Math.min(max, value));
|
|
106
110
|
};
|
|
107
111
|
|
|
@@ -111,9 +115,11 @@ const easeInOutCubic = (t: number): number => {
|
|
|
111
115
|
if (typeof t !== 'number' || isNaN(t)) {
|
|
112
116
|
return 0;
|
|
113
117
|
}
|
|
114
|
-
|
|
118
|
+
|
|
115
119
|
const clampedT = Math.max(0, Math.min(1, t));
|
|
116
|
-
return clampedT < 0.5
|
|
120
|
+
return clampedT < 0.5
|
|
121
|
+
? 4 * clampedT * clampedT * clampedT
|
|
122
|
+
: 1 - Math.pow(-2 * clampedT + 2, 3) / 2;
|
|
117
123
|
};
|
|
118
124
|
|
|
119
125
|
const easeOutQuart = (t: number): number => {
|
|
@@ -121,7 +127,7 @@ const easeOutQuart = (t: number): number => {
|
|
|
121
127
|
if (typeof t !== 'number' || isNaN(t)) {
|
|
122
128
|
return 0;
|
|
123
129
|
}
|
|
124
|
-
|
|
130
|
+
|
|
125
131
|
const clampedT = Math.max(0, Math.min(1, t));
|
|
126
132
|
return 1 - Math.pow(1 - clampedT, 4);
|
|
127
133
|
};
|
|
@@ -132,7 +138,7 @@ const noise2D = (x: number, y: number): number => {
|
|
|
132
138
|
if (typeof x !== 'number' || typeof y !== 'number' || isNaN(x) || isNaN(y)) {
|
|
133
139
|
return 0;
|
|
134
140
|
}
|
|
135
|
-
|
|
141
|
+
|
|
136
142
|
const X = Math.floor(x) & 255;
|
|
137
143
|
const Y = Math.floor(y) & 255;
|
|
138
144
|
|
|
@@ -148,7 +154,7 @@ const noise2D = (x: number, y: number): number => {
|
|
|
148
154
|
if (typeof i !== 'number' || typeof j !== 'number') {
|
|
149
155
|
return 0;
|
|
150
156
|
}
|
|
151
|
-
|
|
157
|
+
|
|
152
158
|
const n = i + j * 57;
|
|
153
159
|
// Use a more stable hash function
|
|
154
160
|
const hashed = Math.sin(n * 12.9898 + 78.233) * 43758.5453;
|
|
@@ -172,10 +178,10 @@ const fbm = (x: number, y: number, octaves: number = 4): number => {
|
|
|
172
178
|
if (typeof x !== 'number' || typeof y !== 'number' || isNaN(x) || isNaN(y)) {
|
|
173
179
|
return 0;
|
|
174
180
|
}
|
|
175
|
-
|
|
181
|
+
|
|
176
182
|
// Clamp octaves to prevent performance issues
|
|
177
183
|
const clampedOctaves = Math.max(1, Math.min(8, Math.floor(octaves)));
|
|
178
|
-
|
|
184
|
+
|
|
179
185
|
let value = 0;
|
|
180
186
|
let amplitude = 0.5;
|
|
181
187
|
let frequency = 1;
|
|
@@ -192,11 +198,17 @@ const fbm = (x: number, y: number, octaves: number = 4): number => {
|
|
|
192
198
|
// Radial distortion for glass-like refraction
|
|
193
199
|
const calculateRadialDistortion = (x: number, y: number, strength: number): Vec2 => {
|
|
194
200
|
// Add input validation
|
|
195
|
-
if (
|
|
196
|
-
|
|
201
|
+
if (
|
|
202
|
+
typeof x !== 'number' ||
|
|
203
|
+
typeof y !== 'number' ||
|
|
204
|
+
typeof strength !== 'number' ||
|
|
205
|
+
isNaN(x) ||
|
|
206
|
+
isNaN(y) ||
|
|
207
|
+
isNaN(strength)
|
|
208
|
+
) {
|
|
197
209
|
return { x: 0, y: 0 };
|
|
198
210
|
}
|
|
199
|
-
|
|
211
|
+
|
|
200
212
|
const distance = calculateLength(x, y);
|
|
201
213
|
const distortion = Math.pow(Math.min(distance, 10), 2) * strength; // Limit distance to prevent extreme values
|
|
202
214
|
|
|
@@ -209,17 +221,23 @@ const calculateRadialDistortion = (x: number, y: number, strength: number): Vec2
|
|
|
209
221
|
// Chromatic aberration calculation
|
|
210
222
|
const calculateChromaticOffset = (x: number, y: number, intensity: number): Vec2 => {
|
|
211
223
|
// Add input validation
|
|
212
|
-
if (
|
|
213
|
-
|
|
224
|
+
if (
|
|
225
|
+
typeof x !== 'number' ||
|
|
226
|
+
typeof y !== 'number' ||
|
|
227
|
+
typeof intensity !== 'number' ||
|
|
228
|
+
isNaN(x) ||
|
|
229
|
+
isNaN(y) ||
|
|
230
|
+
isNaN(intensity)
|
|
231
|
+
) {
|
|
214
232
|
return { x: 0, y: 0 };
|
|
215
233
|
}
|
|
216
|
-
|
|
234
|
+
|
|
217
235
|
const distance = calculateLength(x, y);
|
|
218
236
|
// Prevent division by zero and extreme values
|
|
219
237
|
if (distance === 0) {
|
|
220
238
|
return { x: 0, y: 0 };
|
|
221
239
|
}
|
|
222
|
-
|
|
240
|
+
|
|
223
241
|
const angle = Math.atan2(y, x);
|
|
224
242
|
|
|
225
243
|
return {
|
|
@@ -231,11 +249,19 @@ const calculateChromaticOffset = (x: number, y: number, intensity: number): Vec2
|
|
|
231
249
|
// Advanced caustic pattern generator for glass refraction
|
|
232
250
|
const calculateCaustics = (x: number, y: number, time: number, intensity: number = 1): number => {
|
|
233
251
|
// Add input validation
|
|
234
|
-
if (
|
|
235
|
-
|
|
252
|
+
if (
|
|
253
|
+
typeof x !== 'number' ||
|
|
254
|
+
typeof y !== 'number' ||
|
|
255
|
+
typeof time !== 'number' ||
|
|
256
|
+
typeof intensity !== 'number' ||
|
|
257
|
+
isNaN(x) ||
|
|
258
|
+
isNaN(y) ||
|
|
259
|
+
isNaN(time) ||
|
|
260
|
+
isNaN(intensity)
|
|
261
|
+
) {
|
|
236
262
|
return 0.5; // Return middle value on error
|
|
237
263
|
}
|
|
238
|
-
|
|
264
|
+
|
|
239
265
|
const scale = 8;
|
|
240
266
|
const speed = 2;
|
|
241
267
|
|
|
@@ -263,15 +289,23 @@ const calculateSpectralDispersion = (
|
|
|
263
289
|
intensity: number
|
|
264
290
|
): { r: Vec2; g: Vec2; b: Vec2 } => {
|
|
265
291
|
// Add input validation
|
|
266
|
-
if (
|
|
267
|
-
|
|
292
|
+
if (
|
|
293
|
+
typeof x !== 'number' ||
|
|
294
|
+
typeof y !== 'number' ||
|
|
295
|
+
typeof angle !== 'number' ||
|
|
296
|
+
typeof intensity !== 'number' ||
|
|
297
|
+
isNaN(x) ||
|
|
298
|
+
isNaN(y) ||
|
|
299
|
+
isNaN(angle) ||
|
|
300
|
+
isNaN(intensity)
|
|
301
|
+
) {
|
|
268
302
|
return {
|
|
269
303
|
r: { x: 0, y: 0 },
|
|
270
304
|
g: { x: 0, y: 0 },
|
|
271
|
-
b: { x: 0, y: 0 }
|
|
305
|
+
b: { x: 0, y: 0 },
|
|
272
306
|
};
|
|
273
307
|
}
|
|
274
|
-
|
|
308
|
+
|
|
275
309
|
const distance = calculateLength(x, y);
|
|
276
310
|
const dispersionStrength = Math.min(distance * intensity, 1); // Limit strength to prevent extreme values
|
|
277
311
|
|
|
@@ -305,12 +339,21 @@ const calculateParallaxOffset = (
|
|
|
305
339
|
mouseY: number = 0
|
|
306
340
|
): Vec2 => {
|
|
307
341
|
// Add input validation
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
|
|
342
|
+
if (
|
|
343
|
+
typeof x !== 'number' ||
|
|
344
|
+
typeof y !== 'number' ||
|
|
345
|
+
typeof depth !== 'number' ||
|
|
346
|
+
typeof mouseX !== 'number' ||
|
|
347
|
+
typeof mouseY !== 'number' ||
|
|
348
|
+
isNaN(x) ||
|
|
349
|
+
isNaN(y) ||
|
|
350
|
+
isNaN(depth) ||
|
|
351
|
+
isNaN(mouseX) ||
|
|
352
|
+
isNaN(mouseY)
|
|
353
|
+
) {
|
|
311
354
|
return { x: 0, y: 0 };
|
|
312
355
|
}
|
|
313
|
-
|
|
356
|
+
|
|
314
357
|
const parallaxStrength = Math.min(0.02 * depth, 0.1); // Limit strength to prevent extreme values
|
|
315
358
|
|
|
316
359
|
// Calculate offset based on view angle (simulated by mouse position)
|
|
@@ -323,11 +366,19 @@ const calculateParallaxOffset = (
|
|
|
323
366
|
// Volumetric density for depth perception and scattering
|
|
324
367
|
const calculateVolumetricDensity = (x: number, y: number, depth: number, time: number): number => {
|
|
325
368
|
// Add input validation
|
|
326
|
-
if (
|
|
327
|
-
|
|
369
|
+
if (
|
|
370
|
+
typeof x !== 'number' ||
|
|
371
|
+
typeof y !== 'number' ||
|
|
372
|
+
typeof depth !== 'number' ||
|
|
373
|
+
typeof time !== 'number' ||
|
|
374
|
+
isNaN(x) ||
|
|
375
|
+
isNaN(y) ||
|
|
376
|
+
isNaN(depth) ||
|
|
377
|
+
isNaN(time)
|
|
378
|
+
) {
|
|
328
379
|
return 0.5; // Return middle value on error
|
|
329
380
|
}
|
|
330
|
-
|
|
381
|
+
|
|
331
382
|
const noiseValue = fbm(x * 5 + time * 0.5, y * 5 - time * 0.5, 3);
|
|
332
383
|
const depthFalloff = Math.exp(-Math.max(0, depth) * 2); // Ensure depth is not negative
|
|
333
384
|
|
|
@@ -337,14 +388,22 @@ const calculateVolumetricDensity = (x: number, y: number, depth: number, time: n
|
|
|
337
388
|
// Advanced turbulence for organic glass distortion
|
|
338
389
|
const calculateTurbulence = (x: number, y: number, time: number, octaves: number = 5): number => {
|
|
339
390
|
// Add input validation
|
|
340
|
-
if (
|
|
341
|
-
|
|
391
|
+
if (
|
|
392
|
+
typeof x !== 'number' ||
|
|
393
|
+
typeof y !== 'number' ||
|
|
394
|
+
typeof time !== 'number' ||
|
|
395
|
+
typeof octaves !== 'number' ||
|
|
396
|
+
isNaN(x) ||
|
|
397
|
+
isNaN(y) ||
|
|
398
|
+
isNaN(time) ||
|
|
399
|
+
isNaN(octaves)
|
|
400
|
+
) {
|
|
342
401
|
return 0;
|
|
343
402
|
}
|
|
344
|
-
|
|
403
|
+
|
|
345
404
|
// Clamp octaves to prevent performance issues
|
|
346
405
|
const clampedOctaves = Math.max(1, Math.min(8, Math.floor(octaves)));
|
|
347
|
-
|
|
406
|
+
|
|
348
407
|
let turbulence = 0;
|
|
349
408
|
let amplitude = 1;
|
|
350
409
|
let frequency = 1;
|
|
@@ -362,11 +421,17 @@ const calculateTurbulence = (x: number, y: number, time: number, octaves: number
|
|
|
362
421
|
// Micro-surface detail for high-quality glass texture
|
|
363
422
|
const calculateMicroSurface = (x: number, y: number, time: number): number => {
|
|
364
423
|
// Add input validation
|
|
365
|
-
if (
|
|
366
|
-
|
|
424
|
+
if (
|
|
425
|
+
typeof x !== 'number' ||
|
|
426
|
+
typeof y !== 'number' ||
|
|
427
|
+
typeof time !== 'number' ||
|
|
428
|
+
isNaN(x) ||
|
|
429
|
+
isNaN(y) ||
|
|
430
|
+
isNaN(time)
|
|
431
|
+
) {
|
|
367
432
|
return 0.5; // Return middle value on error
|
|
368
433
|
}
|
|
369
|
-
|
|
434
|
+
|
|
370
435
|
const highFreqNoise = fbm(x * 40 + time * 0.3, y * 40 - time * 0.3, 6);
|
|
371
436
|
const microDetail = fbm(x * 80, y * 80, 4);
|
|
372
437
|
|
|
@@ -742,12 +807,20 @@ export class ShaderDisplacementGenerator {
|
|
|
742
807
|
|
|
743
808
|
this.canvas = document.createElement('canvas');
|
|
744
809
|
// Enhanced validation for canvas dimensions
|
|
745
|
-
this.canvas.width = Math.max(
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
810
|
+
this.canvas.width = Math.max(
|
|
811
|
+
MIN_CANVAS_DIMENSION,
|
|
812
|
+
Math.min(
|
|
813
|
+
MAX_CANVAS_DIMENSION,
|
|
814
|
+
Math.round(options.width * this.canvasDPI || DEFAULT_CANVAS_WIDTH)
|
|
815
|
+
)
|
|
816
|
+
);
|
|
817
|
+
this.canvas.height = Math.max(
|
|
818
|
+
MIN_CANVAS_DIMENSION,
|
|
819
|
+
Math.min(
|
|
820
|
+
MAX_CANVAS_DIMENSION,
|
|
821
|
+
Math.round(options.height * this.canvasDPI || DEFAULT_CANVAS_HEIGHT)
|
|
822
|
+
)
|
|
823
|
+
);
|
|
751
824
|
this.canvas.style.display = 'none';
|
|
752
825
|
|
|
753
826
|
const context = this.canvas.getContext('2d');
|
|
@@ -849,7 +922,10 @@ export class ShaderDisplacementGenerator {
|
|
|
849
922
|
return this.canvas.toDataURL();
|
|
850
923
|
} catch (error) {
|
|
851
924
|
// Graceful fallback on error
|
|
852
|
-
console.warn(
|
|
925
|
+
console.warn(
|
|
926
|
+
'ShaderDisplacementGenerator: Error generating shader map, using fallback',
|
|
927
|
+
error
|
|
928
|
+
);
|
|
853
929
|
return ''; // Return empty string as fallback
|
|
854
930
|
}
|
|
855
931
|
}
|
|
@@ -874,4 +950,4 @@ export class ShaderDisplacementGenerator {
|
|
|
874
950
|
getScale(): number {
|
|
875
951
|
return this.canvasDPI;
|
|
876
952
|
}
|
|
877
|
-
}
|
|
953
|
+
}
|
|
@@ -494,7 +494,7 @@ export const Playground: Story = {
|
|
|
494
494
|
};
|
|
495
495
|
|
|
496
496
|
const backgrounds = [
|
|
497
|
-
'https://images.unsplash.com/photo-
|
|
497
|
+
'https://images.unsplash.com/photo-1579546929518-9e396f3cc809',
|
|
498
498
|
'https://images.unsplash.com/photo-1734760858517-ff3e30c4a420?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=987',
|
|
499
499
|
'https://images.unsplash.com/photo-1590634875052-89c137f8df21?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2072',
|
|
500
500
|
'https://images.unsplash.com/photo-1592880476174-2932b3061c30?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2070',
|
|
@@ -73,7 +73,7 @@ export const LiquidGlass: Story = {
|
|
|
73
73
|
margin: '0 0 16px 0',
|
|
74
74
|
fontSize: '38px',
|
|
75
75
|
fontWeight: 700,
|
|
76
|
-
background: '
|
|
76
|
+
background: 'url(https://images.unsplash.com/photo-1579546929518-9e396f3cc809)',
|
|
77
77
|
WebkitBackgroundClip: 'text',
|
|
78
78
|
WebkitTextFillColor: 'transparent',
|
|
79
79
|
backgroundClip: 'text',
|
|
@@ -109,10 +109,10 @@ export const Basic: Story = {
|
|
|
109
109
|
parameters: {
|
|
110
110
|
docs: {
|
|
111
111
|
description: {
|
|
112
|
-
story: 'Basic avatar with an image source'
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
112
|
+
story: 'Basic avatar with an image source',
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
116
|
};
|
|
117
117
|
|
|
118
118
|
// Avatar with Initials
|
|
@@ -125,10 +125,10 @@ export const WithInitials: Story = {
|
|
|
125
125
|
parameters: {
|
|
126
126
|
docs: {
|
|
127
127
|
description: {
|
|
128
|
-
story: 'Avatar displaying user initials when no image is available'
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
128
|
+
story: 'Avatar displaying user initials when no image is available',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
132
|
};
|
|
133
133
|
|
|
134
134
|
// Avatar with Icon
|
|
@@ -141,10 +141,10 @@ export const WithIcon: Story = {
|
|
|
141
141
|
parameters: {
|
|
142
142
|
docs: {
|
|
143
143
|
description: {
|
|
144
|
-
story: 'Avatar displaying an icon when no image or initials are available'
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
144
|
+
story: 'Avatar displaying an icon when no image or initials are available',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
148
|
};
|
|
149
149
|
|
|
150
150
|
// Avatar Sizes
|
|
@@ -156,10 +156,10 @@ export const Sizes: Story = {
|
|
|
156
156
|
<div className="u-flex u-gap-4 u-flex-wrap u-items-center">
|
|
157
157
|
{sizes.map(size => (
|
|
158
158
|
<div key={size} className="u-flex u-flex-col u-items-center u-gap-2">
|
|
159
|
-
<Avatar
|
|
160
|
-
src={`https://i.pravatar.cc/150?img=${size === 'xs' ? 1 : size === 'sm' ? 2 : size === 'md' ? 3 : size === 'lg' ? 4 : 5}`}
|
|
161
|
-
size={size}
|
|
162
|
-
circle
|
|
159
|
+
<Avatar
|
|
160
|
+
src={`https://i.pravatar.cc/150?img=${size === 'xs' ? 1 : size === 'sm' ? 2 : size === 'md' ? 3 : size === 'lg' ? 4 : 5}`}
|
|
161
|
+
size={size}
|
|
162
|
+
circle
|
|
163
163
|
/>
|
|
164
164
|
<span className="u-text-xs u-capitalize">{size}</span>
|
|
165
165
|
</div>
|
|
@@ -170,10 +170,10 @@ export const Sizes: Story = {
|
|
|
170
170
|
parameters: {
|
|
171
171
|
docs: {
|
|
172
172
|
description: {
|
|
173
|
-
story: 'Different avatar sizes from extra-small to extra-large'
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
173
|
+
story: 'Different avatar sizes from extra-small to extra-large',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
177
|
};
|
|
178
178
|
|
|
179
179
|
// Avatar Shapes
|
|
@@ -182,19 +182,11 @@ export const Shapes: Story = {
|
|
|
182
182
|
return (
|
|
183
183
|
<div className="u-flex u-gap-6 u-items-center">
|
|
184
184
|
<div className="u-flex u-flex-col u-items-center u-gap-2">
|
|
185
|
-
<Avatar
|
|
186
|
-
src="https://i.pravatar.cc/150?img=6"
|
|
187
|
-
size="md"
|
|
188
|
-
circle={false}
|
|
189
|
-
/>
|
|
185
|
+
<Avatar src="https://i.pravatar.cc/150?img=6" size="md" circle={false} />
|
|
190
186
|
<span className="u-text-xs">Square</span>
|
|
191
187
|
</div>
|
|
192
188
|
<div className="u-flex u-flex-col u-items-center u-gap-2">
|
|
193
|
-
<Avatar
|
|
194
|
-
src="https://i.pravatar.cc/150?img=7"
|
|
195
|
-
size="md"
|
|
196
|
-
circle={true}
|
|
197
|
-
/>
|
|
189
|
+
<Avatar src="https://i.pravatar.cc/150?img=7" size="md" circle={true} />
|
|
198
190
|
<span className="u-text-xs">Circle</span>
|
|
199
191
|
</div>
|
|
200
192
|
</div>
|
|
@@ -203,10 +195,10 @@ export const Shapes: Story = {
|
|
|
203
195
|
parameters: {
|
|
204
196
|
docs: {
|
|
205
197
|
description: {
|
|
206
|
-
story: 'Avatar shapes: square and circle'
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
198
|
+
story: 'Avatar shapes: square and circle',
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
210
202
|
};
|
|
211
203
|
|
|
212
204
|
// Avatar States
|
|
@@ -215,20 +207,11 @@ export const States: Story = {
|
|
|
215
207
|
return (
|
|
216
208
|
<div className="u-flex u-gap-6 u-items-center">
|
|
217
209
|
<div className="u-flex u-flex-col u-items-center u-gap-2">
|
|
218
|
-
<Avatar
|
|
219
|
-
src="https://i.pravatar.cc/150?img=8"
|
|
220
|
-
size="md"
|
|
221
|
-
circle
|
|
222
|
-
/>
|
|
210
|
+
<Avatar src="https://i.pravatar.cc/150?img=8" size="md" circle />
|
|
223
211
|
<span className="u-text-xs">Default</span>
|
|
224
212
|
</div>
|
|
225
213
|
<div className="u-flex u-flex-col u-items-center u-gap-2">
|
|
226
|
-
<Avatar
|
|
227
|
-
src="https://i.pravatar.cc/150?img=9"
|
|
228
|
-
size="md"
|
|
229
|
-
circle
|
|
230
|
-
disabled
|
|
231
|
-
/>
|
|
214
|
+
<Avatar src="https://i.pravatar.cc/150?img=9" size="md" circle disabled />
|
|
232
215
|
<span className="u-text-xs">Disabled</span>
|
|
233
216
|
</div>
|
|
234
217
|
</div>
|
|
@@ -237,10 +220,10 @@ export const States: Story = {
|
|
|
237
220
|
parameters: {
|
|
238
221
|
docs: {
|
|
239
222
|
description: {
|
|
240
|
-
story: 'Avatar states: default and disabled'
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
223
|
+
story: 'Avatar states: default and disabled',
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
244
227
|
};
|
|
245
228
|
|
|
246
229
|
// Avatar with Glass Effect
|
|
@@ -254,10 +237,10 @@ export const WithGlassEffect: Story = {
|
|
|
254
237
|
parameters: {
|
|
255
238
|
docs: {
|
|
256
239
|
description: {
|
|
257
|
-
story: 'Avatar with glassmorphism effect'
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
240
|
+
story: 'Avatar with glassmorphism effect',
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
261
244
|
};
|
|
262
245
|
|
|
263
246
|
// Avatar Variants Showcase
|
|
@@ -357,10 +340,10 @@ export const VariantsShowcase: Story = {
|
|
|
357
340
|
parameters: {
|
|
358
341
|
docs: {
|
|
359
342
|
description: {
|
|
360
|
-
story: 'Comprehensive showcase of avatar variants across all sizes'
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
343
|
+
story: 'Comprehensive showcase of avatar variants across all sizes',
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
},
|
|
364
347
|
};
|
|
365
348
|
|
|
366
349
|
// Avatar Group Showcase
|
|
@@ -469,8 +452,8 @@ export const AvatarGroupShowcase: Story = {
|
|
|
469
452
|
parameters: {
|
|
470
453
|
docs: {
|
|
471
454
|
description: {
|
|
472
|
-
story: 'Various configurations of AvatarGroup component'
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
};
|
|
455
|
+
story: 'Various configurations of AvatarGroup component',
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
};
|
|
@@ -3,66 +3,68 @@ import { AvatarProps } from '../../lib/types/components';
|
|
|
3
3
|
import { AVATAR } from '../../lib/constants/components';
|
|
4
4
|
import { Icon } from '../Icon/Icon';
|
|
5
5
|
|
|
6
|
-
export const Avatar: React.FC<AvatarProps> = memo(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
export const Avatar: React.FC<AvatarProps> = memo(
|
|
7
|
+
({
|
|
8
|
+
src,
|
|
9
|
+
alt = 'Avatar',
|
|
10
|
+
initials,
|
|
11
|
+
icon,
|
|
12
|
+
size = 'md',
|
|
13
|
+
circle = false,
|
|
14
|
+
className = '',
|
|
15
|
+
disabled = false,
|
|
16
|
+
onClick,
|
|
17
|
+
style,
|
|
18
|
+
glass,
|
|
19
|
+
}) => {
|
|
20
|
+
const [imageError, setImageError] = useState(false);
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const handleImageError = () => {
|
|
23
|
+
setImageError(true);
|
|
24
|
+
};
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
// Generate CSS classes
|
|
27
|
+
const avatarClasses = [
|
|
28
|
+
AVATAR.CLASSES.BASE,
|
|
29
|
+
size !== 'md' && `c-avatar--${size}`,
|
|
30
|
+
circle && AVATAR.CLASSES.CIRCLE,
|
|
31
|
+
disabled && 'is-disabled',
|
|
32
|
+
className,
|
|
33
|
+
]
|
|
34
|
+
.filter(Boolean)
|
|
35
|
+
.join(' ');
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
// Handle click event
|
|
38
|
+
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
39
|
+
if (!disabled && onClick) {
|
|
40
|
+
onClick(e);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
44
|
+
return (
|
|
45
|
+
<div
|
|
46
|
+
className={avatarClasses}
|
|
47
|
+
onClick={onClick ? handleClick : undefined}
|
|
48
|
+
role={onClick ? 'button' : undefined}
|
|
49
|
+
tabIndex={onClick && !disabled ? 0 : undefined}
|
|
50
|
+
aria-disabled={disabled || undefined}
|
|
51
|
+
style={style}
|
|
52
|
+
>
|
|
53
|
+
{src && !imageError ? (
|
|
54
|
+
<img src={src} alt={alt} className="c-avatar__image" onError={handleImageError} />
|
|
55
|
+
) : initials ? (
|
|
56
|
+
<span className="c-avatar__initials">{initials}</span>
|
|
57
|
+
) : icon ? (
|
|
58
|
+
<span className="c-avatar__icon">{icon}</span>
|
|
59
|
+
) : (
|
|
60
|
+
<span className="c-avatar__icon">
|
|
61
|
+
<Icon name="User" size={size === 'xs' ? 'xs' : size === 'sm' ? 'sm' : 'md'} />
|
|
62
|
+
</span>
|
|
63
|
+
)}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
);
|
|
66
68
|
|
|
67
69
|
Avatar.displayName = 'Avatar';
|
|
68
70
|
|