@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
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
import { LitElement, css, html } from 'lit';
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* `<bds-radio>` — form-associated Radio custom element.
|
|
5
5
|
*
|
|
6
6
|
* Participates in HTML forms via the Form-Associated Custom Elements API.
|
|
7
|
-
* Use multiple `<bds-radio>` elements with the same `name` to form a group
|
|
7
|
+
* Use multiple `<bds-radio>` elements with the same `name` to form a group —
|
|
8
|
+
* checking one automatically unchecks the others sharing that `name`
|
|
9
|
+
* (searched within the same document/shadow root), and Arrow Up/Down/Left/Right
|
|
10
|
+
* move selection between them, mirroring native `<input type="radio">` semantics.
|
|
8
11
|
*
|
|
9
12
|
* Attributes:
|
|
10
|
-
* name
|
|
11
|
-
* value
|
|
12
|
-
* checked
|
|
13
|
-
* required
|
|
14
|
-
* disabled
|
|
13
|
+
* name — form field name (groups radio buttons)
|
|
14
|
+
* value — submitted value when selected
|
|
15
|
+
* checked — boolean; whether this option is selected
|
|
16
|
+
* required — boolean
|
|
17
|
+
* disabled — boolean
|
|
18
|
+
* error — boolean; visual + aria-invalid error state
|
|
19
|
+
* description — optional supporting text rendered below the label
|
|
15
20
|
*
|
|
16
21
|
* Slots:
|
|
17
22
|
* (default) — label text
|
|
18
23
|
*
|
|
24
|
+
* Events:
|
|
25
|
+
* bds-change — fired when this radio becomes checked via user interaction;
|
|
26
|
+
* `detail: { value: string, checked: true }`. Composed so it
|
|
27
|
+
* crosses the shadow boundary (unlike the native `change` event).
|
|
28
|
+
*
|
|
19
29
|
* @example
|
|
20
30
|
* <bds-radio name="size" value="s">Small</bds-radio>
|
|
21
31
|
* <bds-radio name="size" value="m" checked>Medium</bds-radio>
|
|
@@ -25,6 +35,16 @@ export class BdsRadio extends LitElement {
|
|
|
25
35
|
static formAssociated = true;
|
|
26
36
|
|
|
27
37
|
static styles = css`
|
|
38
|
+
/* Shadow DOM does not inherit the global box-sizing reset, so set it
|
|
39
|
+
here; otherwise elements with an explicit size + padding size as
|
|
40
|
+
content-box and layouts drift from the React (light-DOM) versions. */
|
|
41
|
+
:host,
|
|
42
|
+
*,
|
|
43
|
+
*::before,
|
|
44
|
+
*::after {
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
}
|
|
47
|
+
|
|
28
48
|
:host {
|
|
29
49
|
display: inline-flex;
|
|
30
50
|
align-items: flex-start;
|
|
@@ -42,22 +62,25 @@ export class BdsRadio extends LitElement {
|
|
|
42
62
|
}
|
|
43
63
|
|
|
44
64
|
.input {
|
|
65
|
+
box-sizing: border-box;
|
|
45
66
|
--inputSize: calc(var(--bds-space_s) * 2);
|
|
46
|
-
margin-block-start: 0.
|
|
67
|
+
margin-block-start: var(--radio_offset, 0.2em);
|
|
47
68
|
inline-size: var(--inputSize);
|
|
48
69
|
block-size: var(--inputSize);
|
|
49
70
|
flex-shrink: 0;
|
|
50
|
-
|
|
71
|
+
color: var(--radio_color, var(--radio_border-color, var(--bds-color_on-bg)));
|
|
72
|
+
border: var(--radio_border, none);
|
|
73
|
+
--bdc_color: currentcolor;
|
|
51
74
|
--bdc-outline_radius: var(--bds-border_radius--circle);
|
|
52
75
|
|
|
53
|
-
border-radius: var(--radio_radius, var(--
|
|
76
|
+
border-radius: var(--radio_radius, var(--bdc-outline_radius));
|
|
54
77
|
box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--radio_shadow, var(--bdc-outline_shadow));
|
|
55
|
-
border: none;
|
|
56
78
|
appearance: none;
|
|
57
79
|
background-color: var(--radio_color_bg, var(--bds-color_bg));
|
|
58
80
|
cursor: pointer;
|
|
59
81
|
position: relative;
|
|
60
|
-
transition: --bdc_color
|
|
82
|
+
transition: --bdc_color var(--bds-animation_transition-duration) var(--bds-animation_easing),
|
|
83
|
+
background-color var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
61
84
|
}
|
|
62
85
|
|
|
63
86
|
.input:checked {
|
|
@@ -69,23 +92,45 @@ export class BdsRadio extends LitElement {
|
|
|
69
92
|
--bdc_color: var(--radio_color-active, var(--bdc-color_active));
|
|
70
93
|
}
|
|
71
94
|
|
|
95
|
+
.input:focus {
|
|
96
|
+
--bdc_color: var(--bdc_color--focus);
|
|
97
|
+
}
|
|
98
|
+
|
|
72
99
|
.input:focus-visible {
|
|
73
100
|
outline: var(--bds-outline_default);
|
|
74
101
|
outline-offset: var(--bds-outline_offset);
|
|
75
102
|
}
|
|
76
103
|
|
|
104
|
+
:host([error]) .input {
|
|
105
|
+
--bdc_color: var(--bdc_color--error);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.textWrapper {
|
|
109
|
+
display: flex;
|
|
110
|
+
flex-direction: column;
|
|
111
|
+
gap: var(--bds-space_xxxs);
|
|
112
|
+
flex: 1;
|
|
113
|
+
}
|
|
114
|
+
|
|
77
115
|
label {
|
|
78
116
|
cursor: pointer;
|
|
79
|
-
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.description {
|
|
120
|
+
font-size: var(--bds-font_size--body--s);
|
|
121
|
+
color: var(--radio_description-color, var(--bds-color_on-bg--subtle));
|
|
122
|
+
line-height: var(--bds-font_line-height--body);
|
|
80
123
|
}
|
|
81
124
|
`;
|
|
82
125
|
|
|
83
126
|
static properties = {
|
|
84
|
-
name:
|
|
85
|
-
value:
|
|
86
|
-
checked:
|
|
87
|
-
required:
|
|
88
|
-
disabled:
|
|
127
|
+
name: { type: String, reflect: true },
|
|
128
|
+
value: { type: String },
|
|
129
|
+
checked: { type: Boolean, reflect: true },
|
|
130
|
+
required: { type: Boolean, reflect: true },
|
|
131
|
+
disabled: { type: Boolean, reflect: true },
|
|
132
|
+
error: { type: Boolean, reflect: true },
|
|
133
|
+
description: { type: String },
|
|
89
134
|
};
|
|
90
135
|
|
|
91
136
|
declare name: string;
|
|
@@ -93,9 +138,12 @@ export class BdsRadio extends LitElement {
|
|
|
93
138
|
declare checked: boolean;
|
|
94
139
|
declare required: boolean;
|
|
95
140
|
declare disabled: boolean;
|
|
141
|
+
declare error: boolean;
|
|
142
|
+
declare description: string | undefined;
|
|
96
143
|
|
|
97
144
|
private _internals!: ElementInternals;
|
|
98
145
|
private readonly _uid = Math.random().toString(36).slice(2, 8);
|
|
146
|
+
private _initialChecked = false;
|
|
99
147
|
|
|
100
148
|
constructor() {
|
|
101
149
|
super();
|
|
@@ -105,6 +153,12 @@ export class BdsRadio extends LitElement {
|
|
|
105
153
|
this.checked = false;
|
|
106
154
|
this.required = false;
|
|
107
155
|
this.disabled = false;
|
|
156
|
+
this.error = false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
connectedCallback() {
|
|
160
|
+
super.connectedCallback();
|
|
161
|
+
this._initialChecked = this.hasAttribute('checked');
|
|
108
162
|
}
|
|
109
163
|
|
|
110
164
|
updated(changed: Map<string, unknown>) {
|
|
@@ -115,16 +169,68 @@ export class BdsRadio extends LitElement {
|
|
|
115
169
|
}
|
|
116
170
|
|
|
117
171
|
formResetCallback() {
|
|
118
|
-
this.checked =
|
|
119
|
-
this._internals.setFormValue?.(null);
|
|
172
|
+
this.checked = this._initialChecked;
|
|
173
|
+
this._internals.setFormValue?.(this._initialChecked ? this.value : null);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** All `<bds-radio>` elements sharing this radio's `name`, in document order (including this one). */
|
|
177
|
+
private _getGroupMembers(): BdsRadio[] {
|
|
178
|
+
if (!this.name) return [this];
|
|
179
|
+
const root = this.getRootNode() as Document | ShadowRoot;
|
|
180
|
+
return Array.from(root.querySelectorAll('bds-radio')).filter(radio => radio.name === this.name);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Marks `radio` as the sole checked member of its group and notifies listeners. */
|
|
184
|
+
private _selectRadio(radio: BdsRadio) {
|
|
185
|
+
this._getGroupMembers().forEach(member => {
|
|
186
|
+
if (member !== radio) member.checked = false;
|
|
187
|
+
});
|
|
188
|
+
radio.checked = true;
|
|
189
|
+
radio.dispatchEvent(new CustomEvent('bds-change', {
|
|
190
|
+
detail: { value: radio.value, checked: true },
|
|
191
|
+
bubbles: true,
|
|
192
|
+
composed: true,
|
|
193
|
+
}));
|
|
120
194
|
}
|
|
121
195
|
|
|
122
196
|
private _handleChange(e: Event) {
|
|
123
|
-
|
|
197
|
+
const isChecked = (e.target as HTMLInputElement).checked;
|
|
198
|
+
if (isChecked) {
|
|
199
|
+
this._selectRadio(this);
|
|
200
|
+
} else {
|
|
201
|
+
this.checked = false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private _handleKeydown = (e: KeyboardEvent) => {
|
|
206
|
+
if (this.disabled) return;
|
|
207
|
+
if (!['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft'].includes(e.key)) return;
|
|
208
|
+
|
|
209
|
+
const group = this._getGroupMembers().filter(member => !member.disabled);
|
|
210
|
+
if (group.length < 2) return;
|
|
211
|
+
|
|
212
|
+
e.preventDefault();
|
|
213
|
+
const currentIndex = group.indexOf(this);
|
|
214
|
+
const direction = e.key === 'ArrowDown' || e.key === 'ArrowRight' ? 1 : -1;
|
|
215
|
+
const next = group[(currentIndex + direction + group.length) % group.length];
|
|
216
|
+
|
|
217
|
+
this._selectRadio(next);
|
|
218
|
+
void next.updateComplete.then(() => {
|
|
219
|
+
next.shadowRoot?.querySelector<HTMLInputElement>('input')?.focus();
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/** Roving tabindex: only the checked member (or the first member if none is checked) is tabbable. */
|
|
224
|
+
private _isTabbable(): boolean {
|
|
225
|
+
const group = this._getGroupMembers();
|
|
226
|
+
if (group.length <= 1) return true;
|
|
227
|
+
const checkedMember = group.find(member => member.checked);
|
|
228
|
+
return checkedMember ? checkedMember === this : group[0] === this;
|
|
124
229
|
}
|
|
125
230
|
|
|
126
231
|
render() {
|
|
127
232
|
const id = `bds-radio-${this._uid}`;
|
|
233
|
+
const descriptionId = `${id}-description`;
|
|
128
234
|
return html`
|
|
129
235
|
<input
|
|
130
236
|
id=${id}
|
|
@@ -135,9 +241,16 @@ export class BdsRadio extends LitElement {
|
|
|
135
241
|
.checked=${this.checked}
|
|
136
242
|
?required=${this.required}
|
|
137
243
|
?disabled=${this.disabled}
|
|
244
|
+
tabindex=${this._isTabbable() ? 0 : -1}
|
|
245
|
+
aria-invalid=${this.error ? 'true' : 'false'}
|
|
246
|
+
aria-describedby=${this.description ? descriptionId : nothing}
|
|
138
247
|
@change=${this._handleChange}
|
|
248
|
+
@keydown=${this._handleKeydown}
|
|
139
249
|
/>
|
|
140
|
-
<
|
|
250
|
+
<div class="textWrapper">
|
|
251
|
+
<label for=${id}><slot></slot></label>
|
|
252
|
+
${this.description ? html`<span id=${descriptionId} class="description">${this.description}</span>` : ''}
|
|
253
|
+
</div>
|
|
141
254
|
`;
|
|
142
255
|
}
|
|
143
256
|
}
|
|
@@ -71,4 +71,59 @@ describe('bds-segmented-control', () => {
|
|
|
71
71
|
it('is form-associated', () => {
|
|
72
72
|
expect(BdsSegmentedControl.formAssociated).toBe(true);
|
|
73
73
|
});
|
|
74
|
+
|
|
75
|
+
it('fires a bds-change event with the selected value in detail', async () => {
|
|
76
|
+
const el = await fixture(`<bds-segmented-control name="view" options='${OPTIONS}'></bds-segmented-control>`);
|
|
77
|
+
const handler = vi.fn();
|
|
78
|
+
el.addEventListener('bds-change', handler);
|
|
79
|
+
const radios = [...el.shadowRoot!.querySelectorAll<HTMLInputElement>('input[type="radio"]')];
|
|
80
|
+
radios[0].dispatchEvent(new Event('change', { bubbles: true }));
|
|
81
|
+
expect(handler).toHaveBeenCalledOnce();
|
|
82
|
+
expect((handler.mock.calls[0][0] as CustomEvent).detail).toEqual({ value: 'list' });
|
|
83
|
+
cleanup(el);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('sets a string aria-disabled value on disabled link-mode options', async () => {
|
|
87
|
+
const navOptions = JSON.stringify([
|
|
88
|
+
{ value: 'home', label: 'Home', href: '/' },
|
|
89
|
+
{ value: 'about', label: 'About', href: '/about', disabled: true },
|
|
90
|
+
]);
|
|
91
|
+
const el = await fixture(`<bds-segmented-control value="home" options='${navOptions}'></bds-segmented-control>`);
|
|
92
|
+
const links = [...el.shadowRoot!.querySelectorAll('a')];
|
|
93
|
+
const disabledLink = links.find(a => a.textContent?.trim() === 'About')!;
|
|
94
|
+
const enabledLink = links.find(a => a.textContent?.trim() === 'Home')!;
|
|
95
|
+
expect(disabledLink.getAttribute('aria-disabled')).toBe('true');
|
|
96
|
+
expect(enabledLink.hasAttribute('aria-disabled')).toBe(false);
|
|
97
|
+
cleanup(el);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('restores the initial value attribute on form reset', async () => {
|
|
101
|
+
const el = await fixture(`<bds-segmented-control name="view" value="grid" options='${OPTIONS}'></bds-segmented-control>`) as BdsSegmentedControl;
|
|
102
|
+
el.value = 'list';
|
|
103
|
+
el.formResetCallback();
|
|
104
|
+
expect(el.value).toBe('grid');
|
|
105
|
+
cleanup(el);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('falls back to the first option on form reset when no initial value was set', async () => {
|
|
109
|
+
const el = await fixture(`<bds-segmented-control name="view" options='${OPTIONS}'></bds-segmented-control>`) as BdsSegmentedControl;
|
|
110
|
+
el.value = 'grid';
|
|
111
|
+
el.formResetCallback();
|
|
112
|
+
expect(el.value).toBe('list');
|
|
113
|
+
cleanup(el);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('exposes --control_count and --control_selected-index on the control for CSS-driven positioning', async () => {
|
|
117
|
+
const el = await fixture(`<bds-segmented-control name="view" value="grid" options='${OPTIONS}'></bds-segmented-control>`);
|
|
118
|
+
const control = el.shadowRoot!.querySelector<HTMLElement>('.control')!;
|
|
119
|
+
expect(control.style.getPropertyValue('--control_count')).toBe('3');
|
|
120
|
+
expect(control.style.getPropertyValue('--control_selected-index')).toBe('1');
|
|
121
|
+
cleanup(el);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('uses a focus-visible selector that can actually match (label wrapping the radio)', () => {
|
|
125
|
+
const cssText = BdsSegmentedControl.styles.toString();
|
|
126
|
+
expect(cssText).not.toContain('.item-label');
|
|
127
|
+
expect(cssText).toContain(':has(> .radio:focus-visible)');
|
|
128
|
+
});
|
|
74
129
|
});
|
|
@@ -23,7 +23,8 @@ export interface SegmentedOption {
|
|
|
23
23
|
* variant — "outline" (inset border on active item, default) | "filled" (sliding thumb)
|
|
24
24
|
*
|
|
25
25
|
* Events:
|
|
26
|
-
* change — fired when a new segment is selected (radio mode only)
|
|
26
|
+
* bds-change — fired when a new segment is selected (radio mode only); detail: { value }
|
|
27
|
+
* change — deprecated alias for bds-change, kept for backward compatibility (radio mode only)
|
|
27
28
|
*
|
|
28
29
|
* @example
|
|
29
30
|
* <bds-segmented-control
|
|
@@ -43,6 +44,16 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
43
44
|
static formAssociated = true;
|
|
44
45
|
|
|
45
46
|
static styles = css`
|
|
47
|
+
/* Shadow DOM does not inherit the global box-sizing reset, so set it
|
|
48
|
+
here; otherwise elements with an explicit size + padding size as
|
|
49
|
+
content-box and layouts drift from the React (light-DOM) versions. */
|
|
50
|
+
:host,
|
|
51
|
+
*,
|
|
52
|
+
*::before,
|
|
53
|
+
*::after {
|
|
54
|
+
box-sizing: border-box;
|
|
55
|
+
}
|
|
56
|
+
|
|
46
57
|
:host {
|
|
47
58
|
display: inline-flex;
|
|
48
59
|
}
|
|
@@ -53,25 +64,35 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
.control {
|
|
56
|
-
display: inline-flex;
|
|
57
67
|
position: relative;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
display: inline-grid;
|
|
69
|
+
grid-auto-flow: column;
|
|
70
|
+
grid-auto-columns: 1fr;
|
|
71
|
+
padding: var(--control_track-pad, var(--bds-space_xxs));
|
|
72
|
+
background-color: var(--control_track-bg, var(--segmented_color_bg, var(--bds-color_bg--subtle)));
|
|
73
|
+
border-radius: var(--control_radius, var(--bds-border_radius--full));
|
|
61
74
|
gap: 0;
|
|
75
|
+
--control_dir: 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:host(:dir(rtl)) .control {
|
|
79
|
+
--control_dir: -1;
|
|
62
80
|
}
|
|
63
81
|
|
|
64
|
-
/* Sliding thumb
|
|
82
|
+
/* Sliding thumb (filled variant) — positioned entirely via CSS custom properties
|
|
83
|
+
(--control_count / --control_selected-index, set inline from render()) so it
|
|
84
|
+
stays correct across RTL and resize without any JS measurement. */
|
|
65
85
|
.thumb {
|
|
66
86
|
position: absolute;
|
|
67
|
-
inset-block:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
inset-block: var(--control_track-pad, var(--bds-space_xxs));
|
|
88
|
+
inset-inline-start: var(--control_track-pad, var(--bds-space_xxs));
|
|
89
|
+
inline-size: calc((100% - 2 * var(--control_track-pad, var(--bds-space_xxs))) / var(--control_count, 1));
|
|
90
|
+
border-radius: var(--control_thumb-radius, var(--bds-border_radius--full));
|
|
91
|
+
background-color: var(--control_thumb-bg, var(--segmented_thumb-color, var(--bds-color_interactive)));
|
|
92
|
+
box-shadow: var(--control_thumb-shadow, var(--bds-shadow_s));
|
|
73
93
|
pointer-events: none;
|
|
74
|
-
|
|
94
|
+
transform: translateX(calc(var(--control_selected-index, 0) * var(--control_dir, 1) * 100%));
|
|
95
|
+
transition: transform var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
75
96
|
}
|
|
76
97
|
|
|
77
98
|
.radio {
|
|
@@ -84,6 +105,7 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
84
105
|
|
|
85
106
|
.item {
|
|
86
107
|
position: relative;
|
|
108
|
+
z-index: 1;
|
|
87
109
|
display: inline-flex;
|
|
88
110
|
align-items: center;
|
|
89
111
|
justify-content: center;
|
|
@@ -91,9 +113,9 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
91
113
|
font-size: var(--bds-font_size--body--s);
|
|
92
114
|
font-family: var(--bds-font_family--body);
|
|
93
115
|
font-weight: var(--bds-font_weight--semibold);
|
|
94
|
-
color: var(--segmented_color, var(--bds-color_on-bg));
|
|
116
|
+
color: var(--control_label-color, var(--segmented_color, var(--bds-color_on-bg)));
|
|
95
117
|
cursor: pointer;
|
|
96
|
-
border-radius:
|
|
118
|
+
border-radius: var(--control_thumb-radius, var(--bds-border_radius--full));
|
|
97
119
|
transition: color var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
98
120
|
user-select: none;
|
|
99
121
|
white-space: nowrap;
|
|
@@ -101,7 +123,7 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
101
123
|
}
|
|
102
124
|
|
|
103
125
|
.item.--active {
|
|
104
|
-
color: var(--segmented_color--active, var(--bds-color_on-interactive));
|
|
126
|
+
color: var(--control_label-color--active, var(--segmented_color--active, var(--bds-color_on-interactive)));
|
|
105
127
|
}
|
|
106
128
|
|
|
107
129
|
.item.--disabled {
|
|
@@ -109,21 +131,34 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
109
131
|
cursor: not-allowed;
|
|
110
132
|
}
|
|
111
133
|
|
|
112
|
-
|
|
134
|
+
/* Radio-mode items aren't directly focusable (the input is visually hidden inside
|
|
135
|
+
the label), so match focus-visible on the input itself via :has(); link-mode
|
|
136
|
+
items are focusable directly. */
|
|
137
|
+
.item:focus-visible,
|
|
138
|
+
.item:has(> .radio:focus-visible) {
|
|
113
139
|
outline: var(--bds-outline_default);
|
|
114
|
-
outline-offset: var(--bds-outline_offset);
|
|
140
|
+
outline-offset: calc(var(--bds-outline_offset) * -1);
|
|
141
|
+
border-radius: var(--control_thumb-radius, var(--bds-border_radius--full));
|
|
115
142
|
}
|
|
116
143
|
|
|
117
|
-
|
|
144
|
+
@media (hover: hover) and (pointer: fine) {
|
|
145
|
+
.item:not(.--active, .--disabled):hover {
|
|
146
|
+
color: var(--control_label-color--hover, var(--bds-color_on-bg));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Outline variant: sliding inset-border indicator (positioned like .thumb) */
|
|
118
151
|
.indicator {
|
|
119
152
|
position: absolute;
|
|
120
|
-
inset-block:
|
|
121
|
-
|
|
153
|
+
inset-block: var(--control_track-pad, var(--bds-space_xxs));
|
|
154
|
+
inset-inline-start: var(--control_track-pad, var(--bds-space_xxs));
|
|
155
|
+
inline-size: calc((100% - 2 * var(--control_track-pad, var(--bds-space_xxs))) / var(--control_count, 1));
|
|
156
|
+
border-radius: var(--control_thumb-radius, var(--bds-border_radius--full));
|
|
122
157
|
pointer-events: none;
|
|
123
158
|
z-index: 2;
|
|
124
159
|
display: none;
|
|
125
|
-
|
|
126
|
-
|
|
160
|
+
transform: translateX(calc(var(--control_selected-index, 0) * var(--control_dir, 1) * 100%));
|
|
161
|
+
transition: transform var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
127
162
|
}
|
|
128
163
|
|
|
129
164
|
/* Outline variant — no thumb, sliding inset-border indicator, interactive active color */
|
|
@@ -132,17 +167,17 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
132
167
|
}
|
|
133
168
|
|
|
134
169
|
:host([variant='outline']) .item {
|
|
135
|
-
background-color: var(--segmented_item-bg, transparent);
|
|
170
|
+
background-color: var(--control_item-bg, var(--segmented_item-bg, transparent));
|
|
136
171
|
}
|
|
137
172
|
|
|
138
173
|
:host([variant='outline']) .item.--active {
|
|
139
|
-
color: var(--segmented_color--active, var(--bds-color_interactive));
|
|
140
|
-
background-color: var(--segmented_item-bg--active, var(--bds-color_bg));
|
|
174
|
+
color: var(--control_label-color--active, var(--segmented_color--active, var(--bds-color_interactive)));
|
|
175
|
+
background-color: var(--control_item-bg--active, var(--segmented_item-bg--active, var(--bds-color_bg)));
|
|
141
176
|
}
|
|
142
177
|
|
|
143
178
|
:host([variant='outline']) .indicator {
|
|
144
179
|
display: block;
|
|
145
|
-
box-shadow: inset 0 0 0 2px var(--bds-color_interactive);
|
|
180
|
+
box-shadow: inset 0 0 0 var(--control_indicator-width, 2px) var(--control_indicator-color, var(--bds-color_interactive));
|
|
146
181
|
}
|
|
147
182
|
|
|
148
183
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -169,6 +204,7 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
169
204
|
|
|
170
205
|
private _internals!: ElementInternals;
|
|
171
206
|
private readonly _uid = Math.random().toString(36).slice(2, 8);
|
|
207
|
+
private _initialValue = '';
|
|
172
208
|
|
|
173
209
|
constructor() {
|
|
174
210
|
super();
|
|
@@ -180,6 +216,11 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
180
216
|
this.variant = 'outline';
|
|
181
217
|
}
|
|
182
218
|
|
|
219
|
+
connectedCallback() {
|
|
220
|
+
super.connectedCallback();
|
|
221
|
+
this._initialValue = this.value;
|
|
222
|
+
}
|
|
223
|
+
|
|
183
224
|
private get _options(): SegmentedOption[] {
|
|
184
225
|
try {
|
|
185
226
|
return JSON.parse(this.options) as SegmentedOption[];
|
|
@@ -192,52 +233,33 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
192
233
|
super.updated(changed);
|
|
193
234
|
if (changed.has('value') || changed.has('options')) {
|
|
194
235
|
this._internals.setFormValue?.(this.value || null);
|
|
195
|
-
if (this.variant === 'filled') this._updateThumb();
|
|
196
|
-
if (this.variant === 'outline') this._updateIndicator();
|
|
197
|
-
}
|
|
198
|
-
if (changed.has('variant')) {
|
|
199
|
-
if (this.variant === 'filled') this._updateThumb();
|
|
200
|
-
if (this.variant === 'outline') this._updateIndicator();
|
|
201
236
|
}
|
|
202
237
|
}
|
|
203
238
|
|
|
204
|
-
private _positionSlider(el: HTMLElement | null | undefined, items: NodeListOf<HTMLElement>, selectedIndex: number) {
|
|
205
|
-
if (!el || items.length === 0) return;
|
|
206
|
-
const item = items[selectedIndex];
|
|
207
|
-
if (!item) return;
|
|
208
|
-
const controlRect = (item.parentElement as HTMLElement).getBoundingClientRect();
|
|
209
|
-
const itemRect = item.getBoundingClientRect();
|
|
210
|
-
el.style.insetInlineStart = `${itemRect.left - controlRect.left}px`;
|
|
211
|
-
el.style.inlineSize = `${itemRect.width}px`;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
private _updateThumb() {
|
|
215
|
-
const selectedIndex = Math.max(0, this._options.findIndex(o => o.value === this.value));
|
|
216
|
-
const items = this.shadowRoot?.querySelectorAll<HTMLElement>('.item');
|
|
217
|
-
this._positionSlider(this.shadowRoot?.querySelector<HTMLElement>('.thumb'), items!, selectedIndex);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private _updateIndicator() {
|
|
221
|
-
const selectedIndex = Math.max(0, this._options.findIndex(o => o.value === this.value));
|
|
222
|
-
const items = this.shadowRoot?.querySelectorAll<HTMLElement>('.item');
|
|
223
|
-
this._positionSlider(this.shadowRoot?.querySelector<HTMLElement>('.indicator'), items!, selectedIndex);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
239
|
formResetCallback() {
|
|
227
|
-
const
|
|
228
|
-
this.value =
|
|
240
|
+
const fallback = this._options[0]?.value ?? '';
|
|
241
|
+
this.value = this._initialValue || fallback;
|
|
229
242
|
this._internals.setFormValue?.(this.value || null);
|
|
230
243
|
}
|
|
231
244
|
|
|
232
245
|
private _handleChange(optionValue: string) {
|
|
233
246
|
this.value = optionValue;
|
|
247
|
+
this.dispatchEvent(new CustomEvent('bds-change', {
|
|
248
|
+
detail: { value: optionValue },
|
|
249
|
+
bubbles: true,
|
|
250
|
+
composed: true,
|
|
251
|
+
}));
|
|
252
|
+
// Deprecated: kept for backward compatibility, prefer 'bds-change'.
|
|
234
253
|
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
235
254
|
}
|
|
236
255
|
|
|
237
256
|
render() {
|
|
238
257
|
const opts = this._options;
|
|
258
|
+
const selectedIndex = Math.max(0, opts.findIndex(o => o.value === this.value));
|
|
259
|
+
const controlStyle = `--control_count: ${Math.max(opts.length, 1)}; --control_selected-index: ${selectedIndex}`;
|
|
260
|
+
|
|
239
261
|
return html`
|
|
240
|
-
<div class="control" role="group">
|
|
262
|
+
<div class="control" role="group" style=${controlStyle}>
|
|
241
263
|
<span class="thumb" aria-hidden="true"></span>
|
|
242
264
|
<span class="indicator" aria-hidden="true"></span>
|
|
243
265
|
${opts.map((opt, i) => {
|
|
@@ -251,7 +273,7 @@ export class BdsSegmentedControl extends LitElement {
|
|
|
251
273
|
class=${itemClass}
|
|
252
274
|
href=${isDisabled ? nothing : opt.href}
|
|
253
275
|
aria-current=${isActive ? 'page' : nothing}
|
|
254
|
-
|
|
276
|
+
aria-disabled=${isDisabled ? 'true' : nothing}
|
|
255
277
|
>${opt.label}</a>
|
|
256
278
|
`;
|
|
257
279
|
}
|
|
@@ -71,4 +71,61 @@ describe('bds-select', () => {
|
|
|
71
71
|
it('is form-associated', () => {
|
|
72
72
|
expect(BdsSelect.formAssociated).toBe(true);
|
|
73
73
|
});
|
|
74
|
+
|
|
75
|
+
it('fires a composed bds-change event that reaches a host-level listener', async () => {
|
|
76
|
+
const el = await fixture(`<bds-select name="country" options='${OPTIONS}'></bds-select>`);
|
|
77
|
+
const values: string[] = [];
|
|
78
|
+
let composed = false;
|
|
79
|
+
el.addEventListener('bds-change', (e: Event) => {
|
|
80
|
+
composed = (e as CustomEvent).composed;
|
|
81
|
+
values.push((e as CustomEvent).detail.value);
|
|
82
|
+
});
|
|
83
|
+
const select = el.shadowRoot!.querySelector<HTMLSelectElement>('select')!;
|
|
84
|
+
select.value = 'be';
|
|
85
|
+
select.dispatchEvent(new Event('change', { bubbles: true }));
|
|
86
|
+
expect(values).toEqual(['be']);
|
|
87
|
+
expect(composed).toBe(true);
|
|
88
|
+
cleanup(el);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('renders a label when label attribute is set, associated via for/id', async () => {
|
|
92
|
+
const el = await fixture(`<bds-select name="country" label="Country" options='${OPTIONS}'></bds-select>`);
|
|
93
|
+
const label = el.shadowRoot!.querySelector('label')!;
|
|
94
|
+
const select = el.shadowRoot!.querySelector('select')!;
|
|
95
|
+
expect(label.textContent?.trim()).toContain('Country');
|
|
96
|
+
expect(select.id).toBeTruthy();
|
|
97
|
+
expect(label.getAttribute('for')).toBe(select.id);
|
|
98
|
+
cleanup(el);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('forwards a host aria-label to the inner select when no label attribute is set', async () => {
|
|
102
|
+
const el = await fixture(`<bds-select name="country" aria-label="Country" options='${OPTIONS}'></bds-select>`);
|
|
103
|
+
const select = el.shadowRoot!.querySelector('select')!;
|
|
104
|
+
expect(select.getAttribute('aria-label')).toBe('Country');
|
|
105
|
+
cleanup(el);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('does not set aria-label on the inner select when a label attribute is present', async () => {
|
|
109
|
+
const el = await fixture(`<bds-select name="country" label="Country" aria-label="Ignored" options='${OPTIONS}'></bds-select>`);
|
|
110
|
+
const select = el.shadowRoot!.querySelector('select')!;
|
|
111
|
+
expect(select.hasAttribute('aria-label')).toBe(false);
|
|
112
|
+
cleanup(el);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('renders error message and sets aria-invalid/aria-describedby when error is set', async () => {
|
|
116
|
+
const el = await fixture(`<bds-select name="country" error="Please choose a country" options='${OPTIONS}'></bds-select>`);
|
|
117
|
+
const select = el.shadowRoot!.querySelector('select')!;
|
|
118
|
+
const errorMsg = el.shadowRoot!.querySelector('.message--error');
|
|
119
|
+
expect(select.getAttribute('aria-invalid')).toBe('true');
|
|
120
|
+
expect(errorMsg?.textContent?.trim()).toBe('Please choose a country');
|
|
121
|
+
expect(select.getAttribute('aria-describedby')).toContain('-error');
|
|
122
|
+
cleanup(el);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('renders hint message when hint is set (no error)', async () => {
|
|
126
|
+
const el = await fixture(`<bds-select name="country" hint="Pick your country" options='${OPTIONS}'></bds-select>`);
|
|
127
|
+
const hint = el.shadowRoot!.querySelector('.message--hint');
|
|
128
|
+
expect(hint?.textContent?.trim()).toBe('Pick your country');
|
|
129
|
+
cleanup(el);
|
|
130
|
+
});
|
|
74
131
|
});
|