@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
@@ -52,6 +52,23 @@ Or in HTML without a bundler:
52
52
 
53
53
  <ArgTypes of={Stories} />
54
54
 
55
+ ## CSS Custom Properties — `<bds-dropdown-menu>`
56
+
57
+ | Property | Default | Description |
58
+ |----------|---------|-------------|
59
+ | `--dropdown_border` | `none` | Real CSS `border` on the panel (in addition to the bdc inset outline) |
60
+ | `--dropdown_radius` | `--bdc-outline_radius` (`--bds-border_radius--s`) | Panel corner radius |
61
+ | `--dropdown_color` | `--bds-color_bg` | Panel background colour |
62
+ | `--dropdown_on-color` | `--bds-color_on-bg` | Panel text colour |
63
+ | `--dropdown_shadow` | `--bds-shadow_m` | Panel elevation shadow, layered behind the inset border |
64
+
65
+ ## CSS Custom Properties — `<bds-dropdown-menu-item>`
66
+
67
+ | Property | Default | Description |
68
+ |----------|---------|-------------|
69
+ | `--dropdown_item-bg--hover` | `--bds-color_bg--subtle` | Item background colour on hover |
70
+ | `--dropdown_item-color--hover` | `--bds-color_interactive_on-bg` | Item text colour on hover |
71
+
55
72
  ## Attributes — `<bds-dropdown-menu>`
56
73
 
57
74
  | Attribute | Type | Default | Description |
@@ -101,8 +118,10 @@ Or in HTML without a bundler:
101
118
 
102
119
  ## Accessibility
103
120
 
