@mortenbrudvik/waveui 0.7.0 → 0.8.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 (408) hide show
  1. package/README.md +395 -132
  2. package/dist/components/button/Button.cjs +1 -1
  3. package/dist/components/button/Button.cjs.map +1 -1
  4. package/dist/components/button/Button.mjs +36 -35
  5. package/dist/components/button/Button.mjs.map +1 -1
  6. package/dist/components/button/Button.slots.cjs +1 -1
  7. package/dist/components/button/Button.slots.cjs.map +1 -1
  8. package/dist/components/button/Button.slots.mjs +31 -21
  9. package/dist/components/button/Button.slots.mjs.map +1 -1
  10. package/dist/components/button/CompoundButton.cjs +1 -1
  11. package/dist/components/button/CompoundButton.cjs.map +1 -1
  12. package/dist/components/button/CompoundButton.mjs +31 -29
  13. package/dist/components/button/CompoundButton.mjs.map +1 -1
  14. package/dist/components/button/Link.cjs +1 -1
  15. package/dist/components/button/Link.cjs.map +1 -1
  16. package/dist/components/button/Link.mjs +24 -23
  17. package/dist/components/button/Link.mjs.map +1 -1
  18. package/dist/components/button/MenuButton.cjs +1 -1
  19. package/dist/components/button/MenuButton.cjs.map +1 -1
  20. package/dist/components/button/MenuButton.mjs +29 -28
  21. package/dist/components/button/MenuButton.mjs.map +1 -1
  22. package/dist/components/button/SplitButton.cjs +1 -1
  23. package/dist/components/button/SplitButton.cjs.map +1 -1
  24. package/dist/components/button/SplitButton.mjs +46 -45
  25. package/dist/components/button/SplitButton.mjs.map +1 -1
  26. package/dist/components/button/ToggleButton.cjs +1 -1
  27. package/dist/components/button/ToggleButton.cjs.map +1 -1
  28. package/dist/components/button/ToggleButton.mjs +38 -35
  29. package/dist/components/button/ToggleButton.mjs.map +1 -1
  30. package/dist/components/button/Toolbar.cjs +1 -1
  31. package/dist/components/button/Toolbar.cjs.map +1 -1
  32. package/dist/components/button/Toolbar.mjs +43 -42
  33. package/dist/components/button/Toolbar.mjs.map +1 -1
  34. package/dist/components/button/Toolbar.parts.cjs +1 -1
  35. package/dist/components/button/Toolbar.parts.cjs.map +1 -1
  36. package/dist/components/button/Toolbar.parts.mjs +76 -81
  37. package/dist/components/button/Toolbar.parts.mjs.map +1 -1
  38. package/dist/components/data-display/Avatar.cjs +1 -1
  39. package/dist/components/data-display/Avatar.cjs.map +1 -1
  40. package/dist/components/data-display/Avatar.mjs +72 -67
  41. package/dist/components/data-display/Avatar.mjs.map +1 -1
  42. package/dist/components/data-display/AvatarGroup.cjs +1 -1
  43. package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
  44. package/dist/components/data-display/AvatarGroup.mjs +89 -88
  45. package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
  46. package/dist/components/data-display/Badge.cjs +1 -1
  47. package/dist/components/data-display/Badge.cjs.map +1 -1
  48. package/dist/components/data-display/Badge.mjs +17 -16
  49. package/dist/components/data-display/Badge.mjs.map +1 -1
  50. package/dist/components/data-display/CounterBadge.cjs +1 -1
  51. package/dist/components/data-display/CounterBadge.cjs.map +1 -1
  52. package/dist/components/data-display/CounterBadge.mjs +18 -17
  53. package/dist/components/data-display/CounterBadge.mjs.map +1 -1
  54. package/dist/components/data-display/Divider.cjs +1 -1
  55. package/dist/components/data-display/Divider.cjs.map +1 -1
  56. package/dist/components/data-display/Divider.mjs +31 -30
  57. package/dist/components/data-display/Divider.mjs.map +1 -1
  58. package/dist/components/data-display/Image.cjs +1 -1
  59. package/dist/components/data-display/Image.cjs.map +1 -1
  60. package/dist/components/data-display/Image.mjs +16 -15
  61. package/dist/components/data-display/Image.mjs.map +1 -1
  62. package/dist/components/data-display/InfoLabel.cjs +1 -1
  63. package/dist/components/data-display/InfoLabel.cjs.map +1 -1
  64. package/dist/components/data-display/InfoLabel.mjs +74 -73
  65. package/dist/components/data-display/InfoLabel.mjs.map +1 -1
  66. package/dist/components/data-display/List.cjs +1 -1
  67. package/dist/components/data-display/List.cjs.map +1 -1
  68. package/dist/components/data-display/List.mjs +175 -174
  69. package/dist/components/data-display/List.mjs.map +1 -1
  70. package/dist/components/data-display/Persona.cjs +1 -1
  71. package/dist/components/data-display/Persona.cjs.map +1 -1
  72. package/dist/components/data-display/Persona.mjs +31 -29
  73. package/dist/components/data-display/Persona.mjs.map +1 -1
  74. package/dist/components/data-display/PresenceBadge.cjs +1 -1
  75. package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
  76. package/dist/components/data-display/PresenceBadge.mjs +25 -24
  77. package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
  78. package/dist/components/data-display/Tag.cjs +1 -1
  79. package/dist/components/data-display/Tag.cjs.map +1 -1
  80. package/dist/components/data-display/Tag.mjs +87 -82
  81. package/dist/components/data-display/Tag.mjs.map +1 -1
  82. package/dist/components/feedback/MessageBar.cjs +1 -1
  83. package/dist/components/feedback/MessageBar.cjs.map +1 -1
  84. package/dist/components/feedback/MessageBar.mjs +129 -71
  85. package/dist/components/feedback/MessageBar.mjs.map +1 -1
  86. package/dist/components/feedback/MessageBar.parts.cjs +2 -0
  87. package/dist/components/feedback/MessageBar.parts.cjs.map +1 -0
  88. package/dist/components/feedback/MessageBar.parts.mjs +84 -0
  89. package/dist/components/feedback/MessageBar.parts.mjs.map +1 -0
  90. package/dist/components/feedback/MessageBar.reflow.cjs +2 -0
  91. package/dist/components/feedback/MessageBar.reflow.cjs.map +1 -0
  92. package/dist/components/feedback/MessageBar.reflow.mjs +74 -0
  93. package/dist/components/feedback/MessageBar.reflow.mjs.map +1 -0
  94. package/dist/components/feedback/MessageBar.status.cjs +1 -1
  95. package/dist/components/feedback/MessageBar.status.cjs.map +1 -1
  96. package/dist/components/feedback/MessageBar.status.mjs +2 -1
  97. package/dist/components/feedback/MessageBar.status.mjs.map +1 -1
  98. package/dist/components/feedback/ProgressBar.cjs +1 -1
  99. package/dist/components/feedback/ProgressBar.cjs.map +1 -1
  100. package/dist/components/feedback/ProgressBar.mjs +44 -43
  101. package/dist/components/feedback/ProgressBar.mjs.map +1 -1
  102. package/dist/components/feedback/Skeleton.cjs +1 -1
  103. package/dist/components/feedback/Skeleton.cjs.map +1 -1
  104. package/dist/components/feedback/Skeleton.mjs +26 -24
  105. package/dist/components/feedback/Skeleton.mjs.map +1 -1
  106. package/dist/components/feedback/Spinner.cjs +1 -1
  107. package/dist/components/feedback/Spinner.cjs.map +1 -1
  108. package/dist/components/feedback/Spinner.mjs +32 -31
  109. package/dist/components/feedback/Spinner.mjs.map +1 -1
  110. package/dist/components/feedback/Toast.cjs +1 -1
  111. package/dist/components/feedback/Toast.cjs.map +1 -1
  112. package/dist/components/feedback/Toast.context.cjs +2 -0
  113. package/dist/components/feedback/Toast.context.cjs.map +1 -0
  114. package/dist/components/feedback/Toast.context.mjs +23 -0
  115. package/dist/components/feedback/Toast.context.mjs.map +1 -0
  116. package/dist/components/feedback/Toast.mjs +10 -342
  117. package/dist/components/feedback/Toast.mjs.map +1 -1
  118. package/dist/components/feedback/Toast.parts.cjs +2 -0
  119. package/dist/components/feedback/Toast.parts.cjs.map +1 -0
  120. package/dist/components/feedback/Toast.parts.mjs +98 -0
  121. package/dist/components/feedback/Toast.parts.mjs.map +1 -0
  122. package/dist/components/feedback/Toast.root.cjs +2 -0
  123. package/dist/components/feedback/Toast.root.cjs.map +1 -0
  124. package/dist/components/feedback/Toast.root.mjs +109 -0
  125. package/dist/components/feedback/Toast.root.mjs.map +1 -0
  126. package/dist/components/feedback/Toaster.cjs +2 -0
  127. package/dist/components/feedback/Toaster.cjs.map +1 -0
  128. package/dist/components/feedback/Toaster.mjs +564 -0
  129. package/dist/components/feedback/Toaster.mjs.map +1 -0
  130. package/dist/components/input/AlphaSlider.cjs +2 -0
  131. package/dist/components/input/AlphaSlider.cjs.map +1 -0
  132. package/dist/components/input/AlphaSlider.mjs +115 -0
  133. package/dist/components/input/AlphaSlider.mjs.map +1 -0
  134. package/dist/components/input/Checkbox.cjs +1 -1
  135. package/dist/components/input/Checkbox.cjs.map +1 -1
  136. package/dist/components/input/Checkbox.mjs +47 -46
  137. package/dist/components/input/Checkbox.mjs.map +1 -1
  138. package/dist/components/input/ColorArea.cjs +2 -0
  139. package/dist/components/input/ColorArea.cjs.map +1 -0
  140. package/dist/components/input/ColorArea.mjs +204 -0
  141. package/dist/components/input/ColorArea.mjs.map +1 -0
  142. package/dist/components/input/ColorPicker.cjs +5 -5
  143. package/dist/components/input/ColorPicker.cjs.map +1 -1
  144. package/dist/components/input/ColorPicker.mjs +142 -165
  145. package/dist/components/input/ColorPicker.mjs.map +1 -1
  146. package/dist/components/input/ColorPicker.parts.cjs +2 -0
  147. package/dist/components/input/ColorPicker.parts.cjs.map +1 -0
  148. package/dist/components/input/ColorPicker.parts.mjs +192 -0
  149. package/dist/components/input/ColorPicker.parts.mjs.map +1 -0
  150. package/dist/components/input/ColorSlider.cjs +2 -0
  151. package/dist/components/input/ColorSlider.cjs.map +1 -0
  152. package/dist/components/input/ColorSlider.mjs +138 -0
  153. package/dist/components/input/ColorSlider.mjs.map +1 -0
  154. package/dist/components/input/Combobox.cjs +1 -1
  155. package/dist/components/input/Combobox.cjs.map +1 -1
  156. package/dist/components/input/Combobox.expand.cjs +1 -1
  157. package/dist/components/input/Combobox.expand.cjs.map +1 -1
  158. package/dist/components/input/Combobox.expand.mjs +9 -9
  159. package/dist/components/input/Combobox.expand.mjs.map +1 -1
  160. package/dist/components/input/Combobox.mjs +90 -85
  161. package/dist/components/input/Combobox.mjs.map +1 -1
  162. package/dist/components/input/DatePicker.cjs +1 -1
  163. package/dist/components/input/DatePicker.cjs.map +1 -1
  164. package/dist/components/input/DatePicker.mjs +186 -185
  165. package/dist/components/input/DatePicker.mjs.map +1 -1
  166. package/dist/components/input/Dropdown.cjs +1 -1
  167. package/dist/components/input/Dropdown.cjs.map +1 -1
  168. package/dist/components/input/Dropdown.mjs +71 -68
  169. package/dist/components/input/Dropdown.mjs.map +1 -1
  170. package/dist/components/input/Field.cjs +1 -1
  171. package/dist/components/input/Field.cjs.map +1 -1
  172. package/dist/components/input/Field.mjs +113 -112
  173. package/dist/components/input/Field.mjs.map +1 -1
  174. package/dist/components/input/Input.cjs +1 -1
  175. package/dist/components/input/Input.cjs.map +1 -1
  176. package/dist/components/input/Input.mjs +55 -54
  177. package/dist/components/input/Input.mjs.map +1 -1
  178. package/dist/components/input/Label.cjs +1 -1
  179. package/dist/components/input/Label.cjs.map +1 -1
  180. package/dist/components/input/Label.mjs +12 -11
  181. package/dist/components/input/Label.mjs.map +1 -1
  182. package/dist/components/input/Option.cjs +1 -1
  183. package/dist/components/input/Option.cjs.map +1 -1
  184. package/dist/components/input/Option.mjs +100 -98
  185. package/dist/components/input/Option.mjs.map +1 -1
  186. package/dist/components/input/RadioGroup.cjs +1 -1
  187. package/dist/components/input/RadioGroup.cjs.map +1 -1
  188. package/dist/components/input/RadioGroup.mjs +89 -88
  189. package/dist/components/input/RadioGroup.mjs.map +1 -1
  190. package/dist/components/input/Rating.cjs +1 -1
  191. package/dist/components/input/Rating.cjs.map +1 -1
  192. package/dist/components/input/Rating.mjs +110 -109
  193. package/dist/components/input/Rating.mjs.map +1 -1
  194. package/dist/components/input/SearchBox.cjs +1 -1
  195. package/dist/components/input/SearchBox.cjs.map +1 -1
  196. package/dist/components/input/SearchBox.mjs +118 -119
  197. package/dist/components/input/SearchBox.mjs.map +1 -1
  198. package/dist/components/input/Select.cjs +1 -1
  199. package/dist/components/input/Select.cjs.map +1 -1
  200. package/dist/components/input/Select.mjs +25 -24
  201. package/dist/components/input/Select.mjs.map +1 -1
  202. package/dist/components/input/Slider.cjs +1 -1
  203. package/dist/components/input/Slider.cjs.map +1 -1
  204. package/dist/components/input/Slider.mjs +47 -46
  205. package/dist/components/input/Slider.mjs.map +1 -1
  206. package/dist/components/input/SpinButton.cjs +1 -1
  207. package/dist/components/input/SpinButton.cjs.map +1 -1
  208. package/dist/components/input/SpinButton.mjs +76 -75
  209. package/dist/components/input/SpinButton.mjs.map +1 -1
  210. package/dist/components/input/SwatchPicker.cjs +1 -1
  211. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  212. package/dist/components/input/SwatchPicker.mjs +38 -37
  213. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  214. package/dist/components/input/Switch.cjs +1 -1
  215. package/dist/components/input/Switch.cjs.map +1 -1
  216. package/dist/components/input/Switch.mjs +65 -64
  217. package/dist/components/input/Switch.mjs.map +1 -1
  218. package/dist/components/input/TagPicker.cjs +1 -1
  219. package/dist/components/input/TagPicker.cjs.map +1 -1
  220. package/dist/components/input/TagPicker.mjs +161 -157
  221. package/dist/components/input/TagPicker.mjs.map +1 -1
  222. package/dist/components/input/Textarea.cjs +1 -1
  223. package/dist/components/input/Textarea.cjs.map +1 -1
  224. package/dist/components/input/Textarea.mjs +24 -23
  225. package/dist/components/input/Textarea.mjs.map +1 -1
  226. package/dist/components/input/TimePicker.cjs +1 -1
  227. package/dist/components/input/TimePicker.cjs.map +1 -1
  228. package/dist/components/input/TimePicker.mjs +202 -199
  229. package/dist/components/input/TimePicker.mjs.map +1 -1
  230. package/dist/components/input/colorName.cjs +2 -0
  231. package/dist/components/input/colorName.cjs.map +1 -0
  232. package/dist/components/input/colorName.mjs +30 -0
  233. package/dist/components/input/colorName.mjs.map +1 -0
  234. package/dist/components/input/colorUtils.cjs +1 -1
  235. package/dist/components/input/colorUtils.cjs.map +1 -1
  236. package/dist/components/input/colorUtils.mjs +154 -56
  237. package/dist/components/input/colorUtils.mjs.map +1 -1
  238. package/dist/components/layout/Accordion.cjs +1 -1
  239. package/dist/components/layout/Accordion.cjs.map +1 -1
  240. package/dist/components/layout/Accordion.mjs +130 -129
  241. package/dist/components/layout/Accordion.mjs.map +1 -1
  242. package/dist/components/layout/Card.cjs +1 -1
  243. package/dist/components/layout/Card.cjs.map +1 -1
  244. package/dist/components/layout/Card.mjs +78 -77
  245. package/dist/components/layout/Card.mjs.map +1 -1
  246. package/dist/components/layout/Carousel.cjs +1 -1
  247. package/dist/components/layout/Carousel.cjs.map +1 -1
  248. package/dist/components/layout/Carousel.mjs +111 -110
  249. package/dist/components/layout/Carousel.mjs.map +1 -1
  250. package/dist/components/layout/Flex.cjs +1 -1
  251. package/dist/components/layout/Flex.cjs.map +1 -1
  252. package/dist/components/layout/Flex.mjs +22 -21
  253. package/dist/components/layout/Flex.mjs.map +1 -1
  254. package/dist/components/layout/Grid.cjs +1 -1
  255. package/dist/components/layout/Grid.cjs.map +1 -1
  256. package/dist/components/layout/Grid.mjs +19 -18
  257. package/dist/components/layout/Grid.mjs.map +1 -1
  258. package/dist/components/layout/Overflow.cjs +1 -1
  259. package/dist/components/layout/Overflow.cjs.map +1 -1
  260. package/dist/components/layout/Overflow.mjs +92 -91
  261. package/dist/components/layout/Overflow.mjs.map +1 -1
  262. package/dist/components/layout/Stack.cjs +1 -1
  263. package/dist/components/layout/Stack.cjs.map +1 -1
  264. package/dist/components/layout/Stack.mjs +14 -13
  265. package/dist/components/layout/Stack.mjs.map +1 -1
  266. package/dist/components/layout/TabList.cjs +1 -1
  267. package/dist/components/layout/TabList.cjs.map +1 -1
  268. package/dist/components/layout/TabList.mjs +118 -117
  269. package/dist/components/layout/TabList.mjs.map +1 -1
  270. package/dist/components/layout/Tree.cjs +1 -1
  271. package/dist/components/layout/Tree.cjs.map +1 -1
  272. package/dist/components/layout/Tree.context.cjs +2 -0
  273. package/dist/components/layout/Tree.context.cjs.map +1 -0
  274. package/dist/components/layout/Tree.context.mjs +33 -0
  275. package/dist/components/layout/Tree.context.mjs.map +1 -0
  276. package/dist/components/layout/Tree.core.cjs +2 -0
  277. package/dist/components/layout/Tree.core.cjs.map +1 -0
  278. package/dist/components/layout/Tree.core.mjs +416 -0
  279. package/dist/components/layout/Tree.core.mjs.map +1 -0
  280. package/dist/components/layout/Tree.itemPersonaLayout.cjs +2 -0
  281. package/dist/components/layout/Tree.itemPersonaLayout.cjs.map +1 -0
  282. package/dist/components/layout/Tree.itemPersonaLayout.mjs +46 -0
  283. package/dist/components/layout/Tree.itemPersonaLayout.mjs.map +1 -0
  284. package/dist/components/layout/Tree.mjs +7 -215
  285. package/dist/components/layout/Tree.mjs.map +1 -1
  286. package/dist/components/layout/Tree.selection.cjs +2 -0
  287. package/dist/components/layout/Tree.selection.cjs.map +1 -0
  288. package/dist/components/layout/Tree.selection.mjs +73 -0
  289. package/dist/components/layout/Tree.selection.mjs.map +1 -0
  290. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  291. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  292. package/dist/components/navigation/Breadcrumb.mjs +76 -75
  293. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  294. package/dist/components/navigation/Menu.group.cjs +1 -1
  295. package/dist/components/navigation/Menu.group.cjs.map +1 -1
  296. package/dist/components/navigation/Menu.group.mjs +39 -37
  297. package/dist/components/navigation/Menu.group.mjs.map +1 -1
  298. package/dist/components/navigation/Menu.items.cjs +1 -1
  299. package/dist/components/navigation/Menu.items.cjs.map +1 -1
  300. package/dist/components/navigation/Menu.items.mjs +67 -61
  301. package/dist/components/navigation/Menu.items.mjs.map +1 -1
  302. package/dist/components/navigation/Menu.link.cjs +1 -1
  303. package/dist/components/navigation/Menu.link.cjs.map +1 -1
  304. package/dist/components/navigation/Menu.link.mjs +34 -28
  305. package/dist/components/navigation/Menu.link.mjs.map +1 -1
  306. package/dist/components/navigation/Menu.popover.cjs +1 -1
  307. package/dist/components/navigation/Menu.popover.cjs.map +1 -1
  308. package/dist/components/navigation/Menu.popover.mjs +110 -109
  309. package/dist/components/navigation/Menu.popover.mjs.map +1 -1
  310. package/dist/components/navigation/Menu.root.cjs +1 -1
  311. package/dist/components/navigation/Menu.root.cjs.map +1 -1
  312. package/dist/components/navigation/Menu.root.mjs +171 -170
  313. package/dist/components/navigation/Menu.root.mjs.map +1 -1
  314. package/dist/components/navigation/Menu.selectable.cjs +1 -1
  315. package/dist/components/navigation/Menu.selectable.cjs.map +1 -1
  316. package/dist/components/navigation/Menu.selectable.mjs +85 -63
  317. package/dist/components/navigation/Menu.selectable.mjs.map +1 -1
  318. package/dist/components/navigation/Menu.splitGroup.cjs +1 -1
  319. package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -1
  320. package/dist/components/navigation/Menu.splitGroup.mjs +27 -26
  321. package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -1
  322. package/dist/components/navigation/Menu.trigger.cjs +1 -1
  323. package/dist/components/navigation/Menu.trigger.cjs.map +1 -1
  324. package/dist/components/navigation/Menu.trigger.mjs +6 -6
  325. package/dist/components/navigation/Nav.cjs +1 -1
  326. package/dist/components/navigation/Nav.cjs.map +1 -1
  327. package/dist/components/navigation/Nav.mjs +170 -155
  328. package/dist/components/navigation/Nav.mjs.map +1 -1
  329. package/dist/components/navigation/Pagination.cjs +1 -1
  330. package/dist/components/navigation/Pagination.cjs.map +1 -1
  331. package/dist/components/navigation/Pagination.mjs +73 -65
  332. package/dist/components/navigation/Pagination.mjs.map +1 -1
  333. package/dist/components/navigation/Stepper.cjs +1 -1
  334. package/dist/components/navigation/Stepper.cjs.map +1 -1
  335. package/dist/components/navigation/Stepper.mjs +110 -109
  336. package/dist/components/navigation/Stepper.mjs.map +1 -1
  337. package/dist/components/overlays/Dialog.cjs +1 -1
  338. package/dist/components/overlays/Dialog.cjs.map +1 -1
  339. package/dist/components/overlays/Dialog.mjs +109 -108
  340. package/dist/components/overlays/Dialog.mjs.map +1 -1
  341. package/dist/components/overlays/Drawer.cjs +1 -1
  342. package/dist/components/overlays/Drawer.cjs.map +1 -1
  343. package/dist/components/overlays/Drawer.mjs +110 -109
  344. package/dist/components/overlays/Drawer.mjs.map +1 -1
  345. package/dist/components/overlays/Popover.cjs +1 -1
  346. package/dist/components/overlays/Popover.cjs.map +1 -1
  347. package/dist/components/overlays/Popover.mjs +229 -227
  348. package/dist/components/overlays/Popover.mjs.map +1 -1
  349. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  350. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  351. package/dist/components/overlays/TeachingPopover.mjs +41 -37
  352. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  353. package/dist/components/overlays/Tooltip.cjs +1 -1
  354. package/dist/components/overlays/Tooltip.cjs.map +1 -1
  355. package/dist/components/overlays/Tooltip.mjs +87 -86
  356. package/dist/components/overlays/Tooltip.mjs.map +1 -1
  357. package/dist/components/portal/Portal.cjs +1 -1
  358. package/dist/components/portal/Portal.cjs.map +1 -1
  359. package/dist/components/portal/Portal.mjs +33 -32
  360. package/dist/components/portal/Portal.mjs.map +1 -1
  361. package/dist/components/provider/WaveProvider.cjs +1 -1
  362. package/dist/components/provider/WaveProvider.cjs.map +1 -1
  363. package/dist/components/provider/WaveProvider.mjs +31 -30
  364. package/dist/components/provider/WaveProvider.mjs.map +1 -1
  365. package/dist/components/table/DataGrid.cjs +1 -1
  366. package/dist/components/table/DataGrid.cjs.map +1 -1
  367. package/dist/components/table/DataGrid.mjs +228 -227
  368. package/dist/components/table/DataGrid.mjs.map +1 -1
  369. package/dist/components/table/Table.cjs +1 -1
  370. package/dist/components/table/Table.cjs.map +1 -1
  371. package/dist/components/table/Table.mjs +60 -59
  372. package/dist/components/table/Table.mjs.map +1 -1
  373. package/dist/components/typography/Text.cjs +1 -1
  374. package/dist/components/typography/Text.cjs.map +1 -1
  375. package/dist/components/typography/Text.mjs +12 -11
  376. package/dist/components/typography/Text.mjs.map +1 -1
  377. package/dist/hooks/useMediaQuery.cjs +2 -0
  378. package/dist/hooks/useMediaQuery.cjs.map +1 -0
  379. package/dist/hooks/useMediaQuery.mjs +20 -0
  380. package/dist/hooks/useMediaQuery.mjs.map +1 -0
  381. package/dist/hooks/usePrefersReducedMotion.cjs +1 -1
  382. package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -1
  383. package/dist/hooks/usePrefersReducedMotion.mjs +4 -18
  384. package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -1
  385. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  386. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  387. package/dist/hooks/useRovingTabIndex.mjs +3 -3
  388. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  389. package/dist/index.cjs +1 -1
  390. package/dist/index.d.cts +2089 -102
  391. package/dist/index.d.ts +2089 -102
  392. package/dist/index.mjs +99 -87
  393. package/dist/lib/classNames.cjs +2 -0
  394. package/dist/lib/classNames.cjs.map +1 -0
  395. package/dist/lib/classNames.mjs +415 -0
  396. package/dist/lib/classNames.mjs.map +1 -0
  397. package/dist/lib/color.cjs +2 -0
  398. package/dist/lib/color.cjs.map +1 -0
  399. package/dist/lib/color.mjs +86 -0
  400. package/dist/lib/color.mjs.map +1 -0
  401. package/dist/lib/globalRegistry.cjs.map +1 -1
  402. package/dist/lib/globalRegistry.mjs.map +1 -1
  403. package/dist/lib/toaster.cjs +2 -0
  404. package/dist/lib/toaster.cjs.map +1 -0
  405. package/dist/lib/toaster.mjs +77 -0
  406. package/dist/lib/toaster.mjs.map +1 -0
  407. package/dist/styles.css +1 -1
  408. package/package.json +1 -1
