@boostdev/design-system-components 2.15.0 → 2.16.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 +19 -14
- package/dist/client.cjs +271 -205
- package/dist/client.css +801 -642
- package/dist/client.d.cts +19 -4
- package/dist/client.d.ts +19 -4
- package/dist/client.js +206 -139
- package/dist/index.cjs +271 -205
- package/dist/index.css +801 -642
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +206 -139
- package/dist/web-components/chunk-2DHW2WJZ.js +154 -0
- package/dist/web-components/{chunk-LDIPCTRN.js → chunk-2MJTO2IW.js} +48 -2
- package/dist/web-components/{chunk-3WAV6MDN.js → chunk-3FSGP35V.js} +1 -0
- package/dist/web-components/{chunk-KA3VPKMY.js → chunk-4MB2ICSK.js} +1 -0
- package/dist/web-components/{chunk-IDSM74LM.js → chunk-6XL5P76D.js} +3 -3
- package/dist/web-components/{chunk-P24JYC5V.js → chunk-7VXRMCAL.js} +10 -4
- package/dist/web-components/{chunk-CUKQ2L5B.js → chunk-AGI6YQRC.js} +9 -16
- package/dist/web-components/chunk-BDRV452N.js +51 -0
- package/dist/web-components/{chunk-3AY2YKCM.js → chunk-CKCPV347.js} +1 -0
- package/dist/web-components/{chunk-HBLJ4SLY.js → chunk-DD3OUXNG.js} +5 -5
- package/dist/web-components/{chunk-RVF7W653.js → chunk-DGOCPKHI.js} +30 -10
- package/dist/web-components/{chunk-2OLVQUBU.js → chunk-EYCW7TKB.js} +8 -15
- package/dist/web-components/{chunk-VANAKB6D.js → chunk-GPJWLAKU.js} +33 -16
- package/dist/web-components/{chunk-VED2DFJ6.js → chunk-GQNQBEYR.js} +8 -15
- package/dist/web-components/{chunk-WFVKU4GX.js → chunk-IKAJLROF.js} +49 -4
- package/dist/web-components/{chunk-RSZ3BWBK.js → chunk-KSK4RZZQ.js} +30 -7
- package/dist/web-components/{chunk-FEDABOR5.js → chunk-LHFUXZ52.js} +7 -15
- package/dist/web-components/{chunk-M3ECULRH.js → chunk-RBF7WPLI.js} +10 -8
- package/dist/web-components/{chunk-6G22I2CK.js → chunk-RZH5IVB5.js} +31 -1
- package/dist/web-components/chunk-SRKQ6GST.js +40 -0
- package/dist/web-components/{chunk-5HUAFCU6.js → chunk-TJV7UIXC.js} +7 -0
- package/dist/web-components/{chunk-J3HVUIUH.js → chunk-XI2U6U26.js} +8 -15
- package/dist/web-components/{chunk-JH6LQKLK.js → chunk-XJU7KITO.js} +8 -15
- package/dist/web-components/{chunk-JV5QT2OU.js → chunk-YLDQOESI.js} +27 -13
- package/dist/web-components/globals.js +1 -1
- package/dist/web-components/index.d.ts +1 -0
- package/dist/web-components/index.js +33 -28
- package/dist/web-components/interaction/bds-dropdown-menu-group.d.ts +41 -0
- package/dist/web-components/interaction/bds-dropdown-menu-group.js +7 -0
- package/dist/web-components/interaction/bds-dropdown-menu-item.d.ts +14 -1
- package/dist/web-components/interaction/bds-dropdown-menu-item.js +1 -1
- package/dist/web-components/interaction/bds-dropdown-menu.d.ts +2 -1
- package/dist/web-components/interaction/bds-dropdown-menu.js +1 -1
- package/dist/web-components/interaction/bds-tab.d.ts +5 -0
- package/dist/web-components/interaction/bds-tab.js +1 -1
- package/dist/web-components/interaction/bds-tooltip.js +1 -1
- package/dist/web-components/interaction/form/bds-checkbox-group.d.ts +6 -0
- package/dist/web-components/interaction/form/bds-checkbox-group.js +2 -1
- package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
- package/dist/web-components/interaction/form/bds-combobox.js +2 -1
- package/dist/web-components/interaction/form/bds-form-input.js +2 -1
- package/dist/web-components/interaction/form/bds-number-input.js +2 -1
- package/dist/web-components/interaction/form/bds-radio-group.d.ts +5 -0
- package/dist/web-components/interaction/form/bds-radio-group.js +2 -1
- package/dist/web-components/interaction/form/bds-radio.js +1 -1
- package/dist/web-components/interaction/form/bds-select.js +2 -1
- package/dist/web-components/interaction/form/bds-slider.js +2 -1
- package/dist/web-components/interaction/form/bds-switch.js +1 -1
- package/dist/web-components/interaction/form/bds-textarea.js +2 -1
- package/dist/web-components/ui/bds-alert.d.ts +8 -1
- package/dist/web-components/ui/bds-alert.js +1 -1
- package/dist/web-components/ui/bds-avatar.d.ts +11 -0
- package/dist/web-components/ui/bds-avatar.js +1 -1
- package/dist/web-components/ui/bds-notification-banner.d.ts +14 -1
- package/dist/web-components/ui/bds-notification-banner.js +1 -1
- package/dist/web-components/ui/bds-section-header.d.ts +6 -0
- package/dist/web-components/ui/bds-section-header.js +1 -1
- package/dist/web-components/ui/bds-separator.js +1 -1
- package/dist/web-components/ui/bds-table.js +1 -1
- package/package.json +6 -2
- package/src/components/interaction/DropdownMenu/DropdownMenu.mdx +35 -4
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +58 -10
- package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +114 -1
- package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +25 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +69 -17
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -0
- package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +7 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.mdx +1 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +7 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +22 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +1 -1
- package/src/components/interaction/form/Combobox/Combobox.module.css +1 -0
- package/src/components/interaction/form/Combobox/Combobox.spec.tsx +7 -0
- package/src/components/interaction/form/FormInput/FormInput.mdx +9 -0
- package/src/components/interaction/form/FormInput/FormInput.module.css +1 -0
- package/src/components/interaction/form/FormInput/FormInput.spec.tsx +7 -0
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +1 -0
- package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +7 -0
- package/src/components/interaction/form/Radio/Radio.module.css +1 -0
- package/src/components/interaction/form/Radio/Radio.spec.tsx +7 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.mdx +1 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +7 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +22 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +1 -1
- package/src/components/interaction/form/Select/Select.module.css +1 -0
- package/src/components/interaction/form/Select/Select.spec.tsx +7 -0
- package/src/components/interaction/form/Switch/Switch.module.css +1 -0
- package/src/components/interaction/form/Switch/Switch.spec.tsx +7 -0
- package/src/components/interaction/form/Textarea/Textarea.module.css +1 -0
- package/src/components/interaction/form/Textarea/Textarea.spec.tsx +7 -0
- package/src/components/interaction/form/atoms/Message.module.css +14 -3
- package/src/components/interaction/form/atoms/Message.spec.tsx +22 -0
- package/src/components/interaction/form/atoms/Message.tsx +5 -0
- package/src/components/layout/SectionHeader/SectionHeader.mdx +18 -5
- package/src/components/layout/SectionHeader/SectionHeader.module.css +35 -14
- package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +44 -0
- package/src/components/layout/SectionHeader/SectionHeader.stories.tsx +5 -0
- package/src/components/layout/SectionHeader/SectionHeader.tsx +3 -1
- package/src/components/ui/Alert/Alert.mdx +11 -0
- package/src/components/ui/Alert/Alert.module.css +30 -1
- package/src/components/ui/Alert/Alert.spec.tsx +21 -0
- package/src/components/ui/Alert/Alert.stories.tsx +20 -0
- package/src/components/ui/Alert/Alert.tsx +8 -1
- package/src/components/ui/Avatar/Avatar.mdx +22 -2
- package/src/components/ui/Avatar/Avatar.module.css +29 -2
- package/src/components/ui/Avatar/Avatar.spec.tsx +26 -0
- package/src/components/ui/Avatar/Avatar.stories.tsx +23 -0
- package/src/components/ui/Avatar/Avatar.tsx +4 -2
- package/src/components/ui/Avatar/avatarTone.spec.ts +41 -0
- package/src/components/ui/Avatar/avatarTone.ts +22 -0
- package/src/components/ui/Collapsible/Collapsible.module.css +1 -2
- package/src/components/ui/NotificationBanner/NotificationBanner.mdx +14 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +31 -1
- package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +29 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.stories.tsx +25 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.tsx +15 -1
- package/src/components/ui/Separator/Separator.mdx +1 -0
- package/src/components/ui/Separator/Separator.module.css +6 -0
- package/src/components/ui/Separator/Separator.spec.tsx +19 -0
- package/src/components/ui/Separator/Separator.stories.tsx +15 -0
- package/src/components/ui/Table/Table.mdx +4 -1
- package/src/components/ui/Table/Table.module.css +7 -7
- package/src/components/ui/Table/Table.spec.tsx +11 -0
- package/src/components/ui/Tabs/Tabs.mdx +11 -5
- package/src/components/ui/Tabs/Tabs.module.css +23 -5
- package/src/components/ui/Tabs/Tabs.spec.tsx +39 -0
- package/src/components/ui/Tabs/Tabs.tsx +2 -1
- package/src/components/ui/Tabs/getNodeText.spec.tsx +23 -0
- package/src/components/ui/Tabs/getNodeText.ts +13 -0
- package/src/components/ui/Tooltip/Tooltip.mdx +6 -3
- package/src/components/ui/Tooltip/Tooltip.module.css +6 -2
- package/src/components/ui/Tooltip/Tooltip.spec.tsx +10 -0
- package/src/components/ui/Tooltip/Tooltip.stories.tsx +13 -0
- package/src/css/bdc.css +5 -2
- package/src/css/bdc.spec.ts +65 -0
- package/src/stories/DesignSystem/Borders.mdx +17 -9
- package/src/web-components/globals.ts +10 -4
- package/src/web-components/index.ts +1 -0
- package/src/web-components/interaction/BdsAccordion.mdx +1 -1
- package/src/web-components/interaction/BdsAccordion.stories.tsx +1 -1
- package/src/web-components/interaction/BdsButton.mdx +1 -1
- package/src/web-components/interaction/BdsButton.stories.tsx +1 -1
- package/src/web-components/interaction/BdsCollapsible.mdx +1 -1
- package/src/web-components/interaction/BdsCollapsible.stories.tsx +1 -1
- package/src/web-components/interaction/BdsDialog.mdx +1 -1
- package/src/web-components/interaction/BdsDialog.stories.tsx +1 -1
- package/src/web-components/interaction/BdsDrawer.mdx +1 -1
- package/src/web-components/interaction/BdsDrawer.stories.tsx +1 -1
- package/src/web-components/interaction/BdsDropdownMenu.mdx +62 -6
- package/src/web-components/interaction/BdsDropdownMenu.stories.tsx +32 -7
- package/src/web-components/interaction/BdsPopover.mdx +1 -1
- package/src/web-components/interaction/BdsPopover.stories.tsx +1 -1
- package/src/web-components/interaction/BdsSkipLink.mdx +1 -1
- package/src/web-components/interaction/BdsSkipLink.stories.tsx +1 -1
- package/src/web-components/interaction/BdsTabs.mdx +10 -1
- package/src/web-components/interaction/BdsTabs.stories.tsx +1 -1
- package/src/web-components/interaction/BdsToastProvider.mdx +1 -1
- package/src/web-components/interaction/BdsToastProvider.stories.tsx +1 -1
- package/src/web-components/interaction/BdsTooltip.mdx +13 -5
- package/src/web-components/interaction/BdsTooltip.stories.tsx +12 -12
- package/src/web-components/interaction/bds-dropdown-menu-group.ts +72 -0
- package/src/web-components/interaction/bds-dropdown-menu-item.ts +65 -17
- package/src/web-components/interaction/bds-dropdown-menu.spec.ts +135 -0
- package/src/web-components/interaction/bds-dropdown-menu.ts +5 -4
- package/src/web-components/interaction/bds-tab.spec.ts +34 -2
- package/src/web-components/interaction/bds-tab.ts +31 -6
- package/src/web-components/interaction/bds-tooltip.spec.ts +16 -0
- package/src/web-components/interaction/bds-tooltip.ts +10 -8
- package/src/web-components/interaction/form/BdsCheckbox.mdx +5 -1
- package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +5 -1
- package/src/web-components/interaction/form/BdsCheckboxGroup.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsCombobox.mdx +5 -1
- package/src/web-components/interaction/form/BdsCombobox.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsFieldGroup.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsFileInput.mdx +1 -1
- package/src/web-components/interaction/form/BdsFileInput.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsFormInput.mdx +8 -1
- package/src/web-components/interaction/form/BdsFormInput.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsNumberInput.mdx +5 -1
- package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsRadio.mdx +5 -1
- package/src/web-components/interaction/form/BdsRadio.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsRadioGroup.mdx +5 -1
- package/src/web-components/interaction/form/BdsRadioGroup.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsSegmentedControl.mdx +1 -1
- package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsSelect.mdx +5 -1
- package/src/web-components/interaction/form/BdsSelect.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsSlider.mdx +5 -1
- package/src/web-components/interaction/form/BdsSlider.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsSwitch.mdx +5 -1
- package/src/web-components/interaction/form/BdsSwitch.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsTextarea.mdx +5 -1
- package/src/web-components/interaction/form/BdsTextarea.stories.tsx +1 -1
- package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +32 -3
- package/src/web-components/interaction/form/bds-checkbox-group.ts +33 -17
- package/src/web-components/interaction/form/bds-checkbox.ts +1 -0
- package/src/web-components/interaction/form/bds-combobox.ts +6 -16
- package/src/web-components/interaction/form/bds-form-input.ts +6 -16
- package/src/web-components/interaction/form/bds-number-input.ts +6 -16
- package/src/web-components/interaction/form/bds-radio-group.spec.ts +32 -3
- package/src/web-components/interaction/form/bds-radio-group.ts +26 -14
- package/src/web-components/interaction/form/bds-radio.ts +1 -0
- package/src/web-components/interaction/form/bds-select.ts +6 -16
- package/src/web-components/interaction/form/bds-slider.ts +5 -16
- package/src/web-components/interaction/form/bds-switch.ts +1 -0
- package/src/web-components/interaction/form/bds-textarea.ts +6 -16
- package/src/web-components/interaction/form/field-message.spec.ts +62 -0
- package/src/web-components/interaction/form/field-message.ts +55 -0
- package/src/web-components/layout/BdsGrid.mdx +1 -1
- package/src/web-components/layout/BdsGrid.stories.tsx +1 -1
- package/src/web-components/layout/BdsGridItem.mdx +1 -1
- package/src/web-components/layout/BdsGridItem.stories.tsx +1 -1
- package/src/web-components/ui/BdsAlert.mdx +19 -1
- package/src/web-components/ui/BdsAlert.stories.tsx +29 -3
- package/src/web-components/ui/BdsAvatar.mdx +20 -3
- package/src/web-components/ui/BdsAvatar.stories.tsx +25 -2
- package/src/web-components/ui/BdsBadge.mdx +1 -1
- package/src/web-components/ui/BdsBadge.stories.tsx +1 -1
- package/src/web-components/ui/BdsBreadcrumb.mdx +1 -1
- package/src/web-components/ui/BdsBreadcrumb.stories.tsx +1 -1
- package/src/web-components/ui/BdsButtonContainer.mdx +1 -1
- package/src/web-components/ui/BdsButtonContainer.stories.tsx +1 -1
- package/src/web-components/ui/BdsCalendar.mdx +1 -1
- package/src/web-components/ui/BdsCalendar.stories.tsx +1 -1
- package/src/web-components/ui/BdsCalendarRange.mdx +1 -1
- package/src/web-components/ui/BdsCalendarRange.stories.tsx +1 -1
- package/src/web-components/ui/BdsCard.mdx +1 -1
- package/src/web-components/ui/BdsCard.stories.tsx +1 -1
- package/src/web-components/ui/BdsCarousel.mdx +1 -1
- package/src/web-components/ui/BdsCarousel.stories.tsx +1 -1
- package/src/web-components/ui/BdsDescriptionList.mdx +1 -1
- package/src/web-components/ui/BdsDescriptionList.stories.tsx +1 -1
- package/src/web-components/ui/BdsIconWrapper.mdx +1 -1
- package/src/web-components/ui/BdsIconWrapper.stories.tsx +1 -1
- package/src/web-components/ui/BdsLink.mdx +1 -1
- package/src/web-components/ui/BdsLink.stories.tsx +1 -1
- package/src/web-components/ui/BdsLoading.mdx +1 -1
- package/src/web-components/ui/BdsLoading.stories.tsx +1 -1
- package/src/web-components/ui/BdsNotificationBanner.mdx +10 -1
- package/src/web-components/ui/BdsNotificationBanner.stories.tsx +29 -2
- package/src/web-components/ui/BdsPagination.mdx +1 -1
- package/src/web-components/ui/BdsPagination.stories.tsx +1 -1
- package/src/web-components/ui/BdsProgress.mdx +1 -1
- package/src/web-components/ui/BdsProgress.stories.tsx +1 -1
- package/src/web-components/ui/BdsProgressCircle.mdx +1 -1
- package/src/web-components/ui/BdsProgressCircle.stories.tsx +1 -1
- package/src/web-components/ui/BdsRating.mdx +1 -1
- package/src/web-components/ui/BdsRating.stories.tsx +1 -1
- package/src/web-components/ui/BdsSectionHeader.mdx +18 -6
- package/src/web-components/ui/BdsSectionHeader.stories.tsx +10 -2
- package/src/web-components/ui/BdsSeparator.mdx +2 -1
- package/src/web-components/ui/BdsSeparator.stories.tsx +13 -1
- package/src/web-components/ui/BdsSkeleton.mdx +1 -1
- package/src/web-components/ui/BdsSkeleton.stories.tsx +1 -1
- package/src/web-components/ui/BdsTable.mdx +5 -1
- package/src/web-components/ui/BdsTable.stories.tsx +1 -1
- package/src/web-components/ui/BdsTypography.mdx +1 -1
- package/src/web-components/ui/BdsTypography.stories.tsx +1 -1
- package/src/web-components/ui/bds-alert.spec.ts +27 -0
- package/src/web-components/ui/bds-alert.ts +34 -1
- package/src/web-components/ui/bds-avatar.spec.ts +47 -0
- package/src/web-components/ui/bds-avatar.ts +36 -3
- package/src/web-components/ui/bds-notification-banner.spec.ts +45 -0
- package/src/web-components/ui/bds-notification-banner.ts +53 -1
- package/src/web-components/ui/bds-section-header.spec.ts +36 -3
- package/src/web-components/ui/bds-section-header.ts +32 -10
- package/src/web-components/ui/bds-separator.spec.ts +8 -0
- package/src/web-components/ui/bds-separator.ts +7 -0
- package/src/web-components/ui/bds-table.spec.ts +11 -0
- package/src/web-components/ui/bds-table.ts +5 -5
- package/dist/web-components/chunk-QZAIRJ75.js +0 -111
|
@@ -48,6 +48,8 @@ The override surface is **layered**. Setting `--tab_color` / `--tab_border-color
|
|
|
48
48
|
<tbody>
|
|
49
49
|
<tr><td>`--tab_color`</td><td>per state</td><td>Tab text colour. Set to theme every state at once.</td></tr>
|
|
50
50
|
<tr><td>`--tab_border-color`</td><td>per state</td><td>Tab block-end border colour.</td></tr>
|
|
51
|
+
<tr><td>`--tab_font-weight`</td><td>per state</td><td>Tab font weight. Set to theme every state at once.</td></tr>
|
|
52
|
+
<tr><td>`--tab_indicator-width`</td><td>`3px`</td><td>Thickness of the block-end indicator line.</td></tr>
|
|
51
53
|
</tbody>
|
|
52
54
|
</table>
|
|
53
55
|
|
|
@@ -55,16 +57,16 @@ The override surface is **layered**. Setting `--tab_color` / `--tab_border-color
|
|
|
55
57
|
|
|
56
58
|
<table>
|
|
57
59
|
<thead>
|
|
58
|
-
<tr><th>State</th><th>Text</th><th>Border</th></tr>
|
|
60
|
+
<tr><th>State</th><th>Text</th><th>Border</th><th>Font weight</th></tr>
|
|
59
61
|
</thead>
|
|
60
62
|
<tbody>
|
|
61
|
-
<tr><td>resting</td><td
|
|
62
|
-
<tr><td>hover</td><td>`--tab_color--hover`</td><td>—</td></tr>
|
|
63
|
-
<tr><td>active</td><td>`--tab_color--active`</td><td>`--tab_border-color--active`</td></tr>
|
|
63
|
+
<tr><td>resting</td><td>`--tab_color--inactive`</td><td>(`transparent`)</td><td>`--tab_font-weight--inactive`</td></tr>
|
|
64
|
+
<tr><td>hover</td><td>`--tab_color--hover`</td><td>—</td><td>—</td></tr>
|
|
65
|
+
<tr><td>active</td><td>`--tab_color--active`</td><td>`--tab_border-color--active`</td><td>`--tab_font-weight--active`</td></tr>
|
|
64
66
|
</tbody>
|
|
65
67
|
</table>
|
|
66
68
|
|
|
67
|
-
Defaults:
|
|
69
|
+
Defaults: resting text is `--bds-color_on-bg--muted` (falls back to `--bds-color_on-bg`) at `--bds-font_weight--medium`; hover and active text are `--bds-color_on-bg`; active is `--bds-font_weight--bold` with a `--bds-color_interactive` indicator.
|
|
68
70
|
|
|
69
71
|
### Spacing tokens
|
|
70
72
|
|
|
@@ -80,6 +82,10 @@ Defaults: hover/active text resolves to `--bds-color_interactive_on-bg`; active
|
|
|
80
82
|
</tbody>
|
|
81
83
|
</table>
|
|
82
84
|
|
|
85
|
+
## Layout stability
|
|
86
|
+
|
|
87
|
+
The label sits in a `<span data-label>` with a hidden `::after` that repeats the text at the active weight (`--tab_font-weight--active`), so the tab keeps its bold width and selecting a tab does not shift the row. The text comes from `TabItem.label` (strings, numbers and nested elements); the hidden copy is invisible and not read by screen readers.
|
|
88
|
+
|
|
83
89
|
## Accessibility
|
|
84
90
|
|
|
85
91
|
- Implements ARIA tabs pattern: `role="tablist"`, `role="tab"`, `role="tabpanel"`
|
|
@@ -17,19 +17,37 @@
|
|
|
17
17
|
padding: var(--tab_padding, var(--bds-space_s) var(--bds-space_m));
|
|
18
18
|
font-family: var(--bds-font_family--body);
|
|
19
19
|
font-size: var(--bds-font_size--body);
|
|
20
|
-
font-weight: var(--bds-font_weight--
|
|
20
|
+
font-weight: var(--tab_font-weight, var(--tab_font-weight--state, var(--tab_font-weight--inactive, var(--bds-font_weight--medium))));
|
|
21
21
|
|
|
22
22
|
/* Layered cascade: public overrides (--tab_color, --tab_border-color) win over
|
|
23
23
|
per-state defaults. Active/hover write to the inner --tab_*--state slot. */
|
|
24
|
-
color: var(--tab_color, var(--tab_color--state, var(--bds-color_on-bg)));
|
|
25
|
-
border-block-end:
|
|
24
|
+
color: var(--tab_color, var(--tab_color--state, var(--tab_color--inactive, var(--bds-color_on-bg--muted, var(--bds-color_on-bg)))));
|
|
25
|
+
border-block-end: var(--tab_indicator-width, 3px) solid var(--tab_border-color, var(--tab_border-color--state, transparent));
|
|
26
26
|
margin-block-end: -1px;
|
|
27
27
|
cursor: pointer;
|
|
28
28
|
transition: var(--bds-animation_transition);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/* Reserves the width of the bold label so selecting a tab does not shift the row.
|
|
32
|
+
The hidden ::after repeats the label at the active weight in the same grid cell:
|
|
33
|
+
it adds width but no height and stays out of the accessibility tree. */
|
|
34
|
+
.label {
|
|
35
|
+
display: inline-grid;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.label::after {
|
|
39
|
+
content: attr(data-label);
|
|
40
|
+
grid-area: 1 / 1;
|
|
41
|
+
font-weight: var(--tab_font-weight, var(--tab_font-weight--active, var(--bds-font_weight--bold)));
|
|
42
|
+
visibility: hidden;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
block-size: 0;
|
|
45
|
+
overflow: hidden;
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
.tab.--active {
|
|
32
|
-
--tab_color--state: var(--tab_color--active, var(--bds-
|
|
49
|
+
--tab_color--state: var(--tab_color--active, var(--bds-color_on-bg));
|
|
50
|
+
--tab_font-weight--state: var(--tab_font-weight--active, var(--bds-font_weight--bold));
|
|
33
51
|
--tab_border-color--state: var(--tab_border-color--active, var(--bds-color_interactive));
|
|
34
52
|
}
|
|
35
53
|
|
|
@@ -46,7 +64,7 @@
|
|
|
46
64
|
|
|
47
65
|
@media (hover: hover) and (pointer: fine) {
|
|
48
66
|
.tab:not(:disabled, .--active):hover {
|
|
49
|
-
--tab_color--state: var(--tab_color--hover, var(--bds-
|
|
67
|
+
--tab_color--state: var(--tab_color--hover, var(--bds-color_on-bg));
|
|
50
68
|
}
|
|
51
69
|
}
|
|
52
70
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
1
3
|
import { render, screen } from '@testing-library/react';
|
|
2
4
|
import userEvent from '@testing-library/user-event';
|
|
3
5
|
import { Tabs } from './Tabs';
|
|
@@ -108,4 +110,41 @@ describe('Tabs', () => {
|
|
|
108
110
|
render(<Tabs tabs={tabs} />);
|
|
109
111
|
expect(screen.getByText('First panel').closest('[role="tabpanel"]')).toHaveAttribute('tabindex', '0');
|
|
110
112
|
});
|
|
113
|
+
|
|
114
|
+
it('wraps the label with a data-label that reserves the bold width', () => {
|
|
115
|
+
render(<Tabs tabs={[{ id: 'a', label: <>Inbox <em>4</em></>, content: null }]} />);
|
|
116
|
+
const label = screen.getByRole('tab').querySelector('span');
|
|
117
|
+
expect(label).toHaveAttribute('data-label', 'Inbox 4');
|
|
118
|
+
expect(label).toHaveTextContent('Inbox 4');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('styling hooks', () => {
|
|
122
|
+
it('reserves the active font weight through a hidden ::after', () => {
|
|
123
|
+
const rules = readFileSync(resolve(process.cwd(), 'src/components/ui/Tabs/Tabs.module.css'), 'utf8');
|
|
124
|
+
expect(rules).toMatch(/\.label\s*\{\s*display:\s*inline-grid;/);
|
|
125
|
+
expect(rules).toMatch(/\.label::after\s*\{[^}]*content:\s*attr\(data-label\)/);
|
|
126
|
+
expect(rules).toMatch(/\.label::after\s*\{[^}]*font-weight:\s*var\(--tab_font-weight,\s*var\(--tab_font-weight--active,\s*var\(--bds-font_weight--bold\)\)\)/);
|
|
127
|
+
expect(rules).toMatch(/\.label::after\s*\{[^}]*visibility:\s*hidden/);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const css = readFileSync(resolve(process.cwd(), 'src/components/ui/Tabs/Tabs.module.css'), 'utf8');
|
|
131
|
+
|
|
132
|
+
it('styles the resting tab muted and medium', () => {
|
|
133
|
+
expect(css).toMatch(/color:\s*var\(--tab_color,\s*var\(--tab_color--state,\s*var\(--tab_color--inactive,\s*var\(--bds-color_on-bg--muted,\s*var\(--bds-color_on-bg\)\)\)\)\)/);
|
|
134
|
+
expect(css).toMatch(/font-weight:\s*var\(--tab_font-weight,\s*var\(--tab_font-weight--state,\s*var\(--tab_font-weight--inactive,\s*var\(--bds-font_weight--medium\)\)\)\)/);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('styles the active tab in the full text colour and bold', () => {
|
|
138
|
+
expect(css).toMatch(/--tab_color--state:\s*var\(--tab_color--active,\s*var\(--bds-color_on-bg\)\)/);
|
|
139
|
+
expect(css).toMatch(/--tab_font-weight--state:\s*var\(--tab_font-weight--active,\s*var\(--bds-font_weight--bold\)\)/);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('sizes the indicator through --tab_indicator-width', () => {
|
|
143
|
+
expect(css).toMatch(/border-block-end:\s*var\(--tab_indicator-width,\s*3px\) solid/);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('shows the full text colour on hover', () => {
|
|
147
|
+
expect(css).toMatch(/--tab_color--state:\s*var\(--tab_color--hover,\s*var\(--bds-color_on-bg\)\)/);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
111
150
|
});
|
|
@@ -2,6 +2,7 @@ import { HTMLAttributes, KeyboardEvent, ReactNode, useId, useRef, useState } fro
|
|
|
2
2
|
import css from './Tabs.module.css';
|
|
3
3
|
import { cn } from '@boostdev/design-system-foundation';
|
|
4
4
|
import type { WithClassName } from '../../../types';
|
|
5
|
+
import { getNodeText } from './getNodeText';
|
|
5
6
|
|
|
6
7
|
export interface TabItem {
|
|
7
8
|
id: string;
|
|
@@ -74,7 +75,7 @@ export function Tabs({ tabs, defaultTab, className, ...rest }: Readonly<TabsProp
|
|
|
74
75
|
onClick={() => setActiveTab(tab.id)}
|
|
75
76
|
onKeyDown={e => handleKeyDown(e, i)}
|
|
76
77
|
>
|
|
77
|
-
{tab.label}
|
|
78
|
+
<span className={css.label} data-label={getNodeText(tab.label)}>{tab.label}</span>
|
|
78
79
|
</button>
|
|
79
80
|
);
|
|
80
81
|
})}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getNodeText } from './getNodeText';
|
|
2
|
+
|
|
3
|
+
describe('getNodeText', () => {
|
|
4
|
+
it('returns strings and numbers as text', () => {
|
|
5
|
+
expect(getNodeText('Overview')).toBe('Overview');
|
|
6
|
+
expect(getNodeText(3)).toBe('3');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('ignores booleans, null and undefined', () => {
|
|
10
|
+
expect(getNodeText(null)).toBe('');
|
|
11
|
+
expect(getNodeText(undefined)).toBe('');
|
|
12
|
+
expect(getNodeText(false)).toBe('');
|
|
13
|
+
expect(getNodeText(true)).toBe('');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('joins arrays', () => {
|
|
17
|
+
expect(getNodeText(['Inbox ', 4, false])).toBe('Inbox 4');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('reads element children recursively', () => {
|
|
21
|
+
expect(getNodeText(<span>Inbox <strong>(<em>4</em>)</strong></span>)).toBe('Inbox (4)');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isValidElement } from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Plain text of a ReactNode: strings and numbers as written, arrays and element
|
|
6
|
+
* children joined, booleans/null/undefined ignored. Pure, so it also runs on the server.
|
|
7
|
+
*/
|
|
8
|
+
export function getNodeText(node: ReactNode): string {
|
|
9
|
+
if (typeof node === 'string' || typeof node === 'number') return String(node);
|
|
10
|
+
if (Array.isArray(node)) return node.map(getNodeText).join('');
|
|
11
|
+
if (isValidElement<{ children?: ReactNode }>(node)) return getNodeText(node.props.children);
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
@@ -29,6 +29,9 @@ Short contextual label that appears on hover or focus. Use to supplement icon bu
|
|
|
29
29
|
### Right
|
|
30
30
|
<Canvas of={Stories.Right} />
|
|
31
31
|
|
|
32
|
+
### Long text
|
|
33
|
+
<Canvas of={Stories.LongText} />
|
|
34
|
+
|
|
32
35
|
### All placements
|
|
33
36
|
<Canvas of={Stories.AllPlacements} />
|
|
34
37
|
|
|
@@ -48,11 +51,11 @@ Short contextual label that appears on hover or focus. Use to supplement icon bu
|
|
|
48
51
|
<tbody>
|
|
49
52
|
<tr><td>`--tooltip_bg`</td><td>`var(--bds-color_on-bg)`</td><td>Tooltip background colour</td></tr>
|
|
50
53
|
<tr><td>`--tooltip_text`</td><td>`var(--bds-color_bg)`</td><td>Tooltip text colour</td></tr>
|
|
51
|
-
<tr><td>`--tooltip_radius`</td><td>`var(--bds-border_radius--
|
|
52
|
-
<tr><td>`--tooltip_padding`</td><td>`var(--bds-space_xxs) var(--bds-
|
|
54
|
+
<tr><td>`--tooltip_radius`</td><td>`var(--bds-border_radius--xs)`</td><td>Tooltip corner radius</td></tr>
|
|
55
|
+
<tr><td>`--tooltip_padding`</td><td>`var(--bds-space_xxs) var(--bds-space_s)`</td><td>Tooltip padding</td></tr>
|
|
53
56
|
<tr><td>`--tooltip_font-size`</td><td>`var(--bds-font_size--body--s)`</td><td>Tooltip text size</td></tr>
|
|
54
57
|
<tr><td>`--tooltip_offset`</td><td>`var(--bds-space_xs)`</td><td>Gap between the trigger and the tooltip. Set to `0` to close the gap so the pointer can travel from the trigger onto the tooltip without a dead zone.</td></tr>
|
|
55
|
-
<tr><td>`--tooltip_max-inline-size`</td><td>`20rem`</td><td>Maximum inline size before content wraps</td></tr>
|
|
58
|
+
<tr><td>`--tooltip_max-inline-size`</td><td>`20rem`</td><td>Maximum inline size before content wraps. The tooltip is as wide as its text (`max-content`) up to this value</td></tr>
|
|
56
59
|
</tbody>
|
|
57
60
|
</table>
|
|
58
61
|
|
|
@@ -17,12 +17,16 @@
|
|
|
17
17
|
display: block;
|
|
18
18
|
position: absolute;
|
|
19
19
|
z-index: var(--bds-z-index_popover);
|
|
20
|
-
padding: var(--tooltip_padding, var(--bds-space_xxs) var(--bds-
|
|
21
|
-
border-radius: var(--tooltip_radius, var(--bds-border_radius--
|
|
20
|
+
padding: var(--tooltip_padding, var(--bds-space_xxs) var(--bds-space_s));
|
|
21
|
+
border-radius: var(--tooltip_radius, var(--bds-border_radius--xs));
|
|
22
22
|
background-color: var(--tooltip_bg, var(--bds-color_on-bg));
|
|
23
23
|
color: var(--tooltip_text, var(--bds-color_bg));
|
|
24
24
|
font-size: var(--tooltip_font-size, var(--bds-font_size--body--s));
|
|
25
25
|
line-height: var(--bds-font_line-height--body);
|
|
26
|
+
|
|
27
|
+
/* Size to the text, not to the (possibly narrow) trigger wrapper the
|
|
28
|
+
tooltip is absolutely positioned in; wrap only at the max width. */
|
|
29
|
+
inline-size: max-content;
|
|
26
30
|
max-inline-size: var(--tooltip_max-inline-size, 20rem);
|
|
27
31
|
white-space: normal;
|
|
28
32
|
pointer-events: none;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { render, screen } from '@testing-library/react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
3
5
|
import { Tooltip } from './Tooltip';
|
|
4
6
|
|
|
5
7
|
describe('Tooltip', () => {
|
|
@@ -99,4 +101,12 @@ describe('Tooltip', () => {
|
|
|
99
101
|
await user.unhover(tooltip);
|
|
100
102
|
expect(tooltip).not.toBeVisible();
|
|
101
103
|
});
|
|
104
|
+
|
|
105
|
+
it('sizes the tooltip to its text and uses the xs radius hook default', () => {
|
|
106
|
+
const css = readFileSync(resolve(process.cwd(), 'src/components/ui/Tooltip/Tooltip.module.css'), 'utf8');
|
|
107
|
+
expect(css).toMatch(/inline-size:\s*max-content;/);
|
|
108
|
+
expect(css).toMatch(/max-inline-size:\s*var\(--tooltip_max-inline-size,\s*20rem\);/);
|
|
109
|
+
expect(css).toContain('var(--tooltip_radius, var(--bds-border_radius--xs))');
|
|
110
|
+
expect(css).toContain('var(--tooltip_padding, var(--bds-space_xxs) var(--bds-space_s))');
|
|
111
|
+
});
|
|
102
112
|
});
|
|
@@ -56,6 +56,19 @@ export const Right: Story = {
|
|
|
56
56
|
),
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
export const LongText: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
content:
|
|
62
|
+
'Longer explanation that wraps onto a second line once it reaches the maximum width of the tooltip.',
|
|
63
|
+
placement: 'bottom',
|
|
64
|
+
},
|
|
65
|
+
render: args => (
|
|
66
|
+
<Tooltip {...args}>
|
|
67
|
+
<Button>Long tooltip</Button>
|
|
68
|
+
</Tooltip>
|
|
69
|
+
),
|
|
70
|
+
};
|
|
71
|
+
|
|
59
72
|
export const AllPlacements: Story = {
|
|
60
73
|
render: () => (
|
|
61
74
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '3rem' }}>
|
package/src/css/bdc.css
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* --bdc-outline_* — tokens that directly map to CSS outline sub-properties
|
|
10
10
|
*
|
|
11
11
|
* @property declarations must be top-level (not inside @layer).
|
|
12
|
+
* The :root defaults live in boostdev.tokens.semantic so a consumer can override them in
|
|
13
|
+
* boostdev.tokens.override. --bdc-outline_width inherits so a :root value reaches components.
|
|
12
14
|
* --bdc_color uses inherits: false so each element owns its own colour instance,
|
|
13
15
|
* enabling per-element transition: --bdc_color for focus/error state animations.
|
|
14
16
|
* ─────────────────────────────────────────────────────────────────────────────── */
|
|
@@ -22,7 +24,7 @@
|
|
|
22
24
|
|
|
23
25
|
@property --bdc-outline_width {
|
|
24
26
|
syntax: '<length>';
|
|
25
|
-
inherits:
|
|
27
|
+
inherits: true;
|
|
26
28
|
initial-value: 1px;
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
initial-value: 0 0 0 0 transparent;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
@layer boostdev.
|
|
51
|
+
@layer boostdev.tokens.semantic {
|
|
50
52
|
:root {
|
|
51
53
|
/* border: none by default — outline provides the visual edge */
|
|
52
54
|
--bdc-outline_border: none;
|
|
@@ -66,6 +68,7 @@
|
|
|
66
68
|
|
|
67
69
|
/* Outline geometry */
|
|
68
70
|
--bdc-outline_width: 1px;
|
|
71
|
+
--bdc-outline_width--error: 2px;
|
|
69
72
|
--bdc-outline_offset: -1px; /* available for consumer use; bdc borders now use inset box-shadow */
|
|
70
73
|
--bdc-outline_radius: var(--bds-border_radius--xs);
|
|
71
74
|
--bdc-outline_radius--l: 1.5em;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
|
|
5
|
+
const read = (path: string): string => readFileSync(resolve(__dirname, path), 'utf8');
|
|
6
|
+
|
|
7
|
+
const sources = {
|
|
8
|
+
'bdc.css': read('./bdc.css'),
|
|
9
|
+
'globals.ts': read('../web-components/globals.ts'),
|
|
10
|
+
} as const;
|
|
11
|
+
|
|
12
|
+
/** Returns the text between the braces of `@layer boostdev.tokens.semantic { ... }`. */
|
|
13
|
+
const semanticLayerBody = (source: string): string | undefined => {
|
|
14
|
+
const start = source.indexOf('@layer boostdev.tokens.semantic');
|
|
15
|
+
if (start === -1) return undefined;
|
|
16
|
+
const open = source.indexOf('{', start);
|
|
17
|
+
const body = [...source.slice(open)].reduce<{ depth: number; end: number }>(
|
|
18
|
+
(acc, ch, i) => {
|
|
19
|
+
if (acc.end !== -1) return acc;
|
|
20
|
+
const depth = acc.depth + (ch === '{' ? 1 : ch === '}' ? -1 : 0);
|
|
21
|
+
return { depth, end: depth === 0 ? i : -1 };
|
|
22
|
+
},
|
|
23
|
+
{ depth: 0, end: -1 },
|
|
24
|
+
);
|
|
25
|
+
return source.slice(open + 1, open + body.end);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const rootDeclarations = (source: string): string[] =>
|
|
29
|
+
[...(semanticLayerBody(source) ?? '').matchAll(/^\s*(--[\w-]+)\s*:/gm)].map((m) => m[1] ?? '');
|
|
30
|
+
|
|
31
|
+
describe.each(Object.entries(sources))('%s', (_name, source) => {
|
|
32
|
+
it('puts the :root defaults in boostdev.tokens.semantic', () => {
|
|
33
|
+
const body = semanticLayerBody(source);
|
|
34
|
+
expect(body).toBeDefined();
|
|
35
|
+
expect(body).toContain(':root');
|
|
36
|
+
expect(body).toContain('--bdc-color_active:');
|
|
37
|
+
expect(body).toContain('--bdc_color--error:');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('does not put the :root defaults in boostdev.component', () => {
|
|
41
|
+
expect(source).not.toContain('@layer boostdev.component');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('registers --bdc-outline_width as inheriting', () => {
|
|
45
|
+
expect(source).toMatch(/@property --bdc-outline_width\s*\{[^}]*inherits:\s*true/);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('keeps the per-element tokens non-inheriting', () => {
|
|
49
|
+
['--bdc_color', '--bdc-outline_offset', '--bdc-outline_radius', '--bdc-outline_shadow'].forEach((token) => {
|
|
50
|
+
expect(source).toMatch(new RegExp(`@property ${token}\\s*\\{[^}]*inherits:\\s*false`));
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('declares the error outline width', () => {
|
|
55
|
+
expect(source).toContain('--bdc-outline_width--error: 2px;');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('bdc.css and globals.ts', () => {
|
|
60
|
+
it('declare the same set of :root custom properties', () => {
|
|
61
|
+
expect([...rootDeclarations(sources['globals.ts'])].sort()).toEqual(
|
|
62
|
+
[...rootDeclarations(sources['bdc.css'])].sort(),
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -123,23 +123,31 @@ See `src/components/ui/Accordion/Accordion.module.css` for a shipped example of
|
|
|
123
123
|
|
|
124
124
|
## Consumer overrides
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
The `:root` defaults of the `bdc` tokens (`--bdc_color--focus`, `--bdc_color--error`, `--bdc-color_active*`, `--bdc-color_on-active*`, `--bdc-outline_width`, `--bdc-outline_width--error`, `--bds-outline_default`, `--bds-outline_offset`) live in `@layer boostdev.tokens.semantic`, so they can be set in `@layer boostdev.tokens.override`:
|
|
127
127
|
|
|
128
128
|
```css
|
|
129
|
-
/* Scoped to a single component instance */
|
|
130
|
-
.my-context .my-input {
|
|
131
|
-
--bdc_color: var(--bds-color_warning);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* Override globally via the token layer */
|
|
135
129
|
@layer boostdev.tokens.override {
|
|
136
130
|
:root {
|
|
137
|
-
--
|
|
131
|
+
--bdc-color_active: var(--bds-color_green);
|
|
132
|
+
--bdc_color--focus: var(--bds-color_green);
|
|
133
|
+
--bdc-outline_width: 2px;
|
|
138
134
|
}
|
|
139
135
|
}
|
|
140
136
|
```
|
|
141
137
|
|
|
142
|
-
|
|
138
|
+
The `bdc` defaults now share the `boostdev.tokens.semantic` layer with the foundation, so load the component stylesheet after the foundation stylesheet for the solid focus ring to win (the documented import order already does this). `--bdc-outline_radius` is registered with `inherits: false` and set by each component itself, so it cannot be set on `:root`.
|
|
139
|
+
|
|
140
|
+
`--bdc-outline_width` is registered with `inherits: true`, so a value on `:root` or on a wrapper reaches the components inside it.
|
|
141
|
+
|
|
142
|
+
`--bdc_color` is per element by design (`inherits: false`): every component owns its own instance so its state colour can transition. Do not set it on `:root`; that has no effect. Change a component's rest border colour through the component's own hook instead:
|
|
143
|
+
|
|
144
|
+
```css
|
|
145
|
+
.my-menu {
|
|
146
|
+
--dropdown_border-color: var(--bds-color_warning);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
To change width or radius for one element:
|
|
143
151
|
|
|
144
152
|
```css
|
|
145
153
|
.my-card {
|
|
@@ -14,7 +14,7 @@ const bdcCss = `
|
|
|
14
14
|
|
|
15
15
|
@property --bdc-outline_width {
|
|
16
16
|
syntax: '<length>';
|
|
17
|
-
inherits:
|
|
17
|
+
inherits: true;
|
|
18
18
|
initial-value: 1px;
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -36,7 +36,7 @@ const bdcCss = `
|
|
|
36
36
|
initial-value: 0 0 0 0 transparent;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
@layer boostdev.
|
|
39
|
+
@layer boostdev.tokens.semantic {
|
|
40
40
|
:root {
|
|
41
41
|
--bdc-outline_border: none;
|
|
42
42
|
|
|
@@ -47,14 +47,20 @@ const bdcCss = `
|
|
|
47
47
|
/* Active / selected state colours — override these to theme all filled form controls globally */
|
|
48
48
|
--bdc-color_active: var(--bds-color_interactive);
|
|
49
49
|
--bdc-color_on-active: var(--bds-color_on-interactive);
|
|
50
|
-
--bdc-color_active--subtle:
|
|
51
|
-
--bdc-
|
|
50
|
+
--bdc-color_active--subtle: var(--bds-color_blue--subtle);
|
|
51
|
+
--bdc-color_on-active--subtle: var(--bds-color_on-blue--subtle);
|
|
52
|
+
--bdc-color_active--strong: var(--bds-color_interactive_on-bg);
|
|
53
|
+
--bdc-color_on-active--strong: var(--bds-color_on-blue--strong);
|
|
52
54
|
|
|
53
55
|
--bdc-outline_width: 1px;
|
|
56
|
+
--bdc-outline_width--error: 2px;
|
|
54
57
|
--bdc-outline_offset: -1px; /* available for consumer use; bdc borders now use inset box-shadow */
|
|
55
58
|
--bdc-outline_radius: var(--bds-border_radius--xs);
|
|
56
59
|
--bdc-outline_radius--l: 1.5em;
|
|
57
60
|
--bdc-outline_shadow: 0 0 0 0 transparent;
|
|
61
|
+
|
|
62
|
+
--bds-outline_default: 2px solid var(--bds-color_interactive);
|
|
63
|
+
--bds-outline_offset: 2px;
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
`;
|
|
@@ -77,3 +77,4 @@ export { BdsCalendar } from './ui/bds-calendar';
|
|
|
77
77
|
export { BdsCalendarRange } from './ui/bds-calendar-range';
|
|
78
78
|
export { BdsDropdownMenu } from './interaction/bds-dropdown-menu';
|
|
79
79
|
export { BdsDropdownMenuItem } from './interaction/bds-dropdown-menu-item';
|
|
80
|
+
export { BdsDropdownMenuGroup } from './interaction/bds-dropdown-menu-group';
|
|
@@ -7,7 +7,7 @@ import * as Stories from './BdsAccordion.stories';
|
|
|
7
7
|
|
|
8
8
|
Framework-agnostic Accordion custom element. Coordinates open/closed state across `<bds-accordion-item>` children; by default only one item is open at a time.
|
|
9
9
|
|
|
10
|
-
> **Status:
|
|
10
|
+
> **Status: alpha** — API may change before stable release.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -61,7 +61,7 @@ function BdsAccordionStory({
|
|
|
61
61
|
const meta = {
|
|
62
62
|
title: 'Web Components/UI/Accordion',
|
|
63
63
|
component: BdsAccordionStory,
|
|
64
|
-
tags: ['!stable', '
|
|
64
|
+
tags: ['!stable', 'alpha'],
|
|
65
65
|
parameters: { layout: 'padded' },
|
|
66
66
|
argTypes: {
|
|
67
67
|
allowMultiple: { control: 'boolean' },
|
|
@@ -7,7 +7,7 @@ import * as Stories from './BdsButton.stories';
|
|
|
7
7
|
|
|
8
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
9
|
|
|
10
|
-
> **Status:
|
|
10
|
+
> **Status: alpha** — API may change before stable release.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -101,7 +101,7 @@ type BdsButtonStoryArgs = Omit<BdsButtonProps, 'iconStart' | 'iconEnd'> & {
|
|
|
101
101
|
const meta: Meta<BdsButtonStoryArgs> = {
|
|
102
102
|
title: 'Web Components/Interaction/Button',
|
|
103
103
|
component: BdsButton,
|
|
104
|
-
tags: ['!stable', '
|
|
104
|
+
tags: ['!stable', 'alpha'],
|
|
105
105
|
parameters: { layout: 'centered' },
|
|
106
106
|
argTypes: {
|
|
107
107
|
variant: {
|
|
@@ -7,7 +7,7 @@ import * as Stories from './BdsCollapsible.stories';
|
|
|
7
7
|
|
|
8
8
|
Framework-agnostic Collapsible custom element. Wraps a native `<details>`/`<summary>` pair for built-in toggle behaviour with design-system styling and a `bds-toggle` event.
|
|
9
9
|
|
|
10
|
-
> **Status:
|
|
10
|
+
> **Status: alpha** — API may change before stable release.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -25,7 +25,7 @@ function BdsCollapsible({
|
|
|
25
25
|
const meta = {
|
|
26
26
|
title: 'Web Components/UI/Collapsible',
|
|
27
27
|
component: BdsCollapsible,
|
|
28
|
-
tags: ['!stable', '
|
|
28
|
+
tags: ['!stable', 'alpha'],
|
|
29
29
|
parameters: { layout: 'padded' },
|
|
30
30
|
argTypes: {
|
|
31
31
|
open: { control: 'boolean' },
|
|
@@ -7,7 +7,7 @@ import * as Stories from './BdsDialog.stories';
|
|
|
7
7
|
|
|
8
8
|
Framework-agnostic Dialog custom element. Wraps a native `<dialog>` element with `showModal()` / `close()` lifecycle, backdrop-click to dismiss, Escape key handling, Tab focus trapping, and the Invoker Commands API (custom commands).
|
|
9
9
|
|
|
10
|
-
> **Status:
|
|
10
|
+
> **Status: alpha** — API may change before stable release.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -53,7 +53,7 @@ function BdsDialog({
|
|
|
53
53
|
const meta = {
|
|
54
54
|
title: 'Web Components/Interaction/Dialog',
|
|
55
55
|
component: BdsDialog,
|
|
56
|
-
tags: ['!stable', '
|
|
56
|
+
tags: ['!stable', 'alpha'],
|
|
57
57
|
parameters: { layout: 'centered' },
|
|
58
58
|
argTypes: {
|
|
59
59
|
triggerLabel: { control: 'text' },
|
|
@@ -7,7 +7,7 @@ import * as Stories from './BdsDrawer.stories';
|
|
|
7
7
|
|
|
8
8
|
Framework-agnostic Drawer (slide-in panel) custom element. Same modal infrastructure as `<bds-dialog>` but positioned as a side panel that slides in from either side of the viewport.
|
|
9
9
|
|
|
10
|
-
> **Status:
|
|
10
|
+
> **Status: alpha** — API may change before stable release.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -54,7 +54,7 @@ function BdsDrawer({
|
|
|
54
54
|
const meta = {
|
|
55
55
|
title: 'Web Components/Interaction/Drawer',
|
|
56
56
|
component: BdsDrawer,
|
|
57
|
-
tags: ['!stable', '
|
|
57
|
+
tags: ['!stable', 'alpha'],
|
|
58
58
|
parameters: { layout: 'centered' },
|
|
59
59
|
argTypes: {
|
|
60
60
|
side: { control: 'select', options: ['left', 'right'] },
|