@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
@@ -19,6 +19,16 @@ export class BdsFileInput extends LitElement {
19
19
  static formAssociated = true;
20
20
 
21
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
+
22
32
  :host {
23
33
  display: block;
24
34
  }
@@ -33,12 +43,14 @@ export class BdsFileInput extends LitElement {
33
43
  flex-direction: column;
34
44
  align-items: center;
35
45
  justify-content: center;
36
- gap: var(--bds-space_s);
37
- padding: var(--bds-space_xl);
38
- border-radius: var(--bds-border_radius--m);
39
- border: 2px dashed var(--file-input_border-color, var(--bds-color_bg--subtle));
40
- background-color: var(--file-input_color_bg, var(--bds-color_bg));
41
- color: var(--bds-color_on-bg);
46
+ gap: var(--bds-space_xs);
47
+ padding: var(--bds-space_l) var(--bds-space_m);
48
+ border: 2px dashed currentcolor;
49
+ border-radius: var(--bds-border_radius--s);
50
+ /* --file-input_color_bg is a deprecated alias — React declares no base background (transparent is its effective default) */
51
+ background-color: var(--file-input_color_bg, transparent);
52
+ /* --fileInput_color drives the currentcolor dashed border (matches React) */
53
+ color: var(--fileInput_color, var(--bds-color_on-bg));
42
54
  font-family: var(--bds-font_family--body);
43
55
  font-size: var(--bds-font_size--body);
44
56
  cursor: pointer;
@@ -46,17 +58,26 @@ export class BdsFileInput extends LitElement {
46
58
  transition: var(--bds-animation_transition);
47
59
  }
48
60
 
61
+ .zone:focus-within {
62
+ outline: var(--bds-outline_default);
63
+ outline-offset: var(--bds-outline_offset);
64
+ /* --file-input_border-color is a deprecated alias — prefer --fileInput_border-color (matches React) */
65
+ border-color: var(--fileInput_border-color, var(--file-input_border-color, currentcolor));
66
+ }
67
+
49
68
  .zone.--dragging {
50
- border-color: var(--bds-color_interactive);
51
- background-color: var(--bds-color_bg--subtle);
69
+ border-color: currentcolor;
70
+ background-color: rgb(from currentcolor r g b / 8%);
52
71
  }
53
72
 
54
73
  .zone-input {
55
74
  position: absolute;
56
- opacity: 0;
57
- inline-size: 0;
58
- block-size: 0;
75
+ inline-size: 1px;
76
+ block-size: 1px;
59
77
  overflow: hidden;
78
+ clip: rect(0, 0, 0, 0);
79
+ white-space: nowrap;
80
+ border: 0;
60
81
  }
61
82
 
62
83
  .zone-label {
@@ -85,8 +106,8 @@ export class BdsFileInput extends LitElement {
85
106
 
86
107
  @media (hover: hover) and (pointer: fine) {
87
108
  .zone:hover {
88
- border-color: var(--bds-color_interactive);
89
- background-color: var(--bds-color_bg--subtle);
109
+ border-color: var(--fileInput_border-color--hover, var(--bds-color_interactive));
110
+ background-color: var(--fileInput_bg--hover, rgb(from var(--bds-color_interactive) r g b / 4%));
90
111
  }
91
112
  }
92
113
  `;
@@ -122,7 +143,7 @@ export class BdsFileInput extends LitElement {
122
143
  if (input) input.value = '';
123
144
  }
124
145
 
125
- private _handleFiles(files: FileList | null) {
146
+ private _handleFiles(files: FileList | File[] | null) {
126
147
  if (!files || files.length === 0) return;
127
148
  const formData = new FormData();
128
149
  Array.from(files).forEach(file => formData.append(this.name, file));
@@ -138,8 +159,14 @@ export class BdsFileInput extends LitElement {
138
159
  this._handleFiles((e.target as HTMLInputElement).files);
139
160
  }
140
161
 
141
- private _handleClick() {
142
- this.shadowRoot?.querySelector<HTMLInputElement>('input')?.click();
162
+ private _isFileAccepted(file: File): boolean {
163
+ if (!this.accept) return true;
164
+ return this.accept.split(',').some(token => {
165
+ const t = token.trim();
166
+ if (t.startsWith('.')) return file.name.toLowerCase().endsWith(t.toLowerCase());
167
+ if (t.endsWith('/*')) return file.type.startsWith(t.slice(0, -1));
168
+ return file.type === t;
169
+ });
143
170
  }
144
171
 
145
172
  private _handleDragover(e: DragEvent) {
@@ -159,29 +186,29 @@ export class BdsFileInput extends LitElement {
159
186
  e.preventDefault();
160
187
  this._isDragging = false;
161
188
  this.requestUpdate();
162
- this._handleFiles(e.dataTransfer?.files ?? null);
189
+ if (this.disabled) return;
190
+ const dropped = e.dataTransfer?.files;
191
+ if (!dropped) return;
192
+ const accepted = Array.from(dropped).filter(file => this._isFileAccepted(file));
193
+ const input = this.shadowRoot?.querySelector<HTMLInputElement>('input');
194
+ // `DataTransfer` is unavailable in some test/runtime environments (e.g. jsdom) — fall back
195
+ // to notifying with the filtered files without syncing the native input's file list.
196
+ if (input && typeof DataTransfer !== 'undefined') {
197
+ const dt = new DataTransfer();
198
+ accepted.forEach(file => dt.items.add(file));
199
+ input.files = dt.files;
200
+ this._handleFiles(input.files);
201
+ } else {
202
+ this._handleFiles(accepted);
203
+ }
163
204
  }
164
205
 
165
206
  render() {
166
207
  const id = `bds-file-${this._uid}`;
167
208
  return html`
168
- <input
169
- id=${id}
170
- type="file"
171
- class="zone-input"
172
- name=${this.name}
173
- accept=${this.accept}
174
- ?multiple=${this.multiple}
175
- ?disabled=${this.disabled}
176
- @change=${this._handleInputChange}
177
- />
178
- <div
209
+ <label
210
+ for=${id}
179
211
  class="zone ${this._isDragging ? '--dragging' : ''}"
180
- role="button"
181
- tabindex=${this.disabled ? '-1' : '0'}
182
- aria-label="Upload file"
183
- @click=${this._handleClick}
184
- @keydown=${(e: KeyboardEvent) => (e.key === 'Enter' || e.key === ' ') && this._handleClick()}
185
212
  @dragover=${this._handleDragover}
186
213
  @dragleave=${this._handleDragleave}
187
214
  @drop=${this._handleDrop}
@@ -195,7 +222,17 @@ export class BdsFileInput extends LitElement {
195
222
  <slot>Drag &amp; drop or click to browse</slot>
196
223
  </span>
197
224
  <span class="hint">${this.accept ? `Accepted: ${this.accept}` : 'Any file type'}</span>
198
- </div>
225
+ <input
226
+ id=${id}
227
+ type="file"
228
+ class="zone-input"
229
+ name=${this.name}
230
+ accept=${this.accept}
231
+ ?multiple=${this.multiple}
232
+ ?disabled=${this.disabled}
233
+ @change=${this._handleInputChange}
234
+ />
235
+ </label>
199
236
  `;
200
237
  }
201
238
  }
@@ -68,6 +68,28 @@ describe('bds-form-input', () => {
68
68
  cleanup(el);
69
69
  });
70
70
 
71
+ it('renders both error and hint messages when both are set, and aria-describedby references both', async () => {
72
+ const el = await fixture(
73
+ '<bds-form-input name="email" error="Invalid email" hint="We will not share your email"></bds-form-input>',
74
+ );
75
+ const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
76
+ const errorMsg = el.shadowRoot!.querySelector('.message--error');
77
+ const hintMsg = el.shadowRoot!.querySelector('.message--hint');
78
+ expect(errorMsg?.textContent?.trim()).toBe('Invalid email');
79
+ expect(hintMsg?.textContent?.trim()).toBe('We will not share your email');
80
+ const describedBy = input.getAttribute('aria-describedby')!.split(' ');
81
+ expect(describedBy).toContain(errorMsg!.id);
82
+ expect(describedBy).toContain(hintMsg!.id);
83
+ cleanup(el);
84
+ });
85
+
86
+ it('omits aria-describedby when neither error nor hint is set', async () => {
87
+ const el = await fixture('<bds-form-input name="email"></bds-form-input>');
88
+ const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
89
+ expect(input.hasAttribute('aria-describedby')).toBe(false);
90
+ cleanup(el);
91
+ });
92
+
71
93
  it('fires bds-change on change', async () => {
72
94
  const el = await fixture('<bds-form-input name="email"></bds-form-input>');
73
95
  const values: string[] = [];
@@ -1,4 +1,5 @@
1
1
  import { LitElement, css, html } from 'lit';
2
+ import { ifDefined } from 'lit/directives/if-defined.js';
2
3
 
3
4
  /**
4
5
  * `<bds-form-input>` — form-associated text input with label, hint, and error support.
@@ -31,6 +32,16 @@ export class BdsFormInput extends LitElement {
31
32
  static formAssociated = true;
32
33
 
33
34
  static styles = css`
35
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
36
+ here; otherwise elements with an explicit size + padding size as
37
+ content-box and layouts drift from the React (light-DOM) versions. */
38
+ :host,
39
+ *,
40
+ *::before,
41
+ *::after {
42
+ box-sizing: border-box;
43
+ }
44
+
34
45
  :host {
35
46
  display: block;
36
47
  }
@@ -58,17 +69,20 @@ export class BdsFormInput extends LitElement {
58
69
  position: relative;
59
70
  display: flex;
60
71
  align-items: center;
72
+ border: var(--formInput_border, var(--input_border, none));
73
+ /* deprecated: --formInput_border-color kept as a legacy override for the frame colour */
61
74
  --bdc_color: var(--formInput_border-color, currentcolor);
62
- --bdc-outline_radius: var(--bds-border_radius--xs);
75
+ --bdc-outline_radius: var(--bds-border_radius--full);
63
76
 
64
- border-radius: var(--formInput_radius, var(--bdc-outline_radius));
65
- box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--formInput_shadow, var(--bdc-outline_shadow));
66
- background-color: var(--bds-color_bg);
67
- transition: --bdc_color var(--bds-animation_transition-duration) var(--bds-animation_easing);
77
+ border-radius: var(--formInput_radius, var(--input_radius, var(--bdc-outline_radius)));
78
+ box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--formInput_shadow, var(--input_shadow, var(--bdc-outline_shadow)));
79
+ background-color: var(--formInput_color_bg, var(--input_color_bg, var(--bds-color_bg)));
80
+ transition: --bdc_color var(--bds-animation_transition-duration) var(--bds-animation_easing),
81
+ background-color var(--bds-animation_transition-duration) var(--bds-animation_easing);
68
82
  }
69
83
 
70
84
  :host([error]) .wrapper {
71
- --bdc_color: var(--bds-color_error);
85
+ --bdc_color: var(--bdc_color--error);
72
86
  }
73
87
 
74
88
  .wrapper:focus-within {
@@ -76,7 +90,7 @@ export class BdsFormInput extends LitElement {
76
90
  }
77
91
 
78
92
  :host([error]) .wrapper:focus-within {
79
- --bdc_color: var(--bds-color_error);
93
+ --bdc_color: var(--bdc_color--error);
80
94
  }
81
95
 
82
96
  .input {
@@ -87,7 +101,7 @@ export class BdsFormInput extends LitElement {
87
101
  padding: var(--bds-space_s);
88
102
  font-size: var(--bds-font_size--body);
89
103
  font-family: var(--bds-font_family--body);
90
- color: var(--bds-color_on-bg);
104
+ color: var(--formInput_color, var(--input_color, var(--bds-color_on-bg)));
91
105
  outline: none;
92
106
  }
93
107
 
@@ -99,10 +113,10 @@ export class BdsFormInput extends LitElement {
99
113
  outline: none;
100
114
  }
101
115
 
102
- .wrapper:focus-within {
116
+ .wrapper:focus-within:has(:focus-visible) {
103
117
  outline: var(--bds-outline_default);
104
118
  outline-offset: var(--bds-outline_offset);
105
- border-radius: var(--formInput_radius, var(--bdc-outline_radius));
119
+ border-radius: var(--formInput_radius, var(--input_radius, var(--bdc-outline_radius)));
106
120
  }
107
121
 
108
122
  .prefix,
@@ -244,18 +258,15 @@ export class BdsFormInput extends LitElement {
244
258
  ?disabled=${this.disabled}
245
259
  ?required=${this.required}
246
260
  aria-invalid=${this.error ? 'true' : 'false'}
247
- aria-describedby=${describedBy ?? ''}
261
+ aria-describedby=${ifDefined(describedBy)}
248
262
  aria-required=${this.required ? 'true' : 'false'}
249
263
  @input=${this._handleInput}
250
264
  @change=${this._handleChange}
251
265
  />
252
266
  <span class="suffix"><slot name="suffix"></slot></span>
253
267
  </div>
254
- ${this.error
255
- ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
256
- : this.hint
257
- ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
258
- : ''}
268
+ ${this.error ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>` : ''}
269
+ ${this.hint ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>` : ''}
259
270
  `;
260
271
  }
261
272
  }
@@ -84,4 +84,53 @@ describe('bds-number-input', () => {
84
84
  it('is form-associated', () => {
85
85
  expect(BdsNumberInput.formAssociated).toBe(true);
86
86
  });
87
+
88
+ it('renders a label wired to the input via for/id', async () => {
89
+ const el = await fixture('<bds-number-input name="qty" label="Quantity"></bds-number-input>');
90
+ const label = el.shadowRoot!.querySelector<HTMLLabelElement>('label')!;
91
+ const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
92
+ expect(label).not.toBeNull();
93
+ expect(label.textContent?.trim()).toBe('Quantity');
94
+ expect(label.getAttribute('for')).toBe(input.id);
95
+ expect(input.id).not.toBe('');
96
+ cleanup(el);
97
+ });
98
+
99
+ it('renders no label element when label is unset', async () => {
100
+ const el = await fixture('<bds-number-input name="qty"></bds-number-input>');
101
+ expect(el.shadowRoot!.querySelector('label')).toBeNull();
102
+ cleanup(el);
103
+ });
104
+
105
+ it('wires aria-controls on both steppers to the input id', async () => {
106
+ const el = await fixture('<bds-number-input name="qty"></bds-number-input>');
107
+ const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
108
+ const decBtn = el.shadowRoot!.querySelector<HTMLButtonElement>('button[aria-label="Decrease"]')!;
109
+ const incBtn = el.shadowRoot!.querySelector<HTMLButtonElement>('button[aria-label="Increase"]')!;
110
+ expect(decBtn.getAttribute('aria-controls')).toBe(input.id);
111
+ expect(incBtn.getAttribute('aria-controls')).toBe(input.id);
112
+ cleanup(el);
113
+ });
114
+
115
+ it('sets aria-invalid and aria-describedby and renders an error message when error is set', async () => {
116
+ const el = await fixture('<bds-number-input name="qty" error="Out of range"></bds-number-input>');
117
+ const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
118
+ const message = el.shadowRoot!.querySelector<HTMLParagraphElement>('.message--error')!;
119
+ expect(input.getAttribute('aria-invalid')).toBe('true');
120
+ expect(input.getAttribute('aria-describedby')).toBe(message.id);
121
+ expect(message.textContent).toBe('Out of range');
122
+ expect(message.getAttribute('role')).toBe('alert');
123
+ cleanup(el);
124
+ });
125
+
126
+ it('renders a hint message and wires aria-describedby when hint is set (no error)', async () => {
127
+ const el = await fixture('<bds-number-input name="qty" hint="Whole numbers only"></bds-number-input>');
128
+ const input = el.shadowRoot!.querySelector<HTMLInputElement>('input')!;
129
+ const message = el.shadowRoot!.querySelector<HTMLParagraphElement>('.message--hint')!;
130
+ expect(message).not.toBeNull();
131
+ expect(message.textContent).toBe('Whole numbers only');
132
+ expect(input.getAttribute('aria-invalid')).toBe('false');
133
+ expect(input.getAttribute('aria-describedby')).toBe(message.id);
134
+ cleanup(el);
135
+ });
87
136
  });
@@ -10,18 +10,31 @@ import { LitElement, css, html } from 'lit';
10
10
  * max — maximum allowed value
11
11
  * step — increment/decrement step (default: 1)
12
12
  * disabled — boolean
13
+ * label — visible label text, associated with the input via `for`/`id`
14
+ * hint — helper text shown below the input
15
+ * error — error message; when set the input enters error state
13
16
  *
14
17
  * Events:
15
18
  * input — fired on stepper click and native input
16
19
  * change — native change event
17
20
  *
18
21
  * @example
19
- * <bds-number-input name="qty" value="1" min="0" max="99" step="1"></bds-number-input>
22
+ * <bds-number-input name="qty" label="Quantity" value="1" min="0" max="99" step="1"></bds-number-input>
20
23
  */
21
24
  export class BdsNumberInput extends LitElement {
22
25
  static formAssociated = true;
23
26
 
24
27
  static styles = css`
28
+ /* Shadow DOM does not inherit the global box-sizing reset, so set it
29
+ here; otherwise elements with an explicit size + padding size as
30
+ content-box and layouts drift from the React (light-DOM) versions. */
31
+ :host,
32
+ *,
33
+ *::before,
34
+ *::after {
35
+ box-sizing: border-box;
36
+ }
37
+
25
38
  :host {
26
39
  display: block;
27
40
  }
@@ -31,42 +44,67 @@ export class BdsNumberInput extends LitElement {
31
44
  pointer-events: none;
32
45
  }
33
46
 
47
+ .label {
48
+ display: block;
49
+ font-size: var(--bds-font_size--body--s);
50
+ font-family: var(--bds-font_family--body);
51
+ font-weight: var(--bds-font_weight--semibold);
52
+ color: var(--bds-color_on-bg);
53
+ margin-block-end: var(--bds-space_xxs);
54
+ }
55
+
34
56
  .row {
35
57
  display: flex;
36
- align-items: center;
58
+ align-items: stretch;
59
+ border: var(--numberInput_border, none);
60
+ /* deprecated: --number-input_border-color kept as a legacy override for the frame colour */
61
+ --bdc_color: var(--number-input_border-color, currentcolor);
62
+ --bdc-outline_radius: var(--bds-border_radius--full);
63
+
64
+ /* deprecated: --number-input_radius kept as a legacy fallback below --numberInput_radius */
65
+ --_radius: var(--numberInput_radius, var(--number-input_radius, var(--bdc-outline_radius)));
66
+
67
+ border-radius: var(--_radius);
68
+ box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--numberInput_shadow, var(--number-input_shadow, var(--bdc-outline_shadow)));
69
+ overflow: hidden;
70
+ transition: --bdc_color var(--bds-animation_transition-duration) var(--bds-animation_easing);
71
+ }
72
+
73
+ :host([error]) .row {
74
+ --bdc_color: var(--bdc_color--error);
75
+ }
76
+
77
+ .row:focus-within {
78
+ --bdc_color: var(--bdc_color--focus);
79
+ }
80
+
81
+ :host([error]) .row:focus-within {
82
+ --bdc_color: var(--bdc_color--error);
83
+ }
84
+
85
+ .row:focus-within:has(:focus-visible) {
86
+ outline: var(--bds-outline_default);
87
+ outline-offset: var(--bds-outline_offset);
37
88
  }
38
89
 
39
90
  .input {
40
91
  flex: 1;
41
- font-family: var(--bds-font_family--body);
42
- font-size: var(--bds-font_size--body);
43
- padding: var(--bds-space_s);
44
92
  border: none;
45
- --bdc_color: var(--number-input_border-color, currentcolor);
46
- --bdc-outline_radius: var(--bds-border_radius--xs);
47
-
48
- border-radius: var(--number-input_radius, var(--bdc-outline_radius));
49
- box-shadow: inset 0 0 0 var(--bdc-outline_width) var(--bdc_color), var(--number-input_shadow, var(--bdc-outline_shadow));
50
- background-color: var(--number-input_color_bg, var(--bds-color_bg));
51
- color: var(--number-input_color, var(--bds-color_on-bg));
93
+ outline: none;
94
+ font-family: var(--bds-font_family--body);
95
+ font-size: var(--numberInput_font-size, var(--bds-font_size--body));
96
+ padding: var(--numberInput_padding, var(--bds-space_s));
97
+ /* deprecated: --number-input_color_bg kept as a legacy override; React default is transparent */
98
+ background: var(--number-input_color_bg, transparent);
99
+ color: var(--numberInput_color, var(--number-input_color, var(--bds-color_on-bg)));
52
100
  text-align: center;
53
- -moz-appearance: textfield;
101
+ appearance: textfield;
54
102
  min-inline-size: 0;
55
103
  }
56
104
 
57
105
  .input::-webkit-inner-spin-button,
58
106
  .input::-webkit-outer-spin-button {
59
107
  appearance: none;
60
- margin: 0;
61
- }
62
-
63
- .input:focus {
64
- --bdc_color: var(--bdc_color--focus);
65
- }
66
-
67
- .input:focus-visible {
68
- outline: var(--bds-outline_default);
69
- outline-offset: var(--bds-outline_offset);
70
108
  }
71
109
 
72
110
  .stepper {
@@ -74,16 +112,25 @@ export class BdsNumberInput extends LitElement {
74
112
  display: flex;
75
113
  align-items: center;
76
114
  justify-content: center;
77
- margin: 1px;
78
- inline-size: 2rem;
79
- block-size: 2rem;
80
- border-radius: var(--bds-border_radius--xs);
115
+ padding: var(--numberInput_stepper-padding, var(--bds-space_xs));
116
+ margin: var(--bdc-outline_width);
81
117
  cursor: pointer;
82
118
  flex-shrink: 0;
83
- color: var(--bds-color_interactive);
119
+ background-color: var(--numberInput_stepper-bg, var(--bds-color_bg--subtle));
120
+ color: var(--numberInput_stepper-color, var(--bds-color_interactive));
84
121
  transition: var(--bds-animation_transition);
85
122
  }
86
123
 
124
+ .stepper:first-child {
125
+ border-start-start-radius: var(--_radius);
126
+ border-end-start-radius: var(--_radius);
127
+ }
128
+
129
+ .stepper:last-child {
130
+ border-start-end-radius: var(--_radius);
131
+ border-end-end-radius: var(--_radius);
132
+ }
133
+
87
134
  .stepper:focus-visible {
88
135
  outline: var(--bds-outline_default);
89
136
  outline-offset: var(--bds-outline_offset);
@@ -96,13 +143,30 @@ export class BdsNumberInput extends LitElement {
96
143
 
97
144
  @media (hover: hover) and (pointer: fine) {
98
145
  .stepper:not(:disabled):hover {
99
- background-color: var(--bds-color_bg--subtle);
146
+ background-color: var(--numberInput_stepper-bg--hover, var(--bds-color_bg--subtle));
147
+ opacity: var(--numberInput_stepper-opacity--hover, 0.7);
100
148
  }
101
149
  }
102
150
 
103
151
  .stepper svg {
104
152
  inline-size: 1rem;
105
153
  block-size: 1rem;
154
+ color: var(--numberInput_stepper-color, var(--bds-color_interactive));
155
+ }
156
+
157
+ .message {
158
+ margin-block-start: var(--bds-space_xxs);
159
+ font-size: var(--bds-font_size--body--s);
160
+ font-family: var(--bds-font_family--body);
161
+ }
162
+
163
+ .message--error {
164
+ color: var(--bds-color_error);
165
+ }
166
+
167
+ .message--hint {
168
+ color: var(--bds-color_on-bg--subtle);
169
+ font-style: italic;
106
170
  }
107
171
  `;
108
172
 
@@ -113,6 +177,9 @@ export class BdsNumberInput extends LitElement {
113
177
  max: { type: Number },
114
178
  step: { type: Number },
115
179
  disabled: { type: Boolean, reflect: true },
180
+ label: { type: String },
181
+ hint: { type: String },
182
+ error: { type: String, reflect: true },
116
183
  };
117
184
 
118
185
  declare name: string;
@@ -121,8 +188,12 @@ export class BdsNumberInput extends LitElement {
121
188
  declare max: number | undefined;
122
189
  declare step: number;
123
190
  declare disabled: boolean;
191
+ declare label: string;
192
+ declare hint: string | undefined;
193
+ declare error: string | undefined;
124
194
 
125
195
  private _internals!: ElementInternals;
196
+ private readonly _uid = Math.random().toString(36).slice(2, 8);
126
197
 
127
198
  constructor() {
128
199
  super();
@@ -133,6 +204,9 @@ export class BdsNumberInput extends LitElement {
133
204
  this.max = undefined;
134
205
  this.step = 1;
135
206
  this.disabled = false;
207
+ this.label = '';
208
+ this.hint = undefined;
209
+ this.error = undefined;
136
210
  }
137
211
 
138
212
  updated(changed: Map<string, unknown>) {
@@ -168,13 +242,19 @@ export class BdsNumberInput extends LitElement {
168
242
  render() {
169
243
  const atMin = this.min !== undefined && this.value <= this.min;
170
244
  const atMax = this.max !== undefined && this.value >= this.max;
245
+ const id = `bds-number-input-${this._uid}`;
246
+ const hintId = `${id}-hint`;
247
+ const errorId = `${id}-error`;
248
+ const describedBy = [this.error && errorId, this.hint && hintId].filter(Boolean).join(' ') || undefined;
171
249
 
172
250
  return html`
251
+ ${this.label ? html`<label class="label" for=${id}>${this.label}</label>` : ''}
173
252
  <div class="row">
174
253
  <button
175
254
  type="button"
176
255
  class="stepper"
177
256
  aria-label="Decrease"
257
+ aria-controls=${id}
178
258
  tabindex="-1"
179
259
  ?disabled=${this.disabled || atMin}
180
260
  @click=${() => this._adjust(-this.step)}
@@ -184,6 +264,7 @@ export class BdsNumberInput extends LitElement {
184
264
  </svg>
185
265
  </button>
186
266
  <input
267
+ id=${id}
187
268
  type="number"
188
269
  class="input"
189
270
  name=${this.name}
@@ -192,12 +273,15 @@ export class BdsNumberInput extends LitElement {
192
273
  max=${this.max ?? ''}
193
274
  step=${this.step}
194
275
  ?disabled=${this.disabled}
276
+ aria-invalid=${this.error ? 'true' : 'false'}
277
+ aria-describedby=${describedBy ?? ''}
195
278
  @change=${this._handleChange}
196
279
  />
197
280
  <button
198
281
  type="button"
199
282
  class="stepper"
200
283
  aria-label="Increase"
284
+ aria-controls=${id}
201
285
  tabindex="-1"
202
286
  ?disabled=${this.disabled || atMax}
203
287
  @click=${() => this._adjust(this.step)}
@@ -207,6 +291,11 @@ export class BdsNumberInput extends LitElement {
207
291
  </svg>
208
292
  </button>
209
293
  </div>
294
+ ${this.error
295
+ ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
296
+ : this.hint
297
+ ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
298
+ : ''}
210
299
  `;
211
300
  }
212
301
  }