@boostdev/design-system-components 2.7.1 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. package/AGENTS.md +54 -46
  2. package/README.md +34 -20
  3. package/dist/client.cjs +1317 -779
  4. package/dist/client.css +1029 -812
  5. package/dist/client.d.cts +88 -26
  6. package/dist/client.d.ts +88 -26
  7. package/dist/client.js +1278 -732
  8. package/dist/index.cjs +1317 -779
  9. package/dist/index.css +1029 -812
  10. package/dist/index.d.cts +88 -26
  11. package/dist/index.d.ts +88 -26
  12. package/dist/index.js +1278 -732
  13. package/dist/web-components/chunk-2OLVQUBU.js +193 -0
  14. package/dist/web-components/chunk-3AY2YKCM.js +223 -0
  15. package/dist/web-components/chunk-3WAV6MDN.js +212 -0
  16. package/dist/web-components/{chunk-CZBIVR4V.js → chunk-47AT5KZD.js} +88 -16
  17. package/dist/web-components/chunk-4A2YYTYN.js +93 -0
  18. package/dist/web-components/{chunk-Q4T5BJT6.js → chunk-62NK3ZSC.js} +18 -3
  19. package/dist/web-components/chunk-66M6ETWD.js +77 -0
  20. package/dist/web-components/{chunk-NCPQ7AF3.js → chunk-6G22I2CK.js} +18 -3
  21. package/dist/web-components/{chunk-QDST57JC.js → chunk-7ZOJ7N4E.js} +14 -4
  22. package/dist/web-components/{chunk-5R6IFELV.js → chunk-AIBOHNDU.js} +11 -1
  23. package/dist/web-components/{chunk-ITHLKR7Q.js → chunk-AP4RDUL2.js} +16 -5
  24. package/dist/web-components/{chunk-QWPACK5L.js → chunk-BPYKZVDK.js} +11 -1
  25. package/dist/web-components/{chunk-YLVTEY23.js → chunk-BTCMJQKB.js} +53 -21
  26. package/dist/web-components/chunk-CUKQ2L5B.js +245 -0
  27. package/dist/web-components/chunk-DIZDCL7Z.js +14 -0
  28. package/dist/web-components/{chunk-PC3IOQAH.js → chunk-DV5T43ZC.js} +27 -7
  29. package/dist/web-components/{chunk-2QA62WCQ.js → chunk-EF7IVYTY.js} +10 -0
  30. package/dist/web-components/{chunk-L3XHOMN6.js → chunk-F3ZDNHZZ.js} +26 -1
  31. package/dist/web-components/chunk-FEDABOR5.js +248 -0
  32. package/dist/web-components/{chunk-6I2DBFQ7.js → chunk-HGFCJXOQ.js} +36 -5
  33. package/dist/web-components/{chunk-SOQQ7RVJ.js → chunk-IPGHUCJT.js} +23 -8
  34. package/dist/web-components/chunk-ITD2MV5K.js +392 -0
  35. package/dist/web-components/{chunk-CM3KYZ6Z.js → chunk-JH6LQKLK.js} +78 -6
  36. package/dist/web-components/chunk-JMCXAAFK.js +120 -0
  37. package/dist/web-components/{chunk-KUI55GFB.js → chunk-JUPCZVVW.js} +50 -18
  38. package/dist/web-components/chunk-JV5QT2OU.js +146 -0
  39. package/dist/web-components/{chunk-3GFWLSLS.js → chunk-KA3VPKMY.js} +29 -6
  40. package/dist/web-components/{chunk-CR5PGUHV.js → chunk-KJGRFDFI.js} +26 -11
  41. package/dist/web-components/{chunk-PY62FTRW.js → chunk-KZPRFY5P.js} +68 -33
  42. package/dist/web-components/{chunk-X46KL5BK.js → chunk-LDIPCTRN.js} +18 -1
  43. package/dist/web-components/chunk-M3ECULRH.js +174 -0
  44. package/dist/web-components/chunk-NBN2ENWJ.js +90 -0
  45. package/dist/web-components/chunk-NIN3JO6Q.js +189 -0
  46. package/dist/web-components/{chunk-2FGATTGT.js → chunk-NTQ4TCUT.js} +76 -55
  47. package/dist/web-components/chunk-OY74D4X6.js +302 -0
  48. package/dist/web-components/{chunk-3S42DZ7W.js → chunk-P24JYC5V.js} +7 -0
  49. package/dist/web-components/{chunk-BKIHQYJR.js → chunk-PXPPKCLT.js} +17 -2
  50. package/dist/web-components/{chunk-TQ7IQ4GZ.js → chunk-QEF2IRID.js} +71 -29
  51. package/dist/web-components/chunk-QZAIRJ75.js +111 -0
  52. package/dist/web-components/{chunk-6I3CFC26.js → chunk-RSZ3BWBK.js} +20 -5
  53. package/dist/web-components/chunk-RVF7W653.js +101 -0
  54. package/dist/web-components/chunk-SEO2F5KJ.js +234 -0
  55. package/dist/web-components/{chunk-VMMVWLXL.js → chunk-SFZ6Q4BP.js} +10 -0
  56. package/dist/web-components/{chunk-LY62SAVN.js → chunk-SYNLFKD3.js} +12 -2
  57. package/dist/web-components/chunk-TMWXRHGF.js +192 -0
  58. package/dist/web-components/{chunk-65JXQOBA.js → chunk-U3YZE6R6.js} +51 -7
  59. package/dist/web-components/chunk-UO7ROSHD.js +424 -0
  60. package/dist/web-components/chunk-VANAKB6D.js +152 -0
  61. package/dist/web-components/{chunk-PXZWYO6Z.js → chunk-VED2DFJ6.js} +108 -29
  62. package/dist/web-components/chunk-W6H5ID2U.js +161 -0
  63. package/dist/web-components/{chunk-57TRNCWQ.js → chunk-WFVKU4GX.js} +22 -11
  64. package/dist/web-components/{chunk-OQTRTMAB.js → chunk-WIBAN7KP.js} +10 -0
  65. package/dist/web-components/chunk-XI7KRAH7.js +54 -0
  66. package/dist/web-components/{chunk-F5E3IT7G.js → chunk-XIZWAWMJ.js} +50 -11
  67. package/dist/web-components/{chunk-FXURM6D5.js → chunk-YFAXGRPR.js} +10 -0
  68. package/dist/web-components/globals.js +1 -1
  69. package/dist/web-components/index.d.ts +77 -707
  70. package/dist/web-components/index.js +339 -2066
  71. package/dist/web-components/interaction/bds-accordion-item.js +1 -1
  72. package/dist/web-components/interaction/bds-accordion.js +1 -1
  73. package/dist/web-components/interaction/bds-button.d.ts +10 -2
  74. package/dist/web-components/interaction/bds-button.js +1 -1
  75. package/dist/web-components/interaction/bds-collapsible.d.ts +7 -2
  76. package/dist/web-components/interaction/bds-collapsible.js +1 -1
  77. package/dist/web-components/interaction/bds-dialog.d.ts +11 -3
  78. package/dist/web-components/interaction/bds-dialog.js +1 -1
  79. package/dist/web-components/interaction/bds-drawer.d.ts +7 -1
  80. package/dist/web-components/interaction/bds-drawer.js +1 -1
  81. package/dist/web-components/interaction/bds-dropdown-menu-item.d.ts +51 -0
  82. package/dist/web-components/interaction/bds-dropdown-menu-item.js +7 -0
  83. package/dist/web-components/interaction/bds-dropdown-menu.d.ts +70 -0
  84. package/dist/web-components/interaction/bds-dropdown-menu.js +7 -0
  85. package/dist/web-components/interaction/bds-popover.d.ts +14 -3
  86. package/dist/web-components/interaction/bds-popover.js +1 -1
  87. package/dist/web-components/interaction/bds-skip-link.js +1 -1
  88. package/dist/web-components/interaction/bds-tab-panel.js +1 -1
  89. package/dist/web-components/interaction/bds-tab.js +1 -1
  90. package/dist/web-components/interaction/bds-tabs.d.ts +1 -0
  91. package/dist/web-components/interaction/bds-tabs.js +1 -1
  92. package/dist/web-components/interaction/bds-toast-provider.js +1 -1
  93. package/dist/web-components/interaction/bds-tooltip.d.ts +19 -3
  94. package/dist/web-components/interaction/bds-tooltip.js +1 -1
  95. package/dist/web-components/interaction/form/bds-checkbox-group.d.ts +83 -0
  96. package/dist/web-components/interaction/form/bds-checkbox-group.js +7 -0
  97. package/dist/web-components/interaction/form/bds-checkbox.d.ts +6 -0
  98. package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
  99. package/dist/web-components/interaction/form/bds-combobox.d.ts +18 -0
  100. package/dist/web-components/interaction/form/bds-combobox.js +1 -1
  101. package/dist/web-components/interaction/form/bds-field-group.d.ts +89 -0
  102. package/dist/web-components/interaction/form/bds-field-group.js +7 -0
  103. package/dist/web-components/interaction/form/bds-file-input.d.ts +1 -1
  104. package/dist/web-components/interaction/form/bds-file-input.js +1 -1
  105. package/dist/web-components/interaction/form/bds-form-input.d.ts +92 -0
  106. package/dist/web-components/interaction/form/bds-form-input.js +7 -0
  107. package/dist/web-components/interaction/form/bds-number-input.d.ts +18 -1
  108. package/dist/web-components/interaction/form/bds-number-input.js +1 -1
  109. package/dist/web-components/interaction/form/bds-radio-group.d.ts +81 -0
  110. package/dist/web-components/interaction/form/bds-radio-group.js +7 -0
  111. package/dist/web-components/interaction/form/bds-radio.d.ts +34 -6
  112. package/dist/web-components/interaction/form/bds-radio.js +1 -1
  113. package/dist/web-components/interaction/form/bds-segmented-control.d.ts +4 -4
  114. package/dist/web-components/interaction/form/bds-segmented-control.js +1 -1
  115. package/dist/web-components/interaction/form/bds-select.d.ts +22 -1
  116. package/dist/web-components/interaction/form/bds-select.js +1 -1
  117. package/dist/web-components/interaction/form/bds-slider.d.ts +42 -10
  118. package/dist/web-components/interaction/form/bds-slider.js +1 -1
  119. package/dist/web-components/interaction/form/bds-switch.d.ts +20 -0
  120. package/dist/web-components/interaction/form/bds-switch.js +1 -1
  121. package/dist/web-components/interaction/form/bds-textarea.d.ts +23 -3
  122. package/dist/web-components/interaction/form/bds-textarea.js +1 -1
  123. package/dist/web-components/layout/bds-grid-item.d.ts +63 -0
  124. package/dist/web-components/layout/bds-grid-item.js +7 -0
  125. package/dist/web-components/layout/bds-grid.d.ts +108 -0
  126. package/dist/web-components/layout/bds-grid.js +7 -0
  127. package/dist/web-components/ui/bds-alert.d.ts +16 -2
  128. package/dist/web-components/ui/bds-alert.js +1 -1
  129. package/dist/web-components/ui/bds-avatar.d.ts +2 -1
  130. package/dist/web-components/ui/bds-avatar.js +1 -1
  131. package/dist/web-components/ui/bds-badge.js +1 -1
  132. package/dist/web-components/ui/bds-breadcrumb.d.ts +3 -1
  133. package/dist/web-components/ui/bds-breadcrumb.js +1 -1
  134. package/dist/web-components/ui/bds-button-container.d.ts +52 -0
  135. package/dist/web-components/ui/bds-button-container.js +7 -0
  136. package/dist/web-components/ui/bds-button-group.d.ts +21 -0
  137. package/dist/web-components/ui/bds-button-group.js +8 -0
  138. package/dist/web-components/ui/bds-calendar.d.ts +121 -0
  139. package/dist/web-components/ui/bds-calendar.js +7 -0
  140. package/dist/web-components/ui/bds-card.d.ts +12 -3
  141. package/dist/web-components/ui/bds-card.js +1 -1
  142. package/dist/web-components/ui/bds-carousel.d.ts +98 -0
  143. package/dist/web-components/ui/bds-carousel.js +7 -0
  144. package/dist/web-components/ui/bds-description-list.js +1 -1
  145. package/dist/web-components/ui/bds-icon-wrapper.d.ts +0 -9
  146. package/dist/web-components/ui/bds-icon-wrapper.js +1 -1
  147. package/dist/web-components/ui/bds-link.js +1 -1
  148. package/dist/web-components/ui/bds-loading.js +1 -1
  149. package/dist/web-components/ui/bds-notification-banner.js +1 -1
  150. package/dist/web-components/ui/bds-pagination.d.ts +47 -0
  151. package/dist/web-components/ui/bds-pagination.js +7 -0
  152. package/dist/web-components/ui/bds-progress-circle.d.ts +3 -1
  153. package/dist/web-components/ui/bds-progress-circle.js +1 -1
  154. package/dist/web-components/ui/bds-progress.d.ts +3 -1
  155. package/dist/web-components/ui/bds-progress.js +1 -1
  156. package/dist/web-components/ui/bds-rating.js +1 -1
  157. package/dist/web-components/ui/bds-section-header.d.ts +18 -4
  158. package/dist/web-components/ui/bds-section-header.js +1 -1
  159. package/dist/web-components/ui/bds-separator.js +1 -1
  160. package/dist/web-components/ui/bds-skeleton.js +1 -1
  161. package/dist/web-components/ui/bds-table.d.ts +52 -0
  162. package/dist/web-components/ui/bds-table.js +7 -0
  163. package/dist/web-components/ui/bds-typography.d.ts +1 -0
  164. package/dist/web-components/ui/bds-typography.js +1 -1
  165. package/package.json +60 -3
  166. package/src/components/interaction/Button/Button.module.css +23 -14
  167. package/src/components/interaction/Button/Button.spec.tsx +20 -0
  168. package/src/components/interaction/Button/Button.tsx +2 -2
  169. package/src/components/interaction/Command/Command.mdx +5 -2
  170. package/src/components/interaction/Command/Command.module.css +23 -7
  171. package/src/components/interaction/Command/Command.spec.tsx +35 -0
  172. package/src/components/interaction/Command/Command.tsx +15 -4
  173. package/src/components/interaction/Command/index.ts +1 -1
  174. package/src/components/interaction/Dialog/Dialog.mdx +4 -4
  175. package/src/components/interaction/Dialog/Dialog.module.css +20 -0
  176. package/src/components/interaction/Dialog/Dialog.spec.tsx +20 -0
  177. package/src/components/interaction/Dialog/Dialog.tsx +8 -3
  178. package/src/components/interaction/Dialog/index.ts +1 -0
  179. package/src/components/interaction/Drawer/Drawer.mdx +5 -2
  180. package/src/components/interaction/Drawer/Drawer.module.css +34 -3
  181. package/src/components/interaction/Drawer/Drawer.spec.tsx +67 -1
  182. package/src/components/interaction/Drawer/Drawer.tsx +30 -12
  183. package/src/components/interaction/Drawer/index.ts +1 -0
  184. package/src/components/interaction/DropdownMenu/DropdownMenu.mdx +2 -0
  185. package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +34 -0
  186. package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +15 -5
  187. package/src/components/interaction/DropdownMenu/index.ts +1 -0
  188. package/src/components/interaction/Popover/Popover.mdx +6 -2
  189. package/src/components/interaction/Popover/Popover.module.css +26 -18
  190. package/src/components/interaction/Popover/Popover.spec.tsx +38 -0
  191. package/src/components/interaction/Popover/Popover.tsx +19 -5
  192. package/src/components/interaction/Popover/index.ts +1 -0
  193. package/src/components/interaction/Rating/Rating.mdx +1 -1
  194. package/src/components/interaction/Rating/Rating.module.css +2 -2
  195. package/src/components/interaction/Rating/Rating.tsx +1 -1
  196. package/src/components/interaction/Rating/index.ts +1 -0
  197. package/src/components/interaction/Toast/Toast.mdx +3 -0
  198. package/src/components/interaction/Toast/Toast.module.css +35 -5
  199. package/src/components/interaction/Toast/Toast.spec.tsx +69 -1
  200. package/src/components/interaction/Toast/Toast.tsx +15 -9
  201. package/src/components/interaction/form/Checkbox/Checkbox.mdx +3 -0
  202. package/src/components/interaction/form/Checkbox/Checkbox.module.css +13 -6
  203. package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +6 -0
  204. package/src/components/interaction/form/Checkbox/Checkbox.tsx +1 -1
  205. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.mdx +16 -1
  206. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +24 -8
  207. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +32 -2
  208. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +14 -2
  209. package/src/components/interaction/form/Combobox/Combobox.mdx +11 -4
  210. package/src/components/interaction/form/Combobox/Combobox.module.css +6 -6
  211. package/src/components/interaction/form/Combobox/Combobox.spec.tsx +47 -0
  212. package/src/components/interaction/form/Combobox/Combobox.tsx +10 -5
  213. package/src/components/interaction/form/FieldGroup/FieldGroup.mdx +9 -10
  214. package/src/components/interaction/form/FieldGroup/FieldGroup.module.css +57 -23
  215. package/src/components/interaction/form/FieldGroup/FieldGroup.spec.tsx +129 -7
  216. package/src/components/interaction/form/FieldGroup/FieldGroup.tsx +72 -12
  217. package/src/components/interaction/form/FileInput/FileInput.mdx +9 -1
  218. package/src/components/interaction/form/FileInput/FileInput.module.css +8 -8
  219. package/src/components/interaction/form/FileInput/FileInput.spec.tsx +89 -1
  220. package/src/components/interaction/form/FileInput/FileInput.tsx +6 -2
  221. package/src/components/interaction/form/FormInput/FormInput.mdx +9 -5
  222. package/src/components/interaction/form/FormInput/FormInput.module.css +17 -8
  223. package/src/components/interaction/form/FormInput/FormInput.spec.tsx +20 -0
  224. package/src/components/interaction/form/FormInput/FormInput.tsx +7 -2
  225. package/src/components/interaction/form/NumberInput/NumberInput.mdx +5 -1
  226. package/src/components/interaction/form/NumberInput/NumberInput.module.css +6 -6
  227. package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +51 -0
  228. package/src/components/interaction/form/NumberInput/NumberInput.tsx +36 -8
  229. package/src/components/interaction/form/Radio/Radio.mdx +8 -1
  230. package/src/components/interaction/form/Radio/Radio.module.css +20 -7
  231. package/src/components/interaction/form/Radio/Radio.spec.tsx +15 -0
  232. package/src/components/interaction/form/Radio/Radio.tsx +10 -4
  233. package/src/components/interaction/form/RadioGroup/RadioGroup.mdx +16 -1
  234. package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +24 -8
  235. package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +32 -2
  236. package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +14 -2
  237. package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +9 -3
  238. package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +25 -12
  239. package/src/components/interaction/form/SegmentedControl/SegmentedControl.spec.tsx +86 -5
  240. package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +44 -4
  241. package/src/components/interaction/form/Select/Select.mdx +10 -4
  242. package/src/components/interaction/form/Select/Select.module.css +4 -4
  243. package/src/components/interaction/form/Select/Select.spec.tsx +34 -0
  244. package/src/components/interaction/form/Select/Select.tsx +21 -9
  245. package/src/components/interaction/form/Slider/Slider.mdx +4 -1
  246. package/src/components/interaction/form/Slider/Slider.module.css +32 -8
  247. package/src/components/interaction/form/Slider/Slider.spec.tsx +29 -0
  248. package/src/components/interaction/form/Slider/Slider.tsx +9 -7
  249. package/src/components/interaction/form/Switch/Switch.mdx +2 -2
  250. package/src/components/interaction/form/Switch/Switch.module.css +12 -13
  251. package/src/components/interaction/form/Switch/Switch.spec.tsx +20 -0
  252. package/src/components/interaction/form/Switch/Switch.tsx +2 -1
  253. package/src/components/interaction/form/Textarea/Textarea.mdx +5 -0
  254. package/src/components/interaction/form/Textarea/Textarea.module.css +5 -5
  255. package/src/components/interaction/form/Textarea/Textarea.spec.tsx +13 -0
  256. package/src/components/interaction/form/Textarea/Textarea.tsx +3 -1
  257. package/src/components/interaction/form/atoms/Message.module.css +1 -1
  258. package/src/components/interaction/form/atoms/Message.spec.tsx +29 -0
  259. package/src/components/interaction/form/atoms/Message.tsx +1 -1
  260. package/src/components/layout/ButtonGroup/ButtonGroup.mdx +11 -0
  261. package/src/components/layout/ButtonGroup/ButtonGroup.module.css +1 -5
  262. package/src/components/layout/ButtonGroup/ButtonGroup.stories.tsx +14 -0
  263. package/src/components/layout/Card/Card.mdx +6 -1
  264. package/src/components/layout/Card/Card.module.css +26 -5
  265. package/src/components/layout/Card/Card.spec.tsx +7 -0
  266. package/src/components/layout/Card/Card.tsx +4 -3
  267. package/src/components/layout/Grid/Grid.spec.tsx +44 -0
  268. package/src/components/layout/Grid/Grid.tsx +5 -5
  269. package/src/components/layout/Grid/GridItem.tsx +6 -6
  270. package/src/components/layout/Grid/masonry.ts +31 -5
  271. package/src/components/layout/Grid/useIsomorphicLayoutEffect.ts +11 -0
  272. package/src/components/layout/IconWrapper/IconWrapper.mdx +8 -2
  273. package/src/components/layout/IconWrapper/IconWrapper.module.css +9 -6
  274. package/src/components/layout/SectionHeader/SectionHeader.mdx +4 -1
  275. package/src/components/layout/SectionHeader/SectionHeader.module.css +10 -9
  276. package/src/components/ui/Accordion/Accordion.mdx +4 -1
  277. package/src/components/ui/Accordion/Accordion.module.css +2 -1
  278. package/src/components/ui/Alert/Alert.mdx +21 -4
  279. package/src/components/ui/Alert/Alert.module.css +9 -4
  280. package/src/components/ui/Alert/Alert.spec.tsx +20 -0
  281. package/src/components/ui/Avatar/Avatar.mdx +8 -3
  282. package/src/components/ui/Avatar/Avatar.module.css +13 -8
  283. package/src/components/ui/Badge/Badge.mdx +3 -1
  284. package/src/components/ui/Breadcrumb/Breadcrumb.mdx +3 -0
  285. package/src/components/ui/Breadcrumb/Breadcrumb.module.css +4 -0
  286. package/src/components/ui/Breadcrumb/Breadcrumb.spec.tsx +12 -0
  287. package/src/components/ui/Breadcrumb/Breadcrumb.tsx +11 -3
  288. package/src/components/ui/Calendar/Calendar.mdx +6 -0
  289. package/src/components/ui/Calendar/Calendar.module.css +68 -19
  290. package/src/components/ui/Calendar/Calendar.spec.tsx +139 -24
  291. package/src/components/ui/Calendar/Calendar.stories.tsx +14 -0
  292. package/src/components/ui/Calendar/Calendar.tsx +143 -154
  293. package/src/components/ui/Calendar/CalendarRange.mdx +39 -0
  294. package/src/components/ui/Calendar/CalendarRange.spec.tsx +119 -0
  295. package/src/components/ui/Calendar/CalendarRange.stories.tsx +51 -0
  296. package/src/components/ui/Calendar/CalendarRange.tsx +213 -0
  297. package/src/components/ui/Calendar/MonthGrid.tsx +141 -0
  298. package/src/components/ui/Calendar/calendar-core.spec.ts +176 -0
  299. package/src/components/ui/Calendar/calendar-core.ts +164 -0
  300. package/src/components/ui/Calendar/index.ts +1 -0
  301. package/src/components/ui/Carousel/Carousel.mdx +8 -3
  302. package/src/components/ui/Carousel/Carousel.module.css +7 -5
  303. package/src/components/ui/Carousel/Carousel.spec.tsx +67 -0
  304. package/src/components/ui/Carousel/Carousel.tsx +19 -7
  305. package/src/components/ui/Collapsible/Collapsible.mdx +17 -6
  306. package/src/components/ui/Collapsible/Collapsible.module.css +7 -2
  307. package/src/components/ui/Collapsible/Collapsible.spec.tsx +40 -0
  308. package/src/components/ui/Collapsible/Collapsible.tsx +19 -2
  309. package/src/components/ui/DescriptionList/DescriptionList.mdx +2 -0
  310. package/src/components/ui/Link/Link.mdx +4 -2
  311. package/src/components/ui/Loading/Loading.mdx +6 -3
  312. package/src/components/ui/Loading/Loading.module.css +7 -7
  313. package/src/components/ui/Loading/Loading.spec.tsx +12 -0
  314. package/src/components/ui/Loading/Loading.tsx +8 -3
  315. package/src/components/ui/NotificationBanner/NotificationBanner.mdx +4 -0
  316. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +5 -0
  317. package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +20 -0
  318. package/src/components/ui/Pagination/Pagination.mdx +29 -7
  319. package/src/components/ui/Pagination/Pagination.module.css +15 -14
  320. package/src/components/ui/Progress/Progress.mdx +6 -2
  321. package/src/components/ui/Progress/Progress.module.css +1 -1
  322. package/src/components/ui/Progress/Progress.spec.tsx +17 -0
  323. package/src/components/ui/Progress/Progress.tsx +2 -2
  324. package/src/components/ui/ProgressCircle/ProgressCircle.mdx +8 -4
  325. package/src/components/ui/ProgressCircle/ProgressCircle.module.css +2 -2
  326. package/src/components/ui/ProgressCircle/ProgressCircle.spec.tsx +11 -1
  327. package/src/components/ui/ProgressCircle/ProgressCircle.tsx +1 -1
  328. package/src/components/ui/Separator/Separator.mdx +7 -0
  329. package/src/components/ui/Separator/Separator.module.css +1 -0
  330. package/src/components/ui/Skeleton/Skeleton.mdx +17 -0
  331. package/src/components/ui/Skeleton/Skeleton.module.css +12 -5
  332. package/src/components/ui/SkipLink/SkipLink.mdx +19 -0
  333. package/src/components/ui/SkipLink/SkipLink.module.css +8 -7
  334. package/src/components/ui/SkipLink/SkipLink.spec.tsx +28 -0
  335. package/src/components/ui/Table/Table.mdx +14 -0
  336. package/src/components/ui/Table/Table.module.css +13 -8
  337. package/src/components/ui/Table/Table.spec.tsx +56 -0
  338. package/src/components/ui/Table/Table.tsx +44 -6
  339. package/src/components/ui/Tabs/Tabs.mdx +16 -0
  340. package/src/components/ui/Tabs/Tabs.module.css +3 -3
  341. package/src/components/ui/Tabs/Tabs.spec.tsx +20 -0
  342. package/src/components/ui/Tabs/Tabs.tsx +5 -1
  343. package/src/components/ui/Tooltip/Tooltip.mdx +9 -0
  344. package/src/components/ui/Tooltip/Tooltip.module.css +32 -12
  345. package/src/components/ui/Tooltip/Tooltip.spec.tsx +56 -0
  346. package/src/components/ui/Tooltip/Tooltip.tsx +26 -7
  347. package/src/components/ui/Typography/Typography.mdx +7 -0
  348. package/src/components/ui/Typography/Typography.module.css +5 -5
  349. package/src/index.ts +7 -3
  350. package/src/stories/DesignSystem/Borders.mdx +14 -9
  351. package/src/stories/DesignSystem/Colors.mdx +43 -41
  352. package/src/stories/DesignSystem/Overview.mdx +4 -3
  353. package/src/stories/Introduction.mdx +5 -5
  354. package/src/web-components/globals.ts +7 -0
  355. package/src/web-components/index.ts +2 -0
  356. package/src/web-components/interaction/BdsAccordion.mdx +10 -1
  357. package/src/web-components/interaction/BdsButton.mdx +15 -4
  358. package/src/web-components/interaction/BdsButton.stories.tsx +1 -1
  359. package/src/web-components/interaction/BdsCollapsible.mdx +3 -3
  360. package/src/web-components/interaction/BdsDialog.mdx +12 -7
  361. package/src/web-components/interaction/BdsDialog.stories.tsx +2 -2
  362. package/src/web-components/interaction/BdsDrawer.mdx +9 -6
  363. package/src/web-components/interaction/BdsDropdownMenu.mdx +20 -1
  364. package/src/web-components/interaction/BdsPopover.mdx +7 -3
  365. package/src/web-components/interaction/BdsSkipLink.mdx +14 -1
  366. package/src/web-components/interaction/BdsTabs.mdx +18 -1
  367. package/src/web-components/interaction/BdsToastProvider.mdx +21 -3
  368. package/src/web-components/interaction/BdsTooltip.mdx +4 -4
  369. package/src/web-components/interaction/bds-accordion-item.ts +10 -0
  370. package/src/web-components/interaction/bds-accordion.spec.ts +41 -0
  371. package/src/web-components/interaction/bds-accordion.ts +28 -2
  372. package/src/web-components/interaction/bds-button.spec.ts +81 -0
  373. package/src/web-components/interaction/bds-button.ts +60 -13
  374. package/src/web-components/interaction/bds-collapsible.spec.ts +93 -2
  375. package/src/web-components/interaction/bds-collapsible.ts +49 -7
  376. package/src/web-components/interaction/bds-dialog.spec.ts +49 -0
  377. package/src/web-components/interaction/bds-dialog.ts +68 -11
  378. package/src/web-components/interaction/bds-drawer.spec.ts +93 -4
  379. package/src/web-components/interaction/bds-drawer.ts +54 -21
  380. package/src/web-components/interaction/bds-dropdown-menu-item.ts +12 -1
  381. package/src/web-components/interaction/bds-dropdown-menu.spec.ts +63 -0
  382. package/src/web-components/interaction/bds-dropdown-menu.ts +45 -7
  383. package/src/web-components/interaction/bds-popover.spec.ts +80 -6
  384. package/src/web-components/interaction/bds-popover.ts +83 -32
  385. package/src/web-components/interaction/bds-skip-link.spec.ts +18 -0
  386. package/src/web-components/interaction/bds-skip-link.ts +29 -8
  387. package/src/web-components/interaction/bds-tab-panel.ts +10 -0
  388. package/src/web-components/interaction/bds-tab.spec.ts +25 -0
  389. package/src/web-components/interaction/bds-tab.ts +20 -5
  390. package/src/web-components/interaction/bds-tabs.spec.ts +92 -5
  391. package/src/web-components/interaction/bds-tabs.ts +42 -1
  392. package/src/web-components/interaction/bds-toast-provider.spec.ts +43 -0
  393. package/src/web-components/interaction/bds-toast-provider.ts +50 -21
  394. package/src/web-components/interaction/bds-tooltip.spec.ts +71 -0
  395. package/src/web-components/interaction/bds-tooltip.ts +100 -5
  396. package/src/web-components/interaction/form/BdsCheckbox.mdx +20 -1
  397. package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +8 -0
  398. package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +4 -3
  399. package/src/web-components/interaction/form/BdsCombobox.mdx +39 -2
  400. package/src/web-components/interaction/form/BdsCombobox.stories.tsx +31 -0
  401. package/src/web-components/interaction/form/BdsFieldGroup.mdx +8 -3
  402. package/src/web-components/interaction/form/BdsFieldGroup.stories.tsx +1 -1
  403. package/src/web-components/interaction/form/BdsFileInput.mdx +26 -5
  404. package/src/web-components/interaction/form/BdsFormInput.mdx +16 -1
  405. package/src/web-components/interaction/form/BdsNumberInput.mdx +34 -2
  406. package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +27 -3
  407. package/src/web-components/interaction/form/BdsRadio.mdx +39 -12
  408. package/src/web-components/interaction/form/BdsRadio.stories.tsx +26 -0
  409. package/src/web-components/interaction/form/BdsRadioGroup.mdx +9 -4
  410. package/src/web-components/interaction/form/BdsSegmentedControl.mdx +37 -11
  411. package/src/web-components/interaction/form/BdsSelect.mdx +22 -4
  412. package/src/web-components/interaction/form/BdsSelect.stories.tsx +33 -0
  413. package/src/web-components/interaction/form/BdsSlider.mdx +36 -19
  414. package/src/web-components/interaction/form/BdsSlider.stories.tsx +24 -0
  415. package/src/web-components/interaction/form/BdsSwitch.mdx +38 -11
  416. package/src/web-components/interaction/form/BdsSwitch.stories.tsx +16 -0
  417. package/src/web-components/interaction/form/BdsTextarea.mdx +42 -16
  418. package/src/web-components/interaction/form/BdsTextarea.stories.tsx +21 -0
  419. package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +99 -0
  420. package/src/web-components/interaction/form/bds-checkbox-group.ts +95 -9
  421. package/src/web-components/interaction/form/bds-checkbox.spec.ts +55 -0
  422. package/src/web-components/interaction/form/bds-checkbox.ts +30 -5
  423. package/src/web-components/interaction/form/bds-combobox.spec.ts +79 -0
  424. package/src/web-components/interaction/form/bds-combobox.ts +102 -17
  425. package/src/web-components/interaction/form/bds-field-group.spec.ts +158 -0
  426. package/src/web-components/interaction/form/bds-field-group.ts +167 -23
  427. package/src/web-components/interaction/form/bds-file-input.spec.ts +73 -5
  428. package/src/web-components/interaction/form/bds-file-input.ts +71 -34
  429. package/src/web-components/interaction/form/bds-form-input.spec.ts +22 -0
  430. package/src/web-components/interaction/form/bds-form-input.ts +27 -16
  431. package/src/web-components/interaction/form/bds-number-input.spec.ts +49 -0
  432. package/src/web-components/interaction/form/bds-number-input.ts +118 -29
  433. package/src/web-components/interaction/form/bds-radio-group.spec.ts +57 -0
  434. package/src/web-components/interaction/form/bds-radio-group.ts +60 -12
  435. package/src/web-components/interaction/form/bds-radio.spec.ts +123 -0
  436. package/src/web-components/interaction/form/bds-radio.ts +136 -23
  437. package/src/web-components/interaction/form/bds-segmented-control.spec.ts +55 -0
  438. package/src/web-components/interaction/form/bds-segmented-control.ts +81 -59
  439. package/src/web-components/interaction/form/bds-select.spec.ts +57 -0
  440. package/src/web-components/interaction/form/bds-select.ts +96 -8
  441. package/src/web-components/interaction/form/bds-slider.spec.ts +83 -0
  442. package/src/web-components/interaction/form/bds-slider.ts +181 -33
  443. package/src/web-components/interaction/form/bds-switch.spec.ts +68 -0
  444. package/src/web-components/interaction/form/bds-switch.ts +142 -41
  445. package/src/web-components/interaction/form/bds-textarea.spec.ts +71 -0
  446. package/src/web-components/interaction/form/bds-textarea.ts +109 -8
  447. package/src/web-components/layout/BdsGrid.mdx +6 -2
  448. package/src/web-components/layout/BdsGrid.stories.tsx +4 -0
  449. package/src/web-components/layout/bds-grid-item.spec.ts +21 -0
  450. package/src/web-components/layout/bds-grid-item.ts +17 -3
  451. package/src/web-components/layout/bds-grid.spec.ts +98 -0
  452. package/src/web-components/layout/bds-grid.ts +139 -19
  453. package/src/web-components/ui/BdsAlert.mdx +6 -5
  454. package/src/web-components/ui/BdsAlert.stories.tsx +6 -6
  455. package/src/web-components/ui/BdsAvatar.mdx +4 -2
  456. package/src/web-components/ui/BdsBreadcrumb.mdx +3 -2
  457. package/src/web-components/ui/BdsButtonContainer.mdx +64 -0
  458. package/src/web-components/ui/BdsButtonContainer.stories.tsx +84 -0
  459. package/src/web-components/ui/BdsCalendar.mdx +29 -4
  460. package/src/web-components/ui/BdsCalendar.stories.tsx +16 -18
  461. package/src/web-components/ui/BdsCalendarRange.mdx +71 -0
  462. package/src/web-components/ui/BdsCalendarRange.stories.tsx +31 -0
  463. package/src/web-components/ui/BdsCard.mdx +7 -3
  464. package/src/web-components/ui/BdsCard.stories.tsx +17 -1
  465. package/src/web-components/ui/BdsCarousel.mdx +40 -12
  466. package/src/web-components/ui/BdsDescriptionList.mdx +6 -1
  467. package/src/web-components/ui/BdsIconWrapper.mdx +3 -2
  468. package/src/web-components/ui/BdsLink.mdx +14 -2
  469. package/src/web-components/ui/BdsNotificationBanner.mdx +18 -0
  470. package/src/web-components/ui/BdsPagination.mdx +40 -1
  471. package/src/web-components/ui/BdsProgress.mdx +8 -2
  472. package/src/web-components/ui/BdsProgressCircle.mdx +5 -2
  473. package/src/web-components/ui/BdsRating.mdx +7 -0
  474. package/src/web-components/ui/BdsSectionHeader.mdx +22 -3
  475. package/src/web-components/ui/BdsSectionHeader.stories.tsx +15 -13
  476. package/src/web-components/ui/BdsTable.mdx +23 -2
  477. package/src/web-components/ui/BdsTable.stories.tsx +8 -2
  478. package/src/web-components/ui/BdsTypography.mdx +17 -1
  479. package/src/web-components/ui/bds-alert.spec.ts +17 -2
  480. package/src/web-components/ui/bds-alert.ts +31 -5
  481. package/src/web-components/ui/bds-avatar.spec.ts +29 -0
  482. package/src/web-components/ui/bds-avatar.ts +30 -12
  483. package/src/web-components/ui/bds-badge.spec.ts +5 -0
  484. package/src/web-components/ui/bds-badge.ts +11 -1
  485. package/src/web-components/ui/bds-breadcrumb.spec.ts +30 -0
  486. package/src/web-components/ui/bds-breadcrumb.ts +26 -4
  487. package/src/web-components/ui/bds-button-container.spec.ts +39 -0
  488. package/src/web-components/ui/bds-button-container.ts +123 -0
  489. package/src/web-components/ui/bds-button-group.spec.ts +14 -20
  490. package/src/web-components/ui/bds-button-group.ts +13 -64
  491. package/src/web-components/ui/bds-calendar-range.spec.ts +123 -0
  492. package/src/web-components/ui/bds-calendar-range.ts +307 -0
  493. package/src/web-components/ui/bds-calendar.spec.ts +176 -0
  494. package/src/web-components/ui/bds-calendar.ts +186 -344
  495. package/src/web-components/ui/bds-card.spec.ts +32 -0
  496. package/src/web-components/ui/bds-card.ts +34 -9
  497. package/src/web-components/ui/bds-carousel.spec.ts +147 -0
  498. package/src/web-components/ui/bds-carousel.ts +113 -36
  499. package/src/web-components/ui/bds-description-list.spec.ts +15 -0
  500. package/src/web-components/ui/bds-description-list.ts +37 -3
  501. package/src/web-components/ui/bds-icon-wrapper.spec.ts +12 -0
  502. package/src/web-components/ui/bds-icon-wrapper.ts +16 -15
  503. package/src/web-components/ui/bds-link.spec.ts +17 -0
  504. package/src/web-components/ui/bds-link.ts +26 -11
  505. package/src/web-components/ui/bds-loading.ts +11 -1
  506. package/src/web-components/ui/bds-notification-banner.spec.ts +13 -0
  507. package/src/web-components/ui/bds-notification-banner.ts +18 -1
  508. package/src/web-components/ui/bds-pagination.spec.ts +44 -0
  509. package/src/web-components/ui/bds-pagination.ts +39 -19
  510. package/src/web-components/ui/bds-progress-circle.spec.ts +21 -0
  511. package/src/web-components/ui/bds-progress-circle.ts +17 -5
  512. package/src/web-components/ui/bds-progress.spec.ts +21 -0
  513. package/src/web-components/ui/bds-progress.ts +19 -6
  514. package/src/web-components/ui/bds-rating.spec.ts +6 -0
  515. package/src/web-components/ui/bds-rating.ts +12 -2
  516. package/src/web-components/ui/bds-section-header.spec.ts +39 -8
  517. package/src/web-components/ui/bds-section-header.ts +47 -13
  518. package/src/web-components/ui/bds-separator.ts +10 -0
  519. package/src/web-components/ui/bds-skeleton.ts +10 -0
  520. package/src/web-components/ui/bds-table.spec.ts +63 -0
  521. package/src/web-components/ui/bds-table.ts +88 -28
  522. package/src/web-components/ui/bds-typography.spec.ts +47 -0
  523. package/src/web-components/ui/bds-typography.ts +28 -10
  524. package/src/web-components/ui/calendar-styles.ts +94 -0
  525. package/dist/web-components/chunk-5TFWOPLH.js +0 -49
  526. package/dist/web-components/chunk-7FMR53BW.js +0 -127
  527. package/dist/web-components/chunk-AGKJTMJI.js +0 -56
  528. package/dist/web-components/chunk-BQLZ7I4G.js +0 -56
  529. package/dist/web-components/chunk-IYGF6CD5.js +0 -118
  530. package/dist/web-components/chunk-QBB6ZX4R.js +0 -107
  531. package/dist/web-components/chunk-Y3POAKGS.js +0 -133
  532. package/dist/web-components/chunk-Y4MAXTMA.js +0 -80
  533. package/dist/web-components/chunk-Y7V7LM6R.js +0 -98
  534. package/src/web-components/ui/BdsButtonGroup.mdx +0 -69
  535. package/src/web-components/ui/BdsButtonGroup.stories.tsx +0 -66
