@boostdev/design-system-components 1.1.1 → 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-2QA62WCQ.js +48 -0
- package/dist/web-components/chunk-3REOIRDW.js +246 -0
- package/dist/web-components/chunk-57TRNCWQ.js +93 -0
- package/dist/web-components/chunk-5IPHEONG.js +139 -0
- package/dist/web-components/chunk-5R6IFELV.js +63 -0
- package/dist/web-components/chunk-5TFWOPLH.js +49 -0
- package/dist/web-components/chunk-6I3CFC26.js +89 -0
- package/dist/web-components/chunk-6MH5UWUD.js +226 -0
- package/dist/web-components/chunk-7FMR53BW.js +127 -0
- package/dist/web-components/chunk-AGKJTMJI.js +56 -0
- package/dist/web-components/chunk-AJSXNDAP.js +151 -0
- package/dist/web-components/chunk-BQLZ7I4G.js +56 -0
- package/dist/web-components/chunk-BX3IPVOB.js +167 -0
- package/dist/web-components/chunk-CR5PGUHV.js +109 -0
- package/dist/web-components/chunk-DI46Q2EA.js +278 -0
- package/dist/web-components/chunk-DZRSJGPB.js +53 -0
- package/dist/web-components/chunk-EBJM3VD4.js +107 -0
- package/dist/web-components/chunk-ECW3HHWA.js +185 -0
- package/dist/web-components/chunk-HGBNDR22.js +98 -0
- package/dist/web-components/chunk-HHHRF2PS.js +118 -0
- package/dist/web-components/chunk-ITHLKR7Q.js +105 -0
- package/dist/web-components/chunk-JUKB3BUP.js +186 -0
- package/dist/web-components/chunk-L3XHOMN6.js +111 -0
- package/dist/{web-components.js → web-components/chunk-LGEZYFUU.js} +62 -844
- package/dist/web-components/chunk-LY62SAVN.js +64 -0
- package/dist/web-components/chunk-N6IMUOY4.js +185 -0
- package/dist/web-components/chunk-OHUTLSIQ.js +69 -0
- package/dist/web-components/chunk-OQTRTMAB.js +27 -0
- package/dist/web-components/chunk-PY62FTRW.js +179 -0
- package/dist/web-components/chunk-Q4T5BJT6.js +94 -0
- package/dist/web-components/chunk-QDST57JC.js +119 -0
- package/dist/web-components/chunk-QLZ2362S.js +279 -0
- package/dist/web-components/chunk-QPOKHLMQ.js +45 -0
- package/dist/web-components/chunk-SOQQ7RVJ.js +88 -0
- package/dist/web-components/chunk-T6AETZRP.js +131 -0
- package/dist/web-components/chunk-UFFCKVZE.js +149 -0
- package/dist/web-components/chunk-VMMVWLXL.js +53 -0
- package/dist/web-components/chunk-X3FKVHLK.js +144 -0
- package/dist/web-components/chunk-XNA6WTXG.js +133 -0
- package/dist/web-components/chunk-Y4MAXTMA.js +80 -0
- package/dist/web-components/chunk-YLVTEY23.js +165 -0
- package/dist/web-components/chunk-YRXCVKHV.js +116 -0
- package/dist/web-components/chunk-ZTC6GRP7.js +64 -0
- package/dist/web-components/globals.d.ts +2 -0
- package/dist/web-components/globals.js +1 -0
- package/dist/web-components/index.d.ts +41 -0
- package/dist/web-components/index.js +165 -0
- package/dist/web-components/interaction/bds-accordion-item.d.ts +54 -0
- package/dist/web-components/interaction/bds-accordion-item.js +7 -0
- package/dist/web-components/interaction/bds-accordion.d.ts +50 -0
- package/dist/web-components/interaction/bds-accordion.js +7 -0
- package/dist/web-components/interaction/bds-button.d.ts +100 -0
- package/dist/web-components/interaction/bds-button.js +7 -0
- package/dist/web-components/interaction/bds-collapsible.d.ts +52 -0
- package/dist/web-components/interaction/bds-collapsible.js +7 -0
- package/dist/web-components/interaction/bds-dialog.d.ts +56 -0
- package/dist/web-components/interaction/bds-dialog.js +7 -0
- package/dist/web-components/interaction/bds-drawer.d.ts +64 -0
- package/dist/web-components/interaction/bds-drawer.js +7 -0
- package/dist/web-components/interaction/bds-popover.d.ts +62 -0
- package/dist/web-components/interaction/bds-popover.js +7 -0
- package/dist/web-components/interaction/bds-skip-link.d.ts +36 -0
- package/dist/web-components/interaction/bds-skip-link.js +7 -0
- package/dist/web-components/interaction/bds-tab-panel.d.ts +26 -0
- package/dist/web-components/interaction/bds-tab-panel.js +7 -0
- package/dist/web-components/interaction/bds-tab.d.ts +45 -0
- package/dist/web-components/interaction/bds-tab.js +7 -0
- package/dist/web-components/interaction/bds-tabs.d.ts +46 -0
- package/dist/web-components/interaction/bds-tabs.js +7 -0
- package/dist/web-components/interaction/bds-toast-provider.d.ts +57 -0
- package/dist/web-components/interaction/bds-toast-provider.js +7 -0
- package/dist/web-components/interaction/bds-tooltip.d.ts +50 -0
- package/dist/web-components/interaction/bds-tooltip.js +7 -0
- package/dist/web-components/interaction/form/bds-checkbox.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-checkbox.js +7 -0
- package/dist/web-components/interaction/form/bds-combobox.d.ts +84 -0
- package/dist/web-components/interaction/form/bds-combobox.js +7 -0
- package/dist/web-components/interaction/form/bds-file-input.d.ts +62 -0
- package/dist/web-components/interaction/form/bds-file-input.js +7 -0
- package/dist/web-components/interaction/form/bds-number-input.d.ts +68 -0
- package/dist/web-components/interaction/form/bds-number-input.js +7 -0
- package/dist/web-components/interaction/form/bds-radio.d.ts +68 -0
- package/dist/web-components/interaction/form/bds-radio.js +7 -0
- package/dist/web-components/interaction/form/bds-segmented-control.d.ts +88 -0
- package/dist/web-components/interaction/form/bds-segmented-control.js +7 -0
- package/dist/web-components/interaction/form/bds-select.d.ts +79 -0
- package/dist/web-components/interaction/form/bds-select.js +7 -0
- package/dist/web-components/interaction/form/bds-slider.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-slider.js +7 -0
- package/dist/web-components/interaction/form/bds-switch.d.ts +67 -0
- package/dist/web-components/interaction/form/bds-switch.js +7 -0
- package/dist/web-components/interaction/form/bds-textarea.d.ts +70 -0
- package/dist/web-components/interaction/form/bds-textarea.js +7 -0
- package/dist/web-components/ui/bds-alert.d.ts +66 -0
- package/dist/web-components/ui/bds-alert.js +7 -0
- package/dist/web-components/ui/bds-avatar.d.ts +50 -0
- package/dist/web-components/ui/bds-avatar.js +7 -0
- package/dist/web-components/ui/bds-badge.d.ts +35 -0
- package/dist/web-components/ui/bds-badge.js +7 -0
- package/dist/web-components/ui/bds-breadcrumb.d.ts +35 -0
- package/dist/web-components/ui/bds-breadcrumb.js +7 -0
- package/dist/web-components/ui/bds-card.d.ts +72 -0
- package/dist/web-components/ui/bds-card.js +7 -0
- package/dist/web-components/ui/bds-description-list.d.ts +42 -0
- package/dist/web-components/ui/bds-description-list.js +7 -0
- package/dist/web-components/ui/bds-icon-wrapper.d.ts +39 -0
- package/dist/web-components/ui/bds-icon-wrapper.js +7 -0
- package/dist/web-components/ui/bds-link.d.ts +59 -0
- package/dist/web-components/ui/bds-link.js +7 -0
- package/dist/web-components/ui/bds-loading.d.ts +32 -0
- package/dist/web-components/ui/bds-loading.js +7 -0
- package/dist/web-components/ui/bds-notification-banner.d.ts +61 -0
- package/dist/web-components/ui/bds-notification-banner.js +7 -0
- package/dist/web-components/ui/bds-progress-circle.d.ts +53 -0
- package/dist/web-components/ui/bds-progress-circle.js +7 -0
- package/dist/web-components/ui/bds-progress.d.ts +54 -0
- package/dist/web-components/ui/bds-progress.js +7 -0
- package/dist/web-components/ui/bds-rating.d.ts +36 -0
- package/dist/web-components/ui/bds-rating.js +7 -0
- package/dist/web-components/ui/bds-section-header.d.ts +53 -0
- package/dist/web-components/ui/bds-section-header.js +8 -0
- package/dist/web-components/ui/bds-separator.d.ts +32 -0
- package/dist/web-components/ui/bds-separator.js +7 -0
- package/dist/web-components/ui/bds-skeleton.d.ts +22 -0
- package/dist/web-components/ui/bds-skeleton.js +7 -0
- package/dist/web-components/ui/bds-typography.d.ts +44 -0
- package/dist/web-components/ui/bds-typography.js +8 -0
- package/package.json +170 -5
- 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/index.ts +47 -0
- 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-item.spec.ts +75 -0
- package/src/web-components/interaction/bds-accordion-item.ts +181 -0
- package/src/web-components/interaction/bds-accordion.spec.ts +73 -0
- package/src/web-components/interaction/bds-accordion.ts +98 -0
- package/src/web-components/interaction/bds-button.ts +15 -13
- package/src/web-components/interaction/bds-collapsible.spec.ts +56 -0
- package/src/web-components/interaction/bds-collapsible.ts +170 -0
- package/src/web-components/interaction/bds-dialog.spec.ts +119 -0
- package/src/web-components/interaction/bds-dialog.ts +221 -0
- package/src/web-components/interaction/bds-drawer.spec.ts +113 -0
- package/src/web-components/interaction/bds-drawer.ts +315 -0
- package/src/web-components/interaction/bds-skip-link.spec.ts +42 -0
- package/src/web-components/interaction/bds-skip-link.ts +74 -0
- package/src/web-components/interaction/bds-tab-panel.spec.ts +32 -0
- package/src/web-components/interaction/bds-tab-panel.ts +38 -0
- package/src/web-components/interaction/bds-tab.spec.ts +71 -0
- package/src/web-components/interaction/bds-tab.ts +110 -0
- package/src/web-components/interaction/bds-tabs.spec.ts +120 -0
- package/src/web-components/interaction/bds-tabs.ts +152 -0
- package/src/web-components/interaction/bds-tooltip.spec.ts +49 -0
- package/src/web-components/interaction/bds-tooltip.ts +127 -0
- package/src/web-components/interaction/form/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.spec.ts +63 -0
- package/src/web-components/interaction/form/bds-checkbox.ts +166 -0
- package/src/web-components/interaction/form/bds-combobox.spec.ts +117 -0
- package/src/web-components/interaction/form/bds-combobox.ts +334 -0
- package/src/web-components/interaction/form/bds-file-input.spec.ts +58 -0
- package/src/web-components/interaction/form/bds-file-input.ts +209 -0
- package/src/web-components/interaction/form/bds-number-input.spec.ts +87 -0
- package/src/web-components/interaction/form/bds-number-input.ts +220 -0
- package/src/web-components/interaction/form/bds-radio.spec.ts +70 -0
- package/src/web-components/interaction/form/bds-radio.ts +151 -0
- package/src/web-components/interaction/form/bds-segmented-control.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-segmented-control.ts +282 -0
- package/src/web-components/interaction/form/bds-select.spec.ts +74 -0
- package/src/web-components/interaction/form/bds-select.ts +188 -0
- package/src/web-components/interaction/form/bds-slider.spec.ts +41 -0
- package/src/web-components/interaction/form/bds-slider.ts +162 -0
- package/src/web-components/interaction/form/bds-switch.spec.ts +62 -0
- package/src/web-components/interaction/form/bds-switch.ts +165 -0
- package/src/web-components/interaction/form/bds-textarea.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-textarea.ts +141 -0
- 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-avatar.spec.ts +75 -0
- package/src/web-components/ui/bds-avatar.ts +122 -0
- package/src/web-components/ui/bds-breadcrumb.spec.ts +55 -0
- package/src/web-components/ui/bds-breadcrumb.ts +114 -0
- package/src/web-components/ui/bds-card.spec.ts +70 -0
- package/src/web-components/ui/bds-card.ts +154 -0
- package/src/web-components/ui/bds-description-list.spec.ts +36 -0
- package/src/web-components/ui/bds-description-list.ts +79 -0
- package/src/web-components/ui/bds-icon-wrapper.spec.ts +21 -0
- package/src/web-components/ui/bds-icon-wrapper.ts +68 -0
- package/src/web-components/ui/bds-link.spec.ts +72 -0
- package/src/web-components/ui/bds-link.ts +138 -0
- package/src/web-components/ui/bds-loading.spec.ts +38 -0
- package/src/web-components/ui/bds-loading.ts +76 -0
- package/src/web-components/ui/bds-notification-banner.spec.ts +82 -0
- package/src/web-components/ui/bds-notification-banner.ts +184 -0
- package/src/web-components/ui/bds-progress-circle.spec.ts +58 -0
- package/src/web-components/ui/bds-progress-circle.ts +142 -0
- package/src/web-components/ui/bds-progress.spec.ts +66 -0
- package/src/web-components/ui/bds-progress.ts +127 -0
- package/src/web-components/ui/bds-rating.spec.ts +70 -0
- package/src/web-components/ui/bds-rating.ts +80 -0
- package/src/web-components/ui/bds-section-header.spec.ts +57 -0
- package/src/web-components/ui/bds-section-header.ts +96 -0
- package/src/web-components/ui/bds-separator.spec.ts +50 -0
- package/src/web-components/ui/bds-separator.ts +66 -0
- package/src/web-components/ui/bds-skeleton.spec.ts +22 -0
- package/src/web-components/ui/bds-skeleton.ts +55 -0
- package/src/web-components/ui/bds-typography.spec.ts +76 -0
- package/src/web-components/ui/bds-typography.ts +112 -0
- package/dist/web-components.d.ts +0 -304
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsTabs } from './bds-tabs';
|
|
3
|
+
import { BdsTab } from './bds-tab';
|
|
4
|
+
import { BdsTabPanel } from './bds-tab-panel';
|
|
5
|
+
|
|
6
|
+
const html = `
|
|
7
|
+
<bds-tabs>
|
|
8
|
+
<bds-tab slot="tab">Tab 1</bds-tab>
|
|
9
|
+
<bds-tab slot="tab">Tab 2</bds-tab>
|
|
10
|
+
<bds-tab slot="tab" disabled>Tab 3</bds-tab>
|
|
11
|
+
<bds-tab-panel slot="panel">Panel 1</bds-tab-panel>
|
|
12
|
+
<bds-tab-panel slot="panel">Panel 2</bds-tab-panel>
|
|
13
|
+
<bds-tab-panel slot="panel">Panel 3</bds-tab-panel>
|
|
14
|
+
</bds-tabs>
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
describe('bds-tabs', () => {
|
|
18
|
+
it('is registered as a custom element', () => {
|
|
19
|
+
expect(customElements.get('bds-tabs')).toBe(BdsTabs);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('renders a tablist div with role="tablist"', async () => {
|
|
23
|
+
const el = await fixture(html);
|
|
24
|
+
const tablist = el.shadowRoot!.querySelector('[role="tablist"]');
|
|
25
|
+
expect(tablist).not.toBeNull();
|
|
26
|
+
cleanup(el);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('selects the first tab by default', async () => {
|
|
30
|
+
const el = await fixture(html);
|
|
31
|
+
// Wait for deferred _applyState
|
|
32
|
+
await Promise.resolve();
|
|
33
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
34
|
+
expect(tabs[0].selected).toBe(true);
|
|
35
|
+
expect(tabs[1].selected).toBe(false);
|
|
36
|
+
cleanup(el);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('first panel is visible, others are hidden by default', async () => {
|
|
40
|
+
const el = await fixture(html);
|
|
41
|
+
await Promise.resolve();
|
|
42
|
+
const panels = [...el.querySelectorAll<BdsTabPanel>('bds-tab-panel')];
|
|
43
|
+
expect(panels[0].hasAttribute('hidden')).toBe(false);
|
|
44
|
+
expect(panels[1].hasAttribute('hidden')).toBe(true);
|
|
45
|
+
cleanup(el);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('switches to tab on bds-tab-select event', async () => {
|
|
49
|
+
const el = await fixture(html);
|
|
50
|
+
await Promise.resolve();
|
|
51
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
52
|
+
const panels = [...el.querySelectorAll<BdsTabPanel>('bds-tab-panel')];
|
|
53
|
+
|
|
54
|
+
tabs[1].dispatchEvent(new CustomEvent('bds-tab-select', { bubbles: true, composed: true }));
|
|
55
|
+
|
|
56
|
+
expect(tabs[0].selected).toBe(false);
|
|
57
|
+
expect(tabs[1].selected).toBe(true);
|
|
58
|
+
expect(panels[0].hasAttribute('hidden')).toBe(true);
|
|
59
|
+
expect(panels[1].hasAttribute('hidden')).toBe(false);
|
|
60
|
+
cleanup(el);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('does not switch to a disabled tab on bds-tab-select', async () => {
|
|
64
|
+
const el = await fixture(html);
|
|
65
|
+
await Promise.resolve();
|
|
66
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
67
|
+
// Ensure the tab is marked disabled (Lit property may not reflect from HTML attribute in jsdom)
|
|
68
|
+
tabs[2].disabled = true;
|
|
69
|
+
|
|
70
|
+
tabs[2].dispatchEvent(new CustomEvent('bds-tab-select', { bubbles: true, composed: true }));
|
|
71
|
+
|
|
72
|
+
expect(tabs[0].selected).toBe(true);
|
|
73
|
+
expect(tabs[2].selected).toBe(false);
|
|
74
|
+
cleanup(el);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('ArrowRight moves to next enabled tab', async () => {
|
|
78
|
+
const el = await fixture(html);
|
|
79
|
+
await Promise.resolve();
|
|
80
|
+
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));
|
|
81
|
+
await Promise.resolve();
|
|
82
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
83
|
+
expect(tabs[1].selected).toBe(true);
|
|
84
|
+
cleanup(el);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('ArrowLeft wraps around to last enabled tab', async () => {
|
|
88
|
+
const el = await fixture(html);
|
|
89
|
+
await Promise.resolve();
|
|
90
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
91
|
+
tabs[2].disabled = true; // ensure disabled is set (Lit property may not reflect from HTML attribute in jsdom)
|
|
92
|
+
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft', bubbles: true }));
|
|
93
|
+
// disabled tab is skipped; enabled tabs are 0 and 1 → wraps to last enabled (index 1)
|
|
94
|
+
expect(tabs[1].selected).toBe(true);
|
|
95
|
+
cleanup(el);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('Home moves to the first enabled tab', async () => {
|
|
99
|
+
const el = await fixture(html);
|
|
100
|
+
await Promise.resolve();
|
|
101
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
102
|
+
await Promise.all(tabs.map(t => t.updateComplete));
|
|
103
|
+
// Navigate to tab 1 first
|
|
104
|
+
tabs[1].dispatchEvent(new CustomEvent('bds-tab-select', { bubbles: true, composed: true }));
|
|
105
|
+
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Home', bubbles: true }));
|
|
106
|
+
expect(tabs[0].selected).toBe(true);
|
|
107
|
+
cleanup(el);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('End moves to the last enabled tab', async () => {
|
|
111
|
+
const el = await fixture(html);
|
|
112
|
+
await Promise.resolve();
|
|
113
|
+
const tabs = [...el.querySelectorAll<BdsTab>('bds-tab')];
|
|
114
|
+
tabs[2].disabled = true; // ensure disabled is set
|
|
115
|
+
el.dispatchEvent(new KeyboardEvent('keydown', { key: 'End', bubbles: true }));
|
|
116
|
+
// Last enabled tab is index 1 (tab 3 is disabled)
|
|
117
|
+
expect(tabs[1].selected).toBe(true);
|
|
118
|
+
cleanup(el);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { LitElement, css, html } from 'lit';
|
|
2
|
+
import type { BdsTab } from './bds-tab';
|
|
3
|
+
import type { BdsTabPanel } from './bds-tab-panel';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `<bds-tabs>` — framework-agnostic Tabs custom element.
|
|
7
|
+
*
|
|
8
|
+
* Contains `<bds-tab>` and `<bds-tab-panel>` children. Tabs and panels are
|
|
9
|
+
* matched by DOM order: the first tab corresponds to the first panel, etc.
|
|
10
|
+
*
|
|
11
|
+
* Use `slot="tab"` on `<bds-tab>` elements and `slot="panel"` on
|
|
12
|
+
* `<bds-tab-panel>` elements.
|
|
13
|
+
*
|
|
14
|
+
* Keyboard navigation: ArrowLeft/Right moves between tabs, Home/End jumps to
|
|
15
|
+
* first/last enabled tab.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <bds-tabs>
|
|
19
|
+
* <bds-tab slot="tab">Overview</bds-tab>
|
|
20
|
+
* <bds-tab slot="tab">Details</bds-tab>
|
|
21
|
+
* <bds-tab slot="tab" disabled>Disabled</bds-tab>
|
|
22
|
+
* <bds-tab-panel slot="panel">Overview content</bds-tab-panel>
|
|
23
|
+
* <bds-tab-panel slot="panel">Details content</bds-tab-panel>
|
|
24
|
+
* <bds-tab-panel slot="panel">Disabled content</bds-tab-panel>
|
|
25
|
+
* </bds-tabs>
|
|
26
|
+
*/
|
|
27
|
+
export class BdsTabs extends LitElement {
|
|
28
|
+
static styles = css`
|
|
29
|
+
:host {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.tablist {
|
|
35
|
+
display: flex;
|
|
36
|
+
border-block-end: 1px solid var(--bds-color_bg--subtle);
|
|
37
|
+
gap: var(--bds-space_xxs);
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
private _activeIndex = 0;
|
|
42
|
+
private _mo: MutationObserver | null = null;
|
|
43
|
+
|
|
44
|
+
connectedCallback() {
|
|
45
|
+
super.connectedCallback();
|
|
46
|
+
this.addEventListener('bds-tab-select', this._handleTabSelect);
|
|
47
|
+
this.addEventListener('keydown', this._handleKeydown);
|
|
48
|
+
this._mo = new MutationObserver(() => { this._applyState(); });
|
|
49
|
+
this._mo.observe(this, { childList: true, subtree: false });
|
|
50
|
+
// Defer initial state so children have been upgraded
|
|
51
|
+
Promise.resolve().then(() => this._applyState());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
disconnectedCallback() {
|
|
55
|
+
super.disconnectedCallback();
|
|
56
|
+
this.removeEventListener('bds-tab-select', this._handleTabSelect);
|
|
57
|
+
this.removeEventListener('keydown', this._handleKeydown);
|
|
58
|
+
this._mo?.disconnect();
|
|
59
|
+
this._mo = null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private get _tabs(): BdsTab[] {
|
|
63
|
+
return [...this.querySelectorAll<BdsTab>('bds-tab')];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private get _panels(): BdsTabPanel[] {
|
|
67
|
+
return [...this.querySelectorAll<BdsTabPanel>('bds-tab-panel')];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private get _enabledIndexes(): number[] {
|
|
71
|
+
return this._tabs
|
|
72
|
+
.map((tab, i) => ({ tab, i }))
|
|
73
|
+
.filter(({ tab }) => !tab.disabled)
|
|
74
|
+
.map(({ i }) => i);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private _applyState() {
|
|
78
|
+
const tabs = this._tabs;
|
|
79
|
+
const panels = this._panels;
|
|
80
|
+
|
|
81
|
+
// Clamp active index if tabs were removed
|
|
82
|
+
if (this._activeIndex >= tabs.length) {
|
|
83
|
+
this._activeIndex = Math.max(0, tabs.length - 1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
tabs.forEach((tab, i) => {
|
|
87
|
+
tab.selected = (i === this._activeIndex);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
panels.forEach((panel, i) => {
|
|
91
|
+
if (i === this._activeIndex) {
|
|
92
|
+
panel.removeAttribute('hidden');
|
|
93
|
+
} else {
|
|
94
|
+
panel.setAttribute('hidden', '');
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private _handleTabSelect = (e: Event) => {
|
|
100
|
+
const tab = e.target as BdsTab;
|
|
101
|
+
const index = this._tabs.indexOf(tab);
|
|
102
|
+
if (index !== -1 && !tab.disabled) {
|
|
103
|
+
this._activeIndex = index;
|
|
104
|
+
this._applyState();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
private _handleKeydown = (e: KeyboardEvent) => {
|
|
109
|
+
const enabled = this._enabledIndexes;
|
|
110
|
+
if (!enabled.length) return;
|
|
111
|
+
|
|
112
|
+
const pos = enabled.indexOf(this._activeIndex);
|
|
113
|
+
|
|
114
|
+
let next = -1;
|
|
115
|
+
if (e.key === 'ArrowRight') {
|
|
116
|
+
e.preventDefault();
|
|
117
|
+
next = enabled[(pos + 1) % enabled.length];
|
|
118
|
+
} else if (e.key === 'ArrowLeft') {
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
next = enabled[(pos - 1 + enabled.length) % enabled.length];
|
|
121
|
+
} else if (e.key === 'Home') {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
next = enabled[0];
|
|
124
|
+
} else if (e.key === 'End') {
|
|
125
|
+
e.preventDefault();
|
|
126
|
+
next = enabled[enabled.length - 1];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (next !== -1) {
|
|
130
|
+
this._activeIndex = next;
|
|
131
|
+
this._applyState();
|
|
132
|
+
this._tabs[next]?.focusButton?.();
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
render() {
|
|
137
|
+
return html`
|
|
138
|
+
<div class="tablist" role="tablist">
|
|
139
|
+
<slot name="tab"></slot>
|
|
140
|
+
</div>
|
|
141
|
+
<slot name="panel"></slot>
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
customElements.define('bds-tabs', BdsTabs);
|
|
147
|
+
|
|
148
|
+
declare global {
|
|
149
|
+
interface HTMLElementTagNameMap {
|
|
150
|
+
'bds-tabs': BdsTabs;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { fixture, cleanup } from '../test/helpers';
|
|
2
|
+
import { BdsTooltip } from './bds-tooltip';
|
|
3
|
+
|
|
4
|
+
describe('bds-tooltip', () => {
|
|
5
|
+
it('is registered as a custom element', () => {
|
|
6
|
+
expect(customElements.get('bds-tooltip')).toBe(BdsTooltip);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('defaults to placement="top"', async () => {
|
|
10
|
+
const el = await fixture('<bds-tooltip content="Tip"><button>?</button></bds-tooltip>');
|
|
11
|
+
expect(el.getAttribute('placement')).toBe('top');
|
|
12
|
+
cleanup(el);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders a tooltip span with role="tooltip"', async () => {
|
|
16
|
+
const el = await fixture('<bds-tooltip content="Helpful text"><button>?</button></bds-tooltip>');
|
|
17
|
+
const tooltip = el.shadowRoot!.querySelector('[role="tooltip"]');
|
|
18
|
+
expect(tooltip).not.toBeNull();
|
|
19
|
+
cleanup(el);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('renders the content text in the tooltip', async () => {
|
|
23
|
+
const el = await fixture('<bds-tooltip content="Helpful text"><button>?</button></bds-tooltip>');
|
|
24
|
+
const tooltip = el.shadowRoot!.querySelector('[role="tooltip"]');
|
|
25
|
+
expect(tooltip!.textContent?.trim()).toBe('Helpful text');
|
|
26
|
+
cleanup(el);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('applies placement class to the tooltip', async () => {
|
|
30
|
+
const el = await fixture('<bds-tooltip content="Tip" placement="bottom"><button>?</button></bds-tooltip>');
|
|
31
|
+
const tooltip = el.shadowRoot!.querySelector('.tooltip');
|
|
32
|
+
expect(tooltip!.classList.contains('--placement_bottom')).toBe(true);
|
|
33
|
+
cleanup(el);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('reflects placement property updates', async () => {
|
|
37
|
+
const el = await fixture('<bds-tooltip content="Tip"><button>?</button></bds-tooltip>') as BdsTooltip;
|
|
38
|
+
el.placement = 'right';
|
|
39
|
+
await el.updateComplete;
|
|
40
|
+
expect(el.getAttribute('placement')).toBe('right');
|
|
41
|
+
cleanup(el);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('renders slotted trigger content', async () => {
|
|
45
|
+
const el = await fixture('<bds-tooltip content="Tip"><button type="button">Help</button></bds-tooltip>');
|
|
46
|
+
expect(el.querySelector('button')!.textContent).toBe('Help');
|
|
47
|
+
cleanup(el);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { LitElement, css, html } from 'lit';
|
|
2
|
+
|
|
3
|
+
export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `<bds-tooltip>` — framework-agnostic Tooltip custom element.
|
|
7
|
+
*
|
|
8
|
+
* Shows a tooltip panel on hover and keyboard focus using CSS-only visibility.
|
|
9
|
+
* The tooltip position is controlled via the `placement` attribute.
|
|
10
|
+
*
|
|
11
|
+
* Attributes:
|
|
12
|
+
* content — text to display in the tooltip
|
|
13
|
+
* placement — "top" (default) | "bottom" | "left" | "right"
|
|
14
|
+
*
|
|
15
|
+
* Slots:
|
|
16
|
+
* (default) — the trigger element (button, icon, etc.)
|
|
17
|
+
*
|
|
18
|
+
* Accessibility:
|
|
19
|
+
* The `aria-describedby` relationship between trigger and tooltip panel
|
|
20
|
+
* cannot cross shadow DOM boundaries; screen readers will announce the tooltip
|
|
21
|
+
* via role="tooltip" proximity when it becomes visible.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* <bds-tooltip content="More information" placement="bottom">
|
|
25
|
+
* <button type="button">?</button>
|
|
26
|
+
* </bds-tooltip>
|
|
27
|
+
*/
|
|
28
|
+
export class BdsTooltip extends LitElement {
|
|
29
|
+
static styles = css`
|
|
30
|
+
:host {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
position: relative;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.tooltip {
|
|
37
|
+
position: absolute;
|
|
38
|
+
z-index: var(--bds-z-index_popover, 200);
|
|
39
|
+
padding: var(--bds-space_xxs) var(--bds-space_xs);
|
|
40
|
+
border-radius: var(--bds-border_radius--xs);
|
|
41
|
+
background-color: var(--tooltip_bg, var(--bds-color_on-bg));
|
|
42
|
+
color: var(--tooltip_text, var(--bds-color_bg));
|
|
43
|
+
font-size: var(--bds-font_size--body--s);
|
|
44
|
+
line-height: var(--bds-font_line-height--body);
|
|
45
|
+
white-space: nowrap;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
|
|
48
|
+
/* Hidden by default */
|
|
49
|
+
visibility: hidden;
|
|
50
|
+
opacity: 0;
|
|
51
|
+
transition: opacity var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Show on hover and keyboard focus */
|
|
55
|
+
:host(:hover) .tooltip,
|
|
56
|
+
:host(:focus-within) .tooltip {
|
|
57
|
+
visibility: visible;
|
|
58
|
+
opacity: 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Placement: top (default) */
|
|
62
|
+
.tooltip.--placement_top {
|
|
63
|
+
inset-block-end: calc(100% + var(--bds-space_xs));
|
|
64
|
+
inset-inline-start: 50%;
|
|
65
|
+
transform: translateX(-50%);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Placement: bottom */
|
|
69
|
+
.tooltip.--placement_bottom {
|
|
70
|
+
inset-block-start: calc(100% + var(--bds-space_xs));
|
|
71
|
+
inset-inline-start: 50%;
|
|
72
|
+
transform: translateX(-50%);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Placement: left */
|
|
76
|
+
.tooltip.--placement_left {
|
|
77
|
+
inset-inline-end: calc(100% + var(--bds-space_xs));
|
|
78
|
+
inset-block-start: 50%;
|
|
79
|
+
transform: translateY(-50%);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Placement: right */
|
|
83
|
+
.tooltip.--placement_right {
|
|
84
|
+
inset-inline-start: calc(100% + var(--bds-space_xs));
|
|
85
|
+
inset-block-start: 50%;
|
|
86
|
+
transform: translateY(-50%);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@media (prefers-reduced-motion: reduce) {
|
|
90
|
+
.tooltip {
|
|
91
|
+
transition: none;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
static properties = {
|
|
97
|
+
content: { type: String },
|
|
98
|
+
placement: { type: String, reflect: true },
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
declare content: string;
|
|
102
|
+
declare placement: TooltipPlacement;
|
|
103
|
+
|
|
104
|
+
constructor() {
|
|
105
|
+
super();
|
|
106
|
+
this.content = '';
|
|
107
|
+
this.placement = 'top';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
render() {
|
|
111
|
+
return html`
|
|
112
|
+
<slot></slot>
|
|
113
|
+
<span
|
|
114
|
+
class="tooltip --placement_${this.placement}"
|
|
115
|
+
role="tooltip"
|
|
116
|
+
>${this.content}</span>
|
|
117
|
+
`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
customElements.define('bds-tooltip', BdsTooltip);
|
|
122
|
+
|
|
123
|
+
declare global {
|
|
124
|
+
interface HTMLElementTagNameMap {
|
|
125
|
+
'bds-tooltip': BdsTooltip;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsCheckbox.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# Checkbox
|
|
7
|
+
|
|
8
|
+
`<bds-checkbox>` is a form-associated custom element that participates in HTML forms via the Form-Associated Custom Elements API. Native browser validation (`required`) works without any wrapper.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<bds-checkbox name="agree" value="yes" required>I agree to the terms</bds-checkbox>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Attributes
|
|
17
|
+
|
|
18
|
+
| Attribute | Type | Default | Description |
|
|
19
|
+
|------------|-----------|---------|-------------------------------------|
|
|
20
|
+
| `name` | `string` | `""` | Form field name |
|
|
21
|
+
| `value` | `string` | `"on"` | Submitted value when checked |
|
|
22
|
+
| `checked` | `boolean` | `false` | Whether the checkbox is checked |
|
|
23
|
+
| `required` | `boolean` | `false` | Marks the field as required |
|
|
24
|
+
| `disabled` | `boolean` | `false` | Disables interaction |
|
|
25
|
+
|
|
26
|
+
## Slots
|
|
27
|
+
|
|
28
|
+
| Slot | Description |
|
|
29
|
+
|-----------|---------------|
|
|
30
|
+
| (default) | Label text |
|
|
31
|
+
|
|
32
|
+
## Stories
|
|
33
|
+
|
|
34
|
+
<Canvas of={Stories.Default} />
|
|
35
|
+
<Canvas of={Stories.AllVariants} />
|
|
36
|
+
|
|
37
|
+
## Controls
|
|
38
|
+
|
|
39
|
+
<ArgTypes of={Stories} />
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import '../../index';
|
|
4
|
+
|
|
5
|
+
function BdsCheckbox({
|
|
6
|
+
label = 'Check me',
|
|
7
|
+
checked,
|
|
8
|
+
disabled,
|
|
9
|
+
required,
|
|
10
|
+
}: {
|
|
11
|
+
label?: string;
|
|
12
|
+
checked?: boolean;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
}) {
|
|
16
|
+
return React.createElement(
|
|
17
|
+
'bds-checkbox',
|
|
18
|
+
{
|
|
19
|
+
checked: checked || undefined,
|
|
20
|
+
disabled: disabled || undefined,
|
|
21
|
+
required: required || undefined,
|
|
22
|
+
},
|
|
23
|
+
label,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const meta = {
|
|
28
|
+
title: 'Web Components/Interaction/Form/Checkbox',
|
|
29
|
+
component: BdsCheckbox,
|
|
30
|
+
tags: ['!stable', 'experimental'],
|
|
31
|
+
parameters: { layout: 'padded' },
|
|
32
|
+
argTypes: {
|
|
33
|
+
checked: { control: 'boolean' },
|
|
34
|
+
disabled: { control: 'boolean' },
|
|
35
|
+
required: { control: 'boolean' },
|
|
36
|
+
},
|
|
37
|
+
} satisfies Meta<typeof BdsCheckbox>;
|
|
38
|
+
|
|
39
|
+
export default meta;
|
|
40
|
+
type Story = StoryObj<typeof meta>;
|
|
41
|
+
|
|
42
|
+
export const Default: Story = { args: { label: 'Accept terms and conditions' } };
|
|
43
|
+
export const Checked: Story = { args: { label: 'Already checked', checked: true } };
|
|
44
|
+
export const Disabled: Story = { args: { label: 'Disabled option', disabled: true } };
|
|
45
|
+
export const DisabledChecked: Story = { args: { label: 'Disabled and checked', checked: true, disabled: true } };
|
|
46
|
+
|
|
47
|
+
export const AllVariants: Story = {
|
|
48
|
+
render: () => (
|
|
49
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
|
|
50
|
+
{React.createElement('bds-checkbox', null, 'Unchecked')}
|
|
51
|
+
{React.createElement('bds-checkbox', { checked: true }, 'Checked')}
|
|
52
|
+
{React.createElement('bds-checkbox', { disabled: true }, 'Disabled')}
|
|
53
|
+
{React.createElement('bds-checkbox', { checked: true, disabled: true }, 'Disabled checked')}
|
|
54
|
+
{React.createElement('bds-checkbox', { required: true }, 'Required')}
|
|
55
|
+
</div>
|
|
56
|
+
),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const Interactive: Story = {
|
|
60
|
+
render: () => {
|
|
61
|
+
const [checked, setChecked] = React.useState(false);
|
|
62
|
+
return (
|
|
63
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
64
|
+
<p style={{ margin: 0, fontSize: '0.875rem' }}>State: {checked ? 'checked' : 'unchecked'}</p>
|
|
65
|
+
{React.createElement(
|
|
66
|
+
'bds-checkbox',
|
|
67
|
+
{ checked: checked || undefined, onChange: (e: Event) => setChecked((e.target as HTMLInputElement).checked) },
|
|
68
|
+
'Controlled checkbox',
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as Stories from './BdsCombobox.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={Stories} />
|
|
5
|
+
|
|
6
|
+
# Combobox
|
|
7
|
+
|
|
8
|
+
`<bds-combobox>` is a form-associated autocomplete input. The user types to filter options and selects with Enter or mouse click. Keyboard navigation: ArrowDown/ArrowUp to move focus, Enter to select, Escape to close.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<bds-combobox
|
|
14
|
+
name="country"
|
|
15
|
+
placeholder="Search…"
|
|
16
|
+
options='[{"value":"nl","label":"Netherlands"},{"value":"be","label":"Belgium"}]'
|
|
17
|
+
></bds-combobox>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Attributes
|
|
21
|
+
|
|
22
|
+
| Attribute | Type | Default | Description |
|
|
23
|
+
|---------------|-----------|---------|-----------------------------------------------------|
|
|
24
|
+
| `name` | `string` | `""` | Form field name |
|
|
25
|
+
| `value` | `string` | `""` | Currently selected value |
|
|
26
|
+
| `options` | `string` | `"[]"` | JSON array of `{ value, label, disabled? }` objects |
|
|
27
|
+
| `placeholder` | `string` | `""` | Input placeholder text |
|
|
28
|
+
| `disabled` | `boolean` | `false` | Disables the combobox |
|
|
29
|
+
|
|
30
|
+
## Events
|
|
31
|
+
|
|
32
|
+
| Event | Detail | Description |
|
|
33
|
+
|--------------|----------------------------|----------------------------------|
|
|
34
|
+
| `bds-change` | `{ value, label }` | Fired when an option is selected |
|
|
35
|
+
|
|
36
|
+
## Keyboard Navigation
|
|
37
|
+
|
|
38
|
+
| Key | Action |
|
|
39
|
+
|-------------|-------------------------|
|
|
40
|
+
| `ArrowDown` | Move to next option |
|
|
41
|
+
| `ArrowUp` | Move to previous option |
|
|
42
|
+
| `Enter` | Select focused option |
|
|
43
|
+
| `Escape` | Close the listbox |
|
|
44
|
+
|
|
45
|
+
## Stories
|
|
46
|
+
|
|
47
|
+
<Canvas of={Stories.Default} />
|
|
48
|
+
<Canvas of={Stories.AllVariants} />
|
|
49
|
+
|
|
50
|
+
## Controls
|
|
51
|
+
|
|
52
|
+
<ArgTypes of={Stories} />
|