@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.
Files changed (534) 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-OF6FFGOT.js → chunk-3AY2YKCM.js} +77 -21
  15. package/dist/web-components/chunk-3WAV6MDN.js +212 -0
  16. package/dist/web-components/{chunk-UUKSDCYS.js → chunk-47AT5KZD.js} +87 -15
  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-QLT6MTZF.js → chunk-AIBOHNDU.js} +10 -0
  23. package/dist/web-components/{chunk-X3NQMBAQ.js → chunk-AP4RDUL2.js} +14 -3
  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-ARMKC4BQ.js → chunk-JH6LQKLK.js} +77 -5
  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-FSZRP43R.js → chunk-WFVKU4GX.js} +21 -10
  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-ORC56MDY.js → chunk-XIZWAWMJ.js} +45 -6
  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 +55 -8
  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 +101 -16
  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 +135 -22
  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 +95 -7
  441. package/src/web-components/interaction/form/bds-slider.spec.ts +83 -0
  442. package/src/web-components/interaction/form/bds-slider.ts +154 -26
  443. package/src/web-components/interaction/form/bds-switch.spec.ts +68 -0
  444. package/src/web-components/interaction/form/bds-switch.ts +87 -20
  445. package/src/web-components/interaction/form/bds-textarea.spec.ts +71 -0
  446. package/src/web-components/interaction/form/bds-textarea.ts +108 -7
  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 +29 -11
  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 +109 -32
  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 +15 -14
  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 +10 -0
  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 +17 -4
  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-7YURXHTS.js +0 -147
  526. package/dist/web-components/chunk-A3RLT3AS.js +0 -49
  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-DZOEPVFT.js +0 -107
  530. package/dist/web-components/chunk-JYYRJS2D.js +0 -118
  531. package/dist/web-components/chunk-Y4MAXTMA.js +0 -80
  532. package/dist/web-components/chunk-Y7V7LM6R.js +0 -98
  533. package/src/web-components/ui/BdsButtonGroup.mdx +0 -69
  534. package/src/web-components/ui/BdsButtonGroup.stories.tsx +0 -66
@@ -3,19 +3,19 @@ import type { Meta, StoryObj } from '@storybook/react';
3
3
  import '../index'; // auto-registers all custom elements
4
4
 
5
5
  function BdsSectionHeader({
6
- title = '',
6
+ heading = '',
7
7
  subtitle,
8
8
  alignment = 'start',
9
9
  size = 'medium',
10
10
  titleAs,
11
11
  }: {
12
- title?: string;
12
+ heading?: string;
13
13
  subtitle?: string;
14
14
  alignment?: 'start' | 'center' | 'end';
15
- size?: 'small' | 'medium' | 'large';
15
+ size?: 'xs' | 'small' | 'medium' | 'large';
16
16
  titleAs?: string;
17
17
  }) {
18
- return React.createElement('bds-section-header', { title, subtitle, alignment, size, 'title-as': titleAs });
18
+ return React.createElement('bds-section-header', { heading, subtitle, alignment, size, 'title-as': titleAs });
19
19
  }
20
20
 
