@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
|
@@ -3,36 +3,74 @@ import * as Stories from './BdsSelect.stories';
|
|
|
3
3
|
|
|
4
4
|
<Meta of={Stories} />
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# <bds-select>
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Form-associated select custom element. Wraps a native `<select>` with consistent styling. Options are passed as a JSON attribute because slotting `<option>` elements into shadow DOM is not supported cross-browser.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
options='[{"value":"nl","label":"Netherlands"},{"value":"be","label":"Belgium"}]'
|
|
17
|
-
></bds-select>
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@boostdev/components/web-components';
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
##
|
|
18
|
+
## When to use
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|---------------|-----------|---------|------------------------------------------------------|
|
|
24
|
-
| `name` | `string` | `""` | Form field name |
|
|
25
|
-
| `value` | `string` | `""` | Currently selected value |
|
|
26
|
-
| `options` | `string` | `"[]"` | JSON array of `{ value, label, disabled? }` objects |
|
|
27
|
-
| `placeholder` | `string` | `""` | Placeholder option label (disabled, empty value) |
|
|
28
|
-
| `required` | `boolean` | `false` | Marks the field as required |
|
|
29
|
-
| `disabled` | `boolean` | `false` | Disables the select |
|
|
20
|
+
Use `<bds-select>` for pick-from-list dropdowns where users cannot type to search. For searchable/filterable lists, use `<bds-combobox>` instead.
|
|
30
21
|
|
|
31
|
-
##
|
|
22
|
+
## Examples
|
|
32
23
|
|
|
24
|
+
### Default (pre-selected value)
|
|
33
25
|
<Canvas of={Stories.Default} />
|
|
34
|
-
<Canvas of={Stories.AllVariants} />
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
### With placeholder
|
|
28
|
+
<Canvas of={Stories.WithPlaceholder} />
|
|
29
|
+
|
|
30
|
+
### Required
|
|
31
|
+
<Canvas of={Stories.Required} />
|
|
32
|
+
|
|
33
|
+
### Disabled
|
|
34
|
+
<Canvas of={Stories.Disabled} />
|
|
35
|
+
|
|
36
|
+
### With a disabled option
|
|
37
|
+
<Canvas of={Stories.WithDisabledOption} />
|
|
38
|
+
|
|
39
|
+
## Props
|
|
37
40
|
|
|
38
41
|
<ArgTypes of={Stories} />
|
|
42
|
+
|
|
43
|
+
## Attributes
|
|
44
|
+
|
|
45
|
+
| Attribute | Type | Default | Description |
|
|
46
|
+
|---------------|---------|---------|----------------------------------------------------------------|
|
|
47
|
+
| `name` | string | `""` | Form field name |
|
|
48
|
+
| `value` | string | `""` | Currently selected value |
|
|
49
|
+
| `options` | string | `"[]"` | JSON array of `{ value, label, disabled? }` option objects |
|
|
50
|
+
| `placeholder` | string | `""` | Placeholder option label (disabled, empty value) |
|
|
51
|
+
| `required` | boolean | `false` | Marks the field as required |
|
|
52
|
+
| `disabled` | boolean | `false` | Disables the select |
|
|
53
|
+
|
|
54
|
+
## Events
|
|
55
|
+
|
|
56
|
+
| Event | Detail | Description |
|
|
57
|
+
|----------|--------|-------------------------------------------------------|
|
|
58
|
+
| `change` | — | Native change event forwarded from the inner `<select>` |
|
|
59
|
+
|
|
60
|
+
## Usage in plain HTML
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<bds-select
|
|
64
|
+
name="country"
|
|
65
|
+
placeholder="Choose a country…"
|
|
66
|
+
options='[{"value":"nl","label":"Netherlands"},{"value":"be","label":"Belgium"}]'
|
|
67
|
+
></bds-select>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Accessibility
|
|
71
|
+
|
|
72
|
+
- Wraps a native `<select>` which has full browser and assistive technology support
|
|
73
|
+
- The custom chevron icon is `aria-hidden="true"` to avoid duplicate announcements
|
|
74
|
+
- `required` uses the native `<select required>` attribute for browser validation
|
|
75
|
+
- `disabled` uses the native `<select disabled>` attribute
|
|
76
|
+
- Participates in HTML forms via the Form-Associated Custom Elements API
|
|
@@ -1,31 +1,44 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
-
import
|
|
4
|
-
import '../../index';
|
|
3
|
+
import '../../index'; // auto-registers all custom elements
|
|
5
4
|
|
|
6
|
-
const COUNTRIES
|
|
5
|
+
const COUNTRIES = JSON.stringify([
|
|
7
6
|
{ value: 'nl', label: 'Netherlands' },
|
|
8
7
|
{ value: 'be', label: 'Belgium' },
|
|
9
8
|
{ value: 'de', label: 'Germany' },
|
|
10
9
|
{ value: 'fr', label: 'France' },
|
|
11
|
-
{ value: 'gb', label: 'United Kingdom'
|
|
12
|
-
];
|
|
10
|
+
{ value: 'gb', label: 'United Kingdom' },
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
const COUNTRIES_WITH_DISABLED = JSON.stringify([
|
|
14
|
+
{ value: 'nl', label: 'Netherlands' },
|
|
15
|
+
{ value: 'be', label: 'Belgium' },
|
|
16
|
+
{ value: 'de', label: 'Germany', disabled: true },
|
|
17
|
+
{ value: 'fr', label: 'France' },
|
|
18
|
+
]);
|
|
13
19
|
|
|
14
20
|
function BdsSelect({
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
name,
|
|
22
|
+
value,
|
|
23
|
+
options,
|
|
24
|
+
placeholder,
|
|
17
25
|
required,
|
|
26
|
+
disabled,
|
|
18
27
|
}: {
|
|
28
|
+
name?: string;
|
|
29
|
+
value?: string;
|
|
30
|
+
options?: string;
|
|
19
31
|
placeholder?: string;
|
|
20
|
-
disabled?: boolean;
|
|
21
32
|
required?: boolean;
|
|
33
|
+
disabled?: boolean;
|
|
22
34
|
}) {
|
|
23
35
|
return React.createElement('bds-select', {
|
|
24
|
-
|
|
36
|
+
name,
|
|
37
|
+
value,
|
|
38
|
+
options,
|
|
25
39
|
placeholder,
|
|
26
|
-
disabled: disabled || undefined,
|
|
27
40
|
required: required || undefined,
|
|
28
|
-
|
|
41
|
+
disabled: disabled || undefined,
|
|
29
42
|
});
|
|
30
43
|
}
|
|
31
44
|
|
|
@@ -33,61 +46,39 @@ const meta = {
|
|
|
33
46
|
title: 'Web Components/Interaction/Form/Select',
|
|
34
47
|
component: BdsSelect,
|
|
35
48
|
tags: ['!stable', 'experimental'],
|
|
36
|
-
parameters: { layout: '
|
|
49
|
+
parameters: { layout: 'centered' },
|
|
37
50
|
argTypes: {
|
|
38
|
-
disabled: { control: 'boolean' },
|
|
39
51
|
required: { control: 'boolean' },
|
|
52
|
+
disabled: { control: 'boolean' },
|
|
40
53
|
},
|
|
54
|
+
decorators: [
|
|
55
|
+
(Story: React.ComponentType) => (
|
|
56
|
+
<div style={{ width: '280px' }}>
|
|
57
|
+
<Story />
|
|
58
|
+
</div>
|
|
59
|
+
),
|
|
60
|
+
],
|
|
41
61
|
} satisfies Meta<typeof BdsSelect>;
|
|
42
62
|
|
|
43
63
|
export default meta;
|
|
44
64
|
type Story = StoryObj<typeof meta>;
|
|
45
65
|
|
|
46
|
-
export const Default: Story = {
|
|
47
|
-
|
|
48
|
-
export const WithValue: Story = {
|
|
49
|
-
render: () =>
|
|
50
|
-
React.createElement('bds-select', {
|
|
51
|
-
options: JSON.stringify(COUNTRIES),
|
|
52
|
-
value: 'nl',
|
|
53
|
-
style: { minInlineSize: '200px', display: 'block' },
|
|
54
|
-
}),
|
|
66
|
+
export const Default: Story = {
|
|
67
|
+
args: { name: 'country', options: COUNTRIES, value: 'nl' },
|
|
55
68
|
};
|
|
56
69
|
|
|
57
|
-
export const
|
|
58
|
-
|
|
59
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxInlineSize: '300px' }}>
|
|
60
|
-
<div>
|
|
61
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>Default</p>
|
|
62
|
-
{React.createElement('bds-select', { options: JSON.stringify(COUNTRIES), placeholder: 'Choose…' })}
|
|
63
|
-
</div>
|
|
64
|
-
<div>
|
|
65
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>With value</p>
|
|
66
|
-
{React.createElement('bds-select', { options: JSON.stringify(COUNTRIES), value: 'be' })}
|
|
67
|
-
</div>
|
|
68
|
-
<div>
|
|
69
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>Disabled</p>
|
|
70
|
-
{React.createElement('bds-select', { options: JSON.stringify(COUNTRIES), placeholder: 'Choose…', disabled: true })}
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
),
|
|
70
|
+
export const WithPlaceholder: Story = {
|
|
71
|
+
args: { name: 'country', options: COUNTRIES, placeholder: 'Choose a country…' },
|
|
74
72
|
};
|
|
75
73
|
|
|
76
|
-
export const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
placeholder: 'Select a country…',
|
|
87
|
-
value,
|
|
88
|
-
onChange: (e: Event) => setValue((e.target as HTMLSelectElement).value),
|
|
89
|
-
})}
|
|
90
|
-
</div>
|
|
91
|
-
);
|
|
92
|
-
},
|
|
74
|
+
export const Required: Story = {
|
|
75
|
+
args: { name: 'country', options: COUNTRIES, placeholder: 'Choose a country…', required: true },
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const Disabled: Story = {
|
|
79
|
+
args: { name: 'country', options: COUNTRIES, value: 'nl', disabled: true },
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const WithDisabledOption: Story = {
|
|
83
|
+
args: { name: 'country', options: COUNTRIES_WITH_DISABLED, placeholder: 'Choose a country…' },
|
|
93
84
|
};
|
|
@@ -3,47 +3,75 @@ import * as Stories from './BdsSlider.stories';
|
|
|
3
3
|
|
|
4
4
|
<Meta of={Stories} />
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# <bds-slider>
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Form-associated range slider. Wraps a native `<input type="range">` with a styled fill track driven by the `--slider_fill` CSS custom property.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@boostdev/components/web-components';
|
|
14
16
|
```
|
|
15
17
|
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
Use `<bds-slider>` for continuous or stepped numeric ranges — volume controls, price ranges, ratings, or any value that benefits from visual representation of position within a range.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
### Default (0–100)
|
|
25
|
+
<Canvas of={Stories.Default} />
|
|
26
|
+
|
|
27
|
+
### With step (25)
|
|
28
|
+
<Canvas of={Stories.WithStep} />
|
|
29
|
+
|
|
30
|
+
### With custom min/max (1–5)
|
|
31
|
+
<Canvas of={Stories.WithMinMax} />
|
|
32
|
+
|
|
33
|
+
### Disabled
|
|
34
|
+
<Canvas of={Stories.Disabled} />
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
|
|
38
|
+
<ArgTypes of={Stories} />
|
|
39
|
+
|
|
16
40
|
## Attributes
|
|
17
41
|
|
|
18
|
-
| Attribute | Type
|
|
19
|
-
|
|
20
|
-
| `name` |
|
|
21
|
-
| `value` |
|
|
22
|
-
| `min` |
|
|
23
|
-
| `max` |
|
|
24
|
-
| `step` |
|
|
25
|
-
| `disabled` |
|
|
42
|
+
| Attribute | Type | Default | Description |
|
|
43
|
+
|------------|---------|---------|------------------------------------------|
|
|
44
|
+
| `name` | string | `""` | Form field name |
|
|
45
|
+
| `value` | number | `0` | Current value |
|
|
46
|
+
| `min` | number | `0` | Minimum value |
|
|
47
|
+
| `max` | number | `100` | Maximum value |
|
|
48
|
+
| `step` | number | `1` | Step increment |
|
|
49
|
+
| `disabled` | boolean | `false` | Disables the slider |
|
|
26
50
|
|
|
27
51
|
## Events
|
|
28
52
|
|
|
29
|
-
| Event | Description
|
|
30
|
-
|
|
31
|
-
| `input` | Fired as the user drags
|
|
32
|
-
| `change` | Fired when the user releases
|
|
53
|
+
| Event | Detail | Description |
|
|
54
|
+
|----------|--------|--------------------------------------|
|
|
55
|
+
| `input` | — | Fired continuously as the user drags |
|
|
56
|
+
| `change` | — | Fired when the user releases |
|
|
33
57
|
|
|
34
58
|
## CSS Custom Properties
|
|
35
59
|
|
|
36
|
-
| Property
|
|
37
|
-
|
|
38
|
-
| `--slider_fill-color`
|
|
39
|
-
| `--slider_track-color
|
|
40
|
-
| `--slider_thumb-color
|
|
60
|
+
| Property | Description |
|
|
61
|
+
|-------------------------|-----------------------------------------|
|
|
62
|
+
| `--slider_fill-color` | Fill track colour (defaults to `--bds-color_interactive`) |
|
|
63
|
+
| `--slider_track-color` | Unfilled track colour (defaults to `--bds-color_bg--subtle`) |
|
|
64
|
+
| `--slider_thumb-color` | Thumb colour (defaults to `--bds-color_interactive`) |
|
|
41
65
|
|
|
42
|
-
##
|
|
66
|
+
## Usage in plain HTML
|
|
43
67
|
|
|
44
|
-
|
|
45
|
-
<
|
|
68
|
+
```html
|
|
69
|
+
<bds-slider name="volume" value="50" min="0" max="100" step="5"></bds-slider>
|
|
70
|
+
```
|
|
46
71
|
|
|
47
|
-
##
|
|
72
|
+
## Accessibility
|
|
48
73
|
|
|
49
|
-
|
|
74
|
+
- Wraps a native `<input type="range">` which has full browser and assistive technology support
|
|
75
|
+
- Arrow keys adjust the value by `step`
|
|
76
|
+
- `disabled` prevents interaction and reduces opacity
|
|
77
|
+
- Participates in HTML forms via the Form-Associated Custom Elements API
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
-
import '../../index';
|
|
3
|
+
import '../../index'; // auto-registers all custom elements
|
|
4
4
|
|
|
5
5
|
function BdsSlider({
|
|
6
|
+
name,
|
|
6
7
|
value,
|
|
7
8
|
min,
|
|
8
9
|
max,
|
|
9
10
|
step,
|
|
10
11
|
disabled,
|
|
11
12
|
}: {
|
|
13
|
+
name?: string;
|
|
12
14
|
value?: number;
|
|
13
15
|
min?: number;
|
|
14
16
|
max?: number;
|
|
@@ -16,12 +18,12 @@ function BdsSlider({
|
|
|
16
18
|
disabled?: boolean;
|
|
17
19
|
}) {
|
|
18
20
|
return React.createElement('bds-slider', {
|
|
21
|
+
name,
|
|
19
22
|
value,
|
|
20
23
|
min,
|
|
21
24
|
max,
|
|
22
25
|
step,
|
|
23
26
|
disabled: disabled || undefined,
|
|
24
|
-
style: { display: 'block', maxInlineSize: '320px' },
|
|
25
27
|
});
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -29,7 +31,7 @@ const meta = {
|
|
|
29
31
|
title: 'Web Components/Interaction/Form/Slider',
|
|
30
32
|
component: BdsSlider,
|
|
31
33
|
tags: ['!stable', 'experimental'],
|
|
32
|
-
parameters: { layout: '
|
|
34
|
+
parameters: { layout: 'centered' },
|
|
33
35
|
argTypes: {
|
|
34
36
|
value: { control: 'number' },
|
|
35
37
|
min: { control: 'number' },
|
|
@@ -37,53 +39,30 @@ const meta = {
|
|
|
37
39
|
step: { control: 'number' },
|
|
38
40
|
disabled: { control: 'boolean' },
|
|
39
41
|
},
|
|
42
|
+
decorators: [
|
|
43
|
+
(Story: React.ComponentType) => (
|
|
44
|
+
<div style={{ width: '300px' }}>
|
|
45
|
+
<Story />
|
|
46
|
+
</div>
|
|
47
|
+
),
|
|
48
|
+
],
|
|
40
49
|
} satisfies Meta<typeof BdsSlider>;
|
|
41
50
|
|
|
42
51
|
export default meta;
|
|
43
52
|
type Story = StoryObj<typeof meta>;
|
|
44
53
|
|
|
45
|
-
export const Default: Story = {
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: { name: 'volume', value: 50 },
|
|
56
|
+
};
|
|
48
57
|
|
|
49
|
-
export const
|
|
50
|
-
|
|
51
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px', maxInlineSize: '320px' }}>
|
|
52
|
-
<div>
|
|
53
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>Default (0%)</p>
|
|
54
|
-
{React.createElement('bds-slider', { value: 0, style: { display: 'block' } })}
|
|
55
|
-
</div>
|
|
56
|
-
<div>
|
|
57
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>Mid (50%)</p>
|
|
58
|
-
{React.createElement('bds-slider', { value: 50, style: { display: 'block' } })}
|
|
59
|
-
</div>
|
|
60
|
-
<div>
|
|
61
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>Full (100%)</p>
|
|
62
|
-
{React.createElement('bds-slider', { value: 100, style: { display: 'block' } })}
|
|
63
|
-
</div>
|
|
64
|
-
<div>
|
|
65
|
-
<p style={{ margin: '0 0 4px', fontSize: '0.75rem', color: '#888' }}>Disabled</p>
|
|
66
|
-
{React.createElement('bds-slider', { value: 40, disabled: true, style: { display: 'block' } })}
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
),
|
|
58
|
+
export const WithStep: Story = {
|
|
59
|
+
args: { name: 'volume', value: 25, min: 0, max: 100, step: 25 },
|
|
70
60
|
};
|
|
71
61
|
|
|
72
|
-
export const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
{React.createElement('bds-slider', {
|
|
79
|
-
value: volume,
|
|
80
|
-
min: 0,
|
|
81
|
-
max: 100,
|
|
82
|
-
step: 1,
|
|
83
|
-
style: { display: 'block' },
|
|
84
|
-
onInput: (e: Event) => setVolume(parseFloat((e.target as HTMLInputElement).value)),
|
|
85
|
-
})}
|
|
86
|
-
</div>
|
|
87
|
-
);
|
|
88
|
-
},
|
|
62
|
+
export const WithMinMax: Story = {
|
|
63
|
+
args: { name: 'rating', value: 3, min: 1, max: 5 },
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const Disabled: Story = {
|
|
67
|
+
args: { name: 'volume', value: 40, disabled: true },
|
|
89
68
|
};
|
|
@@ -3,37 +3,70 @@ import * as Stories from './BdsSwitch.stories';
|
|
|
3
3
|
|
|
4
4
|
<Meta of={Stories} />
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# <bds-switch>
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Form-associated toggle switch. Visually a sliding toggle but semantically equivalent to a checkbox (`role="switch"`). Participates in HTML forms via the Form-Associated Custom Elements API.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import '@boostdev/components/web-components';
|
|
14
16
|
```
|
|
15
17
|
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
Use `<bds-switch>` for binary on/off settings where the change takes immediate effect, such as enabling or disabling a feature. For settings that require form submission, `<bds-checkbox>` may be more appropriate.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
### Default (off)
|
|
25
|
+
<Canvas of={Stories.Default} />
|
|
26
|
+
|
|
27
|
+
### Checked (on)
|
|
28
|
+
<Canvas of={Stories.Checked} />
|
|
29
|
+
|
|
30
|
+
### Disabled
|
|
31
|
+
<Canvas of={Stories.Disabled} />
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
<ArgTypes of={Stories} />
|
|
36
|
+
|
|
16
37
|
## Attributes
|
|
17
38
|
|
|
18
|
-
| Attribute | Type
|
|
19
|
-
|
|
20
|
-
| `name` |
|
|
21
|
-
| `value` |
|
|
22
|
-
| `checked` |
|
|
23
|
-
| `required` |
|
|
24
|
-
| `disabled` |
|
|
39
|
+
| Attribute | Type | Default | Description |
|
|
40
|
+
|------------|---------|---------|--------------------------------------------------|
|
|
41
|
+
| `name` | string | `""` | Form field name |
|
|
42
|
+
| `value` | string | `"on"` | Value submitted when the switch is on |
|
|
43
|
+
| `checked` | boolean | `false` | Whether the switch is on |
|
|
44
|
+
| `required` | boolean | `false` | Marks the field as required |
|
|
45
|
+
| `disabled` | boolean | `false` | Disables the switch |
|
|
25
46
|
|
|
26
47
|
## Slots
|
|
27
48
|
|
|
28
|
-
| Slot
|
|
29
|
-
|
|
30
|
-
| (default) | Label text
|
|
49
|
+
| Slot | Description |
|
|
50
|
+
|-------------|--------------------|
|
|
51
|
+
| `(default)` | Label text content |
|
|
31
52
|
|
|
32
|
-
##
|
|
53
|
+
## Events
|
|
33
54
|
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
| Event | Detail | Description |
|
|
56
|
+
|----------|--------|------------------------------------------------|
|
|
57
|
+
| `change` | — | Fired when the switch state changes |
|
|
36
58
|
|
|
37
|
-
##
|
|
59
|
+
## Usage in plain HTML
|
|
38
60
|
|
|
39
|
-
|
|
61
|
+
```html
|
|
62
|
+
<bds-switch name="notifications" value="enabled">Enable notifications</bds-switch>
|
|
63
|
+
<bds-switch name="darkMode" value="on" checked>Dark mode</bds-switch>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Accessibility
|
|
67
|
+
|
|
68
|
+
- Uses `role="switch"` on the inner `<input type="checkbox">` for correct screen reader announcement
|
|
69
|
+
- The inner `<input>` is associated with a `<label>` via matching `id`/`for` attributes
|
|
70
|
+
- The visual track and thumb are inside the `<label>` — clicking the label or the track both toggle the switch
|
|
71
|
+
- `disabled` sets `pointer-events: none` and reduces opacity
|
|
72
|
+
- Participates in HTML forms via the Form-Associated Custom Elements API
|
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
-
import '../../index';
|
|
3
|
+
import '../../index'; // auto-registers all custom elements
|
|
4
4
|
|
|
5
5
|
function BdsSwitch({
|
|
6
|
-
|
|
6
|
+
name,
|
|
7
|
+
value,
|
|
7
8
|
checked,
|
|
9
|
+
required,
|
|
8
10
|
disabled,
|
|
11
|
+
children,
|
|
9
12
|
}: {
|
|
10
|
-
|
|
13
|
+
name?: string;
|
|
14
|
+
value?: string;
|
|
11
15
|
checked?: boolean;
|
|
16
|
+
required?: boolean;
|
|
12
17
|
disabled?: boolean;
|
|
18
|
+
children?: React.ReactNode;
|
|
13
19
|
}) {
|
|
14
20
|
return React.createElement(
|
|
15
21
|
'bds-switch',
|
|
16
22
|
{
|
|
23
|
+
name,
|
|
24
|
+
value,
|
|
17
25
|
checked: checked || undefined,
|
|
26
|
+
required: required || undefined,
|
|
18
27
|
disabled: disabled || undefined,
|
|
19
28
|
},
|
|
20
|
-
|
|
29
|
+
children,
|
|
21
30
|
);
|
|
22
31
|
}
|
|
23
32
|
|
|
@@ -25,9 +34,10 @@ const meta = {
|
|
|
25
34
|
title: 'Web Components/Interaction/Form/Switch',
|
|
26
35
|
component: BdsSwitch,
|
|
27
36
|
tags: ['!stable', 'experimental'],
|
|
28
|
-
parameters: { layout: '
|
|
37
|
+
parameters: { layout: 'centered' },
|
|
29
38
|
argTypes: {
|
|
30
39
|
checked: { control: 'boolean' },
|
|
40
|
+
required: { control: 'boolean' },
|
|
31
41
|
disabled: { control: 'boolean' },
|
|
32
42
|
},
|
|
33
43
|
} satisfies Meta<typeof BdsSwitch>;
|
|
@@ -35,39 +45,14 @@ const meta = {
|
|
|
35
45
|
export default meta;
|
|
36
46
|
type Story = StoryObj<typeof meta>;
|
|
37
47
|
|
|
38
|
-
export const Default: Story = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
export const DisabledOn: Story = { args: { label: 'Always on (managed)', checked: true, disabled: true } };
|
|
48
|
+
export const Default: Story = {
|
|
49
|
+
args: { name: 'notifications', value: 'enabled', children: 'Enable notifications' },
|
|
50
|
+
};
|
|
42
51
|
|
|
43
|
-
export const
|
|
44
|
-
|
|
45
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
46
|
-
{React.createElement('bds-switch', null, 'Off (default)')}
|
|
47
|
-
{React.createElement('bds-switch', { checked: true }, 'On')}
|
|
48
|
-
{React.createElement('bds-switch', { disabled: true }, 'Disabled off')}
|
|
49
|
-
{React.createElement('bds-switch', { checked: true, disabled: true }, 'Disabled on')}
|
|
50
|
-
</div>
|
|
51
|
-
),
|
|
52
|
+
export const Checked: Story = {
|
|
53
|
+
args: { name: 'notifications', value: 'enabled', checked: true, children: 'Notifications enabled' },
|
|
52
54
|
};
|
|
53
55
|
|
|
54
|
-
export const
|
|
55
|
-
|
|
56
|
-
const [enabled, setEnabled] = React.useState(false);
|
|
57
|
-
return (
|
|
58
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
59
|
-
<p style={{ margin: '0 0 8px', fontSize: '0.875rem' }}>
|
|
60
|
-
Dark mode: {enabled ? 'enabled' : 'disabled'}
|
|
61
|
-
</p>
|
|
62
|
-
{React.createElement(
|
|
63
|
-
'bds-switch',
|
|
64
|
-
{
|
|
65
|
-
checked: enabled || undefined,
|
|
66
|
-
onChange: (e: Event) => setEnabled((e.target as HTMLInputElement).checked),
|
|
67
|
-
},
|
|
68
|
-
'Dark mode',
|
|
69
|
-
)}
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
},
|
|
56
|
+
export const Disabled: Story = {
|
|
57
|
+
args: { name: 'notifications', value: 'enabled', disabled: true, children: 'Notifications (disabled)' },
|
|
73
58
|
};
|