@boostdev/design-system-components 2.8.0 → 2.11.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 +54 -46
- package/README.md +34 -20
- package/dist/client.cjs +1317 -779
- package/dist/client.css +1029 -812
- package/dist/client.d.cts +88 -26
- package/dist/client.d.ts +88 -26
- package/dist/client.js +1278 -732
- package/dist/index.cjs +1317 -779
- package/dist/index.css +1029 -812
- package/dist/index.d.cts +88 -26
- package/dist/index.d.ts +88 -26
- package/dist/index.js +1278 -732
- package/dist/web-components/chunk-2OLVQUBU.js +193 -0
- package/dist/web-components/{chunk-OF6FFGOT.js → chunk-3AY2YKCM.js} +77 -21
- package/dist/web-components/chunk-3WAV6MDN.js +212 -0
- package/dist/web-components/{chunk-UUKSDCYS.js → chunk-47AT5KZD.js} +87 -15
- package/dist/web-components/chunk-4A2YYTYN.js +93 -0
- package/dist/web-components/{chunk-Q4T5BJT6.js → chunk-62NK3ZSC.js} +18 -3
- package/dist/web-components/chunk-66M6ETWD.js +77 -0
- package/dist/web-components/{chunk-NCPQ7AF3.js → chunk-6G22I2CK.js} +18 -3
- package/dist/web-components/{chunk-QDST57JC.js → chunk-7ZOJ7N4E.js} +14 -4
- package/dist/web-components/{chunk-QLT6MTZF.js → chunk-AIBOHNDU.js} +10 -0
- package/dist/web-components/{chunk-X3NQMBAQ.js → chunk-AP4RDUL2.js} +14 -3
- package/dist/web-components/{chunk-QWPACK5L.js → chunk-BPYKZVDK.js} +11 -1
- package/dist/web-components/{chunk-YLVTEY23.js → chunk-BTCMJQKB.js} +53 -21
- package/dist/web-components/chunk-CUKQ2L5B.js +245 -0
- package/dist/web-components/chunk-DIZDCL7Z.js +14 -0
- package/dist/web-components/{chunk-PC3IOQAH.js → chunk-DV5T43ZC.js} +27 -7
- package/dist/web-components/{chunk-2QA62WCQ.js → chunk-EF7IVYTY.js} +10 -0
- package/dist/web-components/{chunk-L3XHOMN6.js → chunk-F3ZDNHZZ.js} +26 -1
- package/dist/web-components/chunk-FEDABOR5.js +248 -0
- package/dist/web-components/{chunk-6I2DBFQ7.js → chunk-HGFCJXOQ.js} +36 -5
- package/dist/web-components/{chunk-SOQQ7RVJ.js → chunk-IPGHUCJT.js} +23 -8
- package/dist/web-components/chunk-ITD2MV5K.js +392 -0
- package/dist/web-components/{chunk-ARMKC4BQ.js → chunk-JH6LQKLK.js} +77 -5
- package/dist/web-components/chunk-JMCXAAFK.js +120 -0
- package/dist/web-components/{chunk-KUI55GFB.js → chunk-JUPCZVVW.js} +50 -18
- package/dist/web-components/chunk-JV5QT2OU.js +146 -0
- package/dist/web-components/{chunk-3GFWLSLS.js → chunk-KA3VPKMY.js} +29 -6
- package/dist/web-components/{chunk-CR5PGUHV.js → chunk-KJGRFDFI.js} +26 -11
- package/dist/web-components/{chunk-PY62FTRW.js → chunk-KZPRFY5P.js} +68 -33
- package/dist/web-components/{chunk-X46KL5BK.js → chunk-LDIPCTRN.js} +18 -1
- package/dist/web-components/chunk-M3ECULRH.js +174 -0
- package/dist/web-components/chunk-NBN2ENWJ.js +90 -0
- package/dist/web-components/chunk-NIN3JO6Q.js +189 -0
- package/dist/web-components/{chunk-2FGATTGT.js → chunk-NTQ4TCUT.js} +76 -55
- package/dist/web-components/chunk-OY74D4X6.js +302 -0
- package/dist/web-components/{chunk-3S42DZ7W.js → chunk-P24JYC5V.js} +7 -0
- package/dist/web-components/{chunk-BKIHQYJR.js → chunk-PXPPKCLT.js} +17 -2
- package/dist/web-components/{chunk-TQ7IQ4GZ.js → chunk-QEF2IRID.js} +71 -29
- package/dist/web-components/chunk-QZAIRJ75.js +111 -0
- package/dist/web-components/{chunk-6I3CFC26.js → chunk-RSZ3BWBK.js} +20 -5
- package/dist/web-components/chunk-RVF7W653.js +101 -0
- package/dist/web-components/chunk-SEO2F5KJ.js +234 -0
- package/dist/web-components/{chunk-VMMVWLXL.js → chunk-SFZ6Q4BP.js} +10 -0
- package/dist/web-components/{chunk-LY62SAVN.js → chunk-SYNLFKD3.js} +12 -2
- package/dist/web-components/chunk-TMWXRHGF.js +192 -0
- package/dist/web-components/{chunk-65JXQOBA.js → chunk-U3YZE6R6.js} +51 -7
- package/dist/web-components/chunk-UO7ROSHD.js +424 -0
- package/dist/web-components/chunk-VANAKB6D.js +152 -0
- package/dist/web-components/{chunk-PXZWYO6Z.js → chunk-VED2DFJ6.js} +108 -29
- package/dist/web-components/chunk-W6H5ID2U.js +161 -0
- package/dist/web-components/{chunk-FSZRP43R.js → chunk-WFVKU4GX.js} +21 -10
- package/dist/web-components/{chunk-OQTRTMAB.js → chunk-WIBAN7KP.js} +10 -0
- package/dist/web-components/chunk-XI7KRAH7.js +54 -0
- package/dist/web-components/{chunk-ORC56MDY.js → chunk-XIZWAWMJ.js} +45 -6
- package/dist/web-components/{chunk-FXURM6D5.js → chunk-YFAXGRPR.js} +10 -0
- package/dist/web-components/globals.js +1 -1
- package/dist/web-components/index.d.ts +77 -707
- package/dist/web-components/index.js +339 -2066
- package/dist/web-components/interaction/bds-accordion-item.js +1 -1
- package/dist/web-components/interaction/bds-accordion.js +1 -1
- package/dist/web-components/interaction/bds-button.d.ts +10 -2
- package/dist/web-components/interaction/bds-button.js +1 -1
- package/dist/web-components/interaction/bds-collapsible.d.ts +7 -2
- package/dist/web-components/interaction/bds-collapsible.js +1 -1
- package/dist/web-components/interaction/bds-dialog.d.ts +11 -3
- package/dist/web-components/interaction/bds-dialog.js +1 -1
- package/dist/web-components/interaction/bds-drawer.d.ts +7 -1
- package/dist/web-components/interaction/bds-drawer.js +1 -1
- package/dist/web-components/interaction/bds-dropdown-menu-item.d.ts +51 -0
- package/dist/web-components/interaction/bds-dropdown-menu-item.js +7 -0
- package/dist/web-components/interaction/bds-dropdown-menu.d.ts +70 -0
- package/dist/web-components/interaction/bds-dropdown-menu.js +7 -0
- package/dist/web-components/interaction/bds-popover.d.ts +14 -3
- package/dist/web-components/interaction/bds-popover.js +1 -1
- package/dist/web-components/interaction/bds-skip-link.js +1 -1
- package/dist/web-components/interaction/bds-tab-panel.js +1 -1
- package/dist/web-components/interaction/bds-tab.js +1 -1
- package/dist/web-components/interaction/bds-tabs.d.ts +1 -0
- package/dist/web-components/interaction/bds-tabs.js +1 -1
- package/dist/web-components/interaction/bds-toast-provider.js +1 -1
- package/dist/web-components/interaction/bds-tooltip.d.ts +19 -3
- package/dist/web-components/interaction/bds-tooltip.js +1 -1
- package/dist/web-components/interaction/form/bds-checkbox-group.d.ts +83 -0
- package/dist/web-components/interaction/form/bds-checkbox-group.js +7 -0
- package/dist/web-components/interaction/form/bds-checkbox.d.ts +6 -0
- package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
- package/dist/web-components/interaction/form/bds-combobox.d.ts +18 -0
- package/dist/web-components/interaction/form/bds-combobox.js +1 -1
- package/dist/web-components/interaction/form/bds-field-group.d.ts +89 -0
- package/dist/web-components/interaction/form/bds-field-group.js +7 -0
- package/dist/web-components/interaction/form/bds-file-input.d.ts +1 -1
- package/dist/web-components/interaction/form/bds-file-input.js +1 -1
- package/dist/web-components/interaction/form/bds-form-input.d.ts +92 -0
- package/dist/web-components/interaction/form/bds-form-input.js +7 -0
- package/dist/web-components/interaction/form/bds-number-input.d.ts +18 -1
- package/dist/web-components/interaction/form/bds-number-input.js +1 -1
- package/dist/web-components/interaction/form/bds-radio-group.d.ts +81 -0
- package/dist/web-components/interaction/form/bds-radio-group.js +7 -0
- package/dist/web-components/interaction/form/bds-radio.d.ts +34 -6
- package/dist/web-components/interaction/form/bds-radio.js +1 -1
- package/dist/web-components/interaction/form/bds-segmented-control.d.ts +4 -4
- package/dist/web-components/interaction/form/bds-segmented-control.js +1 -1
- package/dist/web-components/interaction/form/bds-select.d.ts +22 -1
- package/dist/web-components/interaction/form/bds-select.js +1 -1
- package/dist/web-components/interaction/form/bds-slider.d.ts +42 -10
- package/dist/web-components/interaction/form/bds-slider.js +1 -1
- package/dist/web-components/interaction/form/bds-switch.d.ts +20 -0
- package/dist/web-components/interaction/form/bds-switch.js +1 -1
- package/dist/web-components/interaction/form/bds-textarea.d.ts +23 -3
- package/dist/web-components/interaction/form/bds-textarea.js +1 -1
- package/dist/web-components/layout/bds-grid-item.d.ts +63 -0
- package/dist/web-components/layout/bds-grid-item.js +7 -0
- package/dist/web-components/layout/bds-grid.d.ts +108 -0
- package/dist/web-components/layout/bds-grid.js +7 -0
- package/dist/web-components/ui/bds-alert.d.ts +16 -2
- package/dist/web-components/ui/bds-alert.js +1 -1
- package/dist/web-components/ui/bds-avatar.d.ts +2 -1
- package/dist/web-components/ui/bds-avatar.js +1 -1
- package/dist/web-components/ui/bds-badge.js +1 -1
- package/dist/web-components/ui/bds-breadcrumb.d.ts +3 -1
- package/dist/web-components/ui/bds-breadcrumb.js +1 -1
- package/dist/web-components/ui/bds-button-container.d.ts +52 -0
- package/dist/web-components/ui/bds-button-container.js +7 -0
- package/dist/web-components/ui/bds-button-group.d.ts +21 -0
- package/dist/web-components/ui/bds-button-group.js +8 -0
- package/dist/web-components/ui/bds-calendar.d.ts +121 -0
- package/dist/web-components/ui/bds-calendar.js +7 -0
- package/dist/web-components/ui/bds-card.d.ts +12 -3
- package/dist/web-components/ui/bds-card.js +1 -1
- package/dist/web-components/ui/bds-carousel.d.ts +98 -0
- package/dist/web-components/ui/bds-carousel.js +7 -0
- package/dist/web-components/ui/bds-description-list.js +1 -1
- package/dist/web-components/ui/bds-icon-wrapper.d.ts +0 -9
- package/dist/web-components/ui/bds-icon-wrapper.js +1 -1
- package/dist/web-components/ui/bds-link.js +1 -1
- package/dist/web-components/ui/bds-loading.js +1 -1
- package/dist/web-components/ui/bds-notification-banner.js +1 -1
- package/dist/web-components/ui/bds-pagination.d.ts +47 -0
- package/dist/web-components/ui/bds-pagination.js +7 -0
- package/dist/web-components/ui/bds-progress-circle.d.ts +3 -1
- package/dist/web-components/ui/bds-progress-circle.js +1 -1
- package/dist/web-components/ui/bds-progress.d.ts +3 -1
- package/dist/web-components/ui/bds-progress.js +1 -1
- package/dist/web-components/ui/bds-rating.js +1 -1
- package/dist/web-components/ui/bds-section-header.d.ts +18 -4
- 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-skeleton.js +1 -1
- package/dist/web-components/ui/bds-table.d.ts +52 -0
- package/dist/web-components/ui/bds-table.js +7 -0
- package/dist/web-components/ui/bds-typography.d.ts +1 -0
- package/dist/web-components/ui/bds-typography.js +1 -1
- package/package.json +60 -3
- package/src/components/interaction/Button/Button.module.css +23 -14
- package/src/components/interaction/Button/Button.spec.tsx +20 -0
- package/src/components/interaction/Button/Button.tsx +2 -2
- package/src/components/interaction/Command/Command.mdx +5 -2
- package/src/components/interaction/Command/Command.module.css +23 -7
- package/src/components/interaction/Command/Command.spec.tsx +35 -0
- package/src/components/interaction/Command/Command.tsx +15 -4
- package/src/components/interaction/Command/index.ts +1 -1
- package/src/components/interaction/Dialog/Dialog.mdx +4 -4
- package/src/components/interaction/Dialog/Dialog.module.css +20 -0
- package/src/components/interaction/Dialog/Dialog.spec.tsx +20 -0
- package/src/components/interaction/Dialog/Dialog.tsx +8 -3
- package/src/components/interaction/Dialog/index.ts +1 -0
- package/src/components/interaction/Drawer/Drawer.mdx +5 -2
- package/src/components/interaction/Drawer/Drawer.module.css +34 -3
- package/src/components/interaction/Drawer/Drawer.spec.tsx +67 -1
- package/src/components/interaction/Drawer/Drawer.tsx +30 -12
- package/src/components/interaction/Drawer/index.ts +1 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.mdx +2 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +34 -0
- package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +15 -5
- package/src/components/interaction/DropdownMenu/index.ts +1 -0
- package/src/components/interaction/Popover/Popover.mdx +6 -2
- package/src/components/interaction/Popover/Popover.module.css +26 -18
- package/src/components/interaction/Popover/Popover.spec.tsx +38 -0
- package/src/components/interaction/Popover/Popover.tsx +19 -5
- package/src/components/interaction/Popover/index.ts +1 -0
- package/src/components/interaction/Rating/Rating.mdx +1 -1
- package/src/components/interaction/Rating/Rating.module.css +2 -2
- package/src/components/interaction/Rating/Rating.tsx +1 -1
- package/src/components/interaction/Rating/index.ts +1 -0
- package/src/components/interaction/Toast/Toast.mdx +3 -0
- package/src/components/interaction/Toast/Toast.module.css +35 -5
- package/src/components/interaction/Toast/Toast.spec.tsx +69 -1
- package/src/components/interaction/Toast/Toast.tsx +15 -9
- package/src/components/interaction/form/Checkbox/Checkbox.mdx +3 -0
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +13 -6
- package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +6 -0
- package/src/components/interaction/form/Checkbox/Checkbox.tsx +1 -1
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.mdx +16 -1
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +24 -8
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +32 -2
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +14 -2
- package/src/components/interaction/form/Combobox/Combobox.mdx +11 -4
- package/src/components/interaction/form/Combobox/Combobox.module.css +6 -6
- package/src/components/interaction/form/Combobox/Combobox.spec.tsx +47 -0
- package/src/components/interaction/form/Combobox/Combobox.tsx +10 -5
- package/src/components/interaction/form/FieldGroup/FieldGroup.mdx +9 -10
- package/src/components/interaction/form/FieldGroup/FieldGroup.module.css +57 -23
- package/src/components/interaction/form/FieldGroup/FieldGroup.spec.tsx +129 -7
- package/src/components/interaction/form/FieldGroup/FieldGroup.tsx +72 -12
- package/src/components/interaction/form/FileInput/FileInput.mdx +9 -1
- package/src/components/interaction/form/FileInput/FileInput.module.css +8 -8
- package/src/components/interaction/form/FileInput/FileInput.spec.tsx +89 -1
- package/src/components/interaction/form/FileInput/FileInput.tsx +6 -2
- package/src/components/interaction/form/FormInput/FormInput.mdx +9 -5
- package/src/components/interaction/form/FormInput/FormInput.module.css +17 -8
- package/src/components/interaction/form/FormInput/FormInput.spec.tsx +20 -0
- package/src/components/interaction/form/FormInput/FormInput.tsx +7 -2
- package/src/components/interaction/form/NumberInput/NumberInput.mdx +5 -1
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +6 -6
- package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +51 -0
- package/src/components/interaction/form/NumberInput/NumberInput.tsx +36 -8
- package/src/components/interaction/form/Radio/Radio.mdx +8 -1
- package/src/components/interaction/form/Radio/Radio.module.css +20 -7
- package/src/components/interaction/form/Radio/Radio.spec.tsx +15 -0
- package/src/components/interaction/form/Radio/Radio.tsx +10 -4
- package/src/components/interaction/form/RadioGroup/RadioGroup.mdx +16 -1
- package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +24 -8
- package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +32 -2
- package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +14 -2
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +9 -3
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +25 -12
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.spec.tsx +86 -5
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +44 -4
- package/src/components/interaction/form/Select/Select.mdx +10 -4
- package/src/components/interaction/form/Select/Select.module.css +4 -4
- package/src/components/interaction/form/Select/Select.spec.tsx +34 -0
- package/src/components/interaction/form/Select/Select.tsx +21 -9
- package/src/components/interaction/form/Slider/Slider.mdx +4 -1
- package/src/components/interaction/form/Slider/Slider.module.css +32 -8
- package/src/components/interaction/form/Slider/Slider.spec.tsx +29 -0
- package/src/components/interaction/form/Slider/Slider.tsx +9 -7
- package/src/components/interaction/form/Switch/Switch.mdx +2 -2
- package/src/components/interaction/form/Switch/Switch.module.css +12 -13
- package/src/components/interaction/form/Switch/Switch.spec.tsx +20 -0
- package/src/components/interaction/form/Switch/Switch.tsx +2 -1
- package/src/components/interaction/form/Textarea/Textarea.mdx +5 -0
- package/src/components/interaction/form/Textarea/Textarea.module.css +5 -5
- package/src/components/interaction/form/Textarea/Textarea.spec.tsx +13 -0
- package/src/components/interaction/form/Textarea/Textarea.tsx +3 -1
- package/src/components/interaction/form/atoms/Message.module.css +1 -1
- package/src/components/interaction/form/atoms/Message.spec.tsx +29 -0
- package/src/components/interaction/form/atoms/Message.tsx +1 -1
- package/src/components/layout/ButtonGroup/ButtonGroup.mdx +11 -0
- package/src/components/layout/ButtonGroup/ButtonGroup.module.css +1 -5
- package/src/components/layout/ButtonGroup/ButtonGroup.stories.tsx +14 -0
- package/src/components/layout/Card/Card.mdx +6 -1
- package/src/components/layout/Card/Card.module.css +26 -5
- package/src/components/layout/Card/Card.spec.tsx +7 -0
- package/src/components/layout/Card/Card.tsx +4 -3
- package/src/components/layout/Grid/Grid.spec.tsx +44 -0
- package/src/components/layout/Grid/Grid.tsx +5 -5
- package/src/components/layout/Grid/GridItem.tsx +6 -6
- package/src/components/layout/Grid/masonry.ts +31 -5
- package/src/components/layout/Grid/useIsomorphicLayoutEffect.ts +11 -0
- package/src/components/layout/IconWrapper/IconWrapper.mdx +8 -2
- package/src/components/layout/IconWrapper/IconWrapper.module.css +9 -6
- package/src/components/layout/SectionHeader/SectionHeader.mdx +4 -1
- package/src/components/layout/SectionHeader/SectionHeader.module.css +10 -9
- package/src/components/ui/Accordion/Accordion.mdx +4 -1
- package/src/components/ui/Accordion/Accordion.module.css +2 -1
- package/src/components/ui/Alert/Alert.mdx +21 -4
- package/src/components/ui/Alert/Alert.module.css +9 -4
- package/src/components/ui/Alert/Alert.spec.tsx +20 -0
- package/src/components/ui/Avatar/Avatar.mdx +8 -3
- package/src/components/ui/Avatar/Avatar.module.css +13 -8
- package/src/components/ui/Badge/Badge.mdx +3 -1
- package/src/components/ui/Breadcrumb/Breadcrumb.mdx +3 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.module.css +4 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.spec.tsx +12 -0
- package/src/components/ui/Breadcrumb/Breadcrumb.tsx +11 -3
- package/src/components/ui/Calendar/Calendar.mdx +6 -0
- package/src/components/ui/Calendar/Calendar.module.css +68 -19
- package/src/components/ui/Calendar/Calendar.spec.tsx +139 -24
- package/src/components/ui/Calendar/Calendar.stories.tsx +14 -0
- package/src/components/ui/Calendar/Calendar.tsx +143 -154
- package/src/components/ui/Calendar/CalendarRange.mdx +39 -0
- package/src/components/ui/Calendar/CalendarRange.spec.tsx +119 -0
- package/src/components/ui/Calendar/CalendarRange.stories.tsx +51 -0
- package/src/components/ui/Calendar/CalendarRange.tsx +213 -0
- package/src/components/ui/Calendar/MonthGrid.tsx +141 -0
- package/src/components/ui/Calendar/calendar-core.spec.ts +176 -0
- package/src/components/ui/Calendar/calendar-core.ts +164 -0
- package/src/components/ui/Calendar/index.ts +1 -0
- package/src/components/ui/Carousel/Carousel.mdx +8 -3
- package/src/components/ui/Carousel/Carousel.module.css +7 -5
- package/src/components/ui/Carousel/Carousel.spec.tsx +67 -0
- package/src/components/ui/Carousel/Carousel.tsx +19 -7
- package/src/components/ui/Collapsible/Collapsible.mdx +17 -6
- package/src/components/ui/Collapsible/Collapsible.module.css +7 -2
- package/src/components/ui/Collapsible/Collapsible.spec.tsx +40 -0
- package/src/components/ui/Collapsible/Collapsible.tsx +19 -2
- package/src/components/ui/DescriptionList/DescriptionList.mdx +2 -0
- package/src/components/ui/Link/Link.mdx +4 -2
- package/src/components/ui/Loading/Loading.mdx +6 -3
- package/src/components/ui/Loading/Loading.module.css +7 -7
- package/src/components/ui/Loading/Loading.spec.tsx +12 -0
- package/src/components/ui/Loading/Loading.tsx +8 -3
- package/src/components/ui/NotificationBanner/NotificationBanner.mdx +4 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +5 -0
- package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +20 -0
- package/src/components/ui/Pagination/Pagination.mdx +29 -7
- package/src/components/ui/Pagination/Pagination.module.css +15 -14
- package/src/components/ui/Progress/Progress.mdx +6 -2
- package/src/components/ui/Progress/Progress.module.css +1 -1
- package/src/components/ui/Progress/Progress.spec.tsx +17 -0
- package/src/components/ui/Progress/Progress.tsx +2 -2
- package/src/components/ui/ProgressCircle/ProgressCircle.mdx +8 -4
- package/src/components/ui/ProgressCircle/ProgressCircle.module.css +2 -2
- package/src/components/ui/ProgressCircle/ProgressCircle.spec.tsx +11 -1
- package/src/components/ui/ProgressCircle/ProgressCircle.tsx +1 -1
- package/src/components/ui/Separator/Separator.mdx +7 -0
- package/src/components/ui/Separator/Separator.module.css +1 -0
- package/src/components/ui/Skeleton/Skeleton.mdx +17 -0
- package/src/components/ui/Skeleton/Skeleton.module.css +12 -5
- package/src/components/ui/SkipLink/SkipLink.mdx +19 -0
- package/src/components/ui/SkipLink/SkipLink.module.css +8 -7
- package/src/components/ui/SkipLink/SkipLink.spec.tsx +28 -0
- package/src/components/ui/Table/Table.mdx +14 -0
- package/src/components/ui/Table/Table.module.css +13 -8
- package/src/components/ui/Table/Table.spec.tsx +56 -0
- package/src/components/ui/Table/Table.tsx +44 -6
- package/src/components/ui/Tabs/Tabs.mdx +16 -0
- package/src/components/ui/Tabs/Tabs.module.css +3 -3
- package/src/components/ui/Tabs/Tabs.spec.tsx +20 -0
- package/src/components/ui/Tabs/Tabs.tsx +5 -1
- package/src/components/ui/Tooltip/Tooltip.mdx +9 -0
- package/src/components/ui/Tooltip/Tooltip.module.css +32 -12
- package/src/components/ui/Tooltip/Tooltip.spec.tsx +56 -0
- package/src/components/ui/Tooltip/Tooltip.tsx +26 -7
- package/src/components/ui/Typography/Typography.mdx +7 -0
- package/src/components/ui/Typography/Typography.module.css +5 -5
- package/src/index.ts +7 -3
- package/src/stories/DesignSystem/Borders.mdx +14 -9
- package/src/stories/DesignSystem/Colors.mdx +43 -41
- package/src/stories/DesignSystem/Overview.mdx +4 -3
- package/src/stories/Introduction.mdx +5 -5
- package/src/web-components/globals.ts +7 -0
- package/src/web-components/index.ts +2 -0
- package/src/web-components/interaction/BdsAccordion.mdx +10 -1
- package/src/web-components/interaction/BdsButton.mdx +15 -4
- package/src/web-components/interaction/BdsButton.stories.tsx +1 -1
- package/src/web-components/interaction/BdsCollapsible.mdx +3 -3
- package/src/web-components/interaction/BdsDialog.mdx +12 -7
- package/src/web-components/interaction/BdsDialog.stories.tsx +2 -2
- package/src/web-components/interaction/BdsDrawer.mdx +9 -6
- package/src/web-components/interaction/BdsDropdownMenu.mdx +20 -1
- package/src/web-components/interaction/BdsPopover.mdx +7 -3
- package/src/web-components/interaction/BdsSkipLink.mdx +14 -1
- package/src/web-components/interaction/BdsTabs.mdx +18 -1
- package/src/web-components/interaction/BdsToastProvider.mdx +21 -3
- package/src/web-components/interaction/BdsTooltip.mdx +4 -4
- package/src/web-components/interaction/bds-accordion-item.ts +10 -0
- package/src/web-components/interaction/bds-accordion.spec.ts +41 -0
- package/src/web-components/interaction/bds-accordion.ts +28 -2
- package/src/web-components/interaction/bds-button.spec.ts +81 -0
- package/src/web-components/interaction/bds-button.ts +55 -8
- package/src/web-components/interaction/bds-collapsible.spec.ts +93 -2
- package/src/web-components/interaction/bds-collapsible.ts +49 -7
- package/src/web-components/interaction/bds-dialog.spec.ts +49 -0
- package/src/web-components/interaction/bds-dialog.ts +68 -11
- package/src/web-components/interaction/bds-drawer.spec.ts +93 -4
- package/src/web-components/interaction/bds-drawer.ts +54 -21
- package/src/web-components/interaction/bds-dropdown-menu-item.ts +12 -1
- package/src/web-components/interaction/bds-dropdown-menu.spec.ts +63 -0
- package/src/web-components/interaction/bds-dropdown-menu.ts +45 -7
- package/src/web-components/interaction/bds-popover.spec.ts +80 -6
- package/src/web-components/interaction/bds-popover.ts +83 -32
- package/src/web-components/interaction/bds-skip-link.spec.ts +18 -0
- package/src/web-components/interaction/bds-skip-link.ts +29 -8
- package/src/web-components/interaction/bds-tab-panel.ts +10 -0
- package/src/web-components/interaction/bds-tab.spec.ts +25 -0
- package/src/web-components/interaction/bds-tab.ts +20 -5
- package/src/web-components/interaction/bds-tabs.spec.ts +92 -5
- package/src/web-components/interaction/bds-tabs.ts +42 -1
- package/src/web-components/interaction/bds-toast-provider.spec.ts +43 -0
- package/src/web-components/interaction/bds-toast-provider.ts +50 -21
- package/src/web-components/interaction/bds-tooltip.spec.ts +71 -0
- package/src/web-components/interaction/bds-tooltip.ts +100 -5
- package/src/web-components/interaction/form/BdsCheckbox.mdx +20 -1
- package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +8 -0
- package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +4 -3
- package/src/web-components/interaction/form/BdsCombobox.mdx +39 -2
- package/src/web-components/interaction/form/BdsCombobox.stories.tsx +31 -0
- package/src/web-components/interaction/form/BdsFieldGroup.mdx +8 -3
- package/src/web-components/interaction/form/BdsFieldGroup.stories.tsx +1 -1
- package/src/web-components/interaction/form/BdsFileInput.mdx +26 -5
- package/src/web-components/interaction/form/BdsFormInput.mdx +16 -1
- package/src/web-components/interaction/form/BdsNumberInput.mdx +34 -2
- package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +27 -3
- package/src/web-components/interaction/form/BdsRadio.mdx +39 -12
- package/src/web-components/interaction/form/BdsRadio.stories.tsx +26 -0
- package/src/web-components/interaction/form/BdsRadioGroup.mdx +9 -4
- package/src/web-components/interaction/form/BdsSegmentedControl.mdx +37 -11
- package/src/web-components/interaction/form/BdsSelect.mdx +22 -4
- package/src/web-components/interaction/form/BdsSelect.stories.tsx +33 -0
- package/src/web-components/interaction/form/BdsSlider.mdx +36 -19
- package/src/web-components/interaction/form/BdsSlider.stories.tsx +24 -0
- package/src/web-components/interaction/form/BdsSwitch.mdx +38 -11
- package/src/web-components/interaction/form/BdsSwitch.stories.tsx +16 -0
- package/src/web-components/interaction/form/BdsTextarea.mdx +42 -16
- package/src/web-components/interaction/form/BdsTextarea.stories.tsx +21 -0
- package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +99 -0
- package/src/web-components/interaction/form/bds-checkbox-group.ts +95 -9
- package/src/web-components/interaction/form/bds-checkbox.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-checkbox.ts +30 -5
- package/src/web-components/interaction/form/bds-combobox.spec.ts +79 -0
- package/src/web-components/interaction/form/bds-combobox.ts +101 -16
- package/src/web-components/interaction/form/bds-field-group.spec.ts +158 -0
- package/src/web-components/interaction/form/bds-field-group.ts +167 -23
- package/src/web-components/interaction/form/bds-file-input.spec.ts +73 -5
- package/src/web-components/interaction/form/bds-file-input.ts +71 -34
- package/src/web-components/interaction/form/bds-form-input.spec.ts +22 -0
- package/src/web-components/interaction/form/bds-form-input.ts +27 -16
- package/src/web-components/interaction/form/bds-number-input.spec.ts +49 -0
- package/src/web-components/interaction/form/bds-number-input.ts +118 -29
- package/src/web-components/interaction/form/bds-radio-group.spec.ts +57 -0
- package/src/web-components/interaction/form/bds-radio-group.ts +60 -12
- package/src/web-components/interaction/form/bds-radio.spec.ts +123 -0
- package/src/web-components/interaction/form/bds-radio.ts +135 -22
- package/src/web-components/interaction/form/bds-segmented-control.spec.ts +55 -0
- package/src/web-components/interaction/form/bds-segmented-control.ts +81 -59
- package/src/web-components/interaction/form/bds-select.spec.ts +57 -0
- package/src/web-components/interaction/form/bds-select.ts +95 -7
- package/src/web-components/interaction/form/bds-slider.spec.ts +83 -0
- package/src/web-components/interaction/form/bds-slider.ts +154 -26
- package/src/web-components/interaction/form/bds-switch.spec.ts +68 -0
- package/src/web-components/interaction/form/bds-switch.ts +87 -20
- package/src/web-components/interaction/form/bds-textarea.spec.ts +71 -0
- package/src/web-components/interaction/form/bds-textarea.ts +108 -7
- package/src/web-components/layout/BdsGrid.mdx +6 -2
- package/src/web-components/layout/BdsGrid.stories.tsx +4 -0
- package/src/web-components/layout/bds-grid-item.spec.ts +21 -0
- package/src/web-components/layout/bds-grid-item.ts +17 -3
- package/src/web-components/layout/bds-grid.spec.ts +98 -0
- package/src/web-components/layout/bds-grid.ts +139 -19
- package/src/web-components/ui/BdsAlert.mdx +6 -5
- package/src/web-components/ui/BdsAlert.stories.tsx +6 -6
- package/src/web-components/ui/BdsAvatar.mdx +4 -2
- package/src/web-components/ui/BdsBreadcrumb.mdx +3 -2
- package/src/web-components/ui/BdsButtonContainer.mdx +64 -0
- package/src/web-components/ui/BdsButtonContainer.stories.tsx +84 -0
- package/src/web-components/ui/BdsCalendar.mdx +29 -4
- package/src/web-components/ui/BdsCalendar.stories.tsx +16 -18
- package/src/web-components/ui/BdsCalendarRange.mdx +71 -0
- package/src/web-components/ui/BdsCalendarRange.stories.tsx +31 -0
- package/src/web-components/ui/BdsCard.mdx +7 -3
- package/src/web-components/ui/BdsCard.stories.tsx +17 -1
- package/src/web-components/ui/BdsCarousel.mdx +40 -12
- package/src/web-components/ui/BdsDescriptionList.mdx +6 -1
- package/src/web-components/ui/BdsIconWrapper.mdx +3 -2
- package/src/web-components/ui/BdsLink.mdx +14 -2
- package/src/web-components/ui/BdsNotificationBanner.mdx +18 -0
- package/src/web-components/ui/BdsPagination.mdx +40 -1
- package/src/web-components/ui/BdsProgress.mdx +8 -2
- package/src/web-components/ui/BdsProgressCircle.mdx +5 -2
- package/src/web-components/ui/BdsRating.mdx +7 -0
- package/src/web-components/ui/BdsSectionHeader.mdx +22 -3
- package/src/web-components/ui/BdsSectionHeader.stories.tsx +15 -13
- package/src/web-components/ui/BdsTable.mdx +23 -2
- package/src/web-components/ui/BdsTable.stories.tsx +8 -2
- package/src/web-components/ui/BdsTypography.mdx +17 -1
- package/src/web-components/ui/bds-alert.spec.ts +17 -2
- package/src/web-components/ui/bds-alert.ts +31 -5
- package/src/web-components/ui/bds-avatar.spec.ts +29 -0
- package/src/web-components/ui/bds-avatar.ts +29 -11
- package/src/web-components/ui/bds-badge.spec.ts +5 -0
- package/src/web-components/ui/bds-badge.ts +11 -1
- package/src/web-components/ui/bds-breadcrumb.spec.ts +30 -0
- package/src/web-components/ui/bds-breadcrumb.ts +26 -4
- package/src/web-components/ui/bds-button-container.spec.ts +39 -0
- package/src/web-components/ui/bds-button-container.ts +123 -0
- package/src/web-components/ui/bds-button-group.spec.ts +14 -20
- package/src/web-components/ui/bds-button-group.ts +13 -64
- package/src/web-components/ui/bds-calendar-range.spec.ts +123 -0
- package/src/web-components/ui/bds-calendar-range.ts +307 -0
- package/src/web-components/ui/bds-calendar.spec.ts +176 -0
- package/src/web-components/ui/bds-calendar.ts +186 -344
- package/src/web-components/ui/bds-card.spec.ts +32 -0
- package/src/web-components/ui/bds-card.ts +34 -9
- package/src/web-components/ui/bds-carousel.spec.ts +147 -0
- package/src/web-components/ui/bds-carousel.ts +109 -32
- package/src/web-components/ui/bds-description-list.spec.ts +15 -0
- package/src/web-components/ui/bds-description-list.ts +37 -3
- package/src/web-components/ui/bds-icon-wrapper.spec.ts +12 -0
- package/src/web-components/ui/bds-icon-wrapper.ts +15 -14
- package/src/web-components/ui/bds-link.spec.ts +17 -0
- package/src/web-components/ui/bds-link.ts +26 -11
- package/src/web-components/ui/bds-loading.ts +10 -0
- package/src/web-components/ui/bds-notification-banner.spec.ts +13 -0
- package/src/web-components/ui/bds-notification-banner.ts +18 -1
- package/src/web-components/ui/bds-pagination.spec.ts +44 -0
- package/src/web-components/ui/bds-pagination.ts +39 -19
- package/src/web-components/ui/bds-progress-circle.spec.ts +21 -0
- package/src/web-components/ui/bds-progress-circle.ts +17 -5
- package/src/web-components/ui/bds-progress.spec.ts +21 -0
- package/src/web-components/ui/bds-progress.ts +17 -4
- package/src/web-components/ui/bds-rating.spec.ts +6 -0
- package/src/web-components/ui/bds-rating.ts +12 -2
- package/src/web-components/ui/bds-section-header.spec.ts +39 -8
- package/src/web-components/ui/bds-section-header.ts +47 -13
- package/src/web-components/ui/bds-separator.ts +10 -0
- package/src/web-components/ui/bds-skeleton.ts +10 -0
- package/src/web-components/ui/bds-table.spec.ts +63 -0
- package/src/web-components/ui/bds-table.ts +88 -28
- package/src/web-components/ui/bds-typography.spec.ts +47 -0
- package/src/web-components/ui/bds-typography.ts +28 -10
- package/src/web-components/ui/calendar-styles.ts +94 -0
- package/dist/web-components/chunk-7YURXHTS.js +0 -147
- package/dist/web-components/chunk-A3RLT3AS.js +0 -49
- package/dist/web-components/chunk-AGKJTMJI.js +0 -56
- package/dist/web-components/chunk-BQLZ7I4G.js +0 -56
- package/dist/web-components/chunk-DZOEPVFT.js +0 -107
- package/dist/web-components/chunk-JYYRJS2D.js +0 -118
- package/dist/web-components/chunk-Y4MAXTMA.js +0 -80
- package/dist/web-components/chunk-Y7V7LM6R.js +0 -98
- package/src/web-components/ui/BdsButtonGroup.mdx +0 -69
- package/src/web-components/ui/BdsButtonGroup.stories.tsx +0 -66
|
@@ -52,4 +52,103 @@ describe('bds-checkbox-group', () => {
|
|
|
52
52
|
expect(message?.textContent?.trim()).toBe('Select all that apply');
|
|
53
53
|
cleanup(el);
|
|
54
54
|
});
|
|
55
|
+
|
|
56
|
+
it('propagates disabled to slotted bds-checkbox elements', async () => {
|
|
57
|
+
const el = await fixture(
|
|
58
|
+
'<bds-checkbox-group label="Interests" disabled>' +
|
|
59
|
+
'<bds-checkbox value="sports">Sports</bds-checkbox>' +
|
|
60
|
+
'<bds-checkbox value="music">Music</bds-checkbox>' +
|
|
61
|
+
'</bds-checkbox-group>',
|
|
62
|
+
) as BdsCheckboxGroup;
|
|
63
|
+
await Promise.resolve();
|
|
64
|
+
const checkboxes = Array.from(el.querySelectorAll('bds-checkbox'));
|
|
65
|
+
expect(checkboxes.every(checkbox => checkbox.hasAttribute('disabled'))).toBe(true);
|
|
66
|
+
cleanup(el);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('removes propagated disabled from slotted bds-checkbox elements when re-enabled, keeping individually-disabled ones', async () => {
|
|
70
|
+
const el = await fixture(
|
|
71
|
+
'<bds-checkbox-group label="Interests" disabled>' +
|
|
72
|
+
'<bds-checkbox value="sports">Sports</bds-checkbox>' +
|
|
73
|
+
'<bds-checkbox value="music" disabled>Music</bds-checkbox>' +
|
|
74
|
+
'</bds-checkbox-group>',
|
|
75
|
+
) as BdsCheckboxGroup;
|
|
76
|
+
await Promise.resolve();
|
|
77
|
+
|
|
78
|
+
el.disabled = false;
|
|
79
|
+
await el.updateComplete;
|
|
80
|
+
await Promise.resolve();
|
|
81
|
+
|
|
82
|
+
const [sports, music] = Array.from(el.querySelectorAll('bds-checkbox'));
|
|
83
|
+
expect(sports.hasAttribute('disabled')).toBe(false);
|
|
84
|
+
expect(music.hasAttribute('disabled')).toBe(true);
|
|
85
|
+
cleanup(el);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('propagates disabled to a bds-checkbox slotted in after the group is already disabled', async () => {
|
|
89
|
+
const el = await fixture('<bds-checkbox-group label="Interests" disabled></bds-checkbox-group>') as BdsCheckboxGroup;
|
|
90
|
+
const checkbox = document.createElement('bds-checkbox');
|
|
91
|
+
checkbox.setAttribute('value', 'sports');
|
|
92
|
+
el.appendChild(checkbox);
|
|
93
|
+
// slotchange fires asynchronously; allow a microtask.
|
|
94
|
+
await new Promise(r => requestAnimationFrame(() => r(null)));
|
|
95
|
+
expect(checkbox.hasAttribute('disabled')).toBe(true);
|
|
96
|
+
cleanup(el);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('exposes a visually-hidden "(required)" text alternative instead of aria-required on the fieldset', async () => {
|
|
100
|
+
const el = await fixture('<bds-checkbox-group label="Test" required></bds-checkbox-group>');
|
|
101
|
+
const fieldset = el.shadowRoot!.querySelector('fieldset')!;
|
|
102
|
+
// aria-required is not supported ARIA on role=group (which is what a bare
|
|
103
|
+
// <fieldset> maps to) — assert it is never set.
|
|
104
|
+
expect(fieldset.hasAttribute('aria-required')).toBe(false);
|
|
105
|
+
const requiredLabel = el.shadowRoot!.querySelector('.requiredLabel');
|
|
106
|
+
expect(requiredLabel?.textContent?.trim()).toBe('(required)');
|
|
107
|
+
cleanup(el);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('omits the required text alternative when not required', async () => {
|
|
111
|
+
const el = await fixture('<bds-checkbox-group label="Test"></bds-checkbox-group>');
|
|
112
|
+
expect(el.shadowRoot!.querySelector('.requiredLabel')).toBeNull();
|
|
113
|
+
cleanup(el);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('wires aria-describedby on the fieldset to the error message id', async () => {
|
|
117
|
+
const el = await fixture('<bds-checkbox-group label="Test" error="Select at least one"></bds-checkbox-group>');
|
|
118
|
+
const fieldset = el.shadowRoot!.querySelector('fieldset')!;
|
|
119
|
+
const message = el.shadowRoot!.querySelector('.message--error')!;
|
|
120
|
+
expect(fieldset.getAttribute('aria-describedby')).toBe(message.id);
|
|
121
|
+
cleanup(el);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('wires aria-describedby on the fieldset to the hint message id', async () => {
|
|
125
|
+
const el = await fixture('<bds-checkbox-group label="Test" hint="Select all that apply"></bds-checkbox-group>');
|
|
126
|
+
const fieldset = el.shadowRoot!.querySelector('fieldset')!;
|
|
127
|
+
const message = el.shadowRoot!.querySelector('.message--hint')!;
|
|
128
|
+
expect(fieldset.getAttribute('aria-describedby')).toBe(message.id);
|
|
129
|
+
cleanup(el);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('omits aria-describedby on the fieldset when there is no error or hint', async () => {
|
|
133
|
+
const el = await fixture('<bds-checkbox-group label="Test"></bds-checkbox-group>');
|
|
134
|
+
const fieldset = el.shadowRoot!.querySelector('fieldset')!;
|
|
135
|
+
expect(fieldset.hasAttribute('aria-describedby')).toBe(false);
|
|
136
|
+
cleanup(el);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('uses medium font-weight token for the legend (not semibold)', () => {
|
|
140
|
+
const styles = BdsCheckboxGroup.styles.toString();
|
|
141
|
+
expect(styles).toContain('--bds-font_weight--medium');
|
|
142
|
+
expect(styles).not.toContain('--bds-font_weight--semibold');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('uses the on-bg error color token for the error message (not the raw error token)', () => {
|
|
146
|
+
const styles = BdsCheckboxGroup.styles.toString();
|
|
147
|
+
expect(styles).toContain('--bds-color_error_on-bg');
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('applies :host([disabled]) visual styling for the group', () => {
|
|
151
|
+
const styles = BdsCheckboxGroup.styles.toString();
|
|
152
|
+
expect(styles).toContain(':host([disabled])');
|
|
153
|
+
});
|
|
55
154
|
});
|
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
import { LitElement, css, html } from 'lit';
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* `<bds-checkbox-group>` — groups related checkboxes with a shared label.
|
|
5
5
|
*
|
|
6
6
|
* Renders a `<fieldset>` with a `<legend>` for accessible grouping.
|
|
7
|
+
* Propagates `disabled` to slotted `<bds-checkbox>` elements — a shadow-DOM
|
|
8
|
+
* `<fieldset disabled>` has no effect on slotted light-DOM content on its
|
|
9
|
+
* own, so the group attribute is explicitly applied to (and removed from)
|
|
10
|
+
* each child. A checkbox individually marked `disabled` in markup stays
|
|
11
|
+
* disabled even after the group re-enables.
|
|
12
|
+
*
|
|
13
|
+
* `required` is surfaced to assistive tech via a visually-hidden "(required)"
|
|
14
|
+
* text alternative in the legend rather than `aria-required` on the fieldset —
|
|
15
|
+
* `aria-required` is only a supported property on the `checkbox`, `combobox`,
|
|
16
|
+
* `gridcell`, `listbox`, `radiogroup`, `spinbutton`, `textbox` and `tree`
|
|
17
|
+
* roles; a bare `<fieldset>` maps to the generic `group` role, which does not
|
|
18
|
+
* support it (there is no ARIA `checkboxgroup` role), so the attribute would
|
|
19
|
+
* be silently ignored by assistive tech.
|
|
7
20
|
*
|
|
8
21
|
* Attributes:
|
|
9
22
|
* label — visible group label (rendered as `<legend>`)
|
|
10
23
|
* error — error message shown below items
|
|
11
24
|
* hint — hint text shown below items
|
|
12
|
-
* disabled — disables the entire fieldset
|
|
25
|
+
* disabled — disables the entire fieldset and all slotted `<bds-checkbox>` elements
|
|
13
26
|
* required — marks the group as required
|
|
14
27
|
*
|
|
15
28
|
* Slots:
|
|
@@ -23,10 +36,25 @@ import { LitElement, css, html } from 'lit';
|
|
|
23
36
|
*/
|
|
24
37
|
export class BdsCheckboxGroup extends LitElement {
|
|
25
38
|
static styles = css`
|
|
39
|
+
/* Shadow DOM does not inherit the global box-sizing reset, so set it
|
|
40
|
+
here; otherwise elements with an explicit size + padding size as
|
|
41
|
+
content-box and layouts drift from the React (light-DOM) versions. */
|
|
42
|
+
:host,
|
|
43
|
+
*,
|
|
44
|
+
*::before,
|
|
45
|
+
*::after {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
|
|
26
49
|
:host {
|
|
27
50
|
display: block;
|
|
28
51
|
}
|
|
29
52
|
|
|
53
|
+
:host([disabled]) .legend,
|
|
54
|
+
:host([disabled]) .message {
|
|
55
|
+
opacity: 0.5;
|
|
56
|
+
}
|
|
57
|
+
|
|
30
58
|
fieldset {
|
|
31
59
|
border: none;
|
|
32
60
|
margin: 0;
|
|
@@ -36,7 +64,7 @@ export class BdsCheckboxGroup extends LitElement {
|
|
|
36
64
|
.legend {
|
|
37
65
|
font-size: var(--bds-font_size--body--s);
|
|
38
66
|
font-family: var(--bds-font_family--body);
|
|
39
|
-
font-weight: var(--bds-font_weight--
|
|
67
|
+
font-weight: var(--bds-font_weight--medium);
|
|
40
68
|
color: var(--bds-color_on-bg);
|
|
41
69
|
margin-block-end: var(--bds-space_xs);
|
|
42
70
|
}
|
|
@@ -46,6 +74,22 @@ export class BdsCheckboxGroup extends LitElement {
|
|
|
46
74
|
margin-inline-start: var(--bds-space_xxxs);
|
|
47
75
|
}
|
|
48
76
|
|
|
77
|
+
/* Visually hidden but still exposed to assistive tech — carries the
|
|
78
|
+
"required" state into the fieldset's accessible name, since the
|
|
79
|
+
visible asterisk above is aria-hidden and aria-required is not
|
|
80
|
+
supported ARIA on a fieldset (role=group). */
|
|
81
|
+
.requiredLabel {
|
|
82
|
+
position: absolute;
|
|
83
|
+
inline-size: 1px;
|
|
84
|
+
block-size: 1px;
|
|
85
|
+
padding: 0;
|
|
86
|
+
margin: -1px;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
clip: rect(0, 0, 0, 0);
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
border-width: 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
49
93
|
.items {
|
|
50
94
|
display: flex;
|
|
51
95
|
flex-direction: column;
|
|
@@ -59,7 +103,7 @@ export class BdsCheckboxGroup extends LitElement {
|
|
|
59
103
|
}
|
|
60
104
|
|
|
61
105
|
.message--error {
|
|
62
|
-
color: var(--bds-
|
|
106
|
+
color: var(--bds-color_error_on-bg);
|
|
63
107
|
}
|
|
64
108
|
|
|
65
109
|
.message--hint {
|
|
@@ -82,6 +126,8 @@ export class BdsCheckboxGroup extends LitElement {
|
|
|
82
126
|
declare disabled: boolean;
|
|
83
127
|
declare required: boolean;
|
|
84
128
|
|
|
129
|
+
private readonly _uid = Math.random().toString(36).slice(2, 8);
|
|
130
|
+
|
|
85
131
|
constructor() {
|
|
86
132
|
super();
|
|
87
133
|
this.label = '';
|
|
@@ -89,20 +135,60 @@ export class BdsCheckboxGroup extends LitElement {
|
|
|
89
135
|
this.required = false;
|
|
90
136
|
}
|
|
91
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Propagates `disabled` to slotted `<bds-checkbox>` elements. Only checkboxes
|
|
140
|
+
* that were enabled before the group disabled them are re-enabled when the
|
|
141
|
+
* group re-enables — a checkbox individually marked `disabled` in markup
|
|
142
|
+
* stays disabled.
|
|
143
|
+
*/
|
|
144
|
+
private _propagateDisabled = () => {
|
|
145
|
+
this.querySelectorAll('bds-checkbox').forEach(checkbox => {
|
|
146
|
+
const el = checkbox as HTMLElement;
|
|
147
|
+
if (this.disabled) {
|
|
148
|
+
if (!el.hasAttribute('disabled')) {
|
|
149
|
+
el.setAttribute('data-bds-group-disabled', '');
|
|
150
|
+
}
|
|
151
|
+
el.setAttribute('disabled', '');
|
|
152
|
+
} else if (el.hasAttribute('data-bds-group-disabled')) {
|
|
153
|
+
el.removeAttribute('disabled');
|
|
154
|
+
el.removeAttribute('data-bds-group-disabled');
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
connectedCallback() {
|
|
160
|
+
super.connectedCallback();
|
|
161
|
+
// Propagate after slot content has been parsed
|
|
162
|
+
Promise.resolve().then(this._propagateDisabled);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
updated(changed: Map<string, unknown>) {
|
|
166
|
+
super.updated(changed);
|
|
167
|
+
if (changed.has('disabled')) {
|
|
168
|
+
this._propagateDisabled();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
92
172
|
render() {
|
|
173
|
+
const errorId = `bds-checkbox-group-${this._uid}-error`;
|
|
174
|
+
const hintId = `bds-checkbox-group-${this._uid}-hint`;
|
|
175
|
+
const describedBy = [this.error && errorId, this.hint && hintId].filter(Boolean).join(' ') || undefined;
|
|
176
|
+
|
|
93
177
|
return html`
|
|
94
|
-
<fieldset ?disabled=${this.disabled}>
|
|
178
|
+
<fieldset ?disabled=${this.disabled} aria-describedby=${describedBy ?? nothing}>
|
|
95
179
|
<legend class="legend">
|
|
96
180
|
${this.label}
|
|
97
|
-
${this.required
|
|
181
|
+
${this.required
|
|
182
|
+
? html`<span class="required" aria-hidden="true"> *</span> <span class="requiredLabel">(required)</span>`
|
|
183
|
+
: ''}
|
|
98
184
|
</legend>
|
|
99
185
|
<div class="items">
|
|
100
|
-
<slot></slot>
|
|
186
|
+
<slot @slotchange=${this._propagateDisabled}></slot>
|
|
101
187
|
</div>
|
|
102
188
|
${this.error
|
|
103
|
-
? html`<p class="message message--error" role="alert">${this.error}</p>`
|
|
189
|
+
? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
|
|
104
190
|
: this.hint
|
|
105
|
-
? html`<p class="message message--hint">${this.hint}</p>`
|
|
191
|
+
? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
|
|
106
192
|
: ''}
|
|
107
193
|
</fieldset>
|
|
108
194
|
`;
|
|
@@ -60,4 +60,59 @@ describe('bds-checkbox', () => {
|
|
|
60
60
|
it('is form-associated', () => {
|
|
61
61
|
expect(BdsCheckbox.formAssociated).toBe(true);
|
|
62
62
|
});
|
|
63
|
+
|
|
64
|
+
it('recomputes required validity when checked changes (not just when required changes)', async () => {
|
|
65
|
+
const setValidity = vi.fn();
|
|
66
|
+
const spy = vi
|
|
67
|
+
.spyOn(HTMLElement.prototype, 'attachInternals')
|
|
68
|
+
.mockReturnValue({ setValidity, setFormValue: vi.fn() } as unknown as ElementInternals);
|
|
69
|
+
|
|
70
|
+
const el = await fixture('<bds-checkbox name="agree" required>Accept</bds-checkbox>') as BdsCheckbox;
|
|
71
|
+
// Initial connect already reports invalid (required + unchecked) — clear that call.
|
|
72
|
+
setValidity.mockClear();
|
|
73
|
+
|
|
74
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
75
|
+
input.checked = true;
|
|
76
|
+
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
77
|
+
await el.updateComplete;
|
|
78
|
+
|
|
79
|
+
expect(setValidity).toHaveBeenLastCalledWith({});
|
|
80
|
+
|
|
81
|
+
spy.mockRestore();
|
|
82
|
+
cleanup(el);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('reports invalid when a required checkbox becomes unchecked again', async () => {
|
|
86
|
+
const setValidity = vi.fn();
|
|
87
|
+
const spy = vi
|
|
88
|
+
.spyOn(HTMLElement.prototype, 'attachInternals')
|
|
89
|
+
.mockReturnValue({ setValidity, setFormValue: vi.fn() } as unknown as ElementInternals);
|
|
90
|
+
|
|
91
|
+
const el = await fixture('<bds-checkbox name="agree" required checked>Accept</bds-checkbox>') as BdsCheckbox;
|
|
92
|
+
setValidity.mockClear();
|
|
93
|
+
|
|
94
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
95
|
+
input.checked = false;
|
|
96
|
+
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
97
|
+
await el.updateComplete;
|
|
98
|
+
|
|
99
|
+
expect(setValidity).toHaveBeenLastCalledWith({ valueMissing: true }, 'Required');
|
|
100
|
+
|
|
101
|
+
spy.mockRestore();
|
|
102
|
+
cleanup(el);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('sets aria-invalid on the input when error attribute is set', async () => {
|
|
106
|
+
const el = await fixture('<bds-checkbox name="agree" error>Accept</bds-checkbox>');
|
|
107
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
108
|
+
expect(input.getAttribute('aria-invalid')).toBe('true');
|
|
109
|
+
cleanup(el);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('aria-invalid is false by default', async () => {
|
|
113
|
+
const el = await fixture('<bds-checkbox name="agree">Accept</bds-checkbox>');
|
|
114
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
115
|
+
expect(input.getAttribute('aria-invalid')).toBe('false');
|
|
116
|
+
cleanup(el);
|
|
117
|
+
});
|
|
63
118
|
});
|
|
@@ -13,6 +13,7 @@ import { LitElement, css, html } from 'lit';
|
|
|
13
13
|
* checked — boolean; whether the checkbox is checked
|
|
14
14
|
* required — boolean
|
|
15
15
|
* disabled — boolean
|
|
16
|
+
* error — boolean; puts the checkbox in an error state (border colour + aria-invalid)
|
|
16
17
|
*
|
|
17
18
|
* Slots:
|
|
18
19
|
* (default) — label text
|
|
@@ -27,10 +28,20 @@ export class BdsCheckbox extends LitElement {
|
|
|
27
28
|
static formAssociated = true;
|
|
28
29
|
|
|
29
30
|
static styles = css`
|
|
31
|
+
/* Shadow DOM does not inherit the global box-sizing reset, so set it
|
|
32
|
+
here; otherwise elements with an explicit size + padding size as
|
|
33
|
+
content-box and layouts drift from the React (light-DOM) versions. */
|
|
34
|
+
:host,
|
|
35
|
+
*,
|
|
36
|
+
*::before,
|
|
37
|
+
*::after {
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
}
|
|
40
|
+
|
|
30
41
|
:host {
|
|
31
42
|
display: inline-flex;
|
|
32
43
|
align-items: flex-start;
|
|
33
|
-
gap: var(--bds-
|
|
44
|
+
gap: var(--checkbox_gap, var(--bds-space_m));
|
|
34
45
|
cursor: pointer;
|
|
35
46
|
font-size: var(--bds-font_size--body);
|
|
36
47
|
font-family: var(--bds-font_family--body);
|
|
@@ -45,16 +56,18 @@ export class BdsCheckbox extends LitElement {
|
|
|
45
56
|
|
|
46
57
|
.input {
|
|
47
58
|
--inputSize: calc(var(--bds-space_s) * 2);
|
|
48
|
-
margin-block-start: 0.25em;
|
|
59
|
+
margin-block-start: var(--checkbox_offset, 0.25em);
|
|
49
60
|
inline-size: var(--inputSize);
|
|
50
61
|
block-size: var(--inputSize);
|
|
51
62
|
flex-shrink: 0;
|
|
52
|
-
|
|
63
|
+
/* --checkbox_border-color is a deprecated alias — prefer --checkbox_color (matches React) */
|
|
64
|
+
color: var(--checkbox_color, var(--checkbox_border-color, var(--bds-color_on-bg)));
|
|
65
|
+
--bdc_color: currentcolor;
|
|
53
66
|
--bdc-outline_radius: var(--bds-border_radius--xs);
|
|
54
67
|
|
|
55
68
|
border-radius: var(--checkbox_radius, var(--bdc-outline_radius));
|
|
56
69
|
box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--checkbox_shadow, var(--bdc-outline_shadow));
|
|
57
|
-
border: none;
|
|
70
|
+
border: var(--checkbox_border, none);
|
|
58
71
|
appearance: none;
|
|
59
72
|
background-color: var(--checkbox_color_bg, var(--bds-color_bg));
|
|
60
73
|
cursor: pointer;
|
|
@@ -79,11 +92,19 @@ export class BdsCheckbox extends LitElement {
|
|
|
79
92
|
transform: rotate(45deg);
|
|
80
93
|
}
|
|
81
94
|
|
|
95
|
+
.input:focus {
|
|
96
|
+
--bdc_color: var(--bdc_color--focus);
|
|
97
|
+
}
|
|
98
|
+
|
|
82
99
|
.input:focus-visible {
|
|
83
100
|
outline: var(--bds-outline_default);
|
|
84
101
|
outline-offset: var(--bds-outline_offset);
|
|
85
102
|
}
|
|
86
103
|
|
|
104
|
+
:host([error]) .input {
|
|
105
|
+
--bdc_color: var(--bdc_color--error);
|
|
106
|
+
}
|
|
107
|
+
|
|
87
108
|
label {
|
|
88
109
|
cursor: pointer;
|
|
89
110
|
flex: 1;
|
|
@@ -96,6 +117,7 @@ export class BdsCheckbox extends LitElement {
|
|
|
96
117
|
checked: { type: Boolean, reflect: true },
|
|
97
118
|
required: { type: Boolean, reflect: true },
|
|
98
119
|
disabled: { type: Boolean, reflect: true },
|
|
120
|
+
error: { type: Boolean, reflect: true },
|
|
99
121
|
};
|
|
100
122
|
|
|
101
123
|
declare name: string;
|
|
@@ -103,6 +125,7 @@ export class BdsCheckbox extends LitElement {
|
|
|
103
125
|
declare checked: boolean;
|
|
104
126
|
declare required: boolean;
|
|
105
127
|
declare disabled: boolean;
|
|
128
|
+
declare error: boolean;
|
|
106
129
|
|
|
107
130
|
private _internals!: ElementInternals;
|
|
108
131
|
private readonly _uid = Math.random().toString(36).slice(2, 8);
|
|
@@ -115,6 +138,7 @@ export class BdsCheckbox extends LitElement {
|
|
|
115
138
|
this.checked = false;
|
|
116
139
|
this.required = false;
|
|
117
140
|
this.disabled = false;
|
|
141
|
+
this.error = false;
|
|
118
142
|
}
|
|
119
143
|
|
|
120
144
|
updated(changed: Map<string, unknown>) {
|
|
@@ -122,7 +146,7 @@ export class BdsCheckbox extends LitElement {
|
|
|
122
146
|
if (changed.has('checked') || changed.has('value')) {
|
|
123
147
|
this._internals.setFormValue?.(this.checked ? this.value : null);
|
|
124
148
|
}
|
|
125
|
-
if (changed.has('required')) {
|
|
149
|
+
if (changed.has('required') || changed.has('checked')) {
|
|
126
150
|
if (this.required && !this.checked) {
|
|
127
151
|
this._internals.setValidity?.({ valueMissing: true }, 'Required');
|
|
128
152
|
} else {
|
|
@@ -150,6 +174,7 @@ export class BdsCheckbox extends LitElement {
|
|
|
150
174
|
.checked=${this.checked}
|
|
151
175
|
?required=${this.required}
|
|
152
176
|
?disabled=${this.disabled}
|
|
177
|
+
aria-invalid=${this.error ? 'true' : 'false'}
|
|
153
178
|
@change=${this._handleChange}
|
|
154
179
|
/>
|
|
155
180
|
<label for=${id}><slot></slot></label>
|
|
@@ -114,4 +114,83 @@ describe('bds-combobox', () => {
|
|
|
114
114
|
it('is form-associated', () => {
|
|
115
115
|
expect(BdsCombobox.formAssociated).toBe(true);
|
|
116
116
|
});
|
|
117
|
+
|
|
118
|
+
it('associates a visible label with the input via for/id', async () => {
|
|
119
|
+
const el = await fixture(`<bds-combobox name="country" label="Country" options='${OPTIONS}'></bds-combobox>`);
|
|
120
|
+
const label = el.shadowRoot!.querySelector<HTMLLabelElement>('label')!;
|
|
121
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
122
|
+
expect(label).not.toBeNull();
|
|
123
|
+
expect(label.textContent).toBe('Country');
|
|
124
|
+
expect(label.getAttribute('for')).toBe(input.id);
|
|
125
|
+
cleanup(el);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('renders no label when the label attribute is unset', async () => {
|
|
129
|
+
const el = await fixture(`<bds-combobox name="country" options='${OPTIONS}'></bds-combobox>`);
|
|
130
|
+
expect(el.shadowRoot!.querySelector('label')).toBeNull();
|
|
131
|
+
cleanup(el);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('sets aria-controls on the input pointing at the listbox id', async () => {
|
|
135
|
+
const el = await fixture(`<bds-combobox name="country" options='${OPTIONS}'></bds-combobox>`);
|
|
136
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
137
|
+
input.dispatchEvent(new Event('focus'));
|
|
138
|
+
await el.updateComplete;
|
|
139
|
+
const listbox = el.shadowRoot!.querySelector('[role="listbox"]')!;
|
|
140
|
+
expect(input.getAttribute('aria-controls')).toBe(listbox.id);
|
|
141
|
+
cleanup(el);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('sets autocomplete="off" on the input', async () => {
|
|
145
|
+
const el = await fixture(`<bds-combobox name="country" options='${OPTIONS}'></bds-combobox>`);
|
|
146
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
147
|
+
expect(input.getAttribute('autocomplete')).toBe('off');
|
|
148
|
+
cleanup(el);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('updates aria-activedescendant to the focused option id while navigating', async () => {
|
|
152
|
+
const el = await fixture(`<bds-combobox name="country" options='${OPTIONS}'></bds-combobox>`);
|
|
153
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
154
|
+
input.dispatchEvent(new Event('focus'));
|
|
155
|
+
await el.updateComplete;
|
|
156
|
+
expect(input.hasAttribute('aria-activedescendant')).toBe(false);
|
|
157
|
+
|
|
158
|
+
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
|
|
159
|
+
await el.updateComplete;
|
|
160
|
+
const options = Array.from(el.shadowRoot!.querySelectorAll('[role="option"]'));
|
|
161
|
+
const focusedOption = options.find(o => o.className.includes('--focused'))!;
|
|
162
|
+
expect(focusedOption).not.toBeUndefined();
|
|
163
|
+
expect(input.getAttribute('aria-activedescendant')).toBe(focusedOption.id);
|
|
164
|
+
cleanup(el);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('gives the no-results item role="presentation" so it is not exposed as an option', async () => {
|
|
168
|
+
const el = await fixture(`<bds-combobox name="country" options='${OPTIONS}'></bds-combobox>`);
|
|
169
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
170
|
+
input.value = 'zzz';
|
|
171
|
+
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
172
|
+
await el.updateComplete;
|
|
173
|
+
const noResults = el.shadowRoot!.querySelector('.no-results')!;
|
|
174
|
+
expect(noResults.getAttribute('role')).toBe('presentation');
|
|
175
|
+
cleanup(el);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('sets aria-invalid and wires the error message via aria-describedby', async () => {
|
|
179
|
+
const el = await fixture(`<bds-combobox name="country" error="Required field" options='${OPTIONS}'></bds-combobox>`);
|
|
180
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
181
|
+
const error = el.shadowRoot!.querySelector('.message--error')!;
|
|
182
|
+
expect(input.getAttribute('aria-invalid')).toBe('true');
|
|
183
|
+
expect(error.getAttribute('role')).toBe('alert');
|
|
184
|
+
expect(input.getAttribute('aria-describedby')).toBe(error.id);
|
|
185
|
+
cleanup(el);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('wires the hint message via aria-describedby when there is no error', async () => {
|
|
189
|
+
const el = await fixture(`<bds-combobox name="country" hint="Pick a country" options='${OPTIONS}'></bds-combobox>`);
|
|
190
|
+
const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
|
|
191
|
+
const hint = el.shadowRoot!.querySelector('.message--hint')!;
|
|
192
|
+
expect(input.getAttribute('aria-invalid')).toBe('false');
|
|
193
|
+
expect(input.getAttribute('aria-describedby')).toBe(hint.id);
|
|
194
|
+
cleanup(el);
|
|
195
|
+
});
|
|
117
196
|
});
|