@@ -2,65 +2,66 @@
2
2
  import { cn as e } from "../../lib/cn.mjs";
3
3
  import { warnOnce as t } from "../../lib/dev.mjs";
4
4
  import { slotRendersContent as n } from "../../lib/slot.mjs";
5
- import { Button as r } from "./Button.mjs";
6
- import { ChevronDownIcon as i } from "../../lib/icons.mjs";
7
- import { mergeProps as a } from "../../lib/mergeProps.mjs";
8
- import { unwrapButtonGlyph as o } from "./Button.slots.mjs";
9
- import * as s from "react";
10
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
+ import { splitButtonClassNames as r } from "../../lib/classNames.mjs";
6
+ import { Button as i } from "./Button.mjs";
7
+ import { unwrapButtonGlyph as a, withPartClass as o } from "./Button.slots.mjs";
8
+ import { ChevronDownIcon as s } from "../../lib/icons.mjs";
9
+ import { mergeProps as c } from "../../lib/mergeProps.mjs";
10
+ import * as l from "react";
11
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
11
12
  //#region src/components/button/SplitButton.tsx
12
- var u = {
13
+ var f = {
13
14
  "extra-small": "w-auto min-w-6 min-h-6 px-1.5",
14
15
  small: "w-auto min-w-6 min-h-6 px-1.5",
15
16
  medium: "w-auto min-w-6 min-h-6 px-2",
16
17
  large: "w-auto min-w-6 min-h-6 px-2",
17
18
  "extra-large": "w-auto min-w-6 min-h-6 px-3"
18
- }, d = {
19
+ }, p = {
19
20
  primary: "border-s-primary-foreground/30",
20
21
  outline: "border-s-stroke",
21
22
  subtle: "border-s-stroke",
22
23
  transparent: "border-s-stroke"
23
- }, f = "relative min-h-6 focus-visible:z-10", p = ({ appearance: p = "outline", size: m = "medium", disabled: h = !1, disabledFocusable: g = !1, icon: _, iconPosition: v, menuIcon: y, className: b, children: x, onClick: S, onMenuClick: C, menuButtonLabel: w = "More options", menuButtonProps: T, primaryActionButtonProps: E, "aria-describedby": D, role: O, ref: k, ...A }) => {
24
- let j = a({
25
- "aria-describedby": D,
26
- onClick: S
27
- }, E), M = a({
28
- "aria-label": w,
24
+ }, m = "relative min-h-6 focus-visible:z-10", h = ({ appearance: h = "outline", size: g = "medium", disabled: _ = !1, disabledFocusable: v = !1, icon: y, iconPosition: b, menuIcon: x, className: S, children: C, onClick: w, onMenuClick: T, menuButtonLabel: E = "More options", menuButtonProps: D, primaryActionButtonProps: O, "aria-describedby": k, role: A, ref: j, ...M }) => {
25
+ let N = c({
26
+ "aria-describedby": k,
27
+ onClick: w
28
+ }, O), P = c({
29
+ "aria-label": E,
29
30
  "aria-haspopup": "menu",
30
- onClick: C
31
- }, T), N = g || !!j.disabledFocusable, P = g || !!M.disabledFocusable, { glyph: F, button: I } = o(y), L = n(F), R = I === null && y != null && !L;
32
- return s.useEffect(() => {
33
- R && t("SplitButton:menuIcon-empty", "SplitButton: `menuIcon` renders nothing, so the menu button shows the default chevron. Unlike `MenuButton`, a SplitButton always shows a menu indicator: pass an icon, or leave `menuIcon` unset.");
34
- }, [R]), s.useEffect(() => {
35
- I && t("SplitButton:menuIcon-button", `SplitButton: \`menuIcon\` received ${I}; its children render as the glyph of the menu button and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \`menuIcon={<MyIcon />}\`.`);
36
- }, [I]), /* @__PURE__ */ l("div", {
37
- ref: k,
38
- ...A,
39
- role: O ?? "group",
40
- className: e("inline-flex items-stretch", b),
41
- children: [/* @__PURE__ */ c(r, {
42
- ...j,
43
- appearance: p,
44
- size: m,
45
- disabled: !N && (h || !!j.disabled),
46
- disabledFocusable: N,
47
- icon: _,
48
- iconPosition: v,
49
- className: e(f, "rounded-e-none border-e-0", j.className),
50
- children: x
51
- }), /* @__PURE__ */ c(r, {
52
- ...M,
53
- appearance: p,
54
- size: m,
55
- disabled: !P && (h || !!M.disabled),
56
- disabledFocusable: P,
57
- icon: L ? F : /* @__PURE__ */ c(i, {}),
58
- className: e(f, u[m], "rounded-s-none", d[p], M.className)
31
+ onClick: T
32
+ }, D), F = v || !!N.disabledFocusable, I = v || !!P.disabledFocusable, { glyph: L, button: R } = a(x), z = n(L), B = R === null && x != null && !z;
33
+ return l.useEffect(() => {
34
+ B && t("SplitButton:menuIcon-empty", "SplitButton: `menuIcon` renders nothing, so the menu button shows the default chevron. Unlike `MenuButton`, a SplitButton always shows a menu indicator: pass an icon, or leave `menuIcon` unset.");
35
+ }, [B]), l.useEffect(() => {
36
+ R && t("SplitButton:menuIcon-button", `SplitButton: \`menuIcon\` received ${R}; its children render as the glyph of the menu button and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \`menuIcon={<MyIcon />}\`.`);
37
+ }, [R]), /* @__PURE__ */ d("div", {
38
+ ref: j,
39
+ ...M,
40
+ role: A ?? "group",
41
+ className: e(r.root, "inline-flex items-stretch", S),
42
+ children: [/* @__PURE__ */ u(i, {
43
+ ...N,
44
+ appearance: h,
45
+ size: g,
46
+ disabled: !F && (_ || !!N.disabled),
47
+ disabledFocusable: F,
48
+ icon: o(y, r.icon),
49
+ iconPosition: b,
50
+ className: e(r.primaryActionButton, m, "rounded-e-none border-e-0", N.className),
51
+ children: C
52
+ }), /* @__PURE__ */ u(i, {
53
+ ...P,
54
+ appearance: h,
55
+ size: g,
56
+ disabled: !I && (_ || !!P.disabled),
57
+ disabledFocusable: I,
58
+ icon: o(z ? L : /* @__PURE__ */ u(s, {}), r.menuIcon),
59
+ className: e(r.menuButton, m, f[g], "rounded-s-none", p[h], P.className)
59
60
  })]
60
61
  });
61
62
  };
62
- p.displayName = "SplitButton";
63
+ h.displayName = "SplitButton";
63
64
  //#endregion
64
- export { p as SplitButton };
65
+ export { h as SplitButton };
65
66
 
66
67
  //# sourceMappingURL=SplitButton.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"SplitButton.mjs","names":["React","menuButtonSizeClasses","separatorClasses","halfClasses","SplitButton","ariaDescribedBy","props","primary","mergeProps","primaryActionButtonProps","menu","menuButtonLabel","onMenuClick","menuButtonProps","primaryFocusable","disabledFocusable","menuFocusable","menuGlyph","menuIconButton","unwrapButtonGlyph","menuIcon","menuIconRenders","slotRendersContent","menuIconEmpty","warnOnce","role","cn","className","Button","disabled","ChevronDownIcon","size","appearance"],"sources":["../../../src/components/button/SplitButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnOnce } from '../../lib/dev';\nimport { ChevronDownIcon } from '../../lib/icons';\nimport { mergeProps } from '../../lib/mergeProps';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { unwrapButtonGlyph } from './Button.slots';\n\n/**\n * Props for one half of a SplitButton (`menuButtonProps`, `primaryActionButtonProps`): native\n * `<button>` attributes, `data-*` attributes and `ref`. They are merged onto the built-in props\n * of that half: handlers are composed (yours run first), `className` is merged, id lists are\n * joined and any other value you pass wins.\n */\nexport interface SplitButtonMenuButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Makes only this half unavailable but focusable (see `SplitButton.disabledFocusable`, which\n * affects both halves). For each half, focusable-disabled wins over natively disabled.\n * @default false\n */\n disabledFocusable?: boolean;\n /** Ref to the `<button>` element of this half. */\n ref?: React.Ref<HTMLButtonElement>;\n /** Any `data-*` attribute. */\n [dataAttribute: `data-${string}`]: string | number | boolean | undefined;\n}\n\n/** Props for the primary action half of a SplitButton (same shape as the menu half). */\nexport type SplitButtonPrimaryActionButtonProps = SplitButtonMenuButtonProps;\n\n/** Properties for the SplitButton component. */\nexport interface SplitButtonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onClick'> {\n /**\n * Disables both buttons. A half's own `disabled` (`primaryActionButtonProps`,\n * `menuButtonProps`) disables only that half.\n * @default false\n */\n disabled?: boolean;\n /**\n * Makes both halves unavailable but focusable (see `Button.disabledFocusable`): each half\n * renders `aria-disabled=\"true\"`, `data-disabled` and `data-disabled-focusable`, stays in the tab\n * order, and neither `onClick` nor the menu opens. A half's own `disabledFocusable` (in\n * `primaryActionButtonProps`/`menuButtonProps`) affects only that half. For each half,\n * focusable-disabled wins over natively disabled: the half is focusable-disabled when the root's\n * or its own `disabledFocusable` is set; otherwise it is natively disabled when the root's or its\n * own `disabled` is set.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Icon of the primary action, decorative (`aria-hidden`). For an icon-only primary action pass\n * `primaryActionButtonProps={{ 'aria-label': '…' }}`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the primary action's icon renders: before its label (the inline start) or after it.\n * Has no effect on an icon-only primary action. The menu half is not affected.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Replaces the chevron of the menu half (decorative, `aria-hidden`). The menu half always shows\n * an indicator: `null` and `undefined` keep the default chevron, and so does a value that renders\n * nothing (`false`, `''`, an empty array), which also logs a development warning. Unlike\n * `MenuButton.menuIcon`, a value that renders nothing does not hide the indicator. A `<button>`\n * or `Button` element, or a slot object whose `as` is one, is not nested inside the menu half:\n * its children become the glyph (the chevron when they render nothing), its props (`icon`\n * included) are dropped, and a development warning says so.\n */\n menuIcon?: Slot<'span'>;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting height, padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /** Click handler for the primary action button. */\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n /** Click handler for the menu (chevron) button. */\n onMenuClick?: React.MouseEventHandler<HTMLButtonElement>;\n /**\n * Accessible name of the menu button (it shows only a chevron). Localize it.\n * @default 'More options'\n */\n menuButtonLabel?: string;\n /**\n * Props for the menu button: `aria-expanded`, `aria-controls`, `id`, handlers (`onKeyDown` for\n * ArrowDown/ArrowUp), `ref` for focus restoration, … Pass the render-prop props of\n * `Menu.Trigger` here to open a Menu from the chevron.\n */\n menuButtonProps?: SplitButtonMenuButtonProps;\n /** Props for the primary action button (`ref`, `title`, handlers, …). */\n primaryActionButtonProps?: SplitButtonPrimaryActionButtonProps;\n /** Ref to the wrapping `role=\"group\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Menu button size per SplitButton size: at least 24×24 CSS px at every size (WCAG 2.5.8 target\n * size; the chevron shares an edge with the primary button, so the spacing exception does not\n * apply). Overrides the square icon-only sizing of `Button` (`w-*`, `px-0`).\n */\nconst menuButtonSizeClasses: Record<Size, string> = {\n 'extra-small': 'w-auto min-w-6 min-h-6 px-1.5',\n small: 'w-auto min-w-6 min-h-6 px-1.5',\n medium: 'w-auto min-w-6 min-h-6 px-2',\n large: 'w-auto min-w-6 min-h-6 px-2',\n 'extra-large': 'w-auto min-w-6 min-h-6 px-3',\n};\n\n/** The separator is the menu button's start border (logical, so it mirrors in RTL). */\nconst separatorClasses: Record<Appearance, string> = {\n primary: 'border-s-primary-foreground/30',\n outline: 'border-s-stroke',\n subtle: 'border-s-stroke',\n transparent: 'border-s-stroke',\n};\n\n/**\n * Keeps each half's focus ring above its neighbour. `min-h-6` keeps both halves as tall as the\n * 24px menu button target at the extra-small size.\n */\nconst halfClasses = 'relative min-h-6 focus-visible:z-10';\n\n/**\n * A primary action button joined to a menu button (chevron), e.g. Save + \"Save as…\" options.\n * Both halves are {@link Button}s with the shared appearances and sizes, inside a\n * `role=\"group\"` wrapper.\n *\n * - `ref`, `className`, `style`, `aria-label` and other props go to the group; `aria-describedby`\n * is routed to the primary button (so a Tooltip around the SplitButton describes the action).\n * - `primaryActionButtonProps` / `menuButtonProps` reach the two buttons; the menu button is\n * named by `menuButtonLabel` (default `'More options'`).\n * - The menu button is at least 24×24 px at every size, so an extra-small SplitButton is 24px tall.\n * - `icon`/`iconPosition` belong to the primary action; `menuIcon` replaces the chevron, which the\n * menu half always shows (a `menuIcon` that renders nothing keeps it).\n * - `disabledFocusable` keeps both halves focusable while unavailable; `Menu.Trigger` does not open\n * its menu from an `aria-disabled` menu half.\n *\n * @example\n * <Menu>\n * <Menu.Trigger>\n * {(triggerProps) => (\n * <SplitButton menuButtonProps={triggerProps} onClick={save}>Save</SplitButton>\n * )}\n * </Menu.Trigger>\n * <Menu.Popover>…</Menu.Popover>\n * </Menu>\n */\nexport const SplitButton = ({\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n disabledFocusable = false,\n icon,\n iconPosition,\n menuIcon,\n className,\n children,\n onClick,\n onMenuClick,\n menuButtonLabel = 'More options',\n menuButtonProps,\n primaryActionButtonProps,\n 'aria-describedby': ariaDescribedBy,\n role,\n ref,\n ...props\n}: SplitButtonProps) => {\n const primary = mergeProps(\n { 'aria-describedby': ariaDescribedBy, onClick } as SplitButtonMenuButtonProps,\n primaryActionButtonProps,\n );\n const menu = mergeProps(\n {\n 'aria-label': menuButtonLabel,\n 'aria-haspopup': 'menu',\n onClick: onMenuClick,\n } as SplitButtonMenuButtonProps,\n menuButtonProps,\n );\n\n // Per half: focusable-disabled (the root's or its own) wins over natively disabled.\n const primaryFocusable = disabledFocusable || Boolean(primary.disabledFocusable);\n const menuFocusable = disabledFocusable || Boolean(menu.disabledFocusable);\n\n // The glyph sits inside the menu half's button: a button passed as `menuIcon` is unwrapped (its\n // children are the glyph), never nested (C-SLOTS).\n const { glyph: menuGlyph, button: menuIconButton } = unwrapButtonGlyph(menuIcon);\n // The menu half always shows an indicator: a `menuIcon` that renders nothing keeps the chevron.\n const menuIconRenders = slotRendersContent(menuGlyph);\n // An unwrapped button reports its own warning only.\n const menuIconEmpty = menuIconButton === null && menuIcon != null && !menuIconRenders;\n React.useEffect(() => {\n if (menuIconEmpty) {\n warnOnce(\n 'SplitButton:menuIcon-empty',\n 'SplitButton: `menuIcon` renders nothing, so the menu button shows the default chevron. Unlike `MenuButton`, a SplitButton always shows a menu indicator: pass an icon, or leave `menuIcon` unset.',\n );\n }\n }, [menuIconEmpty]);\n React.useEffect(() => {\n if (menuIconButton) {\n warnOnce(\n 'SplitButton:menuIcon-button',\n `SplitButton: \\`menuIcon\\` received ${menuIconButton}; its children render as the glyph of the menu button and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \\`menuIcon={<MyIcon />}\\`.`,\n );\n }\n }, [menuIconButton]);\n\n // `role=\"group\"` applies wherever the consumer's role is `undefined` or `null` (as in Button).\n return (\n <div\n ref={ref}\n {...props}\n role={role ?? 'group'}\n className={cn('inline-flex items-stretch', className)}\n >\n <Button\n {...primary}\n appearance={appearance}\n size={size}\n disabled={!primaryFocusable && (disabled || Boolean(primary.disabled))}\n disabledFocusable={primaryFocusable}\n icon={icon}\n iconPosition={iconPosition}\n className={cn(halfClasses, 'rounded-e-none border-e-0', primary.className)}\n >\n {children}\n </Button>\n <Button\n {...menu}\n appearance={appearance}\n size={size}\n disabled={!menuFocusable && (disabled || Boolean(menu.disabled))}\n disabledFocusable={menuFocusable}\n icon={menuIconRenders ? menuGlyph : <ChevronDownIcon />}\n className={cn(\n halfClasses,\n menuButtonSizeClasses[size],\n 'rounded-s-none',\n separatorClasses[appearance],\n menu.className,\n )}\n />\n </div>\n );\n};\n\nSplitButton.displayName = 'SplitButton';\n"],"mappings":";;;;;;;;;;;AA0GA,IAAMC,IAA8C;CAClD,eAAe;CACf,OAAO;CACP,QAAQ;CACR,OAAO;CACP,eAAe;AACjB,GAGMC,IAA+C;CACnD,SAAS;CACT,SAAS;CACT,QAAQ;CACR,aAAa;AACf,GAMMC,IAAc,uCA2BPC,KAAe,EAC1B,gBAAa,WACb,UAAO,UACP,cAAW,IACX,uBAAoB,IACpB,SACA,iBACA,aACA,cACA,aACA,YACA,gBACA,qBAAkB,gBAClB,oBACA,6BACA,oBAAoBC,GACpB,SACA,QACA,GAAGC,QACmB;CACtB,IAAMC,IAAUC,EACd;EAAE,oBAAoBH;EAAiB;CAAQ,GAC/CI,CACF,GACMC,IAAOF,EACX;EACE,cAAcG;EACd,iBAAiB;EACjB,SAASC;CACX,GACAC,CACF,GAGMC,IAAmBC,KAAqB,EAAQR,EAAQ,mBACxDS,IAAgBD,KAAqB,EAAQL,EAAK,mBAIlD,EAAE,OAAOO,GAAW,QAAQC,MAAmBC,EAAkBC,CAAQ,GAEzEC,IAAkBC,EAAmBL,CAAS,GAE9CM,IAAgBL,MAAmB,QAAQE,KAAY,QAAQ,CAACC;CAmBtE,OAlBArB,EAAM,gBAAgB;EACpB,AAAIuB,KACFC,EACE,8BACA,mMACF;CAEJ,GAAG,CAACD,CAAa,CAAC,GAClBvB,EAAM,gBAAgB;EACpB,AAAIkB,KACFM,EACE,+BACA,sCAAsCN,EAAe,wKACvD;CAEJ,GAAG,CAACA,CAAc,CAAC,GAIjB,kBAAC,OAAD;EACO;EACL,GAAIZ;EACJ,MAAMmB,KAAQ;EACd,WAAWC,EAAG,6BAA6BC,CAAS;EAJtD,UAAA,CAME,kBAACC,GAAD;GACE,GAAIrB;GACQ;GACN;GACN,UAAU,CAACO,MAAqBe,KAAY,EAAQtB,EAAQ;GAC5D,mBAAmBO;GACb;GACQ;GACd,WAAWY,EAAGvB,GAAa,6BAA6BI,EAAQ,SAAS;GAExE;EACK,CAAA,GACR,kBAACqB,GAAD;GACE,GAAIlB;GACQ;GACN;GACN,UAAU,CAACM,MAAkBa,KAAY,EAAQnB,EAAK;GACtD,mBAAmBM;GACnB,MAAMK,IAAkBJ,IAAY,kBAACa,GAAD,CAAkB,CAAA;GACtD,WAAWJ,EACTvB,GACAF,EAAsB8B,IACtB,kBACA7B,EAAiB8B,IACjBtB,EAAK,SACP;EACD,CAAA,CACE;;AAET;AAEA,EAAY,cAAc"}
1
+ {"version":3,"file":"SplitButton.mjs","names":["React","menuButtonSizeClasses","separatorClasses","halfClasses","SplitButton","ariaDescribedBy","props","primary","mergeProps","primaryActionButtonProps","menu","menuButtonLabel","onMenuClick","menuButtonProps","primaryFocusable","disabledFocusable","menuFocusable","menuGlyph","menuIconButton","unwrapButtonGlyph","menuIcon","menuIconRenders","slotRendersContent","menuIconEmpty","warnOnce","role","cn","splitButtonClassNames","className","Button","disabled","withPartClass","icon","ChevronDownIcon","size","appearance"],"sources":["../../../src/components/button/SplitButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { splitButtonClassNames } from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { ChevronDownIcon } from '../../lib/icons';\nimport { mergeProps } from '../../lib/mergeProps';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { unwrapButtonGlyph, withPartClass } from './Button.slots';\n\n/**\n * Props for one half of a SplitButton (`menuButtonProps`, `primaryActionButtonProps`): native\n * `<button>` attributes, `data-*` attributes and `ref`. They are merged onto the built-in props\n * of that half: handlers are composed (yours run first), `className` is merged, id lists are\n * joined and any other value you pass wins.\n */\nexport interface SplitButtonMenuButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Makes only this half unavailable but focusable (see `SplitButton.disabledFocusable`, which\n * affects both halves). For each half, focusable-disabled wins over natively disabled.\n * @default false\n */\n disabledFocusable?: boolean;\n /** Ref to the `<button>` element of this half. */\n ref?: React.Ref<HTMLButtonElement>;\n /** Any `data-*` attribute. */\n [dataAttribute: `data-${string}`]: string | number | boolean | undefined;\n}\n\n/** Props for the primary action half of a SplitButton (same shape as the menu half). */\nexport type SplitButtonPrimaryActionButtonProps = SplitButtonMenuButtonProps;\n\n/** Properties for the SplitButton component. */\nexport interface SplitButtonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onClick'> {\n /**\n * Disables both buttons. A half's own `disabled` (`primaryActionButtonProps`,\n * `menuButtonProps`) disables only that half.\n * @default false\n */\n disabled?: boolean;\n /**\n * Makes both halves unavailable but focusable (see `Button.disabledFocusable`): each half\n * renders `aria-disabled=\"true\"`, `data-disabled` and `data-disabled-focusable`, stays in the tab\n * order, and neither `onClick` nor the menu opens. A half's own `disabledFocusable` (in\n * `primaryActionButtonProps`/`menuButtonProps`) affects only that half. For each half,\n * focusable-disabled wins over natively disabled: the half is focusable-disabled when the root's\n * or its own `disabledFocusable` is set; otherwise it is natively disabled when the root's or its\n * own `disabled` is set.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Icon of the primary action, decorative (`aria-hidden`). For an icon-only primary action pass\n * `primaryActionButtonProps={{ 'aria-label': '…' }}`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the primary action's icon renders: before its label (the inline start) or after it.\n * Has no effect on an icon-only primary action. The menu half is not affected.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Replaces the chevron of the menu half (decorative, `aria-hidden`). The menu half always shows\n * an indicator: `null` and `undefined` keep the default chevron, and so does a value that renders\n * nothing (`false`, `''`, an empty array), which also logs a development warning. Unlike\n * `MenuButton.menuIcon`, a value that renders nothing does not hide the indicator. A `<button>`\n * or `Button` element, or a slot object whose `as` is one, is not nested inside the menu half:\n * its children become the glyph (the chevron when they render nothing), its props (`icon`\n * included) are dropped, and a development warning says so.\n */\n menuIcon?: Slot<'span'>;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting height, padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /** Click handler for the primary action button. */\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n /** Click handler for the menu (chevron) button. */\n onMenuClick?: React.MouseEventHandler<HTMLButtonElement>;\n /**\n * Accessible name of the menu button (it shows only a chevron). Localize it.\n * @default 'More options'\n */\n menuButtonLabel?: string;\n /**\n * Props for the menu button: `aria-expanded`, `aria-controls`, `id`, handlers (`onKeyDown` for\n * ArrowDown/ArrowUp), `ref` for focus restoration, … Pass the render-prop props of\n * `Menu.Trigger` here to open a Menu from the chevron.\n */\n menuButtonProps?: SplitButtonMenuButtonProps;\n /** Props for the primary action button (`ref`, `title`, handlers, …). */\n primaryActionButtonProps?: SplitButtonPrimaryActionButtonProps;\n /** Ref to the wrapping `role=\"group\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Menu button size per SplitButton size: at least 24×24 CSS px at every size (WCAG 2.5.8 target\n * size; the chevron shares an edge with the primary button, so the spacing exception does not\n * apply). Overrides the square icon-only sizing of `Button` (`w-*`, `px-0`).\n */\nconst menuButtonSizeClasses: Record<Size, string> = {\n 'extra-small': 'w-auto min-w-6 min-h-6 px-1.5',\n small: 'w-auto min-w-6 min-h-6 px-1.5',\n medium: 'w-auto min-w-6 min-h-6 px-2',\n large: 'w-auto min-w-6 min-h-6 px-2',\n 'extra-large': 'w-auto min-w-6 min-h-6 px-3',\n};\n\n/** The separator is the menu button's start border (logical, so it mirrors in RTL). */\nconst separatorClasses: Record<Appearance, string> = {\n primary: 'border-s-primary-foreground/30',\n outline: 'border-s-stroke',\n subtle: 'border-s-stroke',\n transparent: 'border-s-stroke',\n};\n\n/**\n * Keeps each half's focus ring above its neighbour. `min-h-6` keeps both halves as tall as the\n * 24px menu button target at the extra-small size.\n */\nconst halfClasses = 'relative min-h-6 focus-visible:z-10';\n\n/**\n * A primary action button joined to a menu button (chevron), e.g. Save + \"Save as…\" options.\n * Both halves are {@link Button}s with the shared appearances and sizes, inside a\n * `role=\"group\"` wrapper.\n *\n * - `ref`, `className`, `style`, `aria-label` and other props go to the group; `aria-describedby`\n * is routed to the primary button (so a Tooltip around the SplitButton describes the action).\n * - `primaryActionButtonProps` / `menuButtonProps` reach the two buttons; the menu button is\n * named by `menuButtonLabel` (default `'More options'`).\n * - The menu button is at least 24×24 px at every size, so an extra-small SplitButton is 24px tall.\n * - `icon`/`iconPosition` belong to the primary action; `menuIcon` replaces the chevron, which the\n * menu half always shows (a `menuIcon` that renders nothing keeps it).\n * - `disabledFocusable` keeps both halves focusable while unavailable; `Menu.Trigger` does not open\n * its menu from an `aria-disabled` menu half.\n *\n * @example\n * <Menu>\n * <Menu.Trigger>\n * {(triggerProps) => (\n * <SplitButton menuButtonProps={triggerProps} onClick={save}>Save</SplitButton>\n * )}\n * </Menu.Trigger>\n * <Menu.Popover>…</Menu.Popover>\n * </Menu>\n */\nexport const SplitButton = ({\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n disabledFocusable = false,\n icon,\n iconPosition,\n menuIcon,\n className,\n children,\n onClick,\n onMenuClick,\n menuButtonLabel = 'More options',\n menuButtonProps,\n primaryActionButtonProps,\n 'aria-describedby': ariaDescribedBy,\n role,\n ref,\n ...props\n}: SplitButtonProps) => {\n const primary = mergeProps(\n { 'aria-describedby': ariaDescribedBy, onClick } as SplitButtonMenuButtonProps,\n primaryActionButtonProps,\n );\n const menu = mergeProps(\n {\n 'aria-label': menuButtonLabel,\n 'aria-haspopup': 'menu',\n onClick: onMenuClick,\n } as SplitButtonMenuButtonProps,\n menuButtonProps,\n );\n\n // Per half: focusable-disabled (the root's or its own) wins over natively disabled.\n const primaryFocusable = disabledFocusable || Boolean(primary.disabledFocusable);\n const menuFocusable = disabledFocusable || Boolean(menu.disabledFocusable);\n\n // The glyph sits inside the menu half's button: a button passed as `menuIcon` is unwrapped (its\n // children are the glyph), never nested (C-SLOTS).\n const { glyph: menuGlyph, button: menuIconButton } = unwrapButtonGlyph(menuIcon);\n // The menu half always shows an indicator: a `menuIcon` that renders nothing keeps the chevron.\n const menuIconRenders = slotRendersContent(menuGlyph);\n // An unwrapped button reports its own warning only.\n const menuIconEmpty = menuIconButton === null && menuIcon != null && !menuIconRenders;\n React.useEffect(() => {\n if (menuIconEmpty) {\n warnOnce(\n 'SplitButton:menuIcon-empty',\n 'SplitButton: `menuIcon` renders nothing, so the menu button shows the default chevron. Unlike `MenuButton`, a SplitButton always shows a menu indicator: pass an icon, or leave `menuIcon` unset.',\n );\n }\n }, [menuIconEmpty]);\n React.useEffect(() => {\n if (menuIconButton) {\n warnOnce(\n 'SplitButton:menuIcon-button',\n `SplitButton: \\`menuIcon\\` received ${menuIconButton}; its children render as the glyph of the menu button and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \\`menuIcon={<MyIcon />}\\`.`,\n );\n }\n }, [menuIconButton]);\n\n // `role=\"group\"` applies wherever the consumer's role is `undefined` or `null` (as in Button).\n return (\n <div\n ref={ref}\n {...props}\n role={role ?? 'group'}\n className={cn(splitButtonClassNames.root, 'inline-flex items-stretch', className)}\n >\n <Button\n {...primary}\n appearance={appearance}\n size={size}\n disabled={!primaryFocusable && (disabled || Boolean(primary.disabled))}\n disabledFocusable={primaryFocusable}\n icon={withPartClass(icon, splitButtonClassNames.icon)}\n iconPosition={iconPosition}\n className={cn(\n splitButtonClassNames.primaryActionButton,\n halfClasses,\n 'rounded-e-none border-e-0',\n primary.className,\n )}\n >\n {children}\n </Button>\n <Button\n {...menu}\n appearance={appearance}\n size={size}\n disabled={!menuFocusable && (disabled || Boolean(menu.disabled))}\n disabledFocusable={menuFocusable}\n icon={withPartClass(\n menuIconRenders ? menuGlyph : <ChevronDownIcon />,\n splitButtonClassNames.menuIcon,\n )}\n className={cn(\n splitButtonClassNames.menuButton,\n halfClasses,\n menuButtonSizeClasses[size],\n 'rounded-s-none',\n separatorClasses[appearance],\n menu.className,\n )}\n />\n </div>\n );\n};\n\nSplitButton.displayName = 'SplitButton';\n"],"mappings":";;;;;;;;;;;;AA2GA,IAAMC,IAA8C;CAClD,eAAe;CACf,OAAO;CACP,QAAQ;CACR,OAAO;CACP,eAAe;AACjB,GAGMC,IAA+C;CACnD,SAAS;CACT,SAAS;CACT,QAAQ;CACR,aAAa;AACf,GAMMC,IAAc,uCA2BPC,KAAe,EAC1B,gBAAa,WACb,UAAO,UACP,cAAW,IACX,uBAAoB,IACpB,SACA,iBACA,aACA,cACA,aACA,YACA,gBACA,qBAAkB,gBAClB,oBACA,6BACA,oBAAoBC,GACpB,SACA,QACA,GAAGC,QACmB;CACtB,IAAMC,IAAUC,EACd;EAAE,oBAAoBH;EAAiB;CAAQ,GAC/CI,CACF,GACMC,IAAOF,EACX;EACE,cAAcG;EACd,iBAAiB;EACjB,SAASC;CACX,GACAC,CACF,GAGMC,IAAmBC,KAAqB,EAAQR,EAAQ,mBACxDS,IAAgBD,KAAqB,EAAQL,EAAK,mBAIlD,EAAE,OAAOO,GAAW,QAAQC,MAAmBC,EAAkBC,CAAQ,GAEzEC,IAAkBC,EAAmBL,CAAS,GAE9CM,IAAgBL,MAAmB,QAAQE,KAAY,QAAQ,CAACC;CAmBtE,OAlBArB,EAAM,gBAAgB;EACpB,AAAIuB,KACFC,EACE,8BACA,mMACF;CAEJ,GAAG,CAACD,CAAa,CAAC,GAClBvB,EAAM,gBAAgB;EACpB,AAAIkB,KACFM,EACE,+BACA,sCAAsCN,EAAe,wKACvD;CAEJ,GAAG,CAACA,CAAc,CAAC,GAIjB,kBAAC,OAAD;EACO;EACL,GAAIZ;EACJ,MAAMmB,KAAQ;EACd,WAAWC,EAAGC,EAAsB,MAAM,6BAA6BC,CAAS;EAJlF,UAAA,CAME,kBAACC,GAAD;GACE,GAAItB;GACQ;GACN;GACN,UAAU,CAACO,MAAqBgB,KAAY,EAAQvB,EAAQ;GAC5D,mBAAmBO;GACnB,MAAMiB,EAAcC,GAAML,EAAsB,IAAI;GACtC;GACd,WAAWD,EACTC,EAAsB,qBACtBxB,GACA,6BACAI,EAAQ,SACV;GAEC;EACK,CAAA,GACR,kBAACsB,GAAD;GACE,GAAInB;GACQ;GACN;GACN,UAAU,CAACM,MAAkBc,KAAY,EAAQpB,EAAK;GACtD,mBAAmBM;GACnB,MAAMe,EACJV,IAAkBJ,IAAY,kBAACgB,GAAD,CAAkB,CAAA,GAChDN,EAAsB,QACxB;GACA,WAAWD,EACTC,EAAsB,YACtBxB,GACAF,EAAsBiC,IACtB,kBACAhC,EAAiBiC,IACjBzB,EAAK,SACP;EACD,CAAA,CACE;;AAET;AAEA,EAAY,cAAc"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../hooks/useControllable.cjs"),a=require("./buttonStyles.cjs"),o=require("./Button.cjs");let s=require("react");s=e.__toESM(s,1);let c=require("react/jsx-runtime");var l=new Map;function u(e,t,n){let r=`${e}:${String(t)}:${String(n)}`,i=l.get(r);if(i===void 0){let o=new Set(a.buttonClassName({appearance:e,disabled:t}).split(/\s+/));i=a.buttonClassName({appearance:e,disabled:t,pressed:!0,accessible:n}).split(/\s+/).filter(e=>e!==``&&!o.has(e)).join(` `),l.set(r,i)}return i}var d=new Set([`checkbox`,`radio`,`switch`,`menuitemcheckbox`,`menuitemradio`,`option`,`treeitem`]);function f(e){let t=e?.trim().split(/\s+/)[0]?.toLowerCase()??``;return t===``||t===`button`?`pressed`:d.has(t)?`checked`:`none`}var p=({pressed:e,defaultPressed:a=!1,onPressedChange:l,appearance:d=`outline`,size:p=`medium`,disabled:m=!1,disabledFocusable:h=!1,isAccessible:g=!1,className:_,onClick:v,...y})=>{let[b,x]=i.useControllable(e,a,l),S=r.composeEventHandlers(v,()=>x(e=>!e)),C=y[`aria-disabled`],w=m||h||C===!0||C===`true`,T=y.role,E=f(T);return s.useEffect(()=>{E===`none`&&n.warnOnce(`ToggleButton:role-state`,`ToggleButton: \`role="${String(T).trim()}"\` allows neither \`aria-pressed\` nor \`aria-checked\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \`button\`), or use a role that has a checked state: \`checkbox\`, \`radio\`, \`switch\`, \`menuitemcheckbox\`, \`menuitemradio\`, \`option\` or \`treeitem\`.`)},[E,T]),(0,c.jsx)(o.Button,{...y,appearance:d,size:p,disabled:m,disabledFocusable:h,"aria-pressed":E===`pressed`?b:void 0,...E===`checked`&&{"aria-checked":b,"data-checked":b?``:void 0},"data-pressed":b?``:void 0,onClick:S,className:t.cn(b&&u(d,w,g),_)})};p.displayName=`ToggleButton`,exports.ToggleButton=p;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useControllable.cjs"),o=require("./buttonStyles.cjs"),s=require("./Button.cjs"),c=require("./Button.slots.cjs");let l=require("react");l=e.__toESM(l,1);let u=require("react/jsx-runtime");var d=new Map;function f(e,t,n){let r=`${e}:${String(t)}:${String(n)}`,i=d.get(r);if(i===void 0){let a=new Set(o.buttonClassName({appearance:e,disabled:t}).split(/\s+/));i=o.buttonClassName({appearance:e,disabled:t,pressed:!0,accessible:n}).split(/\s+/).filter(e=>e!==``&&!a.has(e)).join(` `),d.set(r,i)}return i}var p=new Set([`checkbox`,`radio`,`switch`,`menuitemcheckbox`,`menuitemradio`,`option`,`treeitem`]);function m(e){let t=e?.trim().split(/\s+/)[0]?.toLowerCase()??``;return t===``||t===`button`?`pressed`:p.has(t)?`checked`:`none`}var h=({pressed:e,defaultPressed:o=!1,onPressedChange:d,appearance:p=`outline`,size:h=`medium`,disabled:g=!1,disabledFocusable:_=!1,isAccessible:v=!1,icon:y,className:b,onClick:x,...S})=>{let[C,w]=a.useControllable(e,o,d),T=r.composeEventHandlers(x,()=>w(e=>!e)),E=S[`aria-disabled`],D=g||_||E===!0||E===`true`,O=S.role,k=m(O);return l.useEffect(()=>{k===`none`&&n.warnOnce(`ToggleButton:role-state`,`ToggleButton: \`role="${String(O).trim()}"\` allows neither \`aria-pressed\` nor \`aria-checked\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \`button\`), or use a role that has a checked state: \`checkbox\`, \`radio\`, \`switch\`, \`menuitemcheckbox\`, \`menuitemradio\`, \`option\` or \`treeitem\`.`)},[k,O]),(0,u.jsx)(s.Button,{...S,icon:c.withPartClass(y,i.toggleButtonClassNames.icon),appearance:p,size:h,disabled:g,disabledFocusable:_,"aria-pressed":k===`pressed`?C:void 0,...k===`checked`&&{"aria-checked":C,"data-checked":C?``:void 0},"data-pressed":C?``:void 0,onClick:T,className:t.cn(i.toggleButtonClassNames.root,C&&f(p,D,v),b)})};h.displayName=`ToggleButton`,exports.ToggleButton=h;
2
2
  //# sourceMappingURL=ToggleButton.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleButton.cjs","names":["buttonClassName","useControllable","composeEventHandlers","Button","cn","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_useControllable","require_buttonStyles","require_Button","react","react_jsx_runtime","pressedLayerCache","getPressedLayer","key","appearance","disabled","accessible","layer","unpressed","cls","CHECKED_ROLES","stateAttributeFor","token","role","ToggleButton","props","isPressed","setPressed","pressed","defaultPressed","onPressedChange","handleClick","onClick","current","ariaDisabled","disabledLook","disabledFocusable","stateAttribute","isAccessible","className"],"sources":["../../../src/components/button/ToggleButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { useControllable } from '../../hooks/useControllable';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { buttonClassName } from './buttonStyles';\n\n/** Properties for the ToggleButton component. */\nexport interface ToggleButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'onChange'\n> {\n /** Controlled pressed state. */\n pressed?: boolean;\n /** Initial pressed state for uncontrolled usage.\n * @default false\n */\n defaultPressed?: boolean;\n /**\n * Called with the new pressed state when the user toggles the button. Fires only when the state\n * changes (once per click, also in StrictMode). In controlled mode the button keeps showing\n * `pressed` until the parent passes the new value.\n */\n onPressedChange?: (pressed: boolean) => void;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting height, padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon slot rendered before the label (after it with `iconPosition=\"after\"`). Decorative: it\n * renders with `aria-hidden=\"true\"` (a slot object can override it). An icon-only toggle needs\n * `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the icon renders: before the label (the inline start) or after it (the inline end).\n * Follows the writing direction through DOM order. Has no effect on an icon-only toggle.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Marks the toggle unavailable but keeps it focusable and in the tab order (see\n * `Button.disabledFocusable`): `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable` instead of the native `disabled` attribute. Clicks, Enter and Space\n * neither toggle it nor call `onClick` or `onPressedChange`; a pressed toggle shows the pressed\n * and disabled look. Wins over `disabled` when both are set. In a `Toolbar` it stays in the\n * arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Draws the pressed state as a brand fill with on-brand text (on `primary`, the pressed fill with\n * an inset on-brand stroke), so the state never depends on a light tint (Fluent's\n * `isAccessible`). Recommended for icon-only toggles in toolbars. Forced colors are unchanged.\n * @default false\n */\n isAccessible?: boolean;\n /** Ref to the rendered `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * The classes `buttonClassName({ pressed: true, accessible })` adds on top of the unpressed button,\n * per appearance, disabled state and `isAccessible`. Derived from the shared maps (never re-typed),\n * so ToggleButton's pressed look is exactly the button family's: `Button` merges them after its own\n * classes with `cn()`, which replaces the conflicting unpressed colors. Size classes are not\n * involved.\n */\nconst pressedLayerCache = new Map<string, string>();\nfunction getPressedLayer(appearance: Appearance, disabled: boolean, accessible: boolean): string {\n const key = `${appearance}:${String(disabled)}:${String(accessible)}`;\n let layer = pressedLayerCache.get(key);\n if (layer === undefined) {\n const unpressed = new Set(buttonClassName({ appearance, disabled }).split(/\\s+/));\n layer = buttonClassName({ appearance, disabled, pressed: true, accessible })\n .split(/\\s+/)\n .filter((cls) => cls !== '' && !unpressed.has(cls))\n .join(' ');\n pressedLayerCache.set(key, layer);\n }\n return layer;\n}\n\n/**\n * The roles that report a toggle's state with `aria-checked` (`aria-pressed` is allowed only on\n * `button`).\n */\nconst CHECKED_ROLES: ReadonlySet<string> = new Set([\n 'checkbox',\n 'radio',\n 'switch',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'treeitem',\n]);\n\n/**\n * Which attribute reports the pressed state for `role` (its first token, ASCII case-insensitive):\n * `'pressed'` (no role or `button`), `'checked'` (a checked role) or `'none'` (any other role).\n */\nfunction stateAttributeFor(role: string | undefined): 'pressed' | 'checked' | 'none' {\n const token = role?.trim().split(/\\s+/)[0]?.toLowerCase() ?? '';\n if (token === '' || token === 'button') return 'pressed';\n return CHECKED_ROLES.has(token) ? 'checked' : 'none';\n}\n\n/**\n * A button that switches between pressed and unpressed, e.g. Bold in a text toolbar. Built on\n * {@link Button}: same appearances, sizes, `type=\"button\"` default, decorative icon slot and\n * icon-only warning. The pressed look uses the shared pressed colors (selected tokens; a Highlight\n * outline in forced colors), or a brand fill with `isAccessible`.\n *\n * - Uncontrolled: `defaultPressed`; controlled: `pressed` + `onPressedChange`.\n * - A consumer `onClick` runs first; calling `event.preventDefault()` in it cancels the toggle.\n * - It reports its state with `aria-pressed` without a `role` or with `role=\"button\"`. With `role`\n * `checkbox`, `radio`, `switch`, `menuitemcheckbox`, `menuitemradio`, `option` or `treeitem` it\n * reports it with `aria-checked` (and `data-checked` while pressed) instead; with any other role\n * it renders neither (development warning), because `aria-pressed` is allowed only on buttons.\n * `data-pressed` is present while pressed in every case.\n *\n * @example\n * <ToggleButton icon={<BoldIcon />} aria-label=\"Bold\" />\n * <ToggleButton pressed={bold} onPressedChange={setBold}>Bold</ToggleButton>\n * <ToggleButton role=\"checkbox\" isAccessible icon={<GridIcon />} aria-label=\"Grid\" />\n */\nexport const ToggleButton = ({\n pressed,\n defaultPressed = false,\n onPressedChange,\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n disabledFocusable = false,\n isAccessible = false,\n className,\n onClick,\n ...props\n}: ToggleButtonProps) => {\n const [isPressed, setPressed] = useControllable(pressed, defaultPressed, onPressedChange);\n\n // With `disabledFocusable`, Button replaces this handler, so the toggle never runs.\n const handleClick = composeEventHandlers(onClick, () => setPressed((current) => !current));\n\n // Button shows the disabled look for `disabled`, `disabledFocusable` and a consumer\n // `aria-disabled` alike.\n const ariaDisabled = props['aria-disabled'];\n const disabledLook =\n disabled || disabledFocusable || ariaDisabled === true || ariaDisabled === 'true';\n\n const role = props.role;\n const stateAttribute = stateAttributeFor(role);\n React.useEffect(() => {\n if (stateAttribute !== 'none') return;\n warnOnce(\n 'ToggleButton:role-state',\n `ToggleButton: \\`role=\"${String(role).trim()}\"\\` allows neither \\`aria-pressed\\` nor \\`aria-checked\\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \\`button\\`), or use a role that has a checked state: \\`checkbox\\`, \\`radio\\`, \\`switch\\`, \\`menuitemcheckbox\\`, \\`menuitemradio\\`, \\`option\\` or \\`treeitem\\`.`,\n );\n }, [stateAttribute, role]);\n\n return (\n <Button\n {...props}\n appearance={appearance}\n size={size}\n disabled={disabled}\n disabledFocusable={disabledFocusable}\n // After the consumer's props: the attribute the role allows reports the state, and a\n // consumer `aria-pressed` never survives where it is not allowed.\n aria-pressed={stateAttribute === 'pressed' ? isPressed : undefined}\n {...(stateAttribute === 'checked' && {\n 'aria-checked': isPressed,\n 'data-checked': isPressed ? '' : undefined,\n })}\n data-pressed={isPressed ? '' : undefined}\n onClick={handleClick}\n className={cn(\n isPressed && getPressedLayer(appearance, disabledLook, isAccessible),\n className,\n )}\n />\n );\n};\n\nToggleButton.displayName = 'ToggleButton';\n"],"mappings":"oWA0EA,IAAMc,EAAoB,IAAI,IAC9B,SAASC,EAAgB,EAAwB,EAAmB,EAA6B,CAC/F,IAAMC,EAAM,GAAGC,EAAW,GAAG,OAAOC,CAAQ,EAAE,GAAG,OAAOC,CAAU,IAC9DC,EAAQN,EAAkB,IAAIE,CAAG,EACrC,GAAII,IAAU,IAAA,GAAW,CACvB,IAAMC,EAAY,IAAI,IAAIrB,EAAAA,gBAAgB,CAAE,aAAY,UAAS,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAChF,EAAQA,EAAAA,gBAAgB,CAAE,aAAY,WAAU,QAAS,GAAM,YAAW,CAAC,CAAC,CACzE,MAAM,KAAK,CAAC,CACZ,OAAQ,GAAQsB,IAAQ,IAAM,CAACD,EAAU,IAAIC,CAAG,CAAC,CAAC,CAClD,KAAK,GAAG,EACXR,EAAkB,IAAIE,EAAKI,CAAK,CAClC,CACA,OAAOA,CACT,CAMA,IAAMG,EAAqC,IAAI,IAAI,CACjD,WACA,QACA,SACA,mBACA,gBACA,SACA,UACF,CAAC,EAMD,SAASC,EAAkB,EAA0D,CACnF,IAAMC,EAAQC,GAAM,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,EAAE,YAAY,GAAK,GAE7D,OADID,IAAU,IAAMA,IAAU,SAAiB,UACxCF,EAAc,IAAIE,CAAK,EAAI,UAAY,MAChD,CAqBA,IAAaE,GAAgB,CAC3B,UACA,iBAAiB,GACjB,kBACA,aAAa,UACb,OAAO,SACP,WAAW,GACX,oBAAoB,GACpB,eAAe,GACf,YACA,UACA,GAAGC,KACoB,CACvB,GAAM,CAACC,EAAWC,GAAc7B,EAAAA,gBAAgB8B,EAASC,EAAgBC,CAAe,EAGlFC,EAAchC,EAAAA,qBAAqBiC,MAAeL,EAAY,GAAY,CAACM,CAAO,CAAC,EAInFC,EAAeT,EAAM,iBACrBU,EACJpB,GAAYqB,GAAqBF,IAAiB,IAAQA,IAAiB,OAEvEX,EAAOE,EAAM,KACbY,EAAiBhB,EAAkBE,CAAI,EAS7C,OARAd,EAAM,cAAgB,CAChB4B,IAAmB,QACvBjC,EAAA,SACE,0BACA,yBAAyB,OAAOmB,CAAI,CAAC,CAAC,KAAK,EAAE,iTAC/C,CACF,EAAG,CAACc,EAAgBd,CAAI,CAAC,GAGvB,EAAAb,EAAA,IAAA,CAACV,EAAAA,OAAD,CACE,GAAIyB,EACQ,aACN,OACI,WACS,oBAGnB,eAAcY,IAAmB,UAAYX,EAAY,IAAA,GACzD,GAAKW,IAAmB,WAAa,CACnC,eAAgBX,EAChB,eAAgBA,EAAY,GAAK,IAAA,EACnC,EACA,eAAcA,EAAY,GAAK,IAAA,GAC/B,QAASK,EACT,UAAW9B,EAAAA,GACTyB,GAAad,EAAgBE,EAAYqB,EAAcG,CAAY,EACnEC,CACF,CACD,CAAA,CAEL,EAEA,EAAa,YAAc"}
1
+ {"version":3,"file":"ToggleButton.cjs","names":["buttonClassName","useControllable","composeEventHandlers","Button","withPartClass","toggleButtonClassNames","cn","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_classNames","require_useControllable","require_buttonStyles","require_Button","require_Button_slots","react","react_jsx_runtime","pressedLayerCache","getPressedLayer","key","appearance","disabled","accessible","layer","unpressed","cls","CHECKED_ROLES","stateAttributeFor","token","role","ToggleButton","props","isPressed","setPressed","pressed","defaultPressed","onPressedChange","handleClick","onClick","current","ariaDisabled","disabledLook","disabledFocusable","stateAttribute","icon","isAccessible","className"],"sources":["../../../src/components/button/ToggleButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { toggleButtonClassNames } from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { useControllable } from '../../hooks/useControllable';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { withPartClass } from './Button.slots';\nimport { buttonClassName } from './buttonStyles';\n\n/** Properties for the ToggleButton component. */\nexport interface ToggleButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'onChange'\n> {\n /** Controlled pressed state. */\n pressed?: boolean;\n /** Initial pressed state for uncontrolled usage.\n * @default false\n */\n defaultPressed?: boolean;\n /**\n * Called with the new pressed state when the user toggles the button. Fires only when the state\n * changes (once per click, also in StrictMode). In controlled mode the button keeps showing\n * `pressed` until the parent passes the new value.\n */\n onPressedChange?: (pressed: boolean) => void;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting height, padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon slot rendered before the label (after it with `iconPosition=\"after\"`). Decorative: it\n * renders with `aria-hidden=\"true\"` (a slot object can override it). An icon-only toggle needs\n * `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the icon renders: before the label (the inline start) or after it (the inline end).\n * Follows the writing direction through DOM order. Has no effect on an icon-only toggle.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Marks the toggle unavailable but keeps it focusable and in the tab order (see\n * `Button.disabledFocusable`): `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable` instead of the native `disabled` attribute. Clicks, Enter and Space\n * neither toggle it nor call `onClick` or `onPressedChange`; a pressed toggle shows the pressed\n * and disabled look. Wins over `disabled` when both are set. In a `Toolbar` it stays in the\n * arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Draws the pressed state as a brand fill with on-brand text (on `primary`, the pressed fill with\n * an inset on-brand stroke), so the state never depends on a light tint (Fluent's\n * `isAccessible`). Recommended for icon-only toggles in toolbars. Forced colors are unchanged.\n * @default false\n */\n isAccessible?: boolean;\n /** Ref to the rendered `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * The classes `buttonClassName({ pressed: true, accessible })` adds on top of the unpressed button,\n * per appearance, disabled state and `isAccessible`. Derived from the shared maps (never re-typed),\n * so ToggleButton's pressed look is exactly the button family's: `Button` merges them after its own\n * classes with `cn()`, which replaces the conflicting unpressed colors. Size classes are not\n * involved.\n */\nconst pressedLayerCache = new Map<string, string>();\nfunction getPressedLayer(appearance: Appearance, disabled: boolean, accessible: boolean): string {\n const key = `${appearance}:${String(disabled)}:${String(accessible)}`;\n let layer = pressedLayerCache.get(key);\n if (layer === undefined) {\n const unpressed = new Set(buttonClassName({ appearance, disabled }).split(/\\s+/));\n layer = buttonClassName({ appearance, disabled, pressed: true, accessible })\n .split(/\\s+/)\n .filter((cls) => cls !== '' && !unpressed.has(cls))\n .join(' ');\n pressedLayerCache.set(key, layer);\n }\n return layer;\n}\n\n/**\n * The roles that report a toggle's state with `aria-checked` (`aria-pressed` is allowed only on\n * `button`).\n */\nconst CHECKED_ROLES: ReadonlySet<string> = new Set([\n 'checkbox',\n 'radio',\n 'switch',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'treeitem',\n]);\n\n/**\n * Which attribute reports the pressed state for `role` (its first token, ASCII case-insensitive):\n * `'pressed'` (no role or `button`), `'checked'` (a checked role) or `'none'` (any other role).\n */\nfunction stateAttributeFor(role: string | undefined): 'pressed' | 'checked' | 'none' {\n const token = role?.trim().split(/\\s+/)[0]?.toLowerCase() ?? '';\n if (token === '' || token === 'button') return 'pressed';\n return CHECKED_ROLES.has(token) ? 'checked' : 'none';\n}\n\n/**\n * A button that switches between pressed and unpressed, e.g. Bold in a text toolbar. Built on\n * {@link Button}: same appearances, sizes, `type=\"button\"` default, decorative icon slot and\n * icon-only warning. The pressed look uses the shared pressed colors (selected tokens; a Highlight\n * outline in forced colors), or a brand fill with `isAccessible`.\n *\n * - Uncontrolled: `defaultPressed`; controlled: `pressed` + `onPressedChange`.\n * - A consumer `onClick` runs first; calling `event.preventDefault()` in it cancels the toggle.\n * - It reports its state with `aria-pressed` without a `role` or with `role=\"button\"`. With `role`\n * `checkbox`, `radio`, `switch`, `menuitemcheckbox`, `menuitemradio`, `option` or `treeitem` it\n * reports it with `aria-checked` (and `data-checked` while pressed) instead; with any other role\n * it renders neither (development warning), because `aria-pressed` is allowed only on buttons.\n * `data-pressed` is present while pressed in every case.\n *\n * @example\n * <ToggleButton icon={<BoldIcon />} aria-label=\"Bold\" />\n * <ToggleButton pressed={bold} onPressedChange={setBold}>Bold</ToggleButton>\n * <ToggleButton role=\"checkbox\" isAccessible icon={<GridIcon />} aria-label=\"Grid\" />\n */\nexport const ToggleButton = ({\n pressed,\n defaultPressed = false,\n onPressedChange,\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n disabledFocusable = false,\n isAccessible = false,\n icon,\n className,\n onClick,\n ...props\n}: ToggleButtonProps) => {\n const [isPressed, setPressed] = useControllable(pressed, defaultPressed, onPressedChange);\n\n // With `disabledFocusable`, Button replaces this handler, so the toggle never runs.\n const handleClick = composeEventHandlers(onClick, () => setPressed((current) => !current));\n\n // Button shows the disabled look for `disabled`, `disabledFocusable` and a consumer\n // `aria-disabled` alike.\n const ariaDisabled = props['aria-disabled'];\n const disabledLook =\n disabled || disabledFocusable || ariaDisabled === true || ariaDisabled === 'true';\n\n const role = props.role;\n const stateAttribute = stateAttributeFor(role);\n React.useEffect(() => {\n if (stateAttribute !== 'none') return;\n warnOnce(\n 'ToggleButton:role-state',\n `ToggleButton: \\`role=\"${String(role).trim()}\"\\` allows neither \\`aria-pressed\\` nor \\`aria-checked\\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \\`button\\`), or use a role that has a checked state: \\`checkbox\\`, \\`radio\\`, \\`switch\\`, \\`menuitemcheckbox\\`, \\`menuitemradio\\`, \\`option\\` or \\`treeitem\\`.`,\n );\n }, [stateAttribute, role]);\n\n return (\n <Button\n {...props}\n icon={withPartClass(icon, toggleButtonClassNames.icon)}\n appearance={appearance}\n size={size}\n disabled={disabled}\n disabledFocusable={disabledFocusable}\n // After the consumer's props: the attribute the role allows reports the state, and a\n // consumer `aria-pressed` never survives where it is not allowed.\n aria-pressed={stateAttribute === 'pressed' ? isPressed : undefined}\n {...(stateAttribute === 'checked' && {\n 'aria-checked': isPressed,\n 'data-checked': isPressed ? '' : undefined,\n })}\n data-pressed={isPressed ? '' : undefined}\n onClick={handleClick}\n className={cn(\n toggleButtonClassNames.root,\n isPressed && getPressedLayer(appearance, disabledLook, isAccessible),\n className,\n )}\n />\n );\n};\n\nToggleButton.displayName = 'ToggleButton';\n"],"mappings":"0aA4EA,IAAMkB,EAAoB,IAAI,IAC9B,SAASC,EAAgB,EAAwB,EAAmB,EAA6B,CAC/F,IAAMC,EAAM,GAAGC,EAAW,GAAG,OAAOC,CAAQ,EAAE,GAAG,OAAOC,CAAU,IAC9DC,EAAQN,EAAkB,IAAIE,CAAG,EACrC,GAAII,IAAU,IAAA,GAAW,CACvB,IAAMC,EAAY,IAAI,IAAIzB,EAAAA,gBAAgB,CAAE,aAAY,UAAS,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAChF,EAAQA,EAAAA,gBAAgB,CAAE,aAAY,WAAU,QAAS,GAAM,YAAW,CAAC,CAAC,CACzE,MAAM,KAAK,CAAC,CACZ,OAAQ,GAAQ0B,IAAQ,IAAM,CAACD,EAAU,IAAIC,CAAG,CAAC,CAAC,CAClD,KAAK,GAAG,EACXR,EAAkB,IAAIE,EAAKI,CAAK,CAClC,CACA,OAAOA,CACT,CAMA,IAAMG,EAAqC,IAAI,IAAI,CACjD,WACA,QACA,SACA,mBACA,gBACA,SACA,UACF,CAAC,EAMD,SAASC,EAAkB,EAA0D,CACnF,IAAMC,EAAQC,GAAM,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,EAAE,YAAY,GAAK,GAE7D,OADID,IAAU,IAAMA,IAAU,SAAiB,UACxCF,EAAc,IAAIE,CAAK,EAAI,UAAY,MAChD,CAqBA,IAAaE,GAAgB,CAC3B,UACA,iBAAiB,GACjB,kBACA,aAAa,UACb,OAAO,SACP,WAAW,GACX,oBAAoB,GACpB,eAAe,GACf,OACA,YACA,UACA,GAAGC,KACoB,CACvB,GAAM,CAACC,EAAWC,GAAcjC,EAAAA,gBAAgBkC,EAASC,EAAgBC,CAAe,EAGlFC,EAAcpC,EAAAA,qBAAqBqC,MAAeL,EAAY,GAAY,CAACM,CAAO,CAAC,EAInFC,EAAeT,EAAM,iBACrBU,EACJpB,GAAYqB,GAAqBF,IAAiB,IAAQA,IAAiB,OAEvEX,EAAOE,EAAM,KACbY,EAAiBhB,EAAkBE,CAAI,EAS7C,OARAd,EAAM,cAAgB,CAChB4B,IAAmB,QACvBnC,EAAA,SACE,0BACA,yBAAyB,OAAOqB,CAAI,CAAC,CAAC,KAAK,EAAE,iTAC/C,CACF,EAAG,CAACc,EAAgBd,CAAI,CAAC,GAGvB,EAAAb,EAAA,IAAA,CAACd,EAAAA,OAAD,CACE,GAAI6B,EACJ,KAAM5B,EAAAA,cAAcyC,EAAMxC,EAAAA,uBAAuB,IAAI,EACzC,aACN,OACI,WACS,oBAGnB,eAAcuC,IAAmB,UAAYX,EAAY,IAAA,GACzD,GAAKW,IAAmB,WAAa,CACnC,eAAgBX,EAChB,eAAgBA,EAAY,GAAK,IAAA,EACnC,EACA,eAAcA,EAAY,GAAK,IAAA,GAC/B,QAASK,EACT,UAAWhC,EAAAA,GACTD,EAAAA,uBAAuB,KACvB4B,GAAad,EAAgBE,EAAYqB,EAAcI,CAAY,EACnEC,CACF,CACD,CAAA,CAEL,EAEA,EAAa,YAAc"}
@@ -2,30 +2,32 @@
2
2
  import { cn as e } from "../../lib/cn.mjs";
3
3
  import { warnOnce as t } from "../../lib/dev.mjs";
4
4
  import { composeEventHandlers as n } from "../../lib/composeEventHandlers.mjs";
5
- import { useControllable as r } from "../../hooks/useControllable.mjs";
6
- import { buttonClassName as i } from "./buttonStyles.mjs";
7
- import { Button as a } from "./Button.mjs";
8
- import * as o from "react";
9
- import { jsx as s } from "react/jsx-runtime";
5
+ import { toggleButtonClassNames as r } from "../../lib/classNames.mjs";
6
+ import { useControllable as i } from "../../hooks/useControllable.mjs";
7
+ import { buttonClassName as a } from "./buttonStyles.mjs";
8
+ import { Button as o } from "./Button.mjs";
9
+ import { withPartClass as s } from "./Button.slots.mjs";
10
+ import * as c from "react";
11
+ import { jsx as l } from "react/jsx-runtime";
10
12
  //#region src/components/button/ToggleButton.tsx
11
- var c = /* @__PURE__ */ new Map();
12
- function l(e, t, n) {
13
- let r = `${e}:${String(t)}:${String(n)}`, a = c.get(r);
14
- if (a === void 0) {
15
- let o = new Set(i({
13
+ var u = /* @__PURE__ */ new Map();
14
+ function d(e, t, n) {
15
+ let r = `${e}:${String(t)}:${String(n)}`, i = u.get(r);
16
+ if (i === void 0) {
17
+ let o = new Set(a({
16
18
  appearance: e,
17
19
  disabled: t
18
20
  }).split(/\s+/));
19
- a = i({
21
+ i = a({
20
22
  appearance: e,
21
23
  disabled: t,
22
24
  pressed: !0,
23
25
  accessible: n
24
- }).split(/\s+/).filter((e) => e !== "" && !o.has(e)).join(" "), c.set(r, a);
26
+ }).split(/\s+/).filter((e) => e !== "" && !o.has(e)).join(" "), u.set(r, i);
25
27
  }
26
- return a;
28
+ return i;
27
29
  }
28
- var u = /* @__PURE__ */ new Set([
30
+ var f = /* @__PURE__ */ new Set([
29
31
  "checkbox",
30
32
  "radio",
31
33
  "switch",
@@ -34,32 +36,33 @@ var u = /* @__PURE__ */ new Set([
34
36
  "option",
35
37
  "treeitem"
36
38
  ]);
37
- function d(e) {
39
+ function p(e) {
38
40
  let t = e?.trim().split(/\s+/)[0]?.toLowerCase() ?? "";
39
- return t === "" || t === "button" ? "pressed" : u.has(t) ? "checked" : "none";
41
+ return t === "" || t === "button" ? "pressed" : f.has(t) ? "checked" : "none";
40
42
  }
41
- var f = ({ pressed: i, defaultPressed: c = !1, onPressedChange: u, appearance: f = "outline", size: p = "medium", disabled: m = !1, disabledFocusable: h = !1, isAccessible: g = !1, className: _, onClick: v, ...y }) => {
42
- let [b, x] = r(i, c, u), S = n(v, () => x((e) => !e)), C = y["aria-disabled"], w = m || h || C === !0 || C === "true", T = y.role, E = d(T);
43
- return o.useEffect(() => {
44
- E === "none" && t("ToggleButton:role-state", `ToggleButton: \`role="${String(T).trim()}"\` allows neither \`aria-pressed\` nor \`aria-checked\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \`button\`), or use a role that has a checked state: \`checkbox\`, \`radio\`, \`switch\`, \`menuitemcheckbox\`, \`menuitemradio\`, \`option\` or \`treeitem\`.`);
45
- }, [E, T]), /* @__PURE__ */ s(a, {
46
- ...y,
47
- appearance: f,
48
- size: p,
49
- disabled: m,
50
- disabledFocusable: h,
51
- "aria-pressed": E === "pressed" ? b : void 0,
52
- ...E === "checked" && {
53
- "aria-checked": b,
54
- "data-checked": b ? "" : void 0
43
+ var m = ({ pressed: a, defaultPressed: u = !1, onPressedChange: f, appearance: m = "outline", size: h = "medium", disabled: g = !1, disabledFocusable: _ = !1, isAccessible: v = !1, icon: y, className: b, onClick: x, ...S }) => {
44
+ let [C, w] = i(a, u, f), T = n(x, () => w((e) => !e)), E = S["aria-disabled"], D = g || _ || E === !0 || E === "true", O = S.role, k = p(O);
45
+ return c.useEffect(() => {
46
+ k === "none" && t("ToggleButton:role-state", `ToggleButton: \`role="${String(O).trim()}"\` allows neither \`aria-pressed\` nor \`aria-checked\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \`button\`), or use a role that has a checked state: \`checkbox\`, \`radio\`, \`switch\`, \`menuitemcheckbox\`, \`menuitemradio\`, \`option\` or \`treeitem\`.`);
47
+ }, [k, O]), /* @__PURE__ */ l(o, {
48
+ ...S,
49
+ icon: s(y, r.icon),
50
+ appearance: m,
51
+ size: h,
52
+ disabled: g,
53
+ disabledFocusable: _,
54
+ "aria-pressed": k === "pressed" ? C : void 0,
55
+ ...k === "checked" && {
56
+ "aria-checked": C,
57
+ "data-checked": C ? "" : void 0
55
58
  },
56
- "data-pressed": b ? "" : void 0,
57
- onClick: S,
58
- className: e(b && l(f, w, g), _)
59
+ "data-pressed": C ? "" : void 0,
60
+ onClick: T,
61
+ className: e(r.root, C && d(m, D, v), b)
59
62
  });
60
63
  };
61
- f.displayName = "ToggleButton";
64
+ m.displayName = "ToggleButton";
62
65
  //#endregion
63
- export { f as ToggleButton };
66
+ export { m as ToggleButton };
64
67
 
65
68
  //# sourceMappingURL=ToggleButton.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleButton.mjs","names":["React","pressedLayerCache","getPressedLayer","key","appearance","disabled","accessible","layer","unpressed","buttonClassName","cls","CHECKED_ROLES","stateAttributeFor","token","role","ToggleButton","props","isPressed","setPressed","useControllable","pressed","defaultPressed","onPressedChange","handleClick","composeEventHandlers","onClick","current","ariaDisabled","disabledLook","disabledFocusable","stateAttribute","warnOnce","Button","cn","isAccessible","className"],"sources":["../../../src/components/button/ToggleButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { useControllable } from '../../hooks/useControllable';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { buttonClassName } from './buttonStyles';\n\n/** Properties for the ToggleButton component. */\nexport interface ToggleButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'onChange'\n> {\n /** Controlled pressed state. */\n pressed?: boolean;\n /** Initial pressed state for uncontrolled usage.\n * @default false\n */\n defaultPressed?: boolean;\n /**\n * Called with the new pressed state when the user toggles the button. Fires only when the state\n * changes (once per click, also in StrictMode). In controlled mode the button keeps showing\n * `pressed` until the parent passes the new value.\n */\n onPressedChange?: (pressed: boolean) => void;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting height, padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon slot rendered before the label (after it with `iconPosition=\"after\"`). Decorative: it\n * renders with `aria-hidden=\"true\"` (a slot object can override it). An icon-only toggle needs\n * `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the icon renders: before the label (the inline start) or after it (the inline end).\n * Follows the writing direction through DOM order. Has no effect on an icon-only toggle.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Marks the toggle unavailable but keeps it focusable and in the tab order (see\n * `Button.disabledFocusable`): `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable` instead of the native `disabled` attribute. Clicks, Enter and Space\n * neither toggle it nor call `onClick` or `onPressedChange`; a pressed toggle shows the pressed\n * and disabled look. Wins over `disabled` when both are set. In a `Toolbar` it stays in the\n * arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Draws the pressed state as a brand fill with on-brand text (on `primary`, the pressed fill with\n * an inset on-brand stroke), so the state never depends on a light tint (Fluent's\n * `isAccessible`). Recommended for icon-only toggles in toolbars. Forced colors are unchanged.\n * @default false\n */\n isAccessible?: boolean;\n /** Ref to the rendered `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * The classes `buttonClassName({ pressed: true, accessible })` adds on top of the unpressed button,\n * per appearance, disabled state and `isAccessible`. Derived from the shared maps (never re-typed),\n * so ToggleButton's pressed look is exactly the button family's: `Button` merges them after its own\n * classes with `cn()`, which replaces the conflicting unpressed colors. Size classes are not\n * involved.\n */\nconst pressedLayerCache = new Map<string, string>();\nfunction getPressedLayer(appearance: Appearance, disabled: boolean, accessible: boolean): string {\n const key = `${appearance}:${String(disabled)}:${String(accessible)}`;\n let layer = pressedLayerCache.get(key);\n if (layer === undefined) {\n const unpressed = new Set(buttonClassName({ appearance, disabled }).split(/\\s+/));\n layer = buttonClassName({ appearance, disabled, pressed: true, accessible })\n .split(/\\s+/)\n .filter((cls) => cls !== '' && !unpressed.has(cls))\n .join(' ');\n pressedLayerCache.set(key, layer);\n }\n return layer;\n}\n\n/**\n * The roles that report a toggle's state with `aria-checked` (`aria-pressed` is allowed only on\n * `button`).\n */\nconst CHECKED_ROLES: ReadonlySet<string> = new Set([\n 'checkbox',\n 'radio',\n 'switch',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'treeitem',\n]);\n\n/**\n * Which attribute reports the pressed state for `role` (its first token, ASCII case-insensitive):\n * `'pressed'` (no role or `button`), `'checked'` (a checked role) or `'none'` (any other role).\n */\nfunction stateAttributeFor(role: string | undefined): 'pressed' | 'checked' | 'none' {\n const token = role?.trim().split(/\\s+/)[0]?.toLowerCase() ?? '';\n if (token === '' || token === 'button') return 'pressed';\n return CHECKED_ROLES.has(token) ? 'checked' : 'none';\n}\n\n/**\n * A button that switches between pressed and unpressed, e.g. Bold in a text toolbar. Built on\n * {@link Button}: same appearances, sizes, `type=\"button\"` default, decorative icon slot and\n * icon-only warning. The pressed look uses the shared pressed colors (selected tokens; a Highlight\n * outline in forced colors), or a brand fill with `isAccessible`.\n *\n * - Uncontrolled: `defaultPressed`; controlled: `pressed` + `onPressedChange`.\n * - A consumer `onClick` runs first; calling `event.preventDefault()` in it cancels the toggle.\n * - It reports its state with `aria-pressed` without a `role` or with `role=\"button\"`. With `role`\n * `checkbox`, `radio`, `switch`, `menuitemcheckbox`, `menuitemradio`, `option` or `treeitem` it\n * reports it with `aria-checked` (and `data-checked` while pressed) instead; with any other role\n * it renders neither (development warning), because `aria-pressed` is allowed only on buttons.\n * `data-pressed` is present while pressed in every case.\n *\n * @example\n * <ToggleButton icon={<BoldIcon />} aria-label=\"Bold\" />\n * <ToggleButton pressed={bold} onPressedChange={setBold}>Bold</ToggleButton>\n * <ToggleButton role=\"checkbox\" isAccessible icon={<GridIcon />} aria-label=\"Grid\" />\n */\nexport const ToggleButton = ({\n pressed,\n defaultPressed = false,\n onPressedChange,\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n disabledFocusable = false,\n isAccessible = false,\n className,\n onClick,\n ...props\n}: ToggleButtonProps) => {\n const [isPressed, setPressed] = useControllable(pressed, defaultPressed, onPressedChange);\n\n // With `disabledFocusable`, Button replaces this handler, so the toggle never runs.\n const handleClick = composeEventHandlers(onClick, () => setPressed((current) => !current));\n\n // Button shows the disabled look for `disabled`, `disabledFocusable` and a consumer\n // `aria-disabled` alike.\n const ariaDisabled = props['aria-disabled'];\n const disabledLook =\n disabled || disabledFocusable || ariaDisabled === true || ariaDisabled === 'true';\n\n const role = props.role;\n const stateAttribute = stateAttributeFor(role);\n React.useEffect(() => {\n if (stateAttribute !== 'none') return;\n warnOnce(\n 'ToggleButton:role-state',\n `ToggleButton: \\`role=\"${String(role).trim()}\"\\` allows neither \\`aria-pressed\\` nor \\`aria-checked\\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \\`button\\`), or use a role that has a checked state: \\`checkbox\\`, \\`radio\\`, \\`switch\\`, \\`menuitemcheckbox\\`, \\`menuitemradio\\`, \\`option\\` or \\`treeitem\\`.`,\n );\n }, [stateAttribute, role]);\n\n return (\n <Button\n {...props}\n appearance={appearance}\n size={size}\n disabled={disabled}\n disabledFocusable={disabledFocusable}\n // After the consumer's props: the attribute the role allows reports the state, and a\n // consumer `aria-pressed` never survives where it is not allowed.\n aria-pressed={stateAttribute === 'pressed' ? isPressed : undefined}\n {...(stateAttribute === 'checked' && {\n 'aria-checked': isPressed,\n 'data-checked': isPressed ? '' : undefined,\n })}\n data-pressed={isPressed ? '' : undefined}\n onClick={handleClick}\n className={cn(\n isPressed && getPressedLayer(appearance, disabledLook, isAccessible),\n className,\n )}\n />\n );\n};\n\nToggleButton.displayName = 'ToggleButton';\n"],"mappings":";;;;;;;;;;AA0EA,IAAMC,oBAAoB,IAAI,IAAoB;AAClD,SAASC,EAAgB,GAAwB,GAAmB,GAA6B;CAC/F,IAAMC,IAAM,GAAGC,EAAW,GAAG,OAAOC,CAAQ,EAAE,GAAG,OAAOC,CAAU,KAC9DC,IAAQN,EAAkB,IAAIE,CAAG;CACrC,IAAII,MAAU,KAAA,GAAW;EACvB,IAAMC,IAAY,IAAI,IAAIC,EAAgB;GAAE;GAAY;EAAS,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;EAKhF,AAJA,IAAQA,EAAgB;GAAE;GAAY;GAAU,SAAS;GAAM;EAAW,CAAC,CAAC,CACzE,MAAM,KAAK,CAAC,CACZ,QAAQ,MAAQC,MAAQ,MAAM,CAACF,EAAU,IAAIE,CAAG,CAAC,CAAC,CAClD,KAAK,GAAG,GACXT,EAAkB,IAAIE,GAAKI,CAAK;CAClC;CACA,OAAOA;AACT;AAMA,IAAMI,oBAAqC,IAAI,IAAI;CACjD;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAMD,SAASC,EAAkB,GAA0D;CACnF,IAAMC,IAAQC,GAAM,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,EAAE,YAAY,KAAK;CAE7D,OADID,MAAU,MAAMA,MAAU,WAAiB,YACxCF,EAAc,IAAIE,CAAK,IAAI,YAAY;AAChD;AAqBA,IAAaE,KAAgB,EAC3B,YACA,oBAAiB,IACjB,oBACA,gBAAa,WACb,UAAO,UACP,cAAW,IACX,uBAAoB,IACpB,kBAAe,IACf,cACA,YACA,GAAGC,QACoB;CACvB,IAAM,CAACC,GAAWC,KAAcC,EAAgBC,GAASC,GAAgBC,CAAe,GAGlFC,IAAcC,EAAqBC,SAAeP,GAAY,MAAY,CAACQ,CAAO,CAAC,GAInFC,IAAeX,EAAM,kBACrBY,IACJvB,KAAYwB,KAAqBF,MAAiB,MAAQA,MAAiB,QAEvEb,IAAOE,EAAM,MACbc,IAAiBlB,EAAkBE,CAAI;CAS7C,OARAd,EAAM,gBAAgB;EACpB,AAAI8B,MAAmB,UACvBC,EACE,2BACA,yBAAyB,OAAOjB,CAAI,CAAC,CAAC,KAAK,EAAE,iTAC/C;CACF,GAAG,CAACgB,GAAgBhB,CAAI,CAAC,GAGvB,kBAACkB,GAAD;EACE,GAAIhB;EACQ;EACN;EACI;EACS;EAGnB,gBAAcc,MAAmB,YAAYb,IAAY,KAAA;EACzD,GAAKa,MAAmB,aAAa;GACnC,gBAAgBb;GAChB,gBAAgBA,IAAY,KAAK,KAAA;EACnC;EACA,gBAAcA,IAAY,KAAK,KAAA;EAC/B,SAASM;EACT,WAAWU,EACThB,KAAaf,EAAgBE,GAAYwB,GAAcM,CAAY,GACnEC,CACF;CACD,CAAA;AAEL;AAEA,EAAa,cAAc"}
1
+ {"version":3,"file":"ToggleButton.mjs","names":["React","pressedLayerCache","getPressedLayer","key","appearance","disabled","accessible","layer","unpressed","buttonClassName","cls","CHECKED_ROLES","stateAttributeFor","token","role","ToggleButton","props","isPressed","setPressed","useControllable","pressed","defaultPressed","onPressedChange","handleClick","composeEventHandlers","onClick","current","ariaDisabled","disabledLook","disabledFocusable","stateAttribute","warnOnce","Button","withPartClass","icon","toggleButtonClassNames","cn","isAccessible","className"],"sources":["../../../src/components/button/ToggleButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { toggleButtonClassNames } from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { useControllable } from '../../hooks/useControllable';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { withPartClass } from './Button.slots';\nimport { buttonClassName } from './buttonStyles';\n\n/** Properties for the ToggleButton component. */\nexport interface ToggleButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'onChange'\n> {\n /** Controlled pressed state. */\n pressed?: boolean;\n /** Initial pressed state for uncontrolled usage.\n * @default false\n */\n defaultPressed?: boolean;\n /**\n * Called with the new pressed state when the user toggles the button. Fires only when the state\n * changes (once per click, also in StrictMode). In controlled mode the button keeps showing\n * `pressed` until the parent passes the new value.\n */\n onPressedChange?: (pressed: boolean) => void;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting height, padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon slot rendered before the label (after it with `iconPosition=\"after\"`). Decorative: it\n * renders with `aria-hidden=\"true\"` (a slot object can override it). An icon-only toggle needs\n * `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the icon renders: before the label (the inline start) or after it (the inline end).\n * Follows the writing direction through DOM order. Has no effect on an icon-only toggle.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Marks the toggle unavailable but keeps it focusable and in the tab order (see\n * `Button.disabledFocusable`): `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable` instead of the native `disabled` attribute. Clicks, Enter and Space\n * neither toggle it nor call `onClick` or `onPressedChange`; a pressed toggle shows the pressed\n * and disabled look. Wins over `disabled` when both are set. In a `Toolbar` it stays in the\n * arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Draws the pressed state as a brand fill with on-brand text (on `primary`, the pressed fill with\n * an inset on-brand stroke), so the state never depends on a light tint (Fluent's\n * `isAccessible`). Recommended for icon-only toggles in toolbars. Forced colors are unchanged.\n * @default false\n */\n isAccessible?: boolean;\n /** Ref to the rendered `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * The classes `buttonClassName({ pressed: true, accessible })` adds on top of the unpressed button,\n * per appearance, disabled state and `isAccessible`. Derived from the shared maps (never re-typed),\n * so ToggleButton's pressed look is exactly the button family's: `Button` merges them after its own\n * classes with `cn()`, which replaces the conflicting unpressed colors. Size classes are not\n * involved.\n */\nconst pressedLayerCache = new Map<string, string>();\nfunction getPressedLayer(appearance: Appearance, disabled: boolean, accessible: boolean): string {\n const key = `${appearance}:${String(disabled)}:${String(accessible)}`;\n let layer = pressedLayerCache.get(key);\n if (layer === undefined) {\n const unpressed = new Set(buttonClassName({ appearance, disabled }).split(/\\s+/));\n layer = buttonClassName({ appearance, disabled, pressed: true, accessible })\n .split(/\\s+/)\n .filter((cls) => cls !== '' && !unpressed.has(cls))\n .join(' ');\n pressedLayerCache.set(key, layer);\n }\n return layer;\n}\n\n/**\n * The roles that report a toggle's state with `aria-checked` (`aria-pressed` is allowed only on\n * `button`).\n */\nconst CHECKED_ROLES: ReadonlySet<string> = new Set([\n 'checkbox',\n 'radio',\n 'switch',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'treeitem',\n]);\n\n/**\n * Which attribute reports the pressed state for `role` (its first token, ASCII case-insensitive):\n * `'pressed'` (no role or `button`), `'checked'` (a checked role) or `'none'` (any other role).\n */\nfunction stateAttributeFor(role: string | undefined): 'pressed' | 'checked' | 'none' {\n const token = role?.trim().split(/\\s+/)[0]?.toLowerCase() ?? '';\n if (token === '' || token === 'button') return 'pressed';\n return CHECKED_ROLES.has(token) ? 'checked' : 'none';\n}\n\n/**\n * A button that switches between pressed and unpressed, e.g. Bold in a text toolbar. Built on\n * {@link Button}: same appearances, sizes, `type=\"button\"` default, decorative icon slot and\n * icon-only warning. The pressed look uses the shared pressed colors (selected tokens; a Highlight\n * outline in forced colors), or a brand fill with `isAccessible`.\n *\n * - Uncontrolled: `defaultPressed`; controlled: `pressed` + `onPressedChange`.\n * - A consumer `onClick` runs first; calling `event.preventDefault()` in it cancels the toggle.\n * - It reports its state with `aria-pressed` without a `role` or with `role=\"button\"`. With `role`\n * `checkbox`, `radio`, `switch`, `menuitemcheckbox`, `menuitemradio`, `option` or `treeitem` it\n * reports it with `aria-checked` (and `data-checked` while pressed) instead; with any other role\n * it renders neither (development warning), because `aria-pressed` is allowed only on buttons.\n * `data-pressed` is present while pressed in every case.\n *\n * @example\n * <ToggleButton icon={<BoldIcon />} aria-label=\"Bold\" />\n * <ToggleButton pressed={bold} onPressedChange={setBold}>Bold</ToggleButton>\n * <ToggleButton role=\"checkbox\" isAccessible icon={<GridIcon />} aria-label=\"Grid\" />\n */\nexport const ToggleButton = ({\n pressed,\n defaultPressed = false,\n onPressedChange,\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n disabledFocusable = false,\n isAccessible = false,\n icon,\n className,\n onClick,\n ...props\n}: ToggleButtonProps) => {\n const [isPressed, setPressed] = useControllable(pressed, defaultPressed, onPressedChange);\n\n // With `disabledFocusable`, Button replaces this handler, so the toggle never runs.\n const handleClick = composeEventHandlers(onClick, () => setPressed((current) => !current));\n\n // Button shows the disabled look for `disabled`, `disabledFocusable` and a consumer\n // `aria-disabled` alike.\n const ariaDisabled = props['aria-disabled'];\n const disabledLook =\n disabled || disabledFocusable || ariaDisabled === true || ariaDisabled === 'true';\n\n const role = props.role;\n const stateAttribute = stateAttributeFor(role);\n React.useEffect(() => {\n if (stateAttribute !== 'none') return;\n warnOnce(\n 'ToggleButton:role-state',\n `ToggleButton: \\`role=\"${String(role).trim()}\"\\` allows neither \\`aria-pressed\\` nor \\`aria-checked\\`, so the pressed state is not exposed to assistive technology. Leave the role out (or use \\`button\\`), or use a role that has a checked state: \\`checkbox\\`, \\`radio\\`, \\`switch\\`, \\`menuitemcheckbox\\`, \\`menuitemradio\\`, \\`option\\` or \\`treeitem\\`.`,\n );\n }, [stateAttribute, role]);\n\n return (\n <Button\n {...props}\n icon={withPartClass(icon, toggleButtonClassNames.icon)}\n appearance={appearance}\n size={size}\n disabled={disabled}\n disabledFocusable={disabledFocusable}\n // After the consumer's props: the attribute the role allows reports the state, and a\n // consumer `aria-pressed` never survives where it is not allowed.\n aria-pressed={stateAttribute === 'pressed' ? isPressed : undefined}\n {...(stateAttribute === 'checked' && {\n 'aria-checked': isPressed,\n 'data-checked': isPressed ? '' : undefined,\n })}\n data-pressed={isPressed ? '' : undefined}\n onClick={handleClick}\n className={cn(\n toggleButtonClassNames.root,\n isPressed && getPressedLayer(appearance, disabledLook, isAccessible),\n className,\n )}\n />\n );\n};\n\nToggleButton.displayName = 'ToggleButton';\n"],"mappings":";;;;;;;;;;;;AA4EA,IAAMC,oBAAoB,IAAI,IAAoB;AAClD,SAASC,EAAgB,GAAwB,GAAmB,GAA6B;CAC/F,IAAMC,IAAM,GAAGC,EAAW,GAAG,OAAOC,CAAQ,EAAE,GAAG,OAAOC,CAAU,KAC9DC,IAAQN,EAAkB,IAAIE,CAAG;CACrC,IAAII,MAAU,KAAA,GAAW;EACvB,IAAMC,IAAY,IAAI,IAAIC,EAAgB;GAAE;GAAY;EAAS,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;EAKhF,AAJA,IAAQA,EAAgB;GAAE;GAAY;GAAU,SAAS;GAAM;EAAW,CAAC,CAAC,CACzE,MAAM,KAAK,CAAC,CACZ,QAAQ,MAAQC,MAAQ,MAAM,CAACF,EAAU,IAAIE,CAAG,CAAC,CAAC,CAClD,KAAK,GAAG,GACXT,EAAkB,IAAIE,GAAKI,CAAK;CAClC;CACA,OAAOA;AACT;AAMA,IAAMI,oBAAqC,IAAI,IAAI;CACjD;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAMD,SAASC,EAAkB,GAA0D;CACnF,IAAMC,IAAQC,GAAM,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,EAAE,YAAY,KAAK;CAE7D,OADID,MAAU,MAAMA,MAAU,WAAiB,YACxCF,EAAc,IAAIE,CAAK,IAAI,YAAY;AAChD;AAqBA,IAAaE,KAAgB,EAC3B,YACA,oBAAiB,IACjB,oBACA,gBAAa,WACb,UAAO,UACP,cAAW,IACX,uBAAoB,IACpB,kBAAe,IACf,SACA,cACA,YACA,GAAGC,QACoB;CACvB,IAAM,CAACC,GAAWC,KAAcC,EAAgBC,GAASC,GAAgBC,CAAe,GAGlFC,IAAcC,EAAqBC,SAAeP,GAAY,MAAY,CAACQ,CAAO,CAAC,GAInFC,IAAeX,EAAM,kBACrBY,IACJvB,KAAYwB,KAAqBF,MAAiB,MAAQA,MAAiB,QAEvEb,IAAOE,EAAM,MACbc,IAAiBlB,EAAkBE,CAAI;CAS7C,OARAd,EAAM,gBAAgB;EACpB,AAAI8B,MAAmB,UACvBC,EACE,2BACA,yBAAyB,OAAOjB,CAAI,CAAC,CAAC,KAAK,EAAE,iTAC/C;CACF,GAAG,CAACgB,GAAgBhB,CAAI,CAAC,GAGvB,kBAACkB,GAAD;EACE,GAAIhB;EACJ,MAAMiB,EAAcC,GAAMC,EAAuB,IAAI;EACzC;EACN;EACI;EACS;EAGnB,gBAAcL,MAAmB,YAAYb,IAAY,KAAA;EACzD,GAAKa,MAAmB,aAAa;GACnC,gBAAgBb;GAChB,gBAAgBA,IAAY,KAAK,KAAA;EACnC;EACA,gBAAcA,IAAY,KAAK,KAAA;EAC/B,SAASM;EACT,WAAWa,EACTD,EAAuB,MACvBlB,KAAaf,EAAgBE,GAAYwB,GAAcS,CAAY,GACnEC,CACF;CACD,CAAA;AAEL;AAEA,EAAa,cAAc"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/composeEventHandlers.cjs"),r=require("../../hooks/useRovingTabIndex.cjs"),i=require("../../hooks/useMergedRefs.cjs"),a=require("../../hooks/useCheckedValues.cjs"),o=require("./Toolbar.context.cjs"),s=require("./Toolbar.parts.cjs");let c=require("react");c=e.__toESM(c,1);let l=require("react/jsx-runtime");var u=`button, [href], input, select, textarea, [role="button"], [tabindex]`,d={"extra-small":`p-0.5`,small:`p-0.5`,medium:`p-1`,large:`p-1.5`,"extra-large":`p-2`},f=e=>{let{as:s,orientation:f=`horizontal`,size:p=`medium`,checkedValues:m,defaultCheckedValues:h,onCheckedValuesChange:g,className:_,ref:v,onKeyDown:y,onFocus:b,role:x,"aria-orientation":S,...C}=e,{containerProps:w}=r.useRovingTabIndex({itemSelector:u,manageTabIndex:!0,tabStop:`last-focused`,orientation:f}),T=i.useMergedRefs(w.ref,v),E=a.useCheckedValues(m,h,g),D=o.useToolbarCheckableRegistry(),O=c.useMemo(()=>({orientation:f,size:p,checked:E,registerCheckable:D}),[f,p,E,D]),k=s??`div`;return(0,l.jsx)(o.ToolbarContext.Provider,{value:O,children:(0,l.jsx)(k,{"data-size":p,"data-orientation":f,...C,role:x??`toolbar`,"aria-orientation":S??f,ref:T,"data-roving-container":``,onKeyDown:n.composeEventHandlers(y,w.onKeyDown),onFocus:n.composeEventHandlers(b,w.onFocus,{checkDefaultPrevented:!1}),className:t.cn(`inline-flex items-center gap-1 rounded border border-border`,d[p],f===`vertical`&&`flex-col items-stretch`,_)})})};f.displayName=`Toolbar`;var p=Object.assign(f,{Button:s.ToolbarButton,ToggleButton:s.ToolbarToggleButton,RadioGroup:s.ToolbarRadioGroup,RadioButton:s.ToolbarRadioButton,Group:s.ToolbarGroup,Divider:s.ToolbarDivider});exports.Toolbar=p,exports.ToolbarButton=s.ToolbarButton,exports.ToolbarDivider=s.ToolbarDivider,exports.ToolbarGroup=s.ToolbarGroup,exports.ToolbarRadioButton=s.ToolbarRadioButton,exports.ToolbarRadioGroup=s.ToolbarRadioGroup,exports.ToolbarToggleButton=s.ToolbarToggleButton;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/composeEventHandlers.cjs"),r=require("../../lib/classNames.cjs"),i=require("../../hooks/useRovingTabIndex.cjs"),a=require("../../hooks/useMergedRefs.cjs"),o=require("../../hooks/useCheckedValues.cjs"),s=require("./Toolbar.context.cjs"),c=require("./Toolbar.parts.cjs");let l=require("react");l=e.__toESM(l,1);let u=require("react/jsx-runtime");var d=`button, [href], input, select, textarea, [role="button"], [tabindex]`,f={"extra-small":`p-0.5`,small:`p-0.5`,medium:`p-1`,large:`p-1.5`,"extra-large":`p-2`},p=e=>{let{as:c,orientation:p=`horizontal`,size:m=`medium`,checkedValues:h,defaultCheckedValues:g,onCheckedValuesChange:_,className:v,ref:y,onKeyDown:b,onFocus:x,role:S,"aria-orientation":C,...w}=e,{containerProps:T}=i.useRovingTabIndex({itemSelector:d,manageTabIndex:!0,tabStop:`last-focused`,orientation:p}),E=a.useMergedRefs(T.ref,y),D=o.useCheckedValues(h,g,_),O=s.useToolbarCheckableRegistry(),k=l.useMemo(()=>({orientation:p,size:m,checked:D,registerCheckable:O}),[p,m,D,O]),A=c??`div`;return(0,u.jsx)(s.ToolbarContext.Provider,{value:k,children:(0,u.jsx)(A,{"data-size":m,"data-orientation":p,...w,role:S??`toolbar`,"aria-orientation":C??p,ref:E,"data-roving-container":``,onKeyDown:n.composeEventHandlers(b,T.onKeyDown),onFocus:n.composeEventHandlers(x,T.onFocus,{checkDefaultPrevented:!1}),className:t.cn(r.toolbarClassNames.root,`inline-flex items-center gap-1 rounded border border-border`,f[m],p===`vertical`&&`flex-col items-stretch`,v)})})};p.displayName=`Toolbar`;var m=Object.assign(p,{Button:c.ToolbarButton,ToggleButton:c.ToolbarToggleButton,RadioGroup:c.ToolbarRadioGroup,RadioButton:c.ToolbarRadioButton,Group:c.ToolbarGroup,Divider:c.ToolbarDivider});exports.Toolbar=m,exports.ToolbarButton=c.ToolbarButton,exports.ToolbarDivider=c.ToolbarDivider,exports.ToolbarGroup=c.ToolbarGroup,exports.ToolbarRadioButton=c.ToolbarRadioButton,exports.ToolbarRadioGroup=c.ToolbarRadioGroup,exports.ToolbarToggleButton=c.ToolbarToggleButton;
2
2
  //# sourceMappingURL=Toolbar.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.cjs","names":["useRovingTabIndex","useMergedRefs","useCheckedValues","useToolbarCheckableRegistry","React","ToolbarContext","composeEventHandlers","cn","ToolbarButton","ToolbarToggleButton","ToolbarRadioGroup","ToolbarRadioButton","ToolbarGroup","ToolbarDivider","require_runtime","require_cn","require_composeEventHandlers","require_useRovingTabIndex","require_useMergedRefs","require_useCheckedValues","require_Toolbar_context","require_Toolbar_parts","react","react_jsx_runtime","TOOLBAR_ITEM_SELECTOR","toolbarPaddingClasses","ToolbarRoot","ariaOrientation","rest","props","mergedRef","containerProps","ref","checked","checkedValues","defaultCheckedValues","onCheckedValuesChange","registerCheckable","context","orientation","size","Component","as","role","onKeyDown","onFocus","className","Toolbar"],"sources":["../../../src/components/button/Toolbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { CheckedValues, CheckedValuesChangeHandler, Orientation, Size } from '../../lib/types';\nimport { useCheckedValues } from '../../hooks/useCheckedValues';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { ToolbarContext, useToolbarCheckableRegistry } from './Toolbar.context';\nimport type { ToolbarContextValue } from './Toolbar.context';\nimport {\n ToolbarButton,\n ToolbarDivider,\n ToolbarGroup,\n ToolbarRadioButton,\n ToolbarRadioGroup,\n ToolbarToggleButton,\n} from './Toolbar.parts';\n\nexport {\n ToolbarButton,\n ToolbarDivider,\n ToolbarGroup,\n ToolbarRadioButton,\n ToolbarRadioGroup,\n ToolbarToggleButton,\n};\nexport type {\n ToolbarButtonOwnProps,\n ToolbarButtonProps,\n ToolbarDividerProps,\n ToolbarGroupProps,\n ToolbarRadioButtonProps,\n ToolbarRadioGroupProps,\n ToolbarToggleButtonProps,\n} from './Toolbar.parts';\n\n/**\n * The Toolbar's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props\n * only). Every other prop comes from the rendered element (`as`, default `'div'`). Give the\n * toolbar an `aria-label` (or `aria-labelledby`) that describes its purpose, e.g. \"Formatting\".\n */\nexport interface ToolbarOwnProps {\n /**\n * Layout and arrow-key axis: Left/Right move between items when horizontal (mirrored in RTL),\n * Up/Down when vertical. Exposed as `aria-orientation` and `data-orientation`.\n * @default 'horizontal'\n */\n orientation?: Orientation;\n /**\n * Default size of `Toolbar.Button`, `Toolbar.ToggleButton` and `Toolbar.RadioButton` (their\n * own `size` wins), and the toolbar's padding. Plain Buttons inside keep their own default.\n * Exposed as `data-size`.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Pressed `Toolbar.ToggleButton`s and checked `Toolbar.RadioButton`s, per group `name`\n * (controlled): `{ format: ['bold'], align: ['center'] }`.\n */\n checkedValues?: CheckedValues;\n /** Initial checked values for uncontrolled usage. @default {} */\n defaultCheckedValues?: CheckedValues;\n /**\n * Called when a toggle or radio changes them (only on change): the new checked values first,\n * then `details` with the group's `name`, its `checkedItems` and the `event` (Fluent's\n * `onCheckedValueChange(event, { name, checkedItems })`; always passed, typed optional until 1.0).\n */\n onCheckedValuesChange?: CheckedValuesChangeHandler;\n}\n\n/**\n * Props of {@link Toolbar} rendered as `C` (default `'div'`). `ToolbarProps` without a type\n * argument is the 0.4 name: the props of a Toolbar rendered as a `<div>`, including `ref`.\n */\nexport type ToolbarProps<C extends React.ElementType = 'div'> = PolymorphicProps<\n C,\n ToolbarOwnProps\n>;\n\n/** The props the implementation reads, for any `as`. */\ntype ToolbarImplProps = ToolbarOwnProps &\n React.HTMLAttributes<HTMLElement> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n };\n\n/**\n * Every focusable control a toolbar can contain, whatever component renders it. Matches that\n * cannot take focus (a `type=\"hidden\"` input, a control CSS hides) are dropped by the roving hook.\n */\nconst TOOLBAR_ITEM_SELECTOR =\n 'button, [href], input, select, textarea, [role=\"button\"], [tabindex]';\n\n/** The toolbar's padding per size. */\nconst toolbarPaddingClasses: Record<Size, string> = {\n 'extra-small': 'p-0.5',\n small: 'p-0.5',\n medium: 'p-1',\n large: 'p-1.5',\n 'extra-large': 'p-2',\n};\n\n// The root of the Toolbar compound; its component JSDoc is on the `Toolbar` export below (C-DOCS).\nconst ToolbarRoot: PolymorphicComponent<'div', ToolbarOwnProps> = (props) => {\n const {\n as,\n orientation = 'horizontal',\n size = 'medium',\n checkedValues,\n defaultCheckedValues,\n onCheckedValuesChange,\n className,\n ref,\n onKeyDown,\n onFocus,\n role,\n 'aria-orientation': ariaOrientation,\n ...rest\n } = props as ToolbarImplProps;\n\n const { containerProps } = useRovingTabIndex({\n itemSelector: TOOLBAR_ITEM_SELECTOR,\n manageTabIndex: true,\n tabStop: 'last-focused',\n orientation,\n });\n const mergedRef = useMergedRefs<HTMLElement>(containerProps.ref, ref);\n\n const checked = useCheckedValues(checkedValues, defaultCheckedValues, onCheckedValuesChange);\n const registerCheckable = useToolbarCheckableRegistry();\n const context = React.useMemo<ToolbarContextValue>(\n () => ({ orientation, size, checked, registerCheckable }),\n [orientation, size, checked, registerCheckable],\n );\n\n const Component: React.ElementType = as ?? 'div';\n // The role and `aria-orientation` defaults apply wherever the consumer's value is `undefined` or\n // `null` (as in Button), so a wrapper forwarding its own unset props keeps them.\n return (\n <ToolbarContext.Provider value={context}>\n <Component\n data-size={size}\n data-orientation={orientation}\n {...rest}\n role={role ?? 'toolbar'}\n aria-orientation={ariaOrientation ?? orientation}\n ref={mergedRef}\n data-roving-container=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, containerProps.onKeyDown)}\n onFocus={composeEventHandlers(onFocus, containerProps.onFocus, {\n checkDefaultPrevented: false,\n })}\n className={cn(\n 'inline-flex items-center gap-1 rounded border border-border',\n toolbarPaddingClasses[size],\n orientation === 'vertical' && 'flex-col items-stretch',\n className,\n )}\n />\n </ToolbarContext.Provider>\n );\n};\nToolbarRoot.displayName = 'Toolbar';\n\n/**\n * A container for a set of controls (APG Toolbar pattern): `role=\"toolbar\"`, one Tab stop, and\n * arrow-key navigation between its controls.\n *\n * - Works with any children (Buttons, ToggleButtons, links, inputs, value controls such as\n * Checkbox or Dropdown): the focusable controls are found in the DOM, and the Toolbar sets their\n * `tabIndex` itself (one `0`, the rest `-1`). The `type=\"hidden\"` input that a named value\n * control renders never counts as a control, and controls that CSS hides are skipped.\n * - Parts: `Toolbar.Button`, `Toolbar.ToggleButton` and `Toolbar.RadioButton` take the toolbar's\n * `size` (default `'medium'`) and the `subtle` appearance by default; `Toolbar.RadioGroup`,\n * `Toolbar.Group` and `Toolbar.Divider` lay them out. Plain Buttons keep their own defaults.\n * - State: the pressed `Toolbar.ToggleButton`s and the checked `Toolbar.RadioButton` of each\n * group live in `checkedValues`/`defaultCheckedValues`, per group `name`, and every change calls\n * `onCheckedValuesChange(checkedValues, details)`. The state is in the server HTML.\n * - Left/Right (Up/Down when `orientation=\"vertical\"`) move focus and wrap; Home/End jump to the\n * first/last control; Left/Right are mirrored in RTL. Natively disabled controls are skipped,\n * also when a child disables them on its own; `disabledFocusable` ones stay in the arrow-key\n * order (APG), so a Tooltip can explain why they are unavailable. The arrows never press a\n * toggle or check a radio: Space, Enter or a click does.\n * - The radios of a `Toolbar.RadioGroup` are part of that arrow-key order, and Up/Down (Left/Right\n * in a vertical toolbar) also move among them, wrapping inside the group.\n * - Tab returns to the last focused control. Focusing a nested composite (radio group, tab list)\n * or a text field, select, slider or spin button keeps the Tab stop where it was.\n * - Text fields, selects, sliders, spin buttons and editable comboboxes keep their own arrow keys\n * (the caret moves). A Dropdown (select-only combobox) does not: Left/Right move past it. It\n * keeps Up/Down, Home and End for its list, so in a vertical toolbar the arrows cannot leave it.\n * - Elements with their own `tabIndex={-1}` are left alone, and a nested composite widget (a\n * RadioGroup, a tab list, …; not `Toolbar.RadioGroup`) counts as one control that keeps its own\n * Tab stop and arrow keys.\n * - A Menu or Popover opened from a control keeps its own keys: arrows, Home and End pressed in\n * the popup never move focus back to the toolbar's controls.\n * - A consumer `onKeyDown` runs first; `event.preventDefault()` in it cancels the navigation.\n * - Renders `data-size` and `data-orientation`.\n *\n * React Server Components cannot dot into a client module: import the flat names\n * `ToolbarButton`, `ToolbarToggleButton`, `ToolbarRadioGroup`, `ToolbarRadioButton`,\n * `ToolbarGroup` and `ToolbarDivider` there; `Toolbar.Button` etc. work in client files.\n *\n * @example\n * <Toolbar aria-label=\"Formatting\" defaultCheckedValues={{ format: ['bold'], align: ['left'] }}>\n * <Toolbar.ToggleButton name=\"format\" value=\"bold\" icon={<BoldIcon />} aria-label=\"Bold\" />\n * <Toolbar.ToggleButton name=\"format\" value=\"code\" icon={<CodeIcon />} aria-label=\"Code\" />\n * <Toolbar.Divider />\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\" icon={<AlignLeftIcon />} aria-label=\"Left\" />\n * <Toolbar.RadioButton name=\"align\" value=\"center\" icon={<AlignCenterIcon />} aria-label=\"Center\" />\n * </Toolbar.RadioGroup>\n * </Toolbar>\n */\nexport const Toolbar = /* @__PURE__ */ Object.assign(ToolbarRoot, {\n Button: ToolbarButton,\n ToggleButton: ToolbarToggleButton,\n RadioGroup: ToolbarRadioGroup,\n RadioButton: ToolbarRadioButton,\n Group: ToolbarGroup,\n Divider: ToolbarDivider,\n});\n"],"mappings":"0aA2FA,IAAMwB,EACJ,uEAGIC,EAA8C,CAClD,cAAe,QACf,MAAO,QACP,OAAQ,MACR,MAAO,QACP,cAAe,KACjB,EAGMC,EAA6D,GAAU,CAC3E,GAAM,CACJ,KACA,cAAc,aACd,OAAO,SACP,gBACA,uBACA,wBACA,YACA,MACA,YACA,UACA,OACA,mBAAoBC,EACpB,GAAGC,GACDC,EAEE,CAAE,kBAAmB7B,EAAAA,kBAAkB,CAC3C,aAAcwB,EACd,eAAgB,GAChB,QAAS,eACT,aACF,CAAC,EACKM,EAAY7B,EAAAA,cAA2B8B,EAAe,IAAKC,CAAG,EAE9DC,EAAU/B,EAAAA,iBAAiBgC,EAAeC,EAAsBC,CAAqB,EACrFC,EAAoBlC,EAAAA,4BAA4B,EAChDmC,EAAUlC,EAAM,aACb,CAAE,cAAa,OAAM,UAAS,mBAAkB,GACvD,CAACmC,EAAaC,EAAMP,EAASI,CAAiB,CAChD,EAEMI,EAA+BC,GAAM,MAG3C,OACE,EAAAnB,EAAA,IAAA,CAAClB,EAAAA,eAAe,SAAhB,CAAyB,MAAOiC,EAC9B,UAAA,EAAAf,EAAA,IAAA,CAACkB,EAAD,CACE,YAAWD,EACX,mBAAkBD,EAClB,GAAIX,EACJ,KAAMe,GAAQ,UACd,mBAAkBhB,GAAmBY,EACrC,IAAKT,EACL,wBAAsB,GACtB,UAAWxB,EAAAA,qBAAqBsC,EAAWb,EAAe,SAAS,EACnE,QAASzB,EAAAA,qBAAqBuC,EAASd,EAAe,QAAS,CAC7D,sBAAuB,EACzB,CAAC,EACD,UAAWxB,EAAAA,GACT,8DACAkB,EAAsBe,GACtBD,IAAgB,YAAc,yBAC9BO,CACF,CACD,CAAA,CACsB,CAAA,CAE7B,EACA,EAAY,YAAc,UAmD1B,IAAaC,EAA0B,OAAO,OAAOrB,EAAa,CAChE,OAAQlB,EAAAA,cACR,aAAcC,EAAAA,oBACd,WAAYC,EAAAA,kBACZ,YAAaC,EAAAA,mBACb,MAAOC,EAAAA,aACP,QAASC,EAAAA,cACX,CAAC"}
1
+ {"version":3,"file":"Toolbar.cjs","names":["useRovingTabIndex","useMergedRefs","useCheckedValues","useToolbarCheckableRegistry","React","ToolbarContext","composeEventHandlers","cn","toolbarClassNames","ToolbarButton","ToolbarToggleButton","ToolbarRadioGroup","ToolbarRadioButton","ToolbarGroup","ToolbarDivider","require_runtime","require_cn","require_composeEventHandlers","require_classNames","require_useRovingTabIndex","require_useMergedRefs","require_useCheckedValues","require_Toolbar_context","require_Toolbar_parts","react","react_jsx_runtime","TOOLBAR_ITEM_SELECTOR","toolbarPaddingClasses","ToolbarRoot","ariaOrientation","rest","props","mergedRef","containerProps","ref","checked","checkedValues","defaultCheckedValues","onCheckedValuesChange","registerCheckable","context","orientation","size","Component","as","role","onKeyDown","onFocus","className","Toolbar"],"sources":["../../../src/components/button/Toolbar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { toolbarClassNames } from '../../lib/classNames';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { CheckedValues, CheckedValuesChangeHandler, Orientation, Size } from '../../lib/types';\nimport { useCheckedValues } from '../../hooks/useCheckedValues';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { ToolbarContext, useToolbarCheckableRegistry } from './Toolbar.context';\nimport type { ToolbarContextValue } from './Toolbar.context';\nimport {\n ToolbarButton,\n ToolbarDivider,\n ToolbarGroup,\n ToolbarRadioButton,\n ToolbarRadioGroup,\n ToolbarToggleButton,\n} from './Toolbar.parts';\n\nexport {\n ToolbarButton,\n ToolbarDivider,\n ToolbarGroup,\n ToolbarRadioButton,\n ToolbarRadioGroup,\n ToolbarToggleButton,\n};\nexport type {\n ToolbarButtonOwnProps,\n ToolbarButtonProps,\n ToolbarDividerProps,\n ToolbarGroupProps,\n ToolbarRadioButtonProps,\n ToolbarRadioGroupProps,\n ToolbarToggleButtonProps,\n} from './Toolbar.parts';\n\n/**\n * The Toolbar's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props\n * only). Every other prop comes from the rendered element (`as`, default `'div'`). Give the\n * toolbar an `aria-label` (or `aria-labelledby`) that describes its purpose, e.g. \"Formatting\".\n */\nexport interface ToolbarOwnProps {\n /**\n * Layout and arrow-key axis: Left/Right move between items when horizontal (mirrored in RTL),\n * Up/Down when vertical. Exposed as `aria-orientation` and `data-orientation`.\n * @default 'horizontal'\n */\n orientation?: Orientation;\n /**\n * Default size of `Toolbar.Button`, `Toolbar.ToggleButton` and `Toolbar.RadioButton` (their\n * own `size` wins), and the toolbar's padding. Plain Buttons inside keep their own default.\n * Exposed as `data-size`.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Pressed `Toolbar.ToggleButton`s and checked `Toolbar.RadioButton`s, per group `name`\n * (controlled): `{ format: ['bold'], align: ['center'] }`.\n */\n checkedValues?: CheckedValues;\n /** Initial checked values for uncontrolled usage. @default {} */\n defaultCheckedValues?: CheckedValues;\n /**\n * Called when a toggle or radio changes them (only on change): the new checked values first,\n * then `details` with the group's `name`, its `checkedItems` and the `event` (Fluent's\n * `onCheckedValueChange(event, { name, checkedItems })`; always passed, typed optional until 1.0).\n */\n onCheckedValuesChange?: CheckedValuesChangeHandler;\n}\n\n/**\n * Props of {@link Toolbar} rendered as `C` (default `'div'`). `ToolbarProps` without a type\n * argument is the 0.4 name: the props of a Toolbar rendered as a `<div>`, including `ref`.\n */\nexport type ToolbarProps<C extends React.ElementType = 'div'> = PolymorphicProps<\n C,\n ToolbarOwnProps\n>;\n\n/** The props the implementation reads, for any `as`. */\ntype ToolbarImplProps = ToolbarOwnProps &\n React.HTMLAttributes<HTMLElement> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n };\n\n/**\n * Every focusable control a toolbar can contain, whatever component renders it. Matches that\n * cannot take focus (a `type=\"hidden\"` input, a control CSS hides) are dropped by the roving hook.\n */\nconst TOOLBAR_ITEM_SELECTOR =\n 'button, [href], input, select, textarea, [role=\"button\"], [tabindex]';\n\n/** The toolbar's padding per size. */\nconst toolbarPaddingClasses: Record<Size, string> = {\n 'extra-small': 'p-0.5',\n small: 'p-0.5',\n medium: 'p-1',\n large: 'p-1.5',\n 'extra-large': 'p-2',\n};\n\n// The root of the Toolbar compound; its component JSDoc is on the `Toolbar` export below (C-DOCS).\nconst ToolbarRoot: PolymorphicComponent<'div', ToolbarOwnProps> = (props) => {\n const {\n as,\n orientation = 'horizontal',\n size = 'medium',\n checkedValues,\n defaultCheckedValues,\n onCheckedValuesChange,\n className,\n ref,\n onKeyDown,\n onFocus,\n role,\n 'aria-orientation': ariaOrientation,\n ...rest\n } = props as ToolbarImplProps;\n\n const { containerProps } = useRovingTabIndex({\n itemSelector: TOOLBAR_ITEM_SELECTOR,\n manageTabIndex: true,\n tabStop: 'last-focused',\n orientation,\n });\n const mergedRef = useMergedRefs<HTMLElement>(containerProps.ref, ref);\n\n const checked = useCheckedValues(checkedValues, defaultCheckedValues, onCheckedValuesChange);\n const registerCheckable = useToolbarCheckableRegistry();\n const context = React.useMemo<ToolbarContextValue>(\n () => ({ orientation, size, checked, registerCheckable }),\n [orientation, size, checked, registerCheckable],\n );\n\n const Component: React.ElementType = as ?? 'div';\n // The role and `aria-orientation` defaults apply wherever the consumer's value is `undefined` or\n // `null` (as in Button), so a wrapper forwarding its own unset props keeps them.\n return (\n <ToolbarContext.Provider value={context}>\n <Component\n data-size={size}\n data-orientation={orientation}\n {...rest}\n role={role ?? 'toolbar'}\n aria-orientation={ariaOrientation ?? orientation}\n ref={mergedRef}\n data-roving-container=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, containerProps.onKeyDown)}\n onFocus={composeEventHandlers(onFocus, containerProps.onFocus, {\n checkDefaultPrevented: false,\n })}\n className={cn(\n toolbarClassNames.root,\n 'inline-flex items-center gap-1 rounded border border-border',\n toolbarPaddingClasses[size],\n orientation === 'vertical' && 'flex-col items-stretch',\n className,\n )}\n />\n </ToolbarContext.Provider>\n );\n};\nToolbarRoot.displayName = 'Toolbar';\n\n/**\n * A container for a set of controls (APG Toolbar pattern): `role=\"toolbar\"`, one Tab stop, and\n * arrow-key navigation between its controls.\n *\n * - Works with any children (Buttons, ToggleButtons, links, inputs, value controls such as\n * Checkbox or Dropdown): the focusable controls are found in the DOM, and the Toolbar sets their\n * `tabIndex` itself (one `0`, the rest `-1`). The `type=\"hidden\"` input that a named value\n * control renders never counts as a control, and controls that CSS hides are skipped.\n * - Parts: `Toolbar.Button`, `Toolbar.ToggleButton` and `Toolbar.RadioButton` take the toolbar's\n * `size` (default `'medium'`) and the `subtle` appearance by default; `Toolbar.RadioGroup`,\n * `Toolbar.Group` and `Toolbar.Divider` lay them out. Plain Buttons keep their own defaults.\n * - State: the pressed `Toolbar.ToggleButton`s and the checked `Toolbar.RadioButton` of each\n * group live in `checkedValues`/`defaultCheckedValues`, per group `name`, and every change calls\n * `onCheckedValuesChange(checkedValues, details)`. The state is in the server HTML.\n * - Left/Right (Up/Down when `orientation=\"vertical\"`) move focus and wrap; Home/End jump to the\n * first/last control; Left/Right are mirrored in RTL. Natively disabled controls are skipped,\n * also when a child disables them on its own; `disabledFocusable` ones stay in the arrow-key\n * order (APG), so a Tooltip can explain why they are unavailable. The arrows never press a\n * toggle or check a radio: Space, Enter or a click does.\n * - The radios of a `Toolbar.RadioGroup` are part of that arrow-key order, and Up/Down (Left/Right\n * in a vertical toolbar) also move among them, wrapping inside the group.\n * - Tab returns to the last focused control. Focusing a nested composite (radio group, tab list)\n * or a text field, select, slider or spin button keeps the Tab stop where it was.\n * - Text fields, selects, sliders, spin buttons and editable comboboxes keep their own arrow keys\n * (the caret moves). A Dropdown (select-only combobox) does not: Left/Right move past it. It\n * keeps Up/Down, Home and End for its list, so in a vertical toolbar the arrows cannot leave it.\n * - Elements with their own `tabIndex={-1}` are left alone, and a nested composite widget (a\n * RadioGroup, a tab list, …; not `Toolbar.RadioGroup`) counts as one control that keeps its own\n * Tab stop and arrow keys.\n * - A Menu or Popover opened from a control keeps its own keys: arrows, Home and End pressed in\n * the popup never move focus back to the toolbar's controls.\n * - A consumer `onKeyDown` runs first; `event.preventDefault()` in it cancels the navigation.\n * - Renders `data-size` and `data-orientation`.\n *\n * React Server Components cannot dot into a client module: import the flat names\n * `ToolbarButton`, `ToolbarToggleButton`, `ToolbarRadioGroup`, `ToolbarRadioButton`,\n * `ToolbarGroup` and `ToolbarDivider` there; `Toolbar.Button` etc. work in client files.\n *\n * @example\n * <Toolbar aria-label=\"Formatting\" defaultCheckedValues={{ format: ['bold'], align: ['left'] }}>\n * <Toolbar.ToggleButton name=\"format\" value=\"bold\" icon={<BoldIcon />} aria-label=\"Bold\" />\n * <Toolbar.ToggleButton name=\"format\" value=\"code\" icon={<CodeIcon />} aria-label=\"Code\" />\n * <Toolbar.Divider />\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\" icon={<AlignLeftIcon />} aria-label=\"Left\" />\n * <Toolbar.RadioButton name=\"align\" value=\"center\" icon={<AlignCenterIcon />} aria-label=\"Center\" />\n * </Toolbar.RadioGroup>\n * </Toolbar>\n */\nexport const Toolbar = /* @__PURE__ */ Object.assign(ToolbarRoot, {\n Button: ToolbarButton,\n ToggleButton: ToolbarToggleButton,\n RadioGroup: ToolbarRadioGroup,\n RadioButton: ToolbarRadioButton,\n Group: ToolbarGroup,\n Divider: ToolbarDivider,\n});\n"],"mappings":"gdA4FA,IAAM0B,EACJ,uEAGIC,EAA8C,CAClD,cAAe,QACf,MAAO,QACP,OAAQ,MACR,MAAO,QACP,cAAe,KACjB,EAGMC,EAA6D,GAAU,CAC3E,GAAM,CACJ,KACA,cAAc,aACd,OAAO,SACP,gBACA,uBACA,wBACA,YACA,MACA,YACA,UACA,OACA,mBAAoBC,EACpB,GAAGC,GACDC,EAEE,CAAE,kBAAmB/B,EAAAA,kBAAkB,CAC3C,aAAc0B,EACd,eAAgB,GAChB,QAAS,eACT,aACF,CAAC,EACKM,EAAY/B,EAAAA,cAA2BgC,EAAe,IAAKC,CAAG,EAE9DC,EAAUjC,EAAAA,iBAAiBkC,EAAeC,EAAsBC,CAAqB,EACrFC,EAAoBpC,EAAAA,4BAA4B,EAChDqC,EAAUpC,EAAM,aACb,CAAE,cAAa,OAAM,UAAS,mBAAkB,GACvD,CAACqC,EAAaC,EAAMP,EAASI,CAAiB,CAChD,EAEMI,EAA+BC,GAAM,MAG3C,OACE,EAAAnB,EAAA,IAAA,CAACpB,EAAAA,eAAe,SAAhB,CAAyB,MAAOmC,EAC9B,UAAA,EAAAf,EAAA,IAAA,CAACkB,EAAD,CACE,YAAWD,EACX,mBAAkBD,EAClB,GAAIX,EACJ,KAAMe,GAAQ,UACd,mBAAkBhB,GAAmBY,EACrC,IAAKT,EACL,wBAAsB,GACtB,UAAW1B,EAAAA,qBAAqBwC,EAAWb,EAAe,SAAS,EACnE,QAAS3B,EAAAA,qBAAqByC,EAASd,EAAe,QAAS,CAC7D,sBAAuB,EACzB,CAAC,EACD,UAAW1B,EAAAA,GACTC,EAAAA,kBAAkB,KAClB,8DACAmB,EAAsBe,GACtBD,IAAgB,YAAc,yBAC9BO,CACF,CACD,CAAA,CACsB,CAAA,CAE7B,EACA,EAAY,YAAc,UAmD1B,IAAaC,EAA0B,OAAO,OAAOrB,EAAa,CAChE,OAAQnB,EAAAA,cACR,aAAcC,EAAAA,oBACd,WAAYC,EAAAA,kBACZ,YAAaC,EAAAA,mBACb,MAAOC,EAAAA,aACP,QAASC,EAAAA,cACX,CAAC"}