@shohojdhara/atomix 0.3.15 → 0.4.1
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 +20234 -2027
- 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 +4 -5
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +87 -10
- package/dist/core.js +673 -480
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +15 -3
- package/dist/forms.js +530 -97
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +5 -6
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +644 -277
- package/dist/index.esm.js +1948 -1347
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3333 -2728
- 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 +2 -2
- package/scripts/atomix-cli.js +10 -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 +72 -23
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +219 -96
- package/src/components/Accordion/AccordionCompound.test.tsx +70 -0
- 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 +173 -65
- package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +84 -0
- 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 +166 -918
- package/src/components/Callout/Callout.tsx +196 -84
- package/src/components/Callout/CalloutCompound.test.tsx +72 -0
- 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 +425 -298
- package/src/components/Dropdown/DropdownCompound.test.tsx +64 -0
- package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
- package/src/components/EdgePanel/EdgePanel.tsx +163 -113
- package/src/components/EdgePanel/EdgePanelCompound.test.tsx +53 -0
- 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.stories.tsx +23 -0
- package/src/components/Form/Select.test.tsx +99 -0
- package/src/components/Form/Select.tsx +239 -186
- package/src/components/Form/SelectOption.tsx +88 -0
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +93 -23
- package/src/components/Hero/Hero.test.tsx +142 -0
- package/src/components/Hero/Hero.tsx +343 -58
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.test.tsx +62 -0
- package/src/components/List/List.tsx +32 -25
- package/src/components/List/ListItem.tsx +20 -0
- package/src/components/Modal/Modal.stories.tsx +67 -2
- package/src/components/Modal/Modal.tsx +208 -125
- package/src/components/Modal/ModalCompound.test.tsx +94 -0
- 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/Steps/Steps.tsx +124 -21
- package/src/components/Steps/StepsCompound.test.tsx +81 -0
- package/src/components/Tabs/Tabs.stories.tsx +12 -9
- package/src/components/Tabs/Tabs.tsx +230 -75
- package/src/components/Tabs/TabsCompound.test.tsx +64 -0
- 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/index.ts +0 -4
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +102 -60
- 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 +105 -111
- 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 +180 -73
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/componentUtils.test.ts +57 -2
- package/src/lib/utils/__tests__/csv.test.ts +1 -1
- package/src/lib/utils/__tests__/themeNaming.test.ts +117 -0
- 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 +3 -3
- 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.breakpoints.scss +1 -1
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +36 -24
- 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 -47
|
@@ -254,7 +254,8 @@ export const UsageExamples: Story = {
|
|
|
254
254
|
parameters: {
|
|
255
255
|
docs: {
|
|
256
256
|
description: {
|
|
257
|
-
story:
|
|
257
|
+
story:
|
|
258
|
+
'Practical examples demonstrating how badges can be used in real-world scenarios such as navigation menus, product cards, and task lists.',
|
|
258
259
|
},
|
|
259
260
|
},
|
|
260
261
|
},
|
|
@@ -325,7 +326,8 @@ export const AccessibilityFeatures: Story = {
|
|
|
325
326
|
parameters: {
|
|
326
327
|
docs: {
|
|
327
328
|
description: {
|
|
328
|
-
story:
|
|
329
|
+
story:
|
|
330
|
+
'Examples of accessible badge implementations with proper ARIA labels and keyboard navigation support.',
|
|
329
331
|
},
|
|
330
332
|
},
|
|
331
333
|
},
|
|
@@ -338,14 +340,11 @@ export const AccessibilityFeatures: Story = {
|
|
|
338
340
|
<Badge label="Alert" variant="error" aria-label="Critical notification" />
|
|
339
341
|
</div>
|
|
340
342
|
</div>
|
|
341
|
-
|
|
343
|
+
|
|
342
344
|
<div>
|
|
343
345
|
<h3 className="u-mt-0 u-mb-2">Interactive Badges</h3>
|
|
344
346
|
<div className="u-flex u-gap-2">
|
|
345
|
-
<Badge
|
|
346
|
-
label="Closable Tag"
|
|
347
|
-
variant="info"
|
|
348
|
-
/>
|
|
347
|
+
<Badge label="Closable Tag" variant="info" />
|
|
349
348
|
</div>
|
|
350
349
|
</div>
|
|
351
350
|
</div>
|
|
@@ -361,7 +360,13 @@ export const WithGlassEffect: Story = {
|
|
|
361
360
|
variant: 'primary',
|
|
362
361
|
},
|
|
363
362
|
render: () => (
|
|
364
|
-
<div
|
|
363
|
+
<div
|
|
364
|
+
className="u-bg-cover u-bg-center u-rounded-xl u-p-24"
|
|
365
|
+
style={{
|
|
366
|
+
backgroundImage:
|
|
367
|
+
'url(https://cdn.pixabay.com/photo/2023/07/07/20/42/grasshopper-8113345_1280.jpg)',
|
|
368
|
+
}}
|
|
369
|
+
>
|
|
365
370
|
<div className="u-flex u-flex-wrap u-gap-2">
|
|
366
371
|
{THEME_COLORS.map(color => (
|
|
367
372
|
<Badge key={color} label={color} variant={color} glass={true} />
|
|
@@ -390,7 +395,13 @@ export const WithCustomGlassSettings: Story = {
|
|
|
390
395
|
},
|
|
391
396
|
decorators: [
|
|
392
397
|
Story => (
|
|
393
|
-
<div
|
|
398
|
+
<div
|
|
399
|
+
className="u-bg-cover u-bg-center u-rounded-xl u-p-24"
|
|
400
|
+
style={{
|
|
401
|
+
backgroundImage:
|
|
402
|
+
'url(https://cdn.pixabay.com/photo/2021/06/14/22/46/milky-way-6337038_1280.jpg)',
|
|
403
|
+
}}
|
|
404
|
+
>
|
|
394
405
|
<Story />
|
|
395
406
|
</div>
|
|
396
407
|
),
|
|
@@ -4,48 +4,48 @@ import { Badge } from './Badge';
|
|
|
4
4
|
|
|
5
5
|
// Mock AtomixGlass component
|
|
6
6
|
vi.mock('../AtomixGlass/AtomixGlass', () => ({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
AtomixGlass: ({ children, ...props }: any) => (
|
|
8
|
+
<div data-testid="atomix-glass" data-glass-props={JSON.stringify(props)}>
|
|
9
|
+
{children}
|
|
10
|
+
</div>
|
|
11
|
+
),
|
|
12
12
|
}));
|
|
13
13
|
|
|
14
14
|
describe('Badge Component', () => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
15
|
+
it('renders correctly', () => {
|
|
16
|
+
render(<Badge label="Test Badge" />);
|
|
17
|
+
expect(screen.getByText('Test Badge')).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('renders with aria-label', () => {
|
|
21
|
+
render(<Badge label="Badge" aria-label="Accessible Badge" />);
|
|
22
|
+
expect(screen.getByLabelText('Accessible Badge')).toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('renders close button when onRemove is provided', () => {
|
|
26
|
+
const handleRemove = vi.fn();
|
|
27
|
+
render(<Badge label="Removable" onRemove={handleRemove} />);
|
|
28
|
+
|
|
29
|
+
const closeButton = screen.getByRole('button', { name: 'Remove badge' });
|
|
30
|
+
expect(closeButton).toBeInTheDocument();
|
|
31
|
+
|
|
32
|
+
fireEvent.click(closeButton);
|
|
33
|
+
expect(handleRemove).toHaveBeenCalledTimes(1);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('does not render close button when onRemove is not provided', () => {
|
|
37
|
+
render(<Badge label="Static" />);
|
|
38
|
+
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('disables close button when badge is disabled', () => {
|
|
42
|
+
const handleRemove = vi.fn();
|
|
43
|
+
render(<Badge label="Disabled" onRemove={handleRemove} disabled />);
|
|
44
|
+
|
|
45
|
+
const closeButton = screen.getByRole('button', { name: 'Remove badge' });
|
|
46
|
+
expect(closeButton).toBeDisabled();
|
|
47
|
+
|
|
48
|
+
fireEvent.click(closeButton);
|
|
49
|
+
expect(handleRemove).not.toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
51
|
});
|
|
@@ -4,75 +4,77 @@ import { BADGE } from '../../lib/constants/components';
|
|
|
4
4
|
import { BadgeProps } from '../../lib/types/components';
|
|
5
5
|
import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
|
|
6
6
|
|
|
7
|
-
export const Badge: React.FC<BadgeProps> = memo(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
7
|
+
export const Badge: React.FC<BadgeProps> = memo(
|
|
8
|
+
({
|
|
9
|
+
label,
|
|
10
|
+
variant = 'primary',
|
|
11
|
+
size = 'md',
|
|
12
|
+
disabled = false,
|
|
13
|
+
icon,
|
|
14
|
+
onRemove,
|
|
15
|
+
'aria-label': ariaLabel,
|
|
16
|
+
className = '',
|
|
17
|
+
glass,
|
|
18
|
+
style,
|
|
19
|
+
}) => {
|
|
20
|
+
const { generateBadgeClass } = useBadge({
|
|
21
|
+
variant,
|
|
22
|
+
size,
|
|
23
|
+
disabled,
|
|
24
|
+
});
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
const ref = useRef<HTMLSpanElement>(null);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
const badgeClass = generateBadgeClass({
|
|
29
|
+
variant,
|
|
30
|
+
size,
|
|
31
|
+
disabled,
|
|
32
|
+
className: `${className} ${glass ? 'c-badge--glass' : ''}`.trim(),
|
|
33
|
+
});
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
35
|
+
const badgeElement = (
|
|
36
|
+
<span
|
|
37
|
+
className={badgeClass}
|
|
38
|
+
aria-disabled={disabled}
|
|
39
|
+
aria-label={ariaLabel}
|
|
40
|
+
ref={ref}
|
|
41
|
+
style={style}
|
|
42
|
+
>
|
|
43
|
+
{icon && <span className={BADGE.ICON_CLASS}>{icon}</span>}
|
|
44
|
+
<span>{label}</span>
|
|
45
|
+
{onRemove && (
|
|
46
|
+
<button
|
|
47
|
+
type="button"
|
|
48
|
+
className="c-badge__close"
|
|
49
|
+
onClick={onRemove}
|
|
50
|
+
aria-label="Remove badge"
|
|
51
|
+
disabled={disabled}
|
|
52
|
+
>
|
|
53
|
+
×
|
|
54
|
+
</button>
|
|
55
|
+
)}
|
|
56
|
+
</span>
|
|
57
|
+
);
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
if (glass) {
|
|
60
|
+
// Default glass settings for badges
|
|
61
|
+
const defaultGlassProps = {
|
|
62
|
+
displacementScale: 20,
|
|
63
|
+
cornerRadius: ref.current?.getBoundingClientRect().width
|
|
64
|
+
? ref.current?.getBoundingClientRect().width / 2
|
|
65
|
+
: 16,
|
|
66
|
+
className: 'c-badge--glass',
|
|
67
|
+
elasticity: 0,
|
|
68
|
+
};
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
return <AtomixGlass {...glassProps}>{badgeElement}</AtomixGlass>;
|
|
73
|
+
}
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
}
|
|
75
|
+
return badgeElement;
|
|
76
|
+
}
|
|
77
|
+
);
|
|
76
78
|
|
|
77
79
|
Badge.displayName = 'Badge';
|
|
78
80
|
|
|
@@ -178,7 +178,9 @@ export const ArticleLayout: Story = {
|
|
|
178
178
|
<Block spacing="md" container={{ type: 'sm' }} background="secondary">
|
|
179
179
|
<h3>Ready to get started?</h3>
|
|
180
180
|
<p>Join thousands of developers building with our design system.</p>
|
|
181
|
-
<Button variant="primary" onClick={fn()}>
|
|
181
|
+
<Button variant="primary" onClick={fn()}>
|
|
182
|
+
Start Building
|
|
183
|
+
</Button>
|
|
182
184
|
</Block>
|
|
183
185
|
</div>
|
|
184
186
|
),
|
|
@@ -334,14 +336,22 @@ export const ContentPreview: Story = {
|
|
|
334
336
|
<Card
|
|
335
337
|
title="Cards"
|
|
336
338
|
text="Flexible content containers with multiple options"
|
|
337
|
-
actions={
|
|
339
|
+
actions={
|
|
340
|
+
<Button variant="primary" onClick={fn()}>
|
|
341
|
+
View Details
|
|
342
|
+
</Button>
|
|
343
|
+
}
|
|
338
344
|
/>
|
|
339
345
|
</GridCol>
|
|
340
346
|
<GridCol xs={12} md={6} lg={4}>
|
|
341
347
|
<Card
|
|
342
348
|
title="Blocks"
|
|
343
349
|
text="Layout containers with consistent spacing and backgrounds"
|
|
344
|
-
actions={
|
|
350
|
+
actions={
|
|
351
|
+
<Button variant="primary" onClick={fn()}>
|
|
352
|
+
Learn More
|
|
353
|
+
</Button>
|
|
354
|
+
}
|
|
345
355
|
/>
|
|
346
356
|
</GridCol>
|
|
347
357
|
</Grid>
|
|
@@ -398,4 +408,4 @@ export const ContentPreview: Story = {
|
|
|
398
408
|
</Block>
|
|
399
409
|
</div>
|
|
400
410
|
),
|
|
401
|
-
};
|
|
411
|
+
};
|
|
@@ -181,18 +181,18 @@ export const WithMixedInteractions: Story = {
|
|
|
181
181
|
args: {
|
|
182
182
|
items: [
|
|
183
183
|
{ label: 'Home', href: '/' },
|
|
184
|
-
{
|
|
185
|
-
label: 'Products',
|
|
184
|
+
{
|
|
185
|
+
label: 'Products',
|
|
186
186
|
onClick: fn(),
|
|
187
187
|
// Simulating client-side navigation
|
|
188
188
|
},
|
|
189
|
-
{
|
|
190
|
-
label: 'Category',
|
|
189
|
+
{
|
|
190
|
+
label: 'Category',
|
|
191
191
|
href: '/products/category',
|
|
192
192
|
icon: <Icon name="Folder" size="sm" />,
|
|
193
193
|
},
|
|
194
|
-
{
|
|
195
|
-
label: 'Product Name',
|
|
194
|
+
{
|
|
195
|
+
label: 'Product Name',
|
|
196
196
|
active: true,
|
|
197
197
|
icon: <Icon name="Tag" size="sm" />,
|
|
198
198
|
},
|
|
@@ -202,7 +202,8 @@ export const WithMixedInteractions: Story = {
|
|
|
202
202
|
parameters: {
|
|
203
203
|
docs: {
|
|
204
204
|
description: {
|
|
205
|
-
story:
|
|
205
|
+
story:
|
|
206
|
+
'Breadcrumb combining both traditional link navigation and client-side interactions.',
|
|
206
207
|
},
|
|
207
208
|
},
|
|
208
209
|
},
|
|
@@ -228,4 +229,4 @@ export const LongBreadcrumbPath: Story = {
|
|
|
228
229
|
},
|
|
229
230
|
},
|
|
230
231
|
},
|
|
231
|
-
};
|
|
232
|
+
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import React, { ReactNode, memo } from 'react';
|
|
1
|
+
import React, { ReactNode, memo, forwardRef, Children, cloneElement, isValidElement } from 'react';
|
|
2
2
|
import { BREADCRUMB } from '../../lib/constants/components';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Legacy Item Interface
|
|
5
|
+
export interface BreadcrumbItemData {
|
|
5
6
|
/**
|
|
6
7
|
* Text to display
|
|
7
8
|
*/
|
|
@@ -38,11 +39,108 @@ export interface BreadcrumbItem {
|
|
|
38
39
|
className?: string;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
// Export legacy interface as type alias to preserve backward compatibility for type imports
|
|
43
|
+
export type { BreadcrumbItemData as BreadcrumbItem };
|
|
44
|
+
|
|
45
|
+
// Compound Component Props
|
|
46
|
+
export interface BreadcrumbItemProps extends React.HTMLAttributes<HTMLLIElement> {
|
|
47
|
+
/**
|
|
48
|
+
* URL for the breadcrumb item
|
|
49
|
+
*/
|
|
50
|
+
href?: string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Whether this item is active (current page)
|
|
54
|
+
*/
|
|
55
|
+
active?: boolean;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Optional icon to display before the label
|
|
59
|
+
*/
|
|
60
|
+
icon?: ReactNode;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Optional click handler for the link
|
|
64
|
+
*/
|
|
65
|
+
onClick?: (event: React.MouseEvent<HTMLAnchorElement | HTMLSpanElement>) => void;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Optional custom link component
|
|
69
|
+
*/
|
|
70
|
+
linkAs?: React.ElementType;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Link props to pass to the underlying anchor or LinkComponent
|
|
74
|
+
*/
|
|
75
|
+
linkProps?: Record<string, any>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const BreadcrumbItem = forwardRef<HTMLLIElement, BreadcrumbItemProps>(
|
|
79
|
+
(
|
|
80
|
+
{
|
|
81
|
+
children,
|
|
82
|
+
href,
|
|
83
|
+
active,
|
|
84
|
+
icon,
|
|
85
|
+
onClick,
|
|
86
|
+
className = '',
|
|
87
|
+
style,
|
|
88
|
+
linkAs: LinkComponent,
|
|
89
|
+
linkProps = {},
|
|
90
|
+
...props
|
|
91
|
+
},
|
|
92
|
+
ref
|
|
93
|
+
) => {
|
|
94
|
+
const itemClasses = [BREADCRUMB.CLASSES.ITEM, active ? BREADCRUMB.CLASSES.ACTIVE : '', className]
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.join(' ');
|
|
97
|
+
|
|
98
|
+
const linkContent = (
|
|
99
|
+
<>
|
|
100
|
+
{icon && <span className="c-breadcrumb__icon">{icon}</span>}
|
|
101
|
+
{children}
|
|
102
|
+
</>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const commonLinkProps = {
|
|
106
|
+
className: BREADCRUMB.CLASSES.LINK,
|
|
107
|
+
onClick: onClick as any,
|
|
108
|
+
style, // Apply style to the link as per legacy behavior
|
|
109
|
+
...linkProps,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<li ref={ref} className={itemClasses} style={style} {...props}>
|
|
114
|
+
{href && !active ? (
|
|
115
|
+
LinkComponent ? (
|
|
116
|
+
(() => {
|
|
117
|
+
const Component = LinkComponent;
|
|
118
|
+
return (
|
|
119
|
+
<Component href={href} {...commonLinkProps}>
|
|
120
|
+
{linkContent}
|
|
121
|
+
</Component>
|
|
122
|
+
);
|
|
123
|
+
})()
|
|
124
|
+
) : (
|
|
125
|
+
<a href={href} {...(commonLinkProps as React.HTMLAttributes<HTMLAnchorElement>)}>
|
|
126
|
+
{linkContent}
|
|
127
|
+
</a>
|
|
128
|
+
)
|
|
129
|
+
) : (
|
|
130
|
+
<span className={BREADCRUMB.CLASSES.LINK}>{linkContent}</span>
|
|
131
|
+
)}
|
|
132
|
+
</li>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
BreadcrumbItem.displayName = 'BreadcrumbItem';
|
|
138
|
+
|
|
41
139
|
export interface BreadcrumbProps {
|
|
42
140
|
/**
|
|
43
|
-
* Array of breadcrumb items
|
|
141
|
+
* Array of breadcrumb items (Legacy)
|
|
44
142
|
*/
|
|
45
|
-
items
|
|
143
|
+
items?: BreadcrumbItemData[];
|
|
46
144
|
|
|
47
145
|
/**
|
|
48
146
|
* Custom divider character or element
|
|
@@ -68,69 +166,79 @@ export interface BreadcrumbProps {
|
|
|
68
166
|
* Custom style for the breadcrumb
|
|
69
167
|
*/
|
|
70
168
|
style?: React.CSSProperties;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Children (Compound)
|
|
172
|
+
*/
|
|
173
|
+
children?: ReactNode;
|
|
71
174
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
className
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
175
|
+
|
|
176
|
+
type BreadcrumbComponent = React.FC<BreadcrumbProps> & {
|
|
177
|
+
Item: typeof BreadcrumbItem;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const Breadcrumb: BreadcrumbComponent = memo(
|
|
181
|
+
({
|
|
182
|
+
items,
|
|
183
|
+
divider,
|
|
184
|
+
className = '',
|
|
185
|
+
'aria-label': ariaLabel = 'Breadcrumb',
|
|
186
|
+
LinkComponent,
|
|
187
|
+
style,
|
|
188
|
+
children,
|
|
189
|
+
}) => {
|
|
190
|
+
const breadcrumbClasses = [BREADCRUMB.CLASSES.BASE, className].filter(Boolean).join(' ');
|
|
191
|
+
|
|
192
|
+
let content: ReactNode;
|
|
193
|
+
|
|
194
|
+
if (items && items.length > 0) {
|
|
195
|
+
// Legacy rendering
|
|
196
|
+
content = items.map((item, index) => {
|
|
197
|
+
const isLast = index === items.length - 1;
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<BreadcrumbItem
|
|
201
|
+
key={index}
|
|
202
|
+
href={item.href}
|
|
203
|
+
active={item.active || isLast}
|
|
204
|
+
icon={item.icon}
|
|
205
|
+
onClick={item.onClick}
|
|
206
|
+
className={item.className}
|
|
207
|
+
style={item.style}
|
|
208
|
+
linkAs={LinkComponent}
|
|
209
|
+
>
|
|
210
|
+
{item.label}
|
|
211
|
+
</BreadcrumbItem>
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
} else {
|
|
215
|
+
// Compound rendering
|
|
216
|
+
const childrenCount = Children.count(children);
|
|
217
|
+
content = Children.map(children, (child, index) => {
|
|
218
|
+
if (isValidElement(child)) {
|
|
219
|
+
const isLast = index === childrenCount - 1;
|
|
220
|
+
const childProps = child.props as any;
|
|
221
|
+
|
|
222
|
+
return cloneElement(child, {
|
|
223
|
+
active: childProps.active ?? (isLast ? true : undefined),
|
|
224
|
+
linkAs: childProps.linkAs ?? LinkComponent,
|
|
225
|
+
} as any);
|
|
226
|
+
}
|
|
227
|
+
return child;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
<nav aria-label={ariaLabel} style={style}>
|
|
233
|
+
<ol className={breadcrumbClasses}>
|
|
234
|
+
{content}
|
|
235
|
+
</ol>
|
|
236
|
+
</nav>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
) as unknown as BreadcrumbComponent;
|
|
133
240
|
|
|
134
241
|
Breadcrumb.displayName = 'Breadcrumb';
|
|
242
|
+
Breadcrumb.Item = BreadcrumbItem;
|
|
135
243
|
|
|
136
244
|
export default Breadcrumb;
|