@salt-ds/core 1.70.0 → 1.72.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 (315) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/css/salt-core.css +466 -106
  3. package/dist-cjs/accordion/AccordionHeader.css.js +1 -1
  4. package/dist-cjs/aria-announcer/AriaAnnouncerProvider.js +8 -0
  5. package/dist-cjs/aria-announcer/AriaAnnouncerProvider.js.map +1 -1
  6. package/dist-cjs/avatar/Avatar.css.js +1 -1
  7. package/dist-cjs/badge/Badge.css.js +1 -1
  8. package/dist-cjs/banner/Banner.css.js +1 -1
  9. package/dist-cjs/breadcrumbs/Breadcrumb.css.js +1 -1
  10. package/dist-cjs/breadcrumbs/Breadcrumbs.css.js +1 -1
  11. package/dist-cjs/card/Card.css.js +1 -1
  12. package/dist-cjs/card/Card.js +4 -0
  13. package/dist-cjs/card/Card.js.map +1 -1
  14. package/dist-cjs/checkbox/Checkbox.css.js +1 -1
  15. package/dist-cjs/checkbox/CheckboxIcon.css.js +1 -1
  16. package/dist-cjs/combo-box/ComboBox.js +18 -36
  17. package/dist-cjs/combo-box/ComboBox.js.map +1 -1
  18. package/dist-cjs/combo-box/useComboBox.js +21 -21
  19. package/dist-cjs/combo-box/useComboBox.js.map +1 -1
  20. package/dist-cjs/drawer/Drawer.css.js +1 -1
  21. package/dist-cjs/drawer/Drawer.js +30 -5
  22. package/dist-cjs/drawer/Drawer.js.map +1 -1
  23. package/dist-cjs/drawer/DrawerCloseButton.js +1 -1
  24. package/dist-cjs/drawer/DrawerCloseButton.js.map +1 -1
  25. package/dist-cjs/drawer/DrawerContent.css.js +6 -0
  26. package/dist-cjs/drawer/DrawerContent.css.js.map +1 -0
  27. package/dist-cjs/drawer/DrawerContent.js +75 -0
  28. package/dist-cjs/drawer/DrawerContent.js.map +1 -0
  29. package/dist-cjs/drawer/DrawerContext.js +30 -0
  30. package/dist-cjs/drawer/DrawerContext.js.map +1 -0
  31. package/dist-cjs/drawer/DrawerFooter.css.js +6 -0
  32. package/dist-cjs/drawer/DrawerFooter.css.js.map +1 -0
  33. package/dist-cjs/drawer/DrawerFooter.js +30 -0
  34. package/dist-cjs/drawer/DrawerFooter.js.map +1 -0
  35. package/dist-cjs/drawer/DrawerHeader.css.js +6 -0
  36. package/dist-cjs/drawer/DrawerHeader.css.js.map +1 -0
  37. package/dist-cjs/drawer/DrawerHeader.js +95 -0
  38. package/dist-cjs/drawer/DrawerHeader.js.map +1 -0
  39. package/dist-cjs/drawer/hasDrawerSection.js +22 -0
  40. package/dist-cjs/drawer/hasDrawerSection.js.map +1 -0
  41. package/dist-cjs/dropdown/Dropdown.js +29 -30
  42. package/dist-cjs/dropdown/Dropdown.js.map +1 -1
  43. package/dist-cjs/file-drop-zone/FileDropZone.css.js +1 -1
  44. package/dist-cjs/form-field/FormField.css.js +1 -1
  45. package/dist-cjs/form-field/FormField.js +15 -0
  46. package/dist-cjs/form-field/FormField.js.map +1 -1
  47. package/dist-cjs/form-field/FormFieldHelperText.css.js +1 -1
  48. package/dist-cjs/form-field/FormFieldLabel.css.js +1 -1
  49. package/dist-cjs/form-field/FormFieldLabel.js +1 -1
  50. package/dist-cjs/form-field/FormFieldLabel.js.map +1 -1
  51. package/dist-cjs/index.js +10 -0
  52. package/dist-cjs/index.js.map +1 -1
  53. package/dist-cjs/input/Input.css.js +1 -1
  54. package/dist-cjs/interactable-card/InteractableCard.css.js +1 -1
  55. package/dist-cjs/interactable-card/InteractableCard.js +23 -7
  56. package/dist-cjs/interactable-card/InteractableCard.js.map +1 -1
  57. package/dist-cjs/interactable-card/InteractableCardGroup.js +71 -39
  58. package/dist-cjs/interactable-card/InteractableCardGroup.js.map +1 -1
  59. package/dist-cjs/interactable-card/InteractableCardGroupContext.js.map +1 -1
  60. package/dist-cjs/interactable-card/useInteractableCard.js +2 -3
  61. package/dist-cjs/interactable-card/useInteractableCard.js.map +1 -1
  62. package/dist-cjs/kbd/Kbd.css.js +1 -1
  63. package/dist-cjs/link/Link.css.js +1 -1
  64. package/dist-cjs/link-button/LinkButton.css.js +6 -0
  65. package/dist-cjs/link-button/LinkButton.css.js.map +1 -0
  66. package/dist-cjs/link-button/LinkButton.js +87 -0
  67. package/dist-cjs/link-button/LinkButton.js.map +1 -0
  68. package/dist-cjs/link-card/LinkCard.css.js +1 -1
  69. package/dist-cjs/link-card/LinkCard.js +4 -0
  70. package/dist-cjs/link-card/LinkCard.js.map +1 -1
  71. package/dist-cjs/list-box/ListBox.js +19 -26
  72. package/dist-cjs/list-box/ListBox.js.map +1 -1
  73. package/dist-cjs/list-control/ListControlNavigationKeys.js +74 -0
  74. package/dist-cjs/list-control/ListControlNavigationKeys.js.map +1 -0
  75. package/dist-cjs/list-control/ListControlOptionContext.js +47 -0
  76. package/dist-cjs/list-control/ListControlOptionContext.js.map +1 -0
  77. package/dist-cjs/list-control/ListControlOptionStore.js +159 -0
  78. package/dist-cjs/list-control/ListControlOptionStore.js.map +1 -0
  79. package/dist-cjs/list-control/ListControlProvider.js +39 -0
  80. package/dist-cjs/list-control/ListControlProvider.js.map +1 -0
  81. package/dist-cjs/list-control/ListControlRegistry.js +161 -0
  82. package/dist-cjs/list-control/ListControlRegistry.js.map +1 -0
  83. package/dist-cjs/list-control/ListControlState.js +137 -109
  84. package/dist-cjs/list-control/ListControlState.js.map +1 -1
  85. package/dist-cjs/mega-menu/MegaMenuGroupHeading.css.js +1 -1
  86. package/dist-cjs/mega-menu/MegaMenuListItem.css.js +1 -1
  87. package/dist-cjs/menu/MenuGroup.css.js +1 -1
  88. package/dist-cjs/menu/MenuItem.css.js +1 -1
  89. package/dist-cjs/menu/MenuItem.js +0 -1
  90. package/dist-cjs/menu/MenuItem.js.map +1 -1
  91. package/dist-cjs/navigation-item/NavigationItem.css.js +1 -1
  92. package/dist-cjs/number-input/NumberInput.js +2 -2
  93. package/dist-cjs/number-input/NumberInput.js.map +1 -1
  94. package/dist-cjs/option/Option.js +58 -39
  95. package/dist-cjs/option/Option.js.map +1 -1
  96. package/dist-cjs/option/OptionGroup.css.js +1 -1
  97. package/dist-cjs/overlay/Overlay.js +12 -2
  98. package/dist-cjs/overlay/Overlay.js.map +1 -1
  99. package/dist-cjs/overlay/OverlayContext.js +6 -0
  100. package/dist-cjs/overlay/OverlayContext.js.map +1 -1
  101. package/dist-cjs/overlay/OverlayFooter.css.js +6 -0
  102. package/dist-cjs/overlay/OverlayFooter.css.js.map +1 -0
  103. package/dist-cjs/overlay/OverlayFooter.js +30 -0
  104. package/dist-cjs/overlay/OverlayFooter.js.map +1 -0
  105. package/dist-cjs/overlay/OverlayHeader.css.js +1 -1
  106. package/dist-cjs/overlay/OverlayHeader.js +51 -11
  107. package/dist-cjs/overlay/OverlayHeader.js.map +1 -1
  108. package/dist-cjs/overlay/OverlayPanel.css.js +1 -1
  109. package/dist-cjs/overlay/OverlayPanel.js +20 -7
  110. package/dist-cjs/overlay/OverlayPanel.js.map +1 -1
  111. package/dist-cjs/overlay/OverlayPanelContent.css.js +1 -1
  112. package/dist-cjs/overlay/OverlayPanelContent.js +11 -13
  113. package/dist-cjs/overlay/OverlayPanelContent.js.map +1 -1
  114. package/dist-cjs/overlay/hasOverlaySection.js +24 -0
  115. package/dist-cjs/overlay/hasOverlaySection.js.map +1 -0
  116. package/dist-cjs/panel/Panel.css.js +1 -1
  117. package/dist-cjs/panel/Panel.js +13 -2
  118. package/dist-cjs/panel/Panel.js.map +1 -1
  119. package/dist-cjs/pill-input/PillInput.css.js +1 -1
  120. package/dist-cjs/pill-input/PillInput.js +2 -2
  121. package/dist-cjs/pill-input/PillInput.js.map +1 -1
  122. package/dist-cjs/radio-button/RadioButton.css.js +1 -1
  123. package/dist-cjs/radio-button/RadioButtonIcon.css.js +1 -1
  124. package/dist-cjs/rating/Rating.css.js +1 -1
  125. package/dist-cjs/slider/internal/SliderTrack.css.js +1 -1
  126. package/dist-cjs/stepper/internal/StepText.css.js +1 -1
  127. package/dist-cjs/switch/Switch.css.js +1 -1
  128. package/dist-cjs/table/Table.css.js +1 -1
  129. package/dist-cjs/tabs/internal/overflow/useOverflowSelectionState.js +10 -2
  130. package/dist-cjs/tabs/internal/overflow/useOverflowSelectionState.js.map +1 -1
  131. package/dist-cjs/tag/Tag.css.js +1 -1
  132. package/dist-cjs/text/Text.css.js +1 -1
  133. package/dist-cjs/toast/Toast.css.js +1 -1
  134. package/dist-cjs/toggle-button/ToggleButton.js +8 -2
  135. package/dist-cjs/toggle-button/ToggleButton.js.map +1 -1
  136. package/dist-cjs/toggle-button-group/ToggleButtonGroup.js +71 -8
  137. package/dist-cjs/toggle-button-group/ToggleButtonGroup.js.map +1 -1
  138. package/dist-cjs/toggle-button-group/ToggleButtonGroupContext.js.map +1 -1
  139. package/dist-cjs/toggletip/ToggletipPanel.css.js +1 -1
  140. package/dist-cjs/tooltip/Tooltip.css.js +1 -1
  141. package/dist-cjs/vertical-navigation/VerticalNavigationItemContent.css.js +1 -1
  142. package/dist-cjs/vertical-navigation/VerticalNavigationSubMenu.css.js +1 -1
  143. package/dist-es/accordion/AccordionHeader.css.js +1 -1
  144. package/dist-es/aria-announcer/AriaAnnouncerProvider.js +8 -0
  145. package/dist-es/aria-announcer/AriaAnnouncerProvider.js.map +1 -1
  146. package/dist-es/avatar/Avatar.css.js +1 -1
  147. package/dist-es/badge/Badge.css.js +1 -1
  148. package/dist-es/banner/Banner.css.js +1 -1
  149. package/dist-es/breadcrumbs/Breadcrumb.css.js +1 -1
  150. package/dist-es/breadcrumbs/Breadcrumbs.css.js +1 -1
  151. package/dist-es/card/Card.css.js +1 -1
  152. package/dist-es/card/Card.js +4 -0
  153. package/dist-es/card/Card.js.map +1 -1
  154. package/dist-es/checkbox/Checkbox.css.js +1 -1
  155. package/dist-es/checkbox/CheckboxIcon.css.js +1 -1
  156. package/dist-es/combo-box/ComboBox.js +18 -36
  157. package/dist-es/combo-box/ComboBox.js.map +1 -1
  158. package/dist-es/combo-box/useComboBox.js +21 -21
  159. package/dist-es/combo-box/useComboBox.js.map +1 -1
  160. package/dist-es/drawer/Drawer.css.js +1 -1
  161. package/dist-es/drawer/Drawer.js +31 -6
  162. package/dist-es/drawer/Drawer.js.map +1 -1
  163. package/dist-es/drawer/DrawerCloseButton.js +1 -1
  164. package/dist-es/drawer/DrawerCloseButton.js.map +1 -1
  165. package/dist-es/drawer/DrawerContent.css.js +4 -0
  166. package/dist-es/drawer/DrawerContent.css.js.map +1 -0
  167. package/dist-es/drawer/DrawerContent.js +73 -0
  168. package/dist-es/drawer/DrawerContent.js.map +1 -0
  169. package/dist-es/drawer/DrawerContext.js +27 -0
  170. package/dist-es/drawer/DrawerContext.js.map +1 -0
  171. package/dist-es/drawer/DrawerFooter.css.js +4 -0
  172. package/dist-es/drawer/DrawerFooter.css.js.map +1 -0
  173. package/dist-es/drawer/DrawerFooter.js +28 -0
  174. package/dist-es/drawer/DrawerFooter.js.map +1 -0
  175. package/dist-es/drawer/DrawerHeader.css.js +4 -0
  176. package/dist-es/drawer/DrawerHeader.css.js.map +1 -0
  177. package/dist-es/drawer/DrawerHeader.js +93 -0
  178. package/dist-es/drawer/DrawerHeader.js.map +1 -0
  179. package/dist-es/drawer/hasDrawerSection.js +20 -0
  180. package/dist-es/drawer/hasDrawerSection.js.map +1 -0
  181. package/dist-es/dropdown/Dropdown.js +29 -30
  182. package/dist-es/dropdown/Dropdown.js.map +1 -1
  183. package/dist-es/file-drop-zone/FileDropZone.css.js +1 -1
  184. package/dist-es/form-field/FormField.css.js +1 -1
  185. package/dist-es/form-field/FormField.js +16 -1
  186. package/dist-es/form-field/FormField.js.map +1 -1
  187. package/dist-es/form-field/FormFieldHelperText.css.js +1 -1
  188. package/dist-es/form-field/FormFieldLabel.css.js +1 -1
  189. package/dist-es/form-field/FormFieldLabel.js +1 -1
  190. package/dist-es/form-field/FormFieldLabel.js.map +1 -1
  191. package/dist-es/index.js +5 -0
  192. package/dist-es/index.js.map +1 -1
  193. package/dist-es/input/Input.css.js +1 -1
  194. package/dist-es/interactable-card/InteractableCard.css.js +1 -1
  195. package/dist-es/interactable-card/InteractableCard.js +23 -7
  196. package/dist-es/interactable-card/InteractableCard.js.map +1 -1
  197. package/dist-es/interactable-card/InteractableCardGroup.js +72 -40
  198. package/dist-es/interactable-card/InteractableCardGroup.js.map +1 -1
  199. package/dist-es/interactable-card/InteractableCardGroupContext.js.map +1 -1
  200. package/dist-es/interactable-card/useInteractableCard.js +2 -3
  201. package/dist-es/interactable-card/useInteractableCard.js.map +1 -1
  202. package/dist-es/kbd/Kbd.css.js +1 -1
  203. package/dist-es/link/Link.css.js +1 -1
  204. package/dist-es/link-button/LinkButton.css.js +4 -0
  205. package/dist-es/link-button/LinkButton.css.js.map +1 -0
  206. package/dist-es/link-button/LinkButton.js +85 -0
  207. package/dist-es/link-button/LinkButton.js.map +1 -0
  208. package/dist-es/link-card/LinkCard.css.js +1 -1
  209. package/dist-es/link-card/LinkCard.js +4 -0
  210. package/dist-es/link-card/LinkCard.js.map +1 -1
  211. package/dist-es/list-box/ListBox.js +19 -26
  212. package/dist-es/list-box/ListBox.js.map +1 -1
  213. package/dist-es/list-control/ListControlNavigationKeys.js +69 -0
  214. package/dist-es/list-control/ListControlNavigationKeys.js.map +1 -0
  215. package/dist-es/list-control/ListControlOptionContext.js +44 -0
  216. package/dist-es/list-control/ListControlOptionContext.js.map +1 -0
  217. package/dist-es/list-control/ListControlOptionStore.js +153 -0
  218. package/dist-es/list-control/ListControlOptionStore.js.map +1 -0
  219. package/dist-es/list-control/ListControlProvider.js +37 -0
  220. package/dist-es/list-control/ListControlProvider.js.map +1 -0
  221. package/dist-es/list-control/ListControlRegistry.js +158 -0
  222. package/dist-es/list-control/ListControlRegistry.js.map +1 -0
  223. package/dist-es/list-control/ListControlState.js +137 -110
  224. package/dist-es/list-control/ListControlState.js.map +1 -1
  225. package/dist-es/mega-menu/MegaMenuGroupHeading.css.js +1 -1
  226. package/dist-es/mega-menu/MegaMenuListItem.css.js +1 -1
  227. package/dist-es/menu/MenuGroup.css.js +1 -1
  228. package/dist-es/menu/MenuItem.css.js +1 -1
  229. package/dist-es/menu/MenuItem.js +0 -1
  230. package/dist-es/menu/MenuItem.js.map +1 -1
  231. package/dist-es/navigation-item/NavigationItem.css.js +1 -1
  232. package/dist-es/number-input/NumberInput.js +2 -2
  233. package/dist-es/number-input/NumberInput.js.map +1 -1
  234. package/dist-es/option/Option.js +59 -40
  235. package/dist-es/option/Option.js.map +1 -1
  236. package/dist-es/option/OptionGroup.css.js +1 -1
  237. package/dist-es/overlay/Overlay.js +13 -3
  238. package/dist-es/overlay/Overlay.js.map +1 -1
  239. package/dist-es/overlay/OverlayContext.js +6 -0
  240. package/dist-es/overlay/OverlayContext.js.map +1 -1
  241. package/dist-es/overlay/OverlayFooter.css.js +4 -0
  242. package/dist-es/overlay/OverlayFooter.css.js.map +1 -0
  243. package/dist-es/overlay/OverlayFooter.js +28 -0
  244. package/dist-es/overlay/OverlayFooter.js.map +1 -0
  245. package/dist-es/overlay/OverlayHeader.css.js +1 -1
  246. package/dist-es/overlay/OverlayHeader.js +51 -11
  247. package/dist-es/overlay/OverlayHeader.js.map +1 -1
  248. package/dist-es/overlay/OverlayPanel.css.js +1 -1
  249. package/dist-es/overlay/OverlayPanel.js +20 -7
  250. package/dist-es/overlay/OverlayPanel.js.map +1 -1
  251. package/dist-es/overlay/OverlayPanelContent.css.js +1 -1
  252. package/dist-es/overlay/OverlayPanelContent.js +11 -13
  253. package/dist-es/overlay/OverlayPanelContent.js.map +1 -1
  254. package/dist-es/overlay/hasOverlaySection.js +22 -0
  255. package/dist-es/overlay/hasOverlaySection.js.map +1 -0
  256. package/dist-es/panel/Panel.css.js +1 -1
  257. package/dist-es/panel/Panel.js +13 -2
  258. package/dist-es/panel/Panel.js.map +1 -1
  259. package/dist-es/pill-input/PillInput.css.js +1 -1
  260. package/dist-es/pill-input/PillInput.js +2 -2
  261. package/dist-es/pill-input/PillInput.js.map +1 -1
  262. package/dist-es/radio-button/RadioButton.css.js +1 -1
  263. package/dist-es/radio-button/RadioButtonIcon.css.js +1 -1
  264. package/dist-es/rating/Rating.css.js +1 -1
  265. package/dist-es/slider/internal/SliderTrack.css.js +1 -1
  266. package/dist-es/stepper/internal/StepText.css.js +1 -1
  267. package/dist-es/switch/Switch.css.js +1 -1
  268. package/dist-es/table/Table.css.js +1 -1
  269. package/dist-es/tabs/internal/overflow/useOverflowSelectionState.js +10 -2
  270. package/dist-es/tabs/internal/overflow/useOverflowSelectionState.js.map +1 -1
  271. package/dist-es/tag/Tag.css.js +1 -1
  272. package/dist-es/text/Text.css.js +1 -1
  273. package/dist-es/toast/Toast.css.js +1 -1
  274. package/dist-es/toggle-button/ToggleButton.js +8 -2
  275. package/dist-es/toggle-button/ToggleButton.js.map +1 -1
  276. package/dist-es/toggle-button-group/ToggleButtonGroup.js +71 -8
  277. package/dist-es/toggle-button-group/ToggleButtonGroup.js.map +1 -1
  278. package/dist-es/toggle-button-group/ToggleButtonGroupContext.js.map +1 -1
  279. package/dist-es/toggletip/ToggletipPanel.css.js +1 -1
  280. package/dist-es/tooltip/Tooltip.css.js +1 -1
  281. package/dist-es/vertical-navigation/VerticalNavigationItemContent.css.js +1 -1
  282. package/dist-es/vertical-navigation/VerticalNavigationSubMenu.css.js +1 -1
  283. package/dist-types/card/Card.d.ts +10 -0
  284. package/dist-types/combo-box/useComboBox.d.ts +3 -6
  285. package/dist-types/drawer/Drawer.d.ts +1 -1
  286. package/dist-types/drawer/DrawerCloseButton.d.ts +3 -0
  287. package/dist-types/drawer/DrawerContent.d.ts +3 -0
  288. package/dist-types/drawer/DrawerContext.d.ts +9 -0
  289. package/dist-types/drawer/DrawerFooter.d.ts +3 -0
  290. package/dist-types/drawer/DrawerHeader.d.ts +24 -0
  291. package/dist-types/drawer/hasDrawerSection.d.ts +2 -0
  292. package/dist-types/drawer/index.d.ts +3 -0
  293. package/dist-types/index.d.ts +1 -0
  294. package/dist-types/interactable-card/InteractableCard.d.ts +9 -1
  295. package/dist-types/interactable-card/InteractableCardGroupContext.d.ts +2 -0
  296. package/dist-types/interactable-card/useInteractableCard.d.ts +1 -2
  297. package/dist-types/link-button/LinkButton.d.ts +26 -0
  298. package/dist-types/link-button/index.d.ts +1 -0
  299. package/dist-types/link-card/LinkCard.d.ts +8 -0
  300. package/dist-types/list-control/ListControlNavigationKeys.d.ts +30 -0
  301. package/dist-types/list-control/ListControlOptionContext.d.ts +18 -0
  302. package/dist-types/list-control/ListControlOptionStore.d.ts +17 -0
  303. package/dist-types/list-control/ListControlProvider.d.ts +11 -0
  304. package/dist-types/list-control/ListControlRegistry.d.ts +22 -0
  305. package/dist-types/list-control/ListControlState.d.ts +6 -6
  306. package/dist-types/option/Option.d.ts +3 -1
  307. package/dist-types/overlay/Overlay.d.ts +2 -1
  308. package/dist-types/overlay/OverlayContext.d.ts +4 -0
  309. package/dist-types/overlay/OverlayFooter.d.ts +4 -0
  310. package/dist-types/overlay/hasOverlaySection.d.ts +2 -0
  311. package/dist-types/overlay/index.d.ts +1 -0
  312. package/dist-types/panel/Panel.d.ts +4 -0
  313. package/dist-types/toggle-button-group/ToggleButtonGroupContext.d.ts +2 -1
  314. package/dist-types/utils/useIsomorphicLayoutEffect.d.ts +2 -2
  315. package/package.json +14 -10
