@boostdev/design-system-components 2.7.1 → 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-3AY2YKCM.js +223 -0
- package/dist/web-components/chunk-3WAV6MDN.js +212 -0
- package/dist/web-components/{chunk-CZBIVR4V.js → chunk-47AT5KZD.js} +88 -16
- 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-5R6IFELV.js → chunk-AIBOHNDU.js} +11 -1
- package/dist/web-components/{chunk-ITHLKR7Q.js → chunk-AP4RDUL2.js} +16 -5
- 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-CM3KYZ6Z.js → chunk-JH6LQKLK.js} +78 -6
- 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-57TRNCWQ.js → chunk-WFVKU4GX.js} +22 -11
- 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-F5E3IT7G.js → chunk-XIZWAWMJ.js} +50 -11
- 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 +60 -13
- 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 +102 -17
- 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 +136 -23
- 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 +96 -8
- package/src/web-components/interaction/form/bds-slider.spec.ts +83 -0
- package/src/web-components/interaction/form/bds-slider.ts +181 -33
- package/src/web-components/interaction/form/bds-switch.spec.ts +68 -0
- package/src/web-components/interaction/form/bds-switch.ts +142 -41
- package/src/web-components/interaction/form/bds-textarea.spec.ts +71 -0
- package/src/web-components/interaction/form/bds-textarea.ts +109 -8
- 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 +30 -12
- 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 +113 -36
- 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 +16 -15
- 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 +11 -1
- 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 +19 -6
- 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-5TFWOPLH.js +0 -49
- package/dist/web-components/chunk-7FMR53BW.js +0 -127
- package/dist/web-components/chunk-AGKJTMJI.js +0 -56
- package/dist/web-components/chunk-BQLZ7I4G.js +0 -56
- package/dist/web-components/chunk-IYGF6CD5.js +0 -118
- package/dist/web-components/chunk-QBB6ZX4R.js +0 -107
- package/dist/web-components/chunk-Y3POAKGS.js +0 -133
- 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
|
@@ -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
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LitElement, css, html } from 'lit';
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
2
|
|
|
3
3
|
export interface ComboboxOption {
|
|
4
4
|
value: string;
|
|
@@ -17,6 +17,9 @@ export interface ComboboxOption {
|
|
|
17
17
|
* value — currently selected value
|
|
18
18
|
* options — JSON array of `{ value, label, disabled? }` option objects
|
|
19
19
|
* placeholder — input placeholder text
|
|
20
|
+
* label — visible label text (associated to the input via `<label for>`)
|
|
21
|
+
* hint — helper text shown below the input
|
|
22
|
+
* error — error message; when set the input enters error state
|
|
20
23
|
* disabled — boolean
|
|
21
24
|
*
|
|
22
25
|
* Events:
|
|
@@ -25,6 +28,7 @@ export interface ComboboxOption {
|
|
|
25
28
|
* @example
|
|
26
29
|
* <bds-combobox
|
|
27
30
|
* name="country"
|
|
31
|
+
* label="Country"
|
|
28
32
|
* placeholder="Search…"
|
|
29
33
|
* options='[{"value":"nl","label":"Netherlands"},{"value":"be","label":"Belgium"}]'
|
|
30
34
|
* ></bds-combobox>
|
|
@@ -33,6 +37,16 @@ export class BdsCombobox extends LitElement {
|
|
|
33
37
|
static formAssociated = true;
|
|
34
38
|
|
|
35
39
|
static styles = css`
|
|
40
|
+
/* Shadow DOM does not inherit the global box-sizing reset, so set it
|
|
41
|
+
here; otherwise elements with an explicit size + padding size as
|
|
42
|
+
content-box and layouts drift from the React (light-DOM) versions. */
|
|
43
|
+
:host,
|
|
44
|
+
*,
|
|
45
|
+
*::before,
|
|
46
|
+
*::after {
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
}
|
|
49
|
+
|
|
36
50
|
:host {
|
|
37
51
|
display: block;
|
|
38
52
|
position: relative;
|
|
@@ -43,6 +57,15 @@ export class BdsCombobox extends LitElement {
|
|
|
43
57
|
pointer-events: none;
|
|
44
58
|
}
|
|
45
59
|
|
|
60
|
+
.label {
|
|
61
|
+
display: block;
|
|
62
|
+
font-size: var(--bds-font_size--body--s);
|
|
63
|
+
font-family: var(--bds-font_family--body);
|
|
64
|
+
font-weight: var(--bds-font_weight--semibold);
|
|
65
|
+
color: var(--bds-color_on-bg);
|
|
66
|
+
margin-block-end: var(--bds-space_xxs);
|
|
67
|
+
}
|
|
68
|
+
|
|
46
69
|
.wrapper {
|
|
47
70
|
position: relative;
|
|
48
71
|
}
|
|
@@ -52,10 +75,10 @@ export class BdsCombobox extends LitElement {
|
|
|
52
75
|
font-family: var(--bds-font_family--body);
|
|
53
76
|
font-size: var(--bds-font_size--body);
|
|
54
77
|
padding: var(--bds-space_s);
|
|
55
|
-
padding-inline-end: var(--bds-
|
|
56
|
-
border: none;
|
|
78
|
+
padding-inline-end: var(--bds-space_xxl);
|
|
79
|
+
border: var(--combobox_border, none);
|
|
57
80
|
--bdc_color: var(--combobox_border-color, currentcolor);
|
|
58
|
-
--bdc-outline_radius: var(--bds-border_radius--
|
|
81
|
+
--bdc-outline_radius: var(--bds-border_radius--full);
|
|
59
82
|
|
|
60
83
|
border-radius: var(--combobox_radius, var(--bdc-outline_radius));
|
|
61
84
|
box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--combobox_shadow, var(--bdc-outline_shadow));
|
|
@@ -74,6 +97,14 @@ export class BdsCombobox extends LitElement {
|
|
|
74
97
|
outline-offset: var(--bds-outline_offset);
|
|
75
98
|
}
|
|
76
99
|
|
|
100
|
+
:host([error]) .input {
|
|
101
|
+
--bdc_color: var(--bdc_color--error);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:host([error]) .input:focus {
|
|
105
|
+
--bdc_color: var(--bdc_color--error);
|
|
106
|
+
}
|
|
107
|
+
|
|
77
108
|
.chevron {
|
|
78
109
|
position: absolute;
|
|
79
110
|
inset-inline-end: var(--bds-space_s);
|
|
@@ -92,31 +123,39 @@ export class BdsCombobox extends LitElement {
|
|
|
92
123
|
|
|
93
124
|
.listbox {
|
|
94
125
|
position: absolute;
|
|
95
|
-
inset-block-start: calc(100% + var(--bds-
|
|
126
|
+
inset-block-start: calc(100% + var(--bds-space_xxs));
|
|
96
127
|
inset-inline-start: 0;
|
|
97
128
|
inline-size: 100%;
|
|
98
129
|
max-block-size: 15rem;
|
|
99
|
-
overflow-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
130
|
+
overflow-block: auto;
|
|
131
|
+
list-style: none;
|
|
132
|
+
margin: 0;
|
|
133
|
+
border: var(--combobox_listbox-border, none);
|
|
134
|
+
--bdc_color: currentcolor;
|
|
135
|
+
--bdc-outline_radius: var(--bds-border_radius--s);
|
|
136
|
+
|
|
137
|
+
border-radius: var(--combobox_listbox-radius, var(--bdc-outline_radius));
|
|
138
|
+
background-color: var(--combobox_color_bg, var(--bds-color_bg));
|
|
139
|
+
color: var(--combobox_on-color, var(--bds-color_on-bg));
|
|
140
|
+
box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--combobox_listbox-shadow, var(--bds-shadow_m));
|
|
141
|
+
z-index: var(--combobox_z-index, var(--bds-z-index_dropdown));
|
|
142
|
+
padding: var(--bds-space_xxs) 0;
|
|
105
143
|
}
|
|
106
144
|
|
|
107
145
|
.option {
|
|
108
146
|
display: block;
|
|
109
|
-
padding: var(--bds-
|
|
147
|
+
padding: var(--bds-space_xs) var(--bds-space_m);
|
|
110
148
|
cursor: pointer;
|
|
111
149
|
font-family: var(--bds-font_family--body);
|
|
112
150
|
font-size: var(--bds-font_size--body);
|
|
113
|
-
color: var(--bds-color_on-bg);
|
|
151
|
+
color: var(--combobox_on-color, var(--bds-color_on-bg));
|
|
114
152
|
transition: background-color var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
115
153
|
}
|
|
116
154
|
|
|
117
155
|
.option:hover,
|
|
118
156
|
.option[aria-selected='true'] {
|
|
119
|
-
background-color: var(--bds-color_bg--subtle);
|
|
157
|
+
background-color: var(--combobox_option-bg--highlighted, var(--bds-color_bg--subtle));
|
|
158
|
+
color: var(--combobox_option-color--highlighted, var(--bds-color_interactive_on-bg));
|
|
120
159
|
}
|
|
121
160
|
|
|
122
161
|
.option[aria-disabled='true'] {
|
|
@@ -125,7 +164,8 @@ export class BdsCombobox extends LitElement {
|
|
|
125
164
|
}
|
|
126
165
|
|
|
127
166
|
.option.--focused {
|
|
128
|
-
background-color: var(--bds-color_bg--subtle);
|
|
167
|
+
background-color: var(--combobox_option-bg--highlighted, var(--bds-color_bg--subtle));
|
|
168
|
+
color: var(--combobox_option-color--highlighted, var(--bds-color_interactive_on-bg));
|
|
129
169
|
outline: none;
|
|
130
170
|
}
|
|
131
171
|
|
|
@@ -135,6 +175,21 @@ export class BdsCombobox extends LitElement {
|
|
|
135
175
|
font-size: var(--bds-font_size--body--s);
|
|
136
176
|
color: var(--bds-color_on-bg--subtle);
|
|
137
177
|
}
|
|
178
|
+
|
|
179
|
+
.message {
|
|
180
|
+
margin-block-start: var(--bds-space_xxs);
|
|
181
|
+
font-size: var(--bds-font_size--body--s);
|
|
182
|
+
font-family: var(--bds-font_family--body);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.message--error {
|
|
186
|
+
color: var(--bds-color_error);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.message--hint {
|
|
190
|
+
color: var(--bds-color_on-bg--subtle);
|
|
191
|
+
font-style: italic;
|
|
192
|
+
}
|
|
138
193
|
`;
|
|
139
194
|
|
|
140
195
|
static properties = {
|
|
@@ -142,6 +197,9 @@ export class BdsCombobox extends LitElement {
|
|
|
142
197
|
value: { type: String },
|
|
143
198
|
options: { type: String },
|
|
144
199
|
placeholder: { type: String },
|
|
200
|
+
label: { type: String },
|
|
201
|
+
hint: { type: String },
|
|
202
|
+
error: { type: String, reflect: true },
|
|
145
203
|
disabled: { type: Boolean, reflect: true },
|
|
146
204
|
};
|
|
147
205
|
|
|
@@ -149,9 +207,13 @@ export class BdsCombobox extends LitElement {
|
|
|
149
207
|
declare value: string;
|
|
150
208
|
declare options: string;
|
|
151
209
|
declare placeholder: string;
|
|
210
|
+
declare label: string;
|
|
211
|
+
declare hint: string | undefined;
|
|
212
|
+
declare error: string | undefined;
|
|
152
213
|
declare disabled: boolean;
|
|
153
214
|
|
|
154
215
|
private _internals!: ElementInternals;
|
|
216
|
+
private readonly _uid = Math.random().toString(36).slice(2, 8);
|
|
155
217
|
private _open = false;
|
|
156
218
|
private _query = '';
|
|
157
219
|
private _focusedIndex = -1;
|
|
@@ -163,6 +225,7 @@ export class BdsCombobox extends LitElement {
|
|
|
163
225
|
this.value = '';
|
|
164
226
|
this.options = '[]';
|
|
165
227
|
this.placeholder = '';
|
|
228
|
+
this.label = '';
|
|
166
229
|
this.disabled = false;
|
|
167
230
|
}
|
|
168
231
|
|
|
@@ -280,16 +343,32 @@ export class BdsCombobox extends LitElement {
|
|
|
280
343
|
render() {
|
|
281
344
|
const filtered = this._filtered;
|
|
282
345
|
const inputValue = this._open ? this._query : this._displayLabel;
|
|
346
|
+
const id = `bds-combobox-${this._uid}`;
|
|
347
|
+
const listboxId = `${id}-listbox`;
|
|
348
|
+
const hintId = `${id}-hint`;
|
|
349
|
+
const errorId = `${id}-error`;
|
|
350
|
+
const describedBy = [this.error && errorId, this.hint && hintId].filter(Boolean).join(' ') || undefined;
|
|
351
|
+
const activeDescendant =
|
|
352
|
+
this._focusedIndex >= 0 && this._focusedIndex < filtered.length
|
|
353
|
+
? `${id}-option-${this._focusedIndex}`
|
|
354
|
+
: undefined;
|
|
283
355
|
|
|
284
356
|
return html`
|
|
357
|
+
${this.label ? html`<label class="label" for=${id}>${this.label}</label>` : ''}
|
|
285
358
|
<div class="wrapper">
|
|
286
359
|
<input
|
|
360
|
+
id=${id}
|
|
287
361
|
type="text"
|
|
288
362
|
class="input"
|
|
289
363
|
role="combobox"
|
|
290
364
|
aria-expanded=${this._open}
|
|
291
365
|
aria-autocomplete="list"
|
|
292
366
|
aria-haspopup="listbox"
|
|
367
|
+
aria-controls=${listboxId}
|
|
368
|
+
aria-activedescendant=${activeDescendant ?? nothing}
|
|
369
|
+
aria-invalid=${this.error ? 'true' : 'false'}
|
|
370
|
+
aria-describedby=${describedBy ?? nothing}
|
|
371
|
+
autocomplete="off"
|
|
293
372
|
name=${this.name}
|
|
294
373
|
placeholder=${this.placeholder}
|
|
295
374
|
.value=${inputValue}
|
|
@@ -305,11 +384,12 @@ export class BdsCombobox extends LitElement {
|
|
|
305
384
|
</svg>
|
|
306
385
|
</span>
|
|
307
386
|
${this._open ? html`
|
|
308
|
-
<ul class="listbox" role="listbox" aria-label="Options">
|
|
387
|
+
<ul id=${listboxId} class="listbox" role="listbox" aria-label="Options">
|
|
309
388
|
${filtered.length === 0
|
|
310
|
-
? html`<li class="no-results">No results</li>`
|
|
389
|
+
? html`<li class="no-results" role="presentation">No results</li>`
|
|
311
390
|
: filtered.map((opt, i) => html`
|
|
312
391
|
<li
|
|
392
|
+
id="${id}-option-${i}"
|
|
313
393
|
class="option ${i === this._focusedIndex ? '--focused' : ''}"
|
|
314
394
|
role="option"
|
|
315
395
|
aria-selected=${opt.value === this.value}
|
|
@@ -321,6 +401,11 @@ export class BdsCombobox extends LitElement {
|
|
|
321
401
|
</ul>
|
|
322
402
|
` : ''}
|
|
323
403
|
</div>
|
|
404
|
+
${this.error
|
|
405
|
+
? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
|
|
406
|
+
: this.hint
|
|
407
|
+
? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
|
|
408
|
+
: ''}
|
|
324
409
|
`;
|
|
325
410
|
}
|
|
326
411
|
}
|