@boostdev/design-system-components 2.15.0 → 2.17.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 (299) hide show
  1. package/AGENTS.md +22 -15
  2. package/dist/client.cjs +271 -205
  3. package/dist/client.css +813 -650
  4. package/dist/client.d.cts +19 -4
  5. package/dist/client.d.ts +19 -4
  6. package/dist/client.js +206 -139
  7. package/dist/index.cjs +271 -205
  8. package/dist/index.css +813 -650
  9. package/dist/index.d.cts +19 -4
  10. package/dist/index.d.ts +19 -4
  11. package/dist/index.js +206 -139
  12. package/dist/web-components/chunk-2DHW2WJZ.js +154 -0
  13. package/dist/web-components/{chunk-3WAV6MDN.js → chunk-3FSGP35V.js} +1 -0
  14. package/dist/web-components/{chunk-SYNLFKD3.js → chunk-3LQKFSMR.js} +6 -0
  15. package/dist/web-components/{chunk-KA3VPKMY.js → chunk-4MB2ICSK.js} +1 -0
  16. package/dist/web-components/{chunk-6G22I2CK.js → chunk-5ATTKUCP.js} +33 -3
  17. package/dist/web-components/{chunk-IDSM74LM.js → chunk-6XL5P76D.js} +3 -3
  18. package/dist/web-components/{chunk-P24JYC5V.js → chunk-7VXRMCAL.js} +10 -4
  19. package/dist/web-components/{chunk-CUKQ2L5B.js → chunk-AGI6YQRC.js} +9 -16
  20. package/dist/web-components/chunk-BDRV452N.js +51 -0
  21. package/dist/web-components/{chunk-3AY2YKCM.js → chunk-CKCPV347.js} +1 -0
  22. package/dist/web-components/{chunk-HBLJ4SLY.js → chunk-DD3OUXNG.js} +5 -5
  23. package/dist/web-components/{chunk-RVF7W653.js → chunk-DGOCPKHI.js} +30 -10
  24. package/dist/web-components/{chunk-2OLVQUBU.js → chunk-EYCW7TKB.js} +8 -15
  25. package/dist/web-components/{chunk-VANAKB6D.js → chunk-GPJWLAKU.js} +33 -16
  26. package/dist/web-components/{chunk-VED2DFJ6.js → chunk-GQNQBEYR.js} +8 -15
  27. package/dist/web-components/{chunk-WFVKU4GX.js → chunk-IKAJLROF.js} +49 -4
  28. package/dist/web-components/{chunk-RSZ3BWBK.js → chunk-KSK4RZZQ.js} +30 -7
  29. package/dist/web-components/{chunk-FEDABOR5.js → chunk-LHFUXZ52.js} +7 -15
  30. package/dist/web-components/{chunk-M3ECULRH.js → chunk-RBF7WPLI.js} +10 -8
  31. package/dist/web-components/{chunk-BPYKZVDK.js → chunk-SJLMW2VR.js} +2 -2
  32. package/dist/web-components/chunk-SRKQ6GST.js +40 -0
  33. package/dist/web-components/{chunk-5HUAFCU6.js → chunk-TJV7UIXC.js} +7 -0
  34. package/dist/web-components/{chunk-LDIPCTRN.js → chunk-WWWJCSXN.js} +50 -4
  35. package/dist/web-components/{chunk-J3HVUIUH.js → chunk-XI2U6U26.js} +8 -15
  36. package/dist/web-components/{chunk-JH6LQKLK.js → chunk-XJU7KITO.js} +8 -15
  37. package/dist/web-components/{chunk-JV5QT2OU.js → chunk-YLDQOESI.js} +27 -13
  38. package/dist/web-components/globals.js +1 -1
  39. package/dist/web-components/index.d.ts +1 -0
  40. package/dist/web-components/index.js +35 -30
  41. package/dist/web-components/interaction/bds-dropdown-menu-group.d.ts +41 -0
  42. package/dist/web-components/interaction/bds-dropdown-menu-group.js +7 -0
  43. package/dist/web-components/interaction/bds-dropdown-menu-item.d.ts +14 -1
  44. package/dist/web-components/interaction/bds-dropdown-menu-item.js +1 -1
  45. package/dist/web-components/interaction/bds-dropdown-menu.d.ts +2 -1
  46. package/dist/web-components/interaction/bds-dropdown-menu.js +1 -1
  47. package/dist/web-components/interaction/bds-tab.d.ts +5 -0
  48. package/dist/web-components/interaction/bds-tab.js +1 -1
  49. package/dist/web-components/interaction/bds-tooltip.js +1 -1
  50. package/dist/web-components/interaction/form/bds-checkbox-group.d.ts +6 -0
  51. package/dist/web-components/interaction/form/bds-checkbox-group.js +2 -1
  52. package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
  53. package/dist/web-components/interaction/form/bds-combobox.js +2 -1
  54. package/dist/web-components/interaction/form/bds-form-input.js +2 -1
  55. package/dist/web-components/interaction/form/bds-number-input.js +2 -1
  56. package/dist/web-components/interaction/form/bds-radio-group.d.ts +5 -0
  57. package/dist/web-components/interaction/form/bds-radio-group.js +2 -1
  58. package/dist/web-components/interaction/form/bds-radio.js +1 -1
  59. package/dist/web-components/interaction/form/bds-select.js +2 -1
  60. package/dist/web-components/interaction/form/bds-slider.js +2 -1
  61. package/dist/web-components/interaction/form/bds-switch.js +1 -1
  62. package/dist/web-components/interaction/form/bds-textarea.js +2 -1
  63. package/dist/web-components/ui/bds-alert.d.ts +8 -1
  64. package/dist/web-components/ui/bds-alert.js +1 -1
  65. package/dist/web-components/ui/bds-avatar.d.ts +11 -0
  66. package/dist/web-components/ui/bds-avatar.js +1 -1
  67. package/dist/web-components/ui/bds-badge.js +1 -1
  68. package/dist/web-components/ui/bds-notification-banner.d.ts +14 -1
  69. package/dist/web-components/ui/bds-notification-banner.js +1 -1
  70. package/dist/web-components/ui/bds-rating.js +1 -1
  71. package/dist/web-components/ui/bds-section-header.d.ts +6 -0
  72. package/dist/web-components/ui/bds-section-header.js +1 -1
  73. package/dist/web-components/ui/bds-separator.js +1 -1
  74. package/dist/web-components/ui/bds-table.js +1 -1
  75. package/package.json +6 -2
  76. package/src/components/interaction/DropdownMenu/DropdownMenu.mdx +35 -4
  77. package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +58 -10
  78. package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +114 -1
  79. package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +25 -0
  80. package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +69 -17
  81. package/src/components/interaction/Rating/Rating.mdx +4 -1
  82. package/src/components/interaction/Rating/Rating.module.css +9 -0
  83. package/src/components/interaction/Rating/Rating.spec.tsx +9 -0
  84. package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -0
  85. package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +7 -0
  86. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.mdx +2 -1
  87. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +8 -1
  88. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +27 -0
  89. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +1 -1
  90. package/src/components/interaction/form/Combobox/Combobox.module.css +1 -0
  91. package/src/components/interaction/form/Combobox/Combobox.spec.tsx +7 -0
  92. package/src/components/interaction/form/FormInput/FormInput.mdx +9 -0
  93. package/src/components/interaction/form/FormInput/FormInput.module.css +1 -0
  94. package/src/components/interaction/form/FormInput/FormInput.spec.tsx +7 -0
  95. package/src/components/interaction/form/NumberInput/NumberInput.module.css +1 -0
  96. package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +7 -0
  97. package/src/components/interaction/form/Radio/Radio.module.css +1 -0
  98. package/src/components/interaction/form/Radio/Radio.spec.tsx +7 -0
  99. package/src/components/interaction/form/RadioGroup/RadioGroup.mdx +2 -1
  100. package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +8 -1
  101. package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +27 -0
  102. package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +1 -1
  103. package/src/components/interaction/form/Select/Select.module.css +1 -0
  104. package/src/components/interaction/form/Select/Select.spec.tsx +7 -0
  105. package/src/components/interaction/form/Switch/Switch.module.css +1 -0
  106. package/src/components/interaction/form/Switch/Switch.spec.tsx +7 -0
  107. package/src/components/interaction/form/Textarea/Textarea.module.css +1 -0
  108. package/src/components/interaction/form/Textarea/Textarea.spec.tsx +7 -0
  109. package/src/components/interaction/form/atoms/Message.module.css +14 -3
  110. package/src/components/interaction/form/atoms/Message.spec.tsx +22 -0
  111. package/src/components/interaction/form/atoms/Message.tsx +5 -0
  112. package/src/components/layout/SectionHeader/SectionHeader.mdx +18 -5
  113. package/src/components/layout/SectionHeader/SectionHeader.module.css +35 -14
  114. package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +44 -0
  115. package/src/components/layout/SectionHeader/SectionHeader.stories.tsx +5 -0
  116. package/src/components/layout/SectionHeader/SectionHeader.tsx +3 -1
  117. package/src/components/ui/Alert/Alert.mdx +12 -1
  118. package/src/components/ui/Alert/Alert.module.css +32 -3
  119. package/src/components/ui/Alert/Alert.spec.tsx +27 -0
  120. package/src/components/ui/Alert/Alert.stories.tsx +20 -0
  121. package/src/components/ui/Alert/Alert.tsx +8 -1
  122. package/src/components/ui/Avatar/Avatar.mdx +22 -2
  123. package/src/components/ui/Avatar/Avatar.module.css +29 -2
  124. package/src/components/ui/Avatar/Avatar.spec.tsx +26 -0
  125. package/src/components/ui/Avatar/Avatar.stories.tsx +23 -0
  126. package/src/components/ui/Avatar/Avatar.tsx +4 -2
  127. package/src/components/ui/Avatar/avatarTone.spec.ts +41 -0
  128. package/src/components/ui/Avatar/avatarTone.ts +22 -0
  129. package/src/components/ui/Badge/Badge.mdx +1 -1
  130. package/src/components/ui/Badge/Badge.module.css +2 -2
  131. package/src/components/ui/Badge/Badge.spec.tsx +8 -0
  132. package/src/components/ui/Collapsible/Collapsible.module.css +1 -2
  133. package/src/components/ui/NotificationBanner/NotificationBanner.mdx +27 -1
  134. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +33 -3
  135. package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +35 -0
  136. package/src/components/ui/NotificationBanner/NotificationBanner.stories.tsx +25 -0
  137. package/src/components/ui/NotificationBanner/NotificationBanner.tsx +15 -1
  138. package/src/components/ui/Separator/Separator.mdx +1 -0
  139. package/src/components/ui/Separator/Separator.module.css +6 -0
  140. package/src/components/ui/Separator/Separator.spec.tsx +19 -0
  141. package/src/components/ui/Separator/Separator.stories.tsx +15 -0
  142. package/src/components/ui/Table/Table.mdx +4 -1
  143. package/src/components/ui/Table/Table.module.css +7 -7
  144. package/src/components/ui/Table/Table.spec.tsx +11 -0
  145. package/src/components/ui/Tabs/Tabs.mdx +11 -5
  146. package/src/components/ui/Tabs/Tabs.module.css +23 -5
  147. package/src/components/ui/Tabs/Tabs.spec.tsx +39 -0
  148. package/src/components/ui/Tabs/Tabs.tsx +2 -1
  149. package/src/components/ui/Tabs/getNodeText.spec.tsx +23 -0
  150. package/src/components/ui/Tabs/getNodeText.ts +13 -0
  151. package/src/components/ui/Tooltip/Tooltip.mdx +6 -3
  152. package/src/components/ui/Tooltip/Tooltip.module.css +6 -2
  153. package/src/components/ui/Tooltip/Tooltip.spec.tsx +10 -0
  154. package/src/components/ui/Tooltip/Tooltip.stories.tsx +13 -0
  155. package/src/css/bdc.css +5 -2
  156. package/src/css/bdc.spec.ts +65 -0
  157. package/src/stories/DesignSystem/Borders.mdx +17 -9
  158. package/src/test/token-contract.spec.ts +1 -0
  159. package/src/web-components/globals.ts +10 -4
  160. package/src/web-components/index.ts +1 -0
  161. package/src/web-components/interaction/BdsAccordion.mdx +1 -1
  162. package/src/web-components/interaction/BdsAccordion.stories.tsx +1 -1
  163. package/src/web-components/interaction/BdsButton.mdx +1 -1
  164. package/src/web-components/interaction/BdsButton.stories.tsx +1 -1
  165. package/src/web-components/interaction/BdsCollapsible.mdx +1 -1
  166. package/src/web-components/interaction/BdsCollapsible.stories.tsx +1 -1
  167. package/src/web-components/interaction/BdsDialog.mdx +1 -1
  168. package/src/web-components/interaction/BdsDialog.stories.tsx +1 -1
  169. package/src/web-components/interaction/BdsDrawer.mdx +1 -1
  170. package/src/web-components/interaction/BdsDrawer.stories.tsx +1 -1
  171. package/src/web-components/interaction/BdsDropdownMenu.mdx +62 -6
  172. package/src/web-components/interaction/BdsDropdownMenu.stories.tsx +32 -7
  173. package/src/web-components/interaction/BdsPopover.mdx +1 -1
  174. package/src/web-components/interaction/BdsPopover.stories.tsx +1 -1
  175. package/src/web-components/interaction/BdsSkipLink.mdx +1 -1
  176. package/src/web-components/interaction/BdsSkipLink.stories.tsx +1 -1
  177. package/src/web-components/interaction/BdsTabs.mdx +10 -1
  178. package/src/web-components/interaction/BdsTabs.stories.tsx +1 -1
  179. package/src/web-components/interaction/BdsToastProvider.mdx +1 -1
  180. package/src/web-components/interaction/BdsToastProvider.stories.tsx +1 -1
  181. package/src/web-components/interaction/BdsTooltip.mdx +13 -5
  182. package/src/web-components/interaction/BdsTooltip.stories.tsx +12 -12
  183. package/src/web-components/interaction/bds-dropdown-menu-group.ts +72 -0
  184. package/src/web-components/interaction/bds-dropdown-menu-item.ts +65 -17
  185. package/src/web-components/interaction/bds-dropdown-menu.spec.ts +135 -0
  186. package/src/web-components/interaction/bds-dropdown-menu.ts +5 -4
  187. package/src/web-components/interaction/bds-tab.spec.ts +34 -2
  188. package/src/web-components/interaction/bds-tab.ts +31 -6
  189. package/src/web-components/interaction/bds-tooltip.spec.ts +16 -0
  190. package/src/web-components/interaction/bds-tooltip.ts +10 -8
  191. package/src/web-components/interaction/form/BdsCheckbox.mdx +5 -1
  192. package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +1 -1
  193. package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +5 -1
  194. package/src/web-components/interaction/form/BdsCheckboxGroup.stories.tsx +1 -1
  195. package/src/web-components/interaction/form/BdsCombobox.mdx +5 -1
  196. package/src/web-components/interaction/form/BdsCombobox.stories.tsx +1 -1
  197. package/src/web-components/interaction/form/BdsFieldGroup.stories.tsx +1 -1
  198. package/src/web-components/interaction/form/BdsFileInput.mdx +1 -1
  199. package/src/web-components/interaction/form/BdsFileInput.stories.tsx +1 -1
  200. package/src/web-components/interaction/form/BdsFormInput.mdx +8 -1
  201. package/src/web-components/interaction/form/BdsFormInput.stories.tsx +1 -1
  202. package/src/web-components/interaction/form/BdsNumberInput.mdx +5 -1
  203. package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +1 -1
  204. package/src/web-components/interaction/form/BdsRadio.mdx +5 -1
  205. package/src/web-components/interaction/form/BdsRadio.stories.tsx +1 -1
  206. package/src/web-components/interaction/form/BdsRadioGroup.mdx +5 -1
  207. package/src/web-components/interaction/form/BdsRadioGroup.stories.tsx +1 -1
  208. package/src/web-components/interaction/form/BdsSegmentedControl.mdx +1 -1
  209. package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +1 -1
  210. package/src/web-components/interaction/form/BdsSelect.mdx +5 -1
  211. package/src/web-components/interaction/form/BdsSelect.stories.tsx +1 -1
  212. package/src/web-components/interaction/form/BdsSlider.mdx +5 -1
  213. package/src/web-components/interaction/form/BdsSlider.stories.tsx +1 -1
  214. package/src/web-components/interaction/form/BdsSwitch.mdx +5 -1
  215. package/src/web-components/interaction/form/BdsSwitch.stories.tsx +1 -1
  216. package/src/web-components/interaction/form/BdsTextarea.mdx +5 -1
  217. package/src/web-components/interaction/form/BdsTextarea.stories.tsx +1 -1
  218. package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +32 -3
  219. package/src/web-components/interaction/form/bds-checkbox-group.ts +33 -17
  220. package/src/web-components/interaction/form/bds-checkbox.ts +1 -0
  221. package/src/web-components/interaction/form/bds-combobox.ts +6 -16
  222. package/src/web-components/interaction/form/bds-form-input.ts +6 -16
  223. package/src/web-components/interaction/form/bds-number-input.ts +6 -16
  224. package/src/web-components/interaction/form/bds-radio-group.spec.ts +32 -3
  225. package/src/web-components/interaction/form/bds-radio-group.ts +26 -14
  226. package/src/web-components/interaction/form/bds-radio.ts +1 -0
  227. package/src/web-components/interaction/form/bds-select.ts +6 -16
  228. package/src/web-components/interaction/form/bds-slider.ts +5 -16
  229. package/src/web-components/interaction/form/bds-switch.ts +1 -0
  230. package/src/web-components/interaction/form/bds-textarea.ts +6 -16
  231. package/src/web-components/interaction/form/field-message.spec.ts +62 -0
  232. package/src/web-components/interaction/form/field-message.ts +55 -0
  233. package/src/web-components/layout/BdsGrid.mdx +1 -1
  234. package/src/web-components/layout/BdsGrid.stories.tsx +1 -1
  235. package/src/web-components/layout/BdsGridItem.mdx +1 -1
  236. package/src/web-components/layout/BdsGridItem.stories.tsx +1 -1
  237. package/src/web-components/ui/BdsAlert.mdx +20 -1
  238. package/src/web-components/ui/BdsAlert.stories.tsx +29 -3
  239. package/src/web-components/ui/BdsAvatar.mdx +20 -3
  240. package/src/web-components/ui/BdsAvatar.stories.tsx +25 -2
  241. package/src/web-components/ui/BdsBadge.mdx +2 -1
  242. package/src/web-components/ui/BdsBadge.stories.tsx +1 -1
  243. package/src/web-components/ui/BdsBreadcrumb.mdx +1 -1
  244. package/src/web-components/ui/BdsBreadcrumb.stories.tsx +1 -1
  245. package/src/web-components/ui/BdsButtonContainer.mdx +1 -1
  246. package/src/web-components/ui/BdsButtonContainer.stories.tsx +1 -1
  247. package/src/web-components/ui/BdsCalendar.mdx +1 -1
  248. package/src/web-components/ui/BdsCalendar.stories.tsx +1 -1
  249. package/src/web-components/ui/BdsCalendarRange.mdx +1 -1
  250. package/src/web-components/ui/BdsCalendarRange.stories.tsx +1 -1
  251. package/src/web-components/ui/BdsCard.mdx +1 -1
  252. package/src/web-components/ui/BdsCard.stories.tsx +1 -1
  253. package/src/web-components/ui/BdsCarousel.mdx +1 -1
  254. package/src/web-components/ui/BdsCarousel.stories.tsx +1 -1
  255. package/src/web-components/ui/BdsDescriptionList.mdx +1 -1
  256. package/src/web-components/ui/BdsDescriptionList.stories.tsx +1 -1
  257. package/src/web-components/ui/BdsIconWrapper.mdx +1 -1
  258. package/src/web-components/ui/BdsIconWrapper.stories.tsx +1 -1
  259. package/src/web-components/ui/BdsLink.mdx +1 -1
  260. package/src/web-components/ui/BdsLink.stories.tsx +1 -1
  261. package/src/web-components/ui/BdsLoading.mdx +1 -1
  262. package/src/web-components/ui/BdsLoading.stories.tsx +1 -1
  263. package/src/web-components/ui/BdsNotificationBanner.mdx +11 -2
  264. package/src/web-components/ui/BdsNotificationBanner.stories.tsx +29 -2
  265. package/src/web-components/ui/BdsPagination.mdx +1 -1
  266. package/src/web-components/ui/BdsPagination.stories.tsx +1 -1
  267. package/src/web-components/ui/BdsProgress.mdx +1 -1
  268. package/src/web-components/ui/BdsProgress.stories.tsx +1 -1
  269. package/src/web-components/ui/BdsProgressCircle.mdx +1 -1
  270. package/src/web-components/ui/BdsProgressCircle.stories.tsx +1 -1
  271. package/src/web-components/ui/BdsRating.mdx +5 -2
  272. package/src/web-components/ui/BdsRating.stories.tsx +1 -1
  273. package/src/web-components/ui/BdsSectionHeader.mdx +18 -6
  274. package/src/web-components/ui/BdsSectionHeader.stories.tsx +10 -2
  275. package/src/web-components/ui/BdsSeparator.mdx +2 -1
  276. package/src/web-components/ui/BdsSeparator.stories.tsx +13 -1
  277. package/src/web-components/ui/BdsSkeleton.mdx +1 -1
  278. package/src/web-components/ui/BdsSkeleton.stories.tsx +1 -1
  279. package/src/web-components/ui/BdsTable.mdx +5 -1
  280. package/src/web-components/ui/BdsTable.stories.tsx +1 -1
  281. package/src/web-components/ui/BdsTypography.mdx +1 -1
  282. package/src/web-components/ui/BdsTypography.stories.tsx +1 -1
  283. package/src/web-components/ui/bds-alert.spec.ts +34 -0
  284. package/src/web-components/ui/bds-alert.ts +36 -3
  285. package/src/web-components/ui/bds-avatar.spec.ts +47 -0
  286. package/src/web-components/ui/bds-avatar.ts +36 -3
  287. package/src/web-components/ui/bds-badge.spec.ts +6 -0
  288. package/src/web-components/ui/bds-badge.ts +2 -2
  289. package/src/web-components/ui/bds-notification-banner.spec.ts +52 -0
  290. package/src/web-components/ui/bds-notification-banner.ts +55 -3
  291. package/src/web-components/ui/bds-rating.spec.ts +7 -0
  292. package/src/web-components/ui/bds-rating.ts +6 -0
  293. package/src/web-components/ui/bds-section-header.spec.ts +36 -3
  294. package/src/web-components/ui/bds-section-header.ts +32 -10
  295. package/src/web-components/ui/bds-separator.spec.ts +8 -0
  296. package/src/web-components/ui/bds-separator.ts +7 -0
  297. package/src/web-components/ui/bds-table.spec.ts +11 -0
  298. package/src/web-components/ui/bds-table.ts +5 -5
  299. package/dist/web-components/chunk-QZAIRJ75.js +0 -111
