@boostdev/design-system-components 2.15.0 → 2.16.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 (284) hide show
  1. package/AGENTS.md +19 -14
  2. package/dist/client.cjs +271 -205
  3. package/dist/client.css +801 -642
  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 +801 -642
  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-LDIPCTRN.js → chunk-2MJTO2IW.js} +48 -2
  14. package/dist/web-components/{chunk-3WAV6MDN.js → chunk-3FSGP35V.js} +1 -0
  15. package/dist/web-components/{chunk-KA3VPKMY.js → chunk-4MB2ICSK.js} +1 -0
  16. package/dist/web-components/{chunk-IDSM74LM.js → chunk-6XL5P76D.js} +3 -3
  17. package/dist/web-components/{chunk-P24JYC5V.js → chunk-7VXRMCAL.js} +10 -4
  18. package/dist/web-components/{chunk-CUKQ2L5B.js → chunk-AGI6YQRC.js} +9 -16
  19. package/dist/web-components/chunk-BDRV452N.js +51 -0
  20. package/dist/web-components/{chunk-3AY2YKCM.js → chunk-CKCPV347.js} +1 -0
  21. package/dist/web-components/{chunk-HBLJ4SLY.js → chunk-DD3OUXNG.js} +5 -5
  22. package/dist/web-components/{chunk-RVF7W653.js → chunk-DGOCPKHI.js} +30 -10
  23. package/dist/web-components/{chunk-2OLVQUBU.js → chunk-EYCW7TKB.js} +8 -15
  24. package/dist/web-components/{chunk-VANAKB6D.js → chunk-GPJWLAKU.js} +33 -16
  25. package/dist/web-components/{chunk-VED2DFJ6.js → chunk-GQNQBEYR.js} +8 -15
  26. package/dist/web-components/{chunk-WFVKU4GX.js → chunk-IKAJLROF.js} +49 -4
  27. package/dist/web-components/{chunk-RSZ3BWBK.js → chunk-KSK4RZZQ.js} +30 -7
  28. package/dist/web-components/{chunk-FEDABOR5.js → chunk-LHFUXZ52.js} +7 -15
  29. package/dist/web-components/{chunk-M3ECULRH.js → chunk-RBF7WPLI.js} +10 -8
  30. package/dist/web-components/{chunk-6G22I2CK.js → chunk-RZH5IVB5.js} +31 -1
  31. package/dist/web-components/chunk-SRKQ6GST.js +40 -0
  32. package/dist/web-components/{chunk-5HUAFCU6.js → chunk-TJV7UIXC.js} +7 -0
  33. package/dist/web-components/{chunk-J3HVUIUH.js → chunk-XI2U6U26.js} +8 -15
  34. package/dist/web-components/{chunk-JH6LQKLK.js → chunk-XJU7KITO.js} +8 -15
  35. package/dist/web-components/{chunk-JV5QT2OU.js → chunk-YLDQOESI.js} +27 -13
  36. package/dist/web-components/globals.js +1 -1
  37. package/dist/web-components/index.d.ts +1 -0
  38. package/dist/web-components/index.js +33 -28
  39. package/dist/web-components/interaction/bds-dropdown-menu-group.d.ts +41 -0
  40. package/dist/web-components/interaction/bds-dropdown-menu-group.js +7 -0
  41. package/dist/web-components/interaction/bds-dropdown-menu-item.d.ts +14 -1
  42. package/dist/web-components/interaction/bds-dropdown-menu-item.js +1 -1
  43. package/dist/web-components/interaction/bds-dropdown-menu.d.ts +2 -1
  44. package/dist/web-components/interaction/bds-dropdown-menu.js +1 -1
  45. package/dist/web-components/interaction/bds-tab.d.ts +5 -0
  46. package/dist/web-components/interaction/bds-tab.js +1 -1
  47. package/dist/web-components/interaction/bds-tooltip.js +1 -1
  48. package/dist/web-components/interaction/form/bds-checkbox-group.d.ts +6 -0
  49. package/dist/web-components/interaction/form/bds-checkbox-group.js +2 -1
  50. package/dist/web-components/interaction/form/bds-checkbox.js +1 -1
  51. package/dist/web-components/interaction/form/bds-combobox.js +2 -1
  52. package/dist/web-components/interaction/form/bds-form-input.js +2 -1
  53. package/dist/web-components/interaction/form/bds-number-input.js +2 -1
  54. package/dist/web-components/interaction/form/bds-radio-group.d.ts +5 -0
  55. package/dist/web-components/interaction/form/bds-radio-group.js +2 -1
  56. package/dist/web-components/interaction/form/bds-radio.js +1 -1
  57. package/dist/web-components/interaction/form/bds-select.js +2 -1
  58. package/dist/web-components/interaction/form/bds-slider.js +2 -1
  59. package/dist/web-components/interaction/form/bds-switch.js +1 -1
  60. package/dist/web-components/interaction/form/bds-textarea.js +2 -1
  61. package/dist/web-components/ui/bds-alert.d.ts +8 -1
  62. package/dist/web-components/ui/bds-alert.js +1 -1
  63. package/dist/web-components/ui/bds-avatar.d.ts +11 -0
  64. package/dist/web-components/ui/bds-avatar.js +1 -1
  65. package/dist/web-components/ui/bds-notification-banner.d.ts +14 -1
  66. package/dist/web-components/ui/bds-notification-banner.js +1 -1
  67. package/dist/web-components/ui/bds-section-header.d.ts +6 -0
  68. package/dist/web-components/ui/bds-section-header.js +1 -1
  69. package/dist/web-components/ui/bds-separator.js +1 -1
  70. package/dist/web-components/ui/bds-table.js +1 -1
  71. package/package.json +6 -2
  72. package/src/components/interaction/DropdownMenu/DropdownMenu.mdx +35 -4
  73. package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +58 -10
  74. package/src/components/interaction/DropdownMenu/DropdownMenu.spec.tsx +114 -1
  75. package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +25 -0
  76. package/src/components/interaction/DropdownMenu/DropdownMenu.tsx +69 -17
  77. package/src/components/interaction/form/Checkbox/Checkbox.module.css +1 -0
  78. package/src/components/interaction/form/Checkbox/Checkbox.spec.tsx +7 -0
  79. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.mdx +1 -0
  80. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +7 -0
  81. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +22 -0
  82. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +1 -1
  83. package/src/components/interaction/form/Combobox/Combobox.module.css +1 -0
  84. package/src/components/interaction/form/Combobox/Combobox.spec.tsx +7 -0
  85. package/src/components/interaction/form/FormInput/FormInput.mdx +9 -0
  86. package/src/components/interaction/form/FormInput/FormInput.module.css +1 -0
  87. package/src/components/interaction/form/FormInput/FormInput.spec.tsx +7 -0
  88. package/src/components/interaction/form/NumberInput/NumberInput.module.css +1 -0
  89. package/src/components/interaction/form/NumberInput/NumberInput.spec.tsx +7 -0
  90. package/src/components/interaction/form/Radio/Radio.module.css +1 -0
  91. package/src/components/interaction/form/Radio/Radio.spec.tsx +7 -0
  92. package/src/components/interaction/form/RadioGroup/RadioGroup.mdx +1 -0
  93. package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +7 -0
  94. package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +22 -0
  95. package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +1 -1
  96. package/src/components/interaction/form/Select/Select.module.css +1 -0
  97. package/src/components/interaction/form/Select/Select.spec.tsx +7 -0
  98. package/src/components/interaction/form/Switch/Switch.module.css +1 -0
  99. package/src/components/interaction/form/Switch/Switch.spec.tsx +7 -0
  100. package/src/components/interaction/form/Textarea/Textarea.module.css +1 -0
  101. package/src/components/interaction/form/Textarea/Textarea.spec.tsx +7 -0
  102. package/src/components/interaction/form/atoms/Message.module.css +14 -3
  103. package/src/components/interaction/form/atoms/Message.spec.tsx +22 -0
  104. package/src/components/interaction/form/atoms/Message.tsx +5 -0
  105. package/src/components/layout/SectionHeader/SectionHeader.mdx +18 -5
  106. package/src/components/layout/SectionHeader/SectionHeader.module.css +35 -14
  107. package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +44 -0
  108. package/src/components/layout/SectionHeader/SectionHeader.stories.tsx +5 -0
  109. package/src/components/layout/SectionHeader/SectionHeader.tsx +3 -1
  110. package/src/components/ui/Alert/Alert.mdx +11 -0
  111. package/src/components/ui/Alert/Alert.module.css +30 -1
  112. package/src/components/ui/Alert/Alert.spec.tsx +21 -0
  113. package/src/components/ui/Alert/Alert.stories.tsx +20 -0
  114. package/src/components/ui/Alert/Alert.tsx +8 -1
  115. package/src/components/ui/Avatar/Avatar.mdx +22 -2
  116. package/src/components/ui/Avatar/Avatar.module.css +29 -2
  117. package/src/components/ui/Avatar/Avatar.spec.tsx +26 -0
  118. package/src/components/ui/Avatar/Avatar.stories.tsx +23 -0
  119. package/src/components/ui/Avatar/Avatar.tsx +4 -2
  120. package/src/components/ui/Avatar/avatarTone.spec.ts +41 -0
  121. package/src/components/ui/Avatar/avatarTone.ts +22 -0
  122. package/src/components/ui/Collapsible/Collapsible.module.css +1 -2
  123. package/src/components/ui/NotificationBanner/NotificationBanner.mdx +14 -0
  124. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +31 -1
  125. package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +29 -0
  126. package/src/components/ui/NotificationBanner/NotificationBanner.stories.tsx +25 -0
  127. package/src/components/ui/NotificationBanner/NotificationBanner.tsx +15 -1
  128. package/src/components/ui/Separator/Separator.mdx +1 -0
  129. package/src/components/ui/Separator/Separator.module.css +6 -0
  130. package/src/components/ui/Separator/Separator.spec.tsx +19 -0
  131. package/src/components/ui/Separator/Separator.stories.tsx +15 -0
  132. package/src/components/ui/Table/Table.mdx +4 -1
  133. package/src/components/ui/Table/Table.module.css +7 -7
  134. package/src/components/ui/Table/Table.spec.tsx +11 -0
  135. package/src/components/ui/Tabs/Tabs.mdx +11 -5
  136. package/src/components/ui/Tabs/Tabs.module.css +23 -5
  137. package/src/components/ui/Tabs/Tabs.spec.tsx +39 -0
  138. package/src/components/ui/Tabs/Tabs.tsx +2 -1
  139. package/src/components/ui/Tabs/getNodeText.spec.tsx +23 -0
  140. package/src/components/ui/Tabs/getNodeText.ts +13 -0
  141. package/src/components/ui/Tooltip/Tooltip.mdx +6 -3
  142. package/src/components/ui/Tooltip/Tooltip.module.css +6 -2
  143. package/src/components/ui/Tooltip/Tooltip.spec.tsx +10 -0
  144. package/src/components/ui/Tooltip/Tooltip.stories.tsx +13 -0
  145. package/src/css/bdc.css +5 -2
  146. package/src/css/bdc.spec.ts +65 -0
  147. package/src/stories/DesignSystem/Borders.mdx +17 -9
  148. package/src/web-components/globals.ts +10 -4
  149. package/src/web-components/index.ts +1 -0
  150. package/src/web-components/interaction/BdsAccordion.mdx +1 -1
  151. package/src/web-components/interaction/BdsAccordion.stories.tsx +1 -1
  152. package/src/web-components/interaction/BdsButton.mdx +1 -1
  153. package/src/web-components/interaction/BdsButton.stories.tsx +1 -1
  154. package/src/web-components/interaction/BdsCollapsible.mdx +1 -1
  155. package/src/web-components/interaction/BdsCollapsible.stories.tsx +1 -1
  156. package/src/web-components/interaction/BdsDialog.mdx +1 -1
  157. package/src/web-components/interaction/BdsDialog.stories.tsx +1 -1
  158. package/src/web-components/interaction/BdsDrawer.mdx +1 -1
  159. package/src/web-components/interaction/BdsDrawer.stories.tsx +1 -1
  160. package/src/web-components/interaction/BdsDropdownMenu.mdx +62 -6
  161. package/src/web-components/interaction/BdsDropdownMenu.stories.tsx +32 -7
  162. package/src/web-components/interaction/BdsPopover.mdx +1 -1
  163. package/src/web-components/interaction/BdsPopover.stories.tsx +1 -1
  164. package/src/web-components/interaction/BdsSkipLink.mdx +1 -1
  165. package/src/web-components/interaction/BdsSkipLink.stories.tsx +1 -1
  166. package/src/web-components/interaction/BdsTabs.mdx +10 -1
  167. package/src/web-components/interaction/BdsTabs.stories.tsx +1 -1
  168. package/src/web-components/interaction/BdsToastProvider.mdx +1 -1
  169. package/src/web-components/interaction/BdsToastProvider.stories.tsx +1 -1
  170. package/src/web-components/interaction/BdsTooltip.mdx +13 -5
  171. package/src/web-components/interaction/BdsTooltip.stories.tsx +12 -12
  172. package/src/web-components/interaction/bds-dropdown-menu-group.ts +72 -0
  173. package/src/web-components/interaction/bds-dropdown-menu-item.ts +65 -17
  174. package/src/web-components/interaction/bds-dropdown-menu.spec.ts +135 -0
  175. package/src/web-components/interaction/bds-dropdown-menu.ts +5 -4
  176. package/src/web-components/interaction/bds-tab.spec.ts +34 -2
  177. package/src/web-components/interaction/bds-tab.ts +31 -6
  178. package/src/web-components/interaction/bds-tooltip.spec.ts +16 -0
  179. package/src/web-components/interaction/bds-tooltip.ts +10 -8
  180. package/src/web-components/interaction/form/BdsCheckbox.mdx +5 -1
  181. package/src/web-components/interaction/form/BdsCheckbox.stories.tsx +1 -1
  182. package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +5 -1
  183. package/src/web-components/interaction/form/BdsCheckboxGroup.stories.tsx +1 -1
  184. package/src/web-components/interaction/form/BdsCombobox.mdx +5 -1
  185. package/src/web-components/interaction/form/BdsCombobox.stories.tsx +1 -1
  186. package/src/web-components/interaction/form/BdsFieldGroup.stories.tsx +1 -1
  187. package/src/web-components/interaction/form/BdsFileInput.mdx +1 -1
  188. package/src/web-components/interaction/form/BdsFileInput.stories.tsx +1 -1
  189. package/src/web-components/interaction/form/BdsFormInput.mdx +8 -1
  190. package/src/web-components/interaction/form/BdsFormInput.stories.tsx +1 -1
  191. package/src/web-components/interaction/form/BdsNumberInput.mdx +5 -1
  192. package/src/web-components/interaction/form/BdsNumberInput.stories.tsx +1 -1
  193. package/src/web-components/interaction/form/BdsRadio.mdx +5 -1
  194. package/src/web-components/interaction/form/BdsRadio.stories.tsx +1 -1
  195. package/src/web-components/interaction/form/BdsRadioGroup.mdx +5 -1
  196. package/src/web-components/interaction/form/BdsRadioGroup.stories.tsx +1 -1
  197. package/src/web-components/interaction/form/BdsSegmentedControl.mdx +1 -1
  198. package/src/web-components/interaction/form/BdsSegmentedControl.stories.tsx +1 -1
  199. package/src/web-components/interaction/form/BdsSelect.mdx +5 -1
  200. package/src/web-components/interaction/form/BdsSelect.stories.tsx +1 -1
  201. package/src/web-components/interaction/form/BdsSlider.mdx +5 -1
  202. package/src/web-components/interaction/form/BdsSlider.stories.tsx +1 -1
  203. package/src/web-components/interaction/form/BdsSwitch.mdx +5 -1
  204. package/src/web-components/interaction/form/BdsSwitch.stories.tsx +1 -1
  205. package/src/web-components/interaction/form/BdsTextarea.mdx +5 -1
  206. package/src/web-components/interaction/form/BdsTextarea.stories.tsx +1 -1
  207. package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +32 -3
  208. package/src/web-components/interaction/form/bds-checkbox-group.ts +33 -17
  209. package/src/web-components/interaction/form/bds-checkbox.ts +1 -0
  210. package/src/web-components/interaction/form/bds-combobox.ts +6 -16
  211. package/src/web-components/interaction/form/bds-form-input.ts +6 -16
  212. package/src/web-components/interaction/form/bds-number-input.ts +6 -16
  213. package/src/web-components/interaction/form/bds-radio-group.spec.ts +32 -3
  214. package/src/web-components/interaction/form/bds-radio-group.ts +26 -14
  215. package/src/web-components/interaction/form/bds-radio.ts +1 -0
  216. package/src/web-components/interaction/form/bds-select.ts +6 -16
  217. package/src/web-components/interaction/form/bds-slider.ts +5 -16
  218. package/src/web-components/interaction/form/bds-switch.ts +1 -0
  219. package/src/web-components/interaction/form/bds-textarea.ts +6 -16
  220. package/src/web-components/interaction/form/field-message.spec.ts +62 -0
  221. package/src/web-components/interaction/form/field-message.ts +55 -0
  222. package/src/web-components/layout/BdsGrid.mdx +1 -1
  223. package/src/web-components/layout/BdsGrid.stories.tsx +1 -1
  224. package/src/web-components/layout/BdsGridItem.mdx +1 -1
  225. package/src/web-components/layout/BdsGridItem.stories.tsx +1 -1
  226. package/src/web-components/ui/BdsAlert.mdx +19 -1
  227. package/src/web-components/ui/BdsAlert.stories.tsx +29 -3
  228. package/src/web-components/ui/BdsAvatar.mdx +20 -3
  229. package/src/web-components/ui/BdsAvatar.stories.tsx +25 -2
  230. package/src/web-components/ui/BdsBadge.mdx +1 -1
  231. package/src/web-components/ui/BdsBadge.stories.tsx +1 -1
  232. package/src/web-components/ui/BdsBreadcrumb.mdx +1 -1
  233. package/src/web-components/ui/BdsBreadcrumb.stories.tsx +1 -1
  234. package/src/web-components/ui/BdsButtonContainer.mdx +1 -1
  235. package/src/web-components/ui/BdsButtonContainer.stories.tsx +1 -1
  236. package/src/web-components/ui/BdsCalendar.mdx +1 -1
  237. package/src/web-components/ui/BdsCalendar.stories.tsx +1 -1
  238. package/src/web-components/ui/BdsCalendarRange.mdx +1 -1
  239. package/src/web-components/ui/BdsCalendarRange.stories.tsx +1 -1
  240. package/src/web-components/ui/BdsCard.mdx +1 -1
  241. package/src/web-components/ui/BdsCard.stories.tsx +1 -1
  242. package/src/web-components/ui/BdsCarousel.mdx +1 -1
  243. package/src/web-components/ui/BdsCarousel.stories.tsx +1 -1
  244. package/src/web-components/ui/BdsDescriptionList.mdx +1 -1
  245. package/src/web-components/ui/BdsDescriptionList.stories.tsx +1 -1
  246. package/src/web-components/ui/BdsIconWrapper.mdx +1 -1
  247. package/src/web-components/ui/BdsIconWrapper.stories.tsx +1 -1
  248. package/src/web-components/ui/BdsLink.mdx +1 -1
  249. package/src/web-components/ui/BdsLink.stories.tsx +1 -1
  250. package/src/web-components/ui/BdsLoading.mdx +1 -1
  251. package/src/web-components/ui/BdsLoading.stories.tsx +1 -1
  252. package/src/web-components/ui/BdsNotificationBanner.mdx +10 -1
  253. package/src/web-components/ui/BdsNotificationBanner.stories.tsx +29 -2
  254. package/src/web-components/ui/BdsPagination.mdx +1 -1
  255. package/src/web-components/ui/BdsPagination.stories.tsx +1 -1
  256. package/src/web-components/ui/BdsProgress.mdx +1 -1
  257. package/src/web-components/ui/BdsProgress.stories.tsx +1 -1
  258. package/src/web-components/ui/BdsProgressCircle.mdx +1 -1
  259. package/src/web-components/ui/BdsProgressCircle.stories.tsx +1 -1
  260. package/src/web-components/ui/BdsRating.mdx +1 -1
  261. package/src/web-components/ui/BdsRating.stories.tsx +1 -1
  262. package/src/web-components/ui/BdsSectionHeader.mdx +18 -6
  263. package/src/web-components/ui/BdsSectionHeader.stories.tsx +10 -2
  264. package/src/web-components/ui/BdsSeparator.mdx +2 -1
  265. package/src/web-components/ui/BdsSeparator.stories.tsx +13 -1
  266. package/src/web-components/ui/BdsSkeleton.mdx +1 -1
  267. package/src/web-components/ui/BdsSkeleton.stories.tsx +1 -1
  268. package/src/web-components/ui/BdsTable.mdx +5 -1
  269. package/src/web-components/ui/BdsTable.stories.tsx +1 -1
  270. package/src/web-components/ui/BdsTypography.mdx +1 -1
  271. package/src/web-components/ui/BdsTypography.stories.tsx +1 -1
  272. package/src/web-components/ui/bds-alert.spec.ts +27 -0
  273. package/src/web-components/ui/bds-alert.ts +34 -1
  274. package/src/web-components/ui/bds-avatar.spec.ts +47 -0
  275. package/src/web-components/ui/bds-avatar.ts +36 -3
  276. package/src/web-components/ui/bds-notification-banner.spec.ts +45 -0
  277. package/src/web-components/ui/bds-notification-banner.ts +53 -1
  278. package/src/web-components/ui/bds-section-header.spec.ts +36 -3
  279. package/src/web-components/ui/bds-section-header.ts +32 -10
  280. package/src/web-components/ui/bds-separator.spec.ts +8 -0
  281. package/src/web-components/ui/bds-separator.ts +7 -0
  282. package/src/web-components/ui/bds-table.spec.ts +11 -0
  283. package/src/web-components/ui/bds-table.ts +5 -5
  284. package/dist/web-components/chunk-QZAIRJ75.js +0 -111
