@mortenbrudvik/waveui 0.4.0 → 0.7.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 (574) hide show
  1. package/README.md +1221 -173
  2. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  3. package/dist/components/button/Button.cjs +2 -0
  4. package/dist/components/button/Button.cjs.map +1 -0
  5. package/dist/components/button/Button.mjs +50 -0
  6. package/dist/components/button/Button.mjs.map +1 -0
  7. package/dist/components/button/Button.semantics.cjs +2 -0
  8. package/dist/components/button/Button.semantics.cjs.map +1 -0
  9. package/dist/components/button/Button.semantics.mjs +61 -0
  10. package/dist/components/button/Button.semantics.mjs.map +1 -0
  11. package/dist/components/button/Button.slots.cjs +2 -0
  12. package/dist/components/button/Button.slots.cjs.map +1 -0
  13. package/dist/components/button/Button.slots.mjs +47 -0
  14. package/dist/components/button/Button.slots.mjs.map +1 -0
  15. package/dist/components/button/CompoundButton.cjs +2 -0
  16. package/dist/components/button/CompoundButton.cjs.map +1 -0
  17. package/dist/components/button/CompoundButton.mjs +53 -0
  18. package/dist/components/button/CompoundButton.mjs.map +1 -0
  19. package/dist/components/button/Link.cjs +2 -0
  20. package/dist/components/button/Link.cjs.map +1 -0
  21. package/dist/components/button/Link.mjs +37 -0
  22. package/dist/components/button/Link.mjs.map +1 -0
  23. package/dist/components/button/MenuButton.cjs +2 -0
  24. package/dist/components/button/MenuButton.cjs.map +1 -0
  25. package/dist/components/button/MenuButton.mjs +45 -0
  26. package/dist/components/button/MenuButton.mjs.map +1 -0
  27. package/dist/components/button/SplitButton.cjs +2 -0
  28. package/dist/components/button/SplitButton.cjs.map +1 -0
  29. package/dist/components/button/SplitButton.mjs +66 -0
  30. package/dist/components/button/SplitButton.mjs.map +1 -0
  31. package/dist/components/button/ToggleButton.cjs +2 -0
  32. package/dist/components/button/ToggleButton.cjs.map +1 -0
  33. package/dist/components/button/ToggleButton.mjs +65 -0
  34. package/dist/components/button/ToggleButton.mjs.map +1 -0
  35. package/dist/components/button/Toolbar.cjs +2 -0
  36. package/dist/components/button/Toolbar.cjs.map +1 -0
  37. package/dist/components/button/Toolbar.context.cjs +2 -0
  38. package/dist/components/button/Toolbar.context.cjs.map +1 -0
  39. package/dist/components/button/Toolbar.context.mjs +31 -0
  40. package/dist/components/button/Toolbar.context.mjs.map +1 -0
  41. package/dist/components/button/Toolbar.mjs +63 -0
  42. package/dist/components/button/Toolbar.mjs.map +1 -0
  43. package/dist/components/button/Toolbar.parts.cjs +2 -0
  44. package/dist/components/button/Toolbar.parts.cjs.map +1 -0
  45. package/dist/components/button/Toolbar.parts.mjs +131 -0
  46. package/dist/components/button/Toolbar.parts.mjs.map +1 -0
  47. package/dist/components/button/buttonStyles.cjs +2 -0
  48. package/dist/components/button/buttonStyles.cjs.map +1 -0
  49. package/dist/components/button/buttonStyles.mjs +39 -0
  50. package/dist/components/button/buttonStyles.mjs.map +1 -0
  51. package/dist/components/data-display/Avatar.cjs +2 -0
  52. package/dist/components/data-display/Avatar.cjs.map +1 -0
  53. package/dist/components/data-display/Avatar.mjs +157 -0
  54. package/dist/components/data-display/Avatar.mjs.map +1 -0
  55. package/dist/components/data-display/AvatarGroup.cjs +2 -0
  56. package/dist/components/data-display/AvatarGroup.cjs.map +1 -0
  57. package/dist/components/data-display/AvatarGroup.mjs +134 -0
  58. package/dist/components/data-display/AvatarGroup.mjs.map +1 -0
  59. package/dist/components/data-display/Badge.cjs +2 -0
  60. package/dist/components/data-display/Badge.cjs.map +1 -0
  61. package/dist/components/data-display/Badge.colors.cjs +2 -0
  62. package/dist/components/data-display/Badge.colors.cjs.map +1 -0
  63. package/dist/components/data-display/Badge.colors.mjs +58 -0
  64. package/dist/components/data-display/Badge.colors.mjs.map +1 -0
  65. package/dist/components/data-display/Badge.mjs +32 -0
  66. package/dist/components/data-display/Badge.mjs.map +1 -0
  67. package/dist/components/data-display/CounterBadge.cjs +2 -0
  68. package/dist/components/data-display/CounterBadge.cjs.map +1 -0
  69. package/dist/components/data-display/CounterBadge.mjs +28 -0
  70. package/dist/components/data-display/CounterBadge.mjs.map +1 -0
  71. package/dist/components/data-display/Divider.cjs +2 -0
  72. package/dist/components/data-display/Divider.cjs.map +1 -0
  73. package/dist/components/data-display/Divider.mjs +52 -0
  74. package/dist/components/data-display/Divider.mjs.map +1 -0
  75. package/dist/components/data-display/Image.cjs +2 -0
  76. package/dist/components/data-display/Image.cjs.map +1 -0
  77. package/dist/components/data-display/Image.mjs +32 -0
  78. package/dist/components/data-display/Image.mjs.map +1 -0
  79. package/dist/components/data-display/InfoLabel.cjs +2 -0
  80. package/dist/components/data-display/InfoLabel.cjs.map +1 -0
  81. package/dist/components/data-display/InfoLabel.mjs +104 -0
  82. package/dist/components/data-display/InfoLabel.mjs.map +1 -0
  83. package/dist/components/data-display/List.cjs +2 -0
  84. package/dist/components/data-display/List.cjs.map +1 -0
  85. package/dist/components/data-display/List.mjs +381 -0
  86. package/dist/components/data-display/List.mjs.map +1 -0
  87. package/dist/components/data-display/List.registry.cjs +2 -0
  88. package/dist/components/data-display/List.registry.cjs.map +1 -0
  89. package/dist/components/data-display/List.registry.mjs +101 -0
  90. package/dist/components/data-display/List.registry.mjs.map +1 -0
  91. package/dist/components/data-display/Persona.cjs +2 -0
  92. package/dist/components/data-display/Persona.cjs.map +1 -0
  93. package/dist/components/data-display/Persona.mjs +48 -0
  94. package/dist/components/data-display/Persona.mjs.map +1 -0
  95. package/dist/components/data-display/PresenceBadge.cjs +2 -0
  96. package/dist/components/data-display/PresenceBadge.cjs.map +1 -0
  97. package/dist/components/data-display/PresenceBadge.mjs +71 -0
  98. package/dist/components/data-display/PresenceBadge.mjs.map +1 -0
  99. package/dist/components/data-display/Tag.cjs +2 -0
  100. package/dist/components/data-display/Tag.cjs.map +1 -0
  101. package/dist/components/data-display/Tag.mjs +147 -0
  102. package/dist/components/data-display/Tag.mjs.map +1 -0
  103. package/dist/components/feedback/MessageBar.cjs +2 -0
  104. package/dist/components/feedback/MessageBar.cjs.map +1 -0
  105. package/dist/components/feedback/MessageBar.mjs +144 -0
  106. package/dist/components/feedback/MessageBar.mjs.map +1 -0
  107. package/dist/components/feedback/MessageBar.status.cjs +2 -0
  108. package/dist/components/feedback/MessageBar.status.cjs.map +1 -0
  109. package/dist/components/feedback/MessageBar.status.mjs +45 -0
  110. package/dist/components/feedback/MessageBar.status.mjs.map +1 -0
  111. package/dist/components/feedback/ProgressBar.cjs +2 -0
  112. package/dist/components/feedback/ProgressBar.cjs.map +1 -0
  113. package/dist/components/feedback/ProgressBar.mjs +72 -0
  114. package/dist/components/feedback/ProgressBar.mjs.map +1 -0
  115. package/dist/components/feedback/Skeleton.cjs +2 -0
  116. package/dist/components/feedback/Skeleton.cjs.map +1 -0
  117. package/dist/components/feedback/Skeleton.mjs +47 -0
  118. package/dist/components/feedback/Skeleton.mjs.map +1 -0
  119. package/dist/components/feedback/Spinner.cjs +2 -0
  120. package/dist/components/feedback/Spinner.cjs.map +1 -0
  121. package/dist/components/feedback/Spinner.mjs +60 -0
  122. package/dist/components/feedback/Spinner.mjs.map +1 -0
  123. package/dist/components/feedback/Toast.cjs +2 -0
  124. package/dist/components/feedback/Toast.cjs.map +1 -0
  125. package/dist/components/feedback/Toast.mjs +347 -0
  126. package/dist/components/feedback/Toast.mjs.map +1 -0
  127. package/dist/components/input/Checkbox.cjs +2 -0
  128. package/dist/components/input/Checkbox.cjs.map +1 -0
  129. package/dist/components/input/Checkbox.mjs +96 -0
  130. package/dist/components/input/Checkbox.mjs.map +1 -0
  131. package/dist/components/input/ColorPicker.cjs +6 -0
  132. package/dist/components/input/ColorPicker.cjs.map +1 -0
  133. package/dist/components/input/ColorPicker.mjs +236 -0
  134. package/dist/components/input/ColorPicker.mjs.map +1 -0
  135. package/dist/components/input/Combobox.cjs +2 -0
  136. package/dist/components/input/Combobox.cjs.map +1 -0
  137. package/dist/components/input/Combobox.expand.cjs +2 -0
  138. package/dist/components/input/Combobox.expand.cjs.map +1 -0
  139. package/dist/components/input/Combobox.expand.mjs +38 -0
  140. package/dist/components/input/Combobox.expand.mjs.map +1 -0
  141. package/dist/components/input/Combobox.mjs +187 -0
  142. package/dist/components/input/Combobox.mjs.map +1 -0
  143. package/dist/components/input/DatePicker.cjs +2 -0
  144. package/dist/components/input/DatePicker.cjs.map +1 -0
  145. package/dist/components/input/DatePicker.mjs +340 -0
  146. package/dist/components/input/DatePicker.mjs.map +1 -0
  147. package/dist/components/input/Dropdown.cjs +2 -0
  148. package/dist/components/input/Dropdown.cjs.map +1 -0
  149. package/dist/components/input/Dropdown.mjs +128 -0
  150. package/dist/components/input/Dropdown.mjs.map +1 -0
  151. package/dist/components/input/Field.cjs +2 -0
  152. package/dist/components/input/Field.cjs.map +1 -0
  153. package/dist/components/input/Field.mjs +200 -0
  154. package/dist/components/input/Field.mjs.map +1 -0
  155. package/dist/components/input/Input.cjs +2 -0
  156. package/dist/components/input/Input.cjs.map +1 -0
  157. package/dist/components/input/Input.mjs +81 -0
  158. package/dist/components/input/Input.mjs.map +1 -0
  159. package/dist/components/input/Label.cjs +2 -0
  160. package/dist/components/input/Label.cjs.map +1 -0
  161. package/dist/components/input/Label.mjs +28 -0
  162. package/dist/components/input/Label.mjs.map +1 -0
  163. package/dist/components/input/Option.cjs +2 -0
  164. package/dist/components/input/Option.cjs.map +1 -0
  165. package/dist/components/input/Option.mjs +169 -0
  166. package/dist/components/input/Option.mjs.map +1 -0
  167. package/dist/components/input/RadioGroup.cjs +2 -0
  168. package/dist/components/input/RadioGroup.cjs.map +1 -0
  169. package/dist/components/input/RadioGroup.mjs +139 -0
  170. package/dist/components/input/RadioGroup.mjs.map +1 -0
  171. package/dist/components/input/Rating.cjs +2 -0
  172. package/dist/components/input/Rating.cjs.map +1 -0
  173. package/dist/components/input/Rating.mjs +196 -0
  174. package/dist/components/input/Rating.mjs.map +1 -0
  175. package/dist/components/input/SearchBox.cjs +2 -0
  176. package/dist/components/input/SearchBox.cjs.map +1 -0
  177. package/dist/components/input/SearchBox.mjs +205 -0
  178. package/dist/components/input/SearchBox.mjs.map +1 -0
  179. package/dist/components/input/Select.cjs +2 -0
  180. package/dist/components/input/Select.cjs.map +1 -0
  181. package/dist/components/input/Select.mjs +33 -0
  182. package/dist/components/input/Select.mjs.map +1 -0
  183. package/dist/components/input/Slider.cjs +2 -0
  184. package/dist/components/input/Slider.cjs.map +1 -0
  185. package/dist/components/input/Slider.mjs +79 -0
  186. package/dist/components/input/Slider.mjs.map +1 -0
  187. package/dist/components/input/SpinButton.cjs +2 -0
  188. package/dist/components/input/SpinButton.cjs.map +1 -0
  189. package/dist/components/input/SpinButton.mjs +157 -0
  190. package/dist/components/input/SpinButton.mjs.map +1 -0
  191. package/dist/components/input/SwatchPicker.cjs +2 -0
  192. package/dist/components/input/SwatchPicker.cjs.map +1 -0
  193. package/dist/components/input/SwatchPicker.mjs +113 -0
  194. package/dist/components/input/SwatchPicker.mjs.map +1 -0
  195. package/dist/components/input/Switch.cjs +2 -0
  196. package/dist/components/input/Switch.cjs.map +1 -0
  197. package/dist/components/input/Switch.mjs +92 -0
  198. package/dist/components/input/Switch.mjs.map +1 -0
  199. package/dist/components/input/TagPicker.cjs +2 -0
  200. package/dist/components/input/TagPicker.cjs.map +1 -0
  201. package/dist/components/input/TagPicker.mjs +249 -0
  202. package/dist/components/input/TagPicker.mjs.map +1 -0
  203. package/dist/components/input/Textarea.cjs +2 -0
  204. package/dist/components/input/Textarea.cjs.map +1 -0
  205. package/dist/components/input/Textarea.mjs +32 -0
  206. package/dist/components/input/Textarea.mjs.map +1 -0
  207. package/dist/components/input/TimePicker.cjs +2 -0
  208. package/dist/components/input/TimePicker.cjs.map +1 -0
  209. package/dist/components/input/TimePicker.mjs +292 -0
  210. package/dist/components/input/TimePicker.mjs.map +1 -0
  211. package/dist/components/input/colorUtils.cjs +2 -0
  212. package/dist/components/input/colorUtils.cjs.map +1 -0
  213. package/dist/components/input/colorUtils.mjs +96 -0
  214. package/dist/components/input/colorUtils.mjs.map +1 -0
  215. package/dist/components/input/dateUtils.cjs +2 -0
  216. package/dist/components/input/dateUtils.cjs.map +1 -0
  217. package/dist/components/input/dateUtils.mjs +250 -0
  218. package/dist/components/input/dateUtils.mjs.map +1 -0
  219. package/dist/components/input/pickerStyles.cjs +2 -0
  220. package/dist/components/input/pickerStyles.cjs.map +1 -0
  221. package/dist/components/input/pickerStyles.mjs +10 -0
  222. package/dist/components/input/pickerStyles.mjs.map +1 -0
  223. package/dist/components/internal/HiddenInput.cjs +2 -0
  224. package/dist/components/internal/HiddenInput.cjs.map +1 -0
  225. package/dist/components/internal/HiddenInput.mjs +88 -0
  226. package/dist/components/internal/HiddenInput.mjs.map +1 -0
  227. package/dist/components/layout/Accordion.cjs +2 -0
  228. package/dist/components/layout/Accordion.cjs.map +1 -0
  229. package/dist/components/layout/Accordion.mjs +236 -0
  230. package/dist/components/layout/Accordion.mjs.map +1 -0
  231. package/dist/components/layout/Card.cjs +2 -0
  232. package/dist/components/layout/Card.cjs.map +1 -0
  233. package/dist/components/layout/Card.mjs +121 -0
  234. package/dist/components/layout/Card.mjs.map +1 -0
  235. package/dist/components/layout/Carousel.cjs +2 -0
  236. package/dist/components/layout/Carousel.cjs.map +1 -0
  237. package/dist/components/layout/Carousel.mjs +205 -0
  238. package/dist/components/layout/Carousel.mjs.map +1 -0
  239. package/dist/components/layout/Flex.cjs +2 -0
  240. package/dist/components/layout/Flex.cjs.map +1 -0
  241. package/dist/components/layout/Flex.mjs +54 -0
  242. package/dist/components/layout/Flex.mjs.map +1 -0
  243. package/dist/components/layout/Grid.cjs +2 -0
  244. package/dist/components/layout/Grid.cjs.map +1 -0
  245. package/dist/components/layout/Grid.mjs +62 -0
  246. package/dist/components/layout/Grid.mjs.map +1 -0
  247. package/dist/components/layout/Overflow.cjs +2 -0
  248. package/dist/components/layout/Overflow.cjs.map +1 -0
  249. package/dist/components/layout/Overflow.mjs +269 -0
  250. package/dist/components/layout/Overflow.mjs.map +1 -0
  251. package/dist/components/layout/Stack.cjs +2 -0
  252. package/dist/components/layout/Stack.cjs.map +1 -0
  253. package/dist/components/layout/Stack.mjs +39 -0
  254. package/dist/components/layout/Stack.mjs.map +1 -0
  255. package/dist/components/layout/TabList.cjs +2 -0
  256. package/dist/components/layout/TabList.cjs.map +1 -0
  257. package/dist/components/layout/TabList.mjs +238 -0
  258. package/dist/components/layout/TabList.mjs.map +1 -0
  259. package/dist/components/layout/Tree.cjs +2 -0
  260. package/dist/components/layout/Tree.cjs.map +1 -0
  261. package/dist/components/layout/Tree.mjs +220 -0
  262. package/dist/components/layout/Tree.mjs.map +1 -0
  263. package/dist/components/layout/disclosureIds.cjs +2 -0
  264. package/dist/components/layout/disclosureIds.cjs.map +1 -0
  265. package/dist/components/layout/disclosureIds.mjs +12 -0
  266. package/dist/components/layout/disclosureIds.mjs.map +1 -0
  267. package/dist/components/motion/Presence.cjs +2 -0
  268. package/dist/components/motion/Presence.cjs.map +1 -0
  269. package/dist/components/motion/Presence.mjs +35 -0
  270. package/dist/components/motion/Presence.mjs.map +1 -0
  271. package/dist/components/navigation/Breadcrumb.cjs +2 -0
  272. package/dist/components/navigation/Breadcrumb.cjs.map +1 -0
  273. package/dist/components/navigation/Breadcrumb.mjs +144 -0
  274. package/dist/components/navigation/Breadcrumb.mjs.map +1 -0
  275. package/dist/components/navigation/Menu.cjs +2 -0
  276. package/dist/components/navigation/Menu.cjs.map +1 -0
  277. package/dist/components/navigation/Menu.context.cjs +2 -0
  278. package/dist/components/navigation/Menu.context.cjs.map +1 -0
  279. package/dist/components/navigation/Menu.context.mjs +82 -0
  280. package/dist/components/navigation/Menu.context.mjs.map +1 -0
  281. package/dist/components/navigation/Menu.group.cjs +2 -0
  282. package/dist/components/navigation/Menu.group.cjs.map +1 -0
  283. package/dist/components/navigation/Menu.group.mjs +58 -0
  284. package/dist/components/navigation/Menu.group.mjs.map +1 -0
  285. package/dist/components/navigation/Menu.items.cjs +2 -0
  286. package/dist/components/navigation/Menu.items.cjs.map +1 -0
  287. package/dist/components/navigation/Menu.items.mjs +127 -0
  288. package/dist/components/navigation/Menu.items.mjs.map +1 -0
  289. package/dist/components/navigation/Menu.link.cjs +2 -0
  290. package/dist/components/navigation/Menu.link.cjs.map +1 -0
  291. package/dist/components/navigation/Menu.link.mjs +41 -0
  292. package/dist/components/navigation/Menu.link.mjs.map +1 -0
  293. package/dist/components/navigation/Menu.mjs +27 -0
  294. package/dist/components/navigation/Menu.mjs.map +1 -0
  295. package/dist/components/navigation/Menu.popover.cjs +2 -0
  296. package/dist/components/navigation/Menu.popover.cjs.map +1 -0
  297. package/dist/components/navigation/Menu.popover.mjs +231 -0
  298. package/dist/components/navigation/Menu.popover.mjs.map +1 -0
  299. package/dist/components/navigation/Menu.root.cjs +2 -0
  300. package/dist/components/navigation/Menu.root.cjs.map +1 -0
  301. package/dist/components/navigation/Menu.root.mjs +308 -0
  302. package/dist/components/navigation/Menu.root.mjs.map +1 -0
  303. package/dist/components/navigation/Menu.selectable.cjs +2 -0
  304. package/dist/components/navigation/Menu.selectable.cjs.map +1 -0
  305. package/dist/components/navigation/Menu.selectable.mjs +89 -0
  306. package/dist/components/navigation/Menu.selectable.mjs.map +1 -0
  307. package/dist/components/navigation/Menu.shared.cjs +2 -0
  308. package/dist/components/navigation/Menu.shared.cjs.map +1 -0
  309. package/dist/components/navigation/Menu.shared.mjs +23 -0
  310. package/dist/components/navigation/Menu.shared.mjs.map +1 -0
  311. package/dist/components/navigation/Menu.splitGroup.cjs +2 -0
  312. package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -0
  313. package/dist/components/navigation/Menu.splitGroup.mjs +51 -0
  314. package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -0
  315. package/dist/components/navigation/Menu.trigger.cjs +2 -0
  316. package/dist/components/navigation/Menu.trigger.cjs.map +1 -0
  317. package/dist/components/navigation/Menu.trigger.mjs +79 -0
  318. package/dist/components/navigation/Menu.trigger.mjs.map +1 -0
  319. package/dist/components/navigation/Nav.cjs +2 -0
  320. package/dist/components/navigation/Nav.cjs.map +1 -0
  321. package/dist/components/navigation/Nav.mjs +276 -0
  322. package/dist/components/navigation/Nav.mjs.map +1 -0
  323. package/dist/components/navigation/Pagination.cjs +2 -0
  324. package/dist/components/navigation/Pagination.cjs.map +1 -0
  325. package/dist/components/navigation/Pagination.mjs +110 -0
  326. package/dist/components/navigation/Pagination.mjs.map +1 -0
  327. package/dist/components/navigation/Stepper.cjs +2 -0
  328. package/dist/components/navigation/Stepper.cjs.map +1 -0
  329. package/dist/components/navigation/Stepper.mjs +204 -0
  330. package/dist/components/navigation/Stepper.mjs.map +1 -0
  331. package/dist/components/overlays/Dialog.cjs +2 -0
  332. package/dist/components/overlays/Dialog.cjs.map +1 -0
  333. package/dist/components/overlays/Dialog.mjs +180 -0
  334. package/dist/components/overlays/Dialog.mjs.map +1 -0
  335. package/dist/components/overlays/Dialog.shared.cjs +2 -0
  336. package/dist/components/overlays/Dialog.shared.cjs.map +1 -0
  337. package/dist/components/overlays/Dialog.shared.mjs +227 -0
  338. package/dist/components/overlays/Dialog.shared.mjs.map +1 -0
  339. package/dist/components/overlays/Drawer.cjs +2 -0
  340. package/dist/components/overlays/Drawer.cjs.map +1 -0
  341. package/dist/components/overlays/Drawer.mjs +192 -0
  342. package/dist/components/overlays/Drawer.mjs.map +1 -0
  343. package/dist/components/overlays/Popover.cjs +2 -0
  344. package/dist/components/overlays/Popover.cjs.map +1 -0
  345. package/dist/components/overlays/Popover.mjs +365 -0
  346. package/dist/components/overlays/Popover.mjs.map +1 -0
  347. package/dist/components/overlays/Popover.shared.cjs +2 -0
  348. package/dist/components/overlays/Popover.shared.cjs.map +1 -0
  349. package/dist/components/overlays/Popover.shared.mjs +182 -0
  350. package/dist/components/overlays/Popover.shared.mjs.map +1 -0
  351. package/dist/components/overlays/TeachingPopover.cjs +2 -0
  352. package/dist/components/overlays/TeachingPopover.cjs.map +1 -0
  353. package/dist/components/overlays/TeachingPopover.mjs +181 -0
  354. package/dist/components/overlays/TeachingPopover.mjs.map +1 -0
  355. package/dist/components/overlays/Tooltip.cjs +2 -0
  356. package/dist/components/overlays/Tooltip.cjs.map +1 -0
  357. package/dist/components/overlays/Tooltip.mjs +160 -0
  358. package/dist/components/overlays/Tooltip.mjs.map +1 -0
  359. package/dist/components/portal/Portal.cjs +2 -0
  360. package/dist/components/portal/Portal.cjs.map +1 -0
  361. package/dist/components/portal/Portal.mjs +45 -0
  362. package/dist/components/portal/Portal.mjs.map +1 -0
  363. package/dist/components/provider/WaveProvider.cjs +2 -0
  364. package/dist/components/provider/WaveProvider.cjs.map +1 -0
  365. package/dist/components/provider/WaveProvider.mjs +51 -0
  366. package/dist/components/provider/WaveProvider.mjs.map +1 -0
  367. package/dist/components/table/DataGrid.cjs +2 -0
  368. package/dist/components/table/DataGrid.cjs.map +1 -0
  369. package/dist/components/table/DataGrid.mjs +489 -0
  370. package/dist/components/table/DataGrid.mjs.map +1 -0
  371. package/dist/components/table/Table.cjs +2 -0
  372. package/dist/components/table/Table.cjs.map +1 -0
  373. package/dist/components/table/Table.mjs +99 -0
  374. package/dist/components/table/Table.mjs.map +1 -0
  375. package/dist/components/table/useGridNavigation.cjs +2 -0
  376. package/dist/components/table/useGridNavigation.cjs.map +1 -0
  377. package/dist/components/table/useGridNavigation.mjs +336 -0
  378. package/dist/components/table/useGridNavigation.mjs.map +1 -0
  379. package/dist/components/typography/Text.cjs +2 -0
  380. package/dist/components/typography/Text.cjs.map +1 -0
  381. package/dist/components/typography/Text.mjs +38 -0
  382. package/dist/components/typography/Text.mjs.map +1 -0
  383. package/dist/hooks/useAnnounce.cjs +2 -0
  384. package/dist/hooks/useAnnounce.cjs.map +1 -0
  385. package/dist/hooks/useAnnounce.mjs +88 -0
  386. package/dist/hooks/useAnnounce.mjs.map +1 -0
  387. package/dist/hooks/useCheckedValues.cjs +2 -0
  388. package/dist/hooks/useCheckedValues.cjs.map +1 -0
  389. package/dist/hooks/useCheckedValues.mjs +102 -0
  390. package/dist/hooks/useCheckedValues.mjs.map +1 -0
  391. package/dist/hooks/useContextMenuAnchor.cjs +2 -0
  392. package/dist/hooks/useContextMenuAnchor.cjs.map +1 -0
  393. package/dist/hooks/useContextMenuAnchor.mjs +132 -0
  394. package/dist/hooks/useContextMenuAnchor.mjs.map +1 -0
  395. package/dist/hooks/useControllable.cjs +2 -0
  396. package/dist/hooks/useControllable.cjs.map +1 -0
  397. package/dist/hooks/useControllable.mjs +37 -0
  398. package/dist/hooks/useControllable.mjs.map +1 -0
  399. package/dist/hooks/useDirection.cjs +2 -0
  400. package/dist/hooks/useDirection.cjs.map +1 -0
  401. package/dist/hooks/useDirection.mjs +57 -0
  402. package/dist/hooks/useDirection.mjs.map +1 -0
  403. package/dist/hooks/useDismiss.cjs +2 -0
  404. package/dist/hooks/useDismiss.cjs.map +1 -0
  405. package/dist/hooks/useDismiss.mjs +57 -0
  406. package/dist/hooks/useDismiss.mjs.map +1 -0
  407. package/dist/hooks/useEventCallback.cjs +2 -0
  408. package/dist/hooks/useEventCallback.cjs.map +1 -0
  409. package/dist/hooks/useEventCallback.mjs +16 -0
  410. package/dist/hooks/useEventCallback.mjs.map +1 -0
  411. package/dist/hooks/useFieldControl.cjs +2 -0
  412. package/dist/hooks/useFieldControl.cjs.map +1 -0
  413. package/dist/hooks/useFieldControl.mjs +62 -0
  414. package/dist/hooks/useFieldControl.mjs.map +1 -0
  415. package/dist/hooks/useFocusTrap.cjs +2 -0
  416. package/dist/hooks/useFocusTrap.cjs.map +1 -0
  417. package/dist/hooks/useFocusTrap.mjs +266 -0
  418. package/dist/hooks/useFocusTrap.mjs.map +1 -0
  419. package/dist/hooks/useFormReset.cjs +2 -0
  420. package/dist/hooks/useFormReset.cjs.map +1 -0
  421. package/dist/hooks/useFormReset.mjs +33 -0
  422. package/dist/hooks/useFormReset.mjs.map +1 -0
  423. package/dist/hooks/useHoverIntent.cjs +2 -0
  424. package/dist/hooks/useHoverIntent.cjs.map +1 -0
  425. package/dist/hooks/useHoverIntent.mjs +201 -0
  426. package/dist/hooks/useHoverIntent.mjs.map +1 -0
  427. package/dist/hooks/useId.cjs +2 -0
  428. package/dist/hooks/useId.cjs.map +1 -0
  429. package/dist/hooks/useId.mjs +11 -0
  430. package/dist/hooks/useId.mjs.map +1 -0
  431. package/dist/hooks/useIsClient.cjs +2 -0
  432. package/dist/hooks/useIsClient.cjs.map +1 -0
  433. package/dist/hooks/useIsClient.mjs +19 -0
  434. package/dist/hooks/useIsClient.mjs.map +1 -0
  435. package/dist/hooks/useListbox.cjs +2 -0
  436. package/dist/hooks/useListbox.cjs.map +1 -0
  437. package/dist/hooks/useListbox.mjs +492 -0
  438. package/dist/hooks/useListbox.mjs.map +1 -0
  439. package/dist/hooks/useMergedRefs.cjs +2 -0
  440. package/dist/hooks/useMergedRefs.cjs.map +1 -0
  441. package/dist/hooks/useMergedRefs.mjs +57 -0
  442. package/dist/hooks/useMergedRefs.mjs.map +1 -0
  443. package/dist/hooks/useModalIsolation.cjs +2 -0
  444. package/dist/hooks/useModalIsolation.cjs.map +1 -0
  445. package/dist/hooks/useModalIsolation.mjs +87 -0
  446. package/dist/hooks/useModalIsolation.mjs.map +1 -0
  447. package/dist/hooks/useModalLayer.cjs +2 -0
  448. package/dist/hooks/useModalLayer.cjs.map +1 -0
  449. package/dist/hooks/useModalLayer.mjs +30 -0
  450. package/dist/hooks/useModalLayer.mjs.map +1 -0
  451. package/dist/hooks/usePopupPosition.cjs +2 -0
  452. package/dist/hooks/usePopupPosition.cjs.map +1 -0
  453. package/dist/hooks/usePopupPosition.mjs +117 -0
  454. package/dist/hooks/usePopupPosition.mjs.map +1 -0
  455. package/dist/hooks/usePrefersReducedMotion.cjs +2 -0
  456. package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -0
  457. package/dist/hooks/usePrefersReducedMotion.mjs +24 -0
  458. package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -0
  459. package/dist/hooks/usePresence.cjs +2 -0
  460. package/dist/hooks/usePresence.cjs.map +1 -0
  461. package/dist/hooks/usePresence.mjs +136 -0
  462. package/dist/hooks/usePresence.mjs.map +1 -0
  463. package/dist/hooks/usePreserveFocus.cjs +2 -0
  464. package/dist/hooks/usePreserveFocus.cjs.map +1 -0
  465. package/dist/hooks/usePreserveFocus.mjs +50 -0
  466. package/dist/hooks/usePreserveFocus.mjs.map +1 -0
  467. package/dist/hooks/useRestoreFocus.cjs +2 -0
  468. package/dist/hooks/useRestoreFocus.cjs.map +1 -0
  469. package/dist/hooks/useRestoreFocus.mjs +271 -0
  470. package/dist/hooks/useRestoreFocus.mjs.map +1 -0
  471. package/dist/hooks/useRovingTabIndex.cjs +2 -0
  472. package/dist/hooks/useRovingTabIndex.cjs.map +1 -0
  473. package/dist/hooks/useRovingTabIndex.mjs +389 -0
  474. package/dist/hooks/useRovingTabIndex.mjs.map +1 -0
  475. package/dist/hooks/useScrollLock.cjs +2 -0
  476. package/dist/hooks/useScrollLock.cjs.map +1 -0
  477. package/dist/hooks/useScrollLock.mjs +71 -0
  478. package/dist/hooks/useScrollLock.mjs.map +1 -0
  479. package/dist/hooks/useTriggerElement.cjs +2 -0
  480. package/dist/hooks/useTriggerElement.cjs.map +1 -0
  481. package/dist/hooks/useTriggerElement.mjs +126 -0
  482. package/dist/hooks/useTriggerElement.mjs.map +1 -0
  483. package/dist/hooks/useTypeahead.cjs +2 -0
  484. package/dist/hooks/useTypeahead.cjs.map +1 -0
  485. package/dist/hooks/useTypeahead.mjs +38 -0
  486. package/dist/hooks/useTypeahead.mjs.map +1 -0
  487. package/dist/index.cjs +1 -1
  488. package/dist/index.d.cts +9099 -0
  489. package/dist/index.d.ts +7688 -1027
  490. package/dist/index.mjs +91 -5695
  491. package/dist/lib/aria.cjs +2 -0
  492. package/dist/lib/aria.cjs.map +1 -0
  493. package/dist/lib/aria.mjs +29 -0
  494. package/dist/lib/aria.mjs.map +1 -0
  495. package/dist/lib/children.cjs +2 -0
  496. package/dist/lib/children.cjs.map +1 -0
  497. package/dist/lib/children.mjs +37 -0
  498. package/dist/lib/children.mjs.map +1 -0
  499. package/dist/lib/cn.cjs +2 -0
  500. package/dist/lib/cn.cjs.map +1 -0
  501. package/dist/lib/cn.mjs +64 -0
  502. package/dist/lib/cn.mjs.map +1 -0
  503. package/dist/lib/composeEventHandlers.cjs +2 -0
  504. package/dist/lib/composeEventHandlers.cjs.map +1 -0
  505. package/dist/lib/composeEventHandlers.mjs +11 -0
  506. package/dist/lib/composeEventHandlers.mjs.map +1 -0
  507. package/dist/lib/dev.cjs +2 -0
  508. package/dist/lib/dev.cjs.map +1 -0
  509. package/dist/lib/dev.mjs +42 -0
  510. package/dist/lib/dev.mjs.map +1 -0
  511. package/dist/lib/direction.cjs +2 -0
  512. package/dist/lib/direction.cjs.map +1 -0
  513. package/dist/lib/direction.mjs +35 -0
  514. package/dist/lib/direction.mjs.map +1 -0
  515. package/dist/lib/events.cjs +2 -0
  516. package/dist/lib/events.cjs.map +1 -0
  517. package/dist/lib/events.mjs +31 -0
  518. package/dist/lib/events.mjs.map +1 -0
  519. package/dist/lib/focus.cjs +2 -0
  520. package/dist/lib/focus.cjs.map +1 -0
  521. package/dist/lib/focus.mjs +119 -0
  522. package/dist/lib/focus.mjs.map +1 -0
  523. package/dist/lib/globalRegistry.cjs +2 -0
  524. package/dist/lib/globalRegistry.cjs.map +1 -0
  525. package/dist/lib/globalRegistry.mjs +13 -0
  526. package/dist/lib/globalRegistry.mjs.map +1 -0
  527. package/dist/lib/icons.cjs +2 -0
  528. package/dist/lib/icons.cjs.map +1 -0
  529. package/dist/lib/icons.mjs +254 -0
  530. package/dist/lib/icons.mjs.map +1 -0
  531. package/dist/lib/labelInName.cjs +2 -0
  532. package/dist/lib/labelInName.cjs.map +1 -0
  533. package/dist/lib/labelInName.mjs +54 -0
  534. package/dist/lib/labelInName.mjs.map +1 -0
  535. package/dist/lib/layers.cjs +2 -0
  536. package/dist/lib/layers.cjs.map +1 -0
  537. package/dist/lib/layers.mjs +224 -0
  538. package/dist/lib/layers.mjs.map +1 -0
  539. package/dist/lib/mergeProps.cjs +2 -0
  540. package/dist/lib/mergeProps.cjs.map +1 -0
  541. package/dist/lib/mergeProps.mjs +21 -0
  542. package/dist/lib/mergeProps.mjs.map +1 -0
  543. package/dist/lib/mergeRefs.cjs +2 -0
  544. package/dist/lib/mergeRefs.cjs.map +1 -0
  545. package/dist/lib/mergeRefs.mjs +29 -0
  546. package/dist/lib/mergeRefs.mjs.map +1 -0
  547. package/dist/lib/renderTrigger.cjs +2 -0
  548. package/dist/lib/renderTrigger.cjs.map +1 -0
  549. package/dist/lib/renderTrigger.mjs +29 -0
  550. package/dist/lib/renderTrigger.mjs.map +1 -0
  551. package/dist/lib/slot.cjs +2 -0
  552. package/dist/lib/slot.cjs.map +1 -0
  553. package/dist/lib/slot.mjs +122 -0
  554. package/dist/lib/slot.mjs.map +1 -0
  555. package/dist/lib/styles.cjs +2 -0
  556. package/dist/lib/styles.cjs.map +1 -0
  557. package/dist/lib/styles.mjs +16 -0
  558. package/dist/lib/styles.mjs.map +1 -0
  559. package/dist/lib/theme.cjs +2 -0
  560. package/dist/lib/theme.cjs.map +1 -0
  561. package/dist/lib/theme.mjs +16 -0
  562. package/dist/lib/theme.mjs.map +1 -0
  563. package/dist/preflight.css +2 -0
  564. package/dist/styles.css +2 -0
  565. package/package.json +149 -100
  566. package/src/styles/animations.css +7 -39
  567. package/src/styles/base.css +103 -0
  568. package/src/styles/globals.css +10 -22
  569. package/src/styles/legacy-tokens.css +184 -0
  570. package/src/styles/preflight.css +7 -0
  571. package/src/styles/styles.css +32 -0
  572. package/src/styles/tailwind.css +17 -0
  573. package/src/styles/tokens.css +561 -221
  574. package/src/styles/variants.css +29 -0
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
@@ -0,0 +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/slot.cjs"),i=require("./Button.semantics.cjs"),a=require("./buttonStyles.cjs");let o=require("react");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=e=>{let{as:c,appearance:l=`outline`,size:u=`medium`,icon:d,iconPosition:f=`before`,disabled:p=!1,disabledFocusable:m=!1,className:h,children:g,ref:_,onClick:v,onKeyDown:y,onKeyUp:b,onBlur:x,...S}=e,C=c??`button`,w=typeof C==`string`?C:null,T=w!==null&&r.VOID_ELEMENTS.has(w),{defaults:E,enforced:D,handlers:O}=i.useButtonSemantics({tag:w,href:S.href,disabled:p,disabledFocusable:m,onClick:v,onKeyDown:y,onKeyUp:b,onBlur:x}),k=S[`aria-disabled`],A=r.renderSlot(r.slotRendersContent(d)?d:void 0,`span`,`inline-flex shrink-0 items-center`,{"aria-hidden":!0}),j=A!==null,M=r.materialiseSlotContent(g),N=r.slotRendersContent(M),P=j&&!N,F=S[`aria-label`],I=S[`aria-labelledby`],L=S.title;o.useEffect(()=>{P&&!F&&!I&&!L&&n.warnOnce(`Button:icon-only-name`,"Button: an icon-only button has no accessible name. Pass `aria-label`, `aria-labelledby` or `title` (the icon is decorative and hidden from assistive technology).")},[P,F,I,L]);let R={...S};for(let[e,t]of Object.entries(E))R[e]??=t;let z=p||m||k===!0||k===`true`,B=M;return T?B=void 0:A&&(B=f===`after`?(0,s.jsxs)(s.Fragment,{children:[M,A]}):(0,s.jsxs)(s.Fragment,{children:[A,M]})),(0,s.jsx)(C,{...R,...O,ref:_,className:t.cn(a.buttonClassName({appearance:l,size:u,disabled:z,iconOnly:P}),j&&N&&`gap-1.5`,h),...D,children:B})};c.displayName=`Button`,exports.Button=c;
2
+ //# sourceMappingURL=Button.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.cjs","names":["VOID_ELEMENTS","useButtonSemantics","renderSlot","slotRendersContent","materialiseSlotContent","_Fragment","cn","buttonClassName","require_runtime","require_cn","require_dev","require_slot","require_Button_semantics","require_buttonStyles","react","react_jsx_runtime","Button","rest","props","Component","as","tag","isVoid","ariaDisabled","iconElement","icon","hasIcon","label","children","hasLabel","iconOnly","ariaLabel","ariaLabelledBy","title","elementProps","key","value","defaults","showDisabledLook","disabled","disabledFocusable","content","iconPosition","handlers","className","enforced"],"sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnOnce } from '../../lib/dev';\nimport {\n materialiseSlotContent,\n renderSlot,\n slotRendersContent,\n VOID_ELEMENTS,\n} from '../../lib/slot';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { useButtonSemantics } from './Button.semantics';\nimport { buttonClassName } from './buttonStyles';\n\n/**\n * The Button's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`), so `as=\"a\"` accepts `href`/`target`\n * and types `onClick` for an anchor.\n */\nexport interface ButtonOwnProps {\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 button 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, e.g.\n * an \"open in new window\" glyph). Follows the writing direction through DOM order. Has no effect\n * on an icon-only button.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Disables the button. Only the intrinsic form controls (`button`, the default, and `input`,\n * `select`, `textarea`) get the native `disabled` attribute. Every other `as` — `a`, `div`,\n * `span` and **any custom component**, including router links and styled or motion components\n * that render a native `<button>` — does not receive `disabled`: it gets `aria-disabled=\"true\"`\n * and `tabIndex={-1}` instead (neither can be overridden), its clicks and Enter/Space are\n * prevented (a click does not reach ancestor `onClick` handlers either, as with a native\n * disabled button), and an `<a>` drops its `href` (it keeps `role=\"link\"` when it had one,\n * `role=\"button\"` otherwise). Such an element leaves the tab order but, like any\n * `tabIndex={-1}` element, can still take focus from a mouse click, and a component's own\n * `:disabled` styling does not apply. Every disabled Button also renders `data-disabled`.\n * @default false\n */\n disabled?: boolean;\n /**\n * Marks the button unavailable but keeps it focusable and in the tab order: for toolbar items, a\n * button that disables itself when activated, or a disabled button that needs a Tooltip. Renders\n * `aria-disabled=\"true\"`, `data-disabled` and `data-disabled-focusable` instead of the native\n * `disabled` attribute. Clicks, Enter, Space and implicit form submission are prevented; your\n * `onClick` is not called and the click does not reach ancestor click handlers. Hover and pressed\n * colors are off. 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\n/**\n * Props of {@link Button} rendered as `C` (default `'button'`). `ButtonProps` without a type\n * argument is the 0.4 name: the props of a Button rendered as a `<button>`, including `ref`.\n *\n * @example\n * interface SaveButtonProps extends ButtonProps { tracking?: string }\n * const props: ButtonProps<'a'> = { as: 'a', href: '/docs', appearance: 'primary' };\n */\nexport type ButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n ButtonOwnProps\n>;\n\n/** The props the implementation reads, for any `as` (the public typing is `PolymorphicComponent`). */\ntype ButtonImplProps = ButtonOwnProps &\n Omit<React.HTMLAttributes<HTMLElement>, 'onClick' | 'onKeyDown' | 'onKeyUp'> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n /** An anchor's destination (`as=\"a\"`): without one, the anchor gets button semantics. */\n href?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n };\n\n/**\n * A button with Fluent appearances and sizes.\n *\n * - Renders a `<button type=\"button\">` by default (pass `type=\"submit\"` to submit a form).\n * - `as` renders another element or component with correctly typed props\n * (`<Button as=\"a\" href=\"/docs\">`, `<Button as={RouterLink} to=\"/\">`).\n * - Non-button elements keep button semantics: an element that is not interactive by itself\n * (`as=\"div\"`, `as=\"span\"`) and an `as=\"a\"` without `href` get `role=\"button\"`, a tab stop and\n * Enter/Space activation (an `<a>` with any `href`, `''` included, stays a link), and\n * `disabled` becomes `aria-disabled` + `tabIndex={-1}` with clicks and keys prevented.\n * - A custom `as` component receives neither the `type=\"button\"` default nor `disabled` (see\n * `disabled`), even when it renders a native `<button>`: pass `type` yourself inside a form.\n * - The `icon` slot is decorative (`aria-hidden`); give icon-only buttons an `aria-label`.\n * - `disabledFocusable` keeps an unavailable button focusable (a Tooltip can explain why, a\n * toolbar keeps it in its arrow-key order) and blocks its activation.\n * - A consumer `aria-disabled=\"true\"` shows the disabled look and suppresses hover and pressed\n * colors, but the button stays focusable and its handlers still run: guard them yourself, or use\n * `disabledFocusable`, which does both.\n * - Colors are theme tokens; hover and pressed styles never apply while disabled.\n * - Hover and pressed colors are gated (`not-disabled:not-aria-disabled:hover:`), which gives\n * them a higher CSS specificity than a bare `hover:` class. To override them in `className`,\n * use the same prefix (`not-disabled:not-aria-disabled:hover:bg-error`, which replaces the\n * built-in class) or the important modifier (`hover:bg-error!`).\n *\n * @example\n * <Button appearance=\"primary\" icon={<SaveIcon />}>Save</Button>\n * <Button as=\"a\" href=\"/docs\">Documentation</Button>\n * <Button icon={<CloseIcon />} aria-label=\"Close\" appearance=\"subtle\" />\n */\nexport const Button: PolymorphicComponent<'button', ButtonOwnProps> = (props) => {\n const {\n as,\n appearance = 'outline',\n size = 'medium',\n icon,\n iconPosition = 'before',\n disabled = false,\n disabledFocusable = false,\n className,\n children,\n ref,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n ...rest\n } = props as ButtonImplProps;\n\n const Component: React.ElementType = as ?? 'button';\n const tag = typeof Component === 'string' ? Component : null;\n const isVoid = tag !== null && VOID_ELEMENTS.has(tag);\n // Defaults, enforced attributes and handlers per tag and disabled state (shared with Link).\n const { defaults, enforced, handlers } = useButtonSemantics({\n tag,\n href: rest.href,\n disabled,\n disabledFocusable,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n });\n const ariaDisabled = rest['aria-disabled'];\n /**\n * An `icon` that renders nothing (`''` from `icon={name && <Icon />}`, an empty array, Set or\n * Fragment) is treated like no icon: no empty `aria-hidden` span, no gap, no icon-only sizing.\n */\n const iconElement = renderSlot(\n slotRendersContent(icon) ? icon : undefined,\n 'span',\n 'inline-flex shrink-0 items-center',\n { 'aria-hidden': true },\n );\n /** Derived from what renders, so an icon that renders nothing never counts. */\n const hasIcon = iconElement !== null;\n // A generator label is read once by the check; its items are what renders.\n const label = materialiseSlotContent(children);\n const hasLabel = slotRendersContent(label);\n const iconOnly = hasIcon && !hasLabel;\n\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n const title = rest.title;\n React.useEffect(() => {\n if (iconOnly && !ariaLabel && !ariaLabelledBy && !title) {\n warnOnce(\n 'Button:icon-only-name',\n 'Button: an icon-only button has no accessible name. Pass `aria-label`, `aria-labelledby` or `title` (the icon is decorative and hidden from assistive technology).',\n );\n }\n }, [iconOnly, ariaLabel, ariaLabelledBy, title]);\n\n // Defaults apply wherever the consumer's value is `undefined` or `null` (C-COMPOSE), so a wrapper\n // that forwards `type={type}` never drops `type=\"button\"`, the role or the tab stop.\n const elementProps: Record<string, unknown> = { ...rest };\n for (const [key, value] of Object.entries(defaults)) elementProps[key] ??= value;\n\n const showDisabledLook =\n disabled || disabledFocusable || ariaDisabled === true || ariaDisabled === 'true';\n let content: React.ReactNode = label;\n if (isVoid) content = undefined;\n else if (iconElement) {\n // DOM order, so the icon follows the writing direction (no physical classes).\n content =\n iconPosition === 'after' ? (\n <>\n {label}\n {iconElement}\n </>\n ) : (\n <>\n {iconElement}\n {label}\n </>\n );\n }\n\n return (\n <Component\n {...elementProps}\n {...handlers}\n ref={ref}\n className={cn(\n buttonClassName({ appearance, size, disabled: showDisabledLook, iconOnly }),\n hasIcon && hasLabel && 'gap-1.5',\n className,\n )}\n {...enforced}\n >\n {content}\n </Component>\n );\n};\n\nButton.displayName = 'Button';\n"],"mappings":"iTA0HA,IAAagB,EAA0D,GAAU,CAC/E,GAAM,CACJ,KACA,aAAa,UACb,OAAO,SACP,OACA,eAAe,SACf,WAAW,GACX,oBAAoB,GACpB,YACA,WACA,MACA,UACA,YACA,UACA,SACA,GAAGC,GACDC,EAEEC,EAA+BC,GAAM,SACrCC,EAAM,OAAOF,GAAc,SAAWA,EAAY,KAClDG,EAASD,IAAQ,MAAQrB,EAAAA,cAAc,IAAIqB,CAAG,EAE9C,CAAE,WAAU,WAAU,YAAapB,EAAAA,mBAAmB,CAC1D,MACA,KAAMgB,EAAK,KACX,WACA,oBACA,UACA,YACA,UACA,QACF,CAAC,EACKM,EAAeN,EAAK,iBAKpBO,EAActB,EAAAA,WAClBC,EAAAA,mBAAmBsB,CAAI,EAAIA,EAAO,IAAA,GAClC,OACA,oCACA,CAAE,cAAe,EAAK,CACxB,EAEMC,EAAUF,IAAgB,KAE1BG,EAAQvB,EAAAA,uBAAuBwB,CAAQ,EACvCC,EAAW1B,EAAAA,mBAAmBwB,CAAK,EACnCG,EAAWJ,GAAW,CAACG,EAEvBE,EAAYd,EAAK,cACjBe,EAAiBf,EAAK,mBACtBgB,EAAQhB,EAAK,MACnBH,EAAM,cAAgB,CAChBgB,GAAY,CAACC,GAAa,CAACC,GAAkB,CAACC,GAChDvB,EAAA,SACE,wBACA,oKACF,CAEJ,EAAG,CAACoB,EAAUC,EAAWC,EAAgBC,CAAK,CAAC,EAI/C,IAAMC,EAAwC,CAAE,GAAGjB,CAAK,EACxD,IAAK,GAAM,CAACkB,EAAKC,KAAU,OAAO,QAAQC,CAAQ,EAAG,EAAaF,KAASC,EAE3E,IAAME,EACJC,GAAYC,GAAqBjB,IAAiB,IAAQA,IAAiB,OACzEkB,EAA2Bd,EAkB/B,OAjBIL,EAAQ,EAAU,IAAA,GACbE,IAEP,EACEkB,IAAiB,SACf,EAAA3B,EAAA,KAAA,CAAAV,EAAAA,SAAA,CAAA,SAAA,CACGsB,EACAH,CACD,CAAA,CAAA,GAEF,EAAAT,EAAA,KAAA,CAAAV,EAAAA,SAAA,CAAA,SAAA,CACGmB,EACAG,CACD,CAAA,CAAA,IAKN,EAAAZ,EAAA,IAAA,CAACI,EAAD,CACE,GAAIe,EACJ,GAAIS,EACC,MACL,UAAWrC,EAAAA,GACTC,EAAAA,gBAAgB,CAAE,aAAY,OAAM,SAAU+B,EAAkB,UAAS,CAAC,EAC1EZ,GAAWG,GAAY,UACvBe,CACF,EACA,GAAIC,EAEH,SAAAJ,CACQ,CAAA,CAEf,EAEA,EAAO,YAAc"}
@@ -0,0 +1,50 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { warnOnce as t } from "../../lib/dev.mjs";
4
+ import { VOID_ELEMENTS as n, materialiseSlotContent as r, renderSlot as i, slotRendersContent as a } from "../../lib/slot.mjs";
5
+ import { useButtonSemantics as o } from "./Button.semantics.mjs";
6
+ import { buttonClassName as s } from "./buttonStyles.mjs";
7
+ import * as c from "react";
8
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
9
+ //#region src/components/button/Button.tsx
10
+ var f = (f) => {
11
+ let { as: p, appearance: m = "outline", size: h = "medium", icon: g, iconPosition: _ = "before", disabled: v = !1, disabledFocusable: y = !1, className: b, children: x, ref: S, onClick: C, onKeyDown: w, onKeyUp: T, onBlur: E, ...D } = f, O = p ?? "button", k = typeof O == "string" ? O : null, A = k !== null && n.has(k), { defaults: j, enforced: M, handlers: N } = o({
12
+ tag: k,
13
+ href: D.href,
14
+ disabled: v,
15
+ disabledFocusable: y,
16
+ onClick: C,
17
+ onKeyDown: w,
18
+ onKeyUp: T,
19
+ onBlur: E
20
+ }), P = D["aria-disabled"], F = i(a(g) ? g : void 0, "span", "inline-flex shrink-0 items-center", { "aria-hidden": !0 }), I = F !== null, L = r(x), R = a(L), z = I && !R, B = D["aria-label"], V = D["aria-labelledby"], H = D.title;
21
+ c.useEffect(() => {
22
+ z && !B && !V && !H && t("Button:icon-only-name", "Button: an icon-only button has no accessible name. Pass `aria-label`, `aria-labelledby` or `title` (the icon is decorative and hidden from assistive technology).");
23
+ }, [
24
+ z,
25
+ B,
26
+ V,
27
+ H
28
+ ]);
29
+ let U = { ...D };
30
+ for (let [e, t] of Object.entries(j)) U[e] ??= t;
31
+ let W = v || y || P === !0 || P === "true", G = L;
32
+ return A ? G = void 0 : F && (G = _ === "after" ? /* @__PURE__ */ d(l, { children: [L, F] }) : /* @__PURE__ */ d(l, { children: [F, L] })), /* @__PURE__ */ u(O, {
33
+ ...U,
34
+ ...N,
35
+ ref: S,
36
+ className: e(s({
37
+ appearance: m,
38
+ size: h,
39
+ disabled: W,
40
+ iconOnly: z
41
+ }), I && R && "gap-1.5", b),
42
+ ...M,
43
+ children: G
44
+ });
45
+ };
46
+ f.displayName = "Button";
47
+ //#endregion
48
+ export { f as Button };
49
+
50
+ //# sourceMappingURL=Button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.mjs","names":["_Fragment","React","Button","rest","props","Component","as","tag","isVoid","VOID_ELEMENTS","useButtonSemantics","ariaDisabled","iconElement","renderSlot","slotRendersContent","icon","hasIcon","label","materialiseSlotContent","children","hasLabel","iconOnly","ariaLabel","ariaLabelledBy","title","warnOnce","elementProps","key","value","defaults","showDisabledLook","disabled","disabledFocusable","content","iconPosition","Fragment","handlers","cn","buttonClassName","className","enforced"],"sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnOnce } from '../../lib/dev';\nimport {\n materialiseSlotContent,\n renderSlot,\n slotRendersContent,\n VOID_ELEMENTS,\n} from '../../lib/slot';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { useButtonSemantics } from './Button.semantics';\nimport { buttonClassName } from './buttonStyles';\n\n/**\n * The Button's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`), so `as=\"a\"` accepts `href`/`target`\n * and types `onClick` for an anchor.\n */\nexport interface ButtonOwnProps {\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 button 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, e.g.\n * an \"open in new window\" glyph). Follows the writing direction through DOM order. Has no effect\n * on an icon-only button.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n /**\n * Disables the button. Only the intrinsic form controls (`button`, the default, and `input`,\n * `select`, `textarea`) get the native `disabled` attribute. Every other `as` — `a`, `div`,\n * `span` and **any custom component**, including router links and styled or motion components\n * that render a native `<button>` — does not receive `disabled`: it gets `aria-disabled=\"true\"`\n * and `tabIndex={-1}` instead (neither can be overridden), its clicks and Enter/Space are\n * prevented (a click does not reach ancestor `onClick` handlers either, as with a native\n * disabled button), and an `<a>` drops its `href` (it keeps `role=\"link\"` when it had one,\n * `role=\"button\"` otherwise). Such an element leaves the tab order but, like any\n * `tabIndex={-1}` element, can still take focus from a mouse click, and a component's own\n * `:disabled` styling does not apply. Every disabled Button also renders `data-disabled`.\n * @default false\n */\n disabled?: boolean;\n /**\n * Marks the button unavailable but keeps it focusable and in the tab order: for toolbar items, a\n * button that disables itself when activated, or a disabled button that needs a Tooltip. Renders\n * `aria-disabled=\"true\"`, `data-disabled` and `data-disabled-focusable` instead of the native\n * `disabled` attribute. Clicks, Enter, Space and implicit form submission are prevented; your\n * `onClick` is not called and the click does not reach ancestor click handlers. Hover and pressed\n * colors are off. 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\n/**\n * Props of {@link Button} rendered as `C` (default `'button'`). `ButtonProps` without a type\n * argument is the 0.4 name: the props of a Button rendered as a `<button>`, including `ref`.\n *\n * @example\n * interface SaveButtonProps extends ButtonProps { tracking?: string }\n * const props: ButtonProps<'a'> = { as: 'a', href: '/docs', appearance: 'primary' };\n */\nexport type ButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n ButtonOwnProps\n>;\n\n/** The props the implementation reads, for any `as` (the public typing is `PolymorphicComponent`). */\ntype ButtonImplProps = ButtonOwnProps &\n Omit<React.HTMLAttributes<HTMLElement>, 'onClick' | 'onKeyDown' | 'onKeyUp'> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n /** An anchor's destination (`as=\"a\"`): without one, the anchor gets button semantics. */\n href?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n };\n\n/**\n * A button with Fluent appearances and sizes.\n *\n * - Renders a `<button type=\"button\">` by default (pass `type=\"submit\"` to submit a form).\n * - `as` renders another element or component with correctly typed props\n * (`<Button as=\"a\" href=\"/docs\">`, `<Button as={RouterLink} to=\"/\">`).\n * - Non-button elements keep button semantics: an element that is not interactive by itself\n * (`as=\"div\"`, `as=\"span\"`) and an `as=\"a\"` without `href` get `role=\"button\"`, a tab stop and\n * Enter/Space activation (an `<a>` with any `href`, `''` included, stays a link), and\n * `disabled` becomes `aria-disabled` + `tabIndex={-1}` with clicks and keys prevented.\n * - A custom `as` component receives neither the `type=\"button\"` default nor `disabled` (see\n * `disabled`), even when it renders a native `<button>`: pass `type` yourself inside a form.\n * - The `icon` slot is decorative (`aria-hidden`); give icon-only buttons an `aria-label`.\n * - `disabledFocusable` keeps an unavailable button focusable (a Tooltip can explain why, a\n * toolbar keeps it in its arrow-key order) and blocks its activation.\n * - A consumer `aria-disabled=\"true\"` shows the disabled look and suppresses hover and pressed\n * colors, but the button stays focusable and its handlers still run: guard them yourself, or use\n * `disabledFocusable`, which does both.\n * - Colors are theme tokens; hover and pressed styles never apply while disabled.\n * - Hover and pressed colors are gated (`not-disabled:not-aria-disabled:hover:`), which gives\n * them a higher CSS specificity than a bare `hover:` class. To override them in `className`,\n * use the same prefix (`not-disabled:not-aria-disabled:hover:bg-error`, which replaces the\n * built-in class) or the important modifier (`hover:bg-error!`).\n *\n * @example\n * <Button appearance=\"primary\" icon={<SaveIcon />}>Save</Button>\n * <Button as=\"a\" href=\"/docs\">Documentation</Button>\n * <Button icon={<CloseIcon />} aria-label=\"Close\" appearance=\"subtle\" />\n */\nexport const Button: PolymorphicComponent<'button', ButtonOwnProps> = (props) => {\n const {\n as,\n appearance = 'outline',\n size = 'medium',\n icon,\n iconPosition = 'before',\n disabled = false,\n disabledFocusable = false,\n className,\n children,\n ref,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n ...rest\n } = props as ButtonImplProps;\n\n const Component: React.ElementType = as ?? 'button';\n const tag = typeof Component === 'string' ? Component : null;\n const isVoid = tag !== null && VOID_ELEMENTS.has(tag);\n // Defaults, enforced attributes and handlers per tag and disabled state (shared with Link).\n const { defaults, enforced, handlers } = useButtonSemantics({\n tag,\n href: rest.href,\n disabled,\n disabledFocusable,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n });\n const ariaDisabled = rest['aria-disabled'];\n /**\n * An `icon` that renders nothing (`''` from `icon={name && <Icon />}`, an empty array, Set or\n * Fragment) is treated like no icon: no empty `aria-hidden` span, no gap, no icon-only sizing.\n */\n const iconElement = renderSlot(\n slotRendersContent(icon) ? icon : undefined,\n 'span',\n 'inline-flex shrink-0 items-center',\n { 'aria-hidden': true },\n );\n /** Derived from what renders, so an icon that renders nothing never counts. */\n const hasIcon = iconElement !== null;\n // A generator label is read once by the check; its items are what renders.\n const label = materialiseSlotContent(children);\n const hasLabel = slotRendersContent(label);\n const iconOnly = hasIcon && !hasLabel;\n\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n const title = rest.title;\n React.useEffect(() => {\n if (iconOnly && !ariaLabel && !ariaLabelledBy && !title) {\n warnOnce(\n 'Button:icon-only-name',\n 'Button: an icon-only button has no accessible name. Pass `aria-label`, `aria-labelledby` or `title` (the icon is decorative and hidden from assistive technology).',\n );\n }\n }, [iconOnly, ariaLabel, ariaLabelledBy, title]);\n\n // Defaults apply wherever the consumer's value is `undefined` or `null` (C-COMPOSE), so a wrapper\n // that forwards `type={type}` never drops `type=\"button\"`, the role or the tab stop.\n const elementProps: Record<string, unknown> = { ...rest };\n for (const [key, value] of Object.entries(defaults)) elementProps[key] ??= value;\n\n const showDisabledLook =\n disabled || disabledFocusable || ariaDisabled === true || ariaDisabled === 'true';\n let content: React.ReactNode = label;\n if (isVoid) content = undefined;\n else if (iconElement) {\n // DOM order, so the icon follows the writing direction (no physical classes).\n content =\n iconPosition === 'after' ? (\n <>\n {label}\n {iconElement}\n </>\n ) : (\n <>\n {iconElement}\n {label}\n </>\n );\n }\n\n return (\n <Component\n {...elementProps}\n {...handlers}\n ref={ref}\n className={cn(\n buttonClassName({ appearance, size, disabled: showDisabledLook, iconOnly }),\n hasIcon && hasLabel && 'gap-1.5',\n className,\n )}\n {...enforced}\n >\n {content}\n </Component>\n );\n};\n\nButton.displayName = 'Button';\n"],"mappings":";;;;;;;;;AA0HA,IAAaE,KAA0D,MAAU;CAC/E,IAAM,EACJ,OACA,gBAAa,WACb,UAAO,UACP,SACA,kBAAe,UACf,cAAW,IACX,uBAAoB,IACpB,cACA,aACA,QACA,YACA,cACA,YACA,WACA,GAAGC,MACDC,GAEEC,IAA+BC,KAAM,UACrCC,IAAM,OAAOF,KAAc,WAAWA,IAAY,MAClDG,IAASD,MAAQ,QAAQE,EAAc,IAAIF,CAAG,GAE9C,EAAE,aAAU,aAAU,gBAAaG,EAAmB;EAC1D;EACA,MAAMP,EAAK;EACX;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GACKQ,IAAeR,EAAK,kBAKpBS,IAAcC,EAClBC,EAAmBC,CAAI,IAAIA,IAAO,KAAA,GAClC,QACA,qCACA,EAAE,eAAe,GAAK,CACxB,GAEMC,IAAUJ,MAAgB,MAE1BK,IAAQC,EAAuBC,CAAQ,GACvCC,IAAWN,EAAmBG,CAAK,GACnCI,IAAWL,KAAW,CAACI,GAEvBE,IAAYnB,EAAK,eACjBoB,IAAiBpB,EAAK,oBACtBqB,IAAQrB,EAAK;CACnB,EAAM,gBAAgB;EACpB,AAAIkB,KAAY,CAACC,KAAa,CAACC,KAAkB,CAACC,KAChDC,EACE,yBACA,oKACF;CAEJ,GAAG;EAACJ;EAAUC;EAAWC;EAAgBC;CAAK,CAAC;CAI/C,IAAME,IAAwC,EAAE,GAAGvB,EAAK;CACxD,KAAK,IAAM,CAACwB,GAAKC,MAAU,OAAO,QAAQC,CAAQ,GAAG,EAAaF,OAASC;CAE3E,IAAME,IACJC,KAAYC,KAAqBrB,MAAiB,MAAQA,MAAiB,QACzEsB,IAA2BhB;CAkB/B,OAjBIT,IAAQ,IAAU,KAAA,IACbI,MAEP,IACEsB,MAAiB,UACf,kBAAAlC,GAAA,EAAA,UAAA,CACGiB,GACAL,CACD,EAAA,CAAA,IAEF,kBAAAZ,GAAA,EAAA,UAAA,CACGY,GACAK,CACD,EAAA,CAAA,IAKN,kBAACZ,GAAD;EACE,GAAIqB;EACJ,GAAIU;EACC;EACL,WAAWC,EACTC,EAAgB;GAAE;GAAY;GAAM,UAAUR;GAAkB;EAAS,CAAC,GAC1Ed,KAAWI,KAAY,WACvBmB,CACF;EACA,GAAIC;EAEH,UAAAP;CACQ,CAAA;AAEf;AAEA,EAAO,cAAc"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/composeEventHandlers.cjs"),n=require("../../hooks/useEventCallback.cjs"),r=require("../../lib/aria.cjs");let i=require("react");i=e.__toESM(i,1);var a=new Set([`a`,`button`,`input`,`select`,`textarea`,`summary`]),o=new Set([`button`,`input`,`select`,`textarea`]),s=e=>e===`Enter`||e===` `;function c(e,t){return e===null?!1:e===`a`?t==null:!a.has(e)}function l(e){let{tag:a,href:l,disabled:u,disabledFocusable:d,onClick:f,onKeyDown:p,onKeyUp:m,onBlur:h}=e,g=i.useRef(!1),_=n.useEventCallback(e=>{g.current=e}),v=n.useEventCallback(()=>{let e=g.current;return g.current=!1,e}),y=c(a,l),b=a!==null&&o.has(a),x={},S={},C=f,w=p,T=m,E=h;a===`button`&&(x.type=`button`),y&&(x.role=`button`,x.tabIndex=0);let D=d||u&&!b;d?(Object.assign(S,r.focusableDisabledProps(!0,{reachable:!0})),a===`a`&&(x.role??=`link`,x.tabIndex=0,S.href=void 0)):u&&b?(S.disabled=!0,S[`data-disabled`]=``):u&&(a===`a`&&(x.role??=`link`,S.href=void 0),Object.assign(S,r.focusableDisabledProps(!0)),S.tabIndex=-1),D?(C=e=>{e.preventDefault(),e.stopPropagation()},w=e=>{if(s(e.key)){_(!1),e.preventDefault();return}p?.(e)},T=e=>{if(e.key===` `||e.key===`Enter`&&!d){_(!1),e.preventDefault();return}m?.(e)}):y&&(w=t.composeEventHandlers(p,e=>{e.target===e.currentTarget&&s(e.key)&&(e.preventDefault(),e.key===`Enter`?e.currentTarget.click():_(!0))}),T=e=>{m?.(e),e.key===` `&&v()&&!e.defaultPrevented&&e.target===e.currentTarget&&(e.preventDefault(),e.currentTarget.click())},E=t.composeEventHandlers(h,()=>_(!1),{checkDefaultPrevented:!1}));let O={};return C&&(O.onClick=C),w&&(O.onKeyDown=w),T&&(O.onKeyUp=T),E&&(O.onBlur=E),{defaults:x,enforced:S,handlers:O}}exports.NATIVE_DISABLED_ELEMENTS=o,exports.needsButtonSemantics=c,exports.useButtonSemantics=l;
2
+ //# sourceMappingURL=Button.semantics.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.semantics.cjs","names":["React","useEventCallback","focusableDisabledProps","composeEventHandlers","require_runtime","require_composeEventHandlers","require_useEventCallback","require_aria","react","INTERACTIVE_ELEMENTS","NATIVE_DISABLED_ELEMENTS","isActivationKey","key","needsButtonSemantics","tag","href","useButtonSemantics","options","spaceArmedRef","setSpaceArmed","armed","takeSpaceArmed","buttonLike","usesNativeDisabled","defaults","enforced","handleClick","onClick","handleKeyDown","onKeyDown","handleKeyUp","onKeyUp","handleBlur","onBlur","blocksActivation","disabledFocusable","disabled","event","handlers"],"sources":["../../../src/components/button/Button.semantics.ts"],"sourcesContent":["/**\n * Activation semantics shared by `Button` and `Link`: which element needs button semantics, the\n * defaults and enforced attributes of each tag and disabled state, and the handlers that add or\n * block activation. Internal to `src/components/button/` (not exported from the package).\n */\nimport * as React from 'react';\nimport { focusableDisabledProps } from '../../lib/aria';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { useEventCallback } from '../../hooks/useEventCallback';\n\n/** Intrinsic elements that are interactive on their own: no `role=\"button\"` or tab stop added. */\nconst INTERACTIVE_ELEMENTS: ReadonlySet<string> = new Set([\n 'a',\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'summary',\n]);\n\n/** Intrinsic elements whose native `disabled` attribute makes them unavailable. */\nexport const NATIVE_DISABLED_ELEMENTS: ReadonlySet<string> = new Set([\n 'button',\n 'input',\n 'select',\n 'textarea',\n]);\n\nconst isActivationKey = (key: string) => key === 'Enter' || key === ' ';\n\n/**\n * Whether an intrinsic element needs button semantics: not interactive by itself, or an `<a>`\n * whose `href` is `undefined` or `null` (any string, `''` included, keeps it a link). `tag` is\n * `null` for a custom component, which never gets them.\n */\nexport function needsButtonSemantics(tag: string | null, href: unknown): boolean {\n if (tag === null) return false;\n if (tag === 'a') return href == null;\n return !INTERACTIVE_ELEMENTS.has(tag);\n}\n\n/** Options of {@link useButtonSemantics}. */\nexport interface ButtonSemanticsOptions {\n /**\n * The rendered intrinsic tag, or `null` for a custom `as` component (no role, tab stop or key\n * handling is added to it; the disabled attributes and handlers are).\n */\n tag: string | null;\n /** The consumer's `href` (decides link or button semantics for an `<a>`). */\n href: unknown;\n /** Makes the element unavailable: natively for form controls, with `aria-disabled` otherwise. */\n disabled: boolean;\n /** Unavailable but focusable and in the tab order. Wins over `disabled`. */\n disabledFocusable: boolean;\n /** The consumer's handlers; the returned handlers compose or replace them. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n onBlur?: React.FocusEventHandler<HTMLElement>;\n}\n\n/** The result of {@link useButtonSemantics}. */\nexport interface ButtonSemantics {\n /**\n * Defaults the consumer may override (C-COMPOSE: `type`, `role`, `tabIndex`). Apply each one\n * wherever the consumer's value is `undefined` or `null`, so a wrapper that forwards\n * `type={type}` never drops `type=\"button\"`, the role or the tab stop.\n */\n defaults: Record<string, unknown>;\n /**\n * Attributes the consumer must not override: spread after `{...rest}` (`disabled`,\n * `aria-disabled`, `data-disabled`, `data-disabled-focusable`, `href: undefined`, `tabIndex: -1`\n * for a disabled non-native element).\n */\n enforced: Record<string, unknown>;\n /** Only the handlers that exist, so a custom `as` component keeps its own defaults. */\n handlers: {\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n onBlur?: React.FocusEventHandler<HTMLElement>;\n };\n}\n\n/**\n * Defaults, enforced attributes and composed handlers for Button and Link.\n *\n * - An intrinsic element that is not interactive by itself (`div`, `span`) and an `<a>` without\n * `href` get `role=\"button\"` and `tabIndex={0}` as defaults; Enter activates on keydown, Space\n * arms on keydown (preventing page scroll) and activates on the following keyup, and moving\n * focus in between cancels it (native button behaviour). A native `<button>` defaults to\n * `type=\"button\"`.\n * - `disabled` on a form control (`button`, `input`, `select`, `textarea`): the native attribute.\n * On any other element: `aria-disabled` and `tabIndex={-1}`; an `<a>` drops its `href` and keeps\n * `role=\"link\"` when it had one (`role=\"button\"` without).\n * - `disabledFocusable` (wins over `disabled`), for every element: `aria-disabled`,\n * `data-disabled-focusable` and no native `disabled`; the element stays in the tab order (an\n * `<a>` drops its `href` and gets `tabIndex={0}` as a default).\n * - Every disabled state renders `data-disabled`. While disabled without the native attribute, a\n * click is prevented and stopped (a natively disabled button dispatches no click to ancestors),\n * Enter and Space are prevented and not forwarded, and other keys reach the consumer. Under\n * `disabledFocusable` the Enter keyup (which activates nothing) reaches the consumer too.\n */\nexport function useButtonSemantics(options: ButtonSemanticsOptions): ButtonSemantics {\n const { tag, href, disabled, disabledFocusable, onClick, onKeyDown, onKeyUp, onBlur } = options;\n\n /**\n * Set by an unprevented Space keydown on the element itself; Space activates on keyup only while\n * it is set (like a native button: a keyup alone never clicks). Cleared on keyup and blur. The\n * ref is only touched from event handlers, through these two stable callbacks (C-HOOKS).\n */\n const spaceArmedRef = React.useRef(false);\n /** Arms (or disarms) Space activation. */\n const setSpaceArmed = useEventCallback((armed: boolean) => {\n spaceArmedRef.current = armed;\n });\n /** Reads and clears the Space arm. */\n const takeSpaceArmed = useEventCallback(() => {\n const armed = spaceArmedRef.current;\n spaceArmedRef.current = false;\n return armed;\n });\n\n const buttonLike = needsButtonSemantics(tag, href);\n const usesNativeDisabled = tag !== null && NATIVE_DISABLED_ELEMENTS.has(tag);\n\n const defaults: Record<string, unknown> = {};\n const enforced: Record<string, unknown> = {};\n let handleClick = onClick;\n let handleKeyDown = onKeyDown;\n let handleKeyUp = onKeyUp;\n let handleBlur = onBlur;\n\n if (tag === 'button') defaults.type = 'button';\n if (buttonLike) {\n defaults.role = 'button';\n defaults.tabIndex = 0;\n }\n\n const blocksActivation = disabledFocusable || (disabled && !usesNativeDisabled);\n if (disabledFocusable) {\n Object.assign(enforced, focusableDisabledProps(true, { reachable: true }));\n if (tag === 'a') {\n // Drop the destination (no middle-click or context-menu navigation) but keep the tab stop.\n defaults.role ??= 'link';\n defaults.tabIndex = 0;\n enforced.href = undefined;\n }\n } else if (disabled && usesNativeDisabled) {\n enforced.disabled = true;\n enforced['data-disabled'] = '';\n } else if (disabled) {\n // Not a form control: `disabled` has no effect, so expose and enforce the state ourselves.\n if (tag === 'a') {\n // Drop the destination but keep the link role when there was one.\n defaults.role ??= 'link';\n enforced.href = undefined;\n }\n Object.assign(enforced, focusableDisabledProps(true));\n enforced.tabIndex = -1;\n }\n\n if (blocksActivation) {\n // A natively disabled button dispatches no click at all, so ancestors never see this one.\n handleClick = (event) => {\n event.preventDefault();\n event.stopPropagation();\n };\n handleKeyDown = (event) => {\n if (isActivationKey(event.key)) {\n setSpaceArmed(false);\n event.preventDefault();\n return;\n }\n onKeyDown?.(event);\n };\n // Space activates on keyup and is blocked. Enter activates on keydown, so a focusable disabled\n // control forwards its keyup like any other key; a disabled non-native element blocks both.\n handleKeyUp = (event) => {\n if (event.key === ' ' || (event.key === 'Enter' && !disabledFocusable)) {\n setSpaceArmed(false);\n event.preventDefault();\n return;\n }\n onKeyUp?.(event);\n };\n } else if (buttonLike) {\n // APG button: Enter activates on keydown; Space arms on keydown (preventing page scroll) and\n // activates on the following keyup. A consumer `preventDefault()` on the keydown cancels both.\n handleKeyDown = composeEventHandlers(onKeyDown, (event: React.KeyboardEvent<HTMLElement>) => {\n if (event.target !== event.currentTarget || !isActivationKey(event.key)) return;\n event.preventDefault();\n if (event.key === 'Enter') event.currentTarget.click();\n else setSpaceArmed(true);\n });\n handleKeyUp = (event) => {\n onKeyUp?.(event);\n if (event.key !== ' ') return;\n const armed = takeSpaceArmed();\n if (!armed || event.defaultPrevented || event.target !== event.currentTarget) return;\n event.preventDefault();\n event.currentTarget.click();\n };\n // Moving focus away between keydown and keyup cancels a Space activation (native behavior).\n handleBlur = composeEventHandlers(onBlur, () => setSpaceArmed(false), {\n checkDefaultPrevented: false,\n });\n }\n\n const handlers: ButtonSemantics['handlers'] = {};\n if (handleClick) handlers.onClick = handleClick;\n if (handleKeyDown) handlers.onKeyDown = handleKeyDown;\n if (handleKeyUp) handlers.onKeyUp = handleKeyUp;\n if (handleBlur) handlers.onBlur = handleBlur;\n\n return { defaults, enforced, handlers };\n}\n"],"mappings":"2OAWA,IAAMS,EAA4C,IAAI,IAAI,CACxD,IACA,SACA,QACA,SACA,WACA,SACF,CAAC,EAGYC,EAAgD,IAAI,IAAI,CACnE,SACA,QACA,SACA,UACF,CAAC,EAEKC,EAAmB,GAAgBC,IAAQ,SAAWA,IAAQ,IAOpE,SAAgBC,EAAqB,EAAoB,EAAwB,CAG/E,OAFIC,IAAQ,KAAa,GACrBA,IAAQ,IAAYC,GAAQ,KACzB,CAACN,EAAqB,IAAIK,CAAG,CACtC,CAgEA,SAAgBE,EAAmB,EAAkD,CACnF,GAAM,CAAE,MAAK,OAAM,WAAU,oBAAmB,UAAS,YAAW,UAAS,UAAWC,EAOlFC,EAAgBlB,EAAM,OAAO,EAAK,EAElCmB,EAAgBlB,EAAAA,iBAAkB,GAAmB,CACzD,EAAc,QAAUmB,CAC1B,CAAC,EAEKC,EAAiBpB,EAAAA,qBAAuB,CAC5C,IAAMmB,EAAQF,EAAc,QAE5B,MADA,GAAc,QAAU,GACjBE,CACT,CAAC,EAEKE,EAAaT,EAAqBC,EAAKC,CAAI,EAC3CQ,EAAqBT,IAAQ,MAAQJ,EAAyB,IAAII,CAAG,EAErEU,EAAoC,CAAC,EACrCC,EAAoC,CAAC,EACvCC,EAAcC,EACdC,EAAgBC,EAChBC,EAAcC,EACdC,EAAaC,EAEbnB,IAAQ,WAAU,EAAS,KAAO,UAClCQ,IACF,EAAS,KAAO,SAChB,EAAS,SAAW,GAGtB,IAAMY,EAAmBC,GAAsBC,GAAY,CAACb,EACxDY,GACF,OAAO,OAAOV,EAAUvB,EAAAA,uBAAuB,GAAM,CAAE,UAAW,EAAK,CAAC,CAAC,EACrEY,IAAQ,MAEV,EAAS,OAAS,OAClB,EAAS,SAAW,EACpB,EAAS,KAAO,IAAA,KAETsB,GAAYb,GACrB,EAAS,SAAW,GACpB,EAAS,iBAAmB,IACnBa,IAELtB,IAAQ,MAEV,EAAS,OAAS,OAClB,EAAS,KAAO,IAAA,IAElB,OAAO,OAAOW,EAAUvB,EAAAA,uBAAuB,EAAI,CAAC,EACpD,EAAS,SAAW,IAGlBgC,GAEF,EAAe,GAAU,CACvBG,EAAM,eAAe,EACrBA,EAAM,gBAAgB,CACxB,EACA,EAAiB,GAAU,CACzB,GAAI1B,EAAgB0B,EAAM,GAAG,EAAG,CAC9BlB,EAAc,EAAK,EACnBkB,EAAM,eAAe,EACrB,MACF,CACAR,IAAYQ,CAAK,CACnB,EAGA,EAAe,GAAU,CACvB,GAAIA,EAAM,MAAQ,KAAQA,EAAM,MAAQ,SAAW,CAACF,EAAoB,CACtEhB,EAAc,EAAK,EACnBkB,EAAM,eAAe,EACrB,MACF,CACAN,IAAUM,CAAK,CACjB,GACSf,IAGT,EAAgBnB,EAAAA,qBAAqB0B,EAAY,GAA4C,CACvFQ,EAAM,SAAWA,EAAM,eAAkB1B,EAAgB0B,EAAM,GAAG,IACtEA,EAAM,eAAe,EACjBA,EAAM,MAAQ,QAASA,EAAM,cAAc,MAAM,EAChDlB,EAAc,EAAI,EACzB,CAAC,EACD,EAAe,GAAU,CACvBY,IAAUM,CAAK,EACXA,EAAM,MAAQ,KACJhB,EACT,GAAS,GAAM,kBAAoBgB,EAAM,SAAWA,EAAM,gBAC/DA,EAAM,eAAe,EACrBA,EAAM,cAAc,MAAM,EAC5B,EAEA,EAAalC,EAAAA,qBAAqB8B,MAAcd,EAAc,EAAK,EAAG,CACpE,sBAAuB,EACzB,CAAC,GAGH,IAAMmB,EAAwC,CAAC,EAM/C,OALIZ,IAAa,EAAS,QAAUA,GAChCE,IAAe,EAAS,UAAYA,GACpCE,IAAa,EAAS,QAAUA,GAChCE,IAAY,EAAS,OAASA,GAE3B,CAAE,WAAU,WAAU,UAAS,CACxC"}
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { composeEventHandlers as e } from "../../lib/composeEventHandlers.mjs";
3
+ import { useEventCallback as t } from "../../hooks/useEventCallback.mjs";
4
+ import { focusableDisabledProps as n } from "../../lib/aria.mjs";
5
+ import * as r from "react";
6
+ //#region src/components/button/Button.semantics.ts
7
+ var i = /* @__PURE__ */ new Set([
8
+ "a",
9
+ "button",
10
+ "input",
11
+ "select",
12
+ "textarea",
13
+ "summary"
14
+ ]), a = /* @__PURE__ */ new Set([
15
+ "button",
16
+ "input",
17
+ "select",
18
+ "textarea"
19
+ ]), o = (e) => e === "Enter" || e === " ";
20
+ function s(e, t) {
21
+ return e === null ? !1 : e === "a" ? t == null : !i.has(e);
22
+ }
23
+ function c(i) {
24
+ let { tag: c, href: l, disabled: u, disabledFocusable: d, onClick: f, onKeyDown: p, onKeyUp: m, onBlur: h } = i, g = r.useRef(!1), _ = t((e) => {
25
+ g.current = e;
26
+ }), v = t(() => {
27
+ let e = g.current;
28
+ return g.current = !1, e;
29
+ }), y = s(c, l), b = c !== null && a.has(c), x = {}, S = {}, C = f, w = p, T = m, E = h;
30
+ c === "button" && (x.type = "button"), y && (x.role = "button", x.tabIndex = 0);
31
+ let D = d || u && !b;
32
+ d ? (Object.assign(S, n(!0, { reachable: !0 })), c === "a" && (x.role ??= "link", x.tabIndex = 0, S.href = void 0)) : u && b ? (S.disabled = !0, S["data-disabled"] = "") : u && (c === "a" && (x.role ??= "link", S.href = void 0), Object.assign(S, n(!0)), S.tabIndex = -1), D ? (C = (e) => {
33
+ e.preventDefault(), e.stopPropagation();
34
+ }, w = (e) => {
35
+ if (o(e.key)) {
36
+ _(!1), e.preventDefault();
37
+ return;
38
+ }
39
+ p?.(e);
40
+ }, T = (e) => {
41
+ if (e.key === " " || e.key === "Enter" && !d) {
42
+ _(!1), e.preventDefault();
43
+ return;
44
+ }
45
+ m?.(e);
46
+ }) : y && (w = e(p, (e) => {
47
+ e.target === e.currentTarget && o(e.key) && (e.preventDefault(), e.key === "Enter" ? e.currentTarget.click() : _(!0));
48
+ }), T = (e) => {
49
+ m?.(e), e.key === " " && v() && !e.defaultPrevented && e.target === e.currentTarget && (e.preventDefault(), e.currentTarget.click());
50
+ }, E = e(h, () => _(!1), { checkDefaultPrevented: !1 }));
51
+ let O = {};
52
+ return C && (O.onClick = C), w && (O.onKeyDown = w), T && (O.onKeyUp = T), E && (O.onBlur = E), {
53
+ defaults: x,
54
+ enforced: S,
55
+ handlers: O
56
+ };
57
+ }
58
+ //#endregion
59
+ export { a as NATIVE_DISABLED_ELEMENTS, s as needsButtonSemantics, c as useButtonSemantics };
60
+
61
+ //# sourceMappingURL=Button.semantics.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.semantics.mjs","names":["React","INTERACTIVE_ELEMENTS","NATIVE_DISABLED_ELEMENTS","isActivationKey","key","needsButtonSemantics","tag","href","useButtonSemantics","options","spaceArmedRef","setSpaceArmed","useEventCallback","armed","takeSpaceArmed","buttonLike","usesNativeDisabled","defaults","enforced","handleClick","onClick","handleKeyDown","onKeyDown","handleKeyUp","onKeyUp","handleBlur","onBlur","blocksActivation","disabledFocusable","disabled","focusableDisabledProps","event","composeEventHandlers","handlers"],"sources":["../../../src/components/button/Button.semantics.ts"],"sourcesContent":["/**\n * Activation semantics shared by `Button` and `Link`: which element needs button semantics, the\n * defaults and enforced attributes of each tag and disabled state, and the handlers that add or\n * block activation. Internal to `src/components/button/` (not exported from the package).\n */\nimport * as React from 'react';\nimport { focusableDisabledProps } from '../../lib/aria';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { useEventCallback } from '../../hooks/useEventCallback';\n\n/** Intrinsic elements that are interactive on their own: no `role=\"button\"` or tab stop added. */\nconst INTERACTIVE_ELEMENTS: ReadonlySet<string> = new Set([\n 'a',\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'summary',\n]);\n\n/** Intrinsic elements whose native `disabled` attribute makes them unavailable. */\nexport const NATIVE_DISABLED_ELEMENTS: ReadonlySet<string> = new Set([\n 'button',\n 'input',\n 'select',\n 'textarea',\n]);\n\nconst isActivationKey = (key: string) => key === 'Enter' || key === ' ';\n\n/**\n * Whether an intrinsic element needs button semantics: not interactive by itself, or an `<a>`\n * whose `href` is `undefined` or `null` (any string, `''` included, keeps it a link). `tag` is\n * `null` for a custom component, which never gets them.\n */\nexport function needsButtonSemantics(tag: string | null, href: unknown): boolean {\n if (tag === null) return false;\n if (tag === 'a') return href == null;\n return !INTERACTIVE_ELEMENTS.has(tag);\n}\n\n/** Options of {@link useButtonSemantics}. */\nexport interface ButtonSemanticsOptions {\n /**\n * The rendered intrinsic tag, or `null` for a custom `as` component (no role, tab stop or key\n * handling is added to it; the disabled attributes and handlers are).\n */\n tag: string | null;\n /** The consumer's `href` (decides link or button semantics for an `<a>`). */\n href: unknown;\n /** Makes the element unavailable: natively for form controls, with `aria-disabled` otherwise. */\n disabled: boolean;\n /** Unavailable but focusable and in the tab order. Wins over `disabled`. */\n disabledFocusable: boolean;\n /** The consumer's handlers; the returned handlers compose or replace them. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n onBlur?: React.FocusEventHandler<HTMLElement>;\n}\n\n/** The result of {@link useButtonSemantics}. */\nexport interface ButtonSemantics {\n /**\n * Defaults the consumer may override (C-COMPOSE: `type`, `role`, `tabIndex`). Apply each one\n * wherever the consumer's value is `undefined` or `null`, so a wrapper that forwards\n * `type={type}` never drops `type=\"button\"`, the role or the tab stop.\n */\n defaults: Record<string, unknown>;\n /**\n * Attributes the consumer must not override: spread after `{...rest}` (`disabled`,\n * `aria-disabled`, `data-disabled`, `data-disabled-focusable`, `href: undefined`, `tabIndex: -1`\n * for a disabled non-native element).\n */\n enforced: Record<string, unknown>;\n /** Only the handlers that exist, so a custom `as` component keeps its own defaults. */\n handlers: {\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n onBlur?: React.FocusEventHandler<HTMLElement>;\n };\n}\n\n/**\n * Defaults, enforced attributes and composed handlers for Button and Link.\n *\n * - An intrinsic element that is not interactive by itself (`div`, `span`) and an `<a>` without\n * `href` get `role=\"button\"` and `tabIndex={0}` as defaults; Enter activates on keydown, Space\n * arms on keydown (preventing page scroll) and activates on the following keyup, and moving\n * focus in between cancels it (native button behaviour). A native `<button>` defaults to\n * `type=\"button\"`.\n * - `disabled` on a form control (`button`, `input`, `select`, `textarea`): the native attribute.\n * On any other element: `aria-disabled` and `tabIndex={-1}`; an `<a>` drops its `href` and keeps\n * `role=\"link\"` when it had one (`role=\"button\"` without).\n * - `disabledFocusable` (wins over `disabled`), for every element: `aria-disabled`,\n * `data-disabled-focusable` and no native `disabled`; the element stays in the tab order (an\n * `<a>` drops its `href` and gets `tabIndex={0}` as a default).\n * - Every disabled state renders `data-disabled`. While disabled without the native attribute, a\n * click is prevented and stopped (a natively disabled button dispatches no click to ancestors),\n * Enter and Space are prevented and not forwarded, and other keys reach the consumer. Under\n * `disabledFocusable` the Enter keyup (which activates nothing) reaches the consumer too.\n */\nexport function useButtonSemantics(options: ButtonSemanticsOptions): ButtonSemantics {\n const { tag, href, disabled, disabledFocusable, onClick, onKeyDown, onKeyUp, onBlur } = options;\n\n /**\n * Set by an unprevented Space keydown on the element itself; Space activates on keyup only while\n * it is set (like a native button: a keyup alone never clicks). Cleared on keyup and blur. The\n * ref is only touched from event handlers, through these two stable callbacks (C-HOOKS).\n */\n const spaceArmedRef = React.useRef(false);\n /** Arms (or disarms) Space activation. */\n const setSpaceArmed = useEventCallback((armed: boolean) => {\n spaceArmedRef.current = armed;\n });\n /** Reads and clears the Space arm. */\n const takeSpaceArmed = useEventCallback(() => {\n const armed = spaceArmedRef.current;\n spaceArmedRef.current = false;\n return armed;\n });\n\n const buttonLike = needsButtonSemantics(tag, href);\n const usesNativeDisabled = tag !== null && NATIVE_DISABLED_ELEMENTS.has(tag);\n\n const defaults: Record<string, unknown> = {};\n const enforced: Record<string, unknown> = {};\n let handleClick = onClick;\n let handleKeyDown = onKeyDown;\n let handleKeyUp = onKeyUp;\n let handleBlur = onBlur;\n\n if (tag === 'button') defaults.type = 'button';\n if (buttonLike) {\n defaults.role = 'button';\n defaults.tabIndex = 0;\n }\n\n const blocksActivation = disabledFocusable || (disabled && !usesNativeDisabled);\n if (disabledFocusable) {\n Object.assign(enforced, focusableDisabledProps(true, { reachable: true }));\n if (tag === 'a') {\n // Drop the destination (no middle-click or context-menu navigation) but keep the tab stop.\n defaults.role ??= 'link';\n defaults.tabIndex = 0;\n enforced.href = undefined;\n }\n } else if (disabled && usesNativeDisabled) {\n enforced.disabled = true;\n enforced['data-disabled'] = '';\n } else if (disabled) {\n // Not a form control: `disabled` has no effect, so expose and enforce the state ourselves.\n if (tag === 'a') {\n // Drop the destination but keep the link role when there was one.\n defaults.role ??= 'link';\n enforced.href = undefined;\n }\n Object.assign(enforced, focusableDisabledProps(true));\n enforced.tabIndex = -1;\n }\n\n if (blocksActivation) {\n // A natively disabled button dispatches no click at all, so ancestors never see this one.\n handleClick = (event) => {\n event.preventDefault();\n event.stopPropagation();\n };\n handleKeyDown = (event) => {\n if (isActivationKey(event.key)) {\n setSpaceArmed(false);\n event.preventDefault();\n return;\n }\n onKeyDown?.(event);\n };\n // Space activates on keyup and is blocked. Enter activates on keydown, so a focusable disabled\n // control forwards its keyup like any other key; a disabled non-native element blocks both.\n handleKeyUp = (event) => {\n if (event.key === ' ' || (event.key === 'Enter' && !disabledFocusable)) {\n setSpaceArmed(false);\n event.preventDefault();\n return;\n }\n onKeyUp?.(event);\n };\n } else if (buttonLike) {\n // APG button: Enter activates on keydown; Space arms on keydown (preventing page scroll) and\n // activates on the following keyup. A consumer `preventDefault()` on the keydown cancels both.\n handleKeyDown = composeEventHandlers(onKeyDown, (event: React.KeyboardEvent<HTMLElement>) => {\n if (event.target !== event.currentTarget || !isActivationKey(event.key)) return;\n event.preventDefault();\n if (event.key === 'Enter') event.currentTarget.click();\n else setSpaceArmed(true);\n });\n handleKeyUp = (event) => {\n onKeyUp?.(event);\n if (event.key !== ' ') return;\n const armed = takeSpaceArmed();\n if (!armed || event.defaultPrevented || event.target !== event.currentTarget) return;\n event.preventDefault();\n event.currentTarget.click();\n };\n // Moving focus away between keydown and keyup cancels a Space activation (native behavior).\n handleBlur = composeEventHandlers(onBlur, () => setSpaceArmed(false), {\n checkDefaultPrevented: false,\n });\n }\n\n const handlers: ButtonSemantics['handlers'] = {};\n if (handleClick) handlers.onClick = handleClick;\n if (handleKeyDown) handlers.onKeyDown = handleKeyDown;\n if (handleKeyUp) handlers.onKeyUp = handleKeyUp;\n if (handleBlur) handlers.onBlur = handleBlur;\n\n return { defaults, enforced, handlers };\n}\n"],"mappings":";;;;;;AAWA,IAAMC,oBAA4C,IAAI,IAAI;CACxD;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,GAGYC,oBAAgD,IAAI,IAAI;CACnE;CACA;CACA;CACA;AACF,CAAC,GAEKC,KAAmB,MAAgBC,MAAQ,WAAWA,MAAQ;AAOpE,SAAgBC,EAAqB,GAAoB,GAAwB;CAG/E,OAFIC,MAAQ,OAAa,KACrBA,MAAQ,MAAYC,KAAQ,OACzB,CAACN,EAAqB,IAAIK,CAAG;AACtC;AAgEA,SAAgBE,EAAmB,GAAkD;CACnF,IAAM,EAAE,QAAK,SAAM,aAAU,sBAAmB,YAAS,cAAW,YAAS,cAAWC,GAOlFC,IAAgBV,EAAM,OAAO,EAAK,GAElCW,IAAgBC,GAAkB,MAAmB;EACzD,EAAc,UAAUC;CAC1B,CAAC,GAEKC,IAAiBF,QAAuB;EAC5C,IAAMC,IAAQH,EAAc;EAE5B,OADA,EAAc,UAAU,IACjBG;CACT,CAAC,GAEKE,IAAaV,EAAqBC,GAAKC,CAAI,GAC3CS,IAAqBV,MAAQ,QAAQJ,EAAyB,IAAII,CAAG,GAErEW,IAAoC,CAAC,GACrCC,IAAoC,CAAC,GACvCC,IAAcC,GACdC,IAAgBC,GAChBC,IAAcC,GACdC,IAAaC;CAGjB,AADIpB,MAAQ,aAAU,EAAS,OAAO,WAClCS,MACF,EAAS,OAAO,UAChB,EAAS,WAAW;CAGtB,IAAMY,IAAmBC,KAAsBC,KAAY,CAACb;CAuB5D,AAtBIY,KACF,OAAO,OAAOV,GAAUY,EAAuB,IAAM,EAAE,WAAW,GAAK,CAAC,CAAC,GACrExB,MAAQ,QAEV,EAAS,SAAS,QAClB,EAAS,WAAW,GACpB,EAAS,OAAO,KAAA,MAETuB,KAAYb,KACrB,EAAS,WAAW,IACpB,EAAS,mBAAmB,MACnBa,MAELvB,MAAQ,QAEV,EAAS,SAAS,QAClB,EAAS,OAAO,KAAA,IAElB,OAAO,OAAOY,GAAUY,EAAuB,EAAI,CAAC,GACpD,EAAS,WAAW,KAGlBH,KAEF,KAAe,MAAU;EAEvB,AADAI,EAAM,eAAe,GACrBA,EAAM,gBAAgB;CACxB,GACA,KAAiB,MAAU;EACzB,IAAI5B,EAAgB4B,EAAM,GAAG,GAAG;GAE9B,AADApB,EAAc,EAAK,GACnBoB,EAAM,eAAe;GACrB;EACF;EACA,IAAYA,CAAK;CACnB,GAGA,KAAe,MAAU;EACvB,IAAIA,EAAM,QAAQ,OAAQA,EAAM,QAAQ,WAAW,CAACH,GAAoB;GAEtE,AADAjB,EAAc,EAAK,GACnBoB,EAAM,eAAe;GACrB;EACF;EACA,IAAUA,CAAK;CACjB,KACShB,MAGT,IAAgBiB,EAAqBV,IAAY,MAA4C;EAC3F,AAAIS,EAAM,WAAWA,EAAM,iBAAkB5B,EAAgB4B,EAAM,GAAG,MACtEA,EAAM,eAAe,GACjBA,EAAM,QAAQ,UAASA,EAAM,cAAc,MAAM,IAChDpB,EAAc,EAAI;CACzB,CAAC,GACD,KAAe,MAAU;EAEvB,AADAa,IAAUO,CAAK,GACXA,EAAM,QAAQ,OACJjB,EACT,KAAS,GAAM,oBAAoBiB,EAAM,WAAWA,EAAM,kBAC/DA,EAAM,eAAe,GACrBA,EAAM,cAAc,MAAM;CAC5B,GAEA,IAAaC,EAAqBN,SAAcf,EAAc,EAAK,GAAG,EACpE,uBAAuB,GACzB,CAAC;CAGH,IAAMsB,IAAwC,CAAC;CAM/C,OALId,MAAa,EAAS,UAAUA,IAChCE,MAAe,EAAS,YAAYA,IACpCE,MAAa,EAAS,UAAUA,IAChCE,MAAY,EAAS,SAASA,IAE3B;EAAE;EAAU;EAAU;CAAS;AACxC"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/children.cjs"),n=require("../../lib/aria.cjs"),r=require("./Button.cjs");let i=require("react");i=e.__toESM(i,1);let a=require("react/jsx-runtime");var o=new Set(Object.keys({as:!0,appearance:!0,size:!0,icon:!0,iconPosition:!0,disabledFocusable:!0}));function s(e,t,n){return n===`after`?(0,a.jsxs)(a.Fragment,{children:[t,e]}):(0,a.jsxs)(a.Fragment,{children:[e,t]})}function c(e){e.preventDefault(),e.stopPropagation()}var l={...n.focusableDisabledProps(!0,{reachable:!0}),disabled:!1,onClick:c},u=`aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100`;function d(e){if(typeof e!=`object`||!e||i.isValidElement(e)||Symbol.iterator in e||!(`as`in e))return!1;let{as:t}=e;return t===`button`||t===r.Button}function f(e){let n=e;return t.isElementOfType(n,`button`,r.Button)?{glyph:n.props.children,button:`a button element`}:d(e)?{glyph:e.children,button:`a slot object that renders a button`}:{glyph:e,button:null}}exports.BUTTON_OWN_PROP_KEYS=o,exports.MERGED_DISABLED_FOCUSABLE_PROPS=l,exports.mergedAriaDisabledClasses=u,exports.placeButtonIcon=s,exports.unwrapButtonGlyph=f;
2
+ //# sourceMappingURL=Button.slots.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.slots.cjs","names":["_Fragment","focusableDisabledProps","React","Button","isElementOfType","require_runtime","require_children","require_aria","require_Button","react","react_jsx_runtime","BUTTON_OWN_PROP_KEYS","placeButtonIcon","iconPosition","content","icon","blockClick","event","MERGED_DISABLED_FOCUSABLE_PROPS","mergedAriaDisabledClasses","isButtonSlotObject","value","as","unwrapButtonGlyph","node","slot"],"sources":["../../../src/components/button/Button.slots.tsx"],"sourcesContent":["/**\n * How the slots of other components treat a `<button>` or Wave `Button` passed to them (C-SLOTS).\n * Internal (not exported from the package).\n *\n * - Dismiss and clear slots (MessageBar `dismiss`, SearchBox `dismiss`, Tag `dismissIcon`) merge\n * it into their own wired `<button>`. {@link BUTTON_OWN_PROP_KEYS} lists the Button props that\n * must not reach that element; {@link placeButtonIcon} and {@link MERGED_DISABLED_FOCUSABLE_PROPS}\n * give it what the Button would have done with `icon`, `iconPosition` and `disabledFocusable`.\n * - Glyph slots inside a wired button (SplitButton and MenuButton `menuIcon`, Combobox and\n * TimePicker `expandIcon`) unwrap it: {@link unwrapButtonGlyph}.\n */\nimport * as React from 'react';\nimport { focusableDisabledProps } from '../../lib/aria';\nimport { isElementOfType } from '../../lib/children';\nimport type { Slot } from '../../lib/slot';\nimport { Button } from './Button';\nimport type { ButtonOwnProps } from './Button';\n\n/**\n * The keys of {@link BUTTON_OWN_PROP_KEYS}, checked against `ButtonOwnProps`: a new own prop of\n * `Button` does not compile until it is listed here, so it cannot leak onto a wired button.\n */\nconst buttonOwnPropKeys = {\n as: true,\n appearance: true,\n size: true,\n icon: true,\n iconPosition: true,\n disabledFocusable: true,\n} satisfies Record<Exclude<keyof ButtonOwnProps, 'disabled'> | 'as', true>;\n\n/**\n * The props of a Wave `Button` that are not DOM attributes: `as` and every own prop except\n * `disabled` (a native attribute, merged as one). A component that merges a `Button` into its own\n * `<button>` never spreads these onto it; it applies `icon`, `iconPosition` and\n * `disabledFocusable` itself.\n */\nexport const BUTTON_OWN_PROP_KEYS: ReadonlySet<string> = new Set(Object.keys(buttonOwnPropKeys));\n\n/**\n * The content of a wired button that merged a Wave `Button`: the Button's decorative icon before\n * its content, or after it for `iconPosition=\"after\"`, as `Button` renders it (DOM order, so it\n * follows the writing direction).\n *\n * @param icon The rendered icon (`aria-hidden`), or `null`.\n * @param content The Button's content.\n * @param iconPosition The Button's `iconPosition` (anything but `'after'` means before).\n */\nexport function placeButtonIcon(\n icon: React.ReactNode,\n content: React.ReactNode,\n iconPosition: unknown,\n): React.ReactElement {\n return iconPosition === 'after' ? (\n <>\n {content}\n {icon}\n </>\n ) : (\n <>\n {icon}\n {content}\n </>\n );\n}\n\n/** Prevents a click and stops it, as a natively disabled button dispatches none to ancestors. */\nfunction blockClick(event: React.MouseEvent<HTMLElement>) {\n event.preventDefault();\n event.stopPropagation();\n}\n\n/**\n * Spread last on a wired button that merged a Wave `Button` with `disabledFocusable`, so it\n * behaves as that Button would: `aria-disabled`, `data-disabled` and `data-disabled-focusable`\n * instead of the native `disabled` (overridden: `disabledFocusable` wins over `disabled`), so it\n * keeps its tab stop; its click is prevented and stopped, so neither the merged `onClick` nor the\n * component's own action runs and no ancestor click handler sees it. A native `<button>` also\n * activates through a click for Enter, Space and implicit form submission, so those are blocked\n * too.\n */\nexport const MERGED_DISABLED_FOCUSABLE_PROPS = {\n ...focusableDisabledProps(true, { reachable: true }),\n disabled: false,\n onClick: blockClick,\n};\n\n/**\n * The disabled look of a wired dismiss or clear button while `aria-disabled` (a merged\n * `disabledFocusable`, or a consumer `aria-disabled`): dimmed like a disabled button, except while\n * it shows its focus ring, which `opacity` would dim too.\n */\nexport const mergedAriaDisabledClasses =\n 'aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100';\n\n/** What {@link unwrapButtonGlyph} unwrapped, for the slot's development warning. */\nexport type UnwrappedButton = 'a button element' | 'a slot object that renders a button';\n\n/** Whether `value` is a slot object (`{ as, children, … }`) that renders a `<button>` or `Button`. */\nfunction isButtonSlotObject(value: unknown): value is { children?: React.ReactNode } {\n if (typeof value !== 'object' || value === null || React.isValidElement(value)) return false;\n if (Symbol.iterator in value || !('as' in value)) return false;\n const { as } = value as { as?: unknown };\n return as === 'button' || as === Button;\n}\n\n/**\n * A glyph slot's value with a button unwrapped. A glyph inside a wired button is decorative and a\n * button cannot contain a button (C-SLOTS), so for a `<button>` or `Button` element, or a slot\n * object whose `as` is `'button'` or `Button`, the glyph is its `children` and its props are\n * dropped; any other value is the glyph as given. `button` says what was unwrapped (`null`:\n * nothing), so the component can warn once from an effect. A `Button` written in a Server\n * Component (a lazy client reference) is unwrapped too.\n *\n * @example\n * const { glyph, button } = unwrapButtonGlyph(menuIcon);\n */\nexport function unwrapButtonGlyph(slot: Slot<'span'> | undefined): {\n glyph: Slot<'span'> | undefined;\n button: UnwrappedButton | null;\n} {\n // A slot object is never an element, so any slot value can be checked as a node.\n const node = slot as React.ReactNode;\n if (isElementOfType<{ children?: React.ReactNode }>(node, 'button', Button)) {\n return { glyph: node.props.children, button: 'a button element' };\n }\n if (isButtonSlotObject(slot)) {\n return { glyph: slot.children, button: 'a slot object that renders a button' };\n }\n return { glyph: slot, button: null };\n}\n"],"mappings":"8OAqCA,IAAaW,EAA4C,IAAI,IAAI,OAAO,KAAK,CAd3E,GAAI,GACJ,WAAY,GACZ,KAAM,GACN,KAAM,GACN,aAAc,GACd,kBAAmB,EASwD,CAAiB,CAAC,EAW/F,SAAgBC,EACd,EACA,EACA,EACoB,CACpB,OAAOC,IAAiB,SACtB,EAAAH,EAAA,KAAA,CAAAV,EAAAA,SAAA,CAAA,SAAA,CACGc,EACAC,CACD,CAAA,CAAA,GAEF,EAAAL,EAAA,KAAA,CAAAV,EAAAA,SAAA,CAAA,SAAA,CACGe,EACAD,CACD,CAAA,CAAA,CAEN,CAGA,SAASE,EAAW,EAAsC,CACxDC,EAAM,eAAe,EACrBA,EAAM,gBAAgB,CACxB,CAWA,IAAaC,EAAkC,CAC7C,GAAGjB,EAAAA,uBAAuB,GAAM,CAAE,UAAW,EAAK,CAAC,EACnD,SAAU,GACV,QAASe,CACX,EAOaG,EACX,oGAMF,SAASC,EAAmB,EAAyD,CAEnF,GADI,OAAOC,GAAU,WAAYA,GAAkBnB,EAAM,eAAemB,CAAK,GACzE,OAAO,YAAYA,GAAS,EAAE,OAAQA,GAAQ,MAAO,GACzD,GAAM,CAAE,MAAOA,EACf,OAAOC,IAAO,UAAYA,IAAOnB,EAAAA,MACnC,CAaA,SAAgBoB,EAAkB,EAGhC,CAEA,IAAMC,EAAOC,EAOb,OANIrB,EAAAA,gBAAgDoB,EAAM,SAAUrB,EAAAA,MAAM,EACjE,CAAE,MAAOqB,EAAK,MAAM,SAAU,OAAQ,kBAAmB,EAE9DJ,EAAmBK,CAAI,EAClB,CAAE,MAAOA,EAAK,SAAU,OAAQ,qCAAsC,EAExE,CAAE,MAAOA,EAAM,OAAQ,IAAK,CACrC"}
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { isElementOfType as e } from "../../lib/children.mjs";
3
+ import { focusableDisabledProps as t } from "../../lib/aria.mjs";
4
+ import { Button as n } from "./Button.mjs";
5
+ import * as r from "react";
6
+ import { Fragment as i, jsxs as a } from "react/jsx-runtime";
7
+ var o = new Set(Object.keys({
8
+ as: !0,
9
+ appearance: !0,
10
+ size: !0,
11
+ icon: !0,
12
+ iconPosition: !0,
13
+ disabledFocusable: !0
14
+ }));
15
+ function s(e, t, n) {
16
+ return n === "after" ? /* @__PURE__ */ a(i, { children: [t, e] }) : /* @__PURE__ */ a(i, { children: [e, t] });
17
+ }
18
+ function c(e) {
19
+ e.preventDefault(), e.stopPropagation();
20
+ }
21
+ var l = {
22
+ ...t(!0, { reachable: !0 }),
23
+ disabled: !1,
24
+ onClick: c
25
+ }, u = "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100";
26
+ function d(e) {
27
+ if (typeof e != "object" || !e || r.isValidElement(e) || Symbol.iterator in e || !("as" in e)) return !1;
28
+ let { as: t } = e;
29
+ return t === "button" || t === n;
30
+ }
31
+ function f(t) {
32
+ let r = t;
33
+ return e(r, "button", n) ? {
34
+ glyph: r.props.children,
35
+ button: "a button element"
36
+ } : d(t) ? {
37
+ glyph: t.children,
38
+ button: "a slot object that renders a button"
39
+ } : {
40
+ glyph: t,
41
+ button: null
42
+ };
43
+ }
44
+ //#endregion
45
+ export { o as BUTTON_OWN_PROP_KEYS, l as MERGED_DISABLED_FOCUSABLE_PROPS, u as mergedAriaDisabledClasses, s as placeButtonIcon, f as unwrapButtonGlyph };
46
+
47
+ //# sourceMappingURL=Button.slots.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.slots.mjs","names":["_Fragment","React","BUTTON_OWN_PROP_KEYS","placeButtonIcon","iconPosition","Fragment","content","icon","blockClick","event","MERGED_DISABLED_FOCUSABLE_PROPS","focusableDisabledProps","mergedAriaDisabledClasses","isButtonSlotObject","value","as","Button","unwrapButtonGlyph","node","slot","isElementOfType"],"sources":["../../../src/components/button/Button.slots.tsx"],"sourcesContent":["/**\n * How the slots of other components treat a `<button>` or Wave `Button` passed to them (C-SLOTS).\n * Internal (not exported from the package).\n *\n * - Dismiss and clear slots (MessageBar `dismiss`, SearchBox `dismiss`, Tag `dismissIcon`) merge\n * it into their own wired `<button>`. {@link BUTTON_OWN_PROP_KEYS} lists the Button props that\n * must not reach that element; {@link placeButtonIcon} and {@link MERGED_DISABLED_FOCUSABLE_PROPS}\n * give it what the Button would have done with `icon`, `iconPosition` and `disabledFocusable`.\n * - Glyph slots inside a wired button (SplitButton and MenuButton `menuIcon`, Combobox and\n * TimePicker `expandIcon`) unwrap it: {@link unwrapButtonGlyph}.\n */\nimport * as React from 'react';\nimport { focusableDisabledProps } from '../../lib/aria';\nimport { isElementOfType } from '../../lib/children';\nimport type { Slot } from '../../lib/slot';\nimport { Button } from './Button';\nimport type { ButtonOwnProps } from './Button';\n\n/**\n * The keys of {@link BUTTON_OWN_PROP_KEYS}, checked against `ButtonOwnProps`: a new own prop of\n * `Button` does not compile until it is listed here, so it cannot leak onto a wired button.\n */\nconst buttonOwnPropKeys = {\n as: true,\n appearance: true,\n size: true,\n icon: true,\n iconPosition: true,\n disabledFocusable: true,\n} satisfies Record<Exclude<keyof ButtonOwnProps, 'disabled'> | 'as', true>;\n\n/**\n * The props of a Wave `Button` that are not DOM attributes: `as` and every own prop except\n * `disabled` (a native attribute, merged as one). A component that merges a `Button` into its own\n * `<button>` never spreads these onto it; it applies `icon`, `iconPosition` and\n * `disabledFocusable` itself.\n */\nexport const BUTTON_OWN_PROP_KEYS: ReadonlySet<string> = new Set(Object.keys(buttonOwnPropKeys));\n\n/**\n * The content of a wired button that merged a Wave `Button`: the Button's decorative icon before\n * its content, or after it for `iconPosition=\"after\"`, as `Button` renders it (DOM order, so it\n * follows the writing direction).\n *\n * @param icon The rendered icon (`aria-hidden`), or `null`.\n * @param content The Button's content.\n * @param iconPosition The Button's `iconPosition` (anything but `'after'` means before).\n */\nexport function placeButtonIcon(\n icon: React.ReactNode,\n content: React.ReactNode,\n iconPosition: unknown,\n): React.ReactElement {\n return iconPosition === 'after' ? (\n <>\n {content}\n {icon}\n </>\n ) : (\n <>\n {icon}\n {content}\n </>\n );\n}\n\n/** Prevents a click and stops it, as a natively disabled button dispatches none to ancestors. */\nfunction blockClick(event: React.MouseEvent<HTMLElement>) {\n event.preventDefault();\n event.stopPropagation();\n}\n\n/**\n * Spread last on a wired button that merged a Wave `Button` with `disabledFocusable`, so it\n * behaves as that Button would: `aria-disabled`, `data-disabled` and `data-disabled-focusable`\n * instead of the native `disabled` (overridden: `disabledFocusable` wins over `disabled`), so it\n * keeps its tab stop; its click is prevented and stopped, so neither the merged `onClick` nor the\n * component's own action runs and no ancestor click handler sees it. A native `<button>` also\n * activates through a click for Enter, Space and implicit form submission, so those are blocked\n * too.\n */\nexport const MERGED_DISABLED_FOCUSABLE_PROPS = {\n ...focusableDisabledProps(true, { reachable: true }),\n disabled: false,\n onClick: blockClick,\n};\n\n/**\n * The disabled look of a wired dismiss or clear button while `aria-disabled` (a merged\n * `disabledFocusable`, or a consumer `aria-disabled`): dimmed like a disabled button, except while\n * it shows its focus ring, which `opacity` would dim too.\n */\nexport const mergedAriaDisabledClasses =\n 'aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100';\n\n/** What {@link unwrapButtonGlyph} unwrapped, for the slot's development warning. */\nexport type UnwrappedButton = 'a button element' | 'a slot object that renders a button';\n\n/** Whether `value` is a slot object (`{ as, children, … }`) that renders a `<button>` or `Button`. */\nfunction isButtonSlotObject(value: unknown): value is { children?: React.ReactNode } {\n if (typeof value !== 'object' || value === null || React.isValidElement(value)) return false;\n if (Symbol.iterator in value || !('as' in value)) return false;\n const { as } = value as { as?: unknown };\n return as === 'button' || as === Button;\n}\n\n/**\n * A glyph slot's value with a button unwrapped. A glyph inside a wired button is decorative and a\n * button cannot contain a button (C-SLOTS), so for a `<button>` or `Button` element, or a slot\n * object whose `as` is `'button'` or `Button`, the glyph is its `children` and its props are\n * dropped; any other value is the glyph as given. `button` says what was unwrapped (`null`:\n * nothing), so the component can warn once from an effect. A `Button` written in a Server\n * Component (a lazy client reference) is unwrapped too.\n *\n * @example\n * const { glyph, button } = unwrapButtonGlyph(menuIcon);\n */\nexport function unwrapButtonGlyph(slot: Slot<'span'> | undefined): {\n glyph: Slot<'span'> | undefined;\n button: UnwrappedButton | null;\n} {\n // A slot object is never an element, so any slot value can be checked as a node.\n const node = slot as React.ReactNode;\n if (isElementOfType<{ children?: React.ReactNode }>(node, 'button', Button)) {\n return { glyph: node.props.children, button: 'a button element' };\n }\n if (isButtonSlotObject(slot)) {\n return { glyph: slot.children, button: 'a slot object that renders a button' };\n }\n return { glyph: slot, button: null };\n}\n"],"mappings":";;;;;;AAqCA,IAAaE,IAA4C,IAAI,IAAI,OAAO,KAAK;CAd3E,IAAI;CACJ,YAAY;CACZ,MAAM;CACN,MAAM;CACN,cAAc;CACd,mBAAmB;AASwD,CAAiB,CAAC;AAW/F,SAAgBC,EACd,GACA,GACA,GACoB;CACpB,OAAOC,MAAiB,UACtB,kBAAAJ,GAAA,EAAA,UAAA,CACGM,GACAC,CACD,EAAA,CAAA,IAEF,kBAAAP,GAAA,EAAA,UAAA,CACGO,GACAD,CACD,EAAA,CAAA;AAEN;AAGA,SAASE,EAAW,GAAsC;CAExD,AADAC,EAAM,eAAe,GACrBA,EAAM,gBAAgB;AACxB;AAWA,IAAaC,IAAkC;CAC7C,GAAGC,EAAuB,IAAM,EAAE,WAAW,GAAK,CAAC;CACnD,UAAU;CACV,SAASH;AACX,GAOaI,IACX;AAMF,SAASC,EAAmB,GAAyD;CAEnF,IADI,OAAOC,KAAU,aAAYA,KAAkBb,EAAM,eAAea,CAAK,KACzE,OAAO,YAAYA,KAAS,EAAE,QAAQA,IAAQ,OAAO;CACzD,IAAM,EAAE,UAAOA;CACf,OAAOC,MAAO,YAAYA,MAAOC;AACnC;AAaA,SAAgBC,EAAkB,GAGhC;CAEA,IAAMC,IAAOC;CAOb,OANIC,EAAgDF,GAAM,UAAUF,CAAM,IACjE;EAAE,OAAOE,EAAK,MAAM;EAAU,QAAQ;CAAmB,IAE9DL,EAAmBM,CAAI,IAClB;EAAE,OAAOA,EAAK;EAAU,QAAQ;CAAsC,IAExE;EAAE,OAAOA;EAAM,QAAQ;CAAK;AACrC"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/slot.cjs"),r=require("./Button.cjs");let i=require("react");i=e.__toESM(i,1);let a=require("react/jsx-runtime");var o={"extra-small":`py-0.5`,small:`py-1`,medium:`py-2`,large:`py-3`,"extra-large":`py-4`},s={"extra-small":`size-6`,small:`size-8`,medium:`size-10`,large:`size-10`,"extra-large":`size-10`},c=r.Button,l=e=>{let{secondaryText:r,appearance:i=`outline`,size:l=`medium`,icon:u,iconPosition:d=`before`,className:f,children:p,...m}=e,h=n.materialiseSlotContent(p),g=n.materialiseSlotContent(r),_=n.slotRendersContent(g);if(!n.slotRendersContent(h)&&!_)return(0,a.jsx)(c,{...m,appearance:i,size:l,icon:u,iconPosition:d,className:f});let v=n.renderSlot(n.slotRendersContent(u)?u:void 0,`span`,t.cn(`inline-flex shrink-0 items-center justify-center [&>svg]:size-full`,s[l]),{"aria-hidden":!0}),y=(0,a.jsxs)(`span`,{"data-wave-compound-content":``,className:`flex min-w-0 flex-col items-start`,children:[(0,a.jsx)(`span`,{className:`font-bold`,children:h}),_&&(0,a.jsx)(`span`,{className:t.cn(`text-caption-1 font-normal`,i===`primary`?`text-primary-foreground`:`text-muted-foreground`),children:g})]});return(0,a.jsx)(c,{...m,appearance:i,size:l,className:t.cn(`h-auto items-center justify-start gap-3 text-start`,o[l],f),children:d===`after`?(0,a.jsxs)(a.Fragment,{children:[y,v]}):(0,a.jsxs)(a.Fragment,{children:[v,y]})})};l.displayName=`CompoundButton`,exports.CompoundButton=l;
2
+ //# sourceMappingURL=CompoundButton.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompoundButton.cjs","names":["Button","materialiseSlotContent","slotRendersContent","renderSlot","cn","_Fragment","require_runtime","require_cn","require_slot","require_Button","react","react_jsx_runtime","paddingClasses","iconBoxClasses","BaseButton","CompoundButton","rest","props","label","children","secondary","secondaryText","hasSecondary","iconElement","icon","size","content","appearance","className","iconPosition"],"sources":["../../../src/components/button/CompoundButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\n\n/**\n * The CompoundButton's own props (the XOwnProps rule of `PolymorphicProps`: component-specific\n * props only). Every other prop comes from the rendered element (`as`).\n */\nexport interface CompoundButtonOwnProps {\n /**\n * Secondary descriptive text displayed below the main label (part of the accessible name).\n * Content that renders nothing (`''`, `[]`, `<></>`) renders no second line.\n */\n secondaryText?: React.ReactNode;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Disables the button. As with {@link Button}: a native `disabled` attribute for form controls\n * (the default `button`); every other `as` gets `aria-disabled=\"true\"` and `tabIndex={-1}`, its\n * activation is prevented and an `<a>` drops its `href`.\n * @default false\n */\n disabled?: boolean;\n /**\n * Marks the button unavailable but keeps it focusable and in the tab order (for a Tooltip\n * that explains why, or a toolbar). Renders `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable` instead of the native `disabled` attribute; clicks, Enter, Space\n * and implicit form submission are prevented, and your `onClick` is not called. Wins over\n * `disabled` when both are set. In a `Toolbar` it stays in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Icon shown beside the two lines of text, in a 40px box (32px at `small`, 24px at\n * `extra-small`) whose SVG fills it. Decorative (`aria-hidden`). A CompoundButton with only an\n * icon (no label, no `secondaryText`) is an icon-only button: it looks and is checked like an\n * icon-only `Button` and needs `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the icon renders: before the text column (the inline start) or after it (the inline\n * end). Follows the writing direction through DOM order. Has no effect without an icon or on\n * an icon-only button.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n}\n\n/**\n * Props of {@link CompoundButton} rendered as `C` (default `'button'`). `CompoundButtonProps`\n * without a type argument is the 0.4 name: the props of a CompoundButton rendered as a\n * `<button>`, including `ref`.\n */\nexport type CompoundButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n CompoundButtonOwnProps\n>;\n\n/**\n * Vertical padding per size. The height is content-sized (`h-auto` replaces Button's fixed\n * height); horizontal padding and font size come from Button.\n */\nconst paddingClasses: Record<Size, string> = {\n 'extra-small': 'py-0.5',\n small: 'py-1',\n medium: 'py-2',\n large: 'py-3',\n 'extra-large': 'py-4',\n};\n\n/** The icon box per size (its SVG fills it): 24px at extra-small, 32px at small, else 40px. */\nconst iconBoxClasses: Record<Size, string> = {\n 'extra-small': 'size-6',\n small: 'size-8',\n medium: 'size-10',\n large: 'size-10',\n 'extra-large': 'size-10',\n};\n\n/** The props the implementation reads, for any `as`. */\ntype CompoundButtonImplProps = CompoundButtonOwnProps & {\n as?: React.ElementType;\n className?: string;\n children?: React.ReactNode;\n};\n\n/** `Button` widened to any element props, so `as` and the rest props pass through untyped. */\nconst BaseButton = Button as React.ElementType;\n\n/**\n * A button with a main label and a secondary line of text below it, and an optional icon beside\n * them. Built on {@link Button}: same appearances, sizes, token colors, `type=\"button\"` default,\n * `disabled`/`disabledFocusable` and polymorphic `as` behaviour (`as=\"a\"` renders a link; a\n * non-interactive `as` gets `role=\"button\"`, a tab stop and Enter/Space activation; `disabled`\n * becomes `aria-disabled` on non-form-control elements).\n *\n * - The text lines sit in a column wrapper (`span[data-wave-compound-content]`); the icon renders\n * before or after it (`iconPosition`).\n * - With only an icon (no label and no `secondaryText`) it is an icon-only `Button`: square, with\n * the icon-only sizing and name check.\n *\n * @example\n * <CompoundButton secondaryText=\"Opens your email client\">Send mail</CompoundButton>\n * <CompoundButton icon={<CalendarIcon />} secondaryText=\"Next Monday at 9:00\">\n * Schedule\n * </CompoundButton>\n * <CompoundButton as=\"a\" href=\"/signup\" appearance=\"primary\" secondaryText=\"Free for 30 days\">\n * Create account\n * </CompoundButton>\n */\nexport const CompoundButton: PolymorphicComponent<'button', CompoundButtonOwnProps> = (props) => {\n const {\n secondaryText,\n appearance = 'outline',\n size = 'medium',\n icon,\n iconPosition = 'before',\n className,\n children,\n ...rest\n } = props as CompoundButtonImplProps;\n // Content that renders nothing (`''`, `[]`, `<></>`) counts as absent; a generator is read once\n // by the check and its items render.\n const label = materialiseSlotContent(children);\n const secondary = materialiseSlotContent(secondaryText);\n const hasSecondary = slotRendersContent(secondary);\n\n // Without any text it is an icon-only (or empty) Button: Button's own sizing and name check.\n if (!slotRendersContent(label) && !hasSecondary) {\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={size}\n icon={icon}\n iconPosition={iconPosition}\n className={className}\n />\n );\n }\n\n const iconElement = renderSlot(\n slotRendersContent(icon) ? icon : undefined,\n 'span',\n cn('inline-flex shrink-0 items-center justify-center [&>svg]:size-full', iconBoxClasses[size]),\n { 'aria-hidden': true },\n );\n const content = (\n <span data-wave-compound-content=\"\" className=\"flex min-w-0 flex-col items-start\">\n <span className=\"font-bold\">{label}</span>\n {hasSecondary && (\n <span\n className={cn(\n 'text-caption-1 font-normal',\n appearance === 'primary' ? 'text-primary-foreground' : 'text-muted-foreground',\n )}\n >\n {secondary}\n </span>\n )}\n </span>\n );\n\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={size}\n className={cn(\n 'h-auto items-center justify-start gap-3 text-start',\n paddingClasses[size],\n className,\n )}\n >\n {iconPosition === 'after' ? (\n <>\n {content}\n {iconElement}\n </>\n ) : (\n <>\n {iconElement}\n {content}\n </>\n )}\n </BaseButton>\n );\n};\n\nCompoundButton.displayName = 'CompoundButton';\n"],"mappings":"wOAuEA,IAAMY,EAAuC,CAC3C,cAAe,SACf,MAAO,OACP,OAAQ,OACR,MAAO,OACP,cAAe,MACjB,EAGMC,EAAuC,CAC3C,cAAe,SACf,MAAO,SACP,OAAQ,UACR,MAAO,UACP,cAAe,SACjB,EAUMC,EAAad,EAAAA,OAuBNe,EAA0E,GAAU,CAC/F,GAAM,CACJ,gBACA,aAAa,UACb,OAAO,SACP,OACA,eAAe,SACf,YACA,WACA,GAAGC,GACDC,EAGEC,EAAQjB,EAAAA,uBAAuBkB,CAAQ,EACvCC,EAAYnB,EAAAA,uBAAuBoB,CAAa,EAChDC,EAAepB,EAAAA,mBAAmBkB,CAAS,EAGjD,GAAI,CAAClB,EAAAA,mBAAmBgB,CAAK,GAAK,CAACI,EACjC,OACE,EAAAX,EAAA,IAAA,CAACG,EAAD,CACE,GAAIE,EACQ,aACN,OACA,OACQ,eACH,WACZ,CAAA,EAIL,IAAMO,EAAcpB,EAAAA,WAClBD,EAAAA,mBAAmBsB,CAAI,EAAIA,EAAO,IAAA,GAClC,OACApB,EAAAA,GAAG,qEAAsES,EAAeY,EAAK,EAC7F,CAAE,cAAe,EAAK,CACxB,EACMC,GACJ,EAAAf,EAAA,KAAA,CAAC,OAAD,CAAM,6BAA2B,GAAG,UAAU,oCAA9C,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,YAAa,SAAAO,CAAY,CAAA,EACxCI,IACC,EAAAX,EAAA,IAAA,CAAC,OAAD,CACE,UAAWP,EAAAA,GACT,6BACAuB,IAAe,UAAY,0BAA4B,uBACzD,EAEC,SAAAP,CACG,CAAA,CAEJ,IAGR,OACE,EAAAT,EAAA,IAAA,CAACG,EAAD,CACE,GAAIE,EACQ,aACN,OACN,UAAWZ,EAAAA,GACT,qDACAQ,EAAea,GACfG,CACF,EAEC,SAAAC,IAAiB,SAChB,EAAAlB,EAAA,KAAA,CAAAN,EAAAA,SAAA,CAAA,SAAA,CACGqB,EACAH,CACD,CAAA,CAAA,GAEF,EAAAZ,EAAA,KAAA,CAAAN,EAAAA,SAAA,CAAA,SAAA,CACGkB,EACAG,CACD,CAAA,CAAA,CAEM,CAAA,CAEhB,EAEA,EAAe,YAAc"}
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { materialiseSlotContent as t, renderSlot as n, slotRendersContent as r } from "../../lib/slot.mjs";
4
+ import { Button as i } from "./Button.mjs";
5
+ import "react";
6
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ //#region src/components/button/CompoundButton.tsx
8
+ var c = {
9
+ "extra-small": "py-0.5",
10
+ small: "py-1",
11
+ medium: "py-2",
12
+ large: "py-3",
13
+ "extra-large": "py-4"
14
+ }, l = {
15
+ "extra-small": "size-6",
16
+ small: "size-8",
17
+ medium: "size-10",
18
+ large: "size-10",
19
+ "extra-large": "size-10"
20
+ }, u = i, d = (i) => {
21
+ let { secondaryText: d, appearance: f = "outline", size: p = "medium", icon: m, iconPosition: h = "before", className: g, children: _, ...v } = i, y = t(_), b = t(d), x = r(b);
22
+ if (!r(y) && !x) return /* @__PURE__ */ o(u, {
23
+ ...v,
24
+ appearance: f,
25
+ size: p,
26
+ icon: m,
27
+ iconPosition: h,
28
+ className: g
29
+ });
30
+ let S = n(r(m) ? m : void 0, "span", e("inline-flex shrink-0 items-center justify-center [&>svg]:size-full", l[p]), { "aria-hidden": !0 }), C = /* @__PURE__ */ s("span", {
31
+ "data-wave-compound-content": "",
32
+ className: "flex min-w-0 flex-col items-start",
33
+ children: [/* @__PURE__ */ o("span", {
34
+ className: "font-bold",
35
+ children: y
36
+ }), x && /* @__PURE__ */ o("span", {
37
+ className: e("text-caption-1 font-normal", f === "primary" ? "text-primary-foreground" : "text-muted-foreground"),
38
+ children: b
39
+ })]
40
+ });
41
+ return /* @__PURE__ */ o(u, {
42
+ ...v,
43
+ appearance: f,
44
+ size: p,
45
+ className: e("h-auto items-center justify-start gap-3 text-start", c[p], g),
46
+ children: h === "after" ? /* @__PURE__ */ s(a, { children: [C, S] }) : /* @__PURE__ */ s(a, { children: [S, C] })
47
+ });
48
+ };
49
+ d.displayName = "CompoundButton";
50
+ //#endregion
51
+ export { d as CompoundButton };
52
+
53
+ //# sourceMappingURL=CompoundButton.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompoundButton.mjs","names":["_Fragment","paddingClasses","iconBoxClasses","BaseButton","Button","CompoundButton","rest","props","label","materialiseSlotContent","children","secondary","secondaryText","hasSecondary","slotRendersContent","iconElement","renderSlot","icon","cn","size","content","appearance","className","iconPosition","Fragment"],"sources":["../../../src/components/button/CompoundButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { Size, Appearance, IconPosition, Slot } from '../../lib/types';\nimport { Button } from './Button';\n\n/**\n * The CompoundButton's own props (the XOwnProps rule of `PolymorphicProps`: component-specific\n * props only). Every other prop comes from the rendered element (`as`).\n */\nexport interface CompoundButtonOwnProps {\n /**\n * Secondary descriptive text displayed below the main label (part of the accessible name).\n * Content that renders nothing (`''`, `[]`, `<></>`) renders no second line.\n */\n secondaryText?: React.ReactNode;\n /** Visual style variant.\n * @default 'outline'\n */\n appearance?: Appearance;\n /** Size affecting padding and font size.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Disables the button. As with {@link Button}: a native `disabled` attribute for form controls\n * (the default `button`); every other `as` gets `aria-disabled=\"true\"` and `tabIndex={-1}`, its\n * activation is prevented and an `<a>` drops its `href`.\n * @default false\n */\n disabled?: boolean;\n /**\n * Marks the button unavailable but keeps it focusable and in the tab order (for a Tooltip\n * that explains why, or a toolbar). Renders `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable` instead of the native `disabled` attribute; clicks, Enter, Space\n * and implicit form submission are prevented, and your `onClick` is not called. Wins over\n * `disabled` when both are set. In a `Toolbar` it stays in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Icon shown beside the two lines of text, in a 40px box (32px at `small`, 24px at\n * `extra-small`) whose SVG fills it. Decorative (`aria-hidden`). A CompoundButton with only an\n * icon (no label, no `secondaryText`) is an icon-only button: it looks and is checked like an\n * icon-only `Button` and needs `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Where the icon renders: before the text column (the inline start) or after it (the inline\n * end). Follows the writing direction through DOM order. Has no effect without an icon or on\n * an icon-only button.\n * @default 'before'\n */\n iconPosition?: IconPosition;\n}\n\n/**\n * Props of {@link CompoundButton} rendered as `C` (default `'button'`). `CompoundButtonProps`\n * without a type argument is the 0.4 name: the props of a CompoundButton rendered as a\n * `<button>`, including `ref`.\n */\nexport type CompoundButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n CompoundButtonOwnProps\n>;\n\n/**\n * Vertical padding per size. The height is content-sized (`h-auto` replaces Button's fixed\n * height); horizontal padding and font size come from Button.\n */\nconst paddingClasses: Record<Size, string> = {\n 'extra-small': 'py-0.5',\n small: 'py-1',\n medium: 'py-2',\n large: 'py-3',\n 'extra-large': 'py-4',\n};\n\n/** The icon box per size (its SVG fills it): 24px at extra-small, 32px at small, else 40px. */\nconst iconBoxClasses: Record<Size, string> = {\n 'extra-small': 'size-6',\n small: 'size-8',\n medium: 'size-10',\n large: 'size-10',\n 'extra-large': 'size-10',\n};\n\n/** The props the implementation reads, for any `as`. */\ntype CompoundButtonImplProps = CompoundButtonOwnProps & {\n as?: React.ElementType;\n className?: string;\n children?: React.ReactNode;\n};\n\n/** `Button` widened to any element props, so `as` and the rest props pass through untyped. */\nconst BaseButton = Button as React.ElementType;\n\n/**\n * A button with a main label and a secondary line of text below it, and an optional icon beside\n * them. Built on {@link Button}: same appearances, sizes, token colors, `type=\"button\"` default,\n * `disabled`/`disabledFocusable` and polymorphic `as` behaviour (`as=\"a\"` renders a link; a\n * non-interactive `as` gets `role=\"button\"`, a tab stop and Enter/Space activation; `disabled`\n * becomes `aria-disabled` on non-form-control elements).\n *\n * - The text lines sit in a column wrapper (`span[data-wave-compound-content]`); the icon renders\n * before or after it (`iconPosition`).\n * - With only an icon (no label and no `secondaryText`) it is an icon-only `Button`: square, with\n * the icon-only sizing and name check.\n *\n * @example\n * <CompoundButton secondaryText=\"Opens your email client\">Send mail</CompoundButton>\n * <CompoundButton icon={<CalendarIcon />} secondaryText=\"Next Monday at 9:00\">\n * Schedule\n * </CompoundButton>\n * <CompoundButton as=\"a\" href=\"/signup\" appearance=\"primary\" secondaryText=\"Free for 30 days\">\n * Create account\n * </CompoundButton>\n */\nexport const CompoundButton: PolymorphicComponent<'button', CompoundButtonOwnProps> = (props) => {\n const {\n secondaryText,\n appearance = 'outline',\n size = 'medium',\n icon,\n iconPosition = 'before',\n className,\n children,\n ...rest\n } = props as CompoundButtonImplProps;\n // Content that renders nothing (`''`, `[]`, `<></>`) counts as absent; a generator is read once\n // by the check and its items render.\n const label = materialiseSlotContent(children);\n const secondary = materialiseSlotContent(secondaryText);\n const hasSecondary = slotRendersContent(secondary);\n\n // Without any text it is an icon-only (or empty) Button: Button's own sizing and name check.\n if (!slotRendersContent(label) && !hasSecondary) {\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={size}\n icon={icon}\n iconPosition={iconPosition}\n className={className}\n />\n );\n }\n\n const iconElement = renderSlot(\n slotRendersContent(icon) ? icon : undefined,\n 'span',\n cn('inline-flex shrink-0 items-center justify-center [&>svg]:size-full', iconBoxClasses[size]),\n { 'aria-hidden': true },\n );\n const content = (\n <span data-wave-compound-content=\"\" className=\"flex min-w-0 flex-col items-start\">\n <span className=\"font-bold\">{label}</span>\n {hasSecondary && (\n <span\n className={cn(\n 'text-caption-1 font-normal',\n appearance === 'primary' ? 'text-primary-foreground' : 'text-muted-foreground',\n )}\n >\n {secondary}\n </span>\n )}\n </span>\n );\n\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={size}\n className={cn(\n 'h-auto items-center justify-start gap-3 text-start',\n paddingClasses[size],\n className,\n )}\n >\n {iconPosition === 'after' ? (\n <>\n {content}\n {iconElement}\n </>\n ) : (\n <>\n {iconElement}\n {content}\n </>\n )}\n </BaseButton>\n );\n};\n\nCompoundButton.displayName = 'CompoundButton';\n"],"mappings":";;;;;;;AAuEA,IAAMC,IAAuC;CAC3C,eAAe;CACf,OAAO;CACP,QAAQ;CACR,OAAO;CACP,eAAe;AACjB,GAGMC,IAAuC;CAC3C,eAAe;CACf,OAAO;CACP,QAAQ;CACR,OAAO;CACP,eAAe;AACjB,GAUMC,IAAaC,GAuBNC,KAA0E,MAAU;CAC/F,IAAM,EACJ,kBACA,gBAAa,WACb,UAAO,UACP,SACA,kBAAe,UACf,cACA,aACA,GAAGC,MACDC,GAGEC,IAAQC,EAAuBC,CAAQ,GACvCC,IAAYF,EAAuBG,CAAa,GAChDC,IAAeC,EAAmBH,CAAS;CAGjD,IAAI,CAACG,EAAmBN,CAAK,KAAK,CAACK,GACjC,OACE,kBAACV,GAAD;EACE,GAAIG;EACQ;EACN;EACA;EACQ;EACH;CACZ,CAAA;CAIL,IAAMS,IAAcC,EAClBF,EAAmBG,CAAI,IAAIA,IAAO,KAAA,GAClC,QACAC,EAAG,sEAAsEhB,EAAeiB,EAAK,GAC7F,EAAE,eAAe,GAAK,CACxB,GACMC,IACJ,kBAAC,QAAD;EAAM,8BAA2B;EAAG,WAAU;EAA9C,UAAA,CACE,kBAAC,QAAD;GAAM,WAAU;GAAa,UAAAZ;EAAY,CAAA,GACxCK,KACC,kBAAC,QAAD;GACE,WAAWK,EACT,8BACAG,MAAe,YAAY,4BAA4B,uBACzD;GAEC,UAAAV;EACG,CAAA,CAEJ;;CAGR,OACE,kBAACR,GAAD;EACE,GAAIG;EACQ;EACN;EACN,WAAWY,EACT,sDACAjB,EAAekB,IACfG,CACF;EAEC,UAAAC,MAAiB,UAChB,kBAAAvB,GAAA,EAAA,UAAA,CACGoB,GACAL,CACD,EAAA,CAAA,IAEF,kBAAAf,GAAA,EAAA,UAAA,CACGe,GACAK,CACD,EAAA,CAAA;CAEM,CAAA;AAEhB;AAEA,EAAe,cAAc"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("./Button.semantics.cjs"),i=require("../../lib/styles.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("react/jsx-runtime");var s={inline:`text-primary underline not-disabled:not-aria-disabled:hover:decoration-2 focus-visible:decoration-2`,standalone:`font-semibold text-primary no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline`,subtle:`text-foreground no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline`},c=e=>{let{as:a,appearance:c,variant:l,disabled:u=!1,disabledFocusable:d=!1,className:f,onClick:p,onKeyDown:m,onKeyUp:h,onBlur:g,ref:_,...v}=e,y=n.resolveDeprecatedProp(`Link`,c,l,`variant`,`appearance`)??`inline`,b=a??`a`,{defaults:x,enforced:S,handlers:C}=r.useButtonSemantics({tag:typeof b==`string`?b:null,href:v.href,disabled:u,disabledFocusable:d,onClick:p,onKeyDown:m,onKeyUp:h,onBlur:g}),w={...v};for(let[e,t]of Object.entries(x))w[e]??=t;return(0,o.jsx)(b,{...w,...C,ref:_,className:t.cn(`cursor-pointer transition-colors motion-reduce:transition-none`,i.focusRing,s[y],(u||d)&&`cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100`,f),...S})};c.displayName=`Link`,exports.Link=c;
2
+ //# sourceMappingURL=Link.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.cjs","names":["resolveDeprecatedProp","useButtonSemantics","cn","focusRing","require_runtime","require_cn","require_dev","require_Button_semantics","require_styles","react","react_jsx_runtime","appearanceClasses","Link","appearanceProp","rest","props","appearance","variant","Component","as","elementProps","key","value","defaults","handlers","disabled","disabledFocusable","className","enforced"],"sources":["../../../src/components/button/Link.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { resolveDeprecatedProp } from '../../lib/dev';\nimport { focusRing } from '../../lib/styles';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { useButtonSemantics } from './Button.semantics';\n\n/**\n * Color treatment of a {@link Link}.\n *\n * - `inline` (default): for links in running text. Always underlined (the underline thickens on\n * hover and focus), because the link color alone does not stand out enough from body text.\n * - `standalone`: semibold, underlined on hover/focus only. Use it only where the position or\n * container already marks the text as a link (a list of links, a card footer, navigation).\n * - `subtle`: foreground color, underlined on hover/focus only. It cannot be told apart from body\n * text, so never use it inside a paragraph; only where the context makes the link obvious.\n */\nexport type LinkAppearance = 'inline' | 'standalone' | 'subtle';\n\n/** @deprecated Use {@link LinkAppearance}. */\nexport type LinkVariant = LinkAppearance;\n\n/**\n * The Link's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `'a'`).\n */\nexport interface LinkOwnProps {\n /** Color treatment (see {@link LinkAppearance} for where each one may be used).\n * @default 'inline'\n */\n appearance?: LinkAppearance;\n /** @deprecated Use `appearance` (same values). */\n variant?: LinkVariant;\n /**\n * Makes the link unavailable. An `<a>` drops its `href` (no navigation by middle-click, the\n * context menu or drag), keeps `role=\"link\"` (`role=\"button\"` when it had no `href`), and gets\n * `aria-disabled=\"true\"`, `data-disabled` and `tabIndex={-1}` (none can be overridden); a custom\n * `as` (router link) gets the same attributes. Clicks, Enter and Space are prevented: your\n * `onClick` is not called and the click does not reach ancestor click handlers. `as=\"button\"`\n * uses the native `disabled` attribute.\n * @default false\n */\n disabled?: boolean;\n /**\n * Marks the link unavailable but keeps it focusable and in the tab order: for a toolbar item or\n * a disabled link that needs a Tooltip. Renders `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable`; an `<a>` drops its `href`, keeps `role=\"link\"` (`role=\"button\"`\n * when it had no `href`) and gets `tabIndex={0}`, and `as=\"button\"` gets these attributes\n * instead of the native `disabled`.\n * Clicks, Enter and Space are prevented; your `onClick` is not called and the click does not\n * reach ancestor click handlers. Wins over `disabled` when both are set. In a `Toolbar` it stays\n * in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n}\n\n/**\n * Props of {@link Link} rendered as `C` (default `'a'`). `LinkProps` without a type argument is\n * the 0.4 name: the props of a Link rendered as an `<a>`, including `ref`.\n */\nexport type LinkProps<C extends React.ElementType = 'a'> = PolymorphicProps<C, LinkOwnProps>;\n\n/** The props the implementation reads, for any `as`. */\ntype LinkImplProps = LinkOwnProps &\n Omit<React.HTMLAttributes<HTMLElement>, 'onClick' | 'onKeyDown' | 'onKeyUp'> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n /** The destination: without one, the anchor gets button semantics. */\n href?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n };\n\nconst appearanceClasses: Record<LinkAppearance, string> = {\n inline:\n 'text-primary underline not-disabled:not-aria-disabled:hover:decoration-2 focus-visible:decoration-2',\n standalone:\n 'font-semibold text-primary no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline',\n subtle:\n 'text-foreground no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline',\n};\n\n/**\n * A hyperlink with Fluent link styling. Renders an `<a>` by default; `as` renders a router link\n * (`<Link as={RouterLink} to=\"/\">`) or a `<button>` styled as a link (`type=\"button\"` by default).\n *\n * - Without `href`, the `<a>` runs an action instead of navigating (\"Show more\"): it keeps its\n * element and gets `role=\"button\"`, a tab stop and Enter/Space activation (the consumer's\n * `role` and `tabIndex` win). A non-interactive `as` (`span`, `div`) is treated the same way;\n * any `href` string, `''` included, keeps the link semantics.\n *\n * @example\n * <p>Read the <Link href=\"/docs\">documentation</Link> first.</p>\n * <Link appearance=\"standalone\" href=\"/pricing\">See pricing</Link>\n * <Link onClick={showMore}>Show more</Link>\n */\nexport const Link: PolymorphicComponent<'a', LinkOwnProps> = (props) => {\n const {\n as,\n appearance: appearanceProp,\n variant,\n disabled = false,\n disabledFocusable = false,\n className,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n ref,\n ...rest\n } = props as LinkImplProps;\n\n const appearance =\n resolveDeprecatedProp('Link', appearanceProp, variant, 'variant', 'appearance') ?? 'inline';\n\n const Component: React.ElementType = as ?? 'a';\n const tag = typeof Component === 'string' ? Component : null;\n // The activation semantics of Button: an `<a>` without `href` or a `span` is a button, and a\n // disabled link blocks its click (ancestors included), Enter and Space.\n const { defaults, enforced, handlers } = useButtonSemantics({\n tag,\n href: rest.href,\n disabled,\n disabledFocusable,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n });\n\n // Defaults apply wherever the consumer's value is `undefined` or `null` (C-COMPOSE).\n const elementProps: Record<string, unknown> = { ...rest };\n for (const [key, value] of Object.entries(defaults)) elementProps[key] ??= value;\n\n return (\n <Component\n {...elementProps}\n {...handlers}\n ref={ref}\n className={cn(\n 'cursor-pointer transition-colors motion-reduce:transition-none',\n focusRing,\n appearanceClasses[appearance],\n // Full opacity while a focusable disabled link shows its focus ring, which `opacity`\n // would dim below 3:1 (as for buttons).\n (disabled || disabledFocusable) &&\n 'cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100',\n className,\n )}\n {...enforced}\n />\n );\n};\n\nLink.displayName = 'Link';\n"],"mappings":"mRA2EA,IAAMW,EAAoD,CACxD,OACE,sGACF,WACE,iHACF,OACE,qGACJ,EAgBaC,EAAiD,GAAU,CACtE,GAAM,CACJ,KACA,WAAYC,EACZ,UACA,WAAW,GACX,oBAAoB,GACpB,YACA,UACA,YACA,UACA,SACA,MACA,GAAGC,GACDC,EAEEC,EACJhB,EAAAA,sBAAsB,OAAQa,EAAgBI,EAAS,UAAW,YAAY,GAAK,SAE/EC,EAA+BC,GAAM,IAIrC,CAAE,WAAU,WAAU,YAAalB,EAAAA,mBAAmB,CAC1D,IAJU,OAAOiB,GAAc,SAAWA,EAAY,KAKtD,KAAMJ,EAAK,KACX,WACA,oBACA,UACA,YACA,UACA,QACF,CAAC,EAGKM,EAAwC,CAAE,GAAGN,CAAK,EACxD,IAAK,GAAM,CAACO,EAAKC,KAAU,OAAO,QAAQC,CAAQ,EAAG,EAAaF,KAASC,EAE3E,OACE,EAAAZ,EAAA,IAAA,CAACQ,EAAD,CACE,GAAIE,EACJ,GAAII,EACC,MACL,UAAWtB,EAAAA,GACT,iEACAC,EAAAA,UACAQ,EAAkBK,IAGjBS,GAAYC,IACX,wEACFC,CACF,EACA,GAAIC,CACL,CAAA,CAEL,EAEA,EAAK,YAAc"}
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { resolveDeprecatedProp as t } from "../../lib/dev.mjs";
4
+ import { useButtonSemantics as n } from "./Button.semantics.mjs";
5
+ import { focusRing as r } from "../../lib/styles.mjs";
6
+ import "react";
7
+ import { jsx as i } from "react/jsx-runtime";
8
+ //#region src/components/button/Link.tsx
9
+ var a = {
10
+ inline: "text-primary underline not-disabled:not-aria-disabled:hover:decoration-2 focus-visible:decoration-2",
11
+ standalone: "font-semibold text-primary no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline",
12
+ subtle: "text-foreground no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline"
13
+ }, o = (o) => {
14
+ let { as: s, appearance: c, variant: l, disabled: u = !1, disabledFocusable: d = !1, className: f, onClick: p, onKeyDown: m, onKeyUp: h, onBlur: g, ref: _, ...v } = o, y = t("Link", c, l, "variant", "appearance") ?? "inline", b = s ?? "a", { defaults: x, enforced: S, handlers: C } = n({
15
+ tag: typeof b == "string" ? b : null,
16
+ href: v.href,
17
+ disabled: u,
18
+ disabledFocusable: d,
19
+ onClick: p,
20
+ onKeyDown: m,
21
+ onKeyUp: h,
22
+ onBlur: g
23
+ }), w = { ...v };
24
+ for (let [e, t] of Object.entries(x)) w[e] ??= t;
25
+ return /* @__PURE__ */ i(b, {
26
+ ...w,
27
+ ...C,
28
+ ref: _,
29
+ className: e("cursor-pointer transition-colors motion-reduce:transition-none", r, a[y], (u || d) && "cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100", f),
30
+ ...S
31
+ });
32
+ };
33
+ o.displayName = "Link";
34
+ //#endregion
35
+ export { o as Link };
36
+
37
+ //# sourceMappingURL=Link.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.mjs","names":["appearanceClasses","Link","appearanceProp","rest","props","appearance","resolveDeprecatedProp","variant","Component","as","useButtonSemantics","elementProps","key","value","defaults","handlers","cn","focusRing","disabled","disabledFocusable","className","enforced"],"sources":["../../../src/components/button/Link.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { resolveDeprecatedProp } from '../../lib/dev';\nimport { focusRing } from '../../lib/styles';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { useButtonSemantics } from './Button.semantics';\n\n/**\n * Color treatment of a {@link Link}.\n *\n * - `inline` (default): for links in running text. Always underlined (the underline thickens on\n * hover and focus), because the link color alone does not stand out enough from body text.\n * - `standalone`: semibold, underlined on hover/focus only. Use it only where the position or\n * container already marks the text as a link (a list of links, a card footer, navigation).\n * - `subtle`: foreground color, underlined on hover/focus only. It cannot be told apart from body\n * text, so never use it inside a paragraph; only where the context makes the link obvious.\n */\nexport type LinkAppearance = 'inline' | 'standalone' | 'subtle';\n\n/** @deprecated Use {@link LinkAppearance}. */\nexport type LinkVariant = LinkAppearance;\n\n/**\n * The Link's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `'a'`).\n */\nexport interface LinkOwnProps {\n /** Color treatment (see {@link LinkAppearance} for where each one may be used).\n * @default 'inline'\n */\n appearance?: LinkAppearance;\n /** @deprecated Use `appearance` (same values). */\n variant?: LinkVariant;\n /**\n * Makes the link unavailable. An `<a>` drops its `href` (no navigation by middle-click, the\n * context menu or drag), keeps `role=\"link\"` (`role=\"button\"` when it had no `href`), and gets\n * `aria-disabled=\"true\"`, `data-disabled` and `tabIndex={-1}` (none can be overridden); a custom\n * `as` (router link) gets the same attributes. Clicks, Enter and Space are prevented: your\n * `onClick` is not called and the click does not reach ancestor click handlers. `as=\"button\"`\n * uses the native `disabled` attribute.\n * @default false\n */\n disabled?: boolean;\n /**\n * Marks the link unavailable but keeps it focusable and in the tab order: for a toolbar item or\n * a disabled link that needs a Tooltip. Renders `aria-disabled=\"true\"`, `data-disabled` and\n * `data-disabled-focusable`; an `<a>` drops its `href`, keeps `role=\"link\"` (`role=\"button\"`\n * when it had no `href`) and gets `tabIndex={0}`, and `as=\"button\"` gets these attributes\n * instead of the native `disabled`.\n * Clicks, Enter and Space are prevented; your `onClick` is not called and the click does not\n * reach ancestor click handlers. Wins over `disabled` when both are set. In a `Toolbar` it stays\n * in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n}\n\n/**\n * Props of {@link Link} rendered as `C` (default `'a'`). `LinkProps` without a type argument is\n * the 0.4 name: the props of a Link rendered as an `<a>`, including `ref`.\n */\nexport type LinkProps<C extends React.ElementType = 'a'> = PolymorphicProps<C, LinkOwnProps>;\n\n/** The props the implementation reads, for any `as`. */\ntype LinkImplProps = LinkOwnProps &\n Omit<React.HTMLAttributes<HTMLElement>, 'onClick' | 'onKeyDown' | 'onKeyUp'> & {\n as?: React.ElementType;\n ref?: React.Ref<HTMLElement>;\n /** The destination: without one, the anchor gets button semantics. */\n href?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLElement>;\n onKeyUp?: React.KeyboardEventHandler<HTMLElement>;\n };\n\nconst appearanceClasses: Record<LinkAppearance, string> = {\n inline:\n 'text-primary underline not-disabled:not-aria-disabled:hover:decoration-2 focus-visible:decoration-2',\n standalone:\n 'font-semibold text-primary no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline',\n subtle:\n 'text-foreground no-underline not-disabled:not-aria-disabled:hover:underline focus-visible:underline',\n};\n\n/**\n * A hyperlink with Fluent link styling. Renders an `<a>` by default; `as` renders a router link\n * (`<Link as={RouterLink} to=\"/\">`) or a `<button>` styled as a link (`type=\"button\"` by default).\n *\n * - Without `href`, the `<a>` runs an action instead of navigating (\"Show more\"): it keeps its\n * element and gets `role=\"button\"`, a tab stop and Enter/Space activation (the consumer's\n * `role` and `tabIndex` win). A non-interactive `as` (`span`, `div`) is treated the same way;\n * any `href` string, `''` included, keeps the link semantics.\n *\n * @example\n * <p>Read the <Link href=\"/docs\">documentation</Link> first.</p>\n * <Link appearance=\"standalone\" href=\"/pricing\">See pricing</Link>\n * <Link onClick={showMore}>Show more</Link>\n */\nexport const Link: PolymorphicComponent<'a', LinkOwnProps> = (props) => {\n const {\n as,\n appearance: appearanceProp,\n variant,\n disabled = false,\n disabledFocusable = false,\n className,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n ref,\n ...rest\n } = props as LinkImplProps;\n\n const appearance =\n resolveDeprecatedProp('Link', appearanceProp, variant, 'variant', 'appearance') ?? 'inline';\n\n const Component: React.ElementType = as ?? 'a';\n const tag = typeof Component === 'string' ? Component : null;\n // The activation semantics of Button: an `<a>` without `href` or a `span` is a button, and a\n // disabled link blocks its click (ancestors included), Enter and Space.\n const { defaults, enforced, handlers } = useButtonSemantics({\n tag,\n href: rest.href,\n disabled,\n disabledFocusable,\n onClick,\n onKeyDown,\n onKeyUp,\n onBlur,\n });\n\n // Defaults apply wherever the consumer's value is `undefined` or `null` (C-COMPOSE).\n const elementProps: Record<string, unknown> = { ...rest };\n for (const [key, value] of Object.entries(defaults)) elementProps[key] ??= value;\n\n return (\n <Component\n {...elementProps}\n {...handlers}\n ref={ref}\n className={cn(\n 'cursor-pointer transition-colors motion-reduce:transition-none',\n focusRing,\n appearanceClasses[appearance],\n // Full opacity while a focusable disabled link shows its focus ring, which `opacity`\n // would dim below 3:1 (as for buttons).\n (disabled || disabledFocusable) &&\n 'cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100',\n className,\n )}\n {...enforced}\n />\n );\n};\n\nLink.displayName = 'Link';\n"],"mappings":";;;;;;;;AA2EA,IAAMA,IAAoD;CACxD,QACE;CACF,YACE;CACF,QACE;AACJ,GAgBaC,KAAiD,MAAU;CACtE,IAAM,EACJ,OACA,YAAYC,GACZ,YACA,cAAW,IACX,uBAAoB,IACpB,cACA,YACA,cACA,YACA,WACA,QACA,GAAGC,MACDC,GAEEC,IACJC,EAAsB,QAAQJ,GAAgBK,GAAS,WAAW,YAAY,KAAK,UAE/EC,IAA+BC,KAAM,KAIrC,EAAE,aAAU,aAAU,gBAAaC,EAAmB;EAC1D,KAJU,OAAOF,KAAc,WAAWA,IAAY;EAKtD,MAAML,EAAK;EACX;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAGKQ,IAAwC,EAAE,GAAGR,EAAK;CACxD,KAAK,IAAM,CAACS,GAAKC,MAAU,OAAO,QAAQC,CAAQ,GAAG,EAAaF,OAASC;CAE3E,OACE,kBAACL,GAAD;EACE,GAAIG;EACJ,GAAII;EACC;EACL,WAAWC,EACT,kEACAC,GACAjB,EAAkBK,KAGjBa,KAAYC,MACX,yEACFC,CACF;EACA,GAAIC;CACL,CAAA;AAEL;AAEA,EAAK,cAAc"}
@@ -0,0 +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/slot.cjs"),i=require("./Button.cjs"),a=require("../../lib/icons.cjs"),o=require("./Button.slots.cjs");let s=require("react");s=e.__toESM(s,1);let c=require("react/jsx-runtime");var l={"extra-small":`min-w-0 px-1.5`,small:`min-w-0 px-1.5`,medium:`min-w-0 px-2`,large:`min-w-0 px-2`,"extra-large":`min-w-0 px-3`},u=({appearance:e=`outline`,size:u=`medium`,icon:d,menuIcon:f,expanded:p,className:m,children:h,"aria-haspopup":g,"aria-expanded":_,...v})=>{let{glyph:y,button:b}=o.unwrapButtonGlyph(f);s.useEffect(()=>{b&&n.warnOnce(`MenuButton:menuIcon-button`,`MenuButton: \`menuIcon\` received ${b}; its children render as the menu indicator and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \`menuIcon={<MyIcon />}\`.`)},[b]);let x=f==null||b!==null&&!r.slotRendersContent(y)?(0,c.jsx)(a.ChevronDownIcon,{className:`shrink-0`}):r.slotRendersContent(y)?r.renderSlot(y,`span`,`inline-flex shrink-0 items-center`,{"aria-hidden":!0}):null,S=r.materialiseSlotContent(h),C=x!==null&&!r.slotRendersContent(S),w=v[`aria-label`],T=v[`aria-labelledby`],E=v.title;return s.useEffect(()=>{C&&!w&&!T&&!E&&n.warnOnce(`MenuButton:icon-only-name`,"MenuButton: an icon-only menu button has no accessible name. Pass `aria-label`, `aria-labelledby` or `title` (the icon and the menu indicator are decorative and hidden from assistive technology).")},[C,w,T,E]),(0,c.jsxs)(i.Button,{...v,"aria-haspopup":g??`menu`,"aria-expanded":_??p,appearance:e,size:u,icon:d,className:t.cn(`gap-1.5`,C&&l[u],m),children:[S,x]})};u.displayName=`MenuButton`,exports.MenuButton=u;
2
+ //# sourceMappingURL=MenuButton.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MenuButton.cjs","names":["unwrapButtonGlyph","slotRendersContent","ChevronDownIcon","renderSlot","materialiseSlotContent","Button","cn","require_runtime","require_cn","require_dev","require_slot","require_Button","require_icons","require_Button_slots","react","react_jsx_runtime","unlabelledSizeClasses","MenuButton","ariaHasPopup","ariaExpanded","props","menuIconButton","menuIcon","indicator","glyph","label","children","unlabelled","ariaLabel","ariaLabelledBy","title","expanded","size","className"],"sources":["../../../src/components/button/MenuButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnOnce } from '../../lib/dev';\nimport { ChevronDownIcon } from '../../lib/icons';\nimport { materialiseSlotContent, renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Size, Appearance, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport { unwrapButtonGlyph } from './Button.slots';\n\n/** Properties for the MenuButton component. */\nexport interface MenuButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\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. Decorative: it renders with `aria-hidden=\"true\"` (a slot\n * object can override it). A menu button without a label (only the icon and/or the indicator)\n * needs `aria-label`, `aria-labelledby` or `title`.\n */\n icon?: Slot<'span'>;\n /**\n * Custom menu indicator rendered after the label, in place of the default chevron. Decorative\n * (`aria-hidden=\"true\"` unless a slot object overrides it). `false` hides the indicator, as does\n * any value that renders nothing (`true`, `''`, an empty array or Fragment, e.g. from\n * `menuIcon={cond && <X />}`); `null`/`undefined` keep the default chevron. A `<button>` or\n * `Button` element, or a slot object whose `as` is one, is not nested inside the menu button:\n * its children become the indicator (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 /**\n * Whether the associated menu is open (`aria-expanded`). Leave it unset when the button is\n * wrapped in `Menu.Trigger`, which supplies `aria-expanded` itself.\n */\n expanded?: boolean;\n /**\n * Marks the menu button 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 * are prevented and do not call `onClick`; other keys still reach `onKeyDown`, and\n * `Menu.Trigger` does not open its menu from an `aria-disabled` trigger. Wins over `disabled`\n * when both are set. In a `Toolbar` it stays in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /** Ref to the rendered `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * Minimum width and horizontal padding per size of a menu button without a label (an icon, the\n * menu indicator or both): no minimum width and the padding of SplitButton's menu half. Button\n * counts the indicator as content, so it would give such a button the labelled 96px minimum width.\n */\nconst unlabelledSizeClasses: Record<Size, string> = {\n 'extra-small': 'min-w-0 px-1.5',\n small: 'min-w-0 px-1.5',\n medium: 'min-w-0 px-2',\n large: 'min-w-0 px-2',\n 'extra-large': 'min-w-0 px-3',\n};\n\n/**\n * A button that opens a menu: {@link Button} with `aria-haspopup=\"menu\"`, `aria-expanded` and a\n * trailing chevron. Same appearances, sizes, `type=\"button\"` default and decorative icon slot as\n * Button. Without a label (only an icon and/or the chevron) it has no minimum width, and it warns\n * in development when it also has no `aria-label`, `aria-labelledby` or `title`.\n *\n * Use it as the child of `Menu.Trigger`, which supplies `id`, `aria-expanded`, `aria-controls`,\n * the open/keyboard handlers and the ref. A defined `aria-haspopup`/`aria-expanded` prop wins over\n * the built-in `\"menu\"` and `expanded` defaults, so the trigger's live state always wins; an\n * `undefined` or `null` one (a wrapper forwarding its own unset props) keeps the defaults.\n *\n * @example\n * <Menu>\n * <Menu.Trigger><MenuButton>Actions</MenuButton></Menu.Trigger>\n * <Menu.Popover>…</Menu.Popover>\n * </Menu>\n */\nexport const MenuButton = ({\n appearance = 'outline',\n size = 'medium',\n icon,\n menuIcon,\n expanded,\n className,\n children,\n 'aria-haspopup': ariaHasPopup,\n 'aria-expanded': ariaExpanded,\n ...props\n}: MenuButtonProps) => {\n // The indicator sits inside the button: a button passed as `menuIcon` is unwrapped (its children\n // are the indicator), never nested (C-SLOTS).\n const { glyph, button: menuIconButton } = unwrapButtonGlyph(menuIcon);\n React.useEffect(() => {\n if (menuIconButton) {\n warnOnce(\n 'MenuButton:menuIcon-button',\n `MenuButton: \\`menuIcon\\` received ${menuIconButton}; its children render as the menu indicator and its props were dropped (buttons cannot be nested). Pass icon content instead, e.g. \\`menuIcon={<MyIcon />}\\`.`,\n );\n }\n }, [menuIconButton]);\n\n // `menuIcon` follows the `icon` slot rule: unset keeps the chevron, a value that renders nothing\n // (`false`, `true`, `''`, an empty array, Set or Fragment) hides the indicator without leaving an\n // empty `aria-hidden` span behind. An unwrapped button whose children render nothing keeps the\n // chevron, as for a picker's `expandIcon`.\n const indicator =\n menuIcon == null || (menuIconButton !== null && !slotRendersContent(glyph)) ? (\n <ChevronDownIcon className=\"shrink-0\" />\n ) : slotRendersContent(glyph) ? (\n renderSlot(glyph, 'span', 'inline-flex shrink-0 items-center', { 'aria-hidden': true })\n ) : null;\n\n // While the indicator renders, Button counts it as content: it sizes the button as labelled and\n // skips its icon-only name check. A menu button whose only content is decorative (an icon, the\n // indicator or both) is therefore sized and checked here. Without an indicator\n // (`menuIcon={false}`, `''`, …) Button handles both by itself: checking here too would log the\n // same problem twice.\n // A generator label is read once by the check; its items are what renders.\n const label = materialiseSlotContent(children);\n const unlabelled = indicator !== null && !slotRendersContent(label);\n const ariaLabel = props['aria-label'];\n const ariaLabelledBy = props['aria-labelledby'];\n const title = props.title;\n React.useEffect(() => {\n if (unlabelled && !ariaLabel && !ariaLabelledBy && !title) {\n warnOnce(\n 'MenuButton:icon-only-name',\n 'MenuButton: an icon-only menu button has no accessible name. Pass `aria-label`, `aria-labelledby` or `title` (the icon and the menu indicator are decorative and hidden from assistive technology).',\n );\n }\n }, [unlabelled, ariaLabel, ariaLabelledBy, title]);\n\n // `aria-haspopup`/`aria-expanded` defaults apply wherever the consumer's value is `undefined` or\n // `null` (as Button does for `type`, `role` and `tabIndex`), so a forwarded unset prop keeps them.\n return (\n <Button\n {...props}\n aria-haspopup={ariaHasPopup ?? 'menu'}\n aria-expanded={ariaExpanded ?? expanded}\n appearance={appearance}\n size={size}\n icon={icon}\n className={cn('gap-1.5', unlabelled && unlabelledSizeClasses[size], className)}\n >\n {label}\n {indicator}\n </Button>\n );\n};\n\nMenuButton.displayName = 'MenuButton';\n"],"mappings":"wUA2DA,IAAMgB,EAA8C,CAClD,cAAe,iBACf,MAAO,iBACP,OAAQ,eACR,MAAO,eACP,cAAe,cACjB,EAmBaC,GAAc,CACzB,aAAa,UACb,OAAO,SACP,OACA,WACA,WACA,YACA,WACA,gBAAiBC,EACjB,gBAAiBC,EACjB,GAAGC,KACkB,CAGrB,GAAM,CAAE,QAAO,OAAQC,GAAmBrB,EAAAA,kBAAkBsB,CAAQ,EACpER,EAAM,cAAgB,CAChBO,GACFZ,EAAA,SACE,6BACA,qCAAqCY,EAAe,8JACtD,CAEJ,EAAG,CAACA,CAAc,CAAC,EAMnB,IAAME,EACJD,GAAY,MAASD,IAAmB,MAAQ,CAACpB,EAAAA,mBAAmBuB,CAAK,GACvE,EAAAT,EAAA,IAAA,CAACb,EAAAA,gBAAD,CAAiB,UAAU,UAAY,CAAA,EACrCD,EAAAA,mBAAmBuB,CAAK,EAC1BrB,EAAAA,WAAWqB,EAAO,OAAQ,oCAAqC,CAAE,cAAe,EAAK,CAAC,EACpF,KAQAC,EAAQrB,EAAAA,uBAAuBsB,CAAQ,EACvCC,EAAaJ,IAAc,MAAQ,CAACtB,EAAAA,mBAAmBwB,CAAK,EAC5DG,EAAYR,EAAM,cAClBS,EAAiBT,EAAM,mBACvBU,EAAQV,EAAM,MAYpB,OAXAN,EAAM,cAAgB,CAChBa,GAAc,CAACC,GAAa,CAACC,GAAkB,CAACC,GAClDrB,EAAA,SACE,4BACA,qMACF,CAEJ,EAAG,CAACkB,EAAYC,EAAWC,EAAgBC,CAAK,CAAC,GAK/C,EAAAf,EAAA,KAAA,CAACV,EAAAA,OAAD,CACE,GAAIe,EACJ,gBAAeF,GAAgB,OAC/B,gBAAeC,GAAgBY,EACnB,aACN,OACA,OACN,UAAWzB,EAAAA,GAAG,UAAWqB,GAAcX,EAAsBgB,GAAOC,CAAS,EAP/E,SAAA,CASGR,EACAF,CACK,GAEZ,EAEA,EAAW,YAAc"}