@boostdev/design-system-components 1.2.8 → 2.1.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 +5 -3
- package/README.md +57 -38
- package/dist/client.cjs +52 -50
- package/dist/client.css +537 -524
- package/dist/client.d.cts +31 -1
- package/dist/client.d.ts +31 -1
- package/dist/client.js +52 -50
- package/dist/index.cjs +52 -50
- package/dist/index.css +537 -524
- package/dist/index.d.cts +31 -1
- package/dist/index.d.ts +31 -1
- package/dist/index.js +52 -50
- package/dist/native/index.cjs +5 -2
- package/dist/native/index.d.cts +3 -1
- package/dist/native/index.d.ts +3 -1
- package/dist/native/index.js +5 -2
- package/dist/web-components/{chunk-DZRSJGPB.js → chunk-3S42DZ7W.js} +1 -1
- package/dist/web-components/{chunk-3REOIRDW.js → chunk-N3TN6WCH.js} +26 -1
- package/dist/web-components/globals.js +1 -1
- package/dist/web-components/index.js +2 -2
- package/dist/web-components/interaction/bds-button.d.ts +7 -0
- package/dist/web-components/interaction/bds-button.js +1 -1
- package/package.json +3 -3
- package/src/components/interaction/Button/Button.mdx +84 -29
- package/src/components/interaction/Button/Button.module.css +25 -1
- package/src/components/interaction/Button/Button.native.mdx +33 -14
- package/src/components/interaction/Button/Button.native.spec.tsx +20 -0
- package/src/components/interaction/Button/Button.native.stories.tsx +110 -9
- package/src/components/interaction/Button/Button.native.tsx +13 -4
- package/src/components/interaction/Button/Button.spec.tsx +16 -0
- package/src/components/interaction/Button/Button.stories.tsx +134 -16
- package/src/components/interaction/Button/Button.tsx +32 -0
- package/src/components/interaction/Command/Command.module.css +1 -1
- package/src/components/interaction/Dialog/Dialog.module.css +1 -1
- package/src/components/interaction/Dialog/Dialog.native.mdx +2 -2
- package/src/components/interaction/Drawer/Drawer.module.css +1 -1
- package/src/components/interaction/Drawer/Drawer.native.mdx +2 -2
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +1 -1
- package/src/components/interaction/DropdownMenu/DropdownMenu.native.mdx +2 -2
- package/src/components/interaction/Popover/Popover.module.css +1 -1
- package/src/components/interaction/Popover/Popover.native.mdx +2 -2
- package/src/components/interaction/Rating/Rating.module.css +1 -1
- package/src/components/interaction/Rating/Rating.native.mdx +1 -1
- package/src/components/interaction/Toast/Toast.module.css +1 -1
- package/src/components/interaction/Toast/Toast.native.mdx +3 -3
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -1
- package/src/components/interaction/form/Checkbox/Checkbox.native.mdx +1 -1
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +1 -1
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.native.mdx +1 -1
- package/src/components/interaction/form/Combobox/Combobox.module.css +1 -1
- package/src/components/interaction/form/Combobox/Combobox.native.mdx +1 -1
- package/src/components/interaction/form/FileInput/FileInput.module.css +1 -1
- package/src/components/interaction/form/FileInput/FileInput.native.mdx +1 -1
- package/src/components/interaction/form/FormInput/FormInput.module.css +1 -1
- package/src/components/interaction/form/FormInput/FormInput.native.mdx +1 -1
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +1 -1
- package/src/components/interaction/form/NumberInput/NumberInput.native.mdx +1 -1
- package/src/components/interaction/form/Radio/Radio.module.css +1 -1
- package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +1 -1
- package/src/components/interaction/form/RadioGroup/RadioGroup.native.mdx +1 -1
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +1 -1
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.native.mdx +1 -1
- package/src/components/interaction/form/Select/Select.module.css +1 -1
- package/src/components/interaction/form/Select/Select.native.mdx +1 -1
- package/src/components/interaction/form/Slider/Slider.module.css +1 -1
- package/src/components/interaction/form/Slider/Slider.native.mdx +1 -1
- package/src/components/interaction/form/Switch/Switch.module.css +1 -1
- package/src/components/interaction/form/Textarea/Textarea.module.css +1 -1
- package/src/components/interaction/form/Textarea/Textarea.native.mdx +1 -1
- package/src/components/interaction/form/atoms/InputContainer.module.css +1 -1
- package/src/components/interaction/form/atoms/Label.module.css +1 -1
- package/src/components/interaction/form/atoms/Message.module.css +1 -1
- package/src/components/layout/ButtonGroup/ButtonGroup.module.css +1 -1
- package/src/components/layout/Card/Card.module.css +1 -1
- package/src/components/layout/IconWrapper/IconWrapper.module.css +1 -1
- package/src/components/layout/IconWrapper/IconWrapper.stories.tsx +46 -14
- package/src/components/layout/SectionHeader/SectionHeader.module.css +1 -1
- package/src/components/ui/Accordion/Accordion.module.css +1 -1
- package/src/components/ui/Accordion/Accordion.native.mdx +1 -1
- package/src/components/ui/Accordion/Accordion.native.stories.tsx +1 -1
- package/src/components/ui/Alert/Alert.module.css +1 -1
- package/src/components/ui/Alert/Alert.native.mdx +1 -1
- package/src/components/ui/Avatar/Avatar.module.css +1 -1
- package/src/components/ui/Avatar/Avatar.native.mdx +1 -1
- package/src/components/ui/Badge/Badge.module.css +1 -1
- package/src/components/ui/Badge/Badge.native.mdx +1 -1
- package/src/components/ui/Breadcrumb/Breadcrumb.module.css +1 -1
- package/src/components/ui/Breadcrumb/Breadcrumb.native.mdx +1 -1
- package/src/components/ui/Calendar/Calendar.module.css +1 -1
- package/src/components/ui/Calendar/Calendar.native.mdx +1 -1
- package/src/components/ui/Carousel/Carousel.module.css +1 -1
- package/src/components/ui/Carousel/Carousel.native.mdx +1 -1
- package/src/components/ui/Collapsible/Collapsible.module.css +1 -1
- package/src/components/ui/Collapsible/Collapsible.native.mdx +1 -1
- package/src/components/ui/DescriptionList/DescriptionList.module.css +1 -1
- package/src/components/ui/DescriptionList/DescriptionList.native.mdx +1 -1
- package/src/components/ui/Link/Link.module.css +1 -1
- package/src/components/ui/Link/Link.native.mdx +1 -1
- package/src/components/ui/Loading/Loading.module.css +1 -1
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +1 -1
- package/src/components/ui/Pagination/Pagination.module.css +1 -1
- package/src/components/ui/Pagination/Pagination.native.mdx +1 -1
- package/src/components/ui/Progress/Progress.module.css +1 -1
- package/src/components/ui/ProgressCircle/ProgressCircle.module.css +1 -1
- package/src/components/ui/ProgressCircle/ProgressCircle.native.mdx +1 -1
- package/src/components/ui/Separator/Separator.module.css +1 -1
- package/src/components/ui/Skeleton/Skeleton.module.css +1 -1
- package/src/components/ui/SkipLink/SkipLink.module.css +1 -1
- package/src/components/ui/Table/Table.module.css +1 -1
- package/src/components/ui/Table/Table.native.mdx +1 -1
- package/src/components/ui/Tabs/Tabs.module.css +1 -1
- package/src/components/ui/Tabs/Tabs.native.mdx +1 -1
- package/src/components/ui/Tooltip/Tooltip.module.css +1 -1
- package/src/components/ui/Tooltip/Tooltip.native.mdx +1 -1
- package/src/components/ui/Typography/Typography.module.css +1 -1
- package/src/components/ui/Typography/Typography.native.mdx +1 -1
- package/src/css/bdc.css +1 -1
- package/src/css/index.css +1 -1
- package/src/stories/DesignSystem/Borders.mdx +3 -3
- package/src/stories/DesignSystem/Colors.mdx +1 -1
- package/src/stories/DesignSystem/DarkMode.mdx +3 -3
- package/src/stories/DesignSystem/Overview.mdx +16 -5
- package/src/stories/DesignSystem/Typography.mdx +1 -1
- package/src/stories/Introduction.mdx +4 -4
- package/src/stories/ReactNative.mdx +6 -6
- package/src/web-components/globals.ts +1 -1
- package/src/web-components/interaction/BdsAccordion.mdx +3 -3
- package/src/web-components/interaction/BdsAccordion.stories.tsx +1 -1
- package/src/web-components/interaction/BdsButton.mdx +48 -16
- package/src/web-components/interaction/BdsButton.stories.tsx +171 -19
- package/src/web-components/interaction/BdsCollapsible.mdx +2 -2
- package/src/web-components/interaction/BdsDialog.mdx +2 -2
- package/src/web-components/interaction/BdsDrawer.mdx +2 -2
- package/src/web-components/interaction/BdsDropdownMenu.mdx +2 -2
- package/src/web-components/interaction/BdsPopover.mdx +1 -1
- package/src/web-components/interaction/BdsSkipLink.mdx +2 -2
- package/src/web-components/interaction/BdsTabs.mdx +2 -2
- package/src/web-components/interaction/BdsToastProvider.mdx +3 -3
- package/src/web-components/interaction/BdsTooltip.mdx +2 -2
- package/src/web-components/interaction/bds-button.spec.ts +35 -0
- package/src/web-components/interaction/bds-button.ts +28 -1
- package/src/web-components/interaction/form/BdsCheckbox.mdx +1 -1
- package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +1 -1
- package/src/web-components/interaction/form/BdsCombobox.mdx +1 -1
- package/src/web-components/interaction/form/BdsFileInput.mdx +1 -1
- package/src/web-components/interaction/form/BdsFormInput.mdx +1 -1
- package/src/web-components/interaction/form/BdsNumberInput.mdx +1 -1
- package/src/web-components/interaction/form/BdsRadio.mdx +1 -1
- package/src/web-components/interaction/form/BdsRadioGroup.mdx +1 -1
- package/src/web-components/interaction/form/BdsSegmentedControl.mdx +1 -1
- package/src/web-components/interaction/form/BdsSelect.mdx +1 -1
- package/src/web-components/interaction/form/BdsSlider.mdx +1 -1
- package/src/web-components/interaction/form/BdsSwitch.mdx +1 -1
- package/src/web-components/interaction/form/BdsTextarea.mdx +1 -1
- package/src/web-components/ui/BdsAlert.mdx +1 -1
- package/src/web-components/ui/BdsAvatar.mdx +1 -1
- package/src/web-components/ui/BdsBadge.mdx +1 -1
- package/src/web-components/ui/BdsBreadcrumb.mdx +1 -1
- package/src/web-components/ui/BdsButtonGroup.mdx +1 -1
- package/src/web-components/ui/BdsCalendar.mdx +1 -1
- package/src/web-components/ui/BdsCard.mdx +1 -1
- package/src/web-components/ui/BdsCarousel.mdx +1 -1
- package/src/web-components/ui/BdsDescriptionList.mdx +1 -1
- package/src/web-components/ui/BdsIconWrapper.mdx +1 -1
- package/src/web-components/ui/BdsLink.mdx +1 -1
- package/src/web-components/ui/BdsLoading.mdx +1 -1
- package/src/web-components/ui/BdsNotificationBanner.mdx +1 -1
- package/src/web-components/ui/BdsPagination.mdx +1 -1
- package/src/web-components/ui/BdsProgress.mdx +1 -1
- package/src/web-components/ui/BdsProgressCircle.mdx +1 -1
- package/src/web-components/ui/BdsRating.mdx +1 -1
- package/src/web-components/ui/BdsSectionHeader.mdx +1 -1
- package/src/web-components/ui/BdsSeparator.mdx +2 -2
- package/src/web-components/ui/BdsSkeleton.mdx +1 -1
- package/src/web-components/ui/BdsTable.mdx +1 -1
- package/src/web-components/ui/BdsTypography.mdx +1 -1
|
@@ -127,7 +127,7 @@ Override a component's border colour for a specific context by reassigning `--bd
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/* Override globally via the token layer */
|
|
130
|
-
@layer tokens.override {
|
|
130
|
+
@layer boostdev.tokens.override {
|
|
131
131
|
:root {
|
|
132
132
|
--bdc_color: var(--bds-color_green);
|
|
133
133
|
}
|
|
@@ -151,8 +151,8 @@ The `bdc` tokens are included automatically when you import the component styles
|
|
|
151
151
|
|
|
152
152
|
```css
|
|
153
153
|
/* Included automatically with the full component CSS */
|
|
154
|
-
@import '@boostdev/components/css';
|
|
154
|
+
@import '@boostdev/design-system-components/css';
|
|
155
155
|
|
|
156
156
|
/* Or load the token layer standalone */
|
|
157
|
-
@import '@boostdev/components/css/bdc';
|
|
157
|
+
@import '@boostdev/design-system-components/css/bdc';
|
|
158
158
|
```
|
|
@@ -184,7 +184,7 @@ These `--bds-BASE__color--*` tokens are the primitive values. **Do not use them
|
|
|
184
184
|
Override `--bds-color_green` and `--bds-color_interactive` to change the primary action colour globally:
|
|
185
185
|
|
|
186
186
|
```css
|
|
187
|
-
@layer tokens.override {
|
|
187
|
+
@layer boostdev.tokens.override {
|
|
188
188
|
:root {
|
|
189
189
|
--bds-color_green: var(--bds-BASE__color--blue);
|
|
190
190
|
--bds-color_on-green: var(--bds-BASE__color--white);
|
|
@@ -85,20 +85,20 @@ function ThemeToggle() {
|
|
|
85
85
|
|
|
86
86
|
## Customising tokens in dark mode
|
|
87
87
|
|
|
88
|
-
Override any token in `@layer tokens.override` — the rule applies regardless of the active theme unless you scope it:
|
|
88
|
+
Override any token in `@layer boostdev.tokens.override` — the rule applies regardless of the active theme unless you scope it:
|
|
89
89
|
|
|
90
90
|
```css
|
|
91
91
|
@import "@boostdev/design-system-foundation/css";
|
|
92
92
|
|
|
93
93
|
/* override for all themes */
|
|
94
|
-
@layer tokens.override {
|
|
94
|
+
@layer boostdev.tokens.override {
|
|
95
95
|
:root {
|
|
96
96
|
--bds-color_green: oklch(60% 0.15 145);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
/* override for dark mode only */
|
|
101
|
-
@layer tokens.override {
|
|
101
|
+
@layer boostdev.tokens.override {
|
|
102
102
|
[data-theme="dark"],
|
|
103
103
|
@media (prefers-color-scheme: dark) {
|
|
104
104
|
:root:not([data-theme="light"]) {
|
|
@@ -49,14 +49,25 @@ import '@boostdev/design-system-foundation/css';
|
|
|
49
49
|
|
|
50
50
|
## Layer architecture
|
|
51
51
|
|
|
52
|
-
All tokens live inside `@layer` declarations
|
|
52
|
+
All tokens live inside `@layer` declarations, all prefixed with `boostdev.` to prevent collisions
|
|
53
|
+
with consumer layers of the same name. The cascade order, from lowest to highest, is:
|
|
53
54
|
|
|
54
55
|
```
|
|
55
|
-
|
|
56
|
+
boostdev.tokens.base →
|
|
57
|
+
boostdev.tokens.semantic →
|
|
58
|
+
boostdev.tokens.deprecated →
|
|
59
|
+
boostdev.tokens.override →
|
|
60
|
+
boostdev.reset →
|
|
61
|
+
boostdev.base →
|
|
62
|
+
boostdev.utilities →
|
|
63
|
+
boostdev.components →
|
|
64
|
+
boostdev.component
|
|
56
65
|
```
|
|
57
66
|
|
|
58
|
-
`@layer component` — used by every component in this library — sits above the token layers,
|
|
59
|
-
so you can override any component from `@layer my-overrides` without
|
|
67
|
+
`@layer boostdev.component` — used by every component in this library — sits above the token layers,
|
|
68
|
+
so you can override any component from your own layer (e.g. `@layer my-overrides`) without
|
|
69
|
+
specificity fights. Anything written outside of any `@layer` is treated as an unlayered declaration,
|
|
70
|
+
which is the highest-priority in the cascade.
|
|
60
71
|
|
|
61
72
|
## Theming
|
|
62
73
|
|
|
@@ -78,7 +89,7 @@ Override any token in your own layer to retheme:
|
|
|
78
89
|
```css
|
|
79
90
|
@import "@boostdev/design-system-foundation/css";
|
|
80
91
|
|
|
81
|
-
@layer tokens.override {
|
|
92
|
+
@layer boostdev.tokens.override {
|
|
82
93
|
:root {
|
|
83
94
|
--bds-cta: var(--bds-BASE__color--blue);
|
|
84
95
|
--bds-color_on-green: var(--bds-BASE__color--white);
|
|
@@ -49,7 +49,7 @@ export const TrackingSample = ({ token, label, value }) => (
|
|
|
49
49
|
Override both tokens to apply a custom typeface globally:
|
|
50
50
|
|
|
51
51
|
```css
|
|
52
|
-
@layer tokens.override {
|
|
52
|
+
@layer boostdev.tokens.override {
|
|
53
53
|
:root {
|
|
54
54
|
--bds-font_family--heading: 'Inter', sans-serif;
|
|
55
55
|
--bds-font_family--body: 'Inter', sans-serif;
|
|
@@ -30,20 +30,20 @@ import logo from '../static/logo.svg';
|
|
|
30
30
|
## Installation
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
pnpm add @boostdev/components @boostdev/design-system-foundation
|
|
33
|
+
pnpm add @boostdev/design-system-components @boostdev/design-system-foundation
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Import the CSS once at your app root:
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
import '@boostdev/design-system-foundation/css';
|
|
40
|
-
import '@boostdev/components/css';
|
|
40
|
+
import '@boostdev/design-system-components/css';
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
For **Next.js / RSC**, use the `/client` subpath:
|
|
44
44
|
|
|
45
45
|
```ts
|
|
46
|
-
import {Button, Card} from '@boostdev/components/client';
|
|
46
|
+
import {Button, Card} from '@boostdev/design-system-components/client';
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
---
|
|
@@ -92,7 +92,7 @@ import logo from '../static/logo.svg';
|
|
|
92
92
|
everything at once:
|
|
93
93
|
|
|
94
94
|
```css
|
|
95
|
-
@layer tokens.override {
|
|
95
|
+
@layer boostdev.tokens.override {
|
|
96
96
|
:root {
|
|
97
97
|
--bds-cta: var(--bds-BASE__color--orange);
|
|
98
98
|
--bds-on-cta: var(--bds-BASE__color--white);
|
|
@@ -6,21 +6,21 @@ import { Meta } from '@storybook/blocks';
|
|
|
6
6
|
|
|
7
7
|
> **Status: alpha** — components and APIs may change before stable release.
|
|
8
8
|
|
|
9
|
-
`@boostdev/components` ships native implementations for 47 components — near-complete parity with the React web library. These use React Native primitives (`View`, `Text`, `Pressable`, `StyleSheet`, `Modal`, `Animated`) rather than HTML elements, and consume a dedicated token layer instead of CSS custom properties.
|
|
9
|
+
`@boostdev/design-system-components` ships native implementations for 47 components — near-complete parity with the React web library. These use React Native primitives (`View`, `Text`, `Pressable`, `StyleSheet`, `Modal`, `Animated`) rather than HTML elements, and consume a dedicated token layer instead of CSS custom properties.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install @boostdev/components
|
|
14
|
+
npm install @boostdev/design-system-components
|
|
15
15
|
# or
|
|
16
|
-
pnpm add @boostdev/components
|
|
16
|
+
pnpm add @boostdev/design-system-components
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Metro automatically resolves the native entry point via the `"react-native"` export condition in `package.json` — no extra configuration needed.
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
// Import is identical to the web version:
|
|
23
|
-
import { Button, Alert, Badge, Avatar, Typography } from '@boostdev/components';
|
|
23
|
+
import { Button, Alert, Badge, Avatar, Typography } from '@boostdev/design-system-components';
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## Setup — ThemeProvider
|
|
@@ -28,7 +28,7 @@ import { Button, Alert, Badge, Avatar, Typography } from '@boostdev/components';
|
|
|
28
28
|
Wrap your app (or the relevant subtree) in `ThemeProvider` to give native components access to the design token context:
|
|
29
29
|
|
|
30
30
|
```tsx
|
|
31
|
-
import { ThemeProvider } from '@boostdev/components/native/ThemeContext';
|
|
31
|
+
import { ThemeProvider } from '@boostdev/design-system-components/native/ThemeContext';
|
|
32
32
|
|
|
33
33
|
export default function App() {
|
|
34
34
|
return (
|
|
@@ -57,7 +57,7 @@ Native components consume tokens from `src/native/tokens.ts` — a JS object mir
|
|
|
57
57
|
Tokens are accessed inside components via `useTheme()`:
|
|
58
58
|
|
|
59
59
|
```tsx
|
|
60
|
-
import { useTheme } from '@boostdev/components/native/ThemeContext';
|
|
60
|
+
import { useTheme } from '@boostdev/design-system-components/native/ThemeContext';
|
|
61
61
|
|
|
62
62
|
function MyComponent() {
|
|
63
63
|
const { tokens } = useTheme();
|
|
@@ -12,14 +12,14 @@ Framework-agnostic Accordion custom element. Coordinates open/closed state acros
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
|
-
import '@boostdev/components/web-components';
|
|
15
|
+
import '@boostdev/design-system-components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Or in HTML without a bundler:
|
|
19
19
|
|
|
20
20
|
```html
|
|
21
21
|
<script type="module">
|
|
22
|
-
import '@boostdev/components/web-components';
|
|
22
|
+
import '@boostdev/design-system-components/web-components';
|
|
23
23
|
</script>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -85,7 +85,7 @@ Or in HTML without a bundler:
|
|
|
85
85
|
</bds-accordion-item>
|
|
86
86
|
<bds-accordion-item>
|
|
87
87
|
<span slot="header">How do I install it?</span>
|
|
88
|
-
<p>Run npm install @boostdev/components.</p>
|
|
88
|
+
<p>Run npm install @boostdev/design-system-components.</p>
|
|
89
89
|
</bds-accordion-item>
|
|
90
90
|
</bds-accordion>
|
|
91
91
|
|
|
@@ -49,7 +49,7 @@ function BdsAccordionStory({
|
|
|
49
49
|
{React.createElement('p', { style: { margin: 0 } }, 'A framework-agnostic component library built on web standards.')}
|
|
50
50
|
</BdsAccordionItem>
|
|
51
51
|
<BdsAccordionItem header="How do I install it?">
|
|
52
|
-
{React.createElement('p', { style: { margin: 0 } }, 'Run npm install @boostdev/components and import the web components entry point.')}
|
|
52
|
+
{React.createElement('p', { style: { margin: 0 } }, 'Run npm install @boostdev/design-system-components and import the web components entry point.')}
|
|
53
53
|
</BdsAccordionItem>
|
|
54
54
|
<BdsAccordionItem header="Does it support dark mode?">
|
|
55
55
|
{React.createElement('p', { style: { margin: 0 } }, 'Yes — all design tokens respond to [data-theme="dark"] and prefers-color-scheme: dark.')}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
1
|
+
import { Meta, Canvas, ArgTypes, Controls } from '@storybook/blocks';
|
|
2
2
|
import * as Stories from './BdsButton.stories';
|
|
3
3
|
|
|
4
4
|
<Meta of={Stories} />
|
|
@@ -13,37 +13,65 @@ Framework-agnostic button custom element. Renders as `<button>` or `<a>` dependi
|
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
15
|
// Register all web components at once
|
|
16
|
-
import '@boostdev/components/web-components';
|
|
16
|
+
import '@boostdev/design-system-components/web-components';
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Or in HTML without a bundler:
|
|
20
20
|
|
|
21
21
|
```html
|
|
22
22
|
<script type="module">
|
|
23
|
-
import '@boostdev/components/web-components';
|
|
23
|
+
import '@boostdev/design-system-components/web-components';
|
|
24
24
|
</script>
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Playground
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
<
|
|
29
|
+
<Canvas of={Stories.Playground} />
|
|
30
|
+
<Controls of={Stories.Playground} />
|
|
31
|
+
|
|
32
|
+
## Variants
|
|
31
33
|
|
|
32
|
-
### Default
|
|
33
34
|
<Canvas of={Stories.Default} />
|
|
35
|
+
<Canvas of={Stories.Outline} />
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
<Canvas of={Stories.Ghost} />
|
|
37
|
+
## Sizes
|
|
37
38
|
|
|
38
|
-
### Sizes
|
|
39
39
|
<Canvas of={Stories.Small} />
|
|
40
40
|
<Canvas of={Stories.Medium} />
|
|
41
41
|
<Canvas of={Stories.Large} />
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
## Icons
|
|
44
|
+
|
|
45
|
+
Slot an SVG (or any element) into `icon-start` or `icon-end`:
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<bds-button>
|
|
49
|
+
<svg slot="icon-start">…</svg>
|
|
50
|
+
Save
|
|
51
|
+
</bds-button>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
<Canvas of={Stories.WithIconStart} />
|
|
55
|
+
<Canvas of={Stories.WithIconEnd} />
|
|
56
|
+
|
|
57
|
+
### Icon-only (1:1 aspect ratio)
|
|
58
|
+
|
|
59
|
+
Set the `is-icon-only` attribute to render a square button with equal `var(--bds-space_xs)` padding on both axes. Composable with any `variant`. Always pair with `aria-label` — there's no visible label text for assistive tech to read.
|
|
60
|
+
|
|
61
|
+
<Canvas of={Stories.IconOnly} />
|
|
62
|
+
<Canvas of={Stories.IconOnlyOutline} />
|
|
63
|
+
<Canvas of={Stories.AllIconOnly} />
|
|
64
|
+
|
|
65
|
+
## All variants & sizes
|
|
66
|
+
|
|
67
|
+
<Canvas of={Stories.AllVariants} />
|
|
68
|
+
|
|
69
|
+
## Pulse (CTA emphasis)
|
|
70
|
+
|
|
44
71
|
<Canvas of={Stories.WithPulse} />
|
|
45
72
|
|
|
46
|
-
|
|
73
|
+
## Disabled
|
|
74
|
+
|
|
47
75
|
<Canvas of={Stories.Disabled} />
|
|
48
76
|
|
|
49
77
|
## Props
|
|
@@ -54,14 +82,15 @@ Or in HTML without a bundler:
|
|
|
54
82
|
|
|
55
83
|
| Attribute | Type | Default | Description |
|
|
56
84
|
|-----------|------|---------|-------------|
|
|
57
|
-
| `variant` | `"default" \| "
|
|
58
|
-
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | Height and padding
|
|
85
|
+
| `variant` | `"default" \| "outline"` | `"default"` | Visual style — filled or transparent outlined (`"ghost"` is a deprecated alias for `"outline"`) |
|
|
86
|
+
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | Height and horizontal padding |
|
|
59
87
|
| `disabled` | boolean | `false` | Prevents interaction, sets `aria-disabled` |
|
|
60
88
|
| `href` | string | — | Renders as `<a>` when set |
|
|
61
89
|
| `target` | string | — | Forwarded to `<a>` when `href` is set |
|
|
62
90
|
| `rel` | string | — | Forwarded to `<a>` when `href` is set |
|
|
63
91
|
| `type` | `"button" \| "submit" \| "reset"` | `"button"` | Native button type |
|
|
64
92
|
| `has-pulse` | boolean | `false` | Adds animated ring for CTA emphasis |
|
|
93
|
+
| `is-icon-only` | boolean | `false` | 1:1 aspect ratio with equal `xs` padding on both axes. Requires `aria-label`. |
|
|
65
94
|
| `aria-label` | string | — | Accessible label (required for icon-only buttons) |
|
|
66
95
|
|
|
67
96
|
## Slots
|
|
@@ -76,7 +105,7 @@ Or in HTML without a bundler:
|
|
|
76
105
|
|
|
77
106
|
| Property | Description |
|
|
78
107
|
|----------|-------------|
|
|
79
|
-
| `--button_color` | Identity colour — fills the default variant, outlines the
|
|
108
|
+
| `--button_color` | Identity colour — fills the default variant, outlines the outline variant |
|
|
80
109
|
| `--button_on-color` | Text/icon colour on the button surface. Pair with `--button_color` |
|
|
81
110
|
|
|
82
111
|
## Invoker Commands API
|
|
@@ -94,8 +123,11 @@ Or in HTML without a bundler:
|
|
|
94
123
|
|
|
95
124
|
```html
|
|
96
125
|
<bds-button variant="default" size="medium">Save</bds-button>
|
|
97
|
-
<bds-button variant="
|
|
126
|
+
<bds-button variant="outline">Cancel</bds-button>
|
|
98
127
|
<bds-button href="/dashboard">Go to dashboard</bds-button>
|
|
128
|
+
<bds-button is-icon-only aria-label="Confirm">
|
|
129
|
+
<svg viewBox="0 0 24 24">…</svg>
|
|
130
|
+
</bds-button>
|
|
99
131
|
```
|
|
100
132
|
|
|
101
133
|
## Accessibility
|
|
@@ -1,56 +1,188 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import type { ButtonVariant, ButtonSize } from './bds-button';
|
|
4
4
|
import '../index'; // auto-registers all custom elements
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const CheckIcon = (
|
|
7
|
+
<svg
|
|
8
|
+
slot="icon-start"
|
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
10
|
+
viewBox="0 0 24 24"
|
|
11
|
+
width="1em"
|
|
12
|
+
height="1em"
|
|
13
|
+
aria-hidden
|
|
14
|
+
fill="currentColor"
|
|
15
|
+
>
|
|
16
|
+
<path d="M12 0a12 12 0 1 0 12 12A12 12 0 0 0 12 0Zm6.93 8.2-6.85 9.29a1 1 0 0 1-1.43.19l-4.89-3.91a1 1 0 0 1-.15-1.41A1 1 0 0 1 7 12.21l4.08 3.26L17.32 7a1 1 0 0 1 1.39-.21 1 1 0 0 1 .22 1.41Z" />
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const ArrowRightStart = <span slot="icon-start" aria-hidden>→</span>;
|
|
21
|
+
const ArrowRightEnd = <span slot="icon-end" aria-hidden>→</span>;
|
|
22
|
+
const ArrowLeftStart = <span slot="icon-start" aria-hidden>←</span>;
|
|
23
|
+
|
|
24
|
+
// Icon for icon-only buttons — goes into the default slot (no slot attribute)
|
|
25
|
+
const CheckIconDefault = (
|
|
26
|
+
<svg
|
|
27
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
width="1em"
|
|
30
|
+
height="1em"
|
|
31
|
+
aria-hidden
|
|
32
|
+
fill="currentColor"
|
|
33
|
+
>
|
|
34
|
+
<path d="M12 0a12 12 0 1 0 12 12A12 12 0 0 0 12 0Zm6.93 8.2-6.85 9.29a1 1 0 0 1-1.43.19l-4.89-3.91a1 1 0 0 1-.15-1.41A1 1 0 0 1 7 12.21l4.08 3.26L17.32 7a1 1 0 0 1 1.39-.21 1 1 0 0 1 .22 1.41Z" />
|
|
35
|
+
</svg>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const iconStartMap = {
|
|
39
|
+
none: undefined,
|
|
40
|
+
check: CheckIcon,
|
|
41
|
+
arrowRight: ArrowRightStart,
|
|
42
|
+
arrowLeft: ArrowLeftStart,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const iconEndMap = {
|
|
46
|
+
none: undefined,
|
|
47
|
+
arrowRight: ArrowRightEnd,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type IconStartKey = keyof typeof iconStartMap;
|
|
51
|
+
type IconEndKey = keyof typeof iconEndMap;
|
|
52
|
+
|
|
53
|
+
// React wrapper translating typed props into the custom element's attributes/slots
|
|
54
|
+
interface BdsButtonProps {
|
|
55
|
+
variant?: ButtonVariant;
|
|
56
|
+
size?: ButtonSize;
|
|
57
|
+
disabled?: boolean;
|
|
58
|
+
href?: string;
|
|
59
|
+
hasPulse?: boolean;
|
|
60
|
+
isIconOnly?: boolean;
|
|
61
|
+
'aria-label'?: string;
|
|
62
|
+
iconStart?: ReactNode;
|
|
63
|
+
iconEnd?: ReactNode;
|
|
64
|
+
children?: ReactNode;
|
|
65
|
+
}
|
|
66
|
+
|
|
7
67
|
function BdsButton({
|
|
8
68
|
variant = 'default',
|
|
9
69
|
size = 'medium',
|
|
10
70
|
disabled,
|
|
11
71
|
href,
|
|
12
72
|
hasPulse,
|
|
73
|
+
isIconOnly,
|
|
74
|
+
'aria-label': ariaLabel,
|
|
75
|
+
iconStart,
|
|
76
|
+
iconEnd,
|
|
13
77
|
children,
|
|
14
|
-
}: {
|
|
15
|
-
variant?: ButtonVariant;
|
|
16
|
-
size?: ButtonSize;
|
|
17
|
-
disabled?: boolean;
|
|
18
|
-
href?: string;
|
|
19
|
-
hasPulse?: boolean;
|
|
20
|
-
children?: React.ReactNode;
|
|
21
|
-
}) {
|
|
78
|
+
}: BdsButtonProps) {
|
|
22
79
|
return React.createElement(
|
|
23
80
|
'bds-button',
|
|
24
|
-
{
|
|
81
|
+
{
|
|
82
|
+
variant,
|
|
83
|
+
size,
|
|
84
|
+
disabled: disabled || undefined,
|
|
85
|
+
href,
|
|
86
|
+
'has-pulse': hasPulse || undefined,
|
|
87
|
+
'is-icon-only': isIconOnly || undefined,
|
|
88
|
+
'aria-label': ariaLabel,
|
|
89
|
+
},
|
|
90
|
+
iconStart,
|
|
25
91
|
children,
|
|
92
|
+
iconEnd,
|
|
26
93
|
);
|
|
27
94
|
}
|
|
28
95
|
|
|
29
|
-
|
|
96
|
+
type BdsButtonStoryArgs = Omit<BdsButtonProps, 'iconStart' | 'iconEnd'> & {
|
|
97
|
+
iconStart?: IconStartKey;
|
|
98
|
+
iconEnd?: IconEndKey;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const meta: Meta<BdsButtonStoryArgs> = {
|
|
30
102
|
title: 'Web Components/Interaction/Button',
|
|
31
103
|
component: BdsButton,
|
|
32
104
|
tags: ['!stable', 'experimental'],
|
|
33
105
|
parameters: { layout: 'centered' },
|
|
34
106
|
argTypes: {
|
|
35
|
-
variant: {
|
|
36
|
-
|
|
107
|
+
variant: {
|
|
108
|
+
control: 'select',
|
|
109
|
+
options: ['default', 'outline'],
|
|
110
|
+
description: '`default` is filled; `outline` is transparent with a border.',
|
|
111
|
+
table: { defaultValue: { summary: 'default' } },
|
|
112
|
+
},
|
|
113
|
+
size: {
|
|
114
|
+
control: 'select',
|
|
115
|
+
options: ['small', 'medium', 'large'],
|
|
116
|
+
description: 'Height + horizontal padding.',
|
|
117
|
+
table: { defaultValue: { summary: 'medium' } },
|
|
118
|
+
},
|
|
119
|
+
iconStart: {
|
|
120
|
+
control: 'select',
|
|
121
|
+
options: Object.keys(iconStartMap) as IconStartKey[],
|
|
122
|
+
mapping: iconStartMap,
|
|
123
|
+
description: 'Icon rendered in the `icon-start` slot.',
|
|
124
|
+
},
|
|
125
|
+
iconEnd: {
|
|
126
|
+
control: 'select',
|
|
127
|
+
options: Object.keys(iconEndMap) as IconEndKey[],
|
|
128
|
+
mapping: iconEndMap,
|
|
129
|
+
description: 'Icon rendered in the `icon-end` slot.',
|
|
130
|
+
},
|
|
131
|
+
isIconOnly: {
|
|
132
|
+
control: 'boolean',
|
|
133
|
+
description: 'Forces 1:1 aspect ratio with minimal xs padding. Composable with any `variant`. Requires `aria-label`.',
|
|
134
|
+
table: { defaultValue: { summary: 'false' } },
|
|
135
|
+
},
|
|
136
|
+
hasPulse: {
|
|
137
|
+
control: 'boolean',
|
|
138
|
+
description: 'Adds a pulsing animation for CTA emphasis.',
|
|
139
|
+
table: { defaultValue: { summary: 'false' } },
|
|
140
|
+
},
|
|
141
|
+
disabled: { control: 'boolean' },
|
|
142
|
+
href: { control: 'text', description: 'When set, renders as `<a>` with button styling.' },
|
|
143
|
+
'aria-label': { control: 'text', description: 'Required for icon-only buttons.' },
|
|
37
144
|
},
|
|
38
|
-
|
|
145
|
+
args: { variant: 'default', size: 'medium' },
|
|
146
|
+
};
|
|
39
147
|
|
|
40
148
|
export default meta;
|
|
41
|
-
type Story = StoryObj<
|
|
149
|
+
type Story = StoryObj<BdsButtonStoryArgs>;
|
|
42
150
|
|
|
43
|
-
export const
|
|
44
|
-
|
|
151
|
+
export const Playground: Story = {
|
|
152
|
+
args: { children: 'Button', iconStart: 'none', iconEnd: 'none' },
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export const Default: Story = { args: { children: 'Default' } };
|
|
156
|
+
export const Outline: Story = { args: { children: 'Outline', variant: 'outline' } };
|
|
45
157
|
export const Small: Story = { args: { children: 'Small', size: 'small' } };
|
|
46
158
|
export const Medium: Story = { args: { children: 'Medium', size: 'medium' } };
|
|
47
159
|
export const Large: Story = { args: { children: 'Large', size: 'large' } };
|
|
48
160
|
export const WithPulse: Story = { args: { children: 'Pulsing', hasPulse: true } };
|
|
49
161
|
export const Disabled: Story = { args: { children: 'Disabled', disabled: true } };
|
|
162
|
+
export const WithIconStart: Story = { args: { children: 'Confirm', iconStart: 'check' } };
|
|
163
|
+
export const WithIconEnd: Story = { args: { children: 'Continue', iconEnd: 'arrowRight' } };
|
|
164
|
+
|
|
165
|
+
export const IconOnly: Story = {
|
|
166
|
+
args: {
|
|
167
|
+
isIconOnly: true,
|
|
168
|
+
'aria-label': 'Confirm',
|
|
169
|
+
children: CheckIconDefault,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export const IconOnlyOutline: Story = {
|
|
174
|
+
args: {
|
|
175
|
+
variant: 'outline',
|
|
176
|
+
isIconOnly: true,
|
|
177
|
+
'aria-label': 'Confirm',
|
|
178
|
+
children: CheckIconDefault,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
|
|
50
182
|
export const AllVariants: Story = {
|
|
51
183
|
render: () => (
|
|
52
184
|
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', alignItems: 'center' }}>
|
|
53
|
-
{(['default', '
|
|
185
|
+
{(['default', 'outline'] as const).flatMap(v =>
|
|
54
186
|
(['small', 'medium', 'large'] as const).map(s => (
|
|
55
187
|
<BdsButton key={`${v}-${s}`} variant={v} size={s}>{v} {s}</BdsButton>
|
|
56
188
|
)),
|
|
@@ -58,3 +190,23 @@ export const AllVariants: Story = {
|
|
|
58
190
|
</div>
|
|
59
191
|
),
|
|
60
192
|
};
|
|
193
|
+
|
|
194
|
+
export const AllIconOnly: Story = {
|
|
195
|
+
render: () => (
|
|
196
|
+
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', alignItems: 'center' }}>
|
|
197
|
+
{(['default', 'outline'] as const).flatMap(v =>
|
|
198
|
+
(['small', 'medium', 'large'] as const).map(s => (
|
|
199
|
+
<BdsButton
|
|
200
|
+
key={`${v}-${s}`}
|
|
201
|
+
variant={v}
|
|
202
|
+
size={s}
|
|
203
|
+
isIconOnly
|
|
204
|
+
aria-label={`${v} ${s}`}
|
|
205
|
+
>
|
|
206
|
+
{CheckIconDefault}
|
|
207
|
+
</BdsButton>
|
|
208
|
+
)),
|
|
209
|
+
)}
|
|
210
|
+
</div>
|
|
211
|
+
),
|
|
212
|
+
};
|
|
@@ -12,14 +12,14 @@ Framework-agnostic Collapsible custom element. Wraps a native `<details>`/`<summ
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
|
-
import '@boostdev/components/web-components';
|
|
15
|
+
import '@boostdev/design-system-components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Or in HTML without a bundler:
|
|
19
19
|
|
|
20
20
|
```html
|
|
21
21
|
<script type="module">
|
|
22
|
-
import '@boostdev/components/web-components';
|
|
22
|
+
import '@boostdev/design-system-components/web-components';
|
|
23
23
|
</script>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -12,14 +12,14 @@ Framework-agnostic Dialog custom element. Wraps a native `<dialog>` element with
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
|
-
import '@boostdev/components/web-components';
|
|
15
|
+
import '@boostdev/design-system-components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Or in HTML without a bundler:
|
|
19
19
|
|
|
20
20
|
```html
|
|
21
21
|
<script type="module">
|
|
22
|
-
import '@boostdev/components/web-components';
|
|
22
|
+
import '@boostdev/design-system-components/web-components';
|
|
23
23
|
</script>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -12,14 +12,14 @@ Framework-agnostic Drawer (slide-in panel) custom element. Same modal infrastruc
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
|
-
import '@boostdev/components/web-components';
|
|
15
|
+
import '@boostdev/design-system-components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Or in HTML without a bundler:
|
|
19
19
|
|
|
20
20
|
```html
|
|
21
21
|
<script type="module">
|
|
22
|
-
import '@boostdev/components/web-components';
|
|
22
|
+
import '@boostdev/design-system-components/web-components';
|
|
23
23
|
</script>
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -12,14 +12,14 @@ Framework-agnostic Dropdown Menu custom element. A trigger-anchored menu panel w
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```js
|
|
15
|
-
import '@boostdev/components/web-components';
|
|
15
|
+
import '@boostdev/design-system-components/web-components';
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
Or in HTML without a bundler:
|
|
19
19
|
|
|
20
20
|
```html
|
|
21
21
|
<script type="module">
|
|
22
|
-
import '@boostdev/components/web-components';
|
|
22
|
+
import '@boostdev/design-system-components/web-components';
|
|
23
23
|
</script>
|
|
24
24
|
```
|
|
25
25
|
|