@boostdev/design-system-components 1.2.0 → 1.2.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/AGENTS.md +46 -4
- package/README.md +15 -15
- package/dist/client.cjs +149 -124
- package/dist/client.css +503 -525
- package/dist/client.d.cts +71 -96
- package/dist/client.d.ts +71 -96
- package/dist/client.js +149 -124
- package/dist/index.cjs +149 -124
- package/dist/index.css +503 -525
- package/dist/index.d.cts +71 -96
- package/dist/index.d.ts +71 -96
- package/dist/index.js +149 -124
- package/dist/web-components/{chunk-6MH5UWUD.js → chunk-2FGATTGT.js} +5 -0
- package/dist/web-components/{chunk-5IPHEONG.js → chunk-6I2DBFQ7.js} +1 -0
- package/dist/web-components/{chunk-DI46Q2EA.js → chunk-OCODKRVZ.js} +57 -82
- package/dist/web-components/index.d.ts +571 -1
- package/dist/web-components/index.js +1501 -4
- package/dist/web-components/interaction/bds-collapsible.js +1 -1
- package/dist/web-components/interaction/bds-drawer.js +1 -1
- package/dist/web-components/interaction/form/bds-segmented-control.js +1 -1
- package/package.json +1 -1
- package/src/components/interaction/Command/Command.tsx +4 -3
- package/src/components/interaction/Dialog/Dialog.tsx +4 -5
- package/src/components/interaction/Drawer/Drawer.module.css +37 -62
- package/src/components/interaction/Drawer/Drawer.spec.tsx +3 -3
- package/src/components/interaction/Drawer/Drawer.tsx +25 -24
- package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +4 -2
- package/src/components/interaction/Popover/Popover.tsx +4 -3
- package/src/components/interaction/Rating/Rating.tsx +4 -2
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +4 -6
- package/src/components/interaction/form/Combobox/Combobox.tsx +4 -2
- package/src/components/interaction/form/FileInput/FileInput.tsx +4 -3
- package/src/components/interaction/form/NumberInput/NumberInput.tsx +4 -3
- package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +4 -6
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +8 -4
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +13 -6
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +4 -6
- package/src/components/interaction/form/atoms/InputContainer.tsx +2 -2
- package/src/components/layout/ButtonGroup/ButtonGroup.tsx +4 -6
- package/src/components/layout/Card/Card.tsx +4 -10
- package/src/components/layout/IconWrapper/IconWrapper.tsx +4 -5
- package/src/components/layout/SectionHeader/SectionHeader.tsx +5 -4
- package/src/components/ui/Accordion/Accordion.tsx +4 -3
- package/src/components/ui/Alert/Alert.tsx +4 -3
- package/src/components/ui/Avatar/Avatar.tsx +5 -3
- package/src/components/ui/Badge/Badge.tsx +4 -5
- package/src/components/ui/Breadcrumb/Breadcrumb.tsx +4 -3
- package/src/components/ui/Calendar/Calendar.tsx +4 -4
- package/src/components/ui/Carousel/Carousel.tsx +4 -4
- package/src/components/ui/DescriptionList/DescriptionList.tsx +4 -4
- package/src/components/ui/Loading/Loading.tsx +4 -3
- package/src/components/ui/NotificationBanner/NotificationBanner.tsx +4 -2
- package/src/components/ui/Pagination/Pagination.tsx +4 -2
- package/src/components/ui/Progress/Progress.tsx +4 -2
- package/src/components/ui/ProgressCircle/ProgressCircle.tsx +4 -1
- package/src/components/ui/Separator/Separator.tsx +5 -3
- package/src/components/ui/Skeleton/Skeleton.tsx +4 -3
- package/src/components/ui/SkipLink/SkipLink.tsx +4 -5
- package/src/components/ui/Tabs/Tabs.tsx +4 -4
- package/src/components/ui/Tooltip/Tooltip.tsx +4 -2
- package/src/components/ui/Typography/Typography.tsx +4 -5
- package/src/stories/DesignSystem/Grid.mdx +2 -0
- package/src/stories/Introduction.mdx +2 -1
- package/src/web-components/index.ts +12 -0
- package/src/web-components/interaction/BdsAccordion.mdx +80 -28
- package/src/web-components/interaction/BdsAccordion.stories.tsx +67 -58
- package/src/web-components/interaction/BdsCollapsible.mdx +93 -23
- package/src/web-components/interaction/BdsCollapsible.stories.tsx +29 -48
- package/src/web-components/interaction/BdsDialog.mdx +88 -27
- package/src/web-components/interaction/BdsDialog.stories.tsx +129 -47
- package/src/web-components/interaction/BdsDrawer.mdx +85 -27
- package/src/web-components/interaction/BdsDrawer.stories.tsx +161 -31
- package/src/web-components/interaction/BdsDropdownMenu.mdx +108 -0
- package/src/web-components/interaction/BdsDropdownMenu.stories.tsx +91 -0
- package/src/web-components/interaction/BdsSkipLink.mdx +72 -16
- package/src/web-components/interaction/BdsSkipLink.stories.tsx +47 -34
- package/src/web-components/interaction/BdsTabs.mdx +97 -27
- package/src/web-components/interaction/BdsTabs.stories.tsx +69 -55
- package/src/web-components/interaction/BdsTooltip.mdx +84 -18
- package/src/web-components/interaction/BdsTooltip.stories.tsx +49 -30
- package/src/web-components/interaction/bds-collapsible.ts +1 -0
- package/src/web-components/interaction/bds-drawer.ts +59 -82
- package/src/web-components/interaction/bds-dropdown-menu-item.ts +124 -0
- package/src/web-components/interaction/bds-dropdown-menu.spec.ts +102 -0
- package/src/web-components/interaction/bds-dropdown-menu.ts +200 -0
- package/src/web-components/interaction/form/BdsCheckbox.mdx +57 -20
- package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +35 -36
- package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +70 -0
- package/src/web-components/interaction/form/BdsCheckboxGroup.stories.tsx +81 -0
- package/src/web-components/interaction/form/BdsCombobox.mdx +52 -33
- package/src/web-components/interaction/form/BdsCombobox.stories.tsx +55 -53
- package/src/web-components/interaction/form/BdsFileInput.mdx +59 -24
- package/src/web-components/interaction/form/BdsFileInput.stories.tsx +38 -53
- package/src/web-components/interaction/form/BdsFormInput.mdx +98 -0
- package/src/web-components/interaction/form/BdsFormInput.stories.tsx +139 -0
- package/src/web-components/interaction/form/BdsNumberInput.mdx +51 -22
- package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +24 -46
- package/src/web-components/interaction/form/BdsRadio.mdx +53 -22
- package/src/web-components/interaction/form/BdsRadio.stories.tsx +19 -51
- package/src/web-components/interaction/form/BdsRadioGroup.mdx +73 -0
- package/src/web-components/interaction/form/BdsRadioGroup.stories.tsx +88 -0
- package/src/web-components/interaction/form/BdsSegmentedControl.mdx +76 -23
- package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +64 -54
- package/src/web-components/interaction/form/BdsSelect.mdx +59 -21
- package/src/web-components/interaction/form/BdsSelect.stories.tsx +47 -56
- package/src/web-components/interaction/form/BdsSlider.mdx +55 -27
- package/src/web-components/interaction/form/BdsSlider.stories.tsx +23 -44
- package/src/web-components/interaction/form/BdsSwitch.mdx +53 -20
- package/src/web-components/interaction/form/BdsSwitch.stories.tsx +22 -37
- package/src/web-components/interaction/form/BdsTextarea.mdx +54 -22
- package/src/web-components/interaction/form/BdsTextarea.stories.tsx +35 -44
- package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-checkbox-group.ts +117 -0
- package/src/web-components/interaction/form/bds-form-input.spec.ts +83 -0
- package/src/web-components/interaction/form/bds-form-input.ts +268 -0
- package/src/web-components/interaction/form/bds-radio-group.spec.ts +62 -0
- package/src/web-components/interaction/form/bds-radio-group.ts +142 -0
- package/src/web-components/interaction/form/bds-segmented-control.ts +5 -0
- package/src/web-components/ui/BdsAvatar.mdx +29 -20
- package/src/web-components/ui/BdsAvatar.stories.tsx +14 -28
- package/src/web-components/ui/BdsBreadcrumb.mdx +22 -19
- package/src/web-components/ui/BdsBreadcrumb.stories.tsx +11 -21
- package/src/web-components/ui/BdsButtonGroup.mdx +69 -0
- package/src/web-components/ui/BdsButtonGroup.stories.tsx +66 -0
- package/src/web-components/ui/BdsCalendar.mdx +93 -0
- package/src/web-components/ui/BdsCalendar.stories.tsx +63 -0
- package/src/web-components/ui/BdsCard.mdx +30 -25
- package/src/web-components/ui/BdsCard.stories.tsx +19 -42
- package/src/web-components/ui/BdsCarousel.mdx +83 -0
- package/src/web-components/ui/BdsCarousel.stories.tsx +96 -0
- package/src/web-components/ui/BdsDescriptionList.mdx +13 -16
- package/src/web-components/ui/BdsDescriptionList.stories.tsx +34 -49
- package/src/web-components/ui/BdsIconWrapper.mdx +20 -20
- package/src/web-components/ui/BdsIconWrapper.stories.tsx +46 -41
- package/src/web-components/ui/BdsLink.mdx +21 -17
- package/src/web-components/ui/BdsLink.stories.tsx +19 -20
- package/src/web-components/ui/BdsLoading.mdx +9 -13
- package/src/web-components/ui/BdsLoading.stories.tsx +8 -10
- package/src/web-components/ui/BdsNotificationBanner.mdx +32 -37
- package/src/web-components/ui/BdsNotificationBanner.stories.tsx +38 -47
- package/src/web-components/ui/BdsPagination.mdx +74 -0
- package/src/web-components/ui/BdsPagination.stories.tsx +36 -0
- package/src/web-components/ui/BdsProgress.mdx +24 -17
- package/src/web-components/ui/BdsProgress.stories.tsx +55 -29
- package/src/web-components/ui/BdsProgressCircle.mdx +24 -18
- package/src/web-components/ui/BdsProgressCircle.stories.tsx +17 -29
- package/src/web-components/ui/BdsRating.mdx +22 -22
- package/src/web-components/ui/BdsRating.stories.tsx +19 -13
- package/src/web-components/ui/BdsSectionHeader.mdx +31 -28
- package/src/web-components/ui/BdsSectionHeader.stories.tsx +21 -23
- package/src/web-components/ui/BdsSeparator.mdx +22 -8
- package/src/web-components/ui/BdsSeparator.stories.tsx +27 -19
- package/src/web-components/ui/BdsSkeleton.mdx +20 -26
- package/src/web-components/ui/BdsSkeleton.stories.tsx +23 -23
- package/src/web-components/ui/BdsTable.mdx +81 -0
- package/src/web-components/ui/BdsTable.stories.tsx +83 -0
- package/src/web-components/ui/BdsTypography.mdx +20 -29
- package/src/web-components/ui/BdsTypography.stories.tsx +19 -18
- package/src/web-components/ui/bds-button-group.spec.ts +40 -0
- package/src/web-components/ui/bds-button-group.ts +78 -0
- package/src/web-components/ui/bds-calendar.spec.ts +91 -0
- package/src/web-components/ui/bds-calendar.ts +427 -0
- package/src/web-components/ui/bds-carousel.spec.ts +64 -0
- package/src/web-components/ui/bds-carousel.ts +296 -0
- package/src/web-components/ui/bds-pagination.spec.ts +67 -0
- package/src/web-components/ui/bds-pagination.ts +197 -0
- package/src/web-components/ui/bds-table.spec.ts +45 -0
- package/src/web-components/ui/bds-table.ts +96 -0
|
@@ -5,7 +5,7 @@ import * as Stories from './BdsBreadcrumb.stories';
|
|
|
5
5
|
|
|
6
6
|
# <bds-breadcrumb>
|
|
7
7
|
|
|
8
|
-
Framework-agnostic Breadcrumb
|
|
8
|
+
Framework-agnostic Breadcrumb custom element. Renders a horizontal navigation trail from a JSON array of `{ label, href? }` items. The last item is treated as the current page and rendered without a link.
|
|
9
9
|
|
|
10
10
|
> **Status: experimental** — API may change before stable release.
|
|
11
11
|
|
|
@@ -15,16 +15,21 @@ Framework-agnostic Breadcrumb navigation custom element. Renders an ordered list
|
|
|
15
15
|
import '@boostdev/components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- On pages more than one level deep in a hierarchy to help users understand their location
|
|
21
|
+
- Always include a link back to the root/home as the first item
|
|
22
|
+
|
|
18
23
|
## Examples
|
|
19
24
|
|
|
20
|
-
### Default
|
|
25
|
+
### Default
|
|
21
26
|
<Canvas of={Stories.Default} />
|
|
22
27
|
|
|
23
|
-
###
|
|
24
|
-
<Canvas of={Stories.
|
|
28
|
+
### Short (two levels)
|
|
29
|
+
<Canvas of={Stories.Short} />
|
|
25
30
|
|
|
26
|
-
###
|
|
27
|
-
<Canvas of={Stories.
|
|
31
|
+
### Long (five levels)
|
|
32
|
+
<Canvas of={Stories.Long} />
|
|
28
33
|
|
|
29
34
|
## Props
|
|
30
35
|
|
|
@@ -34,30 +39,28 @@ import '@boostdev/components/web-components';
|
|
|
34
39
|
|
|
35
40
|
| Attribute | Type | Default | Description |
|
|
36
41
|
|-----------|------|---------|-------------|
|
|
37
|
-
| `items` |
|
|
42
|
+
| `items` | `Array<{ label: string; href?: string }>` | `[]` | Breadcrumb items as a JSON-serialisable array. The last item is always the current page. |
|
|
38
43
|
|
|
39
44
|
## Usage in plain HTML
|
|
40
45
|
|
|
41
46
|
```html
|
|
42
|
-
<bds-breadcrumb
|
|
43
|
-
{"label":"Home","href":"/"},
|
|
44
|
-
|
|
45
|
-
{"label":"Detail"}
|
|
46
|
-
]'></bds-breadcrumb>
|
|
47
|
+
<bds-breadcrumb
|
|
48
|
+
items='[{"label":"Home","href":"/"},{"label":"Products","href":"/products"},{"label":"Item"}]'>
|
|
49
|
+
</bds-breadcrumb>
|
|
47
50
|
```
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
Or set the property in JavaScript:
|
|
53
|
+
|
|
50
54
|
```js
|
|
51
|
-
|
|
52
|
-
crumb.items = [
|
|
55
|
+
document.querySelector('bds-breadcrumb').items = [
|
|
53
56
|
{ label: 'Home', href: '/' },
|
|
54
57
|
{ label: 'Products', href: '/products' },
|
|
55
|
-
{ label: '
|
|
58
|
+
{ label: 'Item' },
|
|
56
59
|
];
|
|
57
60
|
```
|
|
58
61
|
|
|
59
62
|
## Accessibility
|
|
60
63
|
|
|
61
|
-
-
|
|
62
|
-
- The
|
|
63
|
-
-
|
|
64
|
+
- Wrapped in `<nav aria-label="Breadcrumb">` with an `<ol>` list structure
|
|
65
|
+
- The current page item carries `aria-current="page"`
|
|
66
|
+
- Separator characters are `aria-hidden="true"` to avoid screen reader noise
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import type { BreadcrumbItem } from './bds-breadcrumb';
|
|
4
|
-
import '../index';
|
|
4
|
+
import '../index'; // auto-registers all custom elements
|
|
5
5
|
|
|
6
6
|
function BdsBreadcrumb({ items = [] }: { items?: BreadcrumbItem[] }) {
|
|
7
|
-
return React.createElement('bds-breadcrumb', { items
|
|
7
|
+
return React.createElement('bds-breadcrumb', { items });
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const meta = {
|
|
11
11
|
title: 'Web Components/UI/Breadcrumb',
|
|
12
12
|
component: BdsBreadcrumb,
|
|
13
13
|
tags: ['!stable', 'experimental'],
|
|
14
|
-
parameters: { layout: '
|
|
14
|
+
parameters: { layout: 'centered' },
|
|
15
15
|
} satisfies Meta<typeof BdsBreadcrumb>;
|
|
16
16
|
|
|
17
17
|
export default meta;
|
|
@@ -22,38 +22,28 @@ export const Default: Story = {
|
|
|
22
22
|
items: [
|
|
23
23
|
{ label: 'Home', href: '/' },
|
|
24
24
|
{ label: 'Products', href: '/products' },
|
|
25
|
-
{ label: '
|
|
25
|
+
{ label: 'Item' },
|
|
26
26
|
],
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
export const
|
|
30
|
+
export const Short: Story = {
|
|
31
31
|
args: {
|
|
32
32
|
items: [
|
|
33
33
|
{ label: 'Home', href: '/' },
|
|
34
|
-
{ label: 'Current
|
|
34
|
+
{ label: 'Current Page' },
|
|
35
35
|
],
|
|
36
36
|
},
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export const
|
|
39
|
+
export const Long: Story = {
|
|
40
40
|
args: {
|
|
41
41
|
items: [
|
|
42
42
|
{ label: 'Home', href: '/' },
|
|
43
|
-
{ label: '
|
|
44
|
-
{ label: '
|
|
45
|
-
{ label: '
|
|
46
|
-
{ label: '
|
|
43
|
+
{ label: 'Catalogue', href: '/catalogue' },
|
|
44
|
+
{ label: 'Electronics', href: '/catalogue/electronics' },
|
|
45
|
+
{ label: 'Phones', href: '/catalogue/electronics/phones' },
|
|
46
|
+
{ label: 'Smartphone X' },
|
|
47
47
|
],
|
|
48
48
|
},
|
|
49
49
|
};
|
|
50
|
-
|
|
51
|
-
export const AllVariants: Story = {
|
|
52
|
-
render: () => (
|
|
53
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
54
|
-
<BdsBreadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Current' }]} />
|
|
55
|
-
<BdsBreadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Products', href: '/products' }, { label: 'Detail' }]} />
|
|
56
|
-
<BdsBreadcrumb items={[{ label: 'Home', href: '/' }, { label: 'A', href: '/a' }, { label: 'B', href: '/a/b' }, { label: 'C', href: '/a/b/c' }, { label: 'Current' }]} />
|
|
57
|
-
</div>
|
|
58
|
-
),
|
|
59
|
-
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsButtonGroup.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-button-group>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic Button Group custom element. Groups related `<bds-button>` elements in a flex container, collapsing adjacent border radii so they read as a single unit.
|
|
9
|
+
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@boostdev/components/web-components';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- Toggle groups (Day / Week / Month), segmented actions, or sets of closely related operations
|
|
21
|
+
- Use `orientation="vertical"` for stacked navigation menus
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
### Default (horizontal)
|
|
26
|
+
<Canvas of={Stories.Default} />
|
|
27
|
+
|
|
28
|
+
### Horizontal
|
|
29
|
+
<Canvas of={Stories.Horizontal} />
|
|
30
|
+
|
|
31
|
+
### Vertical
|
|
32
|
+
<Canvas of={Stories.Vertical} />
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
<ArgTypes of={Stories} />
|
|
37
|
+
|
|
38
|
+
## Attributes
|
|
39
|
+
|
|
40
|
+
| Attribute | Type | Default | Description |
|
|
41
|
+
|-----------|------|---------|-------------|
|
|
42
|
+
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Flex direction of the group |
|
|
43
|
+
| `aria-label` | string | — | Accessible label for the group container |
|
|
44
|
+
|
|
45
|
+
## Slots
|
|
46
|
+
|
|
47
|
+
| Slot | Description |
|
|
48
|
+
|------|-------------|
|
|
49
|
+
| `(default)` | `<bds-button>` elements |
|
|
50
|
+
|
|
51
|
+
## Usage in plain HTML
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<bds-button-group aria-label="View options">
|
|
55
|
+
<bds-button>Day</bds-button>
|
|
56
|
+
<bds-button>Week</bds-button>
|
|
57
|
+
<bds-button>Month</bds-button>
|
|
58
|
+
</bds-button-group>
|
|
59
|
+
|
|
60
|
+
<bds-button-group orientation="vertical" aria-label="Navigation">
|
|
61
|
+
<bds-button>Profile</bds-button>
|
|
62
|
+
<bds-button>Settings</bds-button>
|
|
63
|
+
</bds-button-group>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Accessibility
|
|
67
|
+
|
|
68
|
+
- Renders a `<div role="group">` with the provided `aria-label`
|
|
69
|
+
- Always set `aria-label` to describe the purpose of the group
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import type { ButtonGroupOrientation } from './bds-button-group';
|
|
4
|
+
import '../index'; // auto-registers all custom elements
|
|
5
|
+
|
|
6
|
+
function BdsButtonGroup({
|
|
7
|
+
orientation = 'horizontal',
|
|
8
|
+
ariaLabel,
|
|
9
|
+
children,
|
|
10
|
+
}: {
|
|
11
|
+
orientation?: ButtonGroupOrientation;
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}) {
|
|
15
|
+
return React.createElement(
|
|
16
|
+
'bds-button-group',
|
|
17
|
+
{ orientation, 'aria-label': ariaLabel },
|
|
18
|
+
children,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const meta = {
|
|
23
|
+
title: 'Web Components/UI/ButtonGroup',
|
|
24
|
+
component: BdsButtonGroup,
|
|
25
|
+
tags: ['!stable', 'experimental'],
|
|
26
|
+
parameters: { layout: 'centered' },
|
|
27
|
+
argTypes: {
|
|
28
|
+
orientation: { control: 'radio', options: ['horizontal', 'vertical'] },
|
|
29
|
+
ariaLabel: { control: 'text' },
|
|
30
|
+
},
|
|
31
|
+
} satisfies Meta<typeof BdsButtonGroup>;
|
|
32
|
+
|
|
33
|
+
export default meta;
|
|
34
|
+
type Story = StoryObj<typeof meta>;
|
|
35
|
+
|
|
36
|
+
export const Default: Story = {
|
|
37
|
+
render: () =>
|
|
38
|
+
React.createElement(
|
|
39
|
+
'bds-button-group',
|
|
40
|
+
{ 'aria-label': 'View options' },
|
|
41
|
+
React.createElement('bds-button', null, 'Day'),
|
|
42
|
+
React.createElement('bds-button', null, 'Week'),
|
|
43
|
+
React.createElement('bds-button', null, 'Month'),
|
|
44
|
+
),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const Horizontal: Story = {
|
|
48
|
+
render: () =>
|
|
49
|
+
React.createElement(
|
|
50
|
+
'bds-button-group',
|
|
51
|
+
{ orientation: 'horizontal', 'aria-label': 'Actions' },
|
|
52
|
+
React.createElement('bds-button', null, 'Save'),
|
|
53
|
+
React.createElement('bds-button', { variant: 'ghost' }, 'Cancel'),
|
|
54
|
+
),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const Vertical: Story = {
|
|
58
|
+
render: () =>
|
|
59
|
+
React.createElement(
|
|
60
|
+
'bds-button-group',
|
|
61
|
+
{ orientation: 'vertical', 'aria-label': 'Navigation' },
|
|
62
|
+
React.createElement('bds-button', null, 'Profile'),
|
|
63
|
+
React.createElement('bds-button', null, 'Settings'),
|
|
64
|
+
React.createElement('bds-button', null, 'Logout'),
|
|
65
|
+
),
|
|
66
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsCalendar.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-calendar>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic Calendar date picker custom element. Renders a keyboard-navigable month grid for selecting a date. Participates in HTML forms via the Form-Associated Custom Elements API.
|
|
9
|
+
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@boostdev/components/web-components';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- Date selection fields in forms where a visual calendar grid aids comprehension
|
|
21
|
+
- Pair with `min`/`max` to restrict selectable dates to a valid range
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
### Default
|
|
26
|
+
<Canvas of={Stories.Default} />
|
|
27
|
+
|
|
28
|
+
### With preselected value
|
|
29
|
+
<Canvas of={Stories.WithValue} />
|
|
30
|
+
|
|
31
|
+
### With min/max range
|
|
32
|
+
<Canvas of={Stories.WithMinMax} />
|
|
33
|
+
|
|
34
|
+
### Disabled
|
|
35
|
+
<Canvas of={Stories.Disabled} />
|
|
36
|
+
|
|
37
|
+
### Inside a form
|
|
38
|
+
<Canvas of={Stories.FormField} />
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
<ArgTypes of={Stories} />
|
|
43
|
+
|
|
44
|
+
## Attributes
|
|
45
|
+
|
|
46
|
+
| Attribute | Type | Default | Description |
|
|
47
|
+
|-----------|------|---------|-------------|
|
|
48
|
+
| `name` | string | — | Form field name — required to participate in form submission |
|
|
49
|
+
| `value` | string | — | Selected date in ISO 8601 format (`YYYY-MM-DD`) |
|
|
50
|
+
| `min` | string | — | Minimum selectable date (ISO 8601) |
|
|
51
|
+
| `max` | string | — | Maximum selectable date (ISO 8601) |
|
|
52
|
+
| `disabled` | boolean | `false` | Disables all interaction |
|
|
53
|
+
|
|
54
|
+
## Events
|
|
55
|
+
|
|
56
|
+
| Event | Detail | Description |
|
|
57
|
+
|-------|--------|-------------|
|
|
58
|
+
| `bds-date-select` | `{ date: string }` | Fired when the user selects a date; `date` is in `YYYY-MM-DD` format |
|
|
59
|
+
|
|
60
|
+
## Usage in plain HTML
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<bds-calendar name="birthday" value="2026-04-15"></bds-calendar>
|
|
64
|
+
|
|
65
|
+
<!-- With constraints -->
|
|
66
|
+
<bds-calendar name="departure" min="2026-04-01" max="2026-12-31"></bds-calendar>
|
|
67
|
+
|
|
68
|
+
<script>
|
|
69
|
+
document.querySelector('bds-calendar')
|
|
70
|
+
.addEventListener('bds-date-select', e => {
|
|
71
|
+
console.log('Selected date:', e.detail.date);
|
|
72
|
+
});
|
|
73
|
+
</script>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Keyboard Navigation
|
|
77
|
+
|
|
78
|
+
| Key | Action |
|
|
79
|
+
|-----|--------|
|
|
80
|
+
| Arrow keys | Move focus between days |
|
|
81
|
+
| Home | Move to start of week |
|
|
82
|
+
| End | Move to end of week |
|
|
83
|
+
| Page Up | Navigate to previous month |
|
|
84
|
+
| Page Down | Navigate to next month |
|
|
85
|
+
| Enter / Space | Select focused date |
|
|
86
|
+
|
|
87
|
+
## Accessibility
|
|
88
|
+
|
|
89
|
+
- Uses the ARIA grid pattern with `role="grid"` and `role="gridcell"` on day buttons
|
|
90
|
+
- The month/year label uses `aria-live="polite"` for screen reader announcements on navigation
|
|
91
|
+
- Each day carries `aria-selected` and `aria-current="date"` (today)
|
|
92
|
+
- Disabled days carry `aria-disabled="true"` and are not focusable
|
|
93
|
+
- Respects the `disabled` attribute at the host level
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../index'; // auto-registers all custom elements
|
|
4
|
+
|
|
5
|
+
function BdsCalendar({
|
|
6
|
+
name,
|
|
7
|
+
value,
|
|
8
|
+
min,
|
|
9
|
+
max,
|
|
10
|
+
disabled,
|
|
11
|
+
}: {
|
|
12
|
+
name?: string;
|
|
13
|
+
value?: string;
|
|
14
|
+
min?: string;
|
|
15
|
+
max?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}) {
|
|
18
|
+
return React.createElement('bds-calendar', {
|
|
19
|
+
name,
|
|
20
|
+
value,
|
|
21
|
+
min,
|
|
22
|
+
max,
|
|
23
|
+
disabled: disabled || undefined,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const meta = {
|
|
28
|
+
title: 'Web Components/UI/Calendar',
|
|
29
|
+
component: BdsCalendar,
|
|
30
|
+
tags: ['!stable', 'experimental'],
|
|
31
|
+
parameters: { layout: 'centered' },
|
|
32
|
+
argTypes: {
|
|
33
|
+
value: { control: 'text' },
|
|
34
|
+
min: { control: 'text' },
|
|
35
|
+
max: { control: 'text' },
|
|
36
|
+
disabled: { control: 'boolean' },
|
|
37
|
+
},
|
|
38
|
+
} satisfies Meta<typeof BdsCalendar>;
|
|
39
|
+
|
|
40
|
+
export default meta;
|
|
41
|
+
type Story = StoryObj<typeof meta>;
|
|
42
|
+
|
|
43
|
+
export const Default: Story = { args: {} };
|
|
44
|
+
export const WithValue: Story = { args: { value: '2026-04-15' } };
|
|
45
|
+
export const WithMinMax: Story = {
|
|
46
|
+
args: { value: '2026-04-10', min: '2026-04-05', max: '2026-04-25' },
|
|
47
|
+
};
|
|
48
|
+
export const Disabled: Story = { args: { value: '2026-04-10', disabled: true } };
|
|
49
|
+
export const FormField: Story = {
|
|
50
|
+
render: () => (
|
|
51
|
+
<form
|
|
52
|
+
onSubmit={(e) => {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
const data = new FormData(e.currentTarget);
|
|
55
|
+
alert(`Selected: ${data.get('birthday') ?? 'none'}`);
|
|
56
|
+
}}
|
|
57
|
+
style={{ display: 'flex', flexDirection: 'column', gap: 16, alignItems: 'flex-start' }}
|
|
58
|
+
>
|
|
59
|
+
{React.createElement('bds-calendar', { name: 'birthday' })}
|
|
60
|
+
<button type="submit">Submit</button>
|
|
61
|
+
</form>
|
|
62
|
+
),
|
|
63
|
+
};
|
|
@@ -5,7 +5,7 @@ import * as Stories from './BdsCard.stories';
|
|
|
5
5
|
|
|
6
6
|
# <bds-card>
|
|
7
7
|
|
|
8
|
-
Framework-agnostic Card layout element.
|
|
8
|
+
Framework-agnostic Card layout custom element. A versatile container with three visual variants, configurable padding, text alignment, and an optional clickable mode.
|
|
9
9
|
|
|
10
10
|
> **Status: experimental** — API may change before stable release.
|
|
11
11
|
|
|
@@ -15,13 +15,27 @@ Framework-agnostic Card layout element. Groups related content in a contained su
|
|
|
15
15
|
import '@boostdev/components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- Grouping related content visually (product listings, dashboard widgets, feature summaries)
|
|
21
|
+
- Use `clickable` to turn the entire card into an interactive button (e.g. navigation tiles)
|
|
22
|
+
|
|
18
23
|
## Examples
|
|
19
24
|
|
|
20
25
|
### All variants
|
|
21
26
|
<Canvas of={Stories.AllVariants} />
|
|
22
27
|
|
|
28
|
+
### Default
|
|
29
|
+
<Canvas of={Stories.Default} />
|
|
30
|
+
|
|
31
|
+
### Elevated
|
|
32
|
+
<Canvas of={Stories.Elevated} />
|
|
33
|
+
|
|
34
|
+
### Outlined
|
|
35
|
+
<Canvas of={Stories.Outlined} />
|
|
36
|
+
|
|
23
37
|
### Clickable
|
|
24
|
-
<Canvas of={Stories.
|
|
38
|
+
<Canvas of={Stories.Clickable} />
|
|
25
39
|
|
|
26
40
|
## Props
|
|
27
41
|
|
|
@@ -31,11 +45,11 @@ import '@boostdev/components/web-components';
|
|
|
31
45
|
|
|
32
46
|
| Attribute | Type | Default | Description |
|
|
33
47
|
|-----------|------|---------|-------------|
|
|
34
|
-
| `variant` | `"default" \| "elevated" \| "outlined"` | `"default"` |
|
|
35
|
-
| `padding` | `"none" \| "small" \| "medium" \| "large"` | `"medium"` |
|
|
36
|
-
| `text-align` | `"start" \| "center" \| "end"` | `"start"` |
|
|
37
|
-
| `clickable` | boolean | `false` | Renders as `<button
|
|
38
|
-
| `aria-label` | string | — | Accessible label (
|
|
48
|
+
| `variant` | `"default" \| "elevated" \| "outlined"` | `"default"` | Shadow and border style |
|
|
49
|
+
| `padding` | `"none" \| "small" \| "medium" \| "large"` | `"medium"` | Inner padding |
|
|
50
|
+
| `text-align` | `"start" \| "center" \| "end"` | `"start"` | Text alignment |
|
|
51
|
+
| `clickable` | boolean | `false` | Renders the card as a `<button>` with hover/active effects |
|
|
52
|
+
| `aria-label` | string | — | Accessible label (recommended when `clickable` is set) |
|
|
39
53
|
|
|
40
54
|
## Slots
|
|
41
55
|
|
|
@@ -45,39 +59,30 @@ import '@boostdev/components/web-components';
|
|
|
45
59
|
|
|
46
60
|
## Events
|
|
47
61
|
|
|
48
|
-
| Event | Detail |
|
|
49
|
-
|
|
50
|
-
| `bds-click` | — |
|
|
62
|
+
| Event | Detail | Description |
|
|
63
|
+
|-------|--------|-------------|
|
|
64
|
+
| `bds-click` | — | Fired when the card button is clicked (only when `clickable` is set) |
|
|
51
65
|
|
|
52
66
|
## CSS Custom Properties
|
|
53
67
|
|
|
54
68
|
| Property | Description |
|
|
55
69
|
|----------|-------------|
|
|
56
70
|
| `--card_color` | Card background colour |
|
|
57
|
-
| `--card_on-color` | Card text colour |
|
|
71
|
+
| `--card_on-color` | Card text/foreground colour |
|
|
58
72
|
|
|
59
73
|
## Usage in plain HTML
|
|
60
74
|
|
|
61
75
|
```html
|
|
62
76
|
<bds-card variant="elevated" padding="large">
|
|
63
|
-
<
|
|
64
|
-
<p>Card body text.</p>
|
|
77
|
+
<p>Card content</p>
|
|
65
78
|
</bds-card>
|
|
66
79
|
|
|
67
|
-
<bds-card clickable aria-label="
|
|
68
|
-
<
|
|
80
|
+
<bds-card clickable aria-label="Open details">
|
|
81
|
+
<p>Clickable card</p>
|
|
69
82
|
</bds-card>
|
|
70
83
|
```
|
|
71
84
|
|
|
72
|
-
Listen for click:
|
|
73
|
-
```js
|
|
74
|
-
document.querySelector('bds-card[clickable]').addEventListener('bds-click', () => {
|
|
75
|
-
console.log('card clicked');
|
|
76
|
-
});
|
|
77
|
-
```
|
|
78
|
-
|
|
79
85
|
## Accessibility
|
|
80
86
|
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
- Always provide `aria-label` on clickable cards when the text content alone is not descriptive
|
|
87
|
+
- Static cards render as `<div>`; clickable cards render as `<button type="button">`
|
|
88
|
+
- Always provide `aria-label` on clickable cards to give a meaningful accessible name
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import type { CardVariant, CardPadding, CardTextAlign } from './bds-card';
|
|
4
|
-
import '../index';
|
|
4
|
+
import '../index'; // auto-registers all custom elements
|
|
5
5
|
|
|
6
6
|
function BdsCard({
|
|
7
|
-
variant,
|
|
8
|
-
padding,
|
|
9
|
-
textAlign,
|
|
7
|
+
variant = 'default',
|
|
8
|
+
padding = 'medium',
|
|
9
|
+
textAlign = 'start',
|
|
10
10
|
clickable,
|
|
11
11
|
ariaLabel,
|
|
12
|
-
onClick,
|
|
13
12
|
children,
|
|
14
13
|
}: {
|
|
15
14
|
variant?: CardVariant;
|
|
@@ -17,7 +16,6 @@ function BdsCard({
|
|
|
17
16
|
textAlign?: CardTextAlign;
|
|
18
17
|
clickable?: boolean;
|
|
19
18
|
ariaLabel?: string;
|
|
20
|
-
onClick?: () => void;
|
|
21
19
|
children?: React.ReactNode;
|
|
22
20
|
}) {
|
|
23
21
|
return React.createElement(
|
|
@@ -28,7 +26,6 @@ function BdsCard({
|
|
|
28
26
|
'text-align': textAlign,
|
|
29
27
|
clickable: clickable || undefined,
|
|
30
28
|
'aria-label': ariaLabel,
|
|
31
|
-
onbdsclick: onClick,
|
|
32
29
|
},
|
|
33
30
|
children,
|
|
34
31
|
);
|
|
@@ -40,51 +37,31 @@ const meta = {
|
|
|
40
37
|
tags: ['!stable', 'experimental'],
|
|
41
38
|
parameters: { layout: 'centered' },
|
|
42
39
|
argTypes: {
|
|
43
|
-
variant:
|
|
44
|
-
padding:
|
|
40
|
+
variant: { control: 'select', options: ['default', 'elevated', 'outlined'] },
|
|
41
|
+
padding: { control: 'select', options: ['none', 'small', 'medium', 'large'] },
|
|
45
42
|
textAlign: { control: 'select', options: ['start', 'center', 'end'] },
|
|
43
|
+
clickable: { control: 'boolean' },
|
|
46
44
|
},
|
|
47
45
|
} satisfies Meta<typeof BdsCard>;
|
|
48
46
|
|
|
49
47
|
export default meta;
|
|
50
48
|
type Story = StoryObj<typeof meta>;
|
|
51
49
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export const Default: Story = { args: { variant: 'default', children: cardContent } };
|
|
60
|
-
export const Elevated: Story = { args: { variant: 'elevated', children: cardContent } };
|
|
61
|
-
export const Outlined: Story = { args: { variant: 'outlined', children: cardContent } };
|
|
62
|
-
export const Clickable: Story = { args: { variant: 'default', clickable: true, ariaLabel: 'Open details', children: cardContent } };
|
|
50
|
+
export const Default: Story = { args: { variant: 'default', padding: 'medium', children: 'Card content goes here.' } };
|
|
51
|
+
export const Elevated: Story = { args: { variant: 'elevated', padding: 'medium', children: 'Elevated card.' } };
|
|
52
|
+
export const Outlined: Story = { args: { variant: 'outlined', padding: 'medium', children: 'Outlined card.' } };
|
|
53
|
+
export const Clickable: Story = {
|
|
54
|
+
args: { variant: 'default', padding: 'medium', clickable: true, ariaLabel: 'Open details', children: 'Clickable card — hover me.' },
|
|
55
|
+
};
|
|
63
56
|
|
|
64
57
|
export const AllVariants: Story = {
|
|
65
58
|
render: () => (
|
|
66
|
-
<div style={{ display: 'flex', gap:
|
|
67
|
-
{(['default', 'elevated', 'outlined'] as const).map(v =>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
))}
|
|
59
|
+
<div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', maxWidth: 600 }}>
|
|
60
|
+
{(['default', 'elevated', 'outlined'] as const).map(v =>
|
|
61
|
+
React.createElement('bds-card', { key: v, variant: v, padding: 'medium', style: 'width: 160px' },
|
|
62
|
+
React.createElement('p', { style: 'margin: 0' }, v),
|
|
63
|
+
),
|
|
64
|
+
)}
|
|
73
65
|
</div>
|
|
74
66
|
),
|
|
75
67
|
};
|
|
76
|
-
|
|
77
|
-
export const Interactive: Story = {
|
|
78
|
-
render: () => {
|
|
79
|
-
const [count, setCount] = React.useState(0);
|
|
80
|
-
return (
|
|
81
|
-
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '16px' }}>
|
|
82
|
-
<BdsCard variant="elevated" clickable ariaLabel="Click me" onClick={() => setCount(c => c + 1)}>
|
|
83
|
-
<strong>Clickable card</strong>
|
|
84
|
-
<p style={{ margin: '8px 0 0' }}>Click to increment counter</p>
|
|
85
|
-
</BdsCard>
|
|
86
|
-
<p style={{ margin: 0 }}>Clicked {count} times</p>
|
|
87
|
-
</div>
|
|
88
|
-
);
|
|
89
|
-
},
|
|
90
|
-
};
|