@@ -6,6 +6,7 @@ import { forwardRef, useRef, useState, useCallback, useMemo } from 'react';
6
6
  import { makePrefixer } from '../utils/makePrefixer.js';
7
7
  import { ownerDocument } from '../utils/ownerDocument.js';
8
8
  import { useControlled } from '../utils/useControlled.js';
9
+ import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect.js';
9
10
  import '../utils/useFloatingUI/useFloatingUI.js';
10
11
  import { useForkRef } from '../utils/useForkRef.js';
11
12
  import '../utils/useId.js';
@@ -15,6 +16,19 @@ import css_248z from './ToggleButtonGroup.css.js';
15
16
  import { ToggleButtonGroupContext } from './ToggleButtonGroupContext.js';
16
17
 
17
18
  const withBaseName = makePrefixer("saltToggleButtonGroup");
19
+ function isSameValue(a, b) {
20
+ if (Array.isArray(a) && Array.isArray(b)) {
21
+ return a.length === b.length && a.every((value, index) => value === b[index]);
22
+ }
23
+ return a === b;
24
+ }
25
+ const sortButtons = (buttons) => [...buttons].sort((buttonA, buttonB) => {
26
+ const position = buttonA.element.compareDocumentPosition(buttonB.element);
27
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
28
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;
29
+ return 0;
30
+ });
31
+ const buttonsAreEqual = (buttonsA, buttonsB) => buttonsA.length === buttonsB.length && buttonsA.every((button, index) => button === buttonsB[index]);
18
32
  const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
