@boostdev/design-system-components 1.1.2 → 1.2.0
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 +13 -10
- package/dist/client.cjs +77 -99
- package/dist/client.css +611 -580
- package/dist/client.d.cts +13 -16
- package/dist/client.d.ts +13 -16
- package/dist/client.js +87 -109
- package/dist/index.cjs +77 -99
- package/dist/index.css +611 -580
- package/dist/index.d.cts +13 -16
- package/dist/index.d.ts +13 -16
- package/dist/index.js +87 -109
- package/dist/native/index.cjs +9 -8
- package/dist/native/index.d.cts +1 -1
- package/dist/native/index.d.ts +1 -1
- package/dist/native/index.js +9 -8
- package/dist/web-components/{chunk-O4UFI2RX.js → chunk-3REOIRDW.js} +13 -11
- package/dist/web-components/{chunk-K5CE6HSB.js → chunk-6MH5UWUD.js} +74 -17
- package/dist/web-components/{chunk-VM3YHGQ2.js → chunk-AJSXNDAP.js} +1 -2
- package/dist/web-components/{chunk-LSC4N56Q.js → chunk-BX3IPVOB.js} +1 -2
- package/dist/web-components/{chunk-CJ5ZOO42.js → chunk-DI46Q2EA.js} +50 -1
- package/dist/web-components/{chunk-CAPI25CU.js → chunk-DZRSJGPB.js} +3 -3
- package/dist/web-components/{chunk-VSS5ITNE.js → chunk-EBJM3VD4.js} +1 -3
- package/dist/web-components/{chunk-O7I63SQX.js → chunk-HHHRF2PS.js} +6 -12
- package/dist/web-components/{chunk-OTX4COSV.js → chunk-JUKB3BUP.js} +3 -4
- package/dist/web-components/{chunk-IQGLIQSO.js → chunk-N6IMUOY4.js} +2 -5
- package/dist/web-components/{chunk-QDRH46TF.js → chunk-QLZ2362S.js} +1 -3
- package/dist/web-components/{chunk-IK3PTFZ4.js → chunk-T6AETZRP.js} +1 -3
- package/dist/web-components/{chunk-4BX6AWXX.js → chunk-X3FKVHLK.js} +2 -4
- package/dist/web-components/{chunk-A67LCT7C.js → chunk-XNA6WTXG.js} +3 -4
- package/dist/web-components/{chunk-XIENXR7H.js → chunk-YRXCVKHV.js} +1 -3
- package/dist/web-components/{chunk-6T3RKUKG.js → chunk-ZTC6GRP7.js} +1 -2
- package/dist/web-components/globals.js +1 -1
- package/dist/web-components/index.js +16 -16
- package/dist/web-components/interaction/bds-accordion.js +1 -1
- package/dist/web-components/interaction/bds-button.d.ts +2 -2
- package/dist/web-components/interaction/bds-button.js +1 -1
- package/dist/web-components/interaction/bds-dialog.js +1 -1
- package/dist/web-components/interaction/bds-drawer.js +1 -1
- package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
- package/dist/web-components/interaction/form/bds-combobox.js +1 -1
- package/dist/web-components/interaction/form/bds-number-input.js +1 -1
- package/dist/web-components/interaction/form/bds-radio.js +1 -1
- package/dist/web-components/interaction/form/bds-segmented-control.d.ts +20 -3
- package/dist/web-components/interaction/form/bds-segmented-control.js +1 -1
- package/dist/web-components/interaction/form/bds-select.js +1 -1
- package/dist/web-components/interaction/form/bds-switch.js +1 -1
- package/dist/web-components/interaction/form/bds-textarea.js +1 -1
- package/dist/web-components/ui/bds-alert.js +1 -1
- package/dist/web-components/ui/bds-card.js +1 -1
- package/dist/web-components/ui/bds-notification-banner.js +1 -1
- package/package.json +2 -2
- package/src/components/interaction/Button/Button.module.css +12 -11
- package/src/components/interaction/Button/Button.native.tsx +10 -9
- package/src/components/interaction/Button/Button.tsx +1 -1
- package/src/components/interaction/Command/Command.module.css +3 -7
- package/src/components/interaction/Dialog/Dialog.module.css +7 -5
- package/src/components/interaction/Drawer/Drawer.module.css +49 -1
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +1 -3
- package/src/components/interaction/Popover/Popover.module.css +1 -3
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -3
- package/src/components/interaction/form/Combobox/Combobox.module.css +2 -6
- package/src/components/interaction/form/FormInput/FormInput.module.css +1 -3
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +16 -4
- package/src/components/interaction/form/Radio/Radio.module.css +6 -16
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +70 -25
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +55 -33
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.spec.tsx +127 -56
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.stories.tsx +89 -72
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +40 -62
- package/src/components/interaction/form/SegmentedControl/index.ts +1 -1
- package/src/components/interaction/form/Select/Select.module.css +2 -4
- package/src/components/interaction/form/Switch/Switch.module.css +5 -7
- package/src/components/interaction/form/Switch/Switch.native.spec.tsx +9 -9
- package/src/components/interaction/form/Switch/Switch.native.tsx +2 -2
- package/src/components/interaction/form/Textarea/Textarea.module.css +1 -3
- package/src/components/interaction/form/atoms/InputContainer.stories.tsx +64 -0
- package/src/components/interaction/form/atoms/Label.stories.tsx +33 -0
- package/src/components/interaction/form/atoms/Message.stories.tsx +33 -0
- package/src/components/layout/Card/Card.module.css +1 -3
- package/src/components/ui/Accordion/Accordion.module.css +1 -2
- package/src/components/ui/Alert/Alert.module.css +1 -2
- package/src/components/ui/Calendar/Calendar.module.css +2 -5
- package/src/components/ui/Carousel/Carousel.module.css +1 -3
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +1 -2
- package/src/components/ui/Pagination/Pagination.module.css +1 -2
- package/src/components/ui/SkipLink/SkipLink.module.css +1 -2
- package/src/components/ui/Table/Table.module.css +1 -2
- package/src/css/bdc.css +16 -11
- package/src/index.ts +1 -1
- package/src/web-components/globals.ts +3 -3
- package/src/web-components/interaction/BdsAccordion.mdx +51 -0
- package/src/web-components/interaction/BdsAccordion.stories.tsx +85 -0
- package/src/web-components/interaction/BdsCollapsible.mdx +46 -0
- package/src/web-components/interaction/BdsCollapsible.stories.tsx +87 -0
- package/src/web-components/interaction/BdsDialog.mdx +49 -0
- package/src/web-components/interaction/BdsDialog.stories.tsx +75 -0
- package/src/web-components/interaction/BdsDrawer.mdx +50 -0
- package/src/web-components/interaction/BdsDrawer.stories.tsx +66 -0
- package/src/web-components/interaction/BdsSkipLink.mdx +34 -0
- package/src/web-components/interaction/BdsSkipLink.stories.tsx +55 -0
- package/src/web-components/interaction/BdsTabs.mdx +47 -0
- package/src/web-components/interaction/BdsTabs.stories.tsx +80 -0
- package/src/web-components/interaction/BdsTooltip.mdx +38 -0
- package/src/web-components/interaction/BdsTooltip.stories.tsx +68 -0
- package/src/web-components/interaction/bds-accordion.ts +1 -2
- package/src/web-components/interaction/bds-button.ts +15 -13
- package/src/web-components/interaction/bds-dialog.ts +2 -5
- package/src/web-components/interaction/bds-drawer.ts +50 -1
- package/src/web-components/interaction/form/BdsCheckbox.mdx +39 -0
- package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +73 -0
- package/src/web-components/interaction/form/BdsCombobox.mdx +52 -0
- package/src/web-components/interaction/form/BdsCombobox.stories.tsx +91 -0
- package/src/web-components/interaction/form/BdsFileInput.mdx +44 -0
- package/src/web-components/interaction/form/BdsFileInput.stories.tsx +84 -0
- package/src/web-components/interaction/form/BdsNumberInput.mdx +41 -0
- package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +90 -0
- package/src/web-components/interaction/form/BdsRadio.mdx +41 -0
- package/src/web-components/interaction/form/BdsRadio.stories.tsx +90 -0
- package/src/web-components/interaction/form/BdsSegmentedControl.mdx +42 -0
- package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +92 -0
- package/src/web-components/interaction/form/BdsSelect.mdx +38 -0
- package/src/web-components/interaction/form/BdsSelect.stories.tsx +93 -0
- package/src/web-components/interaction/form/BdsSlider.mdx +49 -0
- package/src/web-components/interaction/form/BdsSlider.stories.tsx +89 -0
- package/src/web-components/interaction/form/BdsSwitch.mdx +39 -0
- package/src/web-components/interaction/form/BdsSwitch.stories.tsx +73 -0
- package/src/web-components/interaction/form/BdsTextarea.mdx +41 -0
- package/src/web-components/interaction/form/BdsTextarea.stories.tsx +79 -0
- package/src/web-components/interaction/form/bds-checkbox.ts +1 -3
- package/src/web-components/interaction/form/bds-combobox.ts +1 -3
- package/src/web-components/interaction/form/bds-number-input.ts +3 -4
- package/src/web-components/interaction/form/bds-radio.ts +6 -12
- package/src/web-components/interaction/form/bds-segmented-control.ts +91 -20
- package/src/web-components/interaction/form/bds-select.ts +2 -4
- package/src/web-components/interaction/form/bds-switch.ts +3 -4
- package/src/web-components/interaction/form/bds-textarea.ts +1 -3
- package/src/web-components/ui/BdsAvatar.mdx +67 -0
- package/src/web-components/ui/BdsAvatar.stories.tsx +62 -0
- package/src/web-components/ui/BdsBreadcrumb.mdx +63 -0
- package/src/web-components/ui/BdsBreadcrumb.stories.tsx +59 -0
- package/src/web-components/ui/BdsCard.mdx +83 -0
- package/src/web-components/ui/BdsCard.stories.tsx +90 -0
- package/src/web-components/ui/BdsDescriptionList.mdx +67 -0
- package/src/web-components/ui/BdsDescriptionList.stories.tsx +79 -0
- package/src/web-components/ui/BdsIconWrapper.mdx +70 -0
- package/src/web-components/ui/BdsIconWrapper.stories.tsx +76 -0
- package/src/web-components/ui/BdsLink.mdx +75 -0
- package/src/web-components/ui/BdsLink.stories.tsx +64 -0
- package/src/web-components/ui/BdsLoading.mdx +62 -0
- package/src/web-components/ui/BdsLoading.stories.tsx +37 -0
- package/src/web-components/ui/BdsNotificationBanner.mdx +90 -0
- package/src/web-components/ui/BdsNotificationBanner.stories.tsx +93 -0
- package/src/web-components/ui/BdsProgress.mdx +63 -0
- package/src/web-components/ui/BdsProgress.stories.tsx +70 -0
- package/src/web-components/ui/BdsProgressCircle.mdx +64 -0
- package/src/web-components/ui/BdsProgressCircle.stories.tsx +69 -0
- package/src/web-components/ui/BdsRating.mdx +61 -0
- package/src/web-components/ui/BdsRating.stories.tsx +39 -0
- package/src/web-components/ui/BdsSectionHeader.mdx +69 -0
- package/src/web-components/ui/BdsSectionHeader.stories.tsx +56 -0
- package/src/web-components/ui/BdsSeparator.mdx +63 -0
- package/src/web-components/ui/BdsSeparator.stories.tsx +47 -0
- package/src/web-components/ui/BdsSkeleton.mdx +67 -0
- package/src/web-components/ui/BdsSkeleton.stories.tsx +50 -0
- package/src/web-components/ui/BdsTypography.mdx +83 -0
- package/src/web-components/ui/BdsTypography.stories.tsx +51 -0
- package/src/web-components/ui/bds-alert.ts +1 -2
- package/src/web-components/ui/bds-card.ts +1 -3
- package/src/web-components/ui/bds-notification-banner.ts +1 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsNotificationBanner.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-notification-banner>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic full-width Notification Banner. Use for page-level messages that require user attention — system notices, maintenance windows, or status updates.
|
|
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
|
+
### All variants
|
|
21
|
+
<Canvas of={Stories.AllVariants} />
|
|
22
|
+
|
|
23
|
+
### Dismissible
|
|
24
|
+
<Canvas of={Stories.Interactive} />
|
|
25
|
+
|
|
26
|
+
### With action
|
|
27
|
+
<Canvas of={Stories.WithAction} />
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
<ArgTypes of={Stories} />
|
|
32
|
+
|
|
33
|
+
## Attributes
|
|
34
|
+
|
|
35
|
+
| Attribute | Type | Default | Description |
|
|
36
|
+
|-----------|------|---------|-------------|
|
|
37
|
+
| `variant` | `"info" \| "success" \| "warning" \| "error"` | `"info"` | Semantic colour and urgency |
|
|
38
|
+
| `dismissible` | boolean | `false` | Shows a dismiss (×) button |
|
|
39
|
+
| `dismiss-label` | string | `"Dismiss notification"` | Accessible label for the dismiss button |
|
|
40
|
+
|
|
41
|
+
## Slots
|
|
42
|
+
|
|
43
|
+
| Slot | Description |
|
|
44
|
+
|------|-------------|
|
|
45
|
+
| `(default)` | Banner body content |
|
|
46
|
+
| `action` | Optional action area (e.g. a button or link) |
|
|
47
|
+
|
|
48
|
+
## Events
|
|
49
|
+
|
|
50
|
+
| Event | Detail | Bubbles | Composed | Description |
|
|
51
|
+
|-------|--------|---------|----------|-------------|
|
|
52
|
+
| `bds-dismiss` | — | Yes | Yes | Fired when the dismiss button is clicked |
|
|
53
|
+
|
|
54
|
+
## CSS Custom Properties
|
|
55
|
+
|
|
56
|
+
| Property | Description |
|
|
57
|
+
|----------|-------------|
|
|
58
|
+
| `--banner_bg` | Banner background colour |
|
|
59
|
+
| `--banner_text` | Banner text colour |
|
|
60
|
+
| `--banner_border` | Bottom border accent colour |
|
|
61
|
+
|
|
62
|
+
## Usage in plain HTML
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<bds-notification-banner variant="success">
|
|
66
|
+
Your changes have been saved.
|
|
67
|
+
</bds-notification-banner>
|
|
68
|
+
|
|
69
|
+
<bds-notification-banner variant="warning" dismissible>
|
|
70
|
+
Scheduled maintenance on Sunday.
|
|
71
|
+
</bds-notification-banner>
|
|
72
|
+
|
|
73
|
+
<bds-notification-banner variant="info">
|
|
74
|
+
New features available.
|
|
75
|
+
<button slot="action" type="button">Learn more</button>
|
|
76
|
+
</bds-notification-banner>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Listen for dismiss:
|
|
80
|
+
```js
|
|
81
|
+
document.querySelector('bds-notification-banner').addEventListener('bds-dismiss', () => {
|
|
82
|
+
// hide or remove the element
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Accessibility
|
|
87
|
+
|
|
88
|
+
- `error` and `warning` variants use `role="alert"` + `aria-live="assertive"` — announced immediately
|
|
89
|
+
- `info` and `success` variants use `role="status"` + `aria-live="polite"` — announced at next opportunity
|
|
90
|
+
- The dismiss button has an accessible label; customize with `dismiss-label` when needed
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import type { NotificationBannerVariant } from './bds-notification-banner';
|
|
4
|
+
import '../index';
|
|
5
|
+
|
|
6
|
+
function BdsNotificationBanner({
|
|
7
|
+
variant = 'info',
|
|
8
|
+
dismissible,
|
|
9
|
+
dismissLabel,
|
|
10
|
+
onDismiss,
|
|
11
|
+
action,
|
|
12
|
+
children,
|
|
13
|
+
}: {
|
|
14
|
+
variant?: NotificationBannerVariant;
|
|
15
|
+
dismissible?: boolean;
|
|
16
|
+
dismissLabel?: string;
|
|
17
|
+
onDismiss?: () => void;
|
|
18
|
+
action?: React.ReactNode;
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
}) {
|
|
21
|
+
return React.createElement(
|
|
22
|
+
'bds-notification-banner',
|
|
23
|
+
{
|
|
24
|
+
variant,
|
|
25
|
+
dismissible: dismissible || undefined,
|
|
26
|
+
'dismiss-label': dismissLabel,
|
|
27
|
+
onbdsdismiss: onDismiss,
|
|
28
|
+
},
|
|
29
|
+
children,
|
|
30
|
+
action ? React.createElement('span', { slot: 'action' }, action) : null,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const meta = {
|
|
35
|
+
title: 'Web Components/UI/NotificationBanner',
|
|
36
|
+
component: BdsNotificationBanner,
|
|
37
|
+
tags: ['!stable', 'experimental'],
|
|
38
|
+
parameters: { layout: 'padded' },
|
|
39
|
+
argTypes: {
|
|
40
|
+
variant: { control: 'select', options: ['info', 'success', 'warning', 'error'] },
|
|
41
|
+
},
|
|
42
|
+
} satisfies Meta<typeof BdsNotificationBanner>;
|
|
43
|
+
|
|
44
|
+
export default meta;
|
|
45
|
+
type Story = StoryObj<typeof meta>;
|
|
46
|
+
|
|
47
|
+
export const Info: Story = { args: { children: 'Your session will expire in 10 minutes.', variant: 'info' } };
|
|
48
|
+
export const Success: Story = { args: { children: 'Your changes have been saved.', variant: 'success' } };
|
|
49
|
+
export const Warning: Story = { args: { children: 'Scheduled maintenance on Sunday 02:00–04:00 UTC.', variant: 'warning' } };
|
|
50
|
+
export const Error: Story = { args: { children: 'Something went wrong. Please try again.', variant: 'error' } };
|
|
51
|
+
export const Dismissible: Story = { args: { children: 'This banner can be dismissed.', variant: 'info', dismissible: true } };
|
|
52
|
+
export const WithAction: Story = {
|
|
53
|
+
render: () => (
|
|
54
|
+
<BdsNotificationBanner
|
|
55
|
+
variant="warning"
|
|
56
|
+
action={React.createElement('button', { type: 'button' }, 'Learn more')}
|
|
57
|
+
>
|
|
58
|
+
New terms of service take effect on Jan 1.
|
|
59
|
+
</BdsNotificationBanner>
|
|
60
|
+
),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const AllVariants: Story = {
|
|
64
|
+
render: () => (
|
|
65
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '0' }}>
|
|
66
|
+
{(['info', 'success', 'warning', 'error'] as const).map(v => (
|
|
67
|
+
<BdsNotificationBanner key={v} variant={v}>
|
|
68
|
+
This is a {v} notification banner.
|
|
69
|
+
</BdsNotificationBanner>
|
|
70
|
+
))}
|
|
71
|
+
</div>
|
|
72
|
+
),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const Interactive: Story = {
|
|
76
|
+
render: () => {
|
|
77
|
+
const [visible, setVisible] = React.useState(true);
|
|
78
|
+
return (
|
|
79
|
+
<div style={{ width: '100%' }}>
|
|
80
|
+
{visible ? (
|
|
81
|
+
<BdsNotificationBanner variant="info" dismissible onDismiss={() => setVisible(false)}>
|
|
82
|
+
Click × to dismiss this banner.
|
|
83
|
+
</BdsNotificationBanner>
|
|
84
|
+
) : (
|
|
85
|
+
<div style={{ padding: '1rem', textAlign: 'center' }}>
|
|
86
|
+
<p style={{ margin: '0 0 8px' }}>Banner dismissed.</p>
|
|
87
|
+
<button onClick={() => setVisible(true)}>Show again</button>
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsProgress.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-progress>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic linear Progress bar custom element. Use to show completion status of a task or upload.
|
|
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
|
+
### All values
|
|
21
|
+
<Canvas of={Stories.AllVariants} />
|
|
22
|
+
|
|
23
|
+
### With label
|
|
24
|
+
<Canvas of={Stories.WithLabel} />
|
|
25
|
+
|
|
26
|
+
### Animated
|
|
27
|
+
<Canvas of={Stories.Interactive} />
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
<ArgTypes of={Stories} />
|
|
32
|
+
|
|
33
|
+
## Attributes
|
|
34
|
+
|
|
35
|
+
| Attribute | Type | Default | Description |
|
|
36
|
+
|-----------|------|---------|-------------|
|
|
37
|
+
| `value` | number | `0` | Current progress value |
|
|
38
|
+
| `max` | number | `100` | Maximum value |
|
|
39
|
+
| `label` | string | — | Accessible label text |
|
|
40
|
+
| `show-label` | boolean | `false` | Displays label and percentage above the bar |
|
|
41
|
+
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | Track thickness |
|
|
42
|
+
|
|
43
|
+
## CSS Custom Properties
|
|
44
|
+
|
|
45
|
+
| Property | Description |
|
|
46
|
+
|----------|-------------|
|
|
47
|
+
| `--progress_color-active` | Fill colour (defaults to `--bdc-color_active`) |
|
|
48
|
+
|
|
49
|
+
## Usage in plain HTML
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<bds-progress value="60"></bds-progress>
|
|
53
|
+
|
|
54
|
+
<bds-progress value="75" label="Upload progress" show-label></bds-progress>
|
|
55
|
+
|
|
56
|
+
<bds-progress value="40" size="large" label="Loading" show-label></bds-progress>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Accessibility
|
|
60
|
+
|
|
61
|
+
- Renders `role="progressbar"` with `aria-valuenow`, `aria-valuemin`, `aria-valuemax`, and `aria-label`
|
|
62
|
+
- Always provide a meaningful `label` for screen reader users
|
|
63
|
+
- Transition animation respects `prefers-reduced-motion`
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../index';
|
|
4
|
+
|
|
5
|
+
function BdsProgress({
|
|
6
|
+
value = 0,
|
|
7
|
+
max,
|
|
8
|
+
label,
|
|
9
|
+
showLabel,
|
|
10
|
+
size,
|
|
11
|
+
}: {
|
|
12
|
+
value?: number;
|
|
13
|
+
max?: number;
|
|
14
|
+
label?: string;
|
|
15
|
+
showLabel?: boolean;
|
|
16
|
+
size?: 'small' | 'medium' | 'large';
|
|
17
|
+
}) {
|
|
18
|
+
return React.createElement('bds-progress', {
|
|
19
|
+
value,
|
|
20
|
+
max,
|
|
21
|
+
label,
|
|
22
|
+
'show-label': showLabel || undefined,
|
|
23
|
+
size,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const meta = {
|
|
28
|
+
title: 'Web Components/UI/Progress',
|
|
29
|
+
component: BdsProgress,
|
|
30
|
+
tags: ['!stable', 'experimental'],
|
|
31
|
+
parameters: { layout: 'padded' },
|
|
32
|
+
argTypes: {
|
|
33
|
+
size: { control: 'select', options: ['small', 'medium', 'large'] },
|
|
34
|
+
},
|
|
35
|
+
} satisfies Meta<typeof BdsProgress>;
|
|
36
|
+
|
|
37
|
+
export default meta;
|
|
38
|
+
type Story = StoryObj<typeof meta>;
|
|
39
|
+
|
|
40
|
+
export const Default: Story = { args: { value: 60 } };
|
|
41
|
+
export const WithLabel: Story = { args: { value: 75, label: 'Upload progress', showLabel: true } };
|
|
42
|
+
export const Complete: Story = { args: { value: 100, label: 'Complete', showLabel: true } };
|
|
43
|
+
export const Small: Story = { args: { value: 40, size: 'small' } };
|
|
44
|
+
export const Medium: Story = { args: { value: 40, size: 'medium' } };
|
|
45
|
+
export const Large: Story = { args: { value: 40, size: 'large' } };
|
|
46
|
+
|
|
47
|
+
export const AllVariants: Story = {
|
|
48
|
+
render: () => (
|
|
49
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '400px' }}>
|
|
50
|
+
{[25, 50, 75, 100].map(v => (
|
|
51
|
+
<BdsProgress key={v} value={v} label={`${v}%`} showLabel />
|
|
52
|
+
))}
|
|
53
|
+
</div>
|
|
54
|
+
),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const Interactive: Story = {
|
|
58
|
+
render: () => {
|
|
59
|
+
const [value, setValue] = React.useState(0);
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
const id = setInterval(() => setValue(v => (v >= 100 ? 0 : v + 5)), 200);
|
|
62
|
+
return () => clearInterval(id);
|
|
63
|
+
}, []);
|
|
64
|
+
return (
|
|
65
|
+
<div style={{ maxWidth: '400px', display: 'flex', flexDirection: 'column', gap: '12px' }}>
|
|
66
|
+
<BdsProgress value={value} label="Loading…" showLabel />
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsProgressCircle.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-progress-circle>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic circular Progress indicator. Uses SVG to render a smooth arc that fills based on `value / max`.
|
|
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
|
+
### All sizes
|
|
21
|
+
<Canvas of={Stories.AllVariants} />
|
|
22
|
+
|
|
23
|
+
### With value
|
|
24
|
+
<Canvas of={Stories.WithValue} />
|
|
25
|
+
|
|
26
|
+
### Animated
|
|
27
|
+
<Canvas of={Stories.Interactive} />
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
<ArgTypes of={Stories} />
|
|
32
|
+
|
|
33
|
+
## Attributes
|
|
34
|
+
|
|
35
|
+
| Attribute | Type | Default | Description |
|
|
36
|
+
|-----------|------|---------|-------------|
|
|
37
|
+
| `value` | number | `0` | Current progress value |
|
|
38
|
+
| `max` | number | `100` | Maximum value |
|
|
39
|
+
| `label` | string | — | Accessible label text |
|
|
40
|
+
| `show-value` | boolean | `false` | Displays the percentage in the centre |
|
|
41
|
+
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | SVG diameter (`40px` / `64px` / `96px`) |
|
|
42
|
+
|
|
43
|
+
## CSS Custom Properties
|
|
44
|
+
|
|
45
|
+
| Property | Description |
|
|
46
|
+
|----------|-------------|
|
|
47
|
+
| `--progressCircle_color-active` | Arc stroke colour (defaults to `--bdc-color_active`) |
|
|
48
|
+
|
|
49
|
+
## Usage in plain HTML
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<bds-progress-circle value="75" label="Loading"></bds-progress-circle>
|
|
53
|
+
|
|
54
|
+
<bds-progress-circle value="65" label="Upload" show-value></bds-progress-circle>
|
|
55
|
+
|
|
56
|
+
<bds-progress-circle value="80" size="large" label="Progress" show-value></bds-progress-circle>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Accessibility
|
|
60
|
+
|
|
61
|
+
- Renders `role="progressbar"` with `aria-valuenow`, `aria-valuemin`, `aria-valuemax`, and `aria-label`
|
|
62
|
+
- Always provide a meaningful `label` for screen readers
|
|
63
|
+
- SVG is hidden from assistive technology (`aria-hidden="true"`) — ARIA attributes are on the container
|
|
64
|
+
- Stroke transition respects `prefers-reduced-motion`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../index';
|
|
4
|
+
|
|
5
|
+
function BdsProgressCircle({
|
|
6
|
+
value = 0,
|
|
7
|
+
max,
|
|
8
|
+
label,
|
|
9
|
+
showValue,
|
|
10
|
+
size,
|
|
11
|
+
}: {
|
|
12
|
+
value?: number;
|
|
13
|
+
max?: number;
|
|
14
|
+
label?: string;
|
|
15
|
+
showValue?: boolean;
|
|
16
|
+
size?: 'small' | 'medium' | 'large';
|
|
17
|
+
}) {
|
|
18
|
+
return React.createElement('bds-progress-circle', {
|
|
19
|
+
value,
|
|
20
|
+
max,
|
|
21
|
+
label,
|
|
22
|
+
'show-value': showValue || undefined,
|
|
23
|
+
size,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const meta = {
|
|
28
|
+
title: 'Web Components/UI/ProgressCircle',
|
|
29
|
+
component: BdsProgressCircle,
|
|
30
|
+
tags: ['!stable', 'experimental'],
|
|
31
|
+
parameters: { layout: 'centered' },
|
|
32
|
+
argTypes: {
|
|
33
|
+
size: { control: 'select', options: ['small', 'medium', 'large'] },
|
|
34
|
+
},
|
|
35
|
+
} satisfies Meta<typeof BdsProgressCircle>;
|
|
36
|
+
|
|
37
|
+
export default meta;
|
|
38
|
+
type Story = StoryObj<typeof meta>;
|
|
39
|
+
|
|
40
|
+
export const Default: Story = { args: { value: 75 } };
|
|
41
|
+
export const WithValue: Story = { args: { value: 65, showValue: true, label: 'Progress' } };
|
|
42
|
+
export const Complete: Story = { args: { value: 100, showValue: true, label: 'Complete' } };
|
|
43
|
+
export const Small: Story = { args: { value: 60, size: 'small', showValue: true } };
|
|
44
|
+
export const Medium: Story = { args: { value: 60, size: 'medium', showValue: true } };
|
|
45
|
+
export const Large: Story = { args: { value: 60, size: 'large', showValue: true } };
|
|
46
|
+
|
|
47
|
+
export const AllVariants: Story = {
|
|
48
|
+
render: () => (
|
|
49
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '32px', flexWrap: 'wrap' }}>
|
|
50
|
+
{(['small', 'medium', 'large'] as const).map(s => (
|
|
51
|
+
<div key={s} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px' }}>
|
|
52
|
+
<BdsProgressCircle value={75} size={s} showValue label="Progress" />
|
|
53
|
+
<span style={{ fontSize: '0.75rem', color: '#888' }}>{s}</span>
|
|
54
|
+
</div>
|
|
55
|
+
))}
|
|
56
|
+
</div>
|
|
57
|
+
),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const Interactive: Story = {
|
|
61
|
+
render: () => {
|
|
62
|
+
const [value, setValue] = React.useState(0);
|
|
63
|
+
React.useEffect(() => {
|
|
64
|
+
const id = setInterval(() => setValue(v => (v >= 100 ? 0 : v + 2)), 100);
|
|
65
|
+
return () => clearInterval(id);
|
|
66
|
+
}, []);
|
|
67
|
+
return <BdsProgressCircle value={value} showValue label="Loading" size="large" />;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsRating.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-rating>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic read-only star Rating display. Use to show a score or user rating.
|
|
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
|
+
### All ratings
|
|
21
|
+
<Canvas of={Stories.AllVariants} />
|
|
22
|
+
|
|
23
|
+
### 5 stars
|
|
24
|
+
<Canvas of={Stories.FiveStars} />
|
|
25
|
+
|
|
26
|
+
### Custom max
|
|
27
|
+
<Canvas of={Stories.Custom} />
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
<ArgTypes of={Stories} />
|
|
32
|
+
|
|
33
|
+
## Attributes
|
|
34
|
+
|
|
35
|
+
| Attribute | Type | Default | Description |
|
|
36
|
+
|-----------|------|---------|-------------|
|
|
37
|
+
| `value` | number | `0` | Number of filled stars |
|
|
38
|
+
| `max` | number | `5` | Total number of stars |
|
|
39
|
+
|
|
40
|
+
## CSS Custom Properties
|
|
41
|
+
|
|
42
|
+
| Property | Description |
|
|
43
|
+
|----------|-------------|
|
|
44
|
+
| `--bds-color_warning` | Filled star colour (foundation token) |
|
|
45
|
+
|
|
46
|
+
## Usage in plain HTML
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<bds-rating value="3"></bds-rating>
|
|
50
|
+
|
|
51
|
+
<bds-rating value="4" max="5"></bds-rating>
|
|
52
|
+
|
|
53
|
+
<!-- Custom scale -->
|
|
54
|
+
<bds-rating value="7" max="10"></bds-rating>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Accessibility
|
|
58
|
+
|
|
59
|
+
- Renders `role="img"` with `aria-label="X out of Y stars"`
|
|
60
|
+
- Individual star SVGs are hidden from assistive technology (`aria-hidden="true"`)
|
|
61
|
+
- This is a read-only display — for interactive ratings, use a radio group pattern
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../index';
|
|
4
|
+
|
|
5
|
+
function BdsRating({ value = 0, max }: { value?: number; max?: number }) {
|
|
6
|
+
return React.createElement('bds-rating', { value, max });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Web Components/UI/Rating',
|
|
11
|
+
component: BdsRating,
|
|
12
|
+
tags: ['!stable', 'experimental'],
|
|
13
|
+
parameters: { layout: 'centered' },
|
|
14
|
+
argTypes: {
|
|
15
|
+
value: { control: { type: 'number', min: 0, max: 10 } },
|
|
16
|
+
max: { control: { type: 'number', min: 1, max: 10 } },
|
|
17
|
+
},
|
|
18
|
+
} satisfies Meta<typeof BdsRating>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof meta>;
|
|
22
|
+
|
|
23
|
+
export const OneStar: Story = { args: { value: 1 } };
|
|
24
|
+
export const ThreeStars: Story = { args: { value: 3 } };
|
|
25
|
+
export const FiveStars: Story = { args: { value: 5 } };
|
|
26
|
+
export const Custom: Story = { args: { value: 7, max: 10 } };
|
|
27
|
+
|
|
28
|
+
export const AllVariants: Story = {
|
|
29
|
+
render: () => (
|
|
30
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
31
|
+
{[1, 2, 3, 4, 5].map(v => (
|
|
32
|
+
<div key={v} style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
33
|
+
<BdsRating value={v} />
|
|
34
|
+
<span style={{ fontSize: '0.875rem', color: '#888' }}>{v}/5</span>
|
|
35
|
+
</div>
|
|
36
|
+
))}
|
|
37
|
+
</div>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsSectionHeader.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# <bds-section-header>
|
|
7
|
+
|
|
8
|
+
Framework-agnostic Section Header custom element. Use to introduce page sections with a title and optional subtitle.
|
|
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
|
+
### All sizes
|
|
21
|
+
<Canvas of={Stories.AllVariants} />
|
|
22
|
+
|
|
23
|
+
### With subtitle
|
|
24
|
+
<Canvas of={Stories.WithSubtitle} />
|
|
25
|
+
|
|
26
|
+
### Center aligned
|
|
27
|
+
<Canvas of={Stories.Center} />
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
<ArgTypes of={Stories} />
|
|
32
|
+
|
|
33
|
+
## Attributes
|
|
34
|
+
|
|
35
|
+
| Attribute | Type | Default | Description |
|
|
36
|
+
|-----------|------|---------|-------------|
|
|
37
|
+
| `title` | string | — | Heading text (required) |
|
|
38
|
+
| `subtitle` | string | — | Optional subheading |
|
|
39
|
+
| `alignment` | `"start" \| "center" \| "end"` | `"start"` | Text alignment |
|
|
40
|
+
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | Typography scale |
|
|
41
|
+
| `title-as` | string | `"h2"` | HTML tag for the title element |
|
|
42
|
+
|
|
43
|
+
## CSS Custom Properties
|
|
44
|
+
|
|
45
|
+
| Property | Description |
|
|
46
|
+
|----------|-------------|
|
|
47
|
+
| `--sectionHeader-title-color` | Title text colour |
|
|
48
|
+
| `--sectionHeader_subtitle-color` | Subtitle text colour |
|
|
49
|
+
|
|
50
|
+
## Usage in plain HTML
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<bds-section-header title="Our Products"></bds-section-header>
|
|
54
|
+
|
|
55
|
+
<bds-section-header
|
|
56
|
+
title="Features"
|
|
57
|
+
subtitle="Everything you need"
|
|
58
|
+
alignment="center"
|
|
59
|
+
size="large"
|
|
60
|
+
></bds-section-header>
|
|
61
|
+
|
|
62
|
+
<!-- Use h3 when nested inside another section -->
|
|
63
|
+
<bds-section-header title="Subsection" title-as="h3"></bds-section-header>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Accessibility
|
|
67
|
+
|
|
68
|
+
- Always set `title-as` to match the correct heading level in the document outline
|
|
69
|
+
- Default is `h2` — adjust if the section header is nested inside an `h2` section
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../index';
|
|
4
|
+
|
|
5
|
+
function BdsSectionHeader({
|
|
6
|
+
title,
|
|
7
|
+
subtitle,
|
|
8
|
+
alignment,
|
|
9
|
+
size,
|
|
10
|
+
titleAs,
|
|
11
|
+
}: {
|
|
12
|
+
title?: string;
|
|
13
|
+
subtitle?: string;
|
|
14
|
+
alignment?: 'start' | 'center' | 'end';
|
|
15
|
+
size?: 'small' | 'medium' | 'large';
|
|
16
|
+
titleAs?: string;
|
|
17
|
+
}) {
|
|
18
|
+
return React.createElement('bds-section-header', {
|
|
19
|
+
title,
|
|
20
|
+
subtitle,
|
|
21
|
+
alignment,
|
|
22
|
+
size,
|
|
23
|
+
'title-as': titleAs,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const meta = {
|
|
28
|
+
title: 'Web Components/UI/SectionHeader',
|
|
29
|
+
component: BdsSectionHeader,
|
|
30
|
+
tags: ['!stable', 'experimental'],
|
|
31
|
+
parameters: { layout: 'padded' },
|
|
32
|
+
argTypes: {
|
|
33
|
+
alignment: { control: 'select', options: ['start', 'center', 'end'] },
|
|
34
|
+
size: { control: 'select', options: ['small', 'medium', 'large'] },
|
|
35
|
+
},
|
|
36
|
+
} satisfies Meta<typeof BdsSectionHeader>;
|
|
37
|
+
|
|
38
|
+
export default meta;
|
|
39
|
+
type Story = StoryObj<typeof meta>;
|
|
40
|
+
|
|
41
|
+
export const Default: Story = { args: { title: 'Our Products' } };
|
|
42
|
+
export const WithSubtitle: Story = { args: { title: 'Our Products', subtitle: 'Browse the full range of components' } };
|
|
43
|
+
export const Center: Story = { args: { title: 'Features', subtitle: 'Everything you need to build faster', alignment: 'center' } };
|
|
44
|
+
export const End: Story = { args: { title: 'Aligned end', alignment: 'end' } };
|
|
45
|
+
export const Small: Story = { args: { title: 'Small header', subtitle: 'Compact section intro', size: 'small' } };
|
|
46
|
+
export const Large: Story = { args: { title: 'Large header', subtitle: 'Hero-scale section heading', size: 'large' } };
|
|
47
|
+
|
|
48
|
+
export const AllVariants: Story = {
|
|
49
|
+
render: () => (
|
|
50
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '32px' }}>
|
|
51
|
+
{(['small', 'medium', 'large'] as const).map(s => (
|
|
52
|
+
<BdsSectionHeader key={s} title={`${s.charAt(0).toUpperCase() + s.slice(1)} header`} subtitle="Optional subtitle text" size={s} />
|
|
53
|
+
))}
|
|
54
|
+
</div>
|
|
55
|
+
),
|
|
56
|
+
};
|