@@ -1,5 +1,6 @@
1
1
  import { LitElement, css, html } from 'lit';
2
2
  import { ifDefined } from 'lit/directives/if-defined.js';
3
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
3
4
 
4
5
  /**
5
6
  * `<bds-form-input>` — form-associated text input with label, hint, and error support.
@@ -83,6 +84,7 @@ export class BdsFormInput extends LitElement {
83
84
 
84
85
  :host([error]) .wrapper {
85
86
  --bdc_color: var(--bdc_color--error);
87
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
86
88
  }
87
89
 
88
90
  .wrapper:focus-within {
@@ -91,6 +93,7 @@ export class BdsFormInput extends LitElement {
91
93
 
92
94
  :host([error]) .wrapper:focus-within {
93
95
  --bdc_color: var(--bdc_color--error);
96
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
94
97
  }
95
98
 
96
99
  .input {
@@ -140,20 +143,7 @@ export class BdsFormInput extends LitElement {
140
143
  display: none;
141
144
  }
142
145
 
143
- .message {
144
- margin-block-start: var(--bds-space_xxs);
145
- font-size: var(--bds-font_size--body--s);
146
- font-family: var(--bds-font_family--body);
147
- }
148
-
149
- .message--error {
150
- color: var(--bds-color_error);
151
- }
152
-
153
- .message--hint {
154
- color: var(--bds-color_on-bg--subtle);
155
- font-style: italic;
156
- }
146
+ ${fieldMessageStyles}
157
147
  `;
158
148
 
159
149
  static properties = {
@@ -265,8 +255,8 @@ export class BdsFormInput extends LitElement {
265
255
  />
266
256
  <span class="suffix"><slot name="suffix"></slot></span>
267
257
  </div>
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>` : ''}
258
+ ${this.error ? renderFieldMessage('error', errorId, this.error) : ''}
259
+ ${this.hint ? renderFieldMessage('hint', hintId, this.hint) : ''}
270
260
  `;
271
261
  }
272
262
  }
@@ -1,4 +1,5 @@
1
1
  import { LitElement, css, html } from 'lit';
2
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
2
3
 
3
4
  /**
4
5
  * `<bds-number-input>` — form-associated Number Input with stepper buttons.
@@ -72,6 +73,7 @@ export class BdsNumberInput extends LitElement {
72
73
 
73
74
  :host([error]) .row {
74
75
  --bdc_color: var(--bdc_color--error);
76
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
75
77
  }
76
78
 
77
79
  .row:focus-within {
@@ -80,6 +82,7 @@ export class BdsNumberInput extends LitElement {
80
82
 
81
83
  :host([error]) .row:focus-within {
82
84
  --bdc_color: var(--bdc_color--error);
85
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
83
86
  }
84
87
 
85
88
  .row:focus-within:has(:focus-visible) {
@@ -154,20 +157,7 @@ export class BdsNumberInput extends LitElement {
154
157
  color: var(--numberInput_stepper-color, var(--bds-color_interactive));
155
158
  }
156
159
 
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;
170
- }
160
+ ${fieldMessageStyles}
171
161
  `;
172
162
 
173
163
  static properties = {
@@ -292,9 +282,9 @@ export class BdsNumberInput extends LitElement {
292
282
  </button>
293
283
  </div>
294
284
  ${this.error
295
- ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
285
+ ? renderFieldMessage('error', errorId, this.error)
296
286
  : this.hint
297
- ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
287
+ ? renderFieldMessage('hint', hintId, this.hint)
298
288
  : ''}
299
289
  `;
300
290
  }
@@ -112,8 +112,37 @@ describe('bds-radio-group', () => {
112
112
  });
113
113
 
114
114
  it('uses medium font-weight token for the legend (not semibold)', () => {
115
- const styles = BdsRadioGroup.styles.toString();
116
- expect(styles).toContain('--bds-font_weight--medium');
117
- expect(styles).not.toContain('--bds-font_weight--semibold');
115
+ const legendRule = BdsRadioGroup.styles.toString().match(/\.legend \{[^}]*\}/)?.[0] ?? '';
116
+ expect(legendRule).toContain('--bds-font_weight--medium');
117
+ expect(legendRule).not.toContain('--bds-font_weight--semibold');
118
+ });
119
+
120
+ it('shows the error icon in the message', async () => {
121
+ const el = await fixture('<bds-radio-group label="Test" error="Required field"></bds-radio-group>');
122
+ const message = el.shadowRoot!.querySelector('.message--error')!;
123
+ expect(message.querySelector('svg')?.getAttribute('aria-hidden')).toBe('true');
124
+ expect(message.textContent).toContain('Required field');
125
+ cleanup(el);
126
+ });
127
+
128
+ it('propagates error to slotted bds-radio elements', async () => {
129
+ const el = await fixture(
130
+ '<bds-radio-group label="Test" error="Required field"><bds-radio value="a">A</bds-radio><bds-radio value="b">B</bds-radio></bds-radio-group>',
131
+ );
132
+ const children = Array.from(el.querySelectorAll('bds-radio'));
133
+ expect(children.every(child => child.hasAttribute('error'))).toBe(true);
134
+ cleanup(el);
135
+ });
136
+
137
+ it('removes propagated error when the group error clears, keeping an individual error', async () => {
138
+ const el = await fixture(
139
+ '<bds-radio-group label="Test" error="Required field"><bds-radio value="a">A</bds-radio><bds-radio value="b" error>B</bds-radio></bds-radio-group>',
140
+ ) as BdsRadioGroup;
141
+ el.error = undefined;
142
+ await el.updateComplete;
143
+ const [first, second] = Array.from(el.querySelectorAll('bds-radio'));
144
+ expect(first.hasAttribute('error')).toBe(false);
145
+ expect(second.hasAttribute('error')).toBe(true);
146
+ cleanup(el);
118
147
  });
119
148
  });
@@ -1,4 +1,5 @@
1
1
  import { LitElement, css, html, nothing } from 'lit';
2
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
2
3
 
3
4
  /**
4
5
  * `<bds-radio-group>` — groups related radio buttons with a shared label and name.
@@ -67,19 +68,10 @@ export class BdsRadioGroup extends LitElement {
67
68
  gap: var(--bds-space_xs);
68
69
  }
69
70
 
71
+ ${fieldMessageStyles}
72
+
70
73
  .message {
71
74
  margin-block-start: var(--bds-space_xs);
72
- font-size: var(--bds-font_size--body--s);
73
- font-family: var(--bds-font_family--body);
74
- }
75
-
76
- .message--error {
77
- color: var(--bds-color_error);
78
- }
79
-
80
- .message--hint {
81
- color: var(--bds-color_on-bg--subtle);
82
- font-style: italic;
83
75
  }
84
76
  `;
85
77
 
@@ -136,9 +128,29 @@ export class BdsRadioGroup extends LitElement {
136
128
  });
137
129
  };
138
130
 
131
+ /**
132
+ * Propagates the group's `error` to slotted `<bds-radio>` elements so they show
133
+ * the error ring. A radio individually marked `error` in markup keeps it.
134
+ */
135
+ private _propagateError = () => {
136
+ this.querySelectorAll('bds-radio').forEach(radio => {
137
+ const el = radio as HTMLElement;
138
+ if (this.error) {
139
+ if (!el.hasAttribute('error')) {
140
+ el.setAttribute('data-bds-group-error', '');
141
+ }
142
+ el.setAttribute('error', '');
143
+ } else if (el.hasAttribute('data-bds-group-error')) {
144
+ el.removeAttribute('error');
145
+ el.removeAttribute('data-bds-group-error');
146
+ }
147
+ });
148
+ };
149
+
139
150
  private _propagateToRadios = () => {
140
151
  this._propagateName();
141
152
  this._propagateDisabled();
153
+ this._propagateError();
142
154
  };
