@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,10 +1,5 @@
|
|
|
1
1
|
@layer boostdev.component {
|
|
2
2
|
.switchGroup {
|
|
3
|
-
--switch_thumb-size: 1.25em;
|
|
4
|
-
--switch_track-pad: var(--bds-space_xxxs);
|
|
5
|
-
--switch_track-height: calc(var(--switch_thumb-size) + var(--switch_track-pad) * 2);
|
|
6
|
-
--switch_track-width: calc(var(--switch_thumb-size) * 2 + var(--switch_track-pad) * 2);
|
|
7
|
-
|
|
8
3
|
color: var(--switch_color, var(--bds-color_on-bg));
|
|
9
4
|
display: flex;
|
|
10
5
|
flex-direction: column;
|
|
@@ -25,8 +20,8 @@
|
|
|
25
20
|
display: inline-flex;
|
|
26
21
|
align-items: center;
|
|
27
22
|
flex-shrink: 0;
|
|
28
|
-
inline-size: var(--switch_track-
|
|
29
|
-
block-size: var(--switch_track-
|
|
23
|
+
inline-size: calc(var(--switch_thumb-size, 1.25em) * 2 + var(--switch_track-pad, var(--bds-space_xxxs)) * 2);
|
|
24
|
+
block-size: calc(var(--switch_thumb-size, 1.25em) + var(--switch_track-pad, var(--bds-space_xxxs)) * 2);
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
/* Real input — invisible overlay to capture pointer/keyboard events */
|
|
@@ -50,11 +45,11 @@
|
|
|
50
45
|
.track {
|
|
51
46
|
display: inline-flex;
|
|
52
47
|
align-items: center;
|
|
53
|
-
inline-size: var(--switch_track-
|
|
54
|
-
block-size: var(--switch_track-
|
|
48
|
+
inline-size: calc(var(--switch_thumb-size, 1.25em) * 2 + var(--switch_track-pad, var(--bds-space_xxxs)) * 2);
|
|
49
|
+
block-size: calc(var(--switch_thumb-size, 1.25em) + var(--switch_track-pad, var(--bds-space_xxxs)) * 2);
|
|
55
50
|
border-radius: var(--switch_track-radius, var(--bds-border_radius--full));
|
|
56
51
|
background-color: var(--switch_track-bg, var(--bds-color_grey--subtle));
|
|
57
|
-
padding-inline: var(--switch_track-pad);
|
|
52
|
+
padding-inline: var(--switch_track-pad, var(--bds-space_xxxs));
|
|
58
53
|
pointer-events: none;
|
|
59
54
|
box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--switch_shadow, var(--bdc-outline_shadow));
|
|
60
55
|
transition: --bdc_color var(--bds-animation_transition-duration) var(--bds-animation_easing),
|
|
@@ -67,8 +62,8 @@
|
|
|
67
62
|
/* Thumb */
|
|
68
63
|
.thumb {
|
|
69
64
|
display: block;
|
|
70
|
-
inline-size: var(--switch_thumb-size);
|
|
71
|
-
block-size: var(--switch_thumb-size);
|
|
65
|
+
inline-size: var(--switch_thumb-size, 1.25em);
|
|
66
|
+
block-size: var(--switch_thumb-size, 1.25em);
|
|
72
67
|
border-radius: var(--switch_thumb-radius, var(--bds-border_radius--circle));
|
|
73
68
|
background-color: var(--switch_thumb-bg, var(--bds-color_interactive));
|
|
74
69
|
box-shadow: var(--bds-shadow_s);
|
|
@@ -90,7 +85,11 @@
|
|
|
90
85
|
|
|
91
86
|
.switch:checked + .track .thumb {
|
|
92
87
|
background-color: var(--switch_thumb-bg--active, var(--bds-color_interactive));
|
|
93
|
-
transform: translateX(var(--switch_thumb-size));
|
|
88
|
+
transform: translateX(var(--switch_thumb-size, 1.25em));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[dir='rtl'] .switch:checked + .track .thumb {
|
|
92
|
+
transform: translateX(calc(var(--switch_thumb-size, 1.25em) * -1));
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
/* Focus visible on the visual track */
|
|
@@ -68,4 +68,24 @@ describe('Switch', () => {
|
|
|
68
68
|
render(<Switch label="Toggle" name="size-l" size="large" />);
|
|
69
69
|
expect(screen.getByRole('switch').closest('.switchGroup')).toHaveClass('--size_large');
|
|
70
70
|
});
|
|
71
|
+
|
|
72
|
+
it('sets aria-invalid when an error is present', () => {
|
|
73
|
+
render(<Switch label="Accept" name="accept" error="Required" />);
|
|
74
|
+
expect(screen.getByRole('switch')).toHaveAttribute('aria-invalid', 'true');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('does not set aria-invalid when there is no error', () => {
|
|
78
|
+
render(<Switch label="Accept" name="accept" />);
|
|
79
|
+
expect(screen.getByRole('switch')).toHaveAttribute('aria-invalid', 'false');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('keeps the label associated with the input when a consumer id is passed', () => {
|
|
83
|
+
render(<Switch label="Toggle" name="toggle" id="custom-switch-id" />);
|
|
84
|
+
expect(screen.getByLabelText('Toggle')).toBeInTheDocument();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('keeps role="switch" even when a consumer role is passed', () => {
|
|
88
|
+
render(<Switch label="Toggle" name="toggle" role="checkbox" />);
|
|
89
|
+
expect(screen.getByRole('switch')).toBeInTheDocument();
|
|
90
|
+
});
|
|
71
91
|
});
|
|
@@ -36,13 +36,14 @@ export function Switch({
|
|
|
36
36
|
{prefix && <span>{prefix}</span>}
|
|
37
37
|
<div className={css.trackWrapper}>
|
|
38
38
|
<input
|
|
39
|
+
{...props}
|
|
39
40
|
type="checkbox"
|
|
40
41
|
role="switch"
|
|
41
42
|
id={id}
|
|
42
43
|
name={name}
|
|
43
44
|
aria-describedby={describedBy}
|
|
45
|
+
aria-invalid={!!error}
|
|
44
46
|
className={cn(css.switch, error ? css.switchError : undefined)}
|
|
45
|
-
{...props}
|
|
46
47
|
/>
|
|
47
48
|
<span className={css.track} aria-hidden="true">
|
|
48
49
|
<span className={css.thumb} />
|
|
@@ -47,6 +47,11 @@ Multi-line text input with label, hint, and error support.
|
|
|
47
47
|
<tr><td>`--textarea_border`</td><td>`none`</td><td>Border</td></tr>
|
|
48
48
|
<tr><td>`--textarea_radius`</td><td>`var(--bdc-outline_radius--l)` (1.5em)</td><td>Corner radius</td></tr>
|
|
49
49
|
<tr><td>`--textarea_shadow`</td><td>`var(--bdc-outline_shadow)`</td><td>Box shadow</td></tr>
|
|
50
|
+
<tr><td>`--textarea_padding`</td><td>`var(--bds-space_s)`</td><td>Inner padding</td></tr>
|
|
51
|
+
<tr><td>`--textarea_font-family`</td><td>`var(--bds-font_family--body)`</td><td>Font family</td></tr>
|
|
52
|
+
<tr><td>`--textarea_font-size`</td><td>`var(--bds-font_size--body)`</td><td>Font size</td></tr>
|
|
53
|
+
<tr><td>`--textarea_line-height`</td><td>`var(--bds-font_line-height--body)`</td><td>Line height</td></tr>
|
|
54
|
+
<tr><td>`--textarea_min-block-size`</td><td>`calc(var(--bds-space_m) * 5)`</td><td>Minimum height</td></tr>
|
|
50
55
|
</tbody>
|
|
51
56
|
</table>
|
|
52
57
|
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
.textarea {
|
|
8
|
-
font-family: var(--bds-font_family--body);
|
|
9
|
-
font-size: var(--bds-font_size--body);
|
|
10
|
-
line-height: var(--bds-font_line-height--body);
|
|
11
|
-
padding: var(--bds-space_s);
|
|
8
|
+
font-family: var(--textarea_font-family, var(--bds-font_family--body));
|
|
9
|
+
font-size: var(--textarea_font-size, var(--bds-font_size--body));
|
|
10
|
+
line-height: var(--textarea_line-height, var(--bds-font_line-height--body));
|
|
11
|
+
padding: var(--textarea_padding, var(--bds-space_s));
|
|
12
12
|
border: var(--textarea_border, none);
|
|
13
13
|
--bdc_color: currentcolor;
|
|
14
14
|
--bdc-outline_radius: var(--bdc-outline_radius--l);
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
background-color: var(--textarea_color_bg, var(--bds-color_bg));
|
|
19
19
|
color: var(--textarea_color, var(--bds-color_on-bg));
|
|
20
20
|
resize: vertical;
|
|
21
|
-
min-block-size: calc(var(--bds-space_m) * 5);
|
|
21
|
+
min-block-size: var(--textarea_min-block-size, calc(var(--bds-space_m) * 5));
|
|
22
22
|
transition: --bdc_color var(--bds-animation_transition-duration) var(--bds-animation_easing),
|
|
23
23
|
background-color var(--bds-animation_transition-duration) var(--bds-animation_easing);
|
|
24
24
|
}
|
|
@@ -50,4 +50,17 @@ describe('Textarea', () => {
|
|
|
50
50
|
render(<Textarea label="Message" name="message" rows={6} />);
|
|
51
51
|
expect(screen.getByRole('textbox')).toHaveAttribute('rows', '6');
|
|
52
52
|
});
|
|
53
|
+
|
|
54
|
+
it('keeps the label and message wired to a consumer-provided id', () => {
|
|
55
|
+
render(
|
|
56
|
+
<Textarea label="Message" name="message" id="custom-id" hint="Max 500 characters" error="Required" />
|
|
57
|
+
);
|
|
58
|
+
const textarea = screen.getByLabelText('Message');
|
|
59
|
+
expect(textarea).toHaveAttribute('id', 'custom-id');
|
|
60
|
+
const describedBy = textarea.getAttribute('aria-describedby');
|
|
61
|
+
expect(describedBy).toBeTruthy();
|
|
62
|
+
describedBy
|
|
63
|
+
?.split(' ')
|
|
64
|
+
.forEach((describedById) => expect(describedById.startsWith('custom-id')).toBe(true));
|
|
65
|
+
});
|
|
53
66
|
});
|
|
@@ -20,9 +20,11 @@ export function Textarea({
|
|
|
20
20
|
hint,
|
|
21
21
|
className,
|
|
22
22
|
required,
|
|
23
|
+
id: idProp,
|
|
23
24
|
...props
|
|
24
25
|
}: Readonly<TextareaProps>) {
|
|
25
|
-
const
|
|
26
|
+
const generatedId = useId();
|
|
27
|
+
const id = idProp ?? name + generatedId;
|
|
26
28
|
const hintId = id + 'hint';
|
|
27
29
|
const errorId = id + 'error';
|
|
28
30
|
const describedBy = [error && errorId, hint && hintId].filter(Boolean).join(' ') || undefined;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { Message } from './Message';
|
|
3
|
+
|
|
4
|
+
describe('Message', () => {
|
|
5
|
+
it('renders nothing when message is undefined', () => {
|
|
6
|
+
const { container } = render(<Message inputId="field-1" type="hint" message={undefined} />);
|
|
7
|
+
expect(container).toBeEmptyDOMElement();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('renders the message text', () => {
|
|
11
|
+
render(<Message inputId="field-1" type="hint" message="At least 8 characters." />);
|
|
12
|
+
expect(screen.getByText('At least 8 characters.')).toBeInTheDocument();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('exposes an error message via role=alert so it is announced to assistive tech', () => {
|
|
16
|
+
render(<Message inputId="field-1" type="error" message="This field is required." />);
|
|
17
|
+
expect(screen.getByRole('alert')).toHaveTextContent('This field is required.');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('does not expose a hint message as an alert', () => {
|
|
21
|
+
render(<Message inputId="field-1" type="hint" message="Optional hint." />);
|
|
22
|
+
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('sets the message id to inputId concatenated with type', () => {
|
|
26
|
+
render(<Message inputId="field-1" type="error" message="Required" />);
|
|
27
|
+
expect(screen.getByRole('alert')).toHaveAttribute('id', 'field-1error');
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -12,7 +12,7 @@ export const Message = ({ message, type, inputId, className }: MessageProps) =>
|
|
|
12
12
|
if (!message) return null;
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
|
-
<p id={inputId + type} className={cn(css[type], className)}>
|
|
15
|
+
<p id={inputId + type} role={type === 'error' ? 'alert' : undefined} className={cn(css[type], className)}>
|
|
16
16
|
{message}
|
|
17
17
|
</p>
|
|
18
18
|
);
|
|
@@ -45,6 +45,17 @@ Layout wrapper that arranges `Button` children according to a contextual variant
|
|
|
45
45
|
|
|
46
46
|
<ArgTypes of={Stories} />
|
|
47
47
|
|
|
48
|
+
## CSS variables
|
|
49
|
+
|
|
50
|
+
<table>
|
|
51
|
+
<thead>
|
|
52
|
+
<tr><th>Variable</th><th>Default</th><th>Description</th></tr>
|
|
53
|
+
</thead>
|
|
54
|
+
<tbody>
|
|
55
|
+
<tr><td>`--buttonGroup_gap`</td><td>`var(--bds-space_l)`</td><td>Gap between buttons.</td></tr>
|
|
56
|
+
</tbody>
|
|
57
|
+
</table>
|
|
58
|
+
|
|
48
59
|
## Accessibility
|
|
49
60
|
|
|
50
61
|
- Renders as `<div role="group">` — no additional ARIA needed for the wrapper
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
position: relative;
|
|
11
11
|
display: flex;
|
|
12
12
|
flex-direction: column-reverse;
|
|
13
|
-
gap: var(--bds-space_l);
|
|
13
|
+
gap: var(--buttonGroup_gap, var(--bds-space_l));
|
|
14
14
|
align-items: center;
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -51,10 +51,6 @@
|
|
|
51
51
|
justify-content: flex-start;
|
|
52
52
|
align-items: center;
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
.buttonGroup.--variant_grid .container {
|
|
56
|
-
justify-content: center;
|
|
57
|
-
}
|
|
58
54
|
}
|
|
59
55
|
}
|
|
60
56
|
}
|
|
@@ -20,6 +20,20 @@ const TwoButtons = () => (
|
|
|
20
20
|
</>
|
|
21
21
|
);
|
|
22
22
|
|
|
23
|
+
const ThreeButtons = () => (
|
|
24
|
+
<>
|
|
25
|
+
<Button variant="outline">Back</Button>
|
|
26
|
+
<Button variant="outline">Save draft</Button>
|
|
27
|
+
<Button variant="default">Publish</Button>
|
|
28
|
+
</>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
/** Two actions — the common Cancel / Confirm row. */
|
|
32
|
+
export const TwoButtonsExample: Story = { render: () => <ButtonContainer variant="modal"><TwoButtons /></ButtonContainer> };
|
|
33
|
+
|
|
34
|
+
/** Three actions. */
|
|
35
|
+
export const ThreeButtonsExample: Story = { render: () => <ButtonContainer variant="content"><ThreeButtons /></ButtonContainer> };
|
|
36
|
+
|
|
23
37
|
export const Default: Story = { render: () => <ButtonContainer><TwoButtons /></ButtonContainer> };
|
|
24
38
|
export const Flow: Story = { render: () => <ButtonContainer variant="flow"><TwoButtons /></ButtonContainer> };
|
|
25
39
|
export const Card: Story = { render: () => <ButtonContainer variant="card"><TwoButtons /></ButtonContainer> };
|
|
@@ -54,6 +54,9 @@ Contained surface for grouping related content. Three visual variants provide di
|
|
|
54
54
|
<tr><td>`--card_on-color`</td><td>`var(--bds-color_on-bg)`</td><td>Card text colour.</td></tr>
|
|
55
55
|
<tr><td>`--card_padding`</td><td>varies by `padding` prop</td><td>Card padding (overrides the prop default).</td></tr>
|
|
56
56
|
<tr><td>`--card_border`</td><td>`none`</td><td>Border (outlined variant).</td></tr>
|
|
57
|
+
<tr><td>`--card_radius`</td><td>`var(--bds-border_radius--m)`</td><td>Card corner radius.</td></tr>
|
|
58
|
+
<tr><td>`--card_transition`</td><td>`var(--bds-animation_transition)`</td><td>Transition applied to colour/shadow/transform changes.</td></tr>
|
|
59
|
+
<tr><td>`--card_shadow--active`</td><td>`var(--bds-shadow_s)`</td><td>Box-shadow while a clickable card is pressed (`:active`).</td></tr>
|
|
57
60
|
</tbody>
|
|
58
61
|
</table>
|
|
59
62
|
|
|
@@ -76,6 +79,8 @@ Plus `--card_shadow--clickable-hover` (`var(--bds-shadow_xl)`) for hover on any
|
|
|
76
79
|
## Accessibility
|
|
77
80
|
|
|
78
81
|
- Static card renders as `<div>` — no interactive role
|
|
79
|
-
- Clickable card renders as `<button>` — keyboard and screen reader accessible
|
|
82
|
+
- Clickable card renders as `<button>` — keyboard and screen reader accessible, with browser UA button styling (font, alignment, border, width) reset to match a non-interactive card
|
|
83
|
+
- Focus-visible ring on a clickable card uses `--bds-outline_default` / `--bds-outline_offset` (the same focus treatment as every other interactive component)
|
|
84
|
+
- The hover lift and colour/shadow transitions respect `prefers-reduced-motion` — both are disabled when the user has opted out
|
|
80
85
|
- When using `as="a"`, provide a valid `href`; when using a router `Link`, ensure it forwards `className` and `children`
|
|
81
86
|
- Ensure clickable cards have a meaningful accessible name (via visible text content)
|
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
.card {
|
|
3
3
|
background-color: var(--card_color, var(--bds-color_bg));
|
|
4
4
|
color: var(--card_on-color, var(--bds-color_on-bg));
|
|
5
|
-
border-radius: var(--bds-border_radius--m);
|
|
6
|
-
transition:
|
|
5
|
+
border-radius: var(--card_radius, var(--bds-border_radius--m));
|
|
6
|
+
transition: var(--card_transition, var(--bds-animation_transition));
|
|
7
7
|
position: relative;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/* Clickable cards render as <button> — normalize UA button styles so it
|
|
11
|
+
looks and lays out identically to a non-interactive card. */
|
|
12
|
+
.card:is(button) {
|
|
13
|
+
border: none;
|
|
14
|
+
font: inherit;
|
|
15
|
+
text-align: inherit;
|
|
16
|
+
display: block;
|
|
17
|
+
inline-size: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
/* Resting shadows — consumers can override per-variant via
|
|
11
21
|
--card_shadow--default / --card_shadow--elevated / --card_shadow--outlined. */
|
|
12
22
|
.card.--default {
|
|
@@ -61,13 +71,13 @@
|
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
.card.--clickable:focus-visible {
|
|
64
|
-
outline:
|
|
65
|
-
outline-offset:
|
|
74
|
+
outline: var(--bds-outline_default);
|
|
75
|
+
outline-offset: var(--bds-outline_offset);
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
.card.--clickable:active {
|
|
69
79
|
transform: translateY(0);
|
|
70
|
-
box-shadow: var(--bds-shadow_s);
|
|
80
|
+
box-shadow: var(--card_shadow--active, var(--bds-shadow_s));
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
@media (hover: hover) and (pointer: fine) {
|
|
@@ -88,4 +98,15 @@
|
|
|
88
98
|
box-shadow: var(--card_shadow--outlined-hover, var(--bds-shadow_s));
|
|
89
99
|
}
|
|
90
100
|
}
|
|
101
|
+
|
|
102
|
+
@media (prefers-reduced-motion: reduce) {
|
|
103
|
+
.card {
|
|
104
|
+
transition: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.card.--clickable:hover,
|
|
108
|
+
.card.--clickable:active {
|
|
109
|
+
transform: none;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
91
112
|
}
|
|
@@ -18,6 +18,13 @@ describe('Card', () => {
|
|
|
18
18
|
expect(screen.getByRole('button')).toBeInTheDocument();
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
it('keeps the card class on the button so UA button styles are normalized', () => {
|
|
22
|
+
render(<Card onClick={() => {}}>Clickable</Card>);
|
|
23
|
+
// The `.card:is(button)` rule (font/text-align/display/border reset) only
|
|
24
|
+
// applies if the rendered <button> still carries the base `card` class.
|
|
25
|
+
expect(screen.getByRole('button')).toHaveClass('card');
|
|
26
|
+
});
|
|
27
|
+
|
|
21
28
|
it('calls onClick when clicked', async () => {
|
|
22
29
|
const user = userEvent.setup();
|
|
23
30
|
const onClick = vi.fn();
|
|
@@ -3,14 +3,15 @@ import css from './Card.module.css';
|
|
|
3
3
|
import { cn } from '@boostdev/design-system-foundation';
|
|
4
4
|
import type { WithClassName } from '../../../types';
|
|
5
5
|
|
|
6
|
-
type CardOwnProps = WithClassName & {
|
|
6
|
+
type CardOwnProps<C extends ElementType> = WithClassName & {
|
|
7
7
|
variant?: 'default' | 'elevated' | 'outlined';
|
|
8
8
|
padding?: 'none' | 'small' | 'medium' | 'large' | 'extra-large';
|
|
9
9
|
textAlign?: 'start' | 'center' | 'end';
|
|
10
|
-
as?:
|
|
10
|
+
as?: C;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
type CardProps<C extends ElementType = 'div'> = CardOwnProps
|
|
13
|
+
type CardProps<C extends ElementType = 'div'> = CardOwnProps<C> &
|
|
14
|
+
Omit<ComponentPropsWithoutRef<C>, keyof CardOwnProps<C>>;
|
|
14
15
|
|
|
15
16
|
export function Card<C extends ElementType = 'div'>({
|
|
16
17
|
children,
|
|
@@ -402,6 +402,50 @@ describe('applyMasonryLayout', () => {
|
|
|
402
402
|
expect(a.style.gridColumn).toBe('var(--bds-grid_span-100)');
|
|
403
403
|
});
|
|
404
404
|
|
|
405
|
+
it('accounts for a row wrap when an explicit-span item does not fit the remaining columns', () => {
|
|
406
|
+
// Regression: the demotion cursor advanced by `col + consumed` even when
|
|
407
|
+
// `consumed` overflowed the remaining row space. CSS Grid's `dense`
|
|
408
|
+
// auto-placement actually wraps a too-wide explicit item to the start of
|
|
409
|
+
// the next row, so the cursor must jump to `consumed`, not `col + consumed`.
|
|
410
|
+
const container = makeContainer(10);
|
|
411
|
+
container.style.gridTemplateColumns = '100px 100px 100px 100px';
|
|
412
|
+
const a = makeAutoItem(50);
|
|
413
|
+
const explicit = makeItem(50);
|
|
414
|
+
explicit.style.gridColumn = 'span 3';
|
|
415
|
+
const b = makeAutoItem(50);
|
|
416
|
+
container.append(a, explicit, b);
|
|
417
|
+
// 'half' in a 4-col grid → 2 cols (fraction fallback).
|
|
418
|
+
applyMasonryLayout(container, [a, explicit, b], { preferredColumnSpan: 'half' });
|
|
419
|
+
expect(a.style.gridColumn).toBe('span 2'); // cols 0-1, cursor -> 2
|
|
420
|
+
expect(explicit.style.gridColumn).toBe('span 3'); // doesn't fit remaining 2 cols -> wraps, cursor -> 3
|
|
421
|
+
expect(b.style.gridColumn).toBe('span 1'); // only 1 col remains in the wrapped row -> demoted
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it('refreshes the restore snapshot when something else rewrites the item inline gridColumn between runs', () => {
|
|
425
|
+
// Regression: GridItem's `columnSpan="auto"` re-renders (e.g. once an
|
|
426
|
+
// image's aspect ratio resolves) overwrite the inline `gridColumn` the
|
|
427
|
+
// polyfill previously wrote. The polyfill only snapshotted the ORIGINAL
|
|
428
|
+
// value once, so it never picked up React's fresh value — unsetting
|
|
429
|
+
// `masonryPreferredColumnSpan` later restored the stale pre-resolve span.
|
|
430
|
+
const container = makeContainer(10);
|
|
431
|
+
container.style.gridTemplateColumns = '100px 100px 100px 100px';
|
|
432
|
+
const a = makeAutoItem(50);
|
|
433
|
+
a.style.gridColumn = 'span var(--bds-grid_columns-25)'; // placeholder before media resolves
|
|
434
|
+
container.append(a);
|
|
435
|
+
|
|
436
|
+
applyMasonryLayout(container, [a], { preferredColumnSpan: 'half' });
|
|
437
|
+
expect(a.style.gridColumn).toBe('span 2');
|
|
438
|
+
|
|
439
|
+
// Simulate React re-rendering GridItem after the image resolves, which
|
|
440
|
+
// overwrites the inline style the polyfill wrote.
|
|
441
|
+
a.style.gridColumn = 'span var(--bds-grid_columns-50)';
|
|
442
|
+
applyMasonryLayout(container, [a], { preferredColumnSpan: 'half' });
|
|
443
|
+
expect(a.style.gridColumn).toBe('span 2'); // preferred span still wins while set
|
|
444
|
+
|
|
445
|
+
applyMasonryLayout(container, [a]); // preferredColumnSpan dropped
|
|
446
|
+
expect(a.style.gridColumn).toBe('span var(--bds-grid_columns-50)'); // restores the fresh value, not the stale placeholder
|
|
447
|
+
});
|
|
448
|
+
|
|
405
449
|
it('clearMasonryLayout restores gridColumn on data-column-span-auto items', () => {
|
|
406
450
|
const container = makeContainer(10);
|
|
407
451
|
container.style.gridTemplateColumns = '100px 100px 100px 100px';
|
|
@@ -34,7 +34,7 @@ export function getGridContext(): Context<GridContextValue> {
|
|
|
34
34
|
return _GridContext;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
type GridOwnProps = WithClassName & {
|
|
37
|
+
type GridOwnProps<C extends ElementType> = WithClassName & {
|
|
38
38
|
variant?: GridVariant;
|
|
39
39
|
columns?: number;
|
|
40
40
|
isCentered?: boolean;
|
|
@@ -68,11 +68,11 @@ type GridOwnProps = WithClassName & {
|
|
|
68
68
|
* you've confirmed the auto-tuner is wrong for your case.
|
|
69
69
|
*/
|
|
70
70
|
masonryRowUnitPx?: number;
|
|
71
|
-
as?:
|
|
71
|
+
as?: C;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
type GridProps<C extends ElementType = 'div'> = GridOwnProps &
|
|
75
|
-
Omit<ComponentPropsWithoutRef<C>, keyof GridOwnProps
|
|
74
|
+
type GridProps<C extends ElementType = 'div'> = GridOwnProps<C> &
|
|
75
|
+
Omit<ComponentPropsWithoutRef<C>, keyof GridOwnProps<C>>;
|
|
76
76
|
|
|
77
77
|
export function Grid<C extends ElementType = 'div'>({
|
|
78
78
|
children,
|
|
@@ -113,7 +113,7 @@ export function Grid<C extends ElementType = 'div'>({
|
|
|
113
113
|
const ctx = useMemo<GridContextValue>(() => ({ autoSpanMedia }), [autoSpanMedia]);
|
|
114
114
|
|
|
115
115
|
return (
|
|
116
|
-
<Component ref={ref} {...rest} className={classNames} style={composedStyle}>
|
|
116
|
+
<Component ref={ref as never} {...rest} className={classNames} style={composedStyle}>
|
|
117
117
|
<GridContext.Provider value={ctx}>{children}</GridContext.Provider>
|
|
118
118
|
</Component>
|
|
119
119
|
);
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
ComponentPropsWithoutRef,
|
|
4
4
|
CSSProperties,
|
|
5
5
|
useContext,
|
|
6
|
-
useLayoutEffect,
|
|
7
6
|
useRef,
|
|
8
7
|
useState,
|
|
9
8
|
} from 'react';
|
|
@@ -18,6 +17,7 @@ import {
|
|
|
18
17
|
readMediaAspect,
|
|
19
18
|
type AutoSpanResult,
|
|
20
19
|
} from './autoSpan';
|
|
20
|
+
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
|
|
21
21
|
|
|
22
22
|
export type GridItemSpanValue =
|
|
23
23
|
| 'full'
|
|
@@ -53,16 +53,16 @@ function resolveSpan(value: Exclude<GridItemSpanValue, 'auto'>): string {
|
|
|
53
53
|
return SPAN_VAR[value];
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
type GridItemOwnProps = WithClassName & {
|
|
56
|
+
type GridItemOwnProps<C extends ElementType> = WithClassName & {
|
|
57
57
|
columnSpan?: GridItemSpanValue;
|
|
58
58
|
rowSpan?: number;
|
|
59
59
|
startColumn?: number;
|
|
60
60
|
endColumn?: number;
|
|
61
|
-
as?:
|
|
61
|
+
as?: C;
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
type GridItemProps<C extends ElementType = 'div'> = GridItemOwnProps &
|
|
65
|
-
Omit<ComponentPropsWithoutRef<C>, keyof GridItemOwnProps
|
|
64
|
+
type GridItemProps<C extends ElementType = 'div'> = GridItemOwnProps<C> &
|
|
65
|
+
Omit<ComponentPropsWithoutRef<C>, keyof GridItemOwnProps<C>>;
|
|
66
66
|
|
|
67
67
|
export function GridItem<C extends ElementType = 'div'>({
|
|
68
68
|
children,
|
|
@@ -82,7 +82,7 @@ export function GridItem<C extends ElementType = 'div'>({
|
|
|
82
82
|
const ref = useRef<HTMLElement | null>(null);
|
|
83
83
|
const [autoSpan, setAutoSpan] = useState<AutoSpanResult>('one-quarter');
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
useIsomorphicLayoutEffect(() => {
|
|
86
86
|
if (effectiveSpan !== 'auto') return;
|
|
87
87
|
const el = ref.current;
|
|
88
88
|
if (!el) return;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { RefObject
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
2
|
import type { GridItemSpanValue } from './GridItem';
|
|
3
|
+
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
|
|
3
4
|
|
|
4
5
|
type NamedSpan = Exclude<GridItemSpanValue, 'auto' | number>;
|
|
5
6
|
|
|
@@ -114,6 +115,17 @@ export type MasonryOptions = {
|
|
|
114
115
|
// items pinned to their polyfill-assigned span.
|
|
115
116
|
const ORIGINAL_COL_ATTR = 'data-bds-masonry-original-column';
|
|
116
117
|
|
|
118
|
+
// Data attribute caching the last `gridColumn` value the polyfill itself wrote
|
|
119
|
+
// for a preferred-span item. Used to detect drift: React re-renders a
|
|
120
|
+
// `data-column-span-auto` GridItem whenever its own computed span changes
|
|
121
|
+
// (e.g. `columnSpan="auto"` resolving after an image's aspect ratio loads),
|
|
122
|
+
// overwriting the inline `gridColumn` the polyfill previously set. Without
|
|
123
|
+
// this check, ORIGINAL_COL_ATTR would stay pinned to whatever value existed
|
|
124
|
+
// the very first time the polyfill ran (often a placeholder), so removing
|
|
125
|
+
// `masonryPreferredColumnSpan`/`isMasonry` later would restore that stale
|
|
126
|
+
// value instead of the item's real current span.
|
|
127
|
+
const LAST_COL_ATTR = 'data-bds-masonry-col';
|
|
128
|
+
|
|
117
129
|
// Data attribute caching the last applied row-span. Used to short-circuit no-op
|
|
118
130
|
// re-runs: when every child's newly-measured span matches the cached value, the
|
|
119
131
|
// polyfill skips all writes. This prevents `grid-auto-flow: dense` from
|
|
@@ -190,17 +202,30 @@ export function applyMasonryLayout(
|
|
|
190
202
|
let col = 0;
|
|
191
203
|
for (const child of children) {
|
|
192
204
|
if (child.hasAttribute('data-column-span-auto')) {
|
|
193
|
-
|
|
194
|
-
|
|
205
|
+
const currentInline = child.style.gridColumn;
|
|
206
|
+
const lastWritten = child.getAttribute(LAST_COL_ATTR);
|
|
207
|
+
// Refresh the snapshot on first sight, or when something other than
|
|
208
|
+
// the polyfill (i.e. React re-rendering the item) has since changed
|
|
209
|
+
// the inline value — otherwise we'd restore a stale span later.
|
|
210
|
+
if (!child.hasAttribute(ORIGINAL_COL_ATTR) || currentInline !== lastWritten) {
|
|
211
|
+
child.setAttribute(ORIGINAL_COL_ATTR, currentInline);
|
|
195
212
|
}
|
|
196
213
|
const remaining = totalCols - col;
|
|
197
214
|
const span = Math.max(1, Math.min(preferredCols, remaining));
|
|
198
215
|
child.style.gridColumn = `span ${span}`;
|
|
216
|
+
child.setAttribute(LAST_COL_ATTR, child.style.gridColumn);
|
|
199
217
|
col = (col + span) % totalCols;
|
|
200
218
|
} else {
|
|
201
219
|
// Item has an explicit span — consume its columns for the demotion budget.
|
|
202
220
|
const consumed = Math.min(totalCols, readExplicitSpan(child, totalCols));
|
|
203
|
-
|
|
221
|
+
// A span that doesn't fit the remaining row wraps to a fresh row in
|
|
222
|
+
// the browser's auto-placement algorithm (dense packing places it at
|
|
223
|
+
// the start of the next row, not at `col + consumed`).
|
|
224
|
+
if (consumed > totalCols - col) {
|
|
225
|
+
col = consumed % totalCols;
|
|
226
|
+
} else {
|
|
227
|
+
col = (col + consumed) % totalCols;
|
|
228
|
+
}
|
|
204
229
|
}
|
|
205
230
|
}
|
|
206
231
|
}
|
|
@@ -340,6 +365,7 @@ function restoreOriginalColumn(el: HTMLElement): void {
|
|
|
340
365
|
if (!el.hasAttribute(ORIGINAL_COL_ATTR)) return;
|
|
341
366
|
el.style.gridColumn = el.getAttribute(ORIGINAL_COL_ATTR) ?? '';
|
|
342
367
|
el.removeAttribute(ORIGINAL_COL_ATTR);
|
|
368
|
+
el.removeAttribute(LAST_COL_ATTR);
|
|
343
369
|
}
|
|
344
370
|
|
|
345
371
|
/**
|
|
@@ -353,7 +379,7 @@ export function useMasonry(
|
|
|
353
379
|
options: MasonryOptions = {},
|
|
354
380
|
): void {
|
|
355
381
|
const { preferredColumnSpan, rowUnitPx } = options;
|
|
356
|
-
|
|
382
|
+
useIsomorphicLayoutEffect(() => {
|
|
357
383
|
const container = ref.current;
|
|
358
384
|
if (!container || !enabled) return;
|
|
359
385
|
if (supportsNativeMasonry()) return;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useEffect, useLayoutEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `useLayoutEffect` that falls back to `useEffect` when there is no DOM
|
|
5
|
+
* (SSR / RSC). React 18 logs a warning ("useLayoutEffect does nothing on
|
|
6
|
+
* the server") whenever `useLayoutEffect` runs during a non-browser render —
|
|
7
|
+
* this avoids that warning while preserving the synchronous-before-paint
|
|
8
|
+
* timing `GridItem` and the masonry polyfill both depend on in the browser.
|
|
9
|
+
*/
|
|
10
|
+
export const useIsomorphicLayoutEffect =
|
|
11
|
+
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
@@ -28,11 +28,17 @@ Circular container that sizes to its own `font-size`. Use to give an SVG icon a
|
|
|
28
28
|
<tr><th>Variable</th><th>Default</th><th>Description</th></tr>
|
|
29
29
|
</thead>
|
|
30
30
|
<tbody>
|
|
31
|
-
<tr><td>`--icon-
|
|
32
|
-
<tr><td>`--
|
|
31
|
+
<tr><td>`--icon-wrapper_color`</td><td>`var(--bds-color_bg)`</td><td>Background colour</td></tr>
|
|
32
|
+
<tr><td>`--icon-wrapper_on-color`</td><td>`var(--bds-color_on-bg)`</td><td>Icon colour (text/fill)</td></tr>
|
|
33
|
+
<tr><td>`--icon-wrapper_radius`</td><td>`var(--bds-border_radius--circle)`</td><td>Corner radius</td></tr>
|
|
34
|
+
<tr><td>`--icon-wrapper_size`</td><td>`3em`</td><td>Font size — drives the icon's `1em`-based glyph size</td></tr>
|
|
35
|
+
<tr><td>`--icon-wrapper_margin-block-start`</td><td>`var(--bds-space_l)`</td><td>Space above the wrapper</td></tr>
|
|
36
|
+
<tr><td>`--icon-wrapper_margin-block-end`</td><td>`var(--bds-space_m)`</td><td>Space below the wrapper</td></tr>
|
|
33
37
|
</tbody>
|
|
34
38
|
</table>
|
|
35
39
|
|
|
40
|
+
> `--icon-wrapper-color` and `--icon-wrapper-radius` (hyphen-delimited) are deprecated aliases for `--icon-wrapper_color` and `--icon-wrapper_radius` — still supported, but new code should use the underscore-delimited names.
|
|
41
|
+
|
|
36
42
|
|
|
37
43
|
## Accessibility
|
|
38
44
|
|