@@ -1,6 +1,7 @@
1
1
  import { LitElement, css, html, nothing } from 'lit';
2
2
 
3
3
  export type CardVariant = 'default' | 'elevated' | 'outlined';
4
+ export type CardPadding = 'none' | 'small' | 'medium' | 'large' | 'extra-large';
4
5
  export type CardTextAlign = 'start' | 'center' | 'end';
5
6
 
6
7
  /**
@@ -8,11 +9,14 @@ export type CardTextAlign = 'start' | 'center' | 'end';
8
9
  *
9
10
  * Attributes:
10
11
  * variant — "default" (default) | "elevated" | "outlined"
11
- * --card_padding CSS custom property to override padding (default: var(--bds-space_m))
12
+ * padding "none" | "small" | "medium" (default) | "large" | "extra-large"
12
13
  * text-align — "start" (default) | "center" | "end"
13
14
  * clickable — boolean; renders as a <button> with hover/active effects
14
15
  * aria-label — accessible label (useful when clickable)
15
16
  *
17
+ * CSS Custom Properties:
18
+ * --card_padding — overrides the padding value applied by the active padding variant
19
+ *
16
20
  * Slots:
17
21
  * (default) — card content
18
22
  *
@@ -20,7 +24,7 @@ export type CardTextAlign = 'start' | 'center' | 'end';
20
24
  * bds-click — fired (bubbles, composed) when the card button is clicked
21
25
  *
22
26
  * @example
23
- * <bds-card variant="elevated" style="--card_padding: var(--bds-space_l)">
27
+ * <bds-card variant="elevated" padding="large">
24
28
  * <p>Card content</p>
25
29
  * </bds-card>
26
30
  *
@@ -30,6 +34,16 @@ export type CardTextAlign = 'start' | 'center' | 'end';
30
34
  */
