@boostdev/design-system-components 1.1.0 → 1.1.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 -5
- package/dist/client.cjs +206 -113
- package/dist/client.css +664 -624
- package/dist/client.d.cts +9 -3
- package/dist/client.d.ts +9 -3
- package/dist/client.js +241 -149
- package/dist/index.cjs +206 -113
- package/dist/index.css +664 -624
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +241 -149
- package/dist/web-components/chunk-2QA62WCQ.js +48 -0
- package/dist/web-components/chunk-4BX6AWXX.js +146 -0
- package/dist/web-components/chunk-57TRNCWQ.js +93 -0
- package/dist/web-components/chunk-5IPHEONG.js +139 -0
- package/dist/web-components/chunk-5R6IFELV.js +63 -0
- package/dist/web-components/chunk-5TFWOPLH.js +49 -0
- package/dist/web-components/chunk-6I3CFC26.js +89 -0
- package/dist/web-components/chunk-6T3RKUKG.js +65 -0
- package/dist/web-components/chunk-7FMR53BW.js +127 -0
- package/dist/web-components/chunk-A67LCT7C.js +134 -0
- package/dist/web-components/chunk-AGKJTMJI.js +56 -0
- package/dist/web-components/chunk-BQLZ7I4G.js +56 -0
- package/dist/web-components/chunk-CAPI25CU.js +53 -0
- package/dist/web-components/chunk-CJ5ZOO42.js +229 -0
- package/dist/web-components/chunk-CR5PGUHV.js +109 -0
- package/dist/web-components/chunk-ECW3HHWA.js +185 -0
- package/dist/web-components/chunk-HGBNDR22.js +98 -0
- package/dist/web-components/chunk-IK3PTFZ4.js +133 -0
- package/dist/web-components/chunk-IQGLIQSO.js +188 -0
- package/dist/web-components/chunk-ITHLKR7Q.js +105 -0
- package/dist/web-components/chunk-K5CE6HSB.js +169 -0
- package/dist/web-components/chunk-L3XHOMN6.js +111 -0
- package/dist/{web-components.js → web-components/chunk-LGEZYFUU.js} +62 -834
- package/dist/web-components/chunk-LSC4N56Q.js +168 -0
- package/dist/web-components/chunk-LY62SAVN.js +64 -0
- package/dist/web-components/chunk-O4UFI2RX.js +244 -0
- package/dist/web-components/chunk-O7I63SQX.js +124 -0
- package/dist/web-components/chunk-OHUTLSIQ.js +69 -0
- package/dist/web-components/chunk-OQTRTMAB.js +27 -0
- package/dist/web-components/chunk-OTX4COSV.js +187 -0
- package/dist/web-components/chunk-PY62FTRW.js +179 -0
- package/dist/web-components/chunk-Q4T5BJT6.js +94 -0
- package/dist/web-components/chunk-QDRH46TF.js +281 -0
- package/dist/web-components/chunk-QDST57JC.js +119 -0
- package/dist/web-components/chunk-QPOKHLMQ.js +45 -0
- package/dist/web-components/chunk-SOQQ7RVJ.js +88 -0
- package/dist/web-components/chunk-UFFCKVZE.js +149 -0
- package/dist/web-components/chunk-VM3YHGQ2.js +152 -0
- package/dist/web-components/chunk-VMMVWLXL.js +53 -0
- package/dist/web-components/chunk-VSS5ITNE.js +109 -0
- package/dist/web-components/chunk-XIENXR7H.js +118 -0
- package/dist/web-components/chunk-Y4MAXTMA.js +80 -0
- package/dist/web-components/chunk-YLVTEY23.js +165 -0
- package/dist/web-components/globals.d.ts +2 -0
- package/dist/web-components/globals.js +1 -0
- package/dist/web-components/index.d.ts +41 -0
- package/dist/web-components/index.js +165 -0
- package/dist/web-components/interaction/bds-accordion-item.d.ts +54 -0
- package/dist/web-components/interaction/bds-accordion-item.js +7 -0
- package/dist/web-components/interaction/bds-accordion.d.ts +50 -0
- package/dist/web-components/interaction/bds-accordion.js +7 -0
- package/dist/web-components/interaction/bds-button.d.ts +100 -0
- package/dist/web-components/interaction/bds-button.js +7 -0
- package/dist/web-components/interaction/bds-collapsible.d.ts +52 -0
- package/dist/web-components/interaction/bds-collapsible.js +7 -0
- package/dist/web-components/interaction/bds-dialog.d.ts +56 -0
- package/dist/web-components/interaction/bds-dialog.js +7 -0
- package/dist/web-components/interaction/bds-drawer.d.ts +64 -0
- package/dist/web-components/interaction/bds-drawer.js +7 -0
- package/dist/web-components/interaction/bds-popover.d.ts +62 -0
- package/dist/web-components/interaction/bds-popover.js +7 -0
- package/dist/web-components/interaction/bds-skip-link.d.ts +36 -0
- package/dist/web-components/interaction/bds-skip-link.js +7 -0
- package/dist/web-components/interaction/bds-tab-panel.d.ts +26 -0
- package/dist/web-components/interaction/bds-tab-panel.js +7 -0
- package/dist/web-components/interaction/bds-tab.d.ts +45 -0
- package/dist/web-components/interaction/bds-tab.js +7 -0
- package/dist/web-components/interaction/bds-tabs.d.ts +46 -0
- package/dist/web-components/interaction/bds-tabs.js +7 -0
- package/dist/web-components/interaction/bds-toast-provider.d.ts +57 -0
- package/dist/web-components/interaction/bds-toast-provider.js +7 -0
- package/dist/web-components/interaction/bds-tooltip.d.ts +50 -0
- package/dist/web-components/interaction/bds-tooltip.js +7 -0
- package/dist/web-components/interaction/form/bds-checkbox.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-checkbox.js +7 -0
- package/dist/web-components/interaction/form/bds-combobox.d.ts +84 -0
- package/dist/web-components/interaction/form/bds-combobox.js +7 -0
- package/dist/web-components/interaction/form/bds-file-input.d.ts +62 -0
- package/dist/web-components/interaction/form/bds-file-input.js +7 -0
- package/dist/web-components/interaction/form/bds-number-input.d.ts +68 -0
- package/dist/web-components/interaction/form/bds-number-input.js +7 -0
- package/dist/web-components/interaction/form/bds-radio.d.ts +68 -0
- package/dist/web-components/interaction/form/bds-radio.js +7 -0
- package/dist/web-components/interaction/form/bds-segmented-control.d.ts +71 -0
- package/dist/web-components/interaction/form/bds-segmented-control.js +7 -0
- package/dist/web-components/interaction/form/bds-select.d.ts +79 -0
- package/dist/web-components/interaction/form/bds-select.js +7 -0
- package/dist/web-components/interaction/form/bds-slider.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-slider.js +7 -0
- package/dist/web-components/interaction/form/bds-switch.d.ts +67 -0
- package/dist/web-components/interaction/form/bds-switch.js +7 -0
- package/dist/web-components/interaction/form/bds-textarea.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-textarea.js +7 -0
- package/dist/web-components/ui/bds-alert.d.ts +66 -0
- package/dist/web-components/ui/bds-alert.js +7 -0
- package/dist/web-components/ui/bds-avatar.d.ts +50 -0
- package/dist/web-components/ui/bds-avatar.js +7 -0
- package/dist/web-components/ui/bds-badge.d.ts +35 -0
- package/dist/web-components/ui/bds-badge.js +7 -0
- package/dist/web-components/ui/bds-breadcrumb.d.ts +35 -0
- package/dist/web-components/ui/bds-breadcrumb.js +7 -0
- package/dist/web-components/ui/bds-card.d.ts +72 -0
- package/dist/web-components/ui/bds-card.js +7 -0
- package/dist/web-components/ui/bds-description-list.d.ts +42 -0
- package/dist/web-components/ui/bds-description-list.js +7 -0
- package/dist/web-components/ui/bds-icon-wrapper.d.ts +39 -0
- package/dist/web-components/ui/bds-icon-wrapper.js +7 -0
- package/dist/web-components/ui/bds-link.d.ts +59 -0
- package/dist/web-components/ui/bds-link.js +7 -0
- package/dist/web-components/ui/bds-loading.d.ts +32 -0
- package/dist/web-components/ui/bds-loading.js +7 -0
- package/dist/web-components/ui/bds-notification-banner.d.ts +61 -0
- package/dist/web-components/ui/bds-notification-banner.js +7 -0
- package/dist/web-components/ui/bds-progress-circle.d.ts +53 -0
- package/dist/web-components/ui/bds-progress-circle.js +7 -0
- package/dist/web-components/ui/bds-progress.d.ts +54 -0
- package/dist/web-components/ui/bds-progress.js +7 -0
- package/dist/web-components/ui/bds-rating.d.ts +36 -0
- package/dist/web-components/ui/bds-rating.js +7 -0
- package/dist/web-components/ui/bds-section-header.d.ts +53 -0
- package/dist/web-components/ui/bds-section-header.js +8 -0
- package/dist/web-components/ui/bds-separator.d.ts +32 -0
- package/dist/web-components/ui/bds-separator.js +7 -0
- package/dist/web-components/ui/bds-skeleton.d.ts +22 -0
- package/dist/web-components/ui/bds-skeleton.js +7 -0
- package/dist/web-components/ui/bds-typography.d.ts +44 -0
- package/dist/web-components/ui/bds-typography.js +8 -0
- package/package.json +169 -4
- package/src/components/interaction/Button/Button.module.css +1 -1
- package/src/components/interaction/Button/Button.native.mdx +72 -0
- package/src/components/interaction/Command/Command.module.css +7 -7
- package/src/components/interaction/Command/Command.spec.tsx +37 -0
- package/src/components/interaction/Command/Command.tsx +37 -2
- package/src/components/interaction/Dialog/Dialog.module.css +10 -13
- package/src/components/interaction/Dialog/Dialog.spec.tsx +53 -1
- package/src/components/interaction/Dialog/Dialog.stories.tsx +17 -0
- package/src/components/interaction/Dialog/Dialog.tsx +50 -16
- package/src/components/interaction/Drawer/Drawer.module.css +11 -11
- package/src/components/interaction/Drawer/Drawer.spec.tsx +48 -1
- package/src/components/interaction/Drawer/Drawer.tsx +38 -4
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +6 -6
- package/src/components/interaction/Popover/Popover.module.css +74 -15
- package/src/components/interaction/Popover/Popover.spec.tsx +94 -59
- package/src/components/interaction/Popover/Popover.tsx +44 -60
- package/src/components/interaction/Toast/Toast.module.css +7 -7
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +6 -6
- package/src/components/interaction/form/Checkbox/Checkbox.native.mdx +74 -0
- package/src/components/interaction/form/Combobox/Combobox.module.css +7 -8
- package/src/components/interaction/form/FileInput/FileInput.module.css +4 -4
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +1 -1
- package/src/components/interaction/form/Radio/Radio.module.css +6 -6
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +5 -6
- package/src/components/interaction/form/Select/Select.module.css +3 -3
- package/src/components/interaction/form/Slider/Slider.module.css +6 -6
- package/src/components/interaction/form/Switch/Switch.module.css +8 -8
- package/src/components/interaction/form/Textarea/Textarea.module.css +1 -1
- package/src/components/layout/IconWrapper/IconWrapper.module.css +2 -2
- package/src/components/ui/Accordion/Accordion.module.css +5 -5
- package/src/components/ui/Alert/Alert.native.mdx +62 -0
- package/src/components/ui/Avatar/Avatar.native.mdx +50 -0
- package/src/components/ui/Badge/Badge.native.mdx +54 -0
- package/src/components/ui/Calendar/Calendar.module.css +7 -7
- package/src/components/ui/Carousel/Carousel.module.css +5 -5
- package/src/components/ui/Collapsible/Collapsible.module.css +4 -4
- package/src/components/ui/Link/Link.module.css +2 -2
- package/src/components/ui/Loading/Loading.module.css +7 -7
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +3 -3
- package/src/components/ui/Pagination/Pagination.module.css +6 -6
- package/src/components/ui/Progress/Progress.module.css +5 -5
- package/src/components/ui/Separator/Separator.module.css +3 -3
- package/src/components/ui/Skeleton/Skeleton.module.css +1 -1
- package/src/components/ui/Table/Table.module.css +9 -9
- package/src/components/ui/Tabs/Tabs.module.css +3 -3
- package/src/components/ui/Tooltip/Tooltip.module.css +8 -8
- package/src/components/ui/Typography/Typography.native.mdx +56 -0
- package/src/polyfill-invoker-commands.ts +68 -0
- package/src/react-augment.d.ts +19 -0
- package/src/stories/ReactNative.mdx +121 -0
- package/src/web-components/index.ts +47 -0
- package/src/web-components/interaction/BdsButton.mdx +106 -0
- package/src/web-components/interaction/BdsPopover.mdx +120 -0
- package/src/web-components/interaction/BdsToastProvider.mdx +94 -0
- package/src/web-components/interaction/bds-accordion-item.spec.ts +75 -0
- package/src/web-components/interaction/bds-accordion-item.ts +181 -0
- package/src/web-components/interaction/bds-accordion.spec.ts +73 -0
- package/src/web-components/interaction/bds-accordion.ts +99 -0
- package/src/web-components/interaction/bds-collapsible.spec.ts +56 -0
- package/src/web-components/interaction/bds-collapsible.ts +170 -0
- package/src/web-components/interaction/bds-dialog.spec.ts +119 -0
- package/src/web-components/interaction/bds-dialog.ts +224 -0
- package/src/web-components/interaction/bds-drawer.spec.ts +113 -0
- package/src/web-components/interaction/bds-drawer.ts +266 -0
- package/src/web-components/interaction/bds-popover.spec.ts +49 -1
- package/src/web-components/interaction/bds-popover.ts +12 -0
- package/src/web-components/interaction/bds-skip-link.spec.ts +42 -0
- package/src/web-components/interaction/bds-skip-link.ts +74 -0
- package/src/web-components/interaction/bds-tab-panel.spec.ts +32 -0
- package/src/web-components/interaction/bds-tab-panel.ts +38 -0
- package/src/web-components/interaction/bds-tab.spec.ts +71 -0
- package/src/web-components/interaction/bds-tab.ts +110 -0
- package/src/web-components/interaction/bds-tabs.spec.ts +120 -0
- package/src/web-components/interaction/bds-tabs.ts +152 -0
- package/src/web-components/interaction/bds-tooltip.spec.ts +49 -0
- package/src/web-components/interaction/bds-tooltip.ts +127 -0
- package/src/web-components/interaction/form/bds-checkbox.spec.ts +63 -0
- package/src/web-components/interaction/form/bds-checkbox.ts +168 -0
- package/src/web-components/interaction/form/bds-combobox.spec.ts +117 -0
- package/src/web-components/interaction/form/bds-combobox.ts +336 -0
- package/src/web-components/interaction/form/bds-file-input.spec.ts +58 -0
- package/src/web-components/interaction/form/bds-file-input.ts +209 -0
- package/src/web-components/interaction/form/bds-number-input.spec.ts +87 -0
- package/src/web-components/interaction/form/bds-number-input.ts +221 -0
- package/src/web-components/interaction/form/bds-radio.spec.ts +70 -0
- package/src/web-components/interaction/form/bds-radio.ts +157 -0
- package/src/web-components/interaction/form/bds-segmented-control.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-segmented-control.ts +211 -0
- package/src/web-components/interaction/form/bds-select.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-select.ts +190 -0
- package/src/web-components/interaction/form/bds-slider.spec.ts +41 -0
- package/src/web-components/interaction/form/bds-slider.ts +162 -0
- package/src/web-components/interaction/form/bds-switch.spec.ts +62 -0
- package/src/web-components/interaction/form/bds-switch.ts +166 -0
- package/src/web-components/interaction/form/bds-textarea.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-textarea.ts +143 -0
- package/src/web-components/test/helpers.ts +8 -0
- package/src/web-components/ui/BdsAlert.mdx +90 -0
- package/src/web-components/ui/BdsBadge.mdx +74 -0
- package/src/web-components/ui/bds-avatar.spec.ts +75 -0
- package/src/web-components/ui/bds-avatar.ts +122 -0
- package/src/web-components/ui/bds-breadcrumb.spec.ts +55 -0
- package/src/web-components/ui/bds-breadcrumb.ts +114 -0
- package/src/web-components/ui/bds-card.spec.ts +70 -0
- package/src/web-components/ui/bds-card.ts +156 -0
- package/src/web-components/ui/bds-description-list.spec.ts +36 -0
- package/src/web-components/ui/bds-description-list.ts +79 -0
- package/src/web-components/ui/bds-icon-wrapper.spec.ts +21 -0
- package/src/web-components/ui/bds-icon-wrapper.ts +68 -0
- package/src/web-components/ui/bds-link.spec.ts +72 -0
- package/src/web-components/ui/bds-link.ts +138 -0
- package/src/web-components/ui/bds-loading.spec.ts +38 -0
- package/src/web-components/ui/bds-loading.ts +76 -0
- package/src/web-components/ui/bds-notification-banner.spec.ts +82 -0
- package/src/web-components/ui/bds-notification-banner.ts +185 -0
- package/src/web-components/ui/bds-progress-circle.spec.ts +58 -0
- package/src/web-components/ui/bds-progress-circle.ts +142 -0
- package/src/web-components/ui/bds-progress.spec.ts +66 -0
- package/src/web-components/ui/bds-progress.ts +127 -0
- package/src/web-components/ui/bds-rating.spec.ts +70 -0
- package/src/web-components/ui/bds-rating.ts +80 -0
- package/src/web-components/ui/bds-section-header.spec.ts +57 -0
- package/src/web-components/ui/bds-section-header.ts +96 -0
- package/src/web-components/ui/bds-separator.spec.ts +50 -0
- package/src/web-components/ui/bds-separator.ts +66 -0
- package/src/web-components/ui/bds-skeleton.spec.ts +22 -0
- package/src/web-components/ui/bds-skeleton.ts +55 -0
- package/src/web-components/ui/bds-typography.spec.ts +76 -0
- package/src/web-components/ui/bds-typography.ts +112 -0
- package/dist/web-components.d.ts +0 -303
|
@@ -32,29 +32,29 @@
|
|
|
32
32
|
|
|
33
33
|
/* Placement: top (default) */
|
|
34
34
|
.--placement_top {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
inset-block-end: calc(100% + var(--bds-space_xs));
|
|
36
|
+
inset-inline-start: 50%;
|
|
37
37
|
transform: translateX(-50%);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/* Placement: bottom */
|
|
41
41
|
.--placement_bottom {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
inset-block-start: calc(100% + var(--bds-space_xs));
|
|
43
|
+
inset-inline-start: 50%;
|
|
44
44
|
transform: translateX(-50%);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/* Placement: left */
|
|
48
48
|
.--placement_left {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
inset-inline-end: calc(100% + var(--bds-space_xs));
|
|
50
|
+
inset-block-start: 50%;
|
|
51
51
|
transform: translateY(-50%);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/* Placement: right */
|
|
55
55
|
.--placement_right {
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
inset-inline-start: calc(100% + var(--bds-space_xs));
|
|
57
|
+
inset-block-start: 50%;
|
|
58
58
|
transform: translateY(-50%);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './Typography.native.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# Typography (React Native)
|
|
7
|
+
|
|
8
|
+
React Native typography component wrapping `Text` with semantic variants. Use instead of bare `<Text>` to ensure consistent sizing, weight, and line-height from the design token scale.
|
|
9
|
+
|
|
10
|
+
> **Status: alpha** — API may change before stable release.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { Typography } from '@boostdev/components';
|
|
16
|
+
|
|
17
|
+
<Typography variant="h1">Page title</Typography>
|
|
18
|
+
<Typography variant="body">Body copy text.</Typography>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
### All variants
|
|
24
|
+
<Canvas of={Stories.AllVariants} />
|
|
25
|
+
|
|
26
|
+
### Heading 1
|
|
27
|
+
<Canvas of={Stories.Heading1} />
|
|
28
|
+
|
|
29
|
+
### Heading 2
|
|
30
|
+
<Canvas of={Stories.Heading2} />
|
|
31
|
+
|
|
32
|
+
### Heading 3
|
|
33
|
+
<Canvas of={Stories.Heading3} />
|
|
34
|
+
|
|
35
|
+
### Body
|
|
36
|
+
<Canvas of={Stories.Body} />
|
|
37
|
+
|
|
38
|
+
### Body small
|
|
39
|
+
<Canvas of={Stories.BodySmall} />
|
|
40
|
+
|
|
41
|
+
## Props
|
|
42
|
+
|
|
43
|
+
<ArgTypes of={Stories} />
|
|
44
|
+
|
|
45
|
+
## Props reference
|
|
46
|
+
|
|
47
|
+
| Prop | Type | Default | Description |
|
|
48
|
+
|------|------|---------|-------------|
|
|
49
|
+
| `variant` | `"h1" \| "h2" \| "h3" \| "body" \| "body_s"` | `"body"` | Typographic scale |
|
|
50
|
+
| `children` | `ReactNode` | — | Text content |
|
|
51
|
+
| `style` | `StyleProp<TextStyle>` | — | Override text styles |
|
|
52
|
+
|
|
53
|
+
## Accessibility
|
|
54
|
+
|
|
55
|
+
- `h1`/`h2`/`h3` variants set `accessibilityRole="header"` automatically
|
|
56
|
+
- Override with the `accessibilityRole` prop if the visual hierarchy doesn't match the semantic hierarchy
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoker Commands API polyfill (Baseline 2025).
|
|
3
|
+
*
|
|
4
|
+
* Handles `commandfor` / `command` attributes on <button> elements for browsers
|
|
5
|
+
* that don't yet support the native API. Dispatches a synthetic `command` event
|
|
6
|
+
* on the target element before performing the action — identical to native
|
|
7
|
+
* behaviour — so any existing `command` event listeners continue to work.
|
|
8
|
+
*
|
|
9
|
+
* Supports the dialog-specific commands used by this library:
|
|
10
|
+
* command="show-modal" → dialog.showModal()
|
|
11
|
+
* command="close" → dialog.close()
|
|
12
|
+
*
|
|
13
|
+
* Installation is idempotent and SSR-safe. The function is called automatically
|
|
14
|
+
* when the Dialog component is imported; consumers do not need to call it.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
let installed = false;
|
|
18
|
+
|
|
19
|
+
export function installInvokerCommandsPolyfill(): void {
|
|
20
|
+
if (installed) return;
|
|
21
|
+
if (typeof window === 'undefined') return;
|
|
22
|
+
if ('command' in HTMLButtonElement.prototype) return; // native support present
|
|
23
|
+
|
|
24
|
+
installed = true;
|
|
25
|
+
|
|
26
|
+
document.addEventListener('click', (e: MouseEvent) => {
|
|
27
|
+
const button = (e.target as Element | null)?.closest<HTMLButtonElement>('button[commandfor]');
|
|
28
|
+
if (!button) return;
|
|
29
|
+
|
|
30
|
+
const targetId = button.getAttribute('commandfor');
|
|
31
|
+
const command = button.getAttribute('command');
|
|
32
|
+
if (!targetId || !command) return;
|
|
33
|
+
|
|
34
|
+
const target = document.getElementById(targetId);
|
|
35
|
+
if (!target) return;
|
|
36
|
+
|
|
37
|
+
// Dispatch a synthetic command event that mirrors the native CommandEvent.
|
|
38
|
+
const commandEvent = new Event('command', { cancelable: true, bubbles: false });
|
|
39
|
+
Object.defineProperty(commandEvent, 'command', { value: command, configurable: true });
|
|
40
|
+
Object.defineProperty(commandEvent, 'source', { value: button, configurable: true });
|
|
41
|
+
const notCancelled = target.dispatchEvent(commandEvent);
|
|
42
|
+
|
|
43
|
+
if (!notCancelled) return;
|
|
44
|
+
|
|
45
|
+
if (target instanceof HTMLDialogElement) {
|
|
46
|
+
if (command === 'show-modal' && !target.open) {
|
|
47
|
+
target.showModal();
|
|
48
|
+
} else if (command === 'close' && target.open) {
|
|
49
|
+
target.close();
|
|
50
|
+
}
|
|
51
|
+
} else if (target.hasAttribute('popover') && 'showPopover' in target) {
|
|
52
|
+
// Popover API commands — Popover API is Baseline 2024 so showPopover exists
|
|
53
|
+
// in any browser that lacks native invoker command support.
|
|
54
|
+
const popover = target as HTMLElement & {
|
|
55
|
+
showPopover(): void;
|
|
56
|
+
hidePopover(): void;
|
|
57
|
+
togglePopover(force?: boolean): boolean;
|
|
58
|
+
};
|
|
59
|
+
if (command === 'toggle-popover') {
|
|
60
|
+
popover.togglePopover();
|
|
61
|
+
} else if (command === 'show-popover') {
|
|
62
|
+
popover.showPopover();
|
|
63
|
+
} else if (command === 'hide-popover') {
|
|
64
|
+
popover.hidePopover();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
package/src/react-augment.d.ts
CHANGED
|
@@ -10,4 +10,23 @@ declare module 'react' {
|
|
|
10
10
|
anchorName?: string;
|
|
11
11
|
positionAnchor?: string;
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
// Invoker Commands API (Baseline 2025) — not yet in @types/react.
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
|
+
interface ButtonHTMLAttributes<T> {
|
|
17
|
+
commandfor?: string;
|
|
18
|
+
command?: string;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// CommandEvent and its entry in the DOM event map — not yet in TypeScript's lib.dom.
|
|
23
|
+
declare global {
|
|
24
|
+
interface CommandEvent extends Event {
|
|
25
|
+
readonly command: string;
|
|
26
|
+
readonly source: Element;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface HTMLElementEventMap {
|
|
30
|
+
command: CommandEvent;
|
|
31
|
+
}
|
|
13
32
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="React Native/Overview" />
|
|
4
|
+
|
|
5
|
+
# React Native
|
|
6
|
+
|
|
7
|
+
> **Status: alpha** — components and APIs may change before stable release.
|
|
8
|
+
|
|
9
|
+
`@boostdev/components` ships native implementations for 19 components. These use React Native primitives (`View`, `Text`, `Pressable`, `StyleSheet`) rather than HTML elements, and consume a dedicated token layer instead of CSS custom properties.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @boostdev/components
|
|
15
|
+
# or
|
|
16
|
+
pnpm add @boostdev/components
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Metro automatically resolves the native entry point via the `"react-native"` export condition in `package.json` — no extra configuration needed.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// Import is identical to the web version:
|
|
23
|
+
import { Button, Alert, Badge, Avatar, Typography } from '@boostdev/components';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Setup — ThemeProvider
|
|
27
|
+
|
|
28
|
+
Wrap your app (or the relevant subtree) in `ThemeProvider` to give native components access to the design token context:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { ThemeProvider } from '@boostdev/components/native/ThemeContext';
|
|
32
|
+
|
|
33
|
+
export default function App() {
|
|
34
|
+
return (
|
|
35
|
+
<ThemeProvider>
|
|
36
|
+
{/* your app */}
|
|
37
|
+
</ThemeProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`ThemeProvider` reads the current colour scheme via `useColorScheme()` and applies the corresponding dark/light token set automatically.
|
|
43
|
+
|
|
44
|
+
## Design Tokens
|
|
45
|
+
|
|
46
|
+
Native components consume tokens from `src/native/tokens.ts` — a JS object mirroring the CSS custom properties from `@boostdev/design-system-foundation`. Token categories:
|
|
47
|
+
|
|
48
|
+
| Category | Example |
|
|
49
|
+
|----------|---------|
|
|
50
|
+
| `colors` | `tokens.colors.bg`, `tokens.colors.interactive` |
|
|
51
|
+
| `spacing` | `tokens.spacing.xs`, `tokens.spacing.m` |
|
|
52
|
+
| `font` | `tokens.font.sizeBody`, `tokens.font.weightBold` |
|
|
53
|
+
| `border` | `tokens.border.radiusS`, `tokens.border.radiusM` |
|
|
54
|
+
| `zIndex` | `tokens.zIndex.modal` |
|
|
55
|
+
| `animation` | `tokens.animation.duration` |
|
|
56
|
+
|
|
57
|
+
Tokens are accessed inside components via `useTheme()`:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { useTheme } from '@boostdev/components/native/ThemeContext';
|
|
61
|
+
|
|
62
|
+
function MyComponent() {
|
|
63
|
+
const { tokens } = useTheme();
|
|
64
|
+
return <View style={{ backgroundColor: tokens.colors.bg }} />;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Available Components
|
|
69
|
+
|
|
70
|
+
### UI
|
|
71
|
+
|
|
72
|
+
| Component | Description |
|
|
73
|
+
|-----------|-------------|
|
|
74
|
+
| `Typography` | Text with semantic variants: `h1`, `h2`, `h3`, `body`, `body_s` |
|
|
75
|
+
| `Badge` | Short status label with 5 semantic variants |
|
|
76
|
+
| `Avatar` | Initials-based avatar with 3 sizes |
|
|
77
|
+
| `Alert` | Inline status message with optional title and dismiss |
|
|
78
|
+
| `NotificationBanner` | Full-width banner notification |
|
|
79
|
+
| `Progress` | Linear progress bar |
|
|
80
|
+
| `Skeleton` | Loading placeholder |
|
|
81
|
+
| `Loading` | Animated loading spinner |
|
|
82
|
+
| `Separator` | Visual divider |
|
|
83
|
+
|
|
84
|
+
### Layout
|
|
85
|
+
|
|
86
|
+
| Component | Description |
|
|
87
|
+
|-----------|-------------|
|
|
88
|
+
| `Card` | Elevated content container |
|
|
89
|
+
| `SectionHeader` | Section heading with optional action |
|
|
90
|
+
| `ButtonGroup` | Horizontal or vertical button row |
|
|
91
|
+
| `IconWrapper` | Consistent icon sizing wrapper |
|
|
92
|
+
|
|
93
|
+
### Interaction
|
|
94
|
+
|
|
95
|
+
| Component | Description |
|
|
96
|
+
|-----------|-------------|
|
|
97
|
+
| `Button` | Primary action element with `onPress` |
|
|
98
|
+
|
|
99
|
+
### Form
|
|
100
|
+
|
|
101
|
+
| Component | Description |
|
|
102
|
+
|-----------|-------------|
|
|
103
|
+
| `Checkbox` | Controlled checkbox with label, hint, and error |
|
|
104
|
+
| `Radio` | Controlled radio button |
|
|
105
|
+
| `Switch` | Toggle switch |
|
|
106
|
+
| `Label` | Form field label atom |
|
|
107
|
+
| `Message` | Form field hint/error atom |
|
|
108
|
+
|
|
109
|
+
## Key differences from the web components
|
|
110
|
+
|
|
111
|
+
| Web | React Native |
|
|
112
|
+
|-----|-------------|
|
|
113
|
+
| `onClick` | `onPress` |
|
|
114
|
+
| `aria-label` | `accessibilityLabel` |
|
|
115
|
+
| CSS `className` | `StyleSheet` / `style` prop |
|
|
116
|
+
| `children` as string/HTML | `children` must be `<Text>` nodes (RN restriction) |
|
|
117
|
+
| Design tokens via CSS custom properties | Design tokens via `useTheme()` JS object |
|
|
118
|
+
|
|
119
|
+
## Dark mode
|
|
120
|
+
|
|
121
|
+
`ThemeProvider` subscribes to `useColorScheme()` automatically. No extra work is needed — components adapt their colours when the device switches between light and dark mode.
|
|
@@ -10,3 +10,50 @@ export { BdsAlert } from './ui/bds-alert';
|
|
|
10
10
|
// Phase 2 — layout-driven components
|
|
11
11
|
export { BdsPopover } from './interaction/bds-popover';
|
|
12
12
|
export { BdsToastProvider } from './interaction/bds-toast-provider';
|
|
13
|
+
|
|
14
|
+
// Phase 3 — simple UI display
|
|
15
|
+
export { BdsSeparator } from './ui/bds-separator';
|
|
16
|
+
export { BdsSkeleton } from './ui/bds-skeleton';
|
|
17
|
+
export { BdsLoading } from './ui/bds-loading';
|
|
18
|
+
export { BdsAvatar } from './ui/bds-avatar';
|
|
19
|
+
export { BdsTypography } from './ui/bds-typography';
|
|
20
|
+
export { BdsProgress } from './ui/bds-progress';
|
|
21
|
+
export { BdsProgressCircle } from './ui/bds-progress-circle';
|
|
22
|
+
export { BdsRating } from './ui/bds-rating';
|
|
23
|
+
|
|
24
|
+
// Phase 3 — interactive with state
|
|
25
|
+
export { BdsCollapsible } from './interaction/bds-collapsible';
|
|
26
|
+
export { BdsAccordionItem } from './interaction/bds-accordion-item';
|
|
27
|
+
export { BdsAccordion } from './interaction/bds-accordion';
|
|
28
|
+
export { BdsTab } from './interaction/bds-tab';
|
|
29
|
+
export { BdsTabPanel } from './interaction/bds-tab-panel';
|
|
30
|
+
export { BdsTabs } from './interaction/bds-tabs';
|
|
31
|
+
export { BdsTooltip } from './interaction/bds-tooltip';
|
|
32
|
+
export { BdsSkipLink } from './interaction/bds-skip-link';
|
|
33
|
+
|
|
34
|
+
// Phase 4 — modal overlays
|
|
35
|
+
export { BdsDialog } from './interaction/bds-dialog';
|
|
36
|
+
export { BdsDrawer } from './interaction/bds-drawer';
|
|
37
|
+
|
|
38
|
+
// Phase 5 — basic form inputs (ElementInternals)
|
|
39
|
+
export { BdsCheckbox } from './interaction/form/bds-checkbox';
|
|
40
|
+
export { BdsRadio } from './interaction/form/bds-radio';
|
|
41
|
+
export { BdsSwitch } from './interaction/form/bds-switch';
|
|
42
|
+
export { BdsSelect } from './interaction/form/bds-select';
|
|
43
|
+
export { BdsTextarea } from './interaction/form/bds-textarea';
|
|
44
|
+
|
|
45
|
+
// Phase 6 — complex form inputs (ElementInternals)
|
|
46
|
+
export { BdsNumberInput } from './interaction/form/bds-number-input';
|
|
47
|
+
export { BdsSlider } from './interaction/form/bds-slider';
|
|
48
|
+
export { BdsSegmentedControl } from './interaction/form/bds-segmented-control';
|
|
49
|
+
export { BdsFileInput } from './interaction/form/bds-file-input';
|
|
50
|
+
export { BdsCombobox } from './interaction/form/bds-combobox';
|
|
51
|
+
|
|
52
|
+
// Phase 7 — slotted content display
|
|
53
|
+
export { BdsNotificationBanner } from './ui/bds-notification-banner';
|
|
54
|
+
export { BdsCard } from './ui/bds-card';
|
|
55
|
+
export { BdsSectionHeader } from './ui/bds-section-header';
|
|
56
|
+
export { BdsIconWrapper } from './ui/bds-icon-wrapper';
|
|
57
|
+
export { BdsDescriptionList } from './ui/bds-description-list';
|
|
58
|
+
export { BdsBreadcrumb } from './ui/bds-breadcrumb';
|
|
59
|
+
export { BdsLink } from './ui/bds-link';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsButton.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-button>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic button custom element. Renders as `<button>` or `<a>` depending on whether `href` is set. Matches the React `Button` component in variants, sizes, and theming.
|
|
9
|
+
|
|
10
|
+
> **Status: experimental** — API may change before stable release.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
// Register all web components at once
|
|
16
|
+
import '@boostdev/components/web-components';
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or in HTML without a bundler:
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<script type="module">
|
|
23
|
+
import '@boostdev/components/web-components';
|
|
24
|
+
</script>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### All variants & sizes
|
|
30
|
+
<Canvas of={Stories.AllVariants} />
|
|
31
|
+
|
|
32
|
+
### Default
|
|
33
|
+
<Canvas of={Stories.Default} />
|
|
34
|
+
|
|
35
|
+
### Ghost
|
|
36
|
+
<Canvas of={Stories.Ghost} />
|
|
37
|
+
|
|
38
|
+
### Sizes
|
|
39
|
+
<Canvas of={Stories.Small} />
|
|
40
|
+
<Canvas of={Stories.Medium} />
|
|
41
|
+
<Canvas of={Stories.Large} />
|
|
42
|
+
|
|
43
|
+
### Pulse (CTA emphasis)
|
|
44
|
+
<Canvas of={Stories.WithPulse} />
|
|
45
|
+
|
|
46
|
+
### Disabled
|
|
47
|
+
<Canvas of={Stories.Disabled} />
|
|
48
|
+
|
|
49
|
+
## Props
|
|
50
|
+
|
|
51
|
+
<ArgTypes of={Stories} />
|
|
52
|
+
|
|
53
|
+
## Attributes
|
|
54
|
+
|
|
55
|
+
| Attribute | Type | Default | Description |
|
|
56
|
+
|-----------|------|---------|-------------|
|
|
57
|
+
| `variant` | `"default" \| "ghost"` | `"default"` | Visual style — filled or transparent outlined |
|
|
58
|
+
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | Height and padding scale |
|
|
59
|
+
| `disabled` | boolean | `false` | Prevents interaction, sets `aria-disabled` |
|
|
60
|
+
| `href` | string | — | Renders as `<a>` when set |
|
|
61
|
+
| `target` | string | — | Forwarded to `<a>` when `href` is set |
|
|
62
|
+
| `rel` | string | — | Forwarded to `<a>` when `href` is set |
|
|
63
|
+
| `type` | `"button" \| "submit" \| "reset"` | `"button"` | Native button type |
|
|
64
|
+
| `has-pulse` | boolean | `false` | Adds animated ring for CTA emphasis |
|
|
65
|
+
| `aria-label` | string | — | Accessible label (required for icon-only buttons) |
|
|
66
|
+
|
|
67
|
+
## Slots
|
|
68
|
+
|
|
69
|
+
| Slot | Description |
|
|
70
|
+
|------|-------------|
|
|
71
|
+
| `(default)` | Button label text |
|
|
72
|
+
| `icon-start` | Icon placed before the label |
|
|
73
|
+
| `icon-end` | Icon placed after the label |
|
|
74
|
+
|
|
75
|
+
## CSS Custom Properties
|
|
76
|
+
|
|
77
|
+
| Property | Description |
|
|
78
|
+
|----------|-------------|
|
|
79
|
+
| `--button_color` | Identity colour — fills the default variant, outlines the ghost variant |
|
|
80
|
+
| `--button_on-color` | Text/icon colour on the button surface. Pair with `--button_color` |
|
|
81
|
+
|
|
82
|
+
## Invoker Commands API
|
|
83
|
+
|
|
84
|
+
`<bds-button>` can control a `<bds-popover>` declaratively using `commandfor` and `command`:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<bds-button commandfor="my-popover" command="--toggle">Open popover</bds-button>
|
|
88
|
+
<bds-popover id="my-popover">
|
|
89
|
+
<p>Popover content</p>
|
|
90
|
+
</bds-popover>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Usage in plain HTML
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<bds-button variant="default" size="medium">Save</bds-button>
|
|
97
|
+
<bds-button variant="ghost">Cancel</bds-button>
|
|
98
|
+
<bds-button href="/dashboard">Go to dashboard</bds-button>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Accessibility
|
|
102
|
+
|
|
103
|
+
- Always provide a label via slot content or `aria-label` (required for icon-only buttons)
|
|
104
|
+
- `disabled` sets `aria-disabled="true"` and prevents click events
|
|
105
|
+
- When rendered as `<a>`, `href` must point to a valid destination
|
|
106
|
+
- `has-pulse` animation respects `prefers-reduced-motion`
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsPopover.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-popover>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic popover custom element. A non-modal floating panel anchored to a trigger element. Uses CSS Anchor Positioning for automatic repositioning when near viewport edges.
|
|
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
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
### Default (bottom)
|
|
21
|
+
<Canvas of={Stories.Default} />
|
|
22
|
+
|
|
23
|
+
### Top
|
|
24
|
+
<Canvas of={Stories.Top} />
|
|
25
|
+
|
|
26
|
+
### Right
|
|
27
|
+
<Canvas of={Stories.Right} />
|
|
28
|
+
|
|
29
|
+
### Left
|
|
30
|
+
<Canvas of={Stories.Left} />
|
|
31
|
+
|
|
32
|
+
### With rich content
|
|
33
|
+
<Canvas of={Stories.WithRichContent} />
|
|
34
|
+
|
|
35
|
+
### All placements
|
|
36
|
+
<Canvas of={Stories.AllPlacements} />
|
|
37
|
+
|
|
38
|
+
## Props
|
|
39
|
+
|
|
40
|
+
<ArgTypes of={Stories} />
|
|
41
|
+
|
|
42
|
+
## Attributes
|
|
43
|
+
|
|
44
|
+
| Attribute | Type | Default | Description |
|
|
45
|
+
|-----------|------|---------|-------------|
|
|
46
|
+
| `placement` | `"bottom" \| "top" \| "left" \| "right"` | `"bottom"` | Preferred panel position relative to the trigger |
|
|
47
|
+
| `open` | boolean | `false` | Controls panel visibility; reflects on the element |
|
|
48
|
+
|
|
49
|
+
## Slots
|
|
50
|
+
|
|
51
|
+
| Slot | Description |
|
|
52
|
+
|------|-------------|
|
|
53
|
+
| `trigger` | Element that opens and closes the panel on click |
|
|
54
|
+
| `(default)` | Panel content |
|
|
55
|
+
|
|
56
|
+
## Events
|
|
57
|
+
|
|
58
|
+
| Event | Detail | Bubbles | Composed | Description |
|
|
59
|
+
|-------|--------|---------|----------|-------------|
|
|
60
|
+
| `bds-open` | — | Yes | Yes | Fired when the panel opens |
|
|
61
|
+
| `bds-close` | — | Yes | Yes | Fired when the panel closes |
|
|
62
|
+
|
|
63
|
+
## Behaviour
|
|
64
|
+
|
|
65
|
+
- Clicking the trigger toggles the panel open/closed
|
|
66
|
+
- Pressing `Escape` closes an open panel
|
|
67
|
+
- Clicking outside the element closes the panel
|
|
68
|
+
- CSS Anchor Positioning automatically tries fallback placements (`@position-try`) when the preferred placement would overflow the viewport
|
|
69
|
+
- Each instance gets a unique CSS anchor name — multiple popovers on the same page don't interfere
|
|
70
|
+
|
|
71
|
+
## Invoker Commands API
|
|
72
|
+
|
|
73
|
+
Control the popover declaratively from any `<button>` using `commandfor` and `command` — no JavaScript required:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<button commandfor="my-popover" command="--toggle">Open</button>
|
|
77
|
+
<button commandfor="my-popover" command="--open">Open only</button>
|
|
78
|
+
<button commandfor="my-popover" command="--close">Close only</button>
|
|
79
|
+
|
|
80
|
+
<bds-popover id="my-popover">
|
|
81
|
+
<p>Panel content</p>
|
|
82
|
+
</bds-popover>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage in plain HTML
|
|
86
|
+
|
|
87
|
+
```html
|
|
88
|
+
<bds-popover placement="bottom">
|
|
89
|
+
<button slot="trigger">Open menu</button>
|
|
90
|
+
<nav>
|
|
91
|
+
<a href="/profile">Profile</a>
|
|
92
|
+
<a href="/settings">Settings</a>
|
|
93
|
+
<a href="/logout">Log out</a>
|
|
94
|
+
</nav>
|
|
95
|
+
</bds-popover>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Listen for open/close events:
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
const popover = document.querySelector('bds-popover');
|
|
102
|
+
popover.addEventListener('bds-open', () => console.log('opened'));
|
|
103
|
+
popover.addEventListener('bds-close', () => console.log('closed'));
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## CSS Custom Properties
|
|
107
|
+
|
|
108
|
+
| Property | Default | Description |
|
|
109
|
+
|----------|---------|-------------|
|
|
110
|
+
| `--popover_color` | `--bds-color_bg` | Panel background |
|
|
111
|
+
| `--popover_on-color` | `--bds-color_on-bg` | Panel text colour |
|
|
112
|
+
| `--popover_shadow` | `--bds-shadow_m` | Panel drop shadow |
|
|
113
|
+
| `--popover_z-index` | `100` | Stacking order |
|
|
114
|
+
|
|
115
|
+
## Accessibility
|
|
116
|
+
|
|
117
|
+
- The panel has `role="region"` and `aria-label="Popover"`
|
|
118
|
+
- The trigger element retains its own role (e.g. `<button>`) — no ARIA is added by the component
|
|
119
|
+
- For menus, use a `<nav>` or `role="menu"` inside the default slot as appropriate
|
|
120
|
+
- The component does not trap focus — use `<bds-dialog>` for modal, focus-trapped overlays
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsToastProvider.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-toast-provider>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic toast notification provider. Wrap your page content in `<bds-toast-provider>` to enable toast notifications that render in the browser top layer (above fixed/sticky elements). Auto-dismisses after 5 seconds.
|
|
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
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
### Static API
|
|
21
|
+
<Canvas of={Stories.Default} />
|
|
22
|
+
|
|
23
|
+
### Event API (no import required)
|
|
24
|
+
<Canvas of={Stories.EventAPI} />
|
|
25
|
+
|
|
26
|
+
## Slots
|
|
27
|
+
|
|
28
|
+
| Slot | Description |
|
|
29
|
+
|------|-------------|
|
|
30
|
+
| `(default)` | Page content. `<bds-toast-provider>` renders as `display: contents` so it is invisible in the layout |
|
|
31
|
+
|
|
32
|
+
## Three ways to show a toast
|
|
33
|
+
|
|
34
|
+
### 1. Static method (import required)
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import { BdsToastProvider } from '@boostdev/components/web-components';
|
|
38
|
+
|
|
39
|
+
BdsToastProvider.show('File saved', 'success');
|
|
40
|
+
BdsToastProvider.show('Something went wrong', 'error');
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. Instance method
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
const provider = document.querySelector('bds-toast-provider');
|
|
47
|
+
provider.showToast('Settings updated', 'info');
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Document event (no import required)
|
|
51
|
+
|
|
52
|
+
Useful in frameworks or contexts where importing the class is inconvenient:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
document.dispatchEvent(new CustomEvent('bds-show-toast', {
|
|
56
|
+
detail: { message: 'Copied to clipboard', variant: 'success' },
|
|
57
|
+
}));
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Toast variants
|
|
61
|
+
|
|
62
|
+
| Variant | Use for |
|
|
63
|
+
|---------|---------|
|
|
64
|
+
| `info` | Neutral status updates |
|
|
65
|
+
| `success` | Completed actions |
|
|
66
|
+
| `warning` | Potential issues the user should know about |
|
|
67
|
+
| `error` | Failures requiring attention |
|
|
68
|
+
|
|
69
|
+
## Setup in plain HTML
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<bds-toast-provider>
|
|
73
|
+
<!-- all your page content goes here -->
|
|
74
|
+
<main>…</main>
|
|
75
|
+
</bds-toast-provider>
|
|
76
|
+
|
|
77
|
+
<script type="module">
|
|
78
|
+
import '@boostdev/components/web-components';
|
|
79
|
+
// or use the document event API — no import needed
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Behaviour
|
|
84
|
+
|
|
85
|
+
- Toasts render in the browser top layer via the Popover API (`popover="manual"`) — they appear above `position: fixed` elements and `z-index` stacking
|
|
86
|
+
- Each toast auto-dismisses after **5000 ms**
|
|
87
|
+
- Multiple toasts stack vertically and each has its own dismissal timer
|
|
88
|
+
- A visible dismiss (×) button is always present on each toast
|
|
89
|
+
|
|
90
|
+
## Accessibility
|
|
91
|
+
|
|
92
|
+
- Each toast renders with `role="status"` + `aria-live="polite"` by default so screen readers announce it without interrupting the user
|
|
93
|
+
- `error` toasts use `role="alert"` + `aria-live="assertive"` for immediate announcement
|
|
94
|
+
- The dismiss button has an accessible label
|