143
155
 
144
156
  connectedCallback() {
@@ -149,7 +161,7 @@ export class BdsRadioGroup extends LitElement {
149
161
 
150
162
  updated(changed: Map<string, unknown>) {
151
163
  super.updated(changed);
152
- if (changed.has('name') || changed.has('disabled')) {
164
+ if (changed.has('name') || changed.has('disabled') || changed.has('error')) {
153
165
  this._propagateToRadios();
154
166
  }
155
167
  }
@@ -173,9 +185,9 @@ export class BdsRadioGroup extends LitElement {
173
185
  <slot @slotchange=${this._propagateToRadios}></slot>
174
186
  </div>
175
187
  ${this.error
176
- ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
188
+ ? renderFieldMessage('error', errorId, this.error)
177
189
  : this.hint
178
- ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
190
+ ? renderFieldMessage('hint', hintId, this.hint)
179
191
  : ''}
180
192
  </fieldset>
181
193
  `;
@@ -103,6 +103,7 @@ export class BdsRadio extends LitElement {
103
103
 
104
104
  :host([error]) .input {
105
105
  --bdc_color: var(--bdc_color--error);
106
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
106
107
  }
107
108
 
108
109
  .textWrapper {
@@ -1,4 +1,5 @@
1
1
  import { LitElement, css, html, nothing } from 'lit';
2
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
2
3
 
3
4
  export interface SelectOption {
4
5
  value: string;
@@ -110,22 +111,9 @@ export class BdsSelect extends LitElement {
110
111
 
111
112
  :host([error]) .select {
112
113
  --bdc_color: var(--bdc_color--error);
114
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
113
115
  }
114
116
 
115
- .message {
116
- margin-block-start: var(--bds-space_xxs);
117
- font-size: var(--bds-font_size--body--s);
118
- font-family: var(--bds-font_family--body);
119
- }
120
-
121
- .message--error {
122
- color: var(--bds-color_error);
123
- }
124
-
125
- .message--hint {
126
- color: var(--bds-color_on-bg--subtle);
127
- font-style: italic;
128
- }
129
117
 
130
118
  .chevron {
131
119
  position: absolute;
@@ -142,6 +130,8 @@ export class BdsSelect extends LitElement {
142
130
  inline-size: 100%;
143
131
  block-size: 100%;
144
132
  }
133
+
134
+ ${fieldMessageStyles}
145
135
  `;
146
136
 
147
137
  static properties = {
@@ -259,9 +249,9 @@ export class BdsSelect extends LitElement {
259
249
  </span>
260
250
  </div>
261
251
  ${this.error
262
- ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
252
+ ? renderFieldMessage('error', errorId, this.error)
263
253
  : this.hint
264
- ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
254
+ ? renderFieldMessage('hint', hintId, this.hint)
265
255
  : ''}
266
256
  `;
267
257
  }
@@ -1,4 +1,5 @@
1
1
  import { LitElement, css, html } from 'lit';
2
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
2
3
 
3
4
  /**
4
5
  * `<bds-slider>` — form-associated Slider / Range Input custom element.
@@ -147,20 +148,6 @@ export class BdsSlider extends LitElement {
147
148
  border-radius: var(--slider_track-radius, var(--bds-border_radius--full));
148
149
  }
149
150
 
150
- .message {
151
- margin-block-start: var(--bds-space_xxs);
152
- font-size: var(--bds-font_size--body--s);
153
- font-family: var(--bds-font_family--body);
154
- }
155
-
156
- .message--error {
157
- color: var(--bds-color_error);
158
- }
159
-
160
- .message--hint {
161
- color: var(--bds-color_on-bg--subtle);
162
- font-style: italic;
163
- }
164
151
 
165
152
  @media (prefers-reduced-motion: reduce) {
166
153
  .input,
@@ -169,6 +156,8 @@ export class BdsSlider extends LitElement {
169
156
  transition: none;
170
157
  }
171
158
  }
159
+
160
+ ${fieldMessageStyles}
172
161
  `;
173
162
 
174
163
  static properties = {
@@ -293,9 +282,9 @@ export class BdsSlider extends LitElement {
293
282
  />
294
283
  </div>
295
284
  ${this.error
296
- ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
285
+ ? renderFieldMessage('error', errorId, this.error)
297
286
  : this.hint
298
- ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
287
+ ? renderFieldMessage('hint', hintId, this.hint)
299
288
  : ''}
300
289
  `;
301
290
  }
@@ -142,6 +142,7 @@ export class BdsSwitch extends LitElement {
142
142
  switch still shows the active colour even when it also has an error. */
143
143
  :host([error]) .track {
144
144
  --bdc_color: var(--switch_border-color--error, var(--bds-color_error));
145
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
145
146
  }
146
147
 
147
148
  .input:checked + .track {
@@ -1,4 +1,5 @@
1
1
  import { LitElement, css, html } from 'lit';
2
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
2
3
 
3
4
  /**
4
5
  * `<bds-textarea>` — form-associated Textarea custom element.
@@ -99,26 +100,15 @@ export class BdsTextarea extends LitElement {
99
100
 
100
101
  :host([error]) .textarea {
101
102
  --bdc_color: var(--bdc_color--error);
103
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
102
104
  }
103
105
 
104
106
  :host([error]) .textarea:focus {
105
107
  --bdc_color: var(--bdc_color--error);
108
+ --bdc-outline_width: var(--bdc-outline_width--error, 2px);
106
109
  }
107
110
 
108
- .message {
109
- margin-block-start: var(--bds-space_xxs);
110
- font-size: var(--bds-font_size--body--s);
111
- font-family: var(--bds-font_family--body);
112
- }
113
-
114
- .message--error {
115
- color: var(--bds-color_error);
116
- }
117
-
118
- .message--hint {
119
- color: var(--bds-color_on-bg--subtle);
120
- font-style: italic;
121
- }
111
+ ${fieldMessageStyles}
122
112
  `;
123
113
 
124
114
  static properties = {
@@ -225,9 +215,9 @@ export class BdsTextarea extends LitElement {
225
215
  @change=${this._handleChange}
226
216
  ></textarea>
227
217
  ${this.error
228
- ? html`<p id=${errorId} class="message message--error" role="alert">${this.error}</p>`
218
+ ? renderFieldMessage('error', errorId, this.error)
229
219
  : this.hint
230
- ? html`<p id=${hintId} class="message message--hint">${this.hint}</p>`
220
+ ? renderFieldMessage('hint', hintId, this.hint)
231
221
  : ''}
232
222
  `;
233
223
  }
@@ -0,0 +1,62 @@
1
+ import { render } from 'lit';
2
+ import { fieldMessageStyles, renderFieldMessage } from './field-message';
3
+ import { BdsFormInput } from './bds-form-input';
4
+ import { BdsTextarea } from './bds-textarea';
5
+ import { BdsSelect } from './bds-select';
6
+ import { BdsCombobox } from './bds-combobox';
7
+ import { BdsNumberInput } from './bds-number-input';
8
+ import { BdsCheckbox } from './bds-checkbox';
9
+ import { BdsRadio } from './bds-radio';
10
+ import { BdsSwitch } from './bds-switch';
11
+
12
+ const renderInto = (template: ReturnType<typeof renderFieldMessage>): HTMLElement => {
13
+ const host = document.createElement('div');
14
+ render(template, host);
15
+ return host;
16
+ };
17
+
18
+ describe('field-message', () => {
19
+ it('renders the error with role alert, the id and an aria-hidden icon', () => {
20
+ const host = renderInto(renderFieldMessage('error', 'err-1', 'Invalid email'));
21
+ const message = host.querySelector('p')!;
22
+ expect(message.id).toBe('err-1');
23
+ expect(message.getAttribute('role')).toBe('alert');
24
+ expect(message.classList.contains('message--error')).toBe(true);
25
+ expect(message.querySelector('svg')?.getAttribute('aria-hidden')).toBe('true');
26
+ expect(message.textContent).toContain('Invalid email');
27
+ });
28
+
29
+ it('renders the hint without role and without icon', () => {
30
+ const host = renderInto(renderFieldMessage('hint', 'hint-1', 'We never share it'));
31
+ const message = host.querySelector('p')!;
32
+ expect(message.id).toBe('hint-1');
33
+ expect(message.hasAttribute('role')).toBe(false);
34
+ expect(message.querySelector('svg')).toBeNull();
35
+ });
36
+
37
+ it('reads every message look from a --formMessage_* hook', () => {
38
+ const css = fieldMessageStyles.toString();
39
+ [
40
+ '--formMessage_gap',
41
+ '--formMessage_color--error',
42
+ '--formMessage_font-weight--error',
43
+ '--formMessage_icon-size',
44
+ '--formMessage_color--hint',
45
+ '--formMessage_font-style--hint',
46
+ '--formMessage_font-size',
47
+ ].forEach(hook => expect(css).toContain(hook));
48
+ });
49
+
50
+ it.each([
51
+ ['bds-form-input', BdsFormInput],
52
+ ['bds-textarea', BdsTextarea],
53
+ ['bds-select', BdsSelect],
54
+ ['bds-combobox', BdsCombobox],
55
+ ['bds-number-input', BdsNumberInput],
56
+ ['bds-checkbox', BdsCheckbox],
57
+ ['bds-radio', BdsRadio],
58
+ ['bds-switch', BdsSwitch],
59
+ ])('%s widens the outline in the error state', (_tag, ctor) => {
60
+ expect(ctor.styles.toString()).toContain('--bdc-outline_width: var(--bdc-outline_width--error, 2px)');
61
+ });
62
+ });
@@ -0,0 +1,55 @@
1
+ import { css, html, svg } from 'lit';
2
+ import type { TemplateResult } from 'lit';
3
+
4
+ /**
5
+ * Shared look and markup for the error and hint message under a form control.
6
+ * Every `bds-*` form control spreads `fieldMessageStyles` into its own styles and
7
+ * renders its message with `renderFieldMessage()`, so the controls cannot drift.
8
+ *
9
+ * Hooks: --formMessage_gap, --formMessage_color--error, --formMessage_font-weight--error,
10
+ * --formMessage_icon-size, --formMessage_color--hint, --formMessage_font-style--hint,
11
+ * --formMessage_font-size.
12
+ */
13
+ export const fieldMessageStyles = css`
14
+ .message {
15
+ margin-block-start: var(--bds-space_xxs);
16
+ font-size: var(--formMessage_font-size, var(--bds-font_size--body--s));
17
+ font-family: var(--bds-font_family--body);
18
+ }
19
+
20
+ .message--error {
21
+ display: flex;
22
+ align-items: flex-start;
23
+ gap: var(--formMessage_gap, var(--bds-space_xxs));
24
+ color: var(--formMessage_color--error, var(--bds-color_error_on-bg));
25
+ font-weight: var(--formMessage_font-weight--error, var(--bds-font_weight--semibold));
26
+ }
27
+
28
+ .message__icon {
29
+ flex-shrink: 0;
30
+ inline-size: var(--formMessage_icon-size, 1.15em);
31
+ block-size: var(--formMessage_icon-size, 1.15em);
32
+ }
33
+
34
+ .message--hint {
35
+ color: var(--formMessage_color--hint, inherit);
36
+ font-style: var(--formMessage_font-style--hint, italic);
37
+ }
38
+ `;
39
+
40
+ // Phosphor "warning-circle" (fill)
41
+ const warningIcon = svg`<svg class="message__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor" aria-hidden="true"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-8,56a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm8,104a12,12,0,1,1,12-12A12,12,0,0,1,128,184Z"></path></svg>`;
42
+
43
+ /**
44
+ * Renders the message paragraph. The error variant gets `role="alert"` and a
45
+ * leading icon; the hint variant is plain text. `id` is the one the control
46
+ * references from `aria-describedby`.
47
+ */
48
+ export const renderFieldMessage = (
49
+ kind: 'error' | 'hint',
50
+ id: string,
51
+ text: string,
52
+ ): TemplateResult =>
53
+ kind === 'error'
54
+ ? html`<p id=${id} class="message message--error" role="alert">${warningIcon}${text}</p>`
55
+ : html`<p id=${id} class="message message--hint">${text}</p>`;
@@ -7,7 +7,7 @@ import * as Stories from './BdsGrid.stories';
7
7
 
8
8
  Framework-agnostic Grid layout custom element. Built on the `@boostdev/design-system-foundation` grid tokens.
9
9
 
10
- > **Status: experimental** — API may change before stable release.
10
+ > **Status: alpha** — API may change before stable release.
11
11
 
12
12
  ## Installation
13
13
 
@@ -70,7 +70,7 @@ const cellStyle = {
70
70
  const meta = {
71
71
  title: 'Web Components/Layout/Grid',
72
72
  component: BdsGrid,
73
- tags: ['!stable', 'experimental'],
73
+ tags: ['!stable', 'alpha'],
74
74
  parameters: { layout: 'padded' },
75
75
  argTypes: {
76
76
  variant: { control: 'select', options: ['main', 'page', 'funnel', 'custom'] },
@@ -7,7 +7,7 @@ import * as Stories from './BdsGridItem.stories';
7
7
 
8
8
  Grid cell for `<bds-grid>`. Sets `grid-column` / `grid-row` on its host element using the foundation span tokens.
9
9
 
10
- > **Status: experimental** — API may change before stable release.
10
+ > **Status: alpha** — API may change before stable release.
11
11
 
12
12
  ## Examples
13
13
 
@@ -38,7 +38,7 @@ const cellStyle = {
38
38
  const meta = {
39
39
  title: 'Web Components/Layout/GridItem',
40
40
  component: BdsGridItem,
41
- tags: ['!stable', 'experimental'],
41
+ tags: ['!stable', 'alpha'],
42
42
  parameters: { layout: 'padded' },
43
43
  argTypes: {
44
44
  columnSpan: {
@@ -7,7 +7,7 @@ import * as Stories from './BdsAlert.stories';
7
7
 
8
8
  Framework-agnostic alert custom element for inline status messages. Supports four semantic variants, an optional heading, and a dismissible mode.
9
9
 
10
- > **Status: experimental** — API may change before stable release.
10
+ > **Status: alpha** — API may change before stable release.
11
11
 
12
12
  ## Installation
13
13
 
@@ -38,6 +38,9 @@ import '@boostdev/design-system-components/web-components';
38
38
  ### Dismissible
39
39
  <Canvas of={Stories.Dismissible} />
40
40
 
41
+ ### Gradient
42
+ <Canvas of={Stories.Gradient} />
43
+
41
44
  ## Props
42
45
 
43
46
  <ArgTypes of={Stories} />
@@ -47,6 +50,7 @@ import '@boostdev/design-system-components/web-components';
47
50
  | Attribute | Type | Default | Description |
48
51
  |-----------|------|---------|-------------|
49
52
  | `variant` | `"info" \| "success" \| "warning" \| "error"` | `"info"` | Semantic colour and icon |
53
+ | `appearance` | `"default" \| "gradient"` | `"default"` | `gradient` fades the variant tint to the surface, with a 3px accent line and a shadow |
50
54
  | `heading` | string | — | Optional heading displayed above body content |
51
55
  | `title` | string | — | **Deprecated.** Alias for `heading`, used as a fallback when `heading` is unset. Avoid: it shares its name with the global HTML `title` attribute, which makes the browser show a native tooltip on hover. Will be removed in a later major — use `heading` instead. |
52
56
  | `dismissible` | boolean | `false` | Shows a dismiss (×) button |
@@ -58,6 +62,21 @@ import '@boostdev/design-system-components/web-components';
58
62
  | `(default)` | Alert body text or content |
59
63
  | `icon` | Custom icon, placed left of the content area |
60
64
 
65
+ ## CSS Custom Properties
66
+
67
+ | Property | Default | Description |
68
+ |----------|---------|-------------|
69
+ | `--alert_bg` / `--alert_text` / `--alert_border` | per variant | Colours for all variants. Per-variant forms: `--alert_bg--info`, `--alert_text--info`, `--alert_border--info` (and `success`, `warning`, `error`). |
70
+ | `--alert_bg--error` / `--alert_text--error` / `--alert_border--error` | `var(--bds-color_error--subtle)` / `var(--bds-color_on-error--subtle)` / `var(--bds-color_error)` | Error variant colours, the subtle pair like the other variants |
71
+ | `--alert_border-width` | `var(--bds-space_s)` (`3px` with `appearance="gradient"`) | Width of the inline-start accent line |
72
+ | `--alert_gradient` | `linear-gradient(100deg, transparent 35%, var(--bds-color_bg--strong, var(--bds-color_bg)) 100%)` | Gradient over the variant background, `appearance="gradient"` only |
73
+ | `--alert_shadow` | `var(--bds-shadow_s)` | Box shadow, `appearance="gradient"` only |
74
+ | `--alert_accent--info` | `var(--bds-color_on-blue--subtle)` | Accent line colour with `appearance="gradient"`; `--alert_border--info` and `--alert_border` win |
75
+ | `--alert_accent--success` | `var(--bds-color_on-success--subtle)` | Same, success |
76
+ | `--alert_accent--warning` | `var(--bds-color_warning)` | Same, warning |
77
+ | `--alert_accent--error` | `var(--bds-color_error)` | Same, error |
78
+ | `--alert_dismiss-border` / `--alert_dismiss-radius` / `--alert_dismiss-opacity--hover` | | Dismiss button border, radius and hover opacity |
79
+
61
80
  ## Events
62
81
 
63
82
  | Event | Detail | Bubbles | Composed | Description |
@@ -1,17 +1,19 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
- import type { AlertVariant } from './bds-alert';
3
+ import type { AlertAppearance, AlertVariant } from './bds-alert';
4
4
  import '../index'; // auto-registers all custom elements
5
5
 
6
6
  // Thin React wrapper so Storybook controls work with the custom element's props
7
7
  function BdsAlert({
8
8
  variant = 'info',
9
+ appearance,
9
10
  heading,
10
11
  dismissible,
11
12
  children,
12
13
  onDismiss,
13
14
  }: {
14
15
  variant?: AlertVariant;
16
+ appearance?: AlertAppearance;
15
17
  heading?: string;
16
18
  dismissible?: boolean;
17
19
  children?: React.ReactNode;
@@ -19,7 +21,7 @@ function BdsAlert({
19
21
  }) {
20
22
  return React.createElement(
21
23
  'bds-alert',
22
- { variant, heading, dismissible: dismissible || undefined, onbdsdismiss: onDismiss },
24
+ { variant, appearance, heading, dismissible: dismissible || undefined, onbdsdismiss: onDismiss },
23
25
  children,
24
26
  );
25
27
  }
@@ -27,10 +29,11 @@ function BdsAlert({
27
29
  const meta = {
28
30
  title: 'Web Components/UI/Alert',
29
31
  component: BdsAlert,
30
- tags: ['!stable', 'experimental'],
32
+ tags: ['!stable', 'alpha'],
31
33
  parameters: { layout: 'padded' },
32
34
  argTypes: {
33
35
  variant: { control: 'select', options: ['info', 'success', 'warning', 'error'] },
36
+ appearance: { control: 'select', options: ['default', 'gradient'] },
34
37
  },
35
38
  } satisfies Meta<typeof BdsAlert>;
36
39
 
@@ -58,3 +61,26 @@ export const AllVariants: Story = {
58
61
  </div>
59
62
  ),
60
63
  };
64
+
65
+ const gradientIcon = (path: string) =>
66
+ React.createElement(
67
+ 'svg',
68
+ { slot: 'icon', viewBox: '0 0 24 24', width: 20, height: 20, fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
69
+ React.createElement('circle', { cx: 12, cy: 12, r: 10 }),
70
+ React.createElement('path', { d: path }),
71
+ );
72
+
73
+ export const Gradient: Story = {
74
+ render: () => (
75
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: 500 }}>
76
+ {(['info', 'success', 'warning', 'error'] as const).map(v =>
77
+ React.createElement(
78
+ 'bds-alert',
79
+ { key: v, variant: v, appearance: 'gradient', heading: v.charAt(0).toUpperCase() + v.slice(1) },
80
+ gradientIcon(v === 'success' ? 'm8 12 3 3 5-6' : v === 'info' ? 'M12 16v-4M12 8h.01' : 'M12 7v6M12 16h.01'),
81
+ `This is a ${v} alert.`,
82
+ ),
83
+ )}
84
+ </div>
85
+ ),
86
+ };