31
35
  export class BdsCard extends LitElement {
32
36
  static styles = css`
37
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
38
+ here; otherwise elements with an explicit size + padding size as
39
+ content-box and layouts drift from the React (light-DOM) versions. */
40
+ :host,
41
+ *,
42
+ *::before,
43
+ *::after {
44
+ box-sizing: border-box;
45
+ }
46
+
33
47
  :host {
34
48
  display: block;
35
49
  }
@@ -46,7 +60,6 @@ export class BdsCard extends LitElement {
46
60
  text-align: inherit;
47
61
  font: inherit;
48
62
  border: none;
49
- padding: var(--card_padding, var(--bds-space_m));
50
63
  }
51
64
 
52
65
  /* Resting shadows — consumers can override per-variant via
@@ -60,18 +73,26 @@ export class BdsCard extends LitElement {
60
73
  box-shadow: var(--card_shadow--outlined, inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--bds-shadow_s));
61
74
  }
62
75
 
63
- .card.--text-start { text-align: start; }
64
- .card.--text-center { text-align: center; }
65
- .card.--text-end { text-align: end; }
66
-
67
76
  .card.--clickable {
68
77
  cursor: pointer;
69
78
  display: block;
70
79
  }
71
80
 
81
+ /* Padding variants — consumers can override the resolved value via --card_padding
82
+ (applies whichever scale token the active padding variant resolves to). */
83
+ .card.--padding-none { padding: var(--card_padding, 0); }
84
+ .card.--padding-small { padding: var(--card_padding, var(--bds-space_s)); }
85
+ .card.--padding-medium { padding: var(--card_padding, var(--bds-space_m)); }
86
+ .card.--padding-large { padding: var(--card_padding, var(--bds-space_l)); }
87
+ .card.--padding-extra-large { padding: var(--card_padding, var(--bds-space_xl)); }
88
+
89
+ .card.--text-start { text-align: start; }
90
+ .card.--text-center { text-align: center; }
91
+ .card.--text-end { text-align: end; }
92
+
72
93
  .card.--clickable:focus-visible {
73
- outline: 2px solid var(--color_focus, currentcolor);
74
- outline-offset: 2px;
94
+ outline: var(--bds-outline_default);
95
+ outline-offset: var(--bds-outline_offset);
75
96
  }
76
97
 
77
98
  .card.--clickable:active {
@@ -93,12 +114,14 @@ export class BdsCard extends LitElement {
93
114
 
94
115
  static properties = {
95
116
  variant: { type: String, reflect: true },
117
+ padding: { type: String, reflect: true },
96
118
  textAlign: { type: String, attribute: 'text-align', reflect: true },
97
119
  clickable: { type: Boolean, reflect: true },
98
120
  ariaLabel: { type: String, attribute: 'aria-label' },
99
121
  };
100
122
 
101
123
  declare variant: CardVariant;
124
+ declare padding: CardPadding;
102
125
  declare textAlign: CardTextAlign;
103
126
  declare clickable: boolean;
104
127
  declare ariaLabel: string;
@@ -106,6 +129,7 @@ export class BdsCard extends LitElement {
106
129
  constructor() {
107
130
  super();
108
131
  this.variant = 'default';
132
+ this.padding = 'medium';
109
133
  this.textAlign = 'start';
110
134
  this.clickable = false;
111
135
  this.ariaLabel = '';
@@ -119,6 +143,7 @@ export class BdsCard extends LitElement {
119
143
  const classes = [
120
144
  'card',
121
145
  `--${this.variant}`,
146
+ `--padding-${this.padding}`,
122
147
  `--text-${this.textAlign}`,
123
148
  this.clickable ? '--clickable' : '',
124
149
  ].filter(Boolean).join(' ');
@@ -61,4 +61,151 @@ describe('bds-carousel', () => {
61
61
  expect(dots.length).toBe(3);
62
62
  cleanup(el);
63
63
  });
64
+
65
+ it('exposes public goTo()/next()/prev() navigation methods', async () => {
66
+ const el = await fixture('<bds-carousel><div>S1</div><div>S2</div><div>S3</div></bds-carousel>') as BdsCarousel;
67
+ await el.updateComplete;
68
+
69
+ el.next();
70
+ await el.updateComplete;
71
+ expect(el.currentIndex).toBe(1);
72
+
73
+ el.goTo(2);
74
+ await el.updateComplete;
75
+ expect(el.currentIndex).toBe(2);
76
+
77
+ el.prev();
78
+ await el.updateComplete;
79
+ expect(el.currentIndex).toBe(1);
80
+
81
+ cleanup(el);
82
+ });
83
+
84
+ it('scrolls the target slide into view when current-index changes (goTo)', async () => {
85
+ const el = await fixture('<bds-carousel><div>S1</div><div>S2</div><div>S3</div></bds-carousel>') as BdsCarousel;
86
+ await el.updateComplete;
87
+ const slides = el.querySelectorAll('div');
88
+ const scrollIntoView = vi.fn();
89
+ slides[2].scrollIntoView = scrollIntoView;
90
+
91
+ el.goTo(2);
92
+ await el.updateComplete;
93
+
94
+ expect(scrollIntoView).toHaveBeenCalled();
95
+ cleanup(el);
96
+ });
97
+
98
+ it('scrolls the target slide into view when the current-index attribute is set externally', async () => {
99
+ const el = await fixture('<bds-carousel><div>S1</div><div>S2</div></bds-carousel>') as BdsCarousel;
100
+ await el.updateComplete;
101
+ const slides = el.querySelectorAll('div');
102
+ const scrollIntoView = vi.fn();
103
+ slides[1].scrollIntoView = scrollIntoView;
104
+
105
+ el.setAttribute('current-index', '1');
106
+ await el.updateComplete;
107
+
108
+ expect(scrollIntoView).toHaveBeenCalled();
109
+ cleanup(el);
110
+ });
111
+
112
+ it('navigates when a custom slotted prev/next button is clicked', async () => {
113
+ const el = await fixture(`
114
+ <bds-carousel current-index="1">
115
+ <div>S1</div><div>S2</div><div>S3</div>
116
+ <button slot="prev" class="custom-prev">Back</button>
117
+ <button slot="next" class="custom-next">Forward</button>
118
+ </bds-carousel>
119
+ `) as BdsCarousel;
120
+ await el.updateComplete;
121
+
122
+ const customPrev = el.querySelector<HTMLButtonElement>('.custom-prev')!;
123
+ customPrev.click();
124
+ await el.updateComplete;
125
+ expect(el.currentIndex).toBe(0);
126
+
127
+ const customNext = el.querySelector<HTMLButtonElement>('.custom-next')!;
128
+ customNext.click();
129
+ await el.updateComplete;
130
+ expect(el.currentIndex).toBe(1);
131
+
132
+ cleanup(el);
133
+ });
134
+
135
+ it('excludes named-slot (prev/next) children from the slide count', async () => {
136
+ const el = await fixture(`
137
+ <bds-carousel indicators>
138
+ <div>S1</div><div>S2</div>
139
+ <button slot="prev">Prev</button>
140
+ <button slot="next">Next</button>
141
+ </bds-carousel>
142
+ `);
143
+ await el.updateComplete;
144
+ const dots = el.shadowRoot!.querySelectorAll('.dot');
145
+ expect(dots.length).toBe(2);
146
+ cleanup(el);
147
+ });
148
+
149
+ it('fires bds-slide-change when the active slide changes via manual scroll', async () => {
150
+ class MockIntersectionObserver {
151
+ static instances: MockIntersectionObserver[] = [];
152
+ callback: IntersectionObserverCallback;
153
+ constructor(callback: IntersectionObserverCallback) {
154
+ this.callback = callback;
155
+ MockIntersectionObserver.instances.push(this);
156
+ }
157
+ observe() {}
158
+ disconnect() {}
159
+ unobserve() {}
160
+ takeRecords() { return []; }
161
+ }
162
+ const OriginalIO = (globalThis as { IntersectionObserver?: unknown }).IntersectionObserver;
163
+ (globalThis as { IntersectionObserver?: unknown }).IntersectionObserver = MockIntersectionObserver;
164
+
165
+ try {
166
+ const el = await fixture('<bds-carousel><div>S1</div><div>S2</div><div>S3</div></bds-carousel>') as BdsCarousel;
167
+ await el.updateComplete;
168
+
169
+ const changes: number[] = [];
170
+ el.addEventListener('bds-slide-change', (e: Event) => {
171
+ changes.push((e as CustomEvent).detail.index);
172
+ });
173
+
174
+ const slides = el.querySelectorAll('div');
175
+ const observer = MockIntersectionObserver.instances.at(-1)!;
176
+ observer.callback(
177
+ [{ isIntersecting: true, intersectionRatio: 1, target: slides[2] } as IntersectionObserverEntry],
178
+ observer as unknown as IntersectionObserver,
179
+ );
180
+
181
+ expect(changes).toEqual([2]);
182
+ expect(el.currentIndex).toBe(2);
183
+ cleanup(el);
184
+ } finally {
185
+ (globalThis as { IntersectionObserver?: unknown }).IntersectionObserver = OriginalIO;
186
+ }
187
+ });
188
+
189
+ it('uses aria-current on dots instead of an incomplete tabs pattern', async () => {
190
+ const el = await fixture('<bds-carousel indicators current-index="1"><div>S1</div><div>S2</div></bds-carousel>');
191
+ await el.updateComplete;
192
+ const dots = el.shadowRoot!.querySelectorAll('.dot');
193
+ expect(dots[0].getAttribute('role')).toBeNull();
194
+ expect(dots[1].getAttribute('role')).toBeNull();
195
+ expect(dots[0].getAttribute('aria-current')).toBe('false');
196
+ expect(dots[1].getAttribute('aria-current')).toBe('true');
197
+ expect(el.shadowRoot!.querySelector('[role="tablist"]')).toBeNull();
198
+ cleanup(el);
199
+ });
200
+
201
+ it('supports custom label / prev-label / next-label attributes', async () => {
202
+ const el = await fixture(
203
+ '<bds-carousel label="Featured products" prev-label="Vorige" next-label="Volgende"><div>S1</div></bds-carousel>',
204
+ );
205
+ await el.updateComplete;
206
+ expect(el.shadowRoot!.querySelector('.track')!.getAttribute('aria-label')).toBe('Featured products');
207
+ expect(el.shadowRoot!.querySelector('[aria-label="Vorige"]')).not.toBeNull();
208
+ expect(el.shadowRoot!.querySelector('[aria-label="Volgende"]')).not.toBeNull();
209
+ cleanup(el);
210
+ });
64
211
  });
@@ -4,17 +4,28 @@ import { LitElement, css, html } from 'lit';
4
4
  * `<bds-carousel>` — scroll-snap based carousel/slider.
5
5
  *
6
6
  * Attributes:
7
- * current-index — active slide index (0-based, default: 0)
7
+ * current-index — active slide index (0-based, default: 0); setting it scrolls the track
8
8
  * indicators — show dot indicators
9
9
  * loop — wrap from last slide back to first and vice versa
10
+ * label — accessible name for the slide region (default: "Carousel")
11
+ * prev-label — accessible name for the previous button (default: "Previous slide")
12
+ * next-label — accessible name for the next button (default: "Next slide")
10
13
  *
11
14
  * Slots:
12
- * (default) — slide content elements (each direct child = one slide)
13
- * prev — custom previous button (renders a default button if omitted)
14
- * next — custom next button (renders a default button if omitted)
15
+ * (default) — slide content elements (each direct child with no `slot` attribute = one slide)
16
+ * prev — custom previous button (renders a default button if omitted); clicks anywhere
17
+ * inside this slot navigate to the previous slide
18
+ * next — custom next button (renders a default button if omitted); clicks anywhere
19
+ * inside this slot navigate to the next slide
20
+ *
21
+ * Methods:
22
+ * goTo(index) — navigate to a specific slide (clamped, or wrapped when `loop` is set)
23
+ * next() — navigate to the next slide
24
+ * prev() — navigate to the previous slide
15
25
  *
16
26
  * Events:
17
- * bds-slide-change — fired when active slide changes; `detail: { index: number }`
27
+ * bds-slide-change — fired when active slide changes (navigation or manual scroll/swipe);
28
+ * `detail: { index: number }`
18
29
  *
19
30
  * @example
20
31
  * <bds-carousel indicators loop>
@@ -25,6 +36,16 @@ import { LitElement, css, html } from 'lit';
25
36
  */
26
37
  export class BdsCarousel extends LitElement {
27
38
  static styles = css`
39
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
40
+ here; otherwise elements with an explicit size + padding size as
41
+ content-box and layouts drift from the React (light-DOM) versions. */
42
+ :host,
43
+ *,
44
+ *::before,
45
+ *::after {
46
+ box-sizing: border-box;
47
+ }
48
+
28
49
  :host {
29
50
  display: block;
30
51
  position: relative;
@@ -62,10 +83,14 @@ export class BdsCarousel extends LitElement {
62
83
  justify-content: center;
63
84
  inline-size: 2.5rem;
64
85
  block-size: 2.5rem;
65
- border: none;
66
- border-radius: var(--bds-border_radius--full, 9999px);
67
- background-color: var(--bds-color_bg--subtle);
86
+ border-radius: var(--carousel_navBtn-radius, var(--carousel_indicator-radius, var(--bds-border_radius--circle)));
87
+ background-color: var(--carousel_navBtn-bg, var(--bds-color_bg));
68
88
  color: var(--bds-color_on-bg);
89
+
90
+ --bdc_color: var(--bds-color_on-bg);
91
+
92
+ border: none;
93
+ box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--bds-shadow_s);
69
94
  cursor: pointer;
70
95
  transition: var(--bds-animation_transition);
71
96
  }
@@ -77,7 +102,7 @@ export class BdsCarousel extends LitElement {
77
102
 
78
103
  @media (hover: hover) and (pointer: fine) {
79
104
  .nav-btn:hover {
80
- background-color: var(--bds-color_bg--strong);
105
+ background-color: var(--carousel_navBtn-bg--hover, var(--bds-color_bg--subtle));
81
106
  }
82
107
  }
83
108
 
@@ -100,20 +125,33 @@ export class BdsCarousel extends LitElement {
100
125
  }
101
126
 
102
127
  .dot {
128
+ position: relative;
103
129
  inline-size: 0.5rem;
104
130
  block-size: 0.5rem;
105
- border-radius: 50%;
131
+ border-radius: var(--carousel_indicator-radius, var(--bds-border_radius--circle));
106
132
  border: none;
107
133
  padding: 0;
108
- background-color: var(--bds-color_bg--strong);
134
+ background-color: var(--carousel_indicator-bg, var(--bds-color_bg--strong));
109
135
  cursor: pointer;
110
136
  transition: var(--bds-animation_transition);
111
137
  }
112
138
 
139
+ /* Invisible hit-area overlay: keeps the 8px visual dot but expands the tappable
140
+ region to ~24px (WCAG 2.5.8 minimum) without affecting the flex layout/gap. */
141
+ .dot::before {
142
+ content: '';
143
+ position: absolute;
144
+ inset-block-start: 50%;
145
+ inset-inline-start: 50%;
146
+ translate: -50% -50%;
147
+ inline-size: 1.5rem;
148
+ block-size: 1.5rem;
149
+ }
150
+
113
151
  .dot.--active {
114
- background-color: var(--bds-color_interactive);
152
+ background-color: var(--carousel_indicator-bg--active, var(--bds-color_interactive));
115
153
  inline-size: 1rem;
116
- border-radius: 0.25rem;
154
+ border-radius: var(--carousel_indicator-radius--active, var(--bds-border_radius--full));
117
155
  }
118
156
 
119
157
  .dot:focus-visible {
@@ -132,20 +170,30 @@ export class BdsCarousel extends LitElement {
132
170
  currentIndex: { type: Number, attribute: 'current-index', reflect: true },
133
171
  indicators: { type: Boolean, reflect: true },
134
172
  loop: { type: Boolean, reflect: true },
173
+ label: { type: String },
174
+ prevLabel: { type: String, attribute: 'prev-label' },
175
+ nextLabel: { type: String, attribute: 'next-label' },
135
176
  };
136
177
 
137
178
  declare currentIndex: number;
138
179
  declare indicators: boolean;
139
180
  declare loop: boolean;
181
+ declare label: string;
182
+ declare prevLabel: string;
183
+ declare nextLabel: string;
140
184
 
141
185
  private _slideCount = 0;
142
186
  private _io: IntersectionObserver | null = null;
187
+ private _skipNextScroll = false;
143
188
 
144
189
  constructor() {
145
190
  super();
146
191
  this.currentIndex = 0;
147
192
  this.indicators = false;
148
193
  this.loop = false;
194
+ this.label = 'Carousel';
195
+ this.prevLabel = 'Previous slide';
196
+ this.nextLabel = 'Next slide';
149
197
  }
150
198
 
151
199
  private get _track(): HTMLElement | null {
@@ -164,12 +212,49 @@ export class BdsCarousel extends LitElement {
164
212
  this._io = null;
165
213
  }
166
214
 
215
+ updated(changed: Map<string, unknown>) {
216
+ super.updated(changed);
217
+ if (changed.has('currentIndex')) {
218
+ if (this._skipNextScroll) {
219
+ this._skipNextScroll = false;
220
+ } else {
221
+ this._scrollToIndex(this.currentIndex);
222
+ }
223
+ }
224
+ }
225
+
226
+ /** Navigate to a specific slide (clamped, or wrapped when `loop` is set). */
227
+ goTo(index: number): void {
228
+ this._setIndex(index, true);
229
+ }
230
+
231
+ /** Navigate to the next slide. */
232
+ next(): void {
233
+ this._setIndex(this.currentIndex + 1, true);
234
+ }
235
+
236
+ /** Navigate to the previous slide. */
237
+ prev(): void {
238
+ this._setIndex(this.currentIndex - 1, true);
239
+ }
240
+
167
241
  private _updateSlideCount() {
168
- this._slideCount = this.children.length;
242
+ // Only direct children with no `slot` attribute belong to the default slide slot;
243
+ // children assigned to the named prev/next slots must not inflate the slide count.
244
+ this._slideCount = Array.from(this.children).filter(child => !child.hasAttribute('slot')).length;
169
245
  this.requestUpdate();
170
246
  }
171
247
 
172
- private _goTo(index: number) {
248
+ private _scrollToIndex(index: number) {
249
+ const track = this._track;
250
+ const slides = track?.querySelector('slot')?.assignedElements() ?? [];
251
+ const target = slides[index] as HTMLElement | undefined;
252
+ if (target && typeof target.scrollIntoView === 'function') {
253
+ target.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
254
+ }
255
+ }
256
+
257
+ private _setIndex(index: number, scroll: boolean) {
173
258
  const count = this._slideCount;
174
259
  if (count === 0) return;
175
260
 
@@ -180,17 +265,11 @@ export class BdsCarousel extends LitElement {
180
265
  next = Math.max(0, Math.min(index, count - 1));
181
266
  }
182
267
 
183
- if (next === this.currentIndex && index === next) return;
268
+ if (next === this.currentIndex) return;
184
269
 
270
+ this._skipNextScroll = !scroll;
185
271
  this.currentIndex = next;
186
272
 
187
- const track = this._track;
188
- const slides = track?.querySelector('slot')?.assignedElements() ?? [];
189
- const target = slides[next] as HTMLElement | undefined;
190
- if (target && typeof target.scrollIntoView === 'function') {
191
- target.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' });
192
- }
193
-
194
273
  this.dispatchEvent(new CustomEvent('bds-slide-change', {
195
274
  detail: { index: next },
196
275
  bubbles: true,
@@ -216,8 +295,9 @@ export class BdsCarousel extends LitElement {
216
295
  if (visible) {
217
296
  const idx = slides.indexOf(visible.target as Element);
218
297
  if (idx !== -1 && idx !== this.currentIndex) {
219
- this.currentIndex = idx;
220
- this.requestUpdate();
298
+ // The slide is already in view (this is a manual scroll/swipe) — sync state
299
+ // and notify consumers, but don't re-trigger a programmatic scroll.
300
+ this._setIndex(idx, false);
221
301
  }
222
302
  }
223
303
  },
@@ -234,17 +314,16 @@ export class BdsCarousel extends LitElement {
234
314
  const showNext = this.loop || !atEnd;
235
315
 
236
316
  return html`
237
- <div class="track" aria-label="Carousel" role="region">
317
+ <div class="track" aria-label=${this.label} role="region">
238
318
  <slot @slotchange=${this._onSlotChange}></slot>
239
319
  </div>
240
320
  <div class="controls">
241
- <slot name="prev">
321
+ <slot name="prev" @click=${() => this.prev()}>
242
322
  <button
243
323
  class="nav-btn"
244
324
  type="button"
245
- aria-label="Previous slide"
325
+ aria-label=${this.prevLabel}
246
326
  ?disabled=${!showPrev}
247
- @click=${() => this._goTo(this.currentIndex - 1)}
248
327
  >
249
328
  <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
250
329
  <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" />
@@ -254,28 +333,26 @@ export class BdsCarousel extends LitElement {
254
333
 
255
334
  ${this.indicators
256
335
  ? html`
257
- <div class="indicators" role="tablist" aria-label="Slides">
336
+ <div class="indicators" role="group" aria-label="Slides">
258
337
  ${Array.from({ length: this._slideCount }, (_, i) => html`
259
338
  <button
260
339
  class="dot ${i === this.currentIndex ? '--active' : ''}"
261
340
  type="button"
262
- role="tab"
263
- aria-selected=${i === this.currentIndex ? 'true' : 'false'}
341
+ aria-current=${i === this.currentIndex ? 'true' : 'false'}
264
342
  aria-label="Slide ${i + 1}"
265
- @click=${() => this._goTo(i)}
343
+ @click=${() => this.goTo(i)}
266
344
  ></button>
267
345
  `)}
268
346
  </div>
269
347
  `
270
348
  : html`<span style="flex:1"></span>`}
271
349
 
272
- <slot name="next">
350
+ <slot name="next" @click=${() => this.next()}>
273
351
  <button
274
352
  class="nav-btn"
275
353
  type="button"
276
- aria-label="Next slide"
354
+ aria-label=${this.nextLabel}
277
355
  ?disabled=${!showNext}
278
- @click=${() => this._goTo(this.currentIndex + 1)}
279
356
  >
280
357
  <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
281
358
  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" />
@@ -33,4 +33,19 @@ describe('bds-description-list', () => {
33
33
  expect(el.getAttribute('layout')).toBe('stacked');
34
34
  cleanup(el);
35
35
  });
36
+
37
+ it('lays dt/dd out side by side in a two-column grid when layout="inline"', () => {
38
+ const cssText = BdsDescriptionList.styles.cssText;
39
+ expect(cssText).toMatch(/:host\(\[layout='inline'\]\)\s*\.list\s*{[^}]*display:\s*grid/);
40
+ expect(cssText).toMatch(/:host\(\[layout='inline'\]\)\s*\.list\s*{[^}]*grid-template-columns:\s*minmax\(8rem,\s*1fr\)\s*2fr/);
41
+ expect(cssText).toMatch(/:host\(\[layout='inline'\]\)\s*::slotted\(dt\)\s*{[^}]*grid-column:\s*1/);
42
+ expect(cssText).toMatch(/:host\(\[layout='inline'\]\)\s*::slotted\(dd\)\s*{[^}]*grid-column:\s*2/);
43
+ });
44
+
45
+ it('gives stacked mode a tight xxs gap within a term/detail pair and a looser s gap before the next term', () => {
46
+ const cssText = BdsDescriptionList.styles.cssText;
47
+ expect(cssText).toMatch(/::slotted\(dt\)\s*{[^}]*margin-block-start:\s*var\(--bds-space_s\)/);
48
+ expect(cssText).toMatch(/::slotted\(dt:first-child\)\s*{\s*margin-block-start:\s*0/);
49
+ expect(cssText).toMatch(/::slotted\(dd\)\s*{[^}]*margin-block-start:\s*var\(--bds-space_xxs\)/);
50
+ });
36
51
  });
@@ -22,6 +22,16 @@ import { LitElement, css, html } from 'lit';
22
22
  */
23
23
  export class BdsDescriptionList extends LitElement {
24
24
  static styles = css`
25
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
26
+ here; otherwise elements with an explicit size + padding size as
27
+ content-box and layouts drift from the React (light-DOM) versions. */
28
+ :host,
29
+ *,
30
+ *::before,
31
+ *::after {
32
+ box-sizing: border-box;
33
+ }
34
+
25
35
  :host {
26
36
  display: block;
27
37
  }
@@ -29,28 +39,52 @@ export class BdsDescriptionList extends LitElement {
29
39
  .list {
30
40
  display: flex;
31
41
  flex-direction: column;
32
- gap: var(--bds-space_s);
33
42
  margin: 0;
34
43
  padding: 0;
35
44
  font-size: var(--bds-font_size--body);
36
45
  color: var(--bds-color_on-bg);
37
46
  }
38
47
 
39
- /* Style slotted dt/dd elements */
48
+ /* Style slotted dt/dd elements. Stacked spacing is asymmetric: a tight
49
+ xxs gap between a term and its own detail(s), and a looser "s" gap
50
+ before the next term — mirrors DescriptionList.module.css's
51
+ .group (xxs) nested inside .list (s), without a wrapper element. */
40
52
  ::slotted(dt) {
41
53
  font-weight: var(--bds-font_weight--semibold);
42
54
  color: var(--bds-color_on-bg);
43
55
  margin: 0;
56
+ margin-block-start: var(--bds-space_s);
57
+ }
58
+
59
+ ::slotted(dt:first-child) {
60
+ margin-block-start: 0;
44
61
  }
45
62
 
46
63
  ::slotted(dd) {
47
64
  margin: 0;
65
+ margin-block-start: var(--bds-space_xxs);
48
66
  color: var(--bds-color_on-bg);
49
67
  }
50
68
 
51
- /* Inline layout: pair each dt/dd side by side */
69
+ /* Inline layout: pair each dt/dd side by side. <slot> defaults to
70
+ display: contents, so slotted dt/dd become direct grid items of
71
+ .list and the browser's row-by-row auto-placement pairs each term
72
+ with the detail(s) that follow it. */
52
73
  :host([layout='inline']) .list {
74
+ display: grid;
75
+ grid-template-columns: minmax(8rem, 1fr) 2fr;
53
76
  gap: var(--bds-space_xs);
77
+ align-items: baseline;
78
+ }
79
+
80
+ :host([layout='inline']) ::slotted(dt) {
81
+ grid-column: 1;
82
+ margin-block-start: 0;
83
+ }
84
+
85
+ :host([layout='inline']) ::slotted(dd) {
86
+ grid-column: 2;
87
+ margin-block-start: 0;
54
88
  }
55
89
  `;
56
90
 
@@ -18,4 +18,16 @@ describe('bds-icon-wrapper', () => {
18
18
  expect(svg).not.toBeNull();
19
19
  cleanup(el);
20
20
  });
21
+
22
+ it('does not stamp an empty aria-hidden attribute onto the host by default', async () => {
23
+ const el = await fixture('<bds-icon-wrapper></bds-icon-wrapper>');
24
+ expect(el.hasAttribute('aria-hidden')).toBe(false);
25
+ cleanup(el);
26
+ });
27
+
28
+ it('preserves a consumer-supplied aria-hidden attribute', async () => {
29
+ const el = await fixture('<bds-icon-wrapper aria-hidden="true"></bds-icon-wrapper>');
30
+ expect(el.getAttribute('aria-hidden')).toBe('true');
31
+ cleanup(el);
32
+ });
21
33
  });