@@ -7,7 +7,7 @@ import * as Stories from './BdsIconWrapper.stories';
7
7
 
8
8
  Framework-agnostic Icon Wrapper custom element. Displays a slotted icon inside a circular container with design-system background and foreground colour theming.
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
 
@@ -25,7 +25,7 @@ function BdsIconWrapper({
25
25
  const meta = {
26
26
  title: 'Web Components/Layout/IconWrapper',
27
27
  component: BdsIconWrapper,
28
- tags: ['!stable', 'experimental'],
28
+ tags: ['!stable', 'alpha'],
29
29
  parameters: { layout: 'centered' },
30
30
  argTypes: {
31
31
  ariaHidden: { control: 'text' },
@@ -7,7 +7,7 @@ import * as Stories from './BdsLink.stories';
7
7
 
8
8
  Framework-agnostic Link custom element. Renders a styled `<a>` tag with three visual variants, automatic external link handling, and design-token colours.
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
 
@@ -34,7 +34,7 @@ function BdsLink({
34
34
  const meta = {
35
35
  title: 'Web Components/UI/Link',
36
36
  component: BdsLink,
37
- tags: ['!stable', 'experimental'],
37
+ tags: ['!stable', 'alpha'],
38
38
  parameters: { layout: 'centered' },
39
39
  argTypes: {
40
40
  variant: { control: 'select', options: ['default', 'subtle', 'standalone'] },
@@ -7,7 +7,7 @@ import * as Stories from './BdsLoading.stories';
7
7
 
8
8
  Framework-agnostic Loading spinner custom element. Displays an animated circular spinner to indicate that a process is in progress.
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
 
@@ -9,7 +9,7 @@ function BdsLoading({ size = 'medium' }: { size?: 'small' | 'medium' | 'large' }
9
9
  const meta = {
10
10
  title: 'Web Components/UI/Loading',
11
11
  component: BdsLoading,
12
- tags: ['!stable', 'experimental'],
12
+ tags: ['!stable', 'alpha'],
13
13
  parameters: { layout: 'centered' },
14
14
  argTypes: {
15
15
  size: { control: 'select', options: ['small', 'medium', 'large'] },
@@ -7,7 +7,7 @@ import * as Stories from './BdsNotificationBanner.stories';
7
7
 
8
8
  Framework-agnostic Notification Banner custom element. Renders a full-width status banner at the top of a page or section with optional dismiss button and action slot.
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
  ### Error
39
39
  <Canvas of={Stories.Error} />
40
40
 
41
+ ### Gradient
42
+ <Canvas of={Stories.Gradient} />
43
+
41
44
  ### Dismissible
42
45
  <Canvas of={Stories.Dismissible} />
43
46
 
@@ -53,6 +56,7 @@ import '@boostdev/design-system-components/web-components';
53
56
  | Attribute | Type | Default | Description |
54
57
  |-----------|------|---------|-------------|
55
58
  | `variant` | `"info" \| "success" \| "warning" \| "error"` | `"info"` | Visual style and semantic urgency |
59
+ | `appearance` | `"default" \| "gradient"` | `"default"` | `gradient` fades the variant tint to the surface and adds a shadow |
56
60
  | `dismissible` | boolean | `false` | Shows a dismiss (×) button |
57
61
  | `dismiss-label` | string | `"Dismiss notification"` | `aria-label` for the dismiss button |
58
62
 
@@ -61,6 +65,7 @@ import '@boostdev/design-system-components/web-components';
61
65
  | Slot | Description |
62
66
  |------|-------------|
63
67
  | `(default)` | Banner body text or HTML |
68
+ | `icon` | Optional icon before the content (rendered `aria-hidden`) |
64
69
  | `action` | Optional action area (e.g. a `<button>` or `<a>`) |
65
70
 
66
71
  ## CSS Custom Properties
@@ -74,6 +79,10 @@ import '@boostdev/design-system-components/web-components';
74
79
  | `--banner_bg--success` / `--banner_text--success` / `--banner_border--success` | Success variant colours |
75
80
  | `--banner_bg--warning` / `--banner_text--warning` / `--banner_border--warning` | Warning variant colours |
76
81
  | `--banner_bg--error` / `--banner_text--error` / `--banner_border--error` | Error variant colours |
82
+ | `--banner_border-width` | Width of the block-end accent line (default `3px`) |
83
+ | `--banner_gradient` | Gradient over the variant background, `appearance="gradient"` only (default `linear-gradient(100deg, transparent 35%, var(--bds-color_bg--strong, var(--bds-color_bg)) 100%)`) |
84
+ | `--banner_shadow` | Box shadow, `appearance="gradient"` only (default `var(--bds-shadow_s)`) |
85
+ | `--banner_accent--info` / `--banner_accent--success` / `--banner_accent--warning` / `--banner_accent--error` | Accent line colour with `appearance="gradient"` (defaults `--bds-color_on-blue--subtle`, `--bds-color_on-success--subtle`, `--bds-color_warning`, `--bds-color_error`). `--banner_border--{variant}` and `--banner_border` win. |
77
86
  | `--banner_dismiss-size` | Dismiss button minimum touch target (default `2.75rem`, WCAG 2.5.5); the visible icon stays 1rem |
78
87
  | `--banner_dismiss-radius` | Dismiss button border radius |
79
88
  | `--banner_dismiss-border` | Dismiss button border |
@@ -1,16 +1,18 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
- import type { NotificationBannerVariant } from './bds-notification-banner';
3
+ import type { NotificationBannerAppearance, NotificationBannerVariant } from './bds-notification-banner';
4
4
  import '../index'; // auto-registers all custom elements
5
5
 
6
6
  function BdsNotificationBanner({
7
7
  variant = 'info',
8
+ appearance,
8
9
  dismissible,
9
10
  dismissLabel,
10
11
  children,
11
12
  action,
12
13
  }: {
13
14
  variant?: NotificationBannerVariant;
15
+ appearance?: NotificationBannerAppearance;
14
16
  dismissible?: boolean;
15
17
  dismissLabel?: string;
16
18
  children?: React.ReactNode;
@@ -20,6 +22,7 @@ function BdsNotificationBanner({
20
22
  'bds-notification-banner',
21
23
  {
22
24
  variant,
25
+ appearance,
23
26
  dismissible: dismissible || undefined,
24
27
  'dismiss-label': dismissLabel,
25
28
  },
@@ -33,10 +36,11 @@ function BdsNotificationBanner({
33
36
  const meta = {
34
37
  title: 'Web Components/UI/NotificationBanner',
35
38
  component: BdsNotificationBanner,
36
- tags: ['!stable', 'experimental'],
39
+ tags: ['!stable', 'alpha'],
37
40
  parameters: { layout: 'fullscreen' },
38
41
  argTypes: {
39
42
  variant: { control: 'select', options: ['info', 'success', 'warning', 'error'] },
43
+ appearance: { control: 'select', options: ['default', 'gradient'] },
40
44
  dismissible: { control: 'boolean' },
41
45
  },
42
46
  } satisfies Meta<typeof BdsNotificationBanner>;
@@ -82,3 +86,26 @@ export const AllVariants: Story = {
82
86
  </div>
83
87
  ),
84
88
  };
89
+
90
+ const gradientIcon = (path: string) =>
91
+ React.createElement(
92
+ 'svg',
93
+ { slot: 'icon', viewBox: '0 0 24 24', width: 20, height: 20, fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
94
+ React.createElement('circle', { cx: 12, cy: 12, r: 10 }),
95
+ React.createElement('path', { d: path }),
96
+ );
97
+
98
+ export const Gradient: Story = {
99
+ render: () => (
100
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
101
+ {(['info', 'success', 'warning', 'error'] as const).map(v =>
102
+ React.createElement(
103
+ 'bds-notification-banner',
104
+ { key: v, variant: v, appearance: 'gradient' },
105
+ gradientIcon(v === 'success' ? 'm8 12 3 3 5-6' : v === 'info' ? 'M12 16v-4M12 8h.01' : 'M12 7v6M12 16h.01'),
106
+ `This is a ${v} notification banner.`,
107
+ ),
108
+ )}
109
+ </div>
110
+ ),
111
+ };
@@ -7,7 +7,7 @@ import * as Stories from './BdsPagination.stories';
7
7
 
8
8
  Framework-agnostic Pagination navigation custom element. Renders previous/next buttons and a page number list with smart ellipsis truncation.
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
 
@@ -18,7 +18,7 @@ function BdsPagination({
18
18
  const meta = {
19
19
  title: 'Web Components/UI/Pagination',
20
20
  component: BdsPagination,
21
- tags: ['!stable', 'experimental'],
21
+ tags: ['!stable', 'alpha'],
22
22
  parameters: { layout: 'centered' },
23
23
  argTypes: {
24
24
  currentPage: { control: { type: 'number', min: 1 } },
@@ -7,7 +7,7 @@ import * as Stories from './BdsProgress.stories';
7
7
 
8
8
  Framework-agnostic horizontal Progress bar custom element. Tracks progress toward a goal with optional label and percentage display.
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
 
@@ -27,7 +27,7 @@ function BdsProgress({
27
27
  const meta = {
28
28
  title: 'Web Components/UI/Progress',
29
29
  component: BdsProgress,
30
- tags: ['!stable', 'experimental'],
30
+ tags: ['!stable', 'alpha'],
31
31
  parameters: { layout: 'centered' },
32
32
  argTypes: {
33
33
  value: { control: { type: 'range', min: 0, max: 100 } },
@@ -7,7 +7,7 @@ import * as Stories from './BdsProgressCircle.stories';
7
7
 
8
8
  Framework-agnostic circular Progress custom element. Renders an SVG ring that fills proportionally to the `value` attribute, with an optional centred percentage label.
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
 
@@ -27,7 +27,7 @@ function BdsProgressCircle({
27
27
  const meta = {
28
28
  title: 'Web Components/UI/ProgressCircle',
29
29
  component: BdsProgressCircle,
30
- tags: ['!stable', 'experimental'],
30
+ tags: ['!stable', 'alpha'],
31
31
  parameters: { layout: 'centered' },
32
32
  argTypes: {
33
33
  value: { control: { type: 'range', min: 0, max: 100 } },
@@ -7,7 +7,7 @@ import * as Stories from './BdsRating.stories';
7
7
 
8
8
  Framework-agnostic read-only star Rating custom element. Renders a row of SVG stars with filled/empty states based on `value` and `max`.
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
 
@@ -15,7 +15,7 @@ function BdsRating({
15
15
  const meta = {
16
16
  title: 'Web Components/Interaction/Rating',
17
17
  component: BdsRating,
18
- tags: ['!stable', 'experimental'],
18
+ tags: ['!stable', 'alpha'],
19
19
  parameters: { layout: 'centered' },
20
20
  argTypes: {
21
21
  value: { control: { type: 'range', min: 0, max: 10 } },
@@ -7,7 +7,7 @@ import * as Stories from './BdsSectionHeader.stories';
7
7
 
8
8
  Framework-agnostic Section Header custom element. Combines a title and optional subtitle into a consistently styled page or section heading with size and alignment variants.
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
 
@@ -41,6 +41,15 @@ import '@boostdev/design-system-components/web-components';
41
41
  ### Centered
42
42
  <Canvas of={Stories.Centered} />
43
43
 
44
+ ### Gradient
45
+ <Canvas of={Stories.Gradient} />
46
+
47
+ <Canvas of={Stories.GradientExtraSmall} />
48
+
49
+ <Canvas of={Stories.GradientSmall} />
50
+
51
+ <Canvas of={Stories.GradientLarge} />
52
+
44
53
  ### Title only
45
54
  <Canvas of={Stories.TitleOnly} />
46
55
 
@@ -57,6 +66,7 @@ import '@boostdev/design-system-components/web-components';
57
66
  | `subtitle` | string | — | Optional subheading text |
58
67
  | `alignment` | `"start" \| "center" \| "end"` | `"start"` | Text and flex alignment |
59
68
  | `size` | `"xs" \| "small" \| "medium" \| "large"` | `"medium"` | Font size scale for title and subtitle |
69
+ | `appearance` | `"default" \| "gradient"` | `"default"` | `gradient` fills the title with a gradient that spans the text. Falls back to the normal colour without `background-clip: text` support, and to `CanvasText` in forced-colors mode |
60
70
  | `title-as` | string | `"h2"` | Override the HTML element rendered for the title |
61
71
 
62
72
  ## Usage in plain HTML
@@ -79,13 +89,15 @@ import '@boostdev/design-system-components/web-components';
79
89
 
80
90
  | Token | Default | Description |
81
91
  |-------|---------|--------------|
92
+ | `--sectionHeader_title-font-family` | `--bds-font_family--heading` | Title font family |
93
+ | `--sectionHeader_title-gradient` | `linear-gradient(90deg, --bds-color_primary--strong, --bds-color_accent-3--strong)` | Title gradient, only with `appearance="gradient"` |
82
94
  | `--sectionHeader_gap` | `--bds-space_m` | Gap between title and subtitle |
83
- | `--sectionHeader_title-color` | `--bds-color_on-bg` | Title text color (`--sectionHeader-title-color`, kebab-delimited, is a deprecated alias) |
84
- | `--sectionHeader_subtitle-color` | `--bds-color_grey--strong` | Subtitle text color |
85
- | `--sectionHeader_title-size` | Size-variant font-size token (e.g. `--bds-font_size--display` for medium/large) | Title font size |
95
+ | `--sectionHeader_title-color` | `--bds-color_on-bg` | Title text color; no effect with `appearance="gradient"`, where the colour comes from `--sectionHeader_title-gradient` (`--sectionHeader-title-color`, kebab-delimited, is a deprecated alias) |
96
+ | `--sectionHeader_subtitle-color` | `--bds-color_on-bg--muted` | Subtitle text color |
97
+ | `--sectionHeader_title-size` | `xs` body, `small` heading-3, `medium` heading-2, `large` heading-1 | Title font size |
86
98
  | `--sectionHeader_title-line-height` | Size-variant line-height token | Title line height |
87
- | `--sectionHeader_title-weight` | `--bds-font_weight--bold` | Title font weight |
88
- | `--sectionHeader_subtitle-size` | Size-variant font-size token | Subtitle font size |
99
+ | `--sectionHeader_title-weight` | `--bds-font_weight--heading` | Title font weight |
100
+ | `--sectionHeader_subtitle-size` | `xs` body--s, `small`/`medium` body, `large` heading-3 | Subtitle font size |
89
101
  | `--sectionHeader_subtitle-line-height` | `1.3` (medium/large) or `1.4` (xs/small) | Subtitle line height |
90
102
 
91
103
  The host also sets `grid-column: var(--bds-grid_span-100)` so the header spans the full row when placed inside `<bds-grid>`.
@@ -7,25 +7,28 @@ function BdsSectionHeader({
7
7
  subtitle,
8
8
  alignment = 'start',
9
9
  size = 'medium',
10
+ appearance = 'default',
10
11
  titleAs,
11
12
  }: {
12
13
  heading?: string;
13
14
  subtitle?: string;
14
15
  alignment?: 'start' | 'center' | 'end';
15
16
  size?: 'xs' | 'small' | 'medium' | 'large';
17
+ appearance?: 'default' | 'gradient';
16
18
  titleAs?: string;
17
19
  }) {
18
- return React.createElement('bds-section-header', { heading, subtitle, alignment, size, 'title-as': titleAs });
20
+ return React.createElement('bds-section-header', { heading, subtitle, alignment, size, appearance, 'title-as': titleAs });
19
21
  }
20
22
 
21
23
  const meta = {
22
24
  title: 'Web Components/Layout/SectionHeader',
23
25
  component: BdsSectionHeader,
24
- tags: ['!stable', 'experimental'],
26
+ tags: ['!stable', 'alpha'],
25
27
  parameters: { layout: 'padded' },
26
28
  argTypes: {
27
29
  alignment: { control: 'select', options: ['start', 'center', 'end'] },
28
30
  size: { control: 'select', options: ['xs', 'small', 'medium', 'large'] },
31
+ appearance: { control: 'select', options: ['default', 'gradient'] },
29
32
  titleAs: { control: 'text' },
30
33
  },
31
34
  } satisfies Meta<typeof BdsSectionHeader>;
@@ -54,3 +57,8 @@ export const AllSizes: Story = {
54
57
  </div>
55
58
  ),
56
59
  };
60
+
61
+ export const Gradient: Story = { args: { heading: 'Gradient Header', subtitle: 'Gradient title', appearance: 'gradient' } };
62
+ export const GradientExtraSmall: Story = { args: { heading: 'Gradient Extra Small', subtitle: 'Gradient title', appearance: 'gradient', size: 'xs' } };
63
+ export const GradientSmall: Story = { args: { heading: 'Gradient Small', subtitle: 'Gradient title', appearance: 'gradient', size: 'small' } };
64
+ export const GradientLarge: Story = { args: { heading: 'Gradient Large', subtitle: 'Gradient title', appearance: 'gradient', size: 'large' } };
@@ -7,7 +7,7 @@ import * as Stories from './BdsSeparator.stories';
7
7
 
8
8
  Framework-agnostic Separator custom element. Renders a thin decorative line to visually divide content. Supports both horizontal and vertical orientations.
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
 
@@ -56,6 +56,7 @@ Or in HTML without a bundler:
56
56
  |----------|-------------|
57
57
  | `--separator_color` | Line colour (defaults to `--bds-color_on-bg--as-surface`, the non-text member of the set — a rule is not text, so it needs 3:1, not 4.5:1) |
58
58
  | `--separator_thickness` | Line thickness (default: `1px`) |
59
+ | `--separator_spacing` | Space around the line: inline for vertical (default: `var(--bds-space_s)`), block for horizontal (default: `0`) |
59
60
 
60
61
  ## Usage in plain HTML
61
62
 
@@ -13,7 +13,7 @@ function BdsSeparator({
13
13
  const meta = {
14
14
  title: 'Web Components/UI/Separator',
15
15
  component: BdsSeparator,
16
- tags: ['!stable', 'experimental'],
16
+ tags: ['!stable', 'alpha'],
17
17
  parameters: { layout: 'centered' },
18
18
  argTypes: {
19
19
  orientation: { control: 'radio', options: ['horizontal', 'vertical'] },
@@ -53,3 +53,15 @@ export const Vertical: Story = {
53
53
  </div>
54
54
  ),
55
55
  };
56
+
57
+ export const BetweenLinks: Story = {
58
+ render: () => (
59
+ <nav aria-label="Example" style={{ display: 'flex', alignItems: 'center' }}>
60
+ <a href="#one">Home</a>
61
+ {React.createElement('bds-separator', { orientation: 'vertical' })}
62
+ <a href="#two">Pricing</a>
63
+ {React.createElement('bds-separator', { orientation: 'vertical' })}
64
+ <a href="#three">Contact</a>
65
+ </nav>
66
+ ),
67
+ };
@@ -7,7 +7,7 @@ import * as Stories from './BdsSkeleton.stories';
7
7
 
8
8
  Framework-agnostic Skeleton loading placeholder custom element. Displays an animated shimmer while real content is loading. Size is set via inline styles or CSS on the host element.
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
 
@@ -10,7 +10,7 @@ function BdsSkeleton({ width = '200px', height = '1rem' }: { width?: string; hei
10
10
  const meta = {
11
11
  title: 'Web Components/UI/Skeleton',
12
12
  component: BdsSkeleton,
13
- tags: ['!stable', 'experimental'],
13
+ tags: ['!stable', 'alpha'],
14
14
  parameters: { layout: 'centered' },
15
15
  argTypes: {
16
16
  width: { control: 'text' },
@@ -7,7 +7,7 @@ import * as Stories from './BdsTable.stories';
7
7
 
8
8
  Framework-agnostic scrollable Table wrapper custom element. Apply design-system styles to a standard `<table>` element by nesting it in the default slot.
9
9
 
10
- > **Status: experimental** — API may change before stable release.
10
+ > **Status: alpha** — API may change before stable release.
11
11
 
12
12
  > **Light-DOM styling contract:** `::slotted()` can only match the node placed directly into
13
13
  > the slot (the `<table>` itself), never its descendants. `<thead>`/`<th>`/`<td>` styling is
@@ -57,6 +57,10 @@ import '@boostdev/design-system-components/web-components';
57
57
  | Property | Description |
58
58
  |----------|-------------|
59
59
  | `--table_divider-color` | Colour of the header underline and row rules (default: `--bds-color_on-bg--as-surface`, the non-text member of the set — ≥ 3:1, not a ground colour) |
60
+ | `--table_header-font-size` | Header cell font size (default: `var(--bds-font_size--body)`) |
61
+ | `--table_header-font-weight` | Header cell font weight (default: `var(--bds-font_weight--bold)`) |
62
+ | `--table_header-color` | Header cell text colour (default: `var(--bds-color_on-bg--subtle)`) |
63
+ | `--table_header-bg` | Header row background (default: `var(--bds-color_bg--subtle)`) |
60
64
  | `--table_border` | Wrapper border (default: `none`) |
61
65
  | `--table_radius` | Wrapper corner radius (default: `var(--bdc-outline_radius)`, itself set to `var(--bds-border_radius--s)` on the wrapper) |
62
66
  | `--table_row-bg--hover` | Row background on hover, pointer devices only (default: `var(--bds-color_bg--subtle)`) |
@@ -58,7 +58,7 @@ const sampleTable = () =>
58
58
  const meta = {
59
59
  title: 'Web Components/UI/Table',
60
60
  component: BdsTable,
61
- tags: ['!stable', 'experimental'],
61
+ tags: ['!stable', 'alpha'],
62
62
  parameters: { layout: 'fullscreen' },
63
63
  argTypes: {
64
64
  stickyHeader: { control: 'boolean' },
@@ -7,7 +7,7 @@ import * as Stories from './BdsTypography.stories';
7
7
 
8
8
  Framework-agnostic Typography custom element. Renders slotted text inside the appropriate semantic HTML element (`h1`–`h3`, `p`) based on the `variant` attribute, with optional tag override via `component`.
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
 
@@ -18,7 +18,7 @@ function BdsTypography({
18
18
  const meta = {
19
19
  title: 'Web Components/UI/Typography',
20
20
  component: BdsTypography,
21
- tags: ['!stable', 'experimental'],
21
+ tags: ['!stable', 'alpha'],
22
22
  parameters: { layout: 'centered' },
23
23
  argTypes: {
24
24
  variant: { control: 'select', options: ['h1', 'h2', 'h3', 'body', 'body_s'] },
@@ -121,4 +121,31 @@ describe('bds-alert', () => {
121
121
  expect(div!.getAttribute('role')).toBe('alert');
122
122
  cleanup(el);
123
123
  });
124
+
125
+ it('defaults to appearance="default"', async () => {
126
+ const el = await fixture('<bds-alert>Message</bds-alert>');
127
+ expect(el.getAttribute('appearance')).toBe('default');
128
+ cleanup(el);
129
+ });
130
+
131
+ it('reflects appearance="gradient"', async () => {
132
+ const el = await fixture('<bds-alert appearance="gradient">Message</bds-alert>') as BdsAlert;
133
+ expect(el.appearance).toBe('gradient');
134
+ el.appearance = 'default';
135
+ await el.updateComplete;
136
+ expect(el.getAttribute('appearance')).toBe('default');
137
+ cleanup(el);
138
+ });
139
+
140
+ it('wires the gradient hooks in the styles', () => {
141
+ const styles = String(BdsAlert.styles);
142
+ expect(styles).toContain(":host([appearance='gradient']) .alert");
143
+ expect(styles).toMatch(/background-image:\s*var\(--alert_gradient,\s*linear-gradient\(100deg/);
144
+ expect(styles).toMatch(/box-shadow:\s*var\(--alert_shadow,\s*var\(--bds-shadow_s\)\)/);
145
+ expect(styles).toContain('--alert_border-width--variant: 3px');
146
+ expect(styles).toMatch(/\.alert \{[^}]*--alert_border-width--variant:\s*initial/);
147
+ ['info', 'success', 'warning', 'error'].forEach(v => {
148
+ expect(styles).toContain(`--alert_accent--${v}`);
149
+ });
150
+ });
124
151
  });
@@ -1,12 +1,14 @@
1
1
  import { LitElement, css, html, nothing } from 'lit';
2
2
 
3
3
  export type AlertVariant = 'info' | 'success' | 'warning' | 'error';
4
+ export type AlertAppearance = 'default' | 'gradient';
4
5
 
5
6
  /**
6
7
  * `<bds-alert>` — framework-agnostic Alert custom element.
7
8
  *
8
9
  * Attributes:
9
10
  * variant — "info" (default) | "success" | "warning" | "error"
11
+ * appearance — "default" | "gradient" (fades the tint to the surface, 3px accent line, shadow)
10
12
  * heading — optional heading above the body text
11
13
  * title — deprecated alias for `heading`. Collides with the global HTML
12
14
  * `title` attribute, which triggers a native browser tooltip on
@@ -60,9 +62,12 @@ export class BdsAlert extends LitElement {
60
62
  defaults. Variants write to the inner --alert_*--variant slot. */
61
63
  background-color: var(--alert_bg, var(--alert_bg--variant, var(--bds-color_blue--subtle)));
62
64
  color: var(--alert_text, var(--alert_text--variant, var(--bds-color_on-blue--subtle)));
63
- border-inline-start: var(--bds-space_s) solid var(--alert_border, var(--alert_border--variant, var(--bds-color_blue)));
65
+ border-inline-start: var(--alert_border-width, var(--alert_border-width--variant, var(--bds-space_s))) solid var(--alert_border, var(--alert_border--variant, var(--bds-color_blue)));
64
66
  font-size: var(--bds-font_size--body);
65
67
  line-height: var(--bds-font_line-height--body);
68
+
69
+ /* Reset the slot so a nested default alert does not inherit a parent's gradient width. */
70
+ --alert_border-width--variant: initial;
66
71
  }
67
72
 
68
73
  /* Per-variant resting overrides — consumers can theme per-variant via
@@ -91,6 +96,31 @@ export class BdsAlert extends LitElement {
91
96
  --alert_border--variant: var(--alert_border--error, var(--bds-color_error));
92
97
  }
93
98
 
99
+ /* Gradient appearance: the variant background stays the base colour and a
100
+ gradient fades it to the surface. The accent line is thinner and uses a
101
+ per-variant accent slot; --alert_border still wins over it. */
102
+ :host([appearance='gradient']) .alert {
103
+ --alert_border-width--variant: 3px;
104
+ background-image: var(--alert_gradient, linear-gradient(100deg, transparent 35%, var(--bds-color_bg--strong, var(--bds-color_bg)) 100%));
105
+ box-shadow: var(--alert_shadow, var(--bds-shadow_s));
106
+ }
107
+
108
+ :host([appearance='gradient'][variant='info']) .alert {
109
+ --alert_border--variant: var(--alert_border--info, var(--alert_accent--info, var(--bds-color_on-blue--subtle)));
110
+ }
111
+
112
+ :host([appearance='gradient'][variant='success']) .alert {
113
+ --alert_border--variant: var(--alert_border--success, var(--alert_accent--success, var(--bds-color_on-success--subtle)));
114
+ }
115
+
116
+ :host([appearance='gradient'][variant='warning']) .alert {
117
+ --alert_border--variant: var(--alert_border--warning, var(--alert_accent--warning, var(--bds-color_warning)));
118
+ }
119
+
120
+ :host([appearance='gradient'][variant='error']) .alert {
121
+ --alert_border--variant: var(--alert_border--error, var(--alert_accent--error, var(--bds-color_error)));
122
+ }
123
+
94
124
  /* Icon slot wrapper — hidden unless slot has content */
95
125
  .icon {
96
126
  display: none;
@@ -151,6 +181,7 @@ export class BdsAlert extends LitElement {
151
181
 
152
182
  static properties = {
153
183
  variant: { type: String, reflect: true },
184
+ appearance: { type: String, reflect: true },
154
185
  heading: { type: String },
155
186
  title: { type: String },
156
187
  dismissible: { type: Boolean, reflect: true },
@@ -160,6 +191,7 @@ export class BdsAlert extends LitElement {
160
191
  // `declare` annotates the type without emitting a class field initializer
161
192
  // that would shadow Lit's reactive accessors on the prototype.
162
193
  declare variant: AlertVariant;
194
+ declare appearance: AlertAppearance;
163
195
  declare heading: string;
164
196
  /**
165
197
  * @deprecated Use `heading` instead. Sharing the name with the global HTML
@@ -173,6 +205,7 @@ export class BdsAlert extends LitElement {
173
205
  constructor() {
174
206
  super();
175
207
  this.variant = 'info';
208
+ this.appearance = 'default';
176
209
  this.heading = '';
177
210
  this.title = '';
178
211
  this.dismissible = false;
@@ -1,5 +1,6 @@
1
1
  import { fixture, cleanup } from '../test/helpers';
2
2
  import { BdsAvatar } from './bds-avatar';
3
+ import { toneFromName } from '../../components/ui/Avatar/avatarTone';
3
4
 
4
5
  describe('bds-avatar', () => {
5
6
  it('is registered as a custom element', () => {
@@ -101,4 +102,50 @@ describe('bds-avatar', () => {
101
102
  // The public --avatar_size token itself must never be set directly by a size selector.
102
103
  expect(cssText).not.toMatch(/:host\(\[size=[^)]*\]\)\s*\{\s*--avatar_size:/);
103
104
  });
105
+
106
+ it('defaults to tone="auto"', async () => {
107
+ const el = await fixture('<bds-avatar name="Jane Doe"></bds-avatar>');
108
+ expect(el.getAttribute('tone')).toBe('auto');
109
+ cleanup(el);
110
+ });
111
+
112
+ it('picks the same tone as the React Avatar for the same name', async () => {
113
+ const el = await fixture('<bds-avatar name="Jane Doe"></bds-avatar>');
114
+ const fallback = el.shadowRoot!.querySelector('.fallback');
115
+ expect(fallback!.classList.contains(`tone_${toneFromName('Jane Doe')}`)).toBe(true);
116
+ cleanup(el);
117
+ });
118
+
119
+ it('uses primary when there is no name', async () => {
120
+ const el = await fixture('<bds-avatar></bds-avatar>');
121
+ expect(el.shadowRoot!.querySelector('.fallback')!.classList.contains('tone_primary')).toBe(true);
122
+ cleanup(el);
123
+ });
124
+
125
+ it('falls back to the name tone for an unknown tone attribute', async () => {
126
+ const el = await fixture('<bds-avatar name="Jane Doe" tone="foo"></bds-avatar>');
127
+ expect(el.shadowRoot!.querySelector('.fallback')!.classList.contains(`tone_${toneFromName('Jane Doe')}`)).toBe(true);
128
+ });
129
+
130
+ it('lets an explicit tone win over auto', async () => {
131
+ const el = await fixture('<bds-avatar name="Jane Doe" tone="accent-2"></bds-avatar>');
132
+ expect(el.shadowRoot!.querySelector('.fallback')!.classList.contains('tone_accent-2')).toBe(true);
133
+ cleanup(el);
134
+ });
135
+
136
+ it('does not render a tone for image avatars', async () => {
137
+ const el = await fixture('<bds-avatar src="/photo.jpg" name="Jane Doe" tone="accent-1"></bds-avatar>');
138
+ expect(el.shadowRoot!.querySelector('.fallback')).toBeNull();
139
+ cleanup(el);
140
+ });
141
+
142
+ it('exposes a hook per tone and lets --avatar_bg and --avatar_text win', () => {
143
+ const cssText = BdsAvatar.styles.cssText;
144
+ expect(cssText).toMatch(/background-color:\s*var\(--avatar_bg,\s*var\(--avatar_bg--variant\)\)/);
145
+ expect(cssText).toMatch(/color:\s*var\(--avatar_text,\s*var\(--avatar_text--variant\)\)/);
146
+ ['primary', 'secondary', 'accent-1', 'accent-2', 'accent-3'].forEach(tone => {
147
+ expect(cssText).toContain(`--avatar_bg--${tone}`);
148
+ expect(cssText).toContain(`--avatar_text--${tone}`);
149
+ });
150
+ });
104
151
  });