@boostdev/design-system-components 1.1.2 → 1.2.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.
Files changed (213) hide show
  1. package/AGENTS.md +38 -14
  2. package/dist/client.cjs +85 -103
  3. package/dist/client.css +610 -601
  4. package/dist/client.d.cts +13 -16
  5. package/dist/client.d.ts +13 -16
  6. package/dist/client.js +95 -113
  7. package/dist/index.cjs +85 -103
  8. package/dist/index.css +610 -601
  9. package/dist/index.d.cts +13 -16
  10. package/dist/index.d.ts +13 -16
  11. package/dist/index.js +95 -113
  12. package/dist/native/index.cjs +9 -8
  13. package/dist/native/index.d.cts +1 -1
  14. package/dist/native/index.d.ts +1 -1
  15. package/dist/native/index.js +9 -8
  16. package/dist/web-components/{chunk-K5CE6HSB.js → chunk-2FGATTGT.js} +79 -17
  17. package/dist/web-components/{chunk-O4UFI2RX.js → chunk-3REOIRDW.js} +13 -11
  18. package/dist/web-components/{chunk-5IPHEONG.js → chunk-6I2DBFQ7.js} +1 -0
  19. package/dist/web-components/{chunk-VM3YHGQ2.js → chunk-AJSXNDAP.js} +1 -2
  20. package/dist/web-components/{chunk-LSC4N56Q.js → chunk-BX3IPVOB.js} +1 -2
  21. package/dist/web-components/{chunk-CAPI25CU.js → chunk-DZRSJGPB.js} +3 -3
  22. package/dist/web-components/{chunk-VSS5ITNE.js → chunk-EBJM3VD4.js} +1 -3
  23. package/dist/web-components/{chunk-O7I63SQX.js → chunk-HHHRF2PS.js} +6 -12
  24. package/dist/web-components/{chunk-OTX4COSV.js → chunk-JUKB3BUP.js} +3 -4
  25. package/dist/web-components/{chunk-IQGLIQSO.js → chunk-N6IMUOY4.js} +2 -5
  26. package/dist/web-components/{chunk-CJ5ZOO42.js → chunk-OCODKRVZ.js} +68 -44
  27. package/dist/web-components/{chunk-QDRH46TF.js → chunk-QLZ2362S.js} +1 -3
  28. package/dist/web-components/{chunk-IK3PTFZ4.js → chunk-T6AETZRP.js} +1 -3
  29. package/dist/web-components/{chunk-4BX6AWXX.js → chunk-X3FKVHLK.js} +2 -4
  30. package/dist/web-components/{chunk-A67LCT7C.js → chunk-XNA6WTXG.js} +3 -4
  31. package/dist/web-components/{chunk-XIENXR7H.js → chunk-YRXCVKHV.js} +1 -3
  32. package/dist/web-components/{chunk-6T3RKUKG.js → chunk-ZTC6GRP7.js} +1 -2
  33. package/dist/web-components/globals.js +1 -1
  34. package/dist/web-components/index.d.ts +571 -1
  35. package/dist/web-components/index.js +1515 -18
  36. package/dist/web-components/interaction/bds-accordion.js +1 -1
  37. package/dist/web-components/interaction/bds-button.d.ts +2 -2
  38. package/dist/web-components/interaction/bds-button.js +1 -1
  39. package/dist/web-components/interaction/bds-collapsible.js +1 -1
  40. package/dist/web-components/interaction/bds-dialog.js +1 -1
  41. package/dist/web-components/interaction/bds-drawer.js +1 -1
  42. package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
  43. package/dist/web-components/interaction/form/bds-combobox.js +1 -1
  44. package/dist/web-components/interaction/form/bds-number-input.js +1 -1
  45. package/dist/web-components/interaction/form/bds-radio.js +1 -1
  46. package/dist/web-components/interaction/form/bds-segmented-control.d.ts +20 -3
  47. package/dist/web-components/interaction/form/bds-segmented-control.js +1 -1
  48. package/dist/web-components/interaction/form/bds-select.js +1 -1
  49. package/dist/web-components/interaction/form/bds-switch.js +1 -1
  50. package/dist/web-components/interaction/form/bds-textarea.js +1 -1
  51. package/dist/web-components/ui/bds-alert.js +1 -1
  52. package/dist/web-components/ui/bds-card.js +1 -1
  53. package/dist/web-components/ui/bds-notification-banner.js +1 -1
  54. package/package.json +2 -2
  55. package/src/components/interaction/Button/Button.module.css +12 -11
  56. package/src/components/interaction/Button/Button.native.tsx +10 -9
  57. package/src/components/interaction/Button/Button.tsx +1 -1
  58. package/src/components/interaction/Command/Command.module.css +3 -7
  59. package/src/components/interaction/Dialog/Dialog.module.css +7 -5
  60. package/src/components/interaction/Drawer/Drawer.module.css +48 -25
  61. package/src/components/interaction/Drawer/Drawer.tsx +21 -17
  62. package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +1 -3
  63. package/src/components/interaction/Popover/Popover.module.css +1 -3
  64. package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -3
  65. package/src/components/interaction/form/Combobox/Combobox.module.css +2 -6
  66. package/src/components/interaction/form/FormInput/FormInput.module.css +1 -3
  67. package/src/components/interaction/form/NumberInput/NumberInput.module.css +16 -4
  68. package/src/components/interaction/form/Radio/Radio.module.css +6 -16
  69. package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +74 -25
  70. package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +65 -36
  71. package/src/components/interaction/form/SegmentedControl/SegmentedControl.spec.tsx +127 -56
  72. package/src/components/interaction/form/SegmentedControl/SegmentedControl.stories.tsx +89 -72
  73. package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +40 -62
  74. package/src/components/interaction/form/SegmentedControl/index.ts +1 -1
  75. package/src/components/interaction/form/Select/Select.module.css +2 -4
  76. package/src/components/interaction/form/Switch/Switch.module.css +5 -7
  77. package/src/components/interaction/form/Switch/Switch.native.spec.tsx +9 -9
  78. package/src/components/interaction/form/Switch/Switch.native.tsx +2 -2
  79. package/src/components/interaction/form/Textarea/Textarea.module.css +1 -3
  80. package/src/components/interaction/form/atoms/InputContainer.stories.tsx +64 -0
  81. package/src/components/interaction/form/atoms/Label.stories.tsx +33 -0
  82. package/src/components/interaction/form/atoms/Message.stories.tsx +33 -0
  83. package/src/components/layout/Card/Card.module.css +1 -3
  84. package/src/components/ui/Accordion/Accordion.module.css +1 -2
  85. package/src/components/ui/Alert/Alert.module.css +1 -2
  86. package/src/components/ui/Calendar/Calendar.module.css +2 -5
  87. package/src/components/ui/Carousel/Carousel.module.css +1 -3
  88. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +1 -2
  89. package/src/components/ui/Pagination/Pagination.module.css +1 -2
  90. package/src/components/ui/SkipLink/SkipLink.module.css +1 -2
  91. package/src/components/ui/Table/Table.module.css +1 -2
  92. package/src/css/bdc.css +16 -11
  93. package/src/index.ts +1 -1
  94. package/src/stories/Introduction.mdx +2 -1
  95. package/src/web-components/globals.ts +3 -3
  96. package/src/web-components/index.ts +12 -0
  97. package/src/web-components/interaction/BdsAccordion.mdx +103 -0
  98. package/src/web-components/interaction/BdsAccordion.stories.tsx +94 -0
  99. package/src/web-components/interaction/BdsCollapsible.mdx +116 -0
  100. package/src/web-components/interaction/BdsCollapsible.stories.tsx +68 -0
  101. package/src/web-components/interaction/BdsDialog.mdx +110 -0
  102. package/src/web-components/interaction/BdsDialog.stories.tsx +157 -0
  103. package/src/web-components/interaction/BdsDrawer.mdx +108 -0
  104. package/src/web-components/interaction/BdsDrawer.stories.tsx +196 -0
  105. package/src/web-components/interaction/BdsDropdownMenu.mdx +108 -0
  106. package/src/web-components/interaction/BdsDropdownMenu.stories.tsx +91 -0
  107. package/src/web-components/interaction/BdsSkipLink.mdx +90 -0
  108. package/src/web-components/interaction/BdsSkipLink.stories.tsx +68 -0
  109. package/src/web-components/interaction/BdsTabs.mdx +117 -0
  110. package/src/web-components/interaction/BdsTabs.stories.tsx +94 -0
  111. package/src/web-components/interaction/BdsTooltip.mdx +104 -0
  112. package/src/web-components/interaction/BdsTooltip.stories.tsx +87 -0
  113. package/src/web-components/interaction/bds-accordion.ts +1 -2
  114. package/src/web-components/interaction/bds-button.ts +15 -13
  115. package/src/web-components/interaction/bds-collapsible.ts +1 -0
  116. package/src/web-components/interaction/bds-dialog.ts +2 -5
  117. package/src/web-components/interaction/bds-drawer.ts +70 -44
  118. package/src/web-components/interaction/bds-dropdown-menu-item.ts +124 -0
  119. package/src/web-components/interaction/bds-dropdown-menu.spec.ts +102 -0
  120. package/src/web-components/interaction/bds-dropdown-menu.ts +200 -0
  121. package/src/web-components/interaction/form/BdsCheckbox.mdx +76 -0
  122. package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +72 -0
  123. package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +70 -0
  124. package/src/web-components/interaction/form/BdsCheckboxGroup.stories.tsx +81 -0
  125. package/src/web-components/interaction/form/BdsCombobox.mdx +71 -0
  126. package/src/web-components/interaction/form/BdsCombobox.stories.tsx +93 -0
  127. package/src/web-components/interaction/form/BdsFileInput.mdx +79 -0
  128. package/src/web-components/interaction/form/BdsFileInput.stories.tsx +69 -0
  129. package/src/web-components/interaction/form/BdsFormInput.mdx +98 -0
  130. package/src/web-components/interaction/form/BdsFormInput.stories.tsx +139 -0
  131. package/src/web-components/interaction/form/BdsNumberInput.mdx +70 -0
  132. package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +68 -0
  133. package/src/web-components/interaction/form/BdsRadio.mdx +72 -0
  134. package/src/web-components/interaction/form/BdsRadio.stories.tsx +58 -0
  135. package/src/web-components/interaction/form/BdsRadioGroup.mdx +73 -0
  136. package/src/web-components/interaction/form/BdsRadioGroup.stories.tsx +88 -0
  137. package/src/web-components/interaction/form/BdsSegmentedControl.mdx +95 -0
  138. package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +102 -0
  139. package/src/web-components/interaction/form/BdsSelect.mdx +76 -0
  140. package/src/web-components/interaction/form/BdsSelect.stories.tsx +84 -0
  141. package/src/web-components/interaction/form/BdsSlider.mdx +77 -0
  142. package/src/web-components/interaction/form/BdsSlider.stories.tsx +68 -0
  143. package/src/web-components/interaction/form/BdsSwitch.mdx +72 -0
  144. package/src/web-components/interaction/form/BdsSwitch.stories.tsx +58 -0
  145. package/src/web-components/interaction/form/BdsTextarea.mdx +73 -0
  146. package/src/web-components/interaction/form/BdsTextarea.stories.tsx +70 -0
  147. package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +55 -0
  148. package/src/web-components/interaction/form/bds-checkbox-group.ts +117 -0
  149. package/src/web-components/interaction/form/bds-checkbox.ts +1 -3
  150. package/src/web-components/interaction/form/bds-combobox.ts +1 -3
  151. package/src/web-components/interaction/form/bds-form-input.spec.ts +83 -0
  152. package/src/web-components/interaction/form/bds-form-input.ts +268 -0
  153. package/src/web-components/interaction/form/bds-number-input.ts +3 -4
  154. package/src/web-components/interaction/form/bds-radio-group.spec.ts +62 -0
  155. package/src/web-components/interaction/form/bds-radio-group.ts +142 -0
  156. package/src/web-components/interaction/form/bds-radio.ts +6 -12
  157. package/src/web-components/interaction/form/bds-segmented-control.ts +96 -20
  158. package/src/web-components/interaction/form/bds-select.ts +2 -4
  159. package/src/web-components/interaction/form/bds-switch.ts +3 -4
  160. package/src/web-components/interaction/form/bds-textarea.ts +1 -3
  161. package/src/web-components/ui/BdsAvatar.mdx +76 -0
  162. package/src/web-components/ui/BdsAvatar.stories.tsx +48 -0
  163. package/src/web-components/ui/BdsBreadcrumb.mdx +66 -0
  164. package/src/web-components/ui/BdsBreadcrumb.stories.tsx +49 -0
  165. package/src/web-components/ui/BdsButtonGroup.mdx +69 -0
  166. package/src/web-components/ui/BdsButtonGroup.stories.tsx +66 -0
  167. package/src/web-components/ui/BdsCalendar.mdx +93 -0
  168. package/src/web-components/ui/BdsCalendar.stories.tsx +63 -0
  169. package/src/web-components/ui/BdsCard.mdx +88 -0
  170. package/src/web-components/ui/BdsCard.stories.tsx +67 -0
  171. package/src/web-components/ui/BdsCarousel.mdx +83 -0
  172. package/src/web-components/ui/BdsCarousel.stories.tsx +96 -0
  173. package/src/web-components/ui/BdsDescriptionList.mdx +64 -0
  174. package/src/web-components/ui/BdsDescriptionList.stories.tsx +64 -0
  175. package/src/web-components/ui/BdsIconWrapper.mdx +70 -0
  176. package/src/web-components/ui/BdsIconWrapper.stories.tsx +81 -0
  177. package/src/web-components/ui/BdsLink.mdx +79 -0
  178. package/src/web-components/ui/BdsLink.stories.tsx +63 -0
  179. package/src/web-components/ui/BdsLoading.mdx +58 -0
  180. package/src/web-components/ui/BdsLoading.stories.tsx +35 -0
  181. package/src/web-components/ui/BdsNotificationBanner.mdx +85 -0
  182. package/src/web-components/ui/BdsNotificationBanner.stories.tsx +84 -0
  183. package/src/web-components/ui/BdsPagination.mdx +74 -0
  184. package/src/web-components/ui/BdsPagination.stories.tsx +36 -0
  185. package/src/web-components/ui/BdsProgress.mdx +70 -0
  186. package/src/web-components/ui/BdsProgress.stories.tsx +96 -0
  187. package/src/web-components/ui/BdsProgressCircle.mdx +70 -0
  188. package/src/web-components/ui/BdsProgressCircle.stories.tsx +57 -0
  189. package/src/web-components/ui/BdsRating.mdx +61 -0
  190. package/src/web-components/ui/BdsRating.stories.tsx +45 -0
  191. package/src/web-components/ui/BdsSectionHeader.mdx +72 -0
  192. package/src/web-components/ui/BdsSectionHeader.stories.tsx +54 -0
  193. package/src/web-components/ui/BdsSeparator.mdx +77 -0
  194. package/src/web-components/ui/BdsSeparator.stories.tsx +55 -0
  195. package/src/web-components/ui/BdsSkeleton.mdx +61 -0
  196. package/src/web-components/ui/BdsSkeleton.stories.tsx +50 -0
  197. package/src/web-components/ui/BdsTable.mdx +81 -0
  198. package/src/web-components/ui/BdsTable.stories.tsx +83 -0
  199. package/src/web-components/ui/BdsTypography.mdx +74 -0
  200. package/src/web-components/ui/BdsTypography.stories.tsx +52 -0
  201. package/src/web-components/ui/bds-alert.ts +1 -2
  202. package/src/web-components/ui/bds-button-group.spec.ts +40 -0
  203. package/src/web-components/ui/bds-button-group.ts +78 -0
  204. package/src/web-components/ui/bds-calendar.spec.ts +91 -0
  205. package/src/web-components/ui/bds-calendar.ts +427 -0
  206. package/src/web-components/ui/bds-card.ts +1 -3
  207. package/src/web-components/ui/bds-carousel.spec.ts +64 -0
  208. package/src/web-components/ui/bds-carousel.ts +296 -0
  209. package/src/web-components/ui/bds-notification-banner.ts +1 -2
  210. package/src/web-components/ui/bds-pagination.spec.ts +67 -0
  211. package/src/web-components/ui/bds-pagination.ts +197 -0
  212. package/src/web-components/ui/bds-table.spec.ts +45 -0
  213. package/src/web-components/ui/bds-table.ts +96 -0
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import '../../index'; // auto-registers all custom elements
4
+
5
+ function BdsCheckbox({
6
+ name,
7
+ value,
8
+ checked,
9
+ required,
10
+ disabled,
11
+ children,
12
+ }: {
13
+ name?: string;
14
+ value?: string;
15
+ checked?: boolean;
16
+ required?: boolean;
17
+ disabled?: boolean;
18
+ children?: React.ReactNode;
19
+ }) {
20
+ return React.createElement(
21
+ 'bds-checkbox',
22
+ {
23
+ name,
24
+ value,
25
+ checked: checked || undefined,
26
+ required: required || undefined,
27
+ disabled: disabled || undefined,
28
+ },
29
+ children,
30
+ );
31
+ }
32
+
33
+ const meta = {
34
+ title: 'Web Components/Interaction/Form/Checkbox',
35
+ component: BdsCheckbox,
36
+ tags: ['!stable', 'experimental'],
37
+ parameters: { layout: 'centered' },
38
+ argTypes: {
39
+ checked: { control: 'boolean' },
40
+ required: { control: 'boolean' },
41
+ disabled: { control: 'boolean' },
42
+ },
43
+ } satisfies Meta<typeof BdsCheckbox>;
44
+
45
+ export default meta;
46
+ type Story = StoryObj<typeof meta>;
47
+
48
+ export const Default: Story = {
49
+ args: { name: 'option', value: 'yes', children: 'Accept terms' },
50
+ };
51
+
52
+ export const Checked: Story = {
53
+ args: { name: 'option', value: 'yes', checked: true, children: 'Checked by default' },
54
+ };
55
+
56
+ export const Disabled: Story = {
57
+ args: { name: 'option', value: 'yes', disabled: true, children: 'Disabled' },
58
+ };
59
+
60
+ export const Required: Story = {
61
+ args: { name: 'option', value: 'yes', required: true, children: 'Required field' },
62
+ };
63
+
64
+ export const WithGroup: Story = {
65
+ render: () => (
66
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
67
+ <BdsCheckbox name="interests" value="sports">Sports</BdsCheckbox>
68
+ <BdsCheckbox name="interests" value="music" checked>Music</BdsCheckbox>
69
+ <BdsCheckbox name="interests" value="travel">Travel</BdsCheckbox>
70
+ </div>
71
+ ),
72
+ };
@@ -0,0 +1,70 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as Stories from './BdsCheckboxGroup.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # &lt;bds-checkbox-group&gt;
7
+
8
+ Groups related checkboxes with a shared label, hint, and error message. Renders a `<fieldset>` with a `<legend>` for accessible grouping.
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
+ Use `<bds-checkbox-group>` when you have multiple related checkboxes that belong under a common heading. The `<fieldset>`/`<legend>` structure is announced by screen readers as a group.
21
+
22
+ ## Examples
23
+
24
+ ### Default
25
+ <Canvas of={Stories.Default} />
26
+
27
+ ### With error
28
+ <Canvas of={Stories.WithError} />
29
+
30
+ ### With hint
31
+ <Canvas of={Stories.WithHint} />
32
+
33
+ ### Disabled
34
+ <Canvas of={Stories.Disabled} />
35
+
36
+ ## Props
37
+
38
+ <ArgTypes of={Stories} />
39
+
40
+ ## Attributes
41
+
42
+ | Attribute | Type | Default | Description |
43
+ |------------|---------|---------|----------------------------------------------------|
44
+ | `label` | string | `""` | Group label rendered as `<legend>` |
45
+ | `error` | string | — | Error message shown below items; takes priority over `hint` |
46
+ | `hint` | string | — | Helper text shown below items |
47
+ | `required` | boolean | `false` | Shows a required indicator on the legend |
48
+ | `disabled` | boolean | `false` | Disables the entire fieldset |
49
+
50
+ ## Slots
51
+
52
+ | Slot | Description |
53
+ |-------------|-----------------------------------|
54
+ | `(default)` | `<bds-checkbox>` elements |
55
+
56
+ ## Usage in plain HTML
57
+
58
+ ```html
59
+ <bds-checkbox-group label="Notification preferences" required>
60
+ <bds-checkbox name="email" value="email">Email</bds-checkbox>
61
+ <bds-checkbox name="sms" value="sms">SMS</bds-checkbox>
62
+ </bds-checkbox-group>
63
+ ```
64
+
65
+ ## Accessibility
66
+
67
+ - Renders a `<fieldset>` with a `<legend>`, which is announced as a group by screen readers
68
+ - `required` attribute adds a visual asterisk indicator to the legend
69
+ - `disabled` on the group disables all contained checkboxes via the native `<fieldset disabled>` behaviour
70
+ - Error messages use `role="alert"` so they are announced immediately
@@ -0,0 +1,81 @@
1
+ import React from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import '../../index'; // auto-registers all custom elements
4
+
5
+ function BdsCheckboxGroup({
6
+ label,
7
+ error,
8
+ hint,
9
+ required,
10
+ disabled,
11
+ children,
12
+ }: {
13
+ label?: string;
14
+ error?: string;
15
+ hint?: string;
16
+ required?: boolean;
17
+ disabled?: boolean;
18
+ children?: React.ReactNode;
19
+ }) {
20
+ return React.createElement(
21
+ 'bds-checkbox-group',
22
+ {
23
+ label,
24
+ error,
25
+ hint,
26
+ required: required || undefined,
27
+ disabled: disabled || undefined,
28
+ },
29
+ children,
30
+ );
31
+ }
32
+
33
+ const meta = {
34
+ title: 'Web Components/Interaction/Form/CheckboxGroup',
35
+ component: BdsCheckboxGroup,
36
+ tags: ['!stable', 'experimental'],
37
+ parameters: { layout: 'centered' },
38
+ argTypes: {
39
+ required: { control: 'boolean' },
40
+ disabled: { control: 'boolean' },
41
+ },
42
+ } satisfies Meta<typeof BdsCheckboxGroup>;
43
+
44
+ export default meta;
45
+ type Story = StoryObj<typeof meta>;
46
+
47
+ export const Default: Story = {
48
+ render: () => (
49
+ <BdsCheckboxGroup label="Interests">
50
+ {React.createElement('bds-checkbox', { name: 'sports', value: 'sports' }, 'Sports')}
51
+ {React.createElement('bds-checkbox', { name: 'music', value: 'music' }, 'Music')}
52
+ </BdsCheckboxGroup>
53
+ ),
54
+ };
55
+
56
+ export const WithError: Story = {
57
+ render: () => (
58
+ <BdsCheckboxGroup label="Interests" error="Please select at least one option.">
59
+ {React.createElement('bds-checkbox', { name: 'sports', value: 'sports' }, 'Sports')}
60
+ {React.createElement('bds-checkbox', { name: 'music', value: 'music' }, 'Music')}
61
+ </BdsCheckboxGroup>
62
+ ),
63
+ };
64
+
65
+ export const WithHint: Story = {
66
+ render: () => (
67
+ <BdsCheckboxGroup label="Interests" hint="You can select multiple options.">
68
+ {React.createElement('bds-checkbox', { name: 'sports', value: 'sports' }, 'Sports')}
69
+ {React.createElement('bds-checkbox', { name: 'music', value: 'music' }, 'Music')}
70
+ </BdsCheckboxGroup>
71
+ ),
72
+ };
73
+
74
+ export const Disabled: Story = {
75
+ render: () => (
76
+ <BdsCheckboxGroup label="Interests" disabled>
77
+ {React.createElement('bds-checkbox', { name: 'sports', value: 'sports' }, 'Sports')}
78
+ {React.createElement('bds-checkbox', { name: 'music', value: 'music' }, 'Music')}
79
+ </BdsCheckboxGroup>
80
+ ),
81
+ };
@@ -0,0 +1,71 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as Stories from './BdsCombobox.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # &lt;bds-combobox&gt;
7
+
8
+ Form-associated autocomplete combobox. Renders a text input with a filterable dropdown. Keyboard navigation: `ArrowDown`/`ArrowUp` to move focus, `Enter` to select, `Escape` to close.
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
+ Use `<bds-combobox>` when users need to search and filter a list of options. For a simpler pick-from-list without search, use `<bds-select>`.
21
+
22
+ ## Examples
23
+
24
+ ### Default
25
+ <Canvas of={Stories.Default} />
26
+
27
+ ### With disabled option
28
+ <Canvas of={Stories.WithDisabledOption} />
29
+
30
+ ### Required
31
+ <Canvas of={Stories.Required} />
32
+
33
+ ### Disabled
34
+ <Canvas of={Stories.Disabled} />
35
+
36
+ ## Props
37
+
38
+ <ArgTypes of={Stories} />
39
+
40
+ ## Attributes
41
+
42
+ | Attribute | Type | Default | Description |
43
+ |---------------|---------|---------|------------------------------------------------------------------|
44
+ | `name` | string | `""` | Form field name |
45
+ | `value` | string | `""` | Currently selected value |
46
+ | `options` | string | `"[]"` | JSON array of `{ value, label, disabled? }` option objects |
47
+ | `placeholder` | string | `""` | Input placeholder text |
48
+ | `disabled` | boolean | `false` | Disables the entire combobox |
49
+
50
+ ## Events
51
+
52
+ | Event | Detail | Description |
53
+ |--------------|---------------------------------|--------------------------------------|
54
+ | `bds-change` | `{ value: string, label: string }` | Fired when an option is selected |
55
+
56
+ ## Usage in plain HTML
57
+
58
+ ```html
59
+ <bds-combobox
60
+ name="country"
61
+ placeholder="Search country…"
62
+ options='[{"value":"nl","label":"Netherlands"},{"value":"be","label":"Belgium"}]'
63
+ ></bds-combobox>
64
+ ```
65
+
66
+ ## Accessibility
67
+
68
+ - Uses `role="combobox"` on the input with `aria-expanded`, `aria-autocomplete="list"`, and `aria-haspopup="listbox"`
69
+ - Listbox uses `role="listbox"` and each option uses `role="option"` with `aria-selected` and `aria-disabled`
70
+ - Full keyboard navigation: `ArrowDown`/`ArrowUp` to navigate, `Enter` to select, `Escape` to close
71
+ - Participates in HTML forms via the Form-Associated Custom Elements API
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import '../../index'; // auto-registers all custom elements
4
+
5
+ const COUNTRIES = JSON.stringify([
6
+ { value: 'nl', label: 'Netherlands' },
7
+ { value: 'be', label: 'Belgium' },
8
+ { value: 'de', label: 'Germany' },
9
+ { value: 'fr', label: 'France' },
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
+ ]);
19
+
20
+ function BdsCombobox({
21
+ name,
22
+ value,
23
+ options,
24
+ placeholder,
25
+ disabled,
26
+ }: {
27
+ name?: string;
28
+ value?: string;
29
+ options?: string;
30
+ placeholder?: string;
31
+ disabled?: boolean;
32
+ }) {
33
+ return React.createElement('bds-combobox', {
34
+ name,
35
+ value,
36
+ options,
37
+ placeholder,
38
+ disabled: disabled || undefined,
39
+ });
40
+ }
41
+
42
+ const meta = {
43
+ title: 'Web Components/Interaction/Form/Combobox',
44
+ component: BdsCombobox,
45
+ tags: ['!stable', 'experimental'],
46
+ parameters: { layout: 'centered' },
47
+ argTypes: {
48
+ disabled: { control: 'boolean' },
49
+ },
50
+ decorators: [
51
+ (Story: React.ComponentType) => (
52
+ <div style={{ width: '280px', paddingBlockEnd: '200px' }}>
53
+ <Story />
54
+ </div>
55
+ ),
56
+ ],
57
+ } satisfies Meta<typeof BdsCombobox>;
58
+
59
+ export default meta;
60
+ type Story = StoryObj<typeof meta>;
61
+
62
+ export const Default: Story = {
63
+ args: {
64
+ name: 'country',
65
+ options: COUNTRIES,
66
+ placeholder: 'Search country…',
67
+ },
68
+ };
69
+
70
+ export const WithDisabledOption: Story = {
71
+ args: {
72
+ name: 'country',
73
+ options: COUNTRIES_WITH_DISABLED,
74
+ placeholder: 'Search country…',
75
+ },
76
+ };
77
+
78
+ export const Required: Story = {
79
+ args: {
80
+ name: 'country',
81
+ options: COUNTRIES,
82
+ placeholder: 'Select a country…',
83
+ },
84
+ };
85
+
86
+ export const Disabled: Story = {
87
+ args: {
88
+ name: 'country',
89
+ options: COUNTRIES,
90
+ placeholder: 'Disabled combobox',
91
+ disabled: true,
92
+ },
93
+ };
@@ -0,0 +1,79 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as Stories from './BdsFileInput.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # &lt;bds-file-input&gt;
7
+
8
+ Form-associated file upload zone with drag-and-drop support. Renders a styled drop zone that opens the native file picker on click or keyboard activation.
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
+ Use `<bds-file-input>` wherever users need to attach one or more files to a form. It provides drag-and-drop as a progressive enhancement on top of the native file picker.
21
+
22
+ ## Examples
23
+
24
+ ### Default
25
+ <Canvas of={Stories.Default} />
26
+
27
+ ### Multiple files
28
+ <Canvas of={Stories.Multiple} />
29
+
30
+ ### Accept images only
31
+ <Canvas of={Stories.WithAccept} />
32
+
33
+ ### Accept PDFs and Word documents
34
+ <Canvas of={Stories.WithPDFAccept} />
35
+
36
+ ### Disabled
37
+ <Canvas of={Stories.Disabled} />
38
+
39
+ ## Props
40
+
41
+ <ArgTypes of={Stories} />
42
+
43
+ ## Attributes
44
+
45
+ | Attribute | Type | Default | Description |
46
+ |------------|---------|---------|------------------------------------------------------|
47
+ | `name` | string | `""` | Form field name |
48
+ | `accept` | string | `""` | File types to accept (e.g. `"image/*"`, `".pdf"`) |
49
+ | `multiple` | boolean | `false` | Allow selecting multiple files |
50
+ | `disabled` | boolean | `false` | Disables the file input |
51
+
52
+ ## Slots
53
+
54
+ | Slot | Description |
55
+ |-------------|------------------------------------------------|
56
+ | `(default)` | Drop zone call-to-action text. Defaults to "Drag & drop or click to browse" |
57
+
58
+ ## Events
59
+
60
+ | Event | Detail | Description |
61
+ |--------------|--------------|-----------------------------------------|
62
+ | `bds-change` | `FileList` | Fired when files are selected or dropped |
63
+
64
+ ## Usage in plain HTML
65
+
66
+ ```html
67
+ <bds-file-input name="avatar" accept="image/*">Upload photo</bds-file-input>
68
+
69
+ <!-- Multiple files -->
70
+ <bds-file-input name="documents" accept=".pdf,.docx" multiple></bds-file-input>
71
+ ```
72
+
73
+ ## Accessibility
74
+
75
+ - The drop zone has `role="button"` and `tabindex="0"` so it is keyboard-reachable
76
+ - `aria-label="Upload file"` is set on the zone for screen reader identification
77
+ - `Enter` and `Space` open the native file picker from keyboard focus
78
+ - `disabled` sets `tabindex="-1"` and `pointer-events: none`
79
+ - Participates in HTML forms via the Form-Associated Custom Elements API; files are submitted as `FormData` entries
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import '../../index'; // auto-registers all custom elements
4
+
5
+ function BdsFileInput({
6
+ name,
7
+ accept,
8
+ multiple,
9
+ disabled,
10
+ children,
11
+ }: {
12
+ name?: string;
13
+ accept?: string;
14
+ multiple?: boolean;
15
+ disabled?: boolean;
16
+ children?: React.ReactNode;
17
+ }) {
18
+ return React.createElement(
19
+ 'bds-file-input',
20
+ {
21
+ name,
22
+ accept,
23
+ multiple: multiple || undefined,
24
+ disabled: disabled || undefined,
25
+ },
26
+ children,
27
+ );
28
+ }
29
+
30
+ const meta = {
31
+ title: 'Web Components/Interaction/Form/FileInput',
32
+ component: BdsFileInput,
33
+ tags: ['!stable', 'experimental'],
34
+ parameters: { layout: 'centered' },
35
+ argTypes: {
36
+ multiple: { control: 'boolean' },
37
+ disabled: { control: 'boolean' },
38
+ },
39
+ decorators: [
40
+ (Story: React.ComponentType) => (
41
+ <div style={{ width: '360px' }}>
42
+ <Story />
43
+ </div>
44
+ ),
45
+ ],
46
+ } satisfies Meta<typeof BdsFileInput>;
47
+
48
+ export default meta;
49
+ type Story = StoryObj<typeof meta>;
50
+
51
+ export const Default: Story = {
52
+ args: { name: 'file' },
53
+ };
54
+
55
+ export const Multiple: Story = {
56
+ args: { name: 'files', multiple: true },
57
+ };
58
+
59
+ export const WithAccept: Story = {
60
+ args: { name: 'avatar', accept: 'image/*' },
61
+ };
62
+
63
+ export const WithPDFAccept: Story = {
64
+ args: { name: 'document', accept: '.pdf,.docx' },
65
+ };
66
+
67
+ export const Disabled: Story = {
68
+ args: { name: 'file', disabled: true },
69
+ };
@@ -0,0 +1,98 @@
1
+ import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
2
+ import * as Stories from './BdsFormInput.stories';
3
+
4
+ <Meta of={Stories} />
5
+
6
+ # &lt;bds-form-input&gt;
7
+
8
+ Form-associated text input with label, hint, error, and prefix/suffix slot support. 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
+ Use `<bds-form-input>` for single-line text fields in forms. It handles label association, validation states, and prefix/suffix adornments in a single element.
21
+
22
+ ## Examples
23
+
24
+ ### Default
25
+ <Canvas of={Stories.Default} />
26
+
27
+ ### With label
28
+ <Canvas of={Stories.WithLabel} />
29
+
30
+ ### With hint
31
+ <Canvas of={Stories.WithHint} />
32
+
33
+ ### With error
34
+ <Canvas of={Stories.WithError} />
35
+
36
+ ### With prefix (currency symbol)
37
+ <Canvas of={Stories.WithPrefix} />
38
+
39
+ ### With suffix (unit)
40
+ <Canvas of={Stories.WithSuffix} />
41
+
42
+ ### Email type
43
+ <Canvas of={Stories.Email} />
44
+
45
+ ### Disabled
46
+ <Canvas of={Stories.Disabled} />
47
+
48
+ ## Props
49
+
50
+ <ArgTypes of={Stories} />
51
+
52
+ ## Attributes
53
+
54
+ | Attribute | Type | Default | Description |
55
+ |---------------|---------|----------|----------------------------------------------------------------|
56
+ | `name` | string | `""` | Form field name |
57
+ | `type` | string | `"text"` | Input type: `text`, `email`, `password`, `search`, `url`, `tel` |
58
+ | `value` | string | `""` | Current input value |
59
+ | `placeholder` | string | `""` | Placeholder text |
60
+ | `label` | string | `""` | Visible label text |
61
+ | `hint` | string | — | Helper text shown below the input |
62
+ | `error` | string | — | Error message; when set the input enters error state |
63
+ | `disabled` | boolean | `false` | Disables the input |
64
+ | `required` | boolean | `false` | Marks the field as required |
65
+
66
+ ## Slots
67
+
68
+ | Slot | Description |
69
+ |----------|-------------------------------------------|
70
+ | `prefix` | Icon or text rendered before the input |
71
+ | `suffix` | Icon or text rendered after the input |
72
+
73
+ ## Events
74
+
75
+ | Event | Detail | Description |
76
+ |--------------|-------------------------|-------------------------------------|
77
+ | `bds-input` | `{ value: string }` | Fired on every keystroke |
78
+ | `bds-change` | `{ value: string }` | Fired when the value is committed |
79
+
80
+ ## Usage in plain HTML
81
+
82
+ ```html
83
+ <bds-form-input name="email" type="email" label="Email address" required></bds-form-input>
84
+
85
+ <!-- With prefix -->
86
+ <bds-form-input name="price" label="Price">
87
+ <span slot="prefix">€</span>
88
+ </bds-form-input>
89
+ ```
90
+
91
+ ## Accessibility
92
+
93
+ - `<label>` is associated with the inner `<input>` via matching `id`/`for` attributes
94
+ - `required` adds `aria-required="true"` and a visual asterisk
95
+ - `error` sets `aria-invalid="true"` and links the error message via `aria-describedby`
96
+ - `hint` is linked via `aria-describedby` for screen reader announcement
97
+ - Error messages use `role="alert"` so they are announced immediately
98
+ - The focus ring is applied to the wrapper element, not the inner input