21
21
  const meta = {
@@ -25,7 +25,7 @@ const meta = {
25
25
  parameters: { layout: 'padded' },
26
26
  argTypes: {
27
27
  alignment: { control: 'select', options: ['start', 'center', 'end'] },
28
- size: { control: 'select', options: ['small', 'medium', 'large'] },
28
+ size: { control: 'select', options: ['xs', 'small', 'medium', 'large'] },
29
29
  titleAs: { control: 'text' },
30
30
  },
31
31
  } satisfies Meta<typeof BdsSectionHeader>;
@@ -34,21 +34,23 @@ export default meta;
34
34
  type Story = StoryObj<typeof meta>;
35
35
 
36
36
  export const Default: Story = {
37
- args: { title: 'Our Products', subtitle: 'Browse the full range', size: 'medium', alignment: 'start' },
37
+ args: { heading: 'Our Products', subtitle: 'Browse the full range', size: 'medium', alignment: 'start' },
38
38
  };
39
- export const Small: Story = { args: { title: 'Recent Activity', subtitle: 'Last 30 days', size: 'small' } };
40
- export const Large: Story = { args: { title: 'Welcome Back', subtitle: 'Here is what happened today', size: 'large' } };
39
+ export const ExtraSmall: Story = { args: { heading: 'Filters', subtitle: 'Refine the results', size: 'xs' } };
40
+ export const Small: Story = { args: { heading: 'Recent Activity', subtitle: 'Last 30 days', size: 'small' } };
41
+ export const Large: Story = { args: { heading: 'Welcome Back', subtitle: 'Here is what happened today', size: 'large' } };
41
42
  export const Centered: Story = {
42
- args: { title: 'Our Mission', subtitle: 'We are building something great', alignment: 'center' },
43
+ args: { heading: 'Our Mission', subtitle: 'We are building something great', alignment: 'center' },
43
44
  };
44
- export const TitleOnly: Story = { args: { title: 'Settings', size: 'small' } };
45
+ export const TitleOnly: Story = { args: { heading: 'Settings', size: 'small' } };
45
46
 
46
47
  export const AllSizes: Story = {
47
48
  render: () => (
48
49
  <div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
49
- {React.createElement('bds-section-header', { title: 'Small Heading', subtitle: 'Subtitle text', size: 'small' })}
50
- {React.createElement('bds-section-header', { title: 'Medium Heading', subtitle: 'Subtitle text', size: 'medium' })}
51
- {React.createElement('bds-section-header', { title: 'Large Heading', subtitle: 'Subtitle text', size: 'large' })}
50
+ {React.createElement('bds-section-header', { heading: 'Extra Small Heading', subtitle: 'Subtitle text', size: 'xs' })}
51
+ {React.createElement('bds-section-header', { heading: 'Small Heading', subtitle: 'Subtitle text', size: 'small' })}
52
+ {React.createElement('bds-section-header', { heading: 'Medium Heading', subtitle: 'Subtitle text', size: 'medium' })}
53
+ {React.createElement('bds-section-header', { heading: 'Large Heading', subtitle: 'Subtitle text', size: 'large' })}
52
54
  </div>
53
55
  ),
54
56
  };
@@ -9,6 +9,13 @@ Framework-agnostic scrollable Table wrapper custom element. Apply design-system
9
9
 
10
10
  > **Status: experimental** — API may change before stable release.
11
11
 
12
+ > **Light-DOM styling contract:** `::slotted()` can only match the node placed directly into
13
+ > the slot (the `<table>` itself), never its descendants. `<thead>`/`<th>`/`<td>` styling is
14
+ > therefore shipped as a document-level stylesheet scoped to the `bds-table > table …` selector
15
+ > (adopted once, the first time any `<bds-table>` module is imported). This means the slotted
16
+ > `<table>` must be a **direct child** of `<bds-table>` for cell styling and `sticky-header` to
17
+ > apply — don't wrap it in an intermediate element.
18
+
12
19
  ## Installation
13
20
 
14
21
  ```js
@@ -37,12 +44,21 @@ import '@boostdev/design-system-components/web-components';
37
44
  | Attribute | Type | Default | Description |
38
45
  |-----------|------|---------|-------------|
39
46
  | `sticky-header` | boolean | `false` | Freezes `<thead>` at the top when the table overflows vertically |
47
+ | `aria-label` | string | — | Accessible name for the scrollable region; also enables `role="region"` on the wrapper |
40
48
 
41
49
  ## Slots
42
50
 
43
51
  | Slot | Description |
44
52
  |------|-------------|
45
- | `(default)` | A standard `<table>` element with `<thead>` and `<tbody>` |
53
+ | `(default)` | A standard `<table>` element (must be a direct child — see the light-DOM styling contract above) |
54
+
55
+ ## CSS Custom Properties
56
+
57
+ | Property | Description |
58
+ |----------|-------------|
59
+ | `--table_border` | Wrapper border (default: `none`) |
60
+ | `--table_radius` | Wrapper corner radius (default: `var(--bdc-outline_radius)`, itself set to `var(--bds-border_radius--s)` on the wrapper) |
61
+ | `--table_row-bg--hover` | Row background on hover, pointer devices only (default: `var(--bds-color_bg--subtle)`) |
46
62
 
47
63
  ## Usage in plain HTML
48
64
 
@@ -78,4 +94,9 @@ import '@boostdev/design-system-components/web-components';
78
94
 
79
95
  - Use a standard `<table>` with proper `<thead>` / `<tbody>` structure
80
96
  - Column headers (`<th>`) are automatically styled; add `scope="col"` for complex tables
81
- - The wrapper is horizontally scrollable (`overflow-inline: auto`) on small viewports
97
+ - The wrapper is horizontally scrollable (`overflow-inline: auto`) on small viewports and is
98
+ keyboard-focusable (`tabindex="0"`) with a `:focus-visible` outline, so it can be scrolled
99
+ without a mouse in browsers that don't auto-focus scroll containers
100
+ - Set `aria-label` on `<bds-table>` to give the scrollable region an accessible name — this also
101
+ adds `role="region"` on the wrapper; without it, the wrapper stays unlabelled and roleless to
102
+ avoid a nameless landmark
@@ -4,14 +4,16 @@ import '../index'; // auto-registers all custom elements
4
4
 
5
5
  function BdsTable({
6
6
  stickyHeader,
7
+ ariaLabel,
7
8
  children,
8
9
  }: {
9
10
  stickyHeader?: boolean;
11
+ ariaLabel?: string;
10
12
  children?: React.ReactNode;
11
13
  }) {
12
14
  return React.createElement(
13
15
  'bds-table',
14
- { 'sticky-header': stickyHeader || undefined },
16
+ { 'sticky-header': stickyHeader || undefined, 'aria-label': ariaLabel },
15
17
  children,
16
18
  );
17
19
  }
@@ -77,7 +79,11 @@ export const Default: Story = {
77
79
  export const StickyHeader: Story = {
78
80
  render: () => (
79
81
  <div style={{ padding: 24, maxHeight: 200, overflow: 'auto' }}>
80
- {React.createElement('bds-table', { 'sticky-header': true }, sampleTable())}
82
+ {React.createElement(
83
+ 'bds-table',
84
+ { 'sticky-header': true, 'aria-label': 'Team members' },
85
+ sampleTable(),
86
+ )}
81
87
  </div>
82
88
  ),
83
89
  };
@@ -52,7 +52,7 @@ import '@boostdev/design-system-components/web-components';
52
52
  | Attribute | Type | Default | Description |
53
53
  |-----------|------|---------|-------------|
54
54
  | `variant` | `"h1" \| "h2" \| "h3" \| "body" \| "body_s"` | `"body"` | Visual style and default semantic tag |
55
- | `component` | string | — | Override the rendered HTML tag (e.g. `"span"`, `"label"`) |
55
+ | `component` | string | — | Override the rendered HTML tag (e.g. `"span"`, `"label"`). Reflects to the host attribute, so it also works when set as a JS property (e.g. from React). |
56
56
 
57
57
  ## Slots
58
58
 
@@ -60,6 +60,17 @@ import '@boostdev/design-system-components/web-components';
60
60
  |------|-------------|
61
61
  | `(default)` | Text content |
62
62
 
63
+ ## CSS Custom Properties
64
+
65
+ | Property | Description |
66
+ |----------|-------------|
67
+ | `--typography_color` | Text colour (default: `--bds-color_on-bg`) |
68
+ | `--typography_font-size--h1` | Font size for the `h1` variant (default: `--bds-font_size--heading-1`) |
69
+ | `--typography_font-size--h2` | Font size for the `h2` variant (default: `--bds-font_size--heading-2`) |
70
+ | `--typography_font-size--h3` | Font size for the `h3` variant (default: `--bds-font_size--heading-3`) |
71
+ | `--typography_font-size--body` | Font size for the `body` variant (default: `--bds-font_size--body`) |
72
+ | `--typography_font-size--body_s` | Font size for the `body_s` variant (default: `--bds-font_size--body--s`) |
73
+
63
74
  ## Usage in plain HTML
64
75
 
65
76
  ```html
@@ -68,6 +79,11 @@ import '@boostdev/design-system-components/web-components';
68
79
  <bds-typography variant="body_s" component="span">Small helper text</bds-typography>
69
80
  ```
70
81
 
82
+ ## Layout
83
+
84
+ - The host is `display: block` by default (headings and paragraphs are block-level elements).
85
+ - `component="span"` switches the host to `display: inline` so the element flows inline like a native `<span>`. Other inline tag overrides (e.g. `"label"`) still need host restyling if inline flow is required.
86
+
71
87
  ## Accessibility
72
88
 
73
89
  - Uses semantic heading elements (`h1`–`h3`) or `<p>` by default
@@ -51,7 +51,15 @@ describe('bds-alert', () => {
51
51
  cleanup(el);
52
52
  });
53
53
 
54
- it('renders title when title attribute is set', async () => {
54
+ it('renders heading when heading attribute is set', async () => {
55
+ const el = await fixture('<bds-alert heading="Heads up">Message</bds-alert>');
56
+ const strong = el.shadowRoot!.querySelector('strong.title');
57
+ expect(strong).not.toBeNull();
58
+ expect(strong!.textContent).toBe('Heads up');
59
+ cleanup(el);
60
+ });
61
+
62
+ it('renders heading text from the deprecated title attribute as a fallback', async () => {
55
63
  const el = await fixture('<bds-alert title="Heads up">Message</bds-alert>');
56
64
  const strong = el.shadowRoot!.querySelector('strong.title');
57
65
  expect(strong).not.toBeNull();
@@ -59,7 +67,14 @@ describe('bds-alert', () => {
59
67
  cleanup(el);
60
68
  });
61
69
 
62
- it('does not render title element when title is not set', async () => {
70
+ it('prefers heading over the deprecated title attribute when both are set', async () => {
71
+ const el = await fixture('<bds-alert heading="New" title="Old">Message</bds-alert>');
72
+ const strong = el.shadowRoot!.querySelector('strong.title');
73
+ expect(strong!.textContent).toBe('New');
74
+ cleanup(el);
75
+ });
76
+
77
+ it('does not render title element when neither heading nor title is set', async () => {
63
78
  const el = await fixture('<bds-alert>Message</bds-alert>');
64
79
  const strong = el.shadowRoot!.querySelector('strong.title');
65
80
  expect(strong).toBeNull();
@@ -7,7 +7,11 @@ export type AlertVariant = 'info' | 'success' | 'warning' | 'error';
7
7
  *
8
8
  * Attributes:
9
9
  * variant — "info" (default) | "success" | "warning" | "error"
10
- * title — optional heading above the body text
10
+ * heading — optional heading above the body text
11
+ * title — deprecated alias for `heading`. Collides with the global HTML
12
+ * `title` attribute, which triggers a native browser tooltip on
13
+ * hover — use `heading` instead. Kept working for backwards
14
+ * compatibility; will be removed in a later major.
11
15
  * dismissible — boolean; shows a dismiss button when present
12
16
  *
13
17
  * Slots:
@@ -22,7 +26,7 @@ export type AlertVariant = 'info' | 'success' | 'warning' | 'error';
22
26
  * role="status" + aria-live="polite" for info/success variants.
23
27
  *
24
28
  * @example
25
- * <bds-alert variant="success" title="Saved!">Your changes have been saved.</bds-alert>
29
+ * <bds-alert variant="success" heading="Saved!">Your changes have been saved.</bds-alert>
26
30
  *
27
31
  * <bds-alert variant="error" dismissible>
28
32
  * <svg slot="icon">…</svg>
@@ -31,6 +35,16 @@ export type AlertVariant = 'info' | 'success' | 'warning' | 'error';
31
35
  */
32
36
  export class BdsAlert extends LitElement {
33
37
  static styles = css`
38
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
39
+ here; otherwise elements with an explicit size + padding size as
40
+ content-box and layouts drift from the React (light-DOM) versions. */
41
+ :host,
42
+ *,
43
+ *::before,
44
+ *::after {
45
+ box-sizing: border-box;
46
+ }
47
+
34
48
  :host {
35
49
  display: block;
36
50
  }
@@ -119,8 +133,8 @@ export class BdsAlert extends LitElement {
119
133
  }
120
134
 
121
135
  .dismiss svg {
122
- width: 1rem;
123
- height: 1rem;
136
+ inline-size: 1rem;
137
+ block-size: 1rem;
124
138
  }
125
139
 
126
140
  .dismiss:focus-visible {
@@ -137,6 +151,7 @@ export class BdsAlert extends LitElement {
137
151
 
138
152
  static properties = {
139
153
  variant: { type: String, reflect: true },
154
+ heading: { type: String },
140
155
  title: { type: String },
141
156
  dismissible: { type: Boolean, reflect: true },
142
157
  _iconFilled: { state: true },
@@ -145,6 +160,12 @@ export class BdsAlert extends LitElement {
145
160
  // `declare` annotates the type without emitting a class field initializer
146
161
  // that would shadow Lit's reactive accessors on the prototype.
147
162
  declare variant: AlertVariant;
163
+ declare heading: string;
164
+ /**
165
+ * @deprecated Use `heading` instead. Sharing the name with the global HTML
166
+ * `title` attribute makes the browser show a native tooltip on hover.
167
+ * Still read as a fallback for the heading text when `heading` is unset.
168
+ */
148
169
  declare title: string;
149
170
  declare dismissible: boolean;
150
171
  declare private _iconFilled: boolean;
@@ -152,11 +173,16 @@ export class BdsAlert extends LitElement {
152
173
  constructor() {
153
174
  super();
154
175
  this.variant = 'info';
176
+ this.heading = '';
155
177
  this.title = '';
156
178
  this.dismissible = false;
157
179
  this._iconFilled = false;
158
180
  }
159
181
 
182
+ private get _headingText() {
183
+ return this.heading || this.title;
184
+ }
185
+
160
186
  private _onIconSlotChange(e: Event) {
161
187
  const slot = e.target as HTMLSlotElement;
162
188
  this._iconFilled = slot.assignedNodes({ flatten: true }).length > 0;
@@ -182,7 +208,7 @@ export class BdsAlert extends LitElement {
182
208
  <slot name="icon" @slotchange=${this._onIconSlotChange}></slot>
183
209
  </span>
184
210
  <div class="content">
185
- ${this.title ? html`<strong class="title">${this.title}</strong>` : nothing}
211
+ ${this._headingText ? html`<strong class="title">${this._headingText}</strong>` : nothing}
186
212
  <div><slot></slot></div>
187
213
  </div>
188
214
  ${this.dismissible
@@ -72,4 +72,33 @@ describe('bds-avatar', () => {
72
72
  expect(el.getAttribute('size')).toBe('large');
73
73
  cleanup(el);
74
74
  });
75
+
76
+ it('preserves an explicit empty alt="" as decorative (does not fall back to name)', async () => {
77
+ const el = await fixture('<bds-avatar src="/photo.jpg" alt="" name="Jane Doe"></bds-avatar>');
78
+ const img = el.shadowRoot!.querySelector('img');
79
+ expect(img!.getAttribute('alt')).toBe('');
80
+ cleanup(el);
81
+ });
82
+
83
+ it('falls back to name when alt attribute is entirely absent', async () => {
84
+ const el = await fixture('<bds-avatar src="/photo.jpg" name="Jane Doe"></bds-avatar>');
85
+ const img = el.shadowRoot!.querySelector('img');
86
+ expect(img!.hasAttribute('alt')).toBe(true);
87
+ expect(img!.getAttribute('alt')).toBe('Jane Doe');
88
+ cleanup(el);
89
+ });
90
+
91
+ it('size selectors write to the --avatar_size--variant slot, not the public --avatar_size token (ancestor overrides stay effective)', () => {
92
+ const cssText = BdsAvatar.styles.cssText;
93
+ expect(cssText).toMatch(
94
+ /inline-size:\s*var\(--avatar_size,\s*var\(--avatar_size--variant,\s*3em\)\)/,
95
+ );
96
+ expect(cssText).toMatch(
97
+ /block-size:\s*var\(--avatar_size,\s*var\(--avatar_size--variant,\s*3em\)\)/,
98
+ );
99
+ expect(cssText).toMatch(/:host\(\[size='small'\]\)\s*\{\s*--avatar_size--variant:\s*2em;/);
100
+ expect(cssText).toMatch(/:host\(\[size='large'\]\)\s*\{\s*--avatar_size--variant:\s*4\.5em;/);
101
+ // The public --avatar_size token itself must never be set directly by a size selector.
102
+ expect(cssText).not.toMatch(/:host\(\[size=[^)]*\]\)\s*\{\s*--avatar_size:/);
103
+ });
75
104
  });
@@ -7,7 +7,8 @@ import { LitElement, css, html, nothing } from 'lit';
7
7
  *
8
8
  * Attributes:
9
9
  * src — image URL
10
- * alt — image alt text (defaults to `name` or "User avatar")
10
+ * alt — image alt text (defaults to `name` or "User avatar"). Set alt=""
11
+ * explicitly to mark the image as decorative (silences the accessible name).
11
12
  * name — full name; used to compute initials and as fallback aria-label
12
13
  * size — "small" | "medium" (default) | "large"
13
14
  *
@@ -17,20 +18,34 @@ import { LitElement, css, html, nothing } from 'lit';
17
18
  */
18
19
  export class BdsAvatar extends LitElement {
19
20
  static styles = css`
21
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
22
+ here; otherwise elements with an explicit size + padding size as
23
+ content-box and layouts drift from the React (light-DOM) versions. */
24
+ :host,
25
+ *,
26
+ *::before,
27
+ *::after {
28
+ box-sizing: border-box;
29
+ }
30
+
20
31
  :host {
21
32
  display: inline-flex;
22
33
  align-items: center;
23
34
  justify-content: center;
24
- inline-size: var(--avatar_size, 3em);
25
- block-size: var(--avatar_size, 3em);
35
+ /* Layered cascade (mirrors the React Avatar): a public --avatar_size
36
+ override wins over the per-size-variant default. Size selectors
37
+ below write --avatar_size--variant only, so an ancestor setting
38
+ --avatar_size still cascades correctly. */
39
+ inline-size: var(--avatar_size, var(--avatar_size--variant, 3em));
40
+ block-size: var(--avatar_size, var(--avatar_size--variant, 3em));
26
41
  border-radius: var(--avatar_radius, var(--bds-border_radius--circle));
27
42
  overflow: hidden;
28
43
  flex-shrink: 0;
29
44
  }
30
45
 
31
- :host([size='small']) { --avatar_size: 2em; }
32
- :host([size='medium']) { --avatar_size: 3em; }
33
- :host([size='large']) { --avatar_size: 4.5em; }
46
+ :host([size='small']) { --avatar_size--variant: 2em; }
47
+ :host([size='medium']) { --avatar_size--variant: 3em; }
48
+ :host([size='large']) { --avatar_size--variant: 4.5em; }
34
49
 
35
50
  .fallback {
36
51
  display: inline-flex;
@@ -92,11 +107,14 @@ export class BdsAvatar extends LitElement {
92
107
 
93
108
  render() {
94
109
  if (this.src) {
95
- return html`<img
96
- class="image"
97
- src=${this.src}
98
- alt=${this.alt || this.name || 'User avatar'}
99
- />`;
110
+ // An explicit alt="" attribute marks the image as decorative and must
111
+ // be preserved as-is — only substitute name/"User avatar" when the
112
+ // attribute was never provided (this.alt otherwise defaults to '').
113
+ const altText = this.hasAttribute('alt')
114
+ ? this.alt
115
+ : this.name || 'User avatar';
116
+
117
+ return html`<img class="image" src=${this.src} alt=${altText} />`;
100
118
  }
101
119
 
102
120
  return html`
@@ -48,4 +48,9 @@ describe('bds-badge', () => {
48
48
  cleanup(el);
49
49
  }
50
50
  });
51
+
52
+ it('falls back --badge_radius to the pill token, matching the React counterpart', () => {
53
+ const cssText = BdsBadge.styles.cssText;
54
+ expect(cssText).toMatch(/border-radius:\s*var\(--badge_radius,\s*var\(--bds-border_radius--full\)\)/);
55
+ });
51
56
  });
@@ -16,6 +16,16 @@ export type BadgeVariant = 'primary' | 'secondary' | 'success' | 'error' | 'warn
16
16
  */
17
17
  export class BdsBadge extends LitElement {
18
18
  static styles = css`
19
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
20
+ here; otherwise elements with an explicit size + padding size as
21
+ content-box and layouts drift from the React (light-DOM) versions. */
22
+ :host,
23
+ *,
24
+ *::before,
25
+ *::after {
26
+ box-sizing: border-box;
27
+ }
28
+
19
29
  :host {
20
30
  display: inline-flex;
21
31
  }
@@ -25,7 +35,7 @@ export class BdsBadge extends LitElement {
25
35
  align-items: center;
26
36
  justify-content: center;
27
37
  padding: var(--bds-space_xxs) var(--bds-space_xs);
28
- border-radius: var(--badge_radius, 2em);
38
+ border-radius: var(--badge_radius, var(--bds-border_radius--full));
29
39
  font-size: var(--badge_font-size, var(--bds-font_size--body--s));
30
40
  font-weight: var(--bds-font_weight--semibold);
31
41
  line-height: 1;
@@ -52,4 +52,34 @@ describe('bds-breadcrumb', () => {
52
52
  expect(separators.length).toBe(2); // between each pair
53
53
  cleanup(el);
54
54
  });
55
+
56
+ it('falls back to an empty list instead of crashing when items is null', async () => {
57
+ const el = await fixture('<bds-breadcrumb></bds-breadcrumb>') as BdsBreadcrumb;
58
+ // Simulates what Lit's default Array attribute converter produces for
59
+ // malformed JSON or a removed attribute: it returns null, not [].
60
+ (el as unknown as { items: unknown }).items = null;
61
+ await el.updateComplete;
62
+ const items = el.shadowRoot!.querySelectorAll('.item');
63
+ expect(items.length).toBe(0);
64
+ cleanup(el);
65
+ });
66
+
67
+ it('recovers from malformed items JSON set via the attribute', async () => {
68
+ const el = await fixture('<bds-breadcrumb items="not valid json"></bds-breadcrumb>') as BdsBreadcrumb;
69
+ const items = el.shadowRoot!.querySelectorAll('.item');
70
+ expect(items.length).toBe(0);
71
+ cleanup(el);
72
+ });
73
+
74
+ it('renders non-last items without href as non-interactive text, not a href="#" link', async () => {
75
+ const el = await fixture('<bds-breadcrumb></bds-breadcrumb>') as BdsBreadcrumb;
76
+ el.items = [{ label: 'Home' }, { label: 'Current' }];
77
+ await el.updateComplete;
78
+ const link = el.shadowRoot!.querySelector('a.link');
79
+ expect(link).toBeNull();
80
+ const text = el.shadowRoot!.querySelector('.text');
81
+ expect(text).not.toBeNull();
82
+ expect(text!.textContent).toBe('Home');
83
+ cleanup(el);
84
+ });
55
85
  });
@@ -10,13 +10,25 @@ export interface BreadcrumbItem {
10
10
  *
11
11
  * Attributes:
12
12
  * items — JSON string array of `{ label: string, href?: string }` objects.
13
- * The last item is treated as the current page (no link).
13
+ * The last item is treated as the current page (no link). Any other
14
+ * item without an `href` renders as plain text instead of a link.
15
+ * Malformed JSON (or a removed attribute) falls back to `[]`.
14
16
  *
15
17
  * @example
16
18
  * <bds-breadcrumb items='[{"label":"Home","href":"/"},{"label":"Products","href":"/products"},{"label":"Item"}]'></bds-breadcrumb>
17
19
  */
18
20
  export class BdsBreadcrumb extends LitElement {
19
21
  static styles = css`
22
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
23
+ here; otherwise elements with an explicit size + padding size as
24
+ content-box and layouts drift from the React (light-DOM) versions. */
25
+ :host,
26
+ *,
27
+ *::before,
28
+ *::after {
29
+ box-sizing: border-box;
30
+ }
31
+
20
32
  :host {
21
33
  display: block;
22
34
  }
@@ -65,6 +77,10 @@ export class BdsBreadcrumb extends LitElement {
65
77
  user-select: none;
66
78
  }
67
79
 
80
+ .text {
81
+ color: var(--bds-color_on-bg--subtle);
82
+ }
83
+
68
84
  .current {
69
85
  color: var(--bds-color_on-bg--subtle);
70
86
  font-weight: var(--bds-font_weight--semibold);
@@ -83,17 +99,23 @@ export class BdsBreadcrumb extends LitElement {
83
99
  }
84
100
 
85
101
  render() {
102
+ // this.items may be null: the Lit default Array/Object attribute
103
+ // converter returns null (rather than throwing) both for malformed
104
+ // JSON and for a removed attribute — fall back to an empty list.
105
+ const items = this.items ?? [];
86
106
  return html`
87
107
  <nav class="breadcrumb" aria-label="Breadcrumb">
88
108
  <ol class="list">
89
- ${this.items.map((item, index) => {
90
- const isLast = index === this.items.length - 1;
109
+ ${items.map((item, index) => {
110
+ const isLast = index === items.length - 1;
91
111
  return html`
92
112
  <li class="item">
93
113
  ${isLast
94
114
  ? html`<span class="current" aria-current="page">${item.label}</span>`
95
115
  : html`
96
- <a class="link" href=${item.href ?? '#'}>${item.label}</a>
116
+ ${item.href
117
+ ? html`<a class="link" href=${item.href}>${item.label}</a>`
118
+ : html`<span class="text">${item.label}</span>`}
97
119
  <span class="separator" aria-hidden="true">›</span>
98
120
  `}
99
121
  </li>
@@ -0,0 +1,39 @@
1
+ import { fixture, cleanup } from '../test/helpers';
2
+ import { BdsButtonContainer } from './bds-button-container';
3
+
4
+ describe('bds-button-container', () => {
5
+ it('is registered as a custom element', () => {
6
+ expect(customElements.get('bds-button-container')).toBe(BdsButtonContainer);
7
+ });
8
+
9
+ it('renders a group role element wrapping a slot', async () => {
10
+ const el = await fixture('<bds-button-container>content</bds-button-container>');
11
+ const group = el.shadowRoot!.querySelector('[role="group"]')!;
12
+ expect(group).not.toBeNull();
13
+ expect(group.querySelector('slot')).not.toBeNull();
14
+ cleanup(el);
15
+ });
16
+
17
+ it('reflects the variant attribute', async () => {
18
+ const el = await fixture(
19
+ '<bds-button-container variant="modal">content</bds-button-container>',
20
+ ) as BdsButtonContainer;
21
+ expect(el.variant).toBe('modal');
22
+ expect(el.getAttribute('variant')).toBe('modal');
23
+ cleanup(el);
24
+ });
25
+
26
+ it('forwards aria-label to the group', async () => {
27
+ const el = await fixture('<bds-button-container aria-label="Dialog actions">x</bds-button-container>');
28
+ const group = el.shadowRoot!.querySelector('[role="group"]')!;
29
+ expect(group.getAttribute('aria-label')).toBe('Dialog actions');
30
+ cleanup(el);
31
+ });
32
+
33
+ it('omits aria-label when unset', async () => {
34
+ const el = await fixture('<bds-button-container>x</bds-button-container>');
35
+ const group = el.shadowRoot!.querySelector('[role="group"]')!;
36
+ expect(group.hasAttribute('aria-label')).toBe(false);
37
+ cleanup(el);
38
+ });
39
+ });