121
+ - The slotted trigger receives `aria-haspopup="menu"`, `aria-controls` (pointing at the panel's id), and `aria-expanded` kept in sync with open/close state
104
122
  - The menu panel has `role="menu"` and `aria-hidden` toggled on open/close
105
123
  - Each item renders a `<button role="menuitem">`
106
- - Keyboard navigation: ArrowDown / ArrowUp moves between enabled items; Escape closes and returns focus to the trigger; Tab closes the menu
124
+ - Keyboard navigation: ArrowDown / ArrowUp moves between enabled items; Home / End jump to the first / last enabled item; Escape closes and returns focus to the trigger; Tab closes the menu
107
125
  - Disabled items are excluded from keyboard navigation
108
126
  - Focus returns to the trigger element on close
127
+ - The panel is an absolutely-positioned shadow-DOM element (not the native Popover API), so it can be clipped by an ancestor's `overflow` or stacking context
@@ -45,12 +45,13 @@ import '@boostdev/design-system-components/web-components';
45
45
  |-----------|------|---------|-------------|
46
46
  | `placement` | `"bottom" \| "top" \| "left" \| "right"` | `"bottom"` | Preferred panel position relative to the trigger |
47
47
  | `open` | boolean | `false` | Controls panel visibility; reflects on the element |
48
+ | `aria-label` | string | — | Accessible name for the panel. When set, the panel gets `role="region"` and this label; when omitted, neither is rendered |
48
49
 
49
50
  ## Slots
50
51
 
51
52
  | Slot | Description |
52
53
  |------|-------------|
53
- | `trigger` | Element that opens and closes the panel on click |
54
+ | `trigger` | Element that opens and closes the panel on click. Automatically receives `aria-haspopup="true"`, `aria-controls` (pointing at the panel) and `aria-expanded` synced to the open state |
54
55
  | `(default)` | Panel content |
55
56
 
56
57
  ## Events
@@ -65,6 +66,7 @@ import '@boostdev/design-system-components/web-components';
65
66
  - Clicking the trigger toggles the panel open/closed
66
67
  - Pressing `Escape` closes an open panel
67
68
  - Clicking outside the element closes the panel
69
+ - The panel is `position: fixed`, so it escapes `overflow: hidden`/`scroll` ancestors and stacking contexts instead of being clipped
68
70
  - CSS Anchor Positioning automatically tries fallback placements (`@position-try`) when the preferred placement would overflow the viewport
69
71
  - Each instance gets a unique CSS anchor name — multiple popovers on the same page don't interfere
70
72
 
@@ -114,7 +116,9 @@ popover.addEventListener('bds-close', () => console.log('closed'));
114
116
 
115
117
  ## Accessibility
116
118
 
117
- - The panel has `role="region"` and `aria-label="Popover"`
118
- - The trigger element retains its own role (e.g. `<button>`)no ARIA is added by the component
119
+ - The trigger element automatically receives `aria-haspopup="true"`, `aria-controls` (referencing the panel) and `aria-expanded` — kept in sync as the panel opens and closes
120
+ - The panel gets `role="region"` and the given label only when you set `aria-label` on `<bds-popover>` — omit it if the trigger's own accessible name already describes the panel content, to avoid a meaningless landmark announcement
121
+ - The trigger element otherwise retains its own role (e.g. `<button>`) — no other ARIA is added by the component
119
122
  - For menus, use a `<nav>` or `role="menu"` inside the default slot as appropriate
123
+ - When the panel closes (`Escape` or an outside click) while focus was inside the popover, focus returns to the trigger; an outside click that moves focus elsewhere is left alone
120
124
  - The component does not trap focus — use `<bds-dialog>` for modal, focus-trapped overlays
@@ -57,6 +57,18 @@ Or in HTML without a bundler:
57
57
  |------|-------------|
58
58
  | `(default)` | Link text; defaults to `"Skip to main content"` when no content is provided |
59
59
 
60
+ ## CSS Custom Properties
61
+
62
+ | Property | Description |
63
+ |----------|-------------|
64
+ | `--skip-link_inset` | Distance from the block-start/inline-start edge when focused (default: `var(--bds-space_s)`) |
65
+ | `--skip-link_z-index` | Stacking order so the link rises above sticky headers/nav (default: `var(--bds-z-index_xl)`) |
66
+ | `--skip-link_padding` | Padding of the link surface (default: `var(--bds-space_xs) var(--bds-space_m)`) |
67
+ | `--skip-link_font-size` | Font size of the link text (default: `var(--bds-font_size--body)`) |
68
+ | `--skip-link_radius` | Corner radius (default: `var(--bds-border_radius--s)`) |
69
+ | `--skip-link_border` | Border around the link surface (default: `none`) |
70
+ | `--skip-link_shadow` | Extra shadow appended after the bdc focus-border box-shadow (default: `var(--bdc-outline_shadow)`) |
71
+
60
72
  ## Usage in plain HTML
61
73
 
62
74
  Place `<bds-skip-link>` as the very first element inside `<body>`:
@@ -86,5 +98,6 @@ With custom label text:
86
98
  - Visually hidden via `transform: translateY(...)` until focused — avoids `display: none` and `visibility: hidden` which remove the element from the accessibility tree
87
99
  - Becomes visible on `:focus-visible`, ensuring it is discoverable by keyboard and switch-access users
88
100
  - Uses an `<a>` element so it is announced as a link by screen readers
89
- - `z-index: 9999` ensures it appears above all other content when focused
101
+ - `z-index: var(--skip-link_z-index, var(--bds-z-index_xl))` ensures it rises above sticky headers/navigation when focused
90
102
  - Satisfies WCAG 2.4.1 Bypass Blocks (Level A)
103
+ - The slide-in transition respects `prefers-reduced-motion: reduce`
@@ -86,6 +86,22 @@ Or in HTML without a bundler:
86
86
  |-------|----------|---------|-------------|
87
87
  | `bds-tab-select` | `<bds-tab>` | Yes | Fired when a tab is clicked; handled internally by `<bds-tabs>` |
88
88
 
89
+ ## CSS Custom Properties
90
+
91
+ Resting and state colours are layered overrides: a top-level override (e.g.
92
+ `--tab_color`) always wins over the selected/hover default for that state
93
+ (e.g. `--tab_color--active`), which falls back to the design token. Set
94
+ `--tab_color` on `<bds-tab>` (or an ancestor) to theme the resting colour
95
+ across every state; set `--tab_color--active` to theme only the selected tab.
96
+
97
+ | Property | Description |
98
+ |----------|-------------|
99
+ | `--tab_color` | Tab text colour override (all states) |
100
+ | `--tab_border-color` | Tab bottom-border colour override (all states) |
101
+ | `--tab_color--active` | Text colour override for the selected tab |
102
+ | `--tab_border-color--active` | Bottom-border colour override for the selected tab |
103
+ | `--tab_color--hover` | Text colour override on hover (unselected, enabled tabs) |
104
+
89
105
  ## Usage in plain HTML
90
106
 
91
107
  Tabs and panels are matched by DOM order (first tab → first panel, etc.):
@@ -112,6 +128,7 @@ Tabs and panels are matched by DOM order (first tab → first panel, etc.):
112
128
 
113
129
  - The tab list container has `role="tablist"`
114
130
  - Each `<bds-tab>` renders a `<button role="tab">` with `aria-selected` and the correct `tabindex` (0 for active, -1 for others)
131
+ - `<bds-tabs>` also assigns `role="tab"`, a generated `id`, and `aria-controls` (pointing at the matching panel's `id`) on each `<bds-tab>` **host** element — and `role="tabpanel"`, a generated `id`, and `aria-labelledby` (pointing back at the tab's `id`) on each `<bds-tab-panel>` **host** element. These live on the light-DOM host elements (not inside either element's shadow root) so the `id` references resolve correctly across the shared light-DOM tree. A consumer-supplied `id` on `<bds-tab>` / `<bds-tab-panel>` is preserved rather than overwritten.
115
132
  - Each `<bds-tab-panel>` receives `hidden` when not active
116
- - Keyboard navigation: ArrowRight / ArrowLeft cycles through enabled tabs; Home / End jumps to first / last enabled tab
133
+ - Keyboard navigation: ArrowRight / ArrowLeft cycles through enabled tabs; Home / End jumps to first / last enabled tab. The listener only reacts to keys that originate from a `<bds-tab>` — typing inside tab-panel content (an `<input>`, slider, etc.) never hijacks focus or switches the active tab.
117
134
  - Disabled tabs are excluded from keyboard navigation
@@ -89,6 +89,24 @@ document.dispatchEvent(new CustomEvent('bds-show-toast', {
89
89
 
90
90
  ## Accessibility
91
91
 
92
- - Each toast renders with `role="status"` + `aria-live="polite"` by default so screen readers announce it without interrupting the user
93
- - `error` toasts use `role="alert"` + `aria-live="assertive"` for immediate announcement
94
- - The dismiss button has an accessible label
92
+ - Every toast (all variants, including `error`) renders with `role="status"` + `aria-live="polite"` so screen readers announce it without interrupting the user — this matches the `ToastProvider` React component
93
+ - The dismiss button has an accessible label and a >=44&times;44px hit area (the visible icon stays 16px; the click target is expanded with a transparent `::after` pseudo-element)
94
+
95
+ ## CSS Custom Properties
96
+
97
+ | Property | Default | Description |
98
+ |----------|---------|-------------|
99
+ | `--toast_color` | _(unset)_ | Public override for the toast background colour — wins over the per-variant default on every variant |
100
+ | `--toast_on-color` | _(unset)_ | Public override for the toast text colour — wins over the per-variant default on every variant |
101
+ | `--toast_radius` | `--bds-border_radius--s` | Toast corner radius |
102
+ | `--toast_shadow` | `--bds-shadow_s` | Toast elevation shadow |
103
+ | `--toast_color--success` | `--bds-color_success` | Background colour for `success` toasts |
104
+ | `--toast_on-color--success` | `--bds-color_on-success` | Text colour for `success` toasts |
105
+ | `--toast_color--warning` | `--bds-color_warning` | Background colour for `warning` toasts |
106
+ | `--toast_on-color--warning` | `--bds-color_on-warning` | Text colour for `warning` toasts |
107
+ | `--toast_color--info` | `--bds-color_bg--subtle` | Background colour for `info` toasts |
108
+ | `--toast_on-color--info` | `--bds-color_on-bg--subtle` | Text colour for `info` toasts |
109
+ | `--toast_color--error` | `--bds-color_error` | Background colour for `error` toasts |
110
+ | `--toast_on-color--error` | `--bds-color_on-error` | Text colour for `error` toasts |
111
+
112
+ Setting `--toast_color`/`--toast_on-color` on `<bds-toast-provider>` (or an ancestor) overrides every variant at once; the `--toast_color--<variant>`/`--toast_on-color--<variant>` tokens only change that one variant's default.
@@ -96,9 +96,9 @@ Or in HTML without a bundler:
96
96
 
97
97
  ## Accessibility
98
98
 
99
- - The tooltip panel has `role="tooltip"`
100
- - Visibility is controlled by `:hover` and `:focus-within` no JavaScript required
101
- - The tooltip is rendered adjacent to the trigger inside the same shadow root, so screen readers can read it via proximity
102
- - Note: `aria-describedby` cannot cross shadow DOM boundaries; if your project requires explicit ARIA association, use `<bds-popover>` instead
99
+ - `content` is programmatically associated with the slotted trigger: the element appends a visually-hidden light-DOM `<span>` holding the tooltip text and sets `aria-describedby` on every slotted (non-hidden) child to point at it. This keeps the id reference inside the light DOM's tree scope, so it resolves correctly — `aria-describedby` cannot reference an id that lives inside this element's shadow root, since id references only resolve within the same tree scope.
100
+ - The association is re-computed whenever `content` changes or the default slot's assigned nodes change (`slotchange`), and existing `aria-describedby` values set by the consumer on the trigger are preserved (the tooltip's id is appended, not overwritten).
101
+ - The description is available to assistive technology at all times, independent of hover/focus it does not depend on the visual tooltip being shown.
102
+ - The visible tooltip bubble (`role="tooltip"`) is `aria-hidden="true"`; it is purely the visual presentation shown on `:hover`/`:focus-within` and is not itself the accessible description.
103
103
  - `pointer-events: none` on the tooltip prevents it from interfering with mouse events
104
104
  - Fade transition respects `prefers-reduced-motion`
@@ -27,6 +27,16 @@ import { LitElement, css, html } from 'lit';
27
27
  */
28
28
  export class BdsAccordionItem extends LitElement {
29
29
  static styles = css`
30
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
31
+ here; otherwise elements with an explicit size + padding size as
32
+ content-box and layouts drift from the React (light-DOM) versions. */
33
+ :host,
34
+ *,
35
+ *::before,
36
+ *::after {
37
+ box-sizing: border-box;
38
+ }
39
+
30
40
  :host {
31
41
  display: block;
32
42
  border-block-end: 1px solid var(--bds-color_bg--subtle);
@@ -70,4 +70,45 @@ describe('bds-accordion', () => {
70
70
  expect(items[0].open).toBe(false);
71
71
  cleanup(el);
72
72
  });
73
+
74
+ it('does not let a nested accordion double-handle its own items (and vice versa)', async () => {
75
+ const el = await fixture(`
76
+ <bds-accordion id="outer">
77
+ <bds-accordion-item id="a">
78
+ <span slot="header">Outer Q1</span>
79
+ <bds-accordion id="inner">
80
+ <bds-accordion-item id="b"><span slot="header">Inner Q1</span><p>B</p></bds-accordion-item>
81
+ <bds-accordion-item id="c"><span slot="header">Inner Q2</span><p>C</p></bds-accordion-item>
82
+ </bds-accordion>
83
+ </bds-accordion-item>
84
+ <bds-accordion-item id="d"><span slot="header">Outer Q2</span><p>D</p></bds-accordion-item>
85
+ </bds-accordion>
86
+ `);
87
+ const a = el.querySelector<BdsAccordionItem>('#a')!;
88
+ const b = el.querySelector<BdsAccordionItem>('#b')!;
89
+ const c = el.querySelector<BdsAccordionItem>('#c')!;
90
+ const d = el.querySelector<BdsAccordionItem>('#d')!;
91
+
92
+ // Open outer item A first (exclusive mode).
93
+ a.dispatchEvent(new CustomEvent('bds-accordion-item-toggle', { bubbles: true, composed: true }));
94
+ expect(a.open).toBe(true);
95
+
96
+ // Toggle inner item B. Without ownership scoping, the bubbled event
97
+ // would also be re-processed by the outer accordion, which would
98
+ // erroneously close item A and immediately re-close item B.
99
+ b.dispatchEvent(new CustomEvent('bds-accordion-item-toggle', { bubbles: true, composed: true }));
100
+ expect(b.open).toBe(true);
101
+ expect(c.open).toBe(false);
102
+ expect(a.open).toBe(true);
103
+ expect(d.open).toBe(false);
104
+
105
+ // Toggling outer item D must not disturb the inner accordion's state.
106
+ d.dispatchEvent(new CustomEvent('bds-accordion-item-toggle', { bubbles: true, composed: true }));
107
+ expect(d.open).toBe(true);
108
+ expect(a.open).toBe(false);
109
+ expect(b.open).toBe(true);
110
+ expect(c.open).toBe(false);
111
+
112
+ cleanup(el);
113
+ });
73
114
  });
@@ -24,13 +24,24 @@ import type { BdsAccordionItem } from './bds-accordion-item';
24
24
  */
25
25
  export class BdsAccordion extends LitElement {
26
26
  static styles = css`
27
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
28
+ here; otherwise elements with an explicit size + padding size as
29
+ content-box and layouts drift from the React (light-DOM) versions. */
30
+ :host,
31
+ *,
32
+ *::before,
33
+ *::after {
34
+ box-sizing: border-box;
35
+ }
36
+
27
37
  :host {
28
38
  display: block;
29
39
  border: var(--accordion_border, none);
30
40
  --bdc_color: var(--bds-color_bg--subtle);
31
41
  --bdc-outline_radius: var(--bds-border_radius--s);
32
42
  border-radius: var(--accordion_radius, var(--bdc-outline_radius));
33
- box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color);
43
+ box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color),
44
+ var(--accordion_shadow, var(--bdc-outline_shadow));
34
45
  overflow: hidden;
35
46
  }
36
47
  `;
@@ -63,7 +74,11 @@ export class BdsAccordion extends LitElement {
63
74
  }
64
75
 
65
76
  private get _items(): BdsAccordionItem[] {
66
- return [...this.querySelectorAll<BdsAccordionItem>('bds-accordion-item')];
77
+ // Only items owned by *this* accordion — excludes items that belong to a
78
+ // nested <bds-accordion> rendered inside one of our items' content.
79
+ return [...this.querySelectorAll<BdsAccordionItem>('bds-accordion-item')].filter(
80
+ item => item.closest('bds-accordion') === this,
81
+ );
67
82
  }
68
83
 
69
84
  private _discoverItems() {
@@ -74,6 +89,17 @@ export class BdsAccordion extends LitElement {
74
89
 
75
90
  private _handleItemToggle = (e: Event) => {
76
91
  const toggled = e.target as BdsAccordionItem;
92
+
93
+ // A nested <bds-accordion> is the closest owner of its own items' toggle
94
+ // events. If this element isn't that closest owner, the event belongs to
95
+ // a descendant accordion — ignore it and let that accordion's own
96
+ // listener (which fires first, being closer in the tree) handle it.
97
+ if (toggled.closest('bds-accordion') !== this) return;
98
+
99
+ // Handled by the rightful owner: stop it from also reaching any
100
+ // ancestor <bds-accordion> further up the tree.
101
+ e.stopPropagation();
102
+
77
103
  const items = this._items;
78
104
  const wasOpen = toggled.open;
79
105
 
@@ -127,4 +127,85 @@ describe('bds-button', () => {
127
127
  expect(btn!.getAttribute('aria-label')).toBe('Close');
128
128
  cleanup(el);
129
129
  });
130
+
131
+ describe('slotted icon styling (icons live in light DOM)', () => {
132
+ it('colours slotted icon-start/icon-end svgs via ::slotted(), not a dead shadow-tree "svg" descendant selector', () => {
133
+ const cssText = BdsButton.styles.cssText;
134
+ expect(cssText).toMatch(/\.icon-start ::slotted\(svg\),\s*\.icon-end ::slotted\(svg\)\s*{[^}]*fill:\s*currentcolor/);
135
+ // The old selector could never match slotted content — guard against regressing to it.
136
+ expect(cssText).not.toMatch(/\.button svg\s*{/);
137
+ });
138
+
139
+ it('uses ::slotted() for the hover fadeZoom animation on slotted icons', () => {
140
+ const cssText = BdsButton.styles.cssText;
141
+ expect(cssText).toMatch(
142
+ /\.button:hover \.icon-start ::slotted\(svg\),\s*\.button:hover \.icon-end ::slotted\(svg\)\s*{\s*animation:\s*fadeZoom/,
143
+ );
144
+ });
145
+ });
146
+
147
+ describe('prefers-reduced-motion', () => {
148
+ it('disables the pulse ring and hover icon animation under prefers-reduced-motion: reduce', () => {
149
+ const cssText = BdsButton.styles.cssText;
150
+ expect(cssText).toMatch(
151
+ /@media \(prefers-reduced-motion: reduce\)\s*{\s*\.button\.has-pulse,\s*\.button:hover \.icon-start ::slotted\(svg\),\s*\.button:hover \.icon-end ::slotted\(svg\)\s*{\s*animation:\s*none;/,
152
+ );
153
+ });
154
+ });
155
+
156
+ describe('form participation (type="submit"/"reset" via ElementInternals)', () => {
157
+ it('is form-associated', () => {
158
+ expect(BdsButton.formAssociated).toBe(true);
159
+ });
160
+
161
+ it('calls the associated form\'s requestSubmit() when a type="submit" button is clicked', async () => {
162
+ const requestSubmit = vi.fn();
163
+ const spy = vi
164
+ .spyOn(HTMLElement.prototype, 'attachInternals')
165
+ .mockReturnValue({ form: { requestSubmit, reset: vi.fn() } } as unknown as ElementInternals);
166
+
167
+ const el = await fixture('<bds-button type="submit">Save</bds-button>');
168
+ const btn = el.shadowRoot!.querySelector('button')!;
169
+ btn.click();
170
+
171
+ expect(requestSubmit).toHaveBeenCalledTimes(1);
172
+
173
+ spy.mockRestore();
174
+ cleanup(el);
175
+ });
176
+
177
+ it('calls the associated form\'s reset() when a type="reset" button is clicked', async () => {
178
+ const reset = vi.fn();
179
+ const spy = vi
180
+ .spyOn(HTMLElement.prototype, 'attachInternals')
181
+ .mockReturnValue({ form: { requestSubmit: vi.fn(), reset } } as unknown as ElementInternals);
182
+
183
+ const el = await fixture('<bds-button type="reset">Clear</bds-button>');
184
+ const btn = el.shadowRoot!.querySelector('button')!;
185
+ btn.click();
186
+
187
+ expect(reset).toHaveBeenCalledTimes(1);
188
+
189
+ spy.mockRestore();
190
+ cleanup(el);
191
+ });
192
+
193
+ it('does not call requestSubmit or reset for the default type="button"', async () => {
194
+ const requestSubmit = vi.fn();
195
+ const reset = vi.fn();
196
+ const spy = vi
197
+ .spyOn(HTMLElement.prototype, 'attachInternals')
198
+ .mockReturnValue({ form: { requestSubmit, reset } } as unknown as ElementInternals);
199
+
200
+ const el = await fixture('<bds-button>Click</bds-button>');
201
+ const btn = el.shadowRoot!.querySelector('button')!;
202
+ btn.click();
203
+
204
+ expect(requestSubmit).not.toHaveBeenCalled();
205
+ expect(reset).not.toHaveBeenCalled();
206
+
207
+ spy.mockRestore();
208
+ cleanup(el);
209
+ });
210
+ });
130
211
  });
@@ -13,10 +13,15 @@ export type ButtonSize = 'small' | 'medium' | 'large';
13
13
  * href — renders an <a> tag instead of <button>
14
14
  * target — forwarded to <a> when href is set
15
15
  * rel — forwarded to <a> when href is set
16
- * has-pulse — boolean, enables the pulse ring animation
17
- * is-icon-only — boolean, forces a 1:1 aspect ratio with minimal xs padding (requires aria-label)
16
+ * has-pulse — boolean, enables the pulse ring animation (respects prefers-reduced-motion)
17
+ * is-icon-only — boolean, forces a 1:1 aspect ratio with minimal xxs padding (requires aria-label)
18
18
  * type — "button" (default) | "submit" | "reset"
19
19
  *
20
+ * Form participation: form-associated via the Form-Associated Custom Elements
21
+ * API (ElementInternals). When nested inside a light-DOM <form>, type="submit"
22
+ * calls the form's requestSubmit() and type="reset" calls its reset() — the
23
+ * inner shadow-DOM <button> has no native form of its own to act on.
24
+ *
20
25
  * Slots:
21
26
  * (default) — button label
22
27
  * icon-start — icon placed before the label
@@ -32,7 +37,19 @@ export type ButtonSize = 'small' | 'medium' | 'large';
32
37
  * </bds-button>
33
38
  */
34
39
  export class BdsButton extends LitElement {
40
+ static formAssociated = true;
41
+
35
42
  static styles = css`
43
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
44
+ here; otherwise elements with an explicit size + padding size as
45
+ content-box and layouts drift from the React (light-DOM) versions. */
46
+ :host,
47
+ *,
48
+ *::before,
49
+ *::after {
50
+ box-sizing: border-box;
51
+ }
52
+
36
53
  @keyframes fadeZoom {
37
54
  0%, 100% { opacity: 1; transform: scale(1); }
38
55
  50% { opacity: 0.75; transform: scale(1.15); }
@@ -60,10 +77,11 @@ export class BdsButton extends LitElement {
60
77
  align-items: center;
61
78
  cursor: pointer;
62
79
  justify-content: center;
63
- height: var(--button_height, 3em);
80
+ block-size: var(--button_height, 3em);
64
81
  font-size: var(--button_font-size, inherit);
65
82
  white-space: nowrap;
66
83
  line-height: 1;
84
+ scroll-padding-block-end: var(--bds-space_l);
67
85
 
68
86
  /* Identity tokens — override --button_color + --button_on-color to re-theme */
69
87
  --button_color: var(--bds-color_interactive);
@@ -120,7 +138,7 @@ export class BdsButton extends LitElement {
120
138
  animation: pulse 3s infinite;
121
139
  }
122
140
 
123
- /* Icon-only: square (1:1), equal xs padding on both axes — composes with
141
+ /* Icon-only: square (1:1), equal xxs padding on both axes — composes with
124
142
  any variant/size. box-sizing: border-box keeps the outer box at
125
143
  --button_height; without it, all: unset reverts to content-box and
126
144
  padding-block would stretch the button past its declared height.
@@ -129,7 +147,7 @@ export class BdsButton extends LitElement {
129
147
  .button.is-icon-only {
130
148
  aspect-ratio: 1;
131
149
  box-sizing: border-box;
132
- padding: var(--bds-space_xs);
150
+ padding: var(--bds-space_xxs);
133
151
  }
134
152
 
135
153
  :host([is-icon-only]) ::slotted(*) {
@@ -137,8 +155,11 @@ export class BdsButton extends LitElement {
137
155
  block-size: 100%;
138
156
  }
139
157
 
140
- /* SVG icon colour */
141
- .button svg {
158
+ /* SVG icon colour — icons are slotted (light DOM), so a shadow-tree
159
+ descendant selector like ".button svg" can never match them; ::slotted()
160
+ is required to reach content projected through a <slot>. */
161
+ .icon-start ::slotted(svg),
162
+ .icon-end ::slotted(svg) {
142
163
  --icon__stroke: currentcolor;
143
164
  fill: currentcolor;
144
165
  color: currentcolor;
@@ -170,19 +191,19 @@ export class BdsButton extends LitElement {
170
191
  margin-inline: 0;
171
192
  }
172
193
 
173
- /* Hover icon animation */
194
+ /* Hover icon animation — same ::slotted() requirement as the colour rule above */
174
195
  @media (hover: hover) and (pointer: fine) {
175
- .button:hover .icon-start svg,
176
- .button:hover .icon-end svg {
196
+ .button:hover .icon-start ::slotted(svg),
197
+ .button:hover .icon-end ::slotted(svg) {
177
198
  animation: fadeZoom 2s ease-out infinite;
178
199
  }
179
200
 
180
201
  /* Default hover */
181
202
  .button.default:hover {
182
203
  --button_bg--variant: var(--button_bg--hover, var(--bds-color_bg));
183
- --button_text--variant: var(--button_text--hover, var(--bds-color_interactive));
204
+ --button_text--variant: var(--button_text--hover, var(--bds-color_interactive_on-bg));
184
205
  --button_border--variant: var(--button_border--hover, currentcolor);
185
- --button_pulse-color: var(--button_pulse-color--hover, var(--bds-color_interactive));
206
+ --button_pulse-color: var(--button_pulse-color--hover, var(--bds-color_interactive_on-bg));
186
207
  }
187
208
 
188
209
  /* Outline hover */
@@ -194,11 +215,20 @@ export class BdsButton extends LitElement {
194
215
  }
195
216
  }
196
217
 
218
+ /* Reduced motion — the pulse ring and hover icon animation both loop
219
+ indefinitely; disable them for users who opt out of motion. */
220
+ @media (prefers-reduced-motion: reduce) {
221
+ .button.has-pulse,
222
+ .button:hover .icon-start ::slotted(svg),
223
+ .button:hover .icon-end ::slotted(svg) {
224
+ animation: none;
225
+ }
226
+ }
227
+
197
228
  /* Focus visible */
198
229
  .button:focus-visible {
199
230
  outline: var(--bds-outline_default);
200
231
  outline-offset: var(--bds-outline_offset);
201
- border-radius: var(--bds-border_radius--s);
202
232
  }
203
233
 
204
234
  /* Disabled */
@@ -241,8 +271,11 @@ export class BdsButton extends LitElement {
241
271
  declare private _iconStartFilled: boolean;
242
272
  declare private _iconEndFilled: boolean;
243
273
 
274
+ private _internals!: ElementInternals;
275
+
244
276
  constructor() {
245
277
  super();
278
+ this._internals = this.attachInternals();
246
279
  this.variant = 'default';
247
280
  this.size = 'medium';
248
281
  this.disabled = false;
@@ -274,6 +307,19 @@ export class BdsButton extends LitElement {
274
307
  }
275
308
  }
276
309
 
310
+ // The shadow-DOM <button> below has no native <form> ancestor of its own
311
+ // (the light-DOM form, if any, lives outside the shadow tree), so its
312
+ // type="submit"/"reset" attribute is inert on its own. Drive the real
313
+ // behaviour through ElementInternals, which resolves the form this
314
+ // *custom element* participates in.
315
+ private _handleButtonClick() {
316
+ if (this.type === 'submit') {
317
+ this._internals.form?.requestSubmit();
318
+ } else if (this.type === 'reset') {
319
+ this._internals.form?.reset();
320
+ }
321
+ }
322
+
277
323
  private _iconSlot(position: 'start' | 'end') {
278
324
  const filled = position === 'start' ? this._iconStartFilled : this._iconEndFilled;
279
325
  return html`
@@ -309,6 +355,7 @@ export class BdsButton extends LitElement {
309
355
  type=${this.type}
310
356
  ?disabled=${this.disabled}
311
357
  aria-label=${this.ariaLabel ?? nothing}
358
+ @click=${this._handleButtonClick}
312
359
  >
313
360
  ${this._iconSlot('start')}
314
361
  <slot></slot>