19
33
  const {
20
34
  appearance,
@@ -45,11 +59,39 @@ const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
45
59
  state: "value"
46
60
  });
47
61
  const [focused, setFocused] = useState(value);
62
+ const [enabledButtons, setEnabledButtons] = useState([]);
63
+ const registerButton = useCallback(
64
+ (buttonValue, element) => {
65
+ const button = { element, value: buttonValue };
66
+ setEnabledButtons(
67
+ (currentButtons) => sortButtons([
68
+ ...currentButtons.filter(
69
+ (currentButton) => currentButton.element !== element
70
+ ),
71
+ button
72
+ ])
73
+ );
74
+ return () => {
75
+ setEnabledButtons(
76
+ (currentButtons) => currentButtons.includes(button) ? currentButtons.filter(
77
+ (registeredButton) => registeredButton !== button
78
+ ) : currentButtons
79
+ );
80
+ };
81
+ },
82
+ []
83
+ );
84
+ useIsomorphicLayoutEffect(() => {
85
+ setEnabledButtons((currentButtons) => {
86
+ const sortedButtons = sortButtons(currentButtons);
87
+ return buttonsAreEqual(currentButtons, sortedButtons) ? currentButtons : sortedButtons;
88
+ });
89
+ }, [children]);
48
90
  const select = useCallback(
49
- (event) => {
50
- const newValue = event.currentTarget.value;
91
+ (event, ...values) => {
92
+ const newValue = values.length === 0 ? event.currentTarget.value : values[0];
51
93
  setValue(newValue);
52
- if (value !== newValue) {
94
+ if (!isSameValue(value, newValue)) {
53
95
  onChange == null ? void 0 : onChange(event);
54
96
  }
55
97
  },
@@ -57,7 +99,7 @@ const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
57
99
  );
58
100
  const isSelected = useCallback(
59
101
  (id) => {
60
- return value === id;
102
+ return isSameValue(value, id);
61
103
  },
62
104
  [value]
63
105
  );
@@ -66,9 +108,18 @@ const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
66
108
  }, []);
67
109
  const isFocused = useCallback(
68
110
  (id) => {
69
- return focused === id || !focused;
111
+ if (enabledButtons.length === 0) {
112
+ return focused === id || focused === void 0 || focused === "";
113
+ }
114
+ const hasFocusTarget = enabledButtons.some(
115
+ (button) => isSameValue(button.value, focused)
116
+ );
117
+ return isSameValue(
118
+ hasFocusTarget ? focused : enabledButtons[0].value,
119
+ id
120
+ );
70
121
  },
71
- [focused]
122
+ [focused, enabledButtons]
72
123
  );
73
124
  const contextValue = useMemo(
74
125
  () => ({
@@ -79,6 +130,7 @@ const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
79
130
  isSelected,
80
131
  orientation,
81
132
  readOnly,
133
+ registerButton,
82
134
  select,
83
135
  sentiment
84
136
  }),
@@ -90,12 +142,17 @@ const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
90
142
  isSelected,
91
143
  orientation,
92
144
  readOnly,
145
+ registerButton,
93
146
  select,
94
147
  sentiment
95
148
  ]
96
149
  );
97
150
  const handleKeyDown = (event) => {
98
151
  var _a, _b, _c;
152
+ if (event.altKey || event.ctrlKey || event.metaKey) {
153
+ onKeyDown == null ? void 0 : onKeyDown(event);
154
+ return;
155
+ }
99
156
  const elements = Array.from(
100
157
  ((_a = groupRef.current) == null ? void 0 : _a.querySelectorAll("button:not([disabled])")) ?? []
101
158
  );
@@ -104,11 +161,17 @@ const ToggleButtonGroup = forwardRef(function ToggleButtonGroup2(props, ref) {
104
161
  switch (event.key) {
105
162
  case "ArrowDown":
106
163
  case "ArrowRight":
107
- (_b = elements[(currentIndex + 1) % elements.length]) == null ? void 0 : _b.focus();
164
+ if (elements.length > 0) {
165
+ event.preventDefault();
166
+ (_b = elements[(currentIndex + 1) % elements.length]) == null ? void 0 : _b.focus();
167
+ }
108
168
  break;
109
169
  case "ArrowUp":
110
170
  case "ArrowLeft":
111
- (_c = elements[(currentIndex - 1 + elements.length) % elements.length]) == null ? void 0 : _c.focus();
171
+ if (elements.length > 0) {
172
+ event.preventDefault();
173
+ (_c = elements[(currentIndex - 1 + elements.length) % elements.length]) == null ? void 0 : _c.focus();
174
+ }
112
175
  break;
113
176
  }
114
177
  onKeyDown == null ? void 0 : onKeyDown(event);
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleButtonGroup.js","sources":["../src/toggle-button-group/ToggleButtonGroup.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport type { ButtonAppearance, ButtonSentiment } from \"../button\";\nimport {\n makePrefixer,\n ownerDocument,\n useControlled,\n useForkRef,\n} from \"../utils\";\nimport toggleButtonGroupCss from \"./ToggleButtonGroup.css\";\nimport {\n ToggleButtonGroupContext,\n type Value,\n} from \"./ToggleButtonGroupContext\";\n\nexport interface ToggleButtonGroupProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * The appearance of all the toggle buttons within the group.\n * @default solid\n */\n appearance?: Extract<ButtonAppearance, \"bordered\" | \"solid\">;\n /**\n * The default value. Use when the component is not controlled.\n */\n defaultValue?: Value;\n /**\n * If `true`, the Toggle Button Group will be disabled.\n */\n disabled?: boolean;\n /**\n * Value of the toggle button group, to be used when the component is controlled.\n */\n value?: Value;\n /**\n * Callback fired when the selection changes.\n */\n onChange?: (event: SyntheticEvent<HTMLButtonElement>) => void;\n /**\n * If `true`, the toggle button group will be read-only.\n */\n readOnly?: boolean;\n /**\n * The orientation of the toggle buttons.\n */\n orientation?: \"horizontal\" | \"vertical\";\n /**\n * The visual sentimenent of all the toggle buttons within the group.\n * @default neutral\n */\n sentiment?: ButtonSentiment;\n}\n\nconst withBaseName = makePrefixer(\"saltToggleButtonGroup\");\n\nexport const ToggleButtonGroup = forwardRef<\n HTMLDivElement,\n ToggleButtonGroupProps\n>(function ToggleButtonGroup(props, ref) {\n const {\n appearance,\n children,\n className,\n value: valueProp,\n defaultValue,\n disabled,\n onChange,\n onKeyDown,\n orientation = \"horizontal\",\n readOnly,\n sentiment,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-toggle-button-group\",\n css: toggleButtonGroupCss,\n window: targetWindow,\n });\n\n const groupRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(ref, groupRef);\n\n const [value, setValue] = useControlled({\n default: defaultValue,\n controlled: valueProp,\n name: \"ToggleButtonGroup\",\n state: \"value\",\n });\n const [focused, setFocused] = useState<Value>(value);\n\n const select = useCallback(\n (event: SyntheticEvent<HTMLButtonElement>) => {\n const newValue = event.currentTarget.value;\n setValue(newValue);\n if (value !== newValue) {\n onChange?.(event);\n }\n },\n [onChange, value],\n );\n\n const isSelected = useCallback(\n (id: Value) => {\n return value === id;\n },\n [value],\n );\n\n const focus = useCallback((id: Value) => {\n setFocused(id);\n }, []);\n\n const isFocused = useCallback(\n (id: Value) => {\n return focused === id || !focused;\n },\n [focused],\n );\n\n const contextValue = useMemo(\n () => ({\n appearance,\n disabled,\n focus,\n isFocused,\n isSelected,\n orientation,\n readOnly,\n select,\n sentiment,\n }),\n [\n appearance,\n disabled,\n focus,\n isFocused,\n isSelected,\n orientation,\n readOnly,\n select,\n sentiment,\n ],\n );\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const elements: HTMLElement[] = Array.from(\n groupRef.current?.querySelectorAll(\"button:not([disabled])\") ?? [],\n );\n\n const doc = ownerDocument(groupRef.current);\n\n const currentIndex = elements.indexOf(doc.activeElement as HTMLElement);\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n elements[(currentIndex + 1) % elements.length]?.focus();\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n elements[\n (currentIndex - 1 + elements.length) % elements.length\n ]?.focus();\n break;\n }\n\n onKeyDown?.(event);\n };\n\n return (\n <ToggleButtonGroupContext.Provider value={contextValue}>\n <div\n aria-disabled={disabled}\n aria-readonly={readOnly}\n className={clsx(\n withBaseName(),\n withBaseName(orientation),\n disabled && withBaseName(\"disabled\"),\n readOnly && withBaseName(\"readOnly\"),\n className,\n )}\n role=\"radiogroup\"\n ref={handleRef}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {children}\n </div>\n </ToggleButtonGroupContext.Provider>\n );\n});\n"],"names":["ToggleButtonGroup","toggleButtonGroupCss"],"mappings":";;;;;;;;;;;;;;;;AAiEA,MAAM,YAAA,GAAe,aAAa,uBAAuB,CAAA;AAElD,MAAM,iBAAA,GAAoB,UAAA,CAG/B,SAASA,kBAAAA,CAAkB,OAAO,GAAA,EAAK;AACvC,EAAA,MAAM;AAAA,IACJ,UAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA,EAAO,SAAA;AAAA,IACP,YAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA,GAAc,YAAA;AAAA,IACd,QAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAG;AAAA,GACL,GAAI,KAAA;AAEJ,EAAA,MAAM,eAAe,SAAA,EAAU;AAC/B,EAAA,wBAAA,CAAyB;AAAA,IACvB,MAAA,EAAQ,0BAAA;AAAA,IACR,GAAA,EAAKC,QAAA;AAAA,IACL,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,OAAuB,IAAI,CAAA;AAC5C,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,EAAK,QAAQ,CAAA;AAE1C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,aAAA,CAAc;AAAA,IACtC,OAAA,EAAS,YAAA;AAAA,IACT,UAAA,EAAY,SAAA;AAAA,IACZ,IAAA,EAAM,mBAAA;AAAA,IACN,KAAA,EAAO;AAAA,GACR,CAAA;AACD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAgB,KAAK,CAAA;AAEnD,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,IACb,CAAC,KAAA,KAA6C;AAC5C,MAAA,MAAM,QAAA,GAAW,MAAM,aAAA,CAAc,KAAA;AACrC,MAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,MAAA,IAAI,UAAU,QAAA,EAAU;AACtB,QAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,KAAA,CAAA;AAAA,MACb;AAAA,IACF,CAAA;AAAA,IACA,CAAC,UAAU,KAAK;AAAA,GAClB;AAEA,EAAA,MAAM,UAAA,GAAa,WAAA;AAAA,IACjB,CAAC,EAAA,KAAc;AACb,MAAA,OAAO,KAAA,KAAU,EAAA;AAAA,IACnB,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AAEA,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,CAAC,EAAA,KAAc;AACvC,IAAA,UAAA,CAAW,EAAE,CAAA;AAAA,EACf,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAChB,CAAC,EAAA,KAAc;AACb,MAAA,OAAO,OAAA,KAAY,MAAM,CAAC,OAAA;AAAA,IAC5B,CAAA;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAEA,EAAA,MAAM,YAAA,GAAe,OAAA;AAAA,IACnB,OAAO;AAAA,MACL,UAAA;AAAA,MACA,QAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,UAAA;AAAA,MACA,QAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAyC;AA9JlE,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA+JI,IAAA,MAAM,WAA0B,KAAA,CAAM,IAAA;AAAA,MAAA,CAAA,CACpC,EAAA,GAAA,QAAA,CAAS,OAAA,KAAT,IAAA,GAAA,MAAA,GAAA,EAAA,CAAkB,gBAAA,CAAiB,8BAA6B;AAAC,KACnE;AAEA,IAAA,MAAM,GAAA,GAAM,aAAA,CAAc,QAAA,CAAS,OAAO,CAAA;AAE1C,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAA4B,CAAA;AACtE,IAAA,QAAQ,MAAM,GAAA;AAAK,MACjB,KAAK,WAAA;AAAA,MACL,KAAK,YAAA;AACH,QAAA,CAAA,EAAA,GAAA,QAAA,CAAA,CAAU,YAAA,GAAe,CAAA,IAAK,QAAA,CAAS,MAAM,MAA7C,IAAA,GAAA,MAAA,GAAA,EAAA,CAAgD,KAAA,EAAA;AAChD,QAAA;AAAA,MACF,KAAK,SAAA;AAAA,MACL,KAAK,WAAA;AACH,QAAA,CAAA,EAAA,GAAA,QAAA,CAAA,CACG,eAAe,CAAA,GAAI,QAAA,CAAS,UAAU,QAAA,CAAS,MAClD,MAFA,IAAA,GAAA,MAAA,GAAA,EAAA,CAEG,KAAA,EAAA;AACH,QAAA;AAAA;AAGJ,IAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAY,KAAA,CAAA;AAAA,EACd,CAAA;AAEA,EAAA,uBACE,GAAA,CAAC,wBAAA,CAAyB,QAAA,EAAzB,EAAkC,OAAO,YAAA,EACxC,QAAA,kBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,eAAA,EAAe,QAAA;AAAA,MACf,eAAA,EAAe,QAAA;AAAA,MACf,SAAA,EAAW,IAAA;AAAA,QACT,YAAA,EAAa;AAAA,QACb,aAAa,WAAW,CAAA;AAAA,QACxB,QAAA,IAAY,aAAa,UAAU,CAAA;AAAA,QACnC,QAAA,IAAY,aAAa,UAAU,CAAA;AAAA,QACnC;AAAA,OACF;AAAA,MACA,IAAA,EAAK,YAAA;AAAA,MACL,GAAA,EAAK,SAAA;AAAA,MACL,SAAA,EAAW,aAAA;AAAA,MACV,GAAG,IAAA;AAAA,MAEH;AAAA;AAAA,GACH,EACF,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"ToggleButtonGroup.js","sources":["../src/toggle-button-group/ToggleButtonGroup.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport type { ButtonAppearance, ButtonSentiment } from \"../button\";\nimport {\n makePrefixer,\n ownerDocument,\n useControlled,\n useForkRef,\n useIsomorphicLayoutEffect,\n} from \"../utils\";\nimport toggleButtonGroupCss from \"./ToggleButtonGroup.css\";\nimport {\n ToggleButtonGroupContext,\n type Value,\n} from \"./ToggleButtonGroupContext\";\n\nexport interface ToggleButtonGroupProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /**\n * The appearance of all the toggle buttons within the group.\n * @default solid\n */\n appearance?: Extract<ButtonAppearance, \"bordered\" | \"solid\">;\n /**\n * The default value. Use when the component is not controlled.\n */\n defaultValue?: Value;\n /**\n * If `true`, the Toggle Button Group will be disabled.\n */\n disabled?: boolean;\n /**\n * Value of the toggle button group, to be used when the component is controlled.\n */\n value?: Value;\n /**\n * Callback fired when the selection changes.\n */\n onChange?: (event: SyntheticEvent<HTMLButtonElement>) => void;\n /**\n * If `true`, the toggle button group will be read-only.\n */\n readOnly?: boolean;\n /**\n * The orientation of the toggle buttons.\n */\n orientation?: \"horizontal\" | \"vertical\";\n /**\n * The visual sentimenent of all the toggle buttons within the group.\n * @default neutral\n */\n sentiment?: ButtonSentiment;\n}\n\nconst withBaseName = makePrefixer(\"saltToggleButtonGroup\");\n\nfunction isSameValue(a: Value, b: Value) {\n if (Array.isArray(a) && Array.isArray(b)) {\n return (\n a.length === b.length && a.every((value, index) => value === b[index])\n );\n }\n return a === b;\n}\n\ninterface RegisteredButton {\n element: HTMLElement;\n value: Value;\n}\n\nconst sortButtons = (buttons: RegisteredButton[]) =>\n [...buttons].sort((buttonA, buttonB) => {\n const position = buttonA.element.compareDocumentPosition(buttonB.element);\n if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;\n if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;\n return 0;\n });\n\nconst buttonsAreEqual = (\n buttonsA: RegisteredButton[],\n buttonsB: RegisteredButton[],\n) =>\n buttonsA.length === buttonsB.length &&\n buttonsA.every((button, index) => button === buttonsB[index]);\n\nexport const ToggleButtonGroup = forwardRef<\n HTMLDivElement,\n ToggleButtonGroupProps\n>(function ToggleButtonGroup(props, ref) {\n const {\n appearance,\n children,\n className,\n value: valueProp,\n defaultValue,\n disabled,\n onChange,\n onKeyDown,\n orientation = \"horizontal\",\n readOnly,\n sentiment,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-toggle-button-group\",\n css: toggleButtonGroupCss,\n window: targetWindow,\n });\n\n const groupRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(ref, groupRef);\n\n const [value, setValue] = useControlled({\n default: defaultValue,\n controlled: valueProp,\n name: \"ToggleButtonGroup\",\n state: \"value\",\n });\n const [focused, setFocused] = useState<Value>(value);\n const [enabledButtons, setEnabledButtons] = useState<RegisteredButton[]>([]);\n\n const registerButton = useCallback(\n (buttonValue: Value, element: HTMLElement) => {\n const button = { element, value: buttonValue };\n setEnabledButtons((currentButtons) =>\n sortButtons([\n ...currentButtons.filter(\n (currentButton) => currentButton.element !== element,\n ),\n button,\n ]),\n );\n\n return () => {\n setEnabledButtons((currentButtons) =>\n currentButtons.includes(button)\n ? currentButtons.filter(\n (registeredButton) => registeredButton !== button,\n )\n : currentButtons,\n );\n };\n },\n [],\n );\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: re-sorts registered buttons after children move.\n useIsomorphicLayoutEffect(() => {\n setEnabledButtons((currentButtons) => {\n const sortedButtons = sortButtons(currentButtons);\n return buttonsAreEqual(currentButtons, sortedButtons)\n ? currentButtons\n : sortedButtons;\n });\n }, [children]);\n\n const select = useCallback(\n (\n event: SyntheticEvent<HTMLButtonElement>,\n ...values: [newValue?: Value]\n ) => {\n const newValue =\n values.length === 0 ? event.currentTarget.value : values[0];\n setValue(newValue);\n if (!isSameValue(value, newValue)) {\n onChange?.(event);\n }\n },\n [onChange, value],\n );\n\n const isSelected = useCallback(\n (id: Value) => {\n return isSameValue(value, id);\n },\n [value],\n );\n\n const focus = useCallback((id: Value) => {\n setFocused(id);\n }, []);\n\n const isFocused = useCallback(\n (id: Value) => {\n // Trust the focused value until buttons register (e.g. server rendering).\n if (enabledButtons.length === 0) {\n return focused === id || focused === undefined || focused === \"\";\n }\n\n const hasFocusTarget = enabledButtons.some((button) =>\n isSameValue(button.value, focused),\n );\n\n return isSameValue(\n hasFocusTarget ? focused : enabledButtons[0].value,\n id,\n );\n },\n [focused, enabledButtons],\n );\n\n const contextValue = useMemo(\n () => ({\n appearance,\n disabled,\n focus,\n isFocused,\n isSelected,\n orientation,\n readOnly,\n registerButton,\n select,\n sentiment,\n }),\n [\n appearance,\n disabled,\n focus,\n isFocused,\n isSelected,\n orientation,\n readOnly,\n registerButton,\n select,\n sentiment,\n ],\n );\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n // Leave modified arrow keys (e.g. browser history shortcuts) to the browser.\n if (event.altKey || event.ctrlKey || event.metaKey) {\n onKeyDown?.(event);\n return;\n }\n\n const elements: HTMLElement[] = Array.from(\n groupRef.current?.querySelectorAll(\"button:not([disabled])\") ?? [],\n );\n\n const doc = ownerDocument(groupRef.current);\n\n const currentIndex = elements.indexOf(doc.activeElement as HTMLElement);\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n if (elements.length > 0) {\n event.preventDefault();\n elements[(currentIndex + 1) % elements.length]?.focus();\n }\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n if (elements.length > 0) {\n event.preventDefault();\n elements[\n (currentIndex - 1 + elements.length) % elements.length\n ]?.focus();\n }\n break;\n }\n\n onKeyDown?.(event);\n };\n\n return (\n <ToggleButtonGroupContext.Provider value={contextValue}>\n <div\n aria-disabled={disabled}\n aria-readonly={readOnly}\n className={clsx(\n withBaseName(),\n withBaseName(orientation),\n disabled && withBaseName(\"disabled\"),\n readOnly && withBaseName(\"readOnly\"),\n className,\n )}\n role=\"radiogroup\"\n ref={handleRef}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {children}\n </div>\n </ToggleButtonGroupContext.Provider>\n );\n});\n"],"names":["ToggleButtonGroup","toggleButtonGroupCss"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleButtonGroupContext.js","sources":["../src/toggle-button-group/ToggleButtonGroupContext.ts"],"sourcesContent":["import { type SyntheticEvent, useContext } from \"react\";\nimport type { ButtonAppearance, ButtonSentiment } from \"../button\";\nimport { createContext } from \"../utils\";\n\nexport type Value = string | readonly string[] | number | undefined;\n\nexport interface ToggleButtonGroupContextValue {\n appearance?: Extract<ButtonAppearance, \"bordered\" | \"solid\">;\n disabled?: boolean;\n focus: (id: Value) => void;\n isFocused: (id: Value) => boolean;\n isSelected: (id: Value) => boolean;\n orientation: \"horizontal\" | \"vertical\";\n readOnly?: boolean;\n select: (event: SyntheticEvent<HTMLButtonElement>) => void;\n sentiment?: ButtonSentiment;\n}\n\nexport const ToggleButtonGroupContext = createContext<\n ToggleButtonGroupContextValue | undefined\n>(\"ToggleButtonGroupContext\", undefined);\n\nexport function useToggleButtonGroup() {\n return useContext(ToggleButtonGroupContext);\n}\n"],"names":[],"mappings":";;;;;;;;;AAkBO,MAAM,wBAAA,GAA2B,aAAA,CAEtC,0BAAA,EAA4B,MAAS;AAEhC,SAAS,oBAAA,GAAuB;AACrC,EAAA,OAAO,WAAW,wBAAwB,CAAA;AAC5C;;;;"}
1
+ {"version":3,"file":"ToggleButtonGroupContext.js","sources":["../src/toggle-button-group/ToggleButtonGroupContext.ts"],"sourcesContent":["import { type SyntheticEvent, useContext } from \"react\";\nimport type { ButtonAppearance, ButtonSentiment } from \"../button\";\nimport { createContext } from \"../utils\";\n\nexport type Value = string | readonly string[] | number | undefined;\n\nexport interface ToggleButtonGroupContextValue {\n appearance?: Extract<ButtonAppearance, \"bordered\" | \"solid\">;\n disabled?: boolean;\n focus: (id: Value) => void;\n isFocused: (id: Value) => boolean;\n isSelected: (id: Value) => boolean;\n orientation: \"horizontal\" | \"vertical\";\n readOnly?: boolean;\n registerButton: (value: Value, element: HTMLElement) => () => void;\n select: (event: SyntheticEvent<HTMLButtonElement>, value?: Value) => void;\n sentiment?: ButtonSentiment;\n}\n\nexport const ToggleButtonGroupContext = createContext<\n ToggleButtonGroupContextValue | undefined\n>(\"ToggleButtonGroupContext\", undefined);\n\nexport function useToggleButtonGroup() {\n return useContext(ToggleButtonGroupContext);\n}\n"],"names":[],"mappings":";;;;;;;;;AAmBO,MAAM,wBAAA,GAA2B,aAAA,CAEtC,0BAAA,EAA4B,MAAS;AAEhC,SAAS,oBAAA,GAAuB;AACrC,EAAA,OAAO,WAAW,wBAAwB,CAAA;AAC5C;;;;"}
@@ -1,4 +1,4 @@
1
- var css_248z = ".saltToggletipPanel {\n --toggletip-background: var(--salt-container-primary-background);\n --toggletip-borderColor: var(--salt-container-bold-borderColor);\n\n box-sizing: border-box;\n padding: var(--salt-spacing-100);\n\n font-family: var(--salt-text-fontFamily);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n line-height: var(--salt-text-lineHeight);\n\n border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--toggletip-borderColor);\n border-radius: var(--salt-palette-corner-weak);\n\n background: var(--toggletip-background);\n box-shadow: var(--salt-overlayable-shadow-popout);\n\n color: var(--salt-content-primary-foreground);\n z-index: var(--salt-zIndex-flyover);\n\n max-width: 45ch;\n max-height: 100vh;\n}\n\n.saltToggletipPanel-content {\n max-height: 100%;\n overflow-y: auto;\n}\n\n.saltToggletipPanel-content:focus-visible {\n outline-offset: var(--salt-spacing-fixed-100);\n}\n";
1
+ var css_248z = ".saltToggletipPanel {\n --toggletip-background: var(--salt-container-primary-background);\n --toggletip-borderColor: var(--salt-container-bold-borderColor);\n\n box-sizing: border-box;\n padding: var(--salt-spacing-100);\n\n font-family: var(--salt-text-fontFamily);\n font-size: var(--salt-text-fontSize);\n font-weight: var(--salt-text-fontWeight);\n line-height: var(--salt-text-lineHeight);\n letter-spacing: var(--salt-text-letterSpacing);\n\n border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--toggletip-borderColor);\n border-radius: var(--salt-palette-corner-weak);\n\n background: var(--toggletip-background);\n box-shadow: var(--salt-overlayable-shadow-popout);\n\n color: var(--salt-content-primary-foreground);\n z-index: var(--salt-zIndex-flyover);\n\n max-width: 45ch;\n max-height: 100vh;\n}\n\n.saltToggletipPanel-content {\n max-height: 100%;\n overflow-y: auto;\n}\n\n.saltToggletipPanel-content:focus-visible {\n outline-offset: var(--salt-spacing-fixed-100);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=ToggletipPanel.css.js.map
@@ -1,4 +1,4 @@
1
- var css_248z = "/* Styles applied to root component */\n.saltTooltip {\n --tooltip-background: var(--saltTooltip-background, var(--salt-container-primary-background));\n --tooltip-zIndex: var(--saltTooltip-zIndex, var(--salt-zIndex-flyover));\n /* apply icon margin based on the text line height so it's aligned on all densities */\n --tooltip-icon-marginTop: calc((var(--salt-text-lineHeight) - max(var(--salt-size-icon), 12px)) / 2);\n --tooltip-status-borderColor: var(--salt-container-bold-borderColor);\n /* Single line height should be size-base */\n --tooltip-borderWidth: var(--salt-size-fixed-100);\n --tooltip-padding: calc(var(--salt-spacing-75) - var(--tooltip-borderWidth)) var(--salt-spacing-100);\n}\n\n.saltTooltip {\n box-sizing: border-box;\n background: var(--tooltip-background);\n border-color: var(--saltTooltip-borderColor, var(--tooltip-status-borderColor));\n border-style: var(--saltTooltip-borderStyle, var(--salt-borderStyle-solid));\n border-width: var(--saltTooltip-borderWidth, var(--tooltip-borderWidth));\n border-radius: var(--saltTooltip-borderRadius, var(--salt-palette-corner-weak, 0));\n box-shadow: var(--saltTooltip-shadow, var(--salt-overlayable-shadow-popout));\n color: var(--saltTooltip-text-color, var(--salt-content-primary-foreground));\n font-family: var(--salt-text-fontFamily);\n font-size: var(--saltTooltip-fontSize, var(--salt-text-fontSize));\n font-weight: var(--saltTooltip-fontWeight, var(--salt-text-fontWeight));\n line-height: var(--saltTooltip-lineHeight, var(--salt-text-lineHeight));\n max-width: var(--saltTooltip-maxWidth, 60ch);\n padding: var(--saltTooltip-padding, var(--tooltip-padding));\n position: relative;\n text-align: var(--saltTooltip-textAlign, left);\n z-index: var(--tooltip-zIndex);\n}\n\n/* Styles applied to container */\n.saltTooltip-container {\n display: flex;\n align-items: baseline;\n position: relative;\n}\n\n/* Styles applied to content */\n.saltTooltip-content {\n overflow: hidden;\n}\n\n/* Styles applied to status indicator */\n.saltTooltip-icon {\n --saltIcon-margin: var(--tooltip-icon-marginTop) var(--salt-spacing-75) 0 0;\n vertical-align: top;\n align-self: flex-start;\n}\n\n/* Styles applied when status = \"info\" */\n.saltTooltip-info {\n --tooltip-status-borderColor: var(--salt-status-info-borderColor);\n}\n\n/* Styles applied when status = \"error\" */\n.saltTooltip-error {\n --tooltip-status-borderColor: var(--salt-status-error-borderColor);\n}\n\n/* Styles applied when status = \"warning\" */\n.saltTooltip-warning {\n --tooltip-status-borderColor: var(--salt-status-warning-borderColor);\n}\n\n/* Styles applied when status = \"success\" */\n.saltTooltip-success {\n --tooltip-status-borderColor: var(--salt-status-success-borderColor);\n}\n";
1
+ var css_248z = "/* Styles applied to root component */\n.saltTooltip {\n --tooltip-background: var(--saltTooltip-background, var(--salt-container-primary-background));\n --tooltip-zIndex: var(--saltTooltip-zIndex, var(--salt-zIndex-flyover));\n /* apply icon margin based on the text line height so it's aligned on all densities */\n --tooltip-icon-marginTop: calc((var(--salt-text-lineHeight) - max(var(--salt-size-icon), 12px)) / 2);\n --tooltip-status-borderColor: var(--salt-container-bold-borderColor);\n /* Single line height should be size-base */\n --tooltip-borderWidth: var(--salt-size-fixed-100);\n --tooltip-padding: calc(var(--salt-spacing-75) - var(--tooltip-borderWidth)) var(--salt-spacing-100);\n}\n\n.saltTooltip {\n box-sizing: border-box;\n background: var(--tooltip-background);\n border-color: var(--saltTooltip-borderColor, var(--tooltip-status-borderColor));\n border-style: var(--saltTooltip-borderStyle, var(--salt-borderStyle-solid));\n border-width: var(--saltTooltip-borderWidth, var(--tooltip-borderWidth));\n border-radius: var(--saltTooltip-borderRadius, var(--salt-palette-corner-weak, 0));\n box-shadow: var(--saltTooltip-shadow, var(--salt-overlayable-shadow-popout));\n color: var(--saltTooltip-text-color, var(--salt-content-primary-foreground));\n font-family: var(--salt-text-fontFamily);\n font-size: var(--saltTooltip-fontSize, var(--salt-text-fontSize));\n font-weight: var(--saltTooltip-fontWeight, var(--salt-text-fontWeight));\n line-height: var(--saltTooltip-lineHeight, var(--salt-text-lineHeight));\n letter-spacing: var(--salt-text-letterSpacing);\n max-width: var(--saltTooltip-maxWidth, 60ch);\n padding: var(--saltTooltip-padding, var(--tooltip-padding));\n position: relative;\n text-align: var(--saltTooltip-textAlign, left);\n z-index: var(--tooltip-zIndex);\n}\n\n/* Styles applied to container */\n.saltTooltip-container {\n display: flex;\n align-items: baseline;\n position: relative;\n}\n\n/* Styles applied to content */\n.saltTooltip-content {\n overflow: hidden;\n}\n\n/* Styles applied to status indicator */\n.saltTooltip-icon {\n --saltIcon-margin: var(--tooltip-icon-marginTop) var(--salt-spacing-75) 0 0;\n vertical-align: top;\n align-self: flex-start;\n}\n\n/* Styles applied when status = \"info\" */\n.saltTooltip-info {\n --tooltip-status-borderColor: var(--salt-status-info-borderColor);\n}\n\n/* Styles applied when status = \"error\" */\n.saltTooltip-error {\n --tooltip-status-borderColor: var(--salt-status-error-borderColor);\n}\n\n/* Styles applied when status = \"warning\" */\n.saltTooltip-warning {\n --tooltip-status-borderColor: var(--salt-status-warning-borderColor);\n}\n\n/* Styles applied when status = \"success\" */\n.saltTooltip-success {\n --tooltip-status-borderColor: var(--salt-status-success-borderColor);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=Tooltip.css.js.map
@@ -1,4 +1,4 @@
1
- var css_248z = ".saltVerticalNavigationItemContent {\n --verticalNavigationItem-iconPadding: calc(var(--saltVerticalNavigationItem-iconPaddingMultiplier, 0) * (var(--salt-size-icon) + var(--salt-spacing-100)));\n --verticalNavigationItem-depthPadding: calc(var(--salt-spacing-100) * max(0, calc(var(--verticalNavigationItem-depth, 0) - 1)));\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent {\n --verticalNavigationItem-paddingLeft: calc(var(--salt-spacing-150) + var(--salt-size-indicator) + var(--verticalNavigationItem-depthPadding) + var(--verticalNavigationItem-iconPadding));\n --verticalNavigationItem-paddingBlock: var(--salt-spacing-50);\n}\n\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent {\n --verticalNavigationItem-paddingLeft: calc(var(--salt-spacing-100) + var(--verticalNavigationItem-depthPadding) + var(--verticalNavigationItem-iconPadding));\n --verticalNavigationItem-paddingBlock: calc(var(--salt-spacing-50) - var(--salt-size-fixed-100));\n}\n\n.saltVerticalNavigationItemContent {\n display: flex;\n flex-direction: row;\n gap: var(--salt-spacing-100);\n appearance: none;\n -webkit-appearance: none;\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n min-width: 4em;\n padding: var(--verticalNavigationItem-paddingBlock) var(--salt-spacing-100) var(--verticalNavigationItem-paddingBlock) var(--verticalNavigationItem-paddingLeft);\n position: relative;\n flex-shrink: 0;\n box-sizing: border-box;\n border-radius: var(--salt-palette-corner-weak, 0);\n overflow: hidden;\n\n cursor: var(--salt-cursor-hover);\n color: var(--salt-content-primary-foreground);\n font-weight: var(--salt-text-h4-fontWeight);\n font-family: var(--salt-text-h4-fontFamily);\n text-align: var(--salt-text-textAlign);\n letter-spacing: var(--salt-text-letterSpacing);\n line-height: var(--salt-text-h4-lineHeight);\n font-size: var(--salt-text-h4-fontSize);\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent-active,\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent-active:hover {\n background: var(--salt-navigable-accent-background-active);\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent::before {\n left: var(--salt-spacing-50);\n content: \"\";\n position: absolute;\n top: var(--salt-spacing-50);\n bottom: var(--salt-spacing-50);\n border-radius: var(--salt-palette-corner-strongest);\n width: var(--salt-size-indicator);\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent-active::before {\n background: var(--salt-navigable-accent-indicator-active);\n}\n\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent {\n border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) transparent;\n}\n\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent-active,\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent-active:hover {\n background: var(--salt-navigable-accent-background-active);\n border-color: var(--salt-navigable-accent-borderColor-active);\n}\n\n.saltVerticalNavigationItemContent .saltIcon,\n.saltVerticalNavigationItemContent .saltBadge {\n min-height: var(--salt-text-lineHeight);\n}\n\n.saltVerticalNavigationItemContent-focused {\n outline: var(--salt-focused-outline);\n outline-offset: calc(var(--salt-size-fixed-100) * -2);\n z-index: 1;\n}\n\n.saltVerticalNavigationItemContent:hover {\n background: var(--salt-overlayable-background-hover);\n}\n\n.saltVerticalNavigation .saltVerticalNavigationItemContent-active,\n.saltVerticalNavigation .saltVerticalNavigationSubMenu .saltVerticalNavigationItemContent-active {\n font-weight: var(--salt-text-h4-fontWeight);\n}\n\n@supports selector(:has(*)) {\n .saltVerticalNavigationItemContent-active:hover:has(.saltVerticalNavigationItemTrigger[aria-controls]) {\n background: linear-gradient(var(--salt-overlayable-background-hover), var(--salt-overlayable-background-hover)) var(--salt-navigable-accent-background-active);\n }\n}\n";
1
+ var css_248z = ".saltVerticalNavigationItemContent {\n --verticalNavigationItem-iconPadding: calc(var(--saltVerticalNavigationItem-iconPaddingMultiplier, 0) * (var(--salt-size-icon) + var(--salt-spacing-100)));\n --verticalNavigationItem-depthPadding: calc(var(--salt-spacing-100) * max(0, calc(var(--verticalNavigationItem-depth, 0) - 1)));\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent {\n --verticalNavigationItem-paddingLeft: calc(var(--salt-spacing-150) + var(--salt-size-indicator) + var(--verticalNavigationItem-depthPadding) + var(--verticalNavigationItem-iconPadding));\n --verticalNavigationItem-paddingBlock: var(--salt-spacing-50);\n}\n\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent {\n --verticalNavigationItem-paddingLeft: calc(var(--salt-spacing-100) + var(--verticalNavigationItem-depthPadding) + var(--verticalNavigationItem-iconPadding));\n --verticalNavigationItem-paddingBlock: calc(var(--salt-spacing-50) - var(--salt-size-fixed-100));\n}\n\n.saltVerticalNavigationItemContent {\n display: flex;\n flex-direction: row;\n gap: var(--salt-spacing-100);\n appearance: none;\n -webkit-appearance: none;\n min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));\n min-width: 4em;\n padding: var(--verticalNavigationItem-paddingBlock) var(--salt-spacing-100) var(--verticalNavigationItem-paddingBlock) var(--verticalNavigationItem-paddingLeft);\n position: relative;\n flex-shrink: 0;\n box-sizing: border-box;\n border-radius: var(--salt-palette-corner-weak, 0);\n overflow: hidden;\n\n cursor: var(--salt-cursor-hover);\n color: var(--salt-content-primary-foreground);\n font-weight: var(--salt-text-heading-fontWeight);\n font-family: var(--salt-text-heading-fontFamily);\n text-align: var(--salt-text-textAlign);\n letter-spacing: var(--salt-text-letterSpacing);\n line-height: var(--salt-text-h4-lineHeight);\n font-size: var(--salt-text-h4-fontSize);\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent-active,\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent-active:hover {\n background: var(--salt-navigable-accent-background-active);\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent::before {\n left: var(--salt-spacing-50);\n content: \"\";\n position: absolute;\n top: var(--salt-spacing-50);\n bottom: var(--salt-spacing-50);\n border-radius: var(--salt-palette-corner-strongest);\n width: var(--salt-size-indicator);\n}\n\n.saltVerticalNavigation-indicator .saltVerticalNavigationItemContent-active::before {\n background: var(--salt-navigable-accent-indicator-active);\n}\n\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent {\n border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) transparent;\n}\n\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent-active,\n.saltVerticalNavigation-bordered .saltVerticalNavigationItemContent-active:hover {\n background: var(--salt-navigable-accent-background-active);\n border-color: var(--salt-navigable-accent-borderColor-active);\n}\n\n.saltVerticalNavigationItemContent .saltIcon,\n.saltVerticalNavigationItemContent .saltBadge {\n min-height: var(--salt-text-lineHeight);\n}\n\n.saltVerticalNavigationItemContent-focused {\n outline: var(--salt-focused-outline);\n outline-offset: calc(var(--salt-size-fixed-100) * -2);\n z-index: 1;\n}\n\n.saltVerticalNavigationItemContent:hover {\n background: var(--salt-overlayable-background-hover);\n}\n\n.saltVerticalNavigation .saltVerticalNavigationItemContent-active,\n.saltVerticalNavigation .saltVerticalNavigationSubMenu .saltVerticalNavigationItemContent-active {\n font-weight: var(--salt-text-heading-fontWeight);\n}\n\n@supports selector(:has(*)) {\n .saltVerticalNavigationItemContent-active:hover:has(.saltVerticalNavigationItemTrigger[aria-controls]) {\n background: linear-gradient(var(--salt-overlayable-background-hover), var(--salt-overlayable-background-hover)) var(--salt-navigable-accent-background-active);\n }\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=VerticalNavigationItemContent.css.js.map
@@ -1,4 +1,4 @@
1
- var css_248z = ".saltVerticalNavigationSubMenu {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-fixed-100);\n list-style: none;\n padding: var(--salt-spacing-fixed-100) 0 0;\n margin: 0;\n}\n\n.saltVerticalNavigationSubMenu .saltVerticalNavigationItemContent {\n font-weight: var(--salt-text-h4-fontWeight-small);\n}\n";
1
+ var css_248z = ".saltVerticalNavigationSubMenu {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-fixed-100);\n list-style: none;\n padding: var(--salt-spacing-fixed-100) 0 0;\n margin: 0;\n}\n\n.saltVerticalNavigationSubMenu .saltVerticalNavigationItemContent {\n font-weight: var(--salt-text-heading-fontWeight-small);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=VerticalNavigationSubMenu.css.js.map
@@ -4,6 +4,14 @@ export interface CardProps extends ComponentPropsWithoutRef<"div"> {
4
4
  * If provided an accent is shown in the specified position.
5
5
  */
6
6
  accent?: "bottom" | "top" | "left" | "right";
7
+ /**
8
+ * Visual elevation.
9
+ */
10
+ elevation?: "flat" | "raised";
11
+ /**
12
+ * Border color strength.
13
+ */
14
+ borderColor?: "strong" | "subtle" | "none";
7
15
  /**
8
16
  * **Deprecated:** Use the InteractableCard component instead
9
17
  *
@@ -11,6 +19,8 @@ export interface CardProps extends ComponentPropsWithoutRef<"div"> {
11
19
  */
12
20
  disabled?: boolean;
13
21
  /**
22
+ * @deprecated since 1.71.0. Use `LinkCard` or `InteractableCard` when the entire card is interactive.
23
+ *
14
24
  * If `true` the card will have hover styling.
15
25
  */
16
26
  hoverable?: boolean;
@@ -12,7 +12,7 @@ export declare function useComboBox<Item>(props: UseComboBoxProps<Item>): {
12
12
  setOpen: (newOpen: boolean, reason?: import("../list-control/ListControlState").OpenChangeReason, key?: string) => void;
13
13
  openKey: import("react").MutableRefObject<string | undefined>;
14
14
  activeState: OptionValue<Item> | undefined;
15
- setActive: (option?: OptionValue<Item> | undefined) => void;
15
+ setActive: import("react").Dispatch<import("react").SetStateAction<OptionValue<Item> | undefined>>;
16
16
  selectedState: Item[];
17
17
  setSelectedState: import("react").Dispatch<import("react").SetStateAction<Item[]>>;
18
18
  clear: (event: SyntheticEvent) => void;
@@ -22,17 +22,13 @@ export declare function useComboBox<Item>(props: UseComboBoxProps<Item>): {
22
22
  setFocusedState: import("react").Dispatch<import("react").SetStateAction<boolean>>;
23
23
  setListRef: import("react").Ref<HTMLDivElement>;
24
24
  listRef: import("react").RefObject<HTMLDivElement>;
25
- options: HTMLElement[];
26
25
  register: (optionValue: OptionValue<Item>, element: HTMLElement) => () => void;
27
26
  getOptionAtIndex: (index: number) => {
28
27
  data: OptionValue<Item>;
29
28
  element: HTMLElement;
30
29
  } | undefined;
31
30
  getIndexOfOption: (option: OptionValue<Item>) => number;
32
- getOptionsMatching: (predicate: (option: OptionValue<Item>) => boolean) => {
33
- data: OptionValue<Item>;
34
- element: HTMLElement;
35
- }[];
31
+ getOptionsMatching: (predicate: (option: OptionValue<Item>) => boolean) => import("../list-control/ListControlRegistry").RegisteredOption<Item>[];
36
32
  getOptionFromSearch: (search: string, startFrom?: OptionValue<Item> | undefined) => OptionValue<Item> | undefined;
37
33
  getOptionAfter: (option: OptionValue<Item>) => {
38
34
  data: OptionValue<Item>;
@@ -60,4 +56,5 @@ export declare function useComboBox<Item>(props: UseComboBoxProps<Item>): {
60
56
  } | undefined;
61
57
  valueToString: (item: Item) => string;
62
58
  disabled: boolean | undefined;
59
+ optionStateStore: import("../list-control/ListControlOptionStore").ListControlOptionStore<Item>;
63
60
  };
@@ -18,7 +18,7 @@ export interface DrawerProps extends ComponentPropsWithoutRef<"div"> {
18
18
  */
19
19
  variant?: "primary" | "secondary" | "tertiary";
20
20
  /**
21
- * Prevent the dialog closing on click away
21
+ * Prevent the drawer closing on click away
22
22
  * */
23
23
  disableDismiss?: boolean;
24
24
  /**
@@ -1,2 +1,5 @@
1
1
  import { type ButtonProps } from "../button";
2
+ /**
3
+ * @deprecated since 1.71.0. Use `Button` in `DrawerHeader`'s `actions` instead.
4
+ */
2
5
  export declare const DrawerCloseButton: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,3 @@
1
+ import { type ComponentPropsWithoutRef } from "react";
2
+ export type DrawerContentProps = ComponentPropsWithoutRef<"div">;
3
+ export declare const DrawerContent: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,9 @@
1
+ export interface DrawerContextValue {
2
+ drawerId?: string;
3
+ headerId?: string;
4
+ setHeaderId?: (id: string | undefined) => void;
5
+ descriptionId?: string;
6
+ setDescriptionId?: (id: string | undefined) => void;
7
+ }
8
+ export declare const DrawerContext: import("react").Context<DrawerContextValue>;
9
+ export declare const useDrawerContext: () => DrawerContextValue;
@@ -0,0 +1,3 @@
1
+ import { type ComponentPropsWithoutRef } from "react";
2
+ export type DrawerFooterProps = ComponentPropsWithoutRef<"div">;
3
+ export declare const DrawerFooter: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,24 @@
1
+ import { type ComponentPropsWithoutRef, type ReactNode } from "react";
2
+ export interface DrawerHeaderProps extends ComponentPropsWithoutRef<"div"> {
3
+ /**
4
+ * Hides the accent bar in the Drawer Header. Defaults to `false`.
5
+ */
6
+ disableAccent?: boolean;
7
+ /**
8
+ * Displays the header at the top of the Drawer
9
+ */
10
+ header?: ReactNode;
11
+ /**
12
+ * Displays the preheader just above the header
13
+ **/
14
+ preheader?: ReactNode;
15
+ /**
16
+ * Description text is displayed just below the header
17
+ **/
18
+ description?: ReactNode;
19
+ /**
20
+ * Actions to be displayed in header
21
+ */
22
+ actions?: ReactNode;
23
+ }
24
+ export declare const DrawerHeader: import("react").ForwardRefExoticComponent<DrawerHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ import { type ReactNode } from "react";
2
+ export declare function hasDrawerSection(children: ReactNode): boolean;
@@ -1,2 +1,5 @@
1
1
  export * from "./Drawer";
2
2
  export * from "./DrawerCloseButton";
3
+ export * from "./DrawerContent";
4
+ export * from "./DrawerFooter";
5
+ export * from "./DrawerHeader";
@@ -28,6 +28,7 @@ export * from "./input";
28
28
  export * from "./interactable-card";
29
29
  export * from "./kbd";
30
30
  export * from "./link";
31
+ export * from "./link-button";
31
32
  export * from "./link-card";
32
33
  export * from "./list-box";
33
34
  export * from "./list-control";
@@ -2,9 +2,17 @@ import { type ComponentPropsWithoutRef, type SyntheticEvent } from "react";
2
2
  import { type InteractableCardValue } from "./InteractableCardGroupContext";
3
3
  export interface InteractableCardProps extends ComponentPropsWithoutRef<"div"> {
4
4
  /**
5
- * Accent border position: defaults to "bottom"
5
+ * If provided an accent is shown in the specified position.
6
6
  */
7
7
  accent?: "bottom" | "top" | "left" | "right";
8
+ /**
9
+ * Visual elevation.
10
+ */
11
+ elevation?: "flat" | "raised";
12
+ /**
13
+ * Border color strength.
14
+ */
15
+ borderColor?: "strong" | "subtle" | "none";
8
16
  /**
9
17
  * @deprecated since 1.23.0. Use the `accent` prop instead.
10
18
  */
@@ -3,6 +3,8 @@ export type InteractableCardValue = string | readonly string[] | undefined;
3
3
  export interface InteractableCardGroupContextValue {
4
4
  disabled?: boolean;
5
5
  select: (event: SyntheticEvent<HTMLDivElement>, value: InteractableCardValue) => void;
6
+ registerCard?: (value: InteractableCardValue, element: HTMLElement) => () => void;
7
+ hasEnabledSelection?: boolean;
6
8
  isSelected: (id: InteractableCardValue) => boolean;
7
9
  isFirstChild: (value: InteractableCardValue) => boolean;
8
10
  multiSelect?: boolean;
@@ -10,8 +10,7 @@ export interface CardHookResult<T extends Element> {
10
10
  active: boolean;
11
11
  cardProps: {
12
12
  "aria-disabled"?: boolean;
13
- disabled?: boolean;
14
- tabIndex: number;
13
+ tabIndex?: number;
15
14
  onBlur: (event: FocusEvent<T>) => void;
16
15
  onClick?: (event: MouseEvent<T>) => void;
17
16
  onKeyDown: (event: KeyboardEvent<T>) => void;
@@ -0,0 +1,26 @@
1
+ import type { IconProps } from "@salt-ds/icons";
2
+ import { type ComponentPropsWithoutRef, type ComponentType } from "react";
3
+ import { type RenderPropsType } from "../utils";
4
+ export interface LinkButtonProps extends ComponentPropsWithoutRef<"a"> {
5
+ /**
6
+ * Icon component displayed when `target="_blank"`. Defaults to `ExternalIcon` from `SemanticIconProvider`.
7
+ */
8
+ IconComponent?: ComponentType<IconProps> | null;
9
+ /**
10
+ * The sentiment of the button. Options are 'accented' and 'neutral'.
11
+ * 'neutral' is the default value.
12
+ */
13
+ sentiment?: "accented" | "neutral";
14
+ /**
15
+ * Render prop to enable customisation of anchor element.
16
+ */
17
+ render?: RenderPropsType["render"];
18
+ /**
19
+ * Either "default" or "never".
20
+ * Determines when underline should be applied to the link button.
21
+ *
22
+ * @default "default".
23
+ */
24
+ underline?: "default" | "never";
25
+ }
26
+ export declare const LinkButton: import("react").ForwardRefExoticComponent<LinkButtonProps & import("react").RefAttributes<HTMLAnchorElement>>;
@@ -0,0 +1 @@
1
+ export * from "./LinkButton";
@@ -4,6 +4,14 @@ export interface LinkCardProps extends ComponentPropsWithoutRef<"a"> {
4
4
  * If provided an accent is shown in the specified position.
5
5
  */
6
6
  accent?: "bottom" | "top" | "left" | "right";
7
+ /**
8
+ * Visual elevation.
9
+ */
10
+ elevation?: "flat" | "raised";
11
+ /**
12
+ * Border color strength.
13
+ */
14
+ borderColor?: "strong" | "subtle" | "none";
7
15
  /**
8
16
  * Styling variant; defaults to "primary".
9
17
  */
@@ -0,0 +1,30 @@
1
+ import type { OptionValue } from "./ListControlContext";
2
+ export declare function isListControlNavigationKey(key: string): boolean;
3
+ /**
4
+ * Navigation keys pressed with Ctrl or Meta (e.g. Ctrl+End, Cmd+ArrowDown,
5
+ * Ctrl+PageDown) are browser or OS shortcuts, so list controls leave them to
6
+ * the browser. Alt is only used with ArrowUp and ArrowDown, as in the ARIA
7
+ * combobox pattern.
8
+ */
9
+ export declare function isModifiedListControlNavigationKey(event: {
10
+ key: string;
11
+ altKey: boolean;
12
+ ctrlKey: boolean;
13
+ metaKey: boolean;
14
+ }): boolean;
15
+ export interface OptionAndElement<Item> {
16
+ data: OptionValue<Item>;
17
+ element: HTMLElement;
18
+ }
19
+ export interface ListControlNavigationGetters<Item> {
20
+ getFirstOption: () => OptionAndElement<Item> | undefined;
21
+ getLastOption: () => OptionAndElement<Item> | undefined;
22
+ getOptionAfter: (option: OptionValue<Item>) => OptionAndElement<Item> | undefined;
23
+ getOptionBefore: (option: OptionValue<Item>) => OptionAndElement<Item> | undefined;
24
+ getOptionPageAbove: (option: OptionValue<Item>) => OptionAndElement<Item> | undefined;
25
+ getOptionPageBelow: (option: OptionValue<Item>) => OptionAndElement<Item> | undefined;
26
+ }
27
+ /** Shared by Dropdown and ListBox, which always have an active option. */
28
+ export declare function getListControlNavigationTarget<Item>(key: string, activeOption: OptionValue<Item>, getters: ListControlNavigationGetters<Item>): OptionAndElement<Item> | undefined;
29
+ /** For ComboBox, where the active option may be undefined. */
30
+ export declare function getComboBoxNavigationTarget<Item>(key: string, activeOption: OptionValue<Item> | undefined, getters: ListControlNavigationGetters<Item>): OptionAndElement<Item> | undefined;
@@ -0,0 +1,18 @@
1
+ import { type ReactNode, type RefObject, type SyntheticEvent } from "react";
2
+ import type { OptionValue } from "./ListControlContext";
3
+ import { ListControlOptionStore } from "./ListControlOptionStore";
4
+ export interface ListControlOptionContextValue<Item> {
5
+ disabled?: boolean;
6
+ listRef?: RefObject<HTMLDivElement>;
7
+ multiselect: boolean;
8
+ optionStateStore: ListControlOptionStore<Item>;
9
+ register: (optionValue: OptionValue<Item>, element: HTMLElement) => () => void;
10
+ select: (event: SyntheticEvent, option: OptionValue<Item>) => void;
11
+ setActive: (option: OptionValue<Item>) => void;
12
+ valueToString: (item: Item) => string;
13
+ }
14
+ export declare function ListControlOptionContextProvider<Item>({ children, value, }: {
15
+ children: ReactNode;
16
+ value: ListControlOptionContextValue<Item>;
17
+ }): import("react").JSX.Element;
18
+ export declare function useListControlOptionContext<Item>(): ListControlOptionContextValue<Item>;
@@ -0,0 +1,17 @@
1
+ import type { OptionValue } from "./ListControlContext";
2
+ export declare const OPTION_STATE_ACTIVE = 1;
3
+ export declare const OPTION_STATE_SELECTED = 2;
4
+ export declare const OPTION_STATE_FOCUS_VISIBLE = 4;
5
+ export type OptionStateSnapshot = number;
6
+ export declare function hasOptionState(snapshot: OptionStateSnapshot, state: OptionStateSnapshot): boolean;
7
+ /** Internal per-list store used to target updates at affected Options. */
8
+ export declare class ListControlOptionStore<Item> {
9
+ #private;
10
+ constructor(selected?: readonly Item[]);
11
+ subscribe(id: string, listener: () => void): () => void;
12
+ register(option: OptionValue<Item>): () => void;
13
+ getSnapshot(id: string, currentOption?: OptionValue<Item>): OptionStateSnapshot;
14
+ setActiveId(id: string | undefined): void;
15
+ setFocusVisible(focusVisible: boolean): void;
16
+ setSelected(selected: readonly Item[]): void;
17
+ }
@@ -0,0 +1,11 @@
1
+ import { type ReactNode } from "react";
2
+ import { type ListControlContextValue } from "./ListControlContext";
3
+ import type { ListControlOptionStore } from "./ListControlOptionStore";
4
+ type ListControlProviderValue<Item> = ListControlContextValue<Item> & {
5
+ optionStateStore: ListControlOptionStore<Item>;
6
+ };
7
+ export declare function ListControlProvider<Item>({ children, value, }: {
8
+ children: ReactNode;
9
+ value: ListControlProviderValue<Item>;
10
+ }): import("react").JSX.Element;
11
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { OptionValue } from "./ListControlContext";
2
+ export interface RegisteredOption<Item> {
3
+ data: OptionValue<Item>;
4
+ element: HTMLElement;
5
+ }
6
+ export declare function createCoalescedRebuild(rebuild: () => void, enqueue?: (callback: () => void) => void): {
7
+ schedule: () => void;
8
+ cancel: () => void;
9
+ };
10
+ /** Internal option registry optimized for large, non-virtualized lists. */
11
+ export declare class ListControlRegistry<Item> {
12
+ #private;
13
+ register(option: OptionValue<Item>, element: HTMLElement): () => void;
14
+ rebuild(listElement: Pick<HTMLElement, "querySelectorAll">): void;
15
+ getAt(index: number): RegisteredOption<Item> | undefined;
16
+ get length(): number;
17
+ indexOfId(id: string): number;
18
+ indexOfValue(value: Item): number;
19
+ findByData(option: OptionValue<Item>): RegisteredOption<Item> | undefined;
20
+ matching(predicate: (option: OptionValue<Item>) => boolean): RegisteredOption<Item>[];
21
+ snapshot(): readonly RegisteredOption<Item>[];
22
+ }