@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,92 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { warnDeprecated as t, warnOnce as ee } from "../../lib/dev.mjs";
4
+ import { materialiseSlotContent as te, slotRendersContent as n } from "../../lib/slot.mjs";
5
+ import { composeEventHandlers as ne } from "../../lib/composeEventHandlers.mjs";
6
+ import { useControllable as r } from "../../hooks/useControllable.mjs";
7
+ import { useId as i } from "../../hooks/useId.mjs";
8
+ import { useMergedRefs as re } from "../../hooks/useMergedRefs.mjs";
9
+ import { focusableDisabledProps as ie, joinIds as ae } from "../../lib/aria.mjs";
10
+ import { useFieldContext as oe, useFieldControl as a } from "../../hooks/useFieldControl.mjs";
11
+ import { focusRing as se, forcedColors as o } from "../../lib/styles.mjs";
12
+ import { useFormReset as ce } from "../../hooks/useFormReset.mjs";
13
+ import { HiddenInput as le } from "../internal/HiddenInput.mjs";
14
+ import * as s from "react";
15
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
16
+ //#region src/components/input/Switch.tsx
17
+ var u = "forced-colors:border-[Highlight] forced-colors:bg-[Highlight]", d = "forced-colors:border-[GrayText] forced-colors:bg-[Canvas]", f = ({ checked: f, defaultChecked: p = !1, onCheckedChange: ue, onChange: m, disabled: h = !1, disabledFocusable: g = !1, label: _, labelPosition: v = "after", name: y, value: b, required: x, form: S, id: C, "aria-label": w, "aria-labelledby": T, "aria-describedby": E, "aria-invalid": D, "aria-required": O, "aria-errormessage": k, "aria-details": A, "aria-disabled": j, autoFocus: M, tabIndex: N, onClick: P, onFocus: F, onBlur: de, onKeyDown: I, onKeyUp: L, controlRef: R, className: z, children: B, ref: V, ...H }) => {
18
+ m !== void 0 && t("Switch", "onChange", "onCheckedChange");
19
+ let U = n(B);
20
+ s.useEffect(() => {
21
+ U && ee("Switch:children", "Switch: children are not rendered. Pass the label in `label`.");
22
+ }, [U]);
23
+ let [W, G] = r(f, p, (e) => {
24
+ ue?.(e), m?.(e);
25
+ }), fe = i("switch"), K = i("switch-label"), q = oe(), J = a({
26
+ id: C,
27
+ "aria-label": w,
28
+ "aria-labelledby": T,
29
+ "aria-describedby": E,
30
+ "aria-invalid": D,
31
+ "aria-required": O ?? x
32
+ }), pe = x ?? q?.required ?? !1, Y = n(_), me = Y && J["aria-label"] === void 0 ? ae(J["aria-labelledby"], q && J.id === q.controlId ? q.labelId : void 0, K) : J["aria-labelledby"], X = s.useRef(null), he = re(X, R);
33
+ ce(X, () => G(p), S);
34
+ let Z = Y ? /* @__PURE__ */ c("span", {
35
+ id: K,
36
+ className: "text-body-1 text-foreground",
37
+ children: te(_)
38
+ }) : null, Q = v === "before" || v === "above", $ = h || g;
39
+ return /* @__PURE__ */ l("label", {
40
+ ref: V,
41
+ "data-label-position": v,
42
+ className: e("relative inline-flex items-start gap-2 select-none", v === "above" && "flex-col gap-1", $ ? "cursor-not-allowed opacity-50 has-focus-visible:opacity-100" : "cursor-pointer", z),
43
+ ...H,
44
+ children: [
45
+ Q && Z,
46
+ /* @__PURE__ */ c("button", {
47
+ id: fe,
48
+ type: "button",
49
+ ...J,
50
+ "aria-labelledby": me,
51
+ "aria-errormessage": k,
52
+ "aria-details": A,
53
+ "aria-disabled": j,
54
+ autoFocus: M,
55
+ tabIndex: N,
56
+ onFocus: F,
57
+ onBlur: de,
58
+ onKeyDown: I,
59
+ onKeyUp: L,
60
+ ref: he,
61
+ role: "switch",
62
+ "aria-checked": W,
63
+ disabled: h && !g,
64
+ ...ie(g, { reachable: !0 }),
65
+ onClick: g ? (e) => {
66
+ e.preventDefault(), e.stopPropagation();
67
+ } : ne(P, () => G((e) => !e)),
68
+ className: e("relative inline-flex h-[20px] w-[40px] shrink-0 items-center rounded-full border p-0 transition-colors duration-200 motion-reduce:transition-none", se, W ? e("border-primary bg-primary", $ ? d : u) : e("border-stroke-accessible bg-transparent", $ ? o.disabled : o.control)),
69
+ children: /* @__PURE__ */ c("span", {
70
+ "aria-hidden": "true",
71
+ className: e("block h-[14px] w-[14px] rounded-full transition-transform duration-200 motion-reduce:transition-none forced-colors:forced-color-adjust-none", W ? "translate-x-[22px] wave-rtl:-translate-x-[22px] bg-primary-foreground" : "translate-x-[2px] wave-rtl:-translate-x-[2px] bg-stroke-accessible", $ ? "forced-colors:bg-[GrayText]" : W ? "forced-colors:bg-[HighlightText]" : "forced-colors:bg-[ButtonText]")
72
+ })
73
+ }),
74
+ !Q && Z,
75
+ /* @__PURE__ */ c(le, {
76
+ type: "checkbox",
77
+ name: y,
78
+ form: S,
79
+ disabled: $,
80
+ value: b,
81
+ checked: W,
82
+ required: pe,
83
+ onInvalid: () => X.current?.focus()
84
+ })
85
+ ]
86
+ });
87
+ };
88
+ f.displayName = "Switch";
89
+ //#endregion
90
+ export { f as Switch };
91
+
92
+ //# sourceMappingURL=Switch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Switch.mjs","names":["useId","useId$1","React","onTrack","disabledOnTrack","Switch","checkedProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","ariaDisabled","rest","onChange","warnDeprecated","hasChildren","slotRendersContent","children","warnOnce","checked","setChecked","useControllable","defaultChecked","onCheckedChange","next","generatedId","labelTextId","field","useFieldContext","fieldProps","useFieldControl","required","isRequired","hasLabel","label","labelledBy","joinIds","buttonRef","mergedControlRef","useMergedRefs","controlRef","form","labelText","materialiseSlotContent","labelFirst","labelPosition","unavailable","disabled","disabledFocusable","cn","className","focusableDisabledProps","event","composeEventHandlers","onClick","prev","focusRing","forcedColors","HiddenInput"],"sources":["../../../src/components/input/Switch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { focusableDisabledProps, joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { materialiseSlotContent, slotRendersContent } from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { LabelPosition } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { HiddenInput } from '../internal/HiddenInput';\n\n/*\n * Forced colors: the focusable track keeps system-color utilities, so the browser still forces its\n * focus outline; only the thumb (the leaf indicator) opts out of forced colors. A disabled switch\n * draws a GrayText thumb and border on Canvas, without the Highlight fill.\n */\nconst onTrack = 'forced-colors:border-[Highlight] forced-colors:bg-[Highlight]';\nconst disabledOnTrack = 'forced-colors:border-[GrayText] forced-colors:bg-[Canvas]';\n\n/** Handlers that run on the `role=\"switch\"` button instead of the root label (C-ROUTING). */\ntype SwitchControlHandlers = 'onClick' | 'onFocus' | 'onBlur' | 'onKeyDown' | 'onKeyUp';\n\n/** Where a Switch renders its label: after the track (default), before it or above it. */\nexport type SwitchLabelPosition = Extract<LabelPosition, 'before' | 'after' | 'above'>;\n\n/** Properties for the Switch component. */\nexport interface SwitchProps extends Omit<\n React.HTMLAttributes<HTMLLabelElement>,\n 'onChange' | 'defaultChecked' | SwitchControlHandlers\n> {\n /** Controlled checked (on/off) state. */\n checked?: boolean;\n /** Initial checked state for uncontrolled usage (also the value a form reset restores).\n * @default false\n */\n defaultChecked?: boolean;\n /** Called with the new checked state when the switch is toggled (not for no-op updates). */\n onCheckedChange?: (checked: boolean) => void;\n /**\n * Called with the new checked state when the switch is toggled.\n * @deprecated Use `onCheckedChange`.\n */\n onChange?: (checked: boolean) => void;\n /** Whether the switch is disabled and non-interactive. */\n disabled?: boolean;\n /**\n * Marks the switch unavailable but keeps it focusable and in the tab order: for a disabled\n * switch that needs a Tooltip, or one in a toolbar. Renders `aria-disabled=\"true\"`,\n * `data-disabled` and `data-disabled-focusable` on the switch instead of the native `disabled`\n * attribute. The switch cannot be toggled and is not submitted with its form; your `onClick` is\n * not called, and a click on the switch (or Space and Enter) does not reach ancestor click\n * handlers, as for a natively disabled control. Wins over `disabled` when both are set. In a\n * roving container (a `Toolbar`) it stays in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Label next to the control (any phrasing content, links included, but no other form\n * controls). It names the control through `aria-labelledby`, after a consumer or Field\n * `aria-labelledby`; a consumer `aria-label` names it instead. Clicking its text toggles the\n * control; clicking a link inside it follows the link. `children` are not rendered: pass the\n * label here.\n */\n label?: React.ReactNode;\n /**\n * Where the label renders: after the control (default), before it, or above it. The DOM order\n * follows the visual order.\n * @default 'after'\n */\n labelPosition?: SwitchLabelPosition;\n /**\n * Form field name. With a name, the switch takes part in native form submission: it submits\n * `name=value` while on.\n */\n name?: string;\n /** Value submitted while on.\n * @default 'on'\n */\n value?: string;\n /** The form must not be submitted while the switch is off (native validation). */\n required?: boolean;\n /** Id of the form the switch belongs to, when it is rendered outside that form. */\n form?: string;\n /** Click handler of the switch control (the `role=\"switch\"` button). */\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n /** Focus handler of the switch control. */\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n /** Blur handler of the switch control. */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /** Keydown handler of the switch control. */\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Keyup handler of the switch control. */\n onKeyUp?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Ref to the focusable `role=\"switch\"` button. */\n controlRef?: React.Ref<HTMLButtonElement>;\n /** Ref to the root `<label>` element. */\n ref?: React.Ref<HTMLLabelElement>;\n}\n\n/**\n * An on/off toggle drawn as a `role=\"switch\"` button inside a `<label>`.\n *\n * - The root `<label>` receives `ref`, `className`, `style` and `data-*`; the control receives\n * `id`, `aria-label`/`-labelledby`/`-describedby`/`-invalid`/`-required`/`-errormessage`/\n * `-details`/`-disabled`, `tabIndex`, `autoFocus` and the click, focus and key handlers\n * (`controlRef` exposes it). A consumer `onClick` runs once per activation, before the toggle;\n * `preventDefault()` in it cancels the toggle.\n * - Inside a `Field` it is named by the Field label (followed by its own `label` text) and described\n * by the Field message and hint.\n * - With `name` (or `required`) it takes part in native forms like `<input type=\"checkbox\">`, and\n * a form reset restores `defaultChecked`.\n * - The thumb position mirrors when the switch itself is right-to-left (its nearest `dir`), so a\n * switch in an LTR subtree of an RTL page keeps the LTR layout.\n * - `label` takes rich content (a link) and renders after the switch, or before or above it with\n * `labelPosition` (the root carries `data-label-position`). Beside the label, the switch lines\n * up with the first line of a label that wraps or has a second line. `children` are not\n * rendered (a development warning says so).\n */\nexport const Switch = ({\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n onChange,\n disabled = false,\n disabledFocusable = false,\n label,\n labelPosition = 'after',\n name,\n value,\n required,\n form,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n 'aria-disabled': ariaDisabled,\n autoFocus,\n tabIndex,\n onClick,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n children,\n ref,\n ...rest\n}: SwitchProps) => {\n if (onChange !== undefined) warnDeprecated('Switch', 'onChange', 'onCheckedChange');\n const hasChildren = slotRendersContent(children);\n React.useEffect(() => {\n if (hasChildren) {\n warnOnce('Switch:children', 'Switch: children are not rendered. Pass the label in `label`.');\n }\n }, [hasChildren]);\n const [checked, setChecked] = useControllable(checkedProp, defaultChecked, (next: boolean) => {\n onCheckedChange?.(next);\n onChange?.(next);\n });\n\n const generatedId = useId('switch');\n const labelTextId = useId('switch-label');\n const field = useFieldContext();\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required always matches\n // the native validation below (`isRequired`).\n 'aria-required': ariaRequired ?? required,\n });\n const isRequired = required ?? field?.required ?? false;\n // `0` is a label; `null`, `false`, `''` and empty collections are not (C-SLOTS).\n const hasLabel = slotRendersContent(label);\n // The label text names the control through aria-labelledby, disabled or not: axe exempts the\n // dimmed text of a disabled control only when the control references it this way (its <label>\n // exemption covers native inputs only). A consumer aria-label still names the control alone.\n // The ids already there (the consumer's, the Field label from useFieldControl) come first, then\n // the Field label whose <label htmlFor> targets this control (aria-labelledby would hide it), so\n // the name keeps every label.\n const labelledBy =\n hasLabel && fieldProps['aria-label'] === undefined\n ? joinIds(\n fieldProps['aria-labelledby'],\n field && fieldProps.id === field.controlId ? field.labelId : undefined,\n labelTextId,\n )\n : fieldProps['aria-labelledby'];\n\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const mergedControlRef = useMergedRefs(buttonRef, controlRef);\n useFormReset(buttonRef, () => setChecked(defaultChecked), form);\n\n const labelText = hasLabel ? (\n <span id={labelTextId} className=\"text-body-1 text-foreground\">\n {materialiseSlotContent(label)}\n </span>\n ) : null;\n const labelFirst = labelPosition === 'before' || labelPosition === 'above';\n // Focusable-disabled wins over `disabled`: the switch stays focusable but looks and acts disabled.\n const unavailable = disabled || disabledFocusable;\n\n return (\n <label\n ref={ref}\n data-label-position={labelPosition}\n className={cn(\n // items-start: the 20px track lines up with the 20px first line of a label that wraps or\n // has a second line, not with its middle.\n 'relative inline-flex items-start gap-2 select-none',\n labelPosition === 'above' && 'flex-col gap-1',\n // The dimmed look lifts while a focus ring shows inside the root (the control's, under\n // disabledFocusable, or a link's in the label): opacity would dim the ring below 3:1.\n unavailable\n ? 'cursor-not-allowed opacity-50 has-focus-visible:opacity-100'\n : 'cursor-pointer',\n className,\n )}\n {...rest}\n >\n {labelFirst && labelText}\n <button\n id={generatedId}\n type=\"button\"\n {...fieldProps}\n aria-labelledby={labelledBy}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n aria-disabled={ariaDisabled}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n ref={mergedControlRef}\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled && !disabledFocusable}\n {...focusableDisabledProps(disabledFocusable, { reachable: true })}\n onClick={\n disabledFocusable\n ? // Clicks, Space and Enter (which click a button) neither toggle nor reach `onClick`,\n // and, as a natively disabled control dispatches no click, no ancestor sees them.\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n }\n : composeEventHandlers(onClick, () => setChecked((prev) => !prev))\n }\n className={cn(\n // The whole control is sized in px, like the Checkbox box and the radio circle: the thumb\n // and its offsets are px, so a track in rem would stop fitting them at any root font size\n // other than 16px. The 40x20 track (1px border) leaves a 2px inset around the 14px thumb.\n // p-0 is set here, not left to the native reset, which any app button style overrides\n // (C-NATIVE): the thumb offsets assume no padding.\n 'relative inline-flex h-[20px] w-[40px] shrink-0 items-center rounded-full border p-0 transition-colors duration-200 motion-reduce:transition-none',\n focusRing,\n checked\n ? cn('border-primary bg-primary', unavailable ? disabledOnTrack : onTrack)\n : cn(\n 'border-stroke-accessible bg-transparent',\n unavailable ? forcedColors.disabled : forcedColors.control,\n ),\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'block h-[14px] w-[14px] rounded-full transition-transform duration-200 motion-reduce:transition-none forced-colors:forced-color-adjust-none',\n checked\n ? 'translate-x-[22px] wave-rtl:-translate-x-[22px] bg-primary-foreground'\n : 'translate-x-[2px] wave-rtl:-translate-x-[2px] bg-stroke-accessible',\n unavailable\n ? 'forced-colors:bg-[GrayText]'\n : checked\n ? 'forced-colors:bg-[HighlightText]'\n : 'forced-colors:bg-[ButtonText]',\n )}\n />\n </button>\n {!labelFirst && labelText}\n <HiddenInput\n type=\"checkbox\"\n name={name}\n form={form}\n disabled={unavailable}\n value={value}\n checked={checked}\n required={isRequired}\n onInvalid={() => buttonRef.current?.focus()}\n />\n </label>\n );\n};\n\nSwitch.displayName = 'Switch';\n"],"mappings":"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"}
@@ -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/composeEventHandlers.cjs"),i=require("../../hooks/useControllable.cjs"),a=require("../../hooks/useId.cjs"),o=require("../../lib/direction.cjs"),s=require("../../hooks/useMergedRefs.cjs"),ee=require("../../hooks/useIsClient.cjs"),te=require("../../lib/aria.cjs"),c=require("../../hooks/useFieldControl.cjs"),ne=require("../../hooks/useAnnounce.cjs"),l=require("../../lib/styles.cjs"),u=require("../../lib/icons.cjs"),re=require("./Input.cjs"),ie=require("../../hooks/useFormReset.cjs"),ae=require("../internal/HiddenInput.cjs"),oe=require("../../hooks/useListbox.cjs"),d=require("./Option.cjs"),f=require("../../hooks/usePreserveFocus.cjs");let p=require("react");p=e.__toESM(p,1);let m=require("react/jsx-runtime");var se=e=>`Remove ${e}`,ce=e=>`Selected: ${e.join(`, `)}`,le=(e,t)=>`${e} added, ${t} selected`,ue=(e,t)=>`${e} removed, ${t} selected`,h=[];function de(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}function fe({label:e,disabled:n,onClick:r,onKeyDown:i,getFallback:a}){let o=p.useRef(null);return f.usePreserveFocus(o,a),(0,m.jsx)(`button`,{ref:o,type:`button`,"data-wave-tagpicker-remove":``,disabled:n,"aria-label":e,className:t.cn(`ms-0.5 inline-flex rounded-sm bg-transparent p-0 text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground disabled:cursor-not-allowed`,l.focusRing),onClick:r,onKeyDown:i,children:(0,m.jsx)(u.DismissIcon,{size:12})})}var g=e=>{let{options:u,value:f,defaultValue:g,onValueChange:pe,onChange:_,open:me,defaultOpen:he,onOpenChange:ge,placeholder:_e=`Select...`,disabled:v=!1,name:ve,form:y,required:b,autoComplete:ye=`off`,autoCapitalize:be,autoCorrect:xe,maxLength:Se,readOnly:x,labels:S,inputMode:Ce,spellCheck:we,enterKeyHint:Te,autoFocus:Ee,tabIndex:C,id:w,"aria-label":T,"aria-labelledby":E,"aria-describedby":D,"aria-invalid":De,"aria-required":Oe,"aria-errormessage":ke,"aria-details":Ae,onFocus:je,onBlur:Me,onKeyDown:Ne,onKeyUp:Pe,controlRef:Fe,className:Ie,ref:Le,...Re}=e;_!==void 0&&n.warnDeprecated(`TagPicker`,`onChange`,`onValueChange`);let O=c.useFieldContext(),ze=(b??O?.required??!1)&&!x,k=c.useFieldControl({id:w,"aria-label":T,"aria-labelledby":E,"aria-describedby":D,"aria-invalid":De,"aria-required":Oe??b}),Be=re.isInvalidLook(!1,k[`aria-invalid`]),[A,j]=i.useControllable(f,g??h,e=>{let t=[...e];pe?.(t),_?.(t)}),M=!v&&!x,[N,P]=i.useControllable(me,(he??!1)&&M,ge),Ve=ee.useIsClient(),F=N&&M&&Ve,[I,L]=p.useState(``),[He,Ue]=p.useState(M);He!==M&&(Ue(M),M||L(``));let R=!M&&N;p.useEffect(()=>{R&&P(!1)},[R,P]);let z=ne.useAnnounce(),B=p.useRef(null),V=p.useRef(null),H=a.useId(`tagpicker-summary`),U=p.useMemo(()=>{let e=new Map;for(let t of u)e.has(t.value)||e.set(t.value,t.label);return e},[u]),W=e=>U.get(e)??e,We=p.useMemo(()=>{let e=new Set(A);return u.filter(t=>!e.has(t.value)).map(e=>({value:e.value,label:e.label}))},[u,A]),Ge=p.useMemo(()=>I?e=>e.label.toLowerCase().includes(I.toLowerCase()):void 0,[I]),G=A.filter(e=>!U.has(e)).join(`\0`);p.useEffect(()=>{G&&n.warnOnce(`TagPicker:unknown-value`,`TagPicker: the selected value(s) ${G.split(`\0`).map(e=>`"${e}"`).join(`, `)} match no option; the raw value is shown as the tag label.`)},[G]);let Ke=()=>V.current,K=()=>V.current?.focus(),qe=e=>{if(!M||A.includes(e))return;let t=[...A,e];j(t),L(``),z((S?.added??le)(W(e),t.length))},q=e=>{if(!M)return;let t=A.filter(t=>t!==e);j(t),z((S?.removed??ue)(W(e),t.length)),K()},J=oe.useListbox({open:F,onOpenChange:e=>P(e),mode:`editable`,multiple:!0,selectedValues:A,onSelect:e=>qe(e),items:We,filter:Ge,autoHighlight:I?`first`:!1,idPrefix:`tagpicker-listbox`,onClearDraft:I?()=>L(``):void 0}),Y=F&&J.items.length>0,X=S?.noMatches??`No matches`,Z=F&&(Y||I!==``),Je=Z&&!Y,{layerId:Ye,setReference:Xe,surfaceRef:Ze,floatingProps:Q}=d.useListboxPopup({open:F,surfaceOpen:Z,onDismiss:()=>P(!1),rootRef:B,anchorRef:V}),Qe=s.useMergedRefs(B,Le),$e=s.useMergedRefs(V,Fe);ie.useFormReset(V,()=>{let e=g??h;j(t=>de(t,e)?t:[...e]),L(``)},y);let $=e=>Array.from(e.closest(`[data-wave-tagpicker-control]`)?.querySelectorAll(`[data-wave-tagpicker-remove]`)??[]),et=e=>{if(M){if(e.key===`Escape`&&F&&!Z&&!e.nativeEvent.isComposing){P(!1);return}if(e.key===`Backspace`&&I===``&&A.length>0){e.preventDefault(),$(e.currentTarget).at(-1)?.focus();return}J.onKeyDown(e)}},tt=(e,t)=>{if(!M)return;let n=$(e.currentTarget),r=n.indexOf(e.currentTarget);if(e.key===`Backspace`||e.key===`Delete`){e.preventDefault(),q(t);return}if(e.key===`Escape`){e.preventDefault(),K();return}let i=o.getArrowIntent(e.key,{orientation:`horizontal`,dir:o.getDirection(e.currentTarget)});i===`prev`&&r>0?(e.preventDefault(),n[r-1].focus()):i===`next`&&(e.preventDefault(),r<n.length-1?n[r+1].focus():K())},nt=k[`aria-label`]===void 0?k[`aria-labelledby`]??O?.labelId:k[`aria-labelledby`];return(0,m.jsxs)(`div`,{...Re,ref:Qe,className:t.cn(`relative`,Ie),children:[(0,m.jsxs)(`div`,{ref:Xe,"data-wave-tagpicker-control":``,role:`group`,"aria-disabled":v||void 0,className:t.cn(`flex flex-wrap items-center gap-1 rounded border border-input border-b-stroke-accessible bg-background px-2 py-1.5`,l.inputFocusWithin,Be&&`border-destructive focus-within:border-b-destructive`,v&&`cursor-not-allowed opacity-50`),onClick:e=>{v||e.target.closest(`button`)||(K(),!F&&M&&P(!0))},children:[A.length>0&&(0,m.jsx)(`div`,{role:`list`,"aria-label":S?.selected??`Selected`,className:`flex flex-wrap items-center gap-1`,children:A.map(e=>{let t=W(e);return(0,m.jsxs)(`div`,{role:`listitem`,className:`inline-flex items-center gap-1 rounded bg-muted px-2 py-0.5 text-body-1 text-foreground`,children:[t,!x&&(0,m.jsx)(fe,{label:(S?.remove??se)(t),disabled:v,onClick:()=>q(e),onKeyDown:t=>tt(t,e),getFallback:Ke})]},e)})}),A.length>0&&(0,m.jsx)(`span`,{id:H,hidden:!0,children:(S?.summary??ce)(A.map(W))}),(0,m.jsx)(`input`,{type:`text`,autoComplete:ye,...k,...J.getComboboxProps(),"aria-expanded":Y,"aria-describedby":te.joinIds(k[`aria-describedby`],A.length>0?H:void 0),"aria-errormessage":ke,"aria-details":Ae,ref:$e,disabled:v,readOnly:x,placeholder:A.length===0?_e:``,autoCapitalize:be,autoCorrect:xe,maxLength:Se,inputMode:Ce,spellCheck:we,enterKeyHint:Te,autoFocus:Ee,tabIndex:C,value:I,onChange:e=>{M&&(L(e.target.value),F||P(!0))},onKeyDown:r.composeEventHandlers(Ne,et),onKeyUp:r.composeEventHandlers(Pe,J.onKeyUp),onFocus:je,onBlur:Me,className:`min-w-15 flex-1 bg-transparent py-0.5 text-body-1 text-foreground placeholder:text-muted-foreground focus:outline-hidden`})]}),(0,m.jsx)(`span`,{role:`status`,className:`sr-only`,children:Je&&X}),(0,m.jsx)(d.ListboxSurface,{listbox:J,layerId:Ye,surfaceRef:Ze,floatingProps:Q,open:F,expanded:Y,showCheck:!1,emptyContent:I===``?void 0:(0,m.jsx)(`div`,{"aria-hidden":`true`,className:`px-3 py-1.5 text-body-1 text-muted-foreground`,children:X}),"aria-label":k[`aria-label`],"aria-labelledby":nt,children:Y&&J.items.map(e=>(0,m.jsx)(d.Option,{value:e.value,label:e.label,children:e.label},e.value))}),(0,m.jsx)(ae.HiddenInput,{name:ve,form:y,disabled:v,value:A,type:`text`,required:ze,onInvalid:K})]})};g.displayName=`TagPicker`,exports.TagPicker=g;
2
+ //# sourceMappingURL=TagPicker.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagPicker.cjs","names":["React","cn","focusRing","DismissIcon","useFieldContext","useFieldControl","isInvalidLook","useControllable","useIsClient","useAnnounce","useId","useListbox","useListboxPopup","useMergedRefs","getArrowIntent","getDirection","inputFocusWithin","joinIds","composeEventHandlers","ListboxSurface","Option","HiddenInput","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_useControllable","require_useId","require_direction","require_useMergedRefs","require_useIsClient","require_aria","require_useFieldControl","require_useAnnounce","require_styles","require_icons","require_Input","require_useFormReset","require_HiddenInput","require_useListbox","require_Option","require_usePreserveFocus","react","react_jsx_runtime","defaultRemoveLabel","label","defaultSummaryLabel","labels","defaultAddedLabel","count","defaultRemovedLabel","EMPTY","sameTags","a","b","value","index","TagRemoveButton","ref","getFallback","TagPicker","valueProp","openProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onChange","field","validates","required","readOnly","fieldProps","invalidLook","selected","setSelected","defaultValue","list","next","onValueChange","interactive","disabled","openState","setOpen","defaultOpen","onOpenChange","isClient","open","query","setQuery","wasInteractive","setWasInteractive","lockedOpen","announce","rootRef","inputRef","summaryId","labelByValue","map","option","options","labelOf","available","chosen","filter","item","unknownValues","v","getInput","focusInput","addTag","removeTag","listbox","expanded","noMatchesText","surfaceOpen","noMatches","rootMergedRef","inputMergedRef","controlRef","initial","current","form","removeButtons","from","handleInputKeyDown","event","handleTagKeyDown","buttons","intent","listLabelledBy","className","setReference","placeholder","onKeyDown","onKeyUp"],"sources":["../../../src/components/input/TagPicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport { DismissIcon } from '../../lib/icons';\nimport { focusRing, inputFocusWithin, inputInvalidWithin } from '../../lib/styles';\nimport { useAnnounce } from '../../hooks/useAnnounce';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useListbox, type ListboxItem } from '../../hooks/useListbox';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePreserveFocus } from '../../hooks/usePreserveFocus';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { isInvalidLook } from './Input';\nimport { ListboxSurface, Option, useListboxPopup } from './Option';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/** Represents a single selectable tag option. */\nexport interface TagPickerOption {\n /** Unique identifier for the option. */\n value: string;\n /** Display label for the option. */\n label: string;\n}\n\n/**\n * The TagPicker's built-in names, descriptions and announcements, for localization. Each member is\n * optional and falls back to its English default.\n */\nexport interface TagPickerLabels {\n /** Name of a tag's remove button.\n * @default (label) => `Remove ${label}`\n */\n remove?: (label: string) => string;\n /** Name of the list of selected tags.\n * @default 'Selected'\n */\n selected?: string;\n /** Description of the input that sums up the selected tags (their labels, in order).\n * @default (labels) => `Selected: ${labels.join(', ')}`\n */\n summary?: (labels: string[]) => string;\n /** Announcement when a tag is added; `count` is the number of tags after the change.\n * @default (label, count) => `${label} added, ${count} selected`\n */\n added?: (label: string, count: number) => string;\n /** Announcement when a tag is removed; `count` is the number of tags after the change.\n * @default (label, count) => `${label} removed, ${count} selected`\n */\n removed?: (label: string, count: number) => string;\n /** Status text (announced, and shown in the popup) when the typed text matches no option.\n * @default 'No matches'\n */\n noMatches?: string;\n}\n\nconst defaultRemoveLabel = (label: string) => `Remove ${label}`;\nconst defaultSummaryLabel = (labels: string[]) => `Selected: ${labels.join(', ')}`;\nconst defaultAddedLabel = (label: string, count: number) => `${label} added, ${count} selected`;\nconst defaultRemovedLabel = (label: string, count: number) => `${label} removed, ${count} selected`;\n\n/** Properties for the TagPicker component. */\nexport interface TagPickerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | RoutedHandlers\n> {\n /** Available options to choose from. */\n options: readonly TagPickerOption[];\n /** Controlled array of selected option values (`[]` for none). */\n value?: readonly string[];\n /**\n * Initial selected values for uncontrolled usage; a form reset restores them.\n * @default []\n */\n defaultValue?: readonly string[];\n /**\n * Called with the new selection when it changes: a tag is added or removed, or a form reset\n * restores different tags.\n */\n onValueChange?: (value: string[]) => void;\n /**\n * Called with the new selection when it changes: a tag is added or removed, or a form reset\n * restores different tags.\n * @deprecated Use `onValueChange`.\n */\n onChange?: (value: string[]) => void;\n /**\n * Controlled open state of the option list. The list renders only in the browser: an open\n * picker is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage. A picker that starts disabled or read-only starts\n * closed. The list renders only in the browser: it is closed in the server HTML and opens once\n * the picker has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the option list opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Placeholder text shown when no tags are selected.\n * @default 'Select...'\n */\n placeholder?: string;\n /**\n * Whether the tag picker is disabled: nothing can be added or removed, and the remove buttons\n * leave the tab order.\n * @default false\n */\n disabled?: boolean;\n /** Name of the values in form submissions (one hidden input per value). */\n name?: string;\n /** Id of the form the values belong to, when the TagPicker is outside it. */\n form?: string;\n /**\n * At least one tag is required to submit the form (native constraint validation). Like a native\n * readonly input, a `readOnly` TagPicker does not block submission.\n */\n required?: boolean;\n /**\n * The `autocomplete` attribute of the `<input role=\"combobox\">`. Browser autofill is off unless\n * you set it (for example `'on'`).\n * @default 'off'\n */\n autoComplete?: string;\n /** The maximum length of the typed text (`maxlength` of the `<input role=\"combobox\">`). */\n maxLength?: number;\n /**\n * The selection cannot be changed: the input is read-only, the tags have no remove buttons, and\n * the option list neither opens (click, keyboard, a controlled `open`) nor adds tags; Escape is\n * left to the page. Turning it (or `disabled`) on while the list is open closes it\n * (`onOpenChange(false)`); a focused remove button hands focus to the input.\n */\n readOnly?: boolean;\n /**\n * Names of the remove buttons and the tag list, the summary that describes the input, the\n * announcements and the \"No matches\" text, for localization. Unset members keep their English\n * defaults.\n */\n labels?: TagPickerLabels;\n /** Called when the `<input role=\"combobox\">` receives focus (the root keeps other handlers). */\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n /** Called when the `<input role=\"combobox\">` loses focus. */\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n /**\n * Called on a key press in the `<input role=\"combobox\">`, before the built-in listbox and tag\n * keys; `event.preventDefault()` skips them.\n */\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Called when a key is released in the `<input role=\"combobox\">`. */\n onKeyUp?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Ref to the `<input role=\"combobox\">` (the focusable element). */\n controlRef?: React.Ref<HTMLInputElement>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst EMPTY: readonly string[] = [];\n\n/** Whether two selections hold the same values in the same order. */\nfunction sameTags(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((value, index) => value === b[index]);\n}\n\ninterface TagRemoveButtonProps {\n /** The accessible name of the button. */\n label: string;\n disabled: boolean;\n onClick: () => void;\n onKeyDown: React.KeyboardEventHandler<HTMLButtonElement>;\n /** The element that receives focus when this button unmounts while focused (the input). */\n getFallback: () => HTMLElement | null;\n}\n\n/**\n * A tag's remove button. When it unmounts while focused (`readOnly` turned on, or a controlled\n * value dropped its tag), focus moves to the input instead of falling to `<body>` (C-DISABLED).\n */\nfunction TagRemoveButton({\n label,\n disabled,\n onClick,\n onKeyDown,\n getFallback,\n}: TagRemoveButtonProps) {\n const ref = React.useRef<HTMLButtonElement | null>(null);\n usePreserveFocus(ref, getFallback);\n return (\n <button\n ref={ref}\n type=\"button\"\n data-wave-tagpicker-remove=\"\"\n disabled={disabled}\n aria-label={label}\n className={cn(\n // Padding and background set here (C-NATIVE), not left to an app-wide rule.\n 'ms-0.5 inline-flex rounded-sm bg-transparent p-0 text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground disabled:cursor-not-allowed',\n focusRing,\n )}\n onClick={onClick}\n onKeyDown={onKeyDown}\n >\n <DismissIcon size={12} />\n </button>\n );\n}\n\n/**\n * A multi-select combobox that shows the selected values as removable tags. Typing filters the\n * options and makes the first match active; ArrowDown/ArrowUp move the highlight\n * (`aria-activedescendant`), Enter adds the highlighted option and keeps the list open (with\n * nothing highlighted — no typed text, or text that matches no option — Enter is left to the\n * surrounding form), Escape closes the list (and then clears the typed text). Backspace in the\n * empty input moves focus to the last tag; Backspace or Delete there removes it. Additions and\n * removals are announced (\"Cherry removed, 2 selected\"), and so is \"No matches\" for text that\n * matches no option.\n *\n * The tags form a list named \"Selected\"; the input is described by a summary of the selected\n * labels (\"Selected: Apple, Banana\"). These built-in texts are English; `labels` localizes them.\n * The `<input>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`,\n * `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp` and the text input attributes `autoComplete`,\n * `autoCapitalize`, `autoCorrect`, `maxLength`, `inputMode`, `spellCheck` and `enterKeyHint`.\n * `ref`, `className`, `style`, other `aria-*` attributes and the remaining props stay on the root\n * `<div>`. Inside a `Field` the input is labelled and described by it. The tag area shows the\n * error look whenever the input ends up `aria-invalid` (its own `aria-invalid` or a `Field`\n * error). With `name`/`required` the values take part in form submission, validation and reset.\n * Selected values without a matching option are shown with their raw value. The open list renders\n * only in the browser: an open list (`defaultOpen`, `open`) is closed in the server HTML and opens\n * once the picker has hydrated.\n */\nexport const TagPicker = (props: TagPickerProps) => {\n const {\n options,\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n open: openProp,\n defaultOpen,\n onOpenChange,\n placeholder = 'Select...',\n disabled = false,\n name,\n form,\n required,\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n maxLength,\n readOnly,\n labels,\n inputMode,\n spellCheck,\n enterKeyHint,\n autoFocus,\n tabIndex,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n ref,\n ...rest\n } = props;\n\n if (onChange !== undefined) warnDeprecated('TagPicker', 'onChange', 'onValueChange');\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\n // Like a native readonly input, a read-only TagPicker is barred from constraint validation (the\n // user could not fix it); its values are still submitted.\n const validates = isRequired && !readOnly;\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n });\n // The error look follows the resolved state: the consumer's `aria-invalid` or the Field's.\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n\n const [selected, setSelected] = useControllable<readonly string[]>(\n valueProp,\n defaultValue ?? EMPTY,\n (next) => {\n // The props are read only; the callbacks receive an array of their own.\n const list = [...next];\n onValueChange?.(list);\n onChange?.(list);\n },\n );\n const interactive = !disabled && !readOnly;\n // A picker that starts disabled or read-only never shows its list, so it starts closed (no close\n // to report later).\n const [openState, setOpen] = useControllable(\n openProp,\n (defaultOpen ?? false) && interactive,\n onOpenChange,\n );\n // The open list lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the picker shows the closed inline list and reports it closed, so\n // aria-controls and aria-activedescendant never name a missing element.\n const isClient = useIsClient();\n const open = openState && interactive && isClient;\n const [query, setQuery] = React.useState('');\n // Locking the control (readOnly/disabled) while typing drops the typed text (adjust-during-render\n // pattern, C-HOOKS).\n const [wasInteractive, setWasInteractive] = React.useState(interactive);\n if (wasInteractive !== interactive) {\n setWasInteractive(interactive);\n if (!interactive) setQuery('');\n }\n // Locking also closes the list itself, not only the derived `open`, so unlocking does not reopen\n // it without a user action. The close is reported through onOpenChange (a consumer callback from\n // an effect, C-HOOKS); a controlled `open` that stays true is still not shown while locked.\n const lockedOpen = !interactive && openState;\n React.useEffect(() => {\n if (lockedOpen) setOpen(false);\n }, [lockedOpen, setOpen]);\n const announce = useAnnounce();\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const summaryId = useId('tagpicker-summary');\n\n const labelByValue = React.useMemo(() => {\n const map = new Map<string, string>();\n for (const option of options) if (!map.has(option.value)) map.set(option.value, option.label);\n return map;\n }, [options]);\n const labelOf = (value: string) => labelByValue.get(value) ?? value;\n\n const available = React.useMemo<ListboxItem[]>(() => {\n const chosen = new Set(selected);\n return options\n .filter((option) => !chosen.has(option.value))\n .map((option) => ({ value: option.value, label: option.label }));\n }, [options, selected]);\n const filter = React.useMemo(\n () =>\n query\n ? (item: ListboxItem) => item.label.toLowerCase().includes(query.toLowerCase())\n : undefined,\n [query],\n );\n\n // Unknown values render as tags labelled by the raw value (input-pickers#22).\n const unknownValues = selected.filter((value) => !labelByValue.has(value)).join('\\u0000');\n React.useEffect(() => {\n if (!unknownValues) return;\n warnOnce(\n 'TagPicker:unknown-value',\n `TagPicker: the selected value(s) ${unknownValues\n .split('\\u0000')\n .map((v) => `\"${v}\"`)\n .join(', ')} match no option; the raw value is shown as the tag label.`,\n );\n }, [unknownValues]);\n\n const getInput = () => inputRef.current;\n const focusInput = () => inputRef.current?.focus();\n\n const addTag = (value: string) => {\n if (!interactive || selected.includes(value)) return;\n const next = [...selected, value];\n setSelected(next);\n setQuery('');\n announce((labels?.added ?? defaultAddedLabel)(labelOf(value), next.length));\n };\n\n const removeTag = (value: string) => {\n if (!interactive) return;\n const next = selected.filter((v) => v !== value);\n setSelected(next);\n announce((labels?.removed ?? defaultRemovedLabel)(labelOf(value), next.length));\n focusInput();\n };\n\n const listbox = useListbox({\n open,\n onOpenChange: (next) => setOpen(next),\n mode: 'editable',\n multiple: true,\n selectedValues: selected,\n onSelect: (value) => addTag(value),\n items: available,\n filter,\n // Typing a filter makes its first match active (as in Combobox), so Enter adds what the list\n // shows instead of submitting the form. Nothing is active on open or with the text cleared.\n autoHighlight: query ? 'first' : false,\n idPrefix: 'tagpicker-listbox',\n onClearDraft: query ? () => setQuery('') : undefined,\n });\n\n // aria-expanded only while a listbox with options is shown (input-pickers#21).\n const expanded = open && listbox.items.length > 0;\n const noMatchesText = labels?.noMatches ?? 'No matches';\n // The popup shows the options, or \"No matches\" for a query.\n const surfaceOpen = open && (expanded || query !== '');\n const noMatches = surfaceOpen && !expanded;\n const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({\n open,\n surfaceOpen,\n onDismiss: () => setOpen(false),\n rootRef,\n anchorRef: inputRef,\n });\n\n const rootMergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const inputMergedRef = useMergedRefs<HTMLInputElement>(inputRef, controlRef);\n\n useFormReset(\n inputRef,\n () => {\n // Compared by content (C-FORMS): an inline default is a new array on every render, and a\n // reset that keeps the same tags reports nothing.\n const initial = defaultValue ?? EMPTY;\n setSelected((current) => (sameTags(current, initial) ? current : [...initial]));\n setQuery('');\n },\n form,\n );\n\n /** The tags' remove buttons, found from an element inside the component (no ref read). */\n const removeButtons = (from: Element) =>\n Array.from(\n from\n .closest('[data-wave-tagpicker-control]')\n ?.querySelectorAll<HTMLButtonElement>('[data-wave-tagpicker-remove]') ?? [],\n );\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Read-only: no listbox keys at all (they would open the list, add or remove tags).\n if (!interactive) return;\n if (event.key === 'Escape' && open && !surfaceOpen && !event.nativeEvent.isComposing) {\n // Open with nothing shown (every option selected, no query): close, but leave Escape to an\n // enclosing layer (overlays#1) instead of consuming it for an invisible list.\n setOpen(false);\n return;\n }\n if (event.key === 'Backspace' && query === '' && selected.length > 0) {\n // First Backspace moves to the last tag; Backspace/Delete there removes it (input-pickers#14).\n event.preventDefault();\n removeButtons(event.currentTarget).at(-1)?.focus();\n return;\n }\n listbox.onKeyDown(event);\n };\n\n const handleTagKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>, value: string) => {\n if (!interactive) return;\n const buttons = removeButtons(event.currentTarget);\n const index = buttons.indexOf(event.currentTarget);\n if (event.key === 'Backspace' || event.key === 'Delete') {\n event.preventDefault();\n removeTag(value);\n return;\n }\n if (event.key === 'Escape') {\n // Consumed here, so an enclosing layer ignores it (spec §5.4).\n event.preventDefault();\n focusInput();\n return;\n }\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(event.currentTarget),\n });\n if (intent === 'prev' && index > 0) {\n event.preventDefault();\n buttons[index - 1].focus();\n } else if (intent === 'next') {\n event.preventDefault();\n if (index < buttons.length - 1) buttons[index + 1].focus();\n else focusInput();\n }\n };\n\n const listLabelledBy =\n fieldProps['aria-label'] === undefined\n ? (fieldProps['aria-labelledby'] ?? field?.labelId)\n : fieldProps['aria-labelledby'];\n\n return (\n <div {...rest} ref={rootMergedRef} className={cn('relative', className)}>\n <div\n ref={setReference}\n data-wave-tagpicker-control=\"\"\n role=\"group\"\n aria-disabled={disabled || undefined}\n className={cn(\n 'flex flex-wrap items-center gap-1 rounded border border-input border-b-stroke-accessible bg-background px-2 py-1.5',\n inputFocusWithin,\n invalidLook && inputInvalidWithin,\n disabled && 'cursor-not-allowed opacity-50',\n )}\n onClick={(event) => {\n if (disabled || (event.target as Element).closest('button')) return;\n focusInput();\n if (!open && interactive) setOpen(true);\n }}\n >\n {selected.length > 0 && (\n <div\n role=\"list\"\n aria-label={labels?.selected ?? 'Selected'}\n className=\"flex flex-wrap items-center gap-1\"\n >\n {selected.map((value) => {\n const label = labelOf(value);\n return (\n <div\n key={value}\n role=\"listitem\"\n className=\"inline-flex items-center gap-1 rounded bg-muted px-2 py-0.5 text-body-1 text-foreground\"\n >\n {label}\n {!readOnly && (\n <TagRemoveButton\n label={(labels?.remove ?? defaultRemoveLabel)(label)}\n disabled={disabled}\n onClick={() => removeTag(value)}\n onKeyDown={(event) => handleTagKeyDown(event, value)}\n getFallback={getInput}\n />\n )}\n </div>\n );\n })}\n </div>\n )}\n {selected.length > 0 && (\n // Describes the input. The list itself would read every \"Remove …\" button name too.\n <span id={summaryId} hidden>\n {(labels?.summary ?? defaultSummaryLabel)(selected.map(labelOf))}\n </span>\n )}\n <input\n type=\"text\"\n autoComplete={autoComplete}\n {...fieldProps}\n {...listbox.getComboboxProps()}\n aria-expanded={expanded}\n aria-describedby={joinIds(\n fieldProps['aria-describedby'],\n selected.length > 0 ? summaryId : undefined,\n )}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n ref={inputMergedRef}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={selected.length === 0 ? placeholder : ''}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n maxLength={maxLength}\n inputMode={inputMode}\n spellCheck={spellCheck}\n enterKeyHint={enterKeyHint}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n value={query}\n onChange={(event) => {\n if (!interactive) return;\n setQuery(event.target.value);\n if (!open) setOpen(true);\n }}\n onKeyDown={composeEventHandlers(onKeyDown, handleInputKeyDown)}\n onKeyUp={composeEventHandlers(onKeyUp, listbox.onKeyUp)}\n onFocus={onFocus}\n onBlur={onBlur}\n className=\"min-w-15 flex-1 bg-transparent py-0.5 text-body-1 text-foreground placeholder:text-muted-foreground focus:outline-hidden\"\n />\n </div>\n {/* Mounted before its text: a live region added together with its text is not announced by\n every screen reader. The row in the popup is the visible copy. */}\n <span role=\"status\" className=\"sr-only\">\n {noMatches && noMatchesText}\n </span>\n <ListboxSurface\n listbox={listbox}\n layerId={layerId}\n surfaceRef={surfaceRef}\n floatingProps={floatingProps}\n open={open}\n expanded={expanded}\n showCheck={false}\n emptyContent={\n query !== '' ? (\n <div aria-hidden=\"true\" className=\"px-3 py-1.5 text-body-1 text-muted-foreground\">\n {noMatchesText}\n </div>\n ) : undefined\n }\n aria-label={fieldProps['aria-label']}\n aria-labelledby={listLabelledBy}\n >\n {expanded &&\n listbox.items.map((item) => (\n <Option key={item.value} value={item.value} label={item.label}>\n {item.label}\n </Option>\n ))}\n </ListboxSurface>\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={selected}\n type=\"text\"\n required={validates}\n onInvalid={focusInput}\n />\n </div>\n );\n};\nTagPicker.displayName = 'TagPicker';\n"],"mappings":"k2BA6DA,IAAM4C,GAAsB,GAAkB,UAAUC,IAClDC,GAAuB,GAAqB,aAAaC,EAAO,KAAK,IAAI,IACzEC,IAAqB,EAAe,IAAkB,GAAGH,EAAM,UAAUI,EAAM,WAC/EC,IAAuB,EAAe,IAAkB,GAAGL,EAAM,YAAYI,EAAM,WAmGnFE,EAA2B,CAAC,EAGlC,SAASC,GAAS,EAAsB,EAA+B,CACrE,OAAOC,EAAE,SAAWC,EAAE,QAAUD,EAAE,OAAO,EAAO,IAAUE,IAAUD,EAAEE,EAAM,CAC9E,CAgBA,SAASC,GAAgB,CACvB,QACA,WACA,UACA,YACA,eACuB,CACvB,IAAMC,EAAM1D,EAAM,OAAiC,IAAI,EAEvD,OADAyC,EAAA,iBAAiBiB,EAAKC,CAAW,GAE/B,EAAAhB,EAAA,IAAA,CAAC,SAAD,CACO,MACL,KAAK,SACL,6BAA2B,GACjB,WACV,aAAYE,EACZ,UAAW5C,EAAAA,GAET,0JACAC,EAAAA,SACF,EACS,UACE,YAEX,UAAA,EAAAyC,EAAA,IAAA,CAACxC,EAAAA,YAAD,CAAa,KAAM,EAAK,CAAA,CAClB,CAAA,CAEZ,CA0BA,IAAayD,EAAa,GAA0B,CAClD,GAAM,CACJ,UACA,MAAOC,EACP,eACA,iBACA,WACA,KAAMC,GACN,eACA,gBACA,eAAc,YACd,WAAW,GACX,QACA,OACA,WACA,gBAAe,MACf,kBACA,eACA,aACA,WACA,SACA,aACA,cACA,gBACA,aACA,WACA,KACA,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,GAChB,gBAAiBC,GACjB,oBAAqBC,GACrB,eAAgBC,GAChB,WACA,UACA,aACA,WACA,cACA,aACA,OACA,GAAGC,IACDC,EAEAC,IAAa,IAAA,IAAWhD,EAAA,eAAe,YAAa,WAAY,eAAe,EAEnF,IAAMiD,EAAQrE,EAAAA,gBAAgB,EAIxBsE,IAHaC,GAAYF,GAAO,UAAY,KAGlB,CAACG,EAC3BC,EAAaxE,EAAAA,gBAAgB,CACjC,KACA,aAAc0D,EACd,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,GAGhB,gBAAiBC,IAAgBQ,CACnC,CAAC,EAEKG,GAAcxE,GAAAA,cAAc,GAAOuE,EAAW,eAAe,EAE7D,CAACE,EAAUC,GAAezE,EAAAA,gBAC9BsD,EACAoB,GAAgB9B,EACf,GAAS,CAER,IAAM+B,EAAO,CAAC,GAAGC,CAAI,EACrBC,KAAgBF,CAAI,EACpBV,IAAWU,CAAI,CACjB,CACF,EACMG,EAAc,CAACC,GAAY,CAACV,EAG5B,CAACW,EAAWC,GAAWjF,EAAAA,gBAC3BuD,IACC2B,IAAe,KAAUJ,EAC1BK,EACF,EAIMC,GAAWnF,GAAAA,YAAY,EACvBoF,EAAOL,GAAaF,GAAeM,GACnC,CAACE,EAAOC,GAAY9F,EAAM,SAAS,EAAE,EAGrC,CAAC+F,GAAgBC,IAAqBhG,EAAM,SAASqF,CAAW,EAClEU,KAAmBV,IACrBW,GAAkBX,CAAW,EACxBA,GAAaS,EAAS,EAAE,GAK/B,IAAMG,EAAa,CAACZ,GAAeE,EACnC7C,EAAM,cAAgB,CAChBuD,GAAYT,EAAQ,EAAK,CAC/B,EAAG,CAACS,EAAYT,CAAO,CAAC,EACxB,IAAMU,EAAWzF,GAAAA,YAAY,EAEvB0F,EAAUnG,EAAM,OAA8B,IAAI,EAClDoG,EAAWpG,EAAM,OAAgC,IAAI,EACrDqG,EAAY3F,EAAAA,MAAM,mBAAmB,EAErC4F,EAAetG,EAAM,YAAc,CACvC,IAAMuG,EAAM,IAAI,IAChB,IAAK,IAAMC,KAAUC,EAAcF,EAAI,IAAIC,EAAO,KAAK,GAAGD,EAAI,IAAIC,EAAO,MAAOA,EAAO,KAAK,EAC5F,OAAOD,CACT,EAAG,CAACE,CAAO,CAAC,EACNC,EAAW,GAAkBJ,EAAa,IAAI/C,CAAK,GAAKA,EAExDoD,GAAY3G,EAAM,YAA6B,CACnD,IAAM4G,EAAS,IAAI,IAAI7B,CAAQ,EAC/B,OAAO0B,EACJ,OAAQ,GAAW,CAACG,EAAO,IAAIJ,EAAO,KAAK,CAAC,CAAC,CAC7C,IAAK,IAAY,CAAE,MAAOA,EAAO,MAAO,MAAOA,EAAO,KAAM,EAAE,CACnE,EAAG,CAACC,EAAS1B,CAAQ,CAAC,EAChB8B,GAAS7G,EAAM,YAEjB6F,EACK,GAAsBiB,EAAK,MAAM,YAAY,CAAC,CAAC,SAASjB,EAAM,YAAY,CAAC,EAC5E,IAAA,GACN,CAACA,CAAK,CACR,EAGMkB,EAAgBhC,EAAS,OAAQ,GAAU,CAACuB,EAAa,IAAI/C,CAAK,CAAC,CAAC,CAAC,KAAK,IAAQ,EACxFb,EAAM,cAAgB,CACfqE,GACLvF,EAAA,SACE,0BACA,oCAAoCuF,EACjC,MAAM,IAAQ,CAAC,CACf,IAAK,GAAM,IAAIC,EAAE,EAAE,CAAC,CACpB,KAAK,IAAI,EAAE,2DAChB,CACF,EAAG,CAACD,CAAa,CAAC,EAElB,IAAME,OAAiBb,EAAS,QAC1Bc,MAAmBd,EAAS,SAAS,MAAM,EAE3Ce,GAAU,GAAkB,CAChC,GAAI,CAAC9B,GAAeN,EAAS,SAASxB,CAAK,EAAG,OAC9C,IAAM4B,EAAO,CAAC,GAAGJ,EAAUxB,CAAK,EAChCyB,EAAYG,CAAI,EAChBW,EAAS,EAAE,EACXI,GAAUnD,GAAQ,OAASC,GAAA,CAAmB0D,EAAQnD,CAAK,EAAG4B,EAAK,MAAM,CAAC,CAC5E,EAEMiC,EAAa,GAAkB,CACnC,GAAI,CAAC/B,EAAa,OAClB,IAAMF,EAAOJ,EAAS,OAAQ,GAAMiC,IAAMzD,CAAK,EAC/CyB,EAAYG,CAAI,EAChBe,GAAUnD,GAAQ,SAAWG,GAAA,CAAqBwD,EAAQnD,CAAK,EAAG4B,EAAK,MAAM,CAAC,EAC9E+B,EAAW,CACb,EAEMG,EAAU1G,GAAAA,WAAW,CACzB,OACA,aAAe,GAAS6E,EAAQL,CAAI,EACpC,KAAM,WACN,SAAU,GACV,eAAgBJ,EAChB,SAAW,GAAUoC,GAAO5D,CAAK,EACjC,MAAOoD,GACP,UAGA,cAAed,EAAQ,QAAU,GACjC,SAAU,oBACV,aAAcA,MAAcC,EAAS,EAAE,EAAI,IAAA,EAC7C,CAAC,EAGKwB,EAAW1B,GAAQyB,EAAQ,MAAM,OAAS,EAC1CE,EAAgBxE,GAAQ,WAAa,aAErCyE,EAAc5B,IAAS0B,GAAYzB,IAAU,IAC7C4B,GAAYD,GAAe,CAACF,EAC5B,CAAE,WAAS,gBAAc,cAAY,iBAAkB1G,EAAAA,gBAAgB,CAC3E,OACA,cACA,cAAiB4E,EAAQ,EAAK,EAC9B,UACA,UAAWY,CACb,CAAC,EAEKsB,GAAgB7G,EAAAA,cAA8BsF,EAASzC,EAAG,EAC1DiE,GAAiB9G,EAAAA,cAAgCuF,EAAUwB,EAAU,EAE3EvF,GAAA,aACE+D,MACM,CAGJ,IAAMyB,EAAU5C,GAAgB9B,EAChC6B,EAAa,GAAa5B,GAAS0E,EAASD,CAAO,EAAIC,EAAU,CAAC,GAAGD,CAAO,CAAE,EAC9E/B,EAAS,EAAE,CACb,EACAiC,CACF,EAGA,IAAMC,EAAiB,GACrB,MAAM,KACJC,EACG,QAAQ,+BAA+B,CAAC,EACvC,iBAAoC,8BAA8B,GAAK,CAAC,CAC9E,EAEIC,GAAsB,GAAiD,CAE3E,GAAK7C,EACL,IAAI8C,EAAM,MAAQ,UAAYvC,GAAQ,CAAC4B,GAAe,CAACW,EAAM,YAAY,YAAa,CAGpF3C,EAAQ,EAAK,EACb,MACF,CACA,GAAI2C,EAAM,MAAQ,aAAetC,IAAU,IAAMd,EAAS,OAAS,EAAG,CAEpEoD,EAAM,eAAe,EACrBH,EAAcG,EAAM,aAAa,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EACjD,MACF,CACAd,EAAQ,UAAUc,CAAK,CAPvB,CAQF,EAEMC,IAAoB,EAA+C,IAAkB,CACzF,GAAI,CAAC/C,EAAa,OAClB,IAAMgD,EAAUL,EAAcG,EAAM,aAAa,EAC3C3E,EAAQ6E,EAAQ,QAAQF,EAAM,aAAa,EACjD,GAAIA,EAAM,MAAQ,aAAeA,EAAM,MAAQ,SAAU,CACvDA,EAAM,eAAe,EACrBf,EAAU7D,CAAK,EACf,MACF,CACA,GAAI4E,EAAM,MAAQ,SAAU,CAE1BA,EAAM,eAAe,EACrBjB,EAAW,EACX,MACF,CACA,IAAMoB,EAASxH,EAAAA,eAAeqH,EAAM,IAAK,CACvC,YAAa,aACb,IAAKpH,EAAAA,aAAaoH,EAAM,aAAa,CACvC,CAAC,EACGG,IAAW,QAAU9E,EAAQ,GAC/B2E,EAAM,eAAe,EACrBE,EAAQ7E,EAAQ,EAAE,CAAC,MAAM,GAChB8E,IAAW,SACpBH,EAAM,eAAe,EACjB3E,EAAQ6E,EAAQ,OAAS,EAAGA,EAAQ7E,EAAQ,EAAE,CAAC,MAAM,EACpD0D,EAAW,EAEpB,EAEMqB,GACJ1D,EAAW,gBAAkB,IAAA,GACxBA,EAAW,oBAAsBJ,GAAO,QACzCI,EAAW,mBAEjB,OACE,EAAAlC,EAAA,KAAA,CAAC,MAAD,CAAK,GAAI2B,GAAM,IAAKoD,GAAe,UAAWzH,EAAAA,GAAG,WAAYuI,EAAS,EAAtE,SAAA,EACE,EAAA7F,EAAA,KAAA,CAAC,MAAD,CACE,IAAK8F,GACL,8BAA4B,GAC5B,KAAK,QACL,gBAAenD,GAAY,IAAA,GAC3B,UAAWrF,EAAAA,GACT,qHACAe,EAAAA,iBACA8D,IAAA,uDACAQ,GAAY,+BACd,EACA,QAAU,GAAU,CACdA,GAAa6C,EAAM,OAAmB,QAAQ,QAAQ,IAC1DjB,EAAW,EACP,CAACtB,GAAQP,GAAaG,EAAQ,EAAI,EACxC,EAfF,SAAA,CAiBGT,EAAS,OAAS,IACjB,EAAApC,EAAA,IAAA,CAAC,MAAD,CACE,KAAK,OACL,aAAYI,GAAQ,UAAY,WAChC,UAAU,oCAET,SAAAgC,EAAS,IAAK,GAAU,CACvB,IAAMlC,EAAQ6D,EAAQnD,CAAK,EAC3B,OACE,EAAAZ,EAAA,KAAA,CAAC,MAAD,CAEE,KAAK,WACL,UAAU,0FAHZ,SAAA,CAKGE,EACA,CAAC+B,IACA,EAAAjC,EAAA,IAAA,CAACc,GAAD,CACE,OAAQV,GAAQ,QAAUH,GAAA,CAAoBC,CAAK,EACzC,WACV,YAAeuE,EAAU7D,CAAK,EAC9B,UAAY,GAAU6E,GAAiBD,EAAO5E,CAAK,EACnD,YAAa0D,EACd,CAAA,CAEA,CAdE,EAAA1D,CAcF,CAET,CAAC,CACE,CAAA,EAENwB,EAAS,OAAS,IAEjB,EAAApC,EAAA,IAAA,CAAC,OAAD,CAAM,GAAI0D,EAAW,OAAA,GACjB,UAAAtD,GAAQ,SAAWD,GAAA,CAAqBiC,EAAS,IAAI2B,CAAO,CAAC,CAC3D,CAAA,GAER,EAAA/D,EAAA,IAAA,CAAC,QAAD,CACE,KAAK,OACS,gBACd,GAAIkC,EACJ,GAAIwC,EAAQ,iBAAiB,EAC7B,gBAAeC,EACf,mBAAkBrG,GAAAA,QAChB4D,EAAW,oBACXE,EAAS,OAAS,EAAIsB,EAAY,IAAA,EACpC,EACA,oBAAmBjC,GACnB,eAAcC,GACd,IAAKsD,GACK,WACA,WACV,YAAa5C,EAAS,SAAW,EAAI2D,GAAc,GACnC,kBACH,eACF,aACA,aACC,cACE,gBACH,aACD,WACV,MAAO7C,EACP,SAAW,GAAU,CACdR,IACLS,EAASqC,EAAM,OAAO,KAAK,EACtBvC,GAAMJ,EAAQ,EAAI,EACzB,EACA,UAAWtE,EAAAA,qBAAqByH,GAAWT,EAAkB,EAC7D,QAAShH,EAAAA,qBAAqB0H,GAASvB,EAAQ,OAAO,EAC7C,WACD,UACR,UAAU,0HACX,CAAA,CACE,KAGL,EAAA1E,EAAA,IAAA,CAAC,OAAD,CAAM,KAAK,SAAS,UAAU,UAC3B,SAAA8E,IAAaF,CACV,CAAA,GACN,EAAA5E,EAAA,IAAA,CAACxB,EAAAA,eAAD,CACW,UACA,WACG,cACG,gBACT,OACI,WACV,UAAW,GACX,aACE0E,IAAU,GAIN,IAAA,IAHF,EAAAlD,EAAA,IAAA,CAAC,MAAD,CAAK,cAAY,OAAO,UAAU,gDAC/B,SAAA4E,CACE,CAAA,EAGT,aAAY1C,EAAW,cACvB,kBAAiB0D,GAEhB,SAAAjB,GACCD,EAAQ,MAAM,IAAK,IACjB,EAAA1E,EAAA,IAAA,CAACvB,EAAAA,OAAD,CAAyB,MAAO0F,EAAK,MAAO,MAAOA,EAAK,MACrD,SAAAA,EAAK,KACA,EAFKA,EAAK,KAEV,CACT,CACW,CAAA,GAChB,EAAAnE,EAAA,IAAA,CAACtB,GAAAA,YAAD,CACQ,QACA,OACI,WACV,MAAO0D,EACP,KAAK,OACL,SAAUL,GACV,UAAWwC,CACZ,CAAA,CACE,GAET,EACA,EAAU,YAAc"}
@@ -0,0 +1,249 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { warnDeprecated as t, warnOnce as n } from "../../lib/dev.mjs";
4
+ import { composeEventHandlers as r } from "../../lib/composeEventHandlers.mjs";
5
+ import { useControllable as i } from "../../hooks/useControllable.mjs";
6
+ import { useId as a } from "../../hooks/useId.mjs";
7
+ import { getArrowIntent as o, getDirection as ee } from "../../lib/direction.mjs";
8
+ import { useMergedRefs as s } from "../../hooks/useMergedRefs.mjs";
9
+ import { useIsClient as te } from "../../hooks/useIsClient.mjs";
10
+ import { joinIds as c } from "../../lib/aria.mjs";
11
+ import { useFieldContext as l, useFieldControl as ne } from "../../hooks/useFieldControl.mjs";
12
+ import { useAnnounce as re } from "../../hooks/useAnnounce.mjs";
13
+ import { focusRing as u, inputFocusWithin as ie } from "../../lib/styles.mjs";
14
+ import { DismissIcon as d } from "../../lib/icons.mjs";
15
+ import { isInvalidLook as ae } from "./Input.mjs";
16
+ import { useFormReset as oe } from "../../hooks/useFormReset.mjs";
17
+ import { HiddenInput as se } from "../internal/HiddenInput.mjs";
18
+ import { useListbox as ce } from "../../hooks/useListbox.mjs";
19
+ import { ListboxSurface as le, Option as ue, useListboxPopup as de } from "./Option.mjs";
20
+ import { usePreserveFocus as f } from "../../hooks/usePreserveFocus.mjs";
21
+ import * as p from "react";
22
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
23
+ //#region src/components/input/TagPicker.tsx
24
+ var fe = (e) => `Remove ${e}`, pe = (e) => `Selected: ${e.join(", ")}`, me = (e, t) => `${e} added, ${t} selected`, he = (e, t) => `${e} removed, ${t} selected`, g = [];
25
+ function ge(e, t) {
26
+ return e.length === t.length && e.every((e, n) => e === t[n]);
27
+ }
28
+ function _e({ label: t, disabled: n, onClick: r, onKeyDown: i, getFallback: a }) {
29
+ let o = p.useRef(null);
30
+ return f(o, a), /* @__PURE__ */ m("button", {
31
+ ref: o,
32
+ type: "button",
33
+ "data-wave-tagpicker-remove": "",
34
+ disabled: n,
35
+ "aria-label": t,
36
+ className: e("ms-0.5 inline-flex rounded-sm bg-transparent p-0 text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground disabled:cursor-not-allowed", u),
37
+ onClick: r,
38
+ onKeyDown: i,
39
+ children: /* @__PURE__ */ m(d, { size: 12 })
40
+ });
41
+ }
42
+ var _ = (u) => {
43
+ let { options: d, value: f, defaultValue: _, onValueChange: ve, onChange: v, open: ye, defaultOpen: be, onOpenChange: xe, placeholder: Se = "Select...", disabled: y = !1, name: Ce, form: b, required: x, autoComplete: we = "off", autoCapitalize: Te, autoCorrect: Ee, maxLength: S, readOnly: C, labels: w, inputMode: T, spellCheck: E, enterKeyHint: D, autoFocus: De, tabIndex: Oe, id: ke, "aria-label": Ae, "aria-labelledby": je, "aria-describedby": Me, "aria-invalid": Ne, "aria-required": Pe, "aria-errormessage": Fe, "aria-details": Ie, onFocus: Le, onBlur: Re, onKeyDown: ze, onKeyUp: Be, controlRef: Ve, className: He, ref: Ue, ...We } = u;
44
+ v !== void 0 && t("TagPicker", "onChange", "onValueChange");
45
+ let O = l(), Ge = (x ?? O?.required ?? !1) && !C, k = ne({
46
+ id: ke,
47
+ "aria-label": Ae,
48
+ "aria-labelledby": je,
49
+ "aria-describedby": Me,
50
+ "aria-invalid": Ne,
51
+ "aria-required": Pe ?? x
52
+ }), Ke = ae(!1, k["aria-invalid"]), [A, j] = i(f, _ ?? g, (e) => {
53
+ let t = [...e];
54
+ ve?.(t), v?.(t);
55
+ }), M = !y && !C, [N, P] = i(ye, (be ?? !1) && M, xe), qe = te(), F = N && M && qe, [I, L] = p.useState(""), [Je, Ye] = p.useState(M);
56
+ Je !== M && (Ye(M), M || L(""));
57
+ let R = !M && N;
58
+ p.useEffect(() => {
59
+ R && P(!1);
60
+ }, [R, P]);
61
+ let z = re(), B = p.useRef(null), V = p.useRef(null), H = a("tagpicker-summary"), U = p.useMemo(() => {
62
+ let e = /* @__PURE__ */ new Map();
63
+ for (let t of d) e.has(t.value) || e.set(t.value, t.label);
64
+ return e;
65
+ }, [d]), W = (e) => U.get(e) ?? e, Xe = p.useMemo(() => {
66
+ let e = new Set(A);
67
+ return d.filter((t) => !e.has(t.value)).map((e) => ({
68
+ value: e.value,
69
+ label: e.label
70
+ }));
71
+ }, [d, A]), Ze = p.useMemo(() => I ? (e) => e.label.toLowerCase().includes(I.toLowerCase()) : void 0, [I]), G = A.filter((e) => !U.has(e)).join("\0");
72
+ p.useEffect(() => {
73
+ G && n("TagPicker:unknown-value", `TagPicker: the selected value(s) ${G.split("\0").map((e) => `"${e}"`).join(", ")} match no option; the raw value is shown as the tag label.`);
74
+ }, [G]);
75
+ let Qe = () => V.current, K = () => V.current?.focus(), $e = (e) => {
76
+ if (!M || A.includes(e)) return;
77
+ let t = [...A, e];
78
+ j(t), L(""), z((w?.added ?? me)(W(e), t.length));
79
+ }, q = (e) => {
80
+ if (!M) return;
81
+ let t = A.filter((t) => t !== e);
82
+ j(t), z((w?.removed ?? he)(W(e), t.length)), K();
83
+ }, J = ce({
84
+ open: F,
85
+ onOpenChange: (e) => P(e),
86
+ mode: "editable",
87
+ multiple: !0,
88
+ selectedValues: A,
89
+ onSelect: (e) => $e(e),
90
+ items: Xe,
91
+ filter: Ze,
92
+ autoHighlight: I ? "first" : !1,
93
+ idPrefix: "tagpicker-listbox",
94
+ onClearDraft: I ? () => L("") : void 0
95
+ }), Y = F && J.items.length > 0, X = w?.noMatches ?? "No matches", Z = F && (Y || I !== ""), Q = Z && !Y, { layerId: et, setReference: tt, surfaceRef: nt, floatingProps: rt } = de({
96
+ open: F,
97
+ surfaceOpen: Z,
98
+ onDismiss: () => P(!1),
99
+ rootRef: B,
100
+ anchorRef: V
101
+ }), it = s(B, Ue), at = s(V, Ve);
102
+ oe(V, () => {
103
+ let e = _ ?? g;
104
+ j((t) => ge(t, e) ? t : [...e]), L("");
105
+ }, b);
106
+ let $ = (e) => Array.from(e.closest("[data-wave-tagpicker-control]")?.querySelectorAll("[data-wave-tagpicker-remove]") ?? []), ot = (e) => {
107
+ if (M) {
108
+ if (e.key === "Escape" && F && !Z && !e.nativeEvent.isComposing) {
109
+ P(!1);
110
+ return;
111
+ }
112
+ if (e.key === "Backspace" && I === "" && A.length > 0) {
113
+ e.preventDefault(), $(e.currentTarget).at(-1)?.focus();
114
+ return;
115
+ }
116
+ J.onKeyDown(e);
117
+ }
118
+ }, st = (e, t) => {
119
+ if (!M) return;
120
+ let n = $(e.currentTarget), r = n.indexOf(e.currentTarget);
121
+ if (e.key === "Backspace" || e.key === "Delete") {
122
+ e.preventDefault(), q(t);
123
+ return;
124
+ }
125
+ if (e.key === "Escape") {
126
+ e.preventDefault(), K();
127
+ return;
128
+ }
129
+ let i = o(e.key, {
130
+ orientation: "horizontal",
131
+ dir: ee(e.currentTarget)
132
+ });
133
+ i === "prev" && r > 0 ? (e.preventDefault(), n[r - 1].focus()) : i === "next" && (e.preventDefault(), r < n.length - 1 ? n[r + 1].focus() : K());
134
+ }, ct = k["aria-label"] === void 0 ? k["aria-labelledby"] ?? O?.labelId : k["aria-labelledby"];
135
+ return /* @__PURE__ */ h("div", {
136
+ ...We,
137
+ ref: it,
138
+ className: e("relative", He),
139
+ children: [
140
+ /* @__PURE__ */ h("div", {
141
+ ref: tt,
142
+ "data-wave-tagpicker-control": "",
143
+ role: "group",
144
+ "aria-disabled": y || void 0,
145
+ className: e("flex flex-wrap items-center gap-1 rounded border border-input border-b-stroke-accessible bg-background px-2 py-1.5", ie, Ke && "border-destructive focus-within:border-b-destructive", y && "cursor-not-allowed opacity-50"),
146
+ onClick: (e) => {
147
+ y || e.target.closest("button") || (K(), !F && M && P(!0));
148
+ },
149
+ children: [
150
+ A.length > 0 && /* @__PURE__ */ m("div", {
151
+ role: "list",
152
+ "aria-label": w?.selected ?? "Selected",
153
+ className: "flex flex-wrap items-center gap-1",
154
+ children: A.map((e) => {
155
+ let t = W(e);
156
+ return /* @__PURE__ */ h("div", {
157
+ role: "listitem",
158
+ className: "inline-flex items-center gap-1 rounded bg-muted px-2 py-0.5 text-body-1 text-foreground",
159
+ children: [t, !C && /* @__PURE__ */ m(_e, {
160
+ label: (w?.remove ?? fe)(t),
161
+ disabled: y,
162
+ onClick: () => q(e),
163
+ onKeyDown: (t) => st(t, e),
164
+ getFallback: Qe
165
+ })]
166
+ }, e);
167
+ })
168
+ }),
169
+ A.length > 0 && /* @__PURE__ */ m("span", {
170
+ id: H,
171
+ hidden: !0,
172
+ children: (w?.summary ?? pe)(A.map(W))
173
+ }),
174
+ /* @__PURE__ */ m("input", {
175
+ type: "text",
176
+ autoComplete: we,
177
+ ...k,
178
+ ...J.getComboboxProps(),
179
+ "aria-expanded": Y,
180
+ "aria-describedby": c(k["aria-describedby"], A.length > 0 ? H : void 0),
181
+ "aria-errormessage": Fe,
182
+ "aria-details": Ie,
183
+ ref: at,
184
+ disabled: y,
185
+ readOnly: C,
186
+ placeholder: A.length === 0 ? Se : "",
187
+ autoCapitalize: Te,
188
+ autoCorrect: Ee,
189
+ maxLength: S,
190
+ inputMode: T,
191
+ spellCheck: E,
192
+ enterKeyHint: D,
193
+ autoFocus: De,
194
+ tabIndex: Oe,
195
+ value: I,
196
+ onChange: (e) => {
197
+ M && (L(e.target.value), F || P(!0));
198
+ },
199
+ onKeyDown: r(ze, ot),
200
+ onKeyUp: r(Be, J.onKeyUp),
201
+ onFocus: Le,
202
+ onBlur: Re,
203
+ className: "min-w-15 flex-1 bg-transparent py-0.5 text-body-1 text-foreground placeholder:text-muted-foreground focus:outline-hidden"
204
+ })
205
+ ]
206
+ }),
207
+ /* @__PURE__ */ m("span", {
208
+ role: "status",
209
+ className: "sr-only",
210
+ children: Q && X
211
+ }),
212
+ /* @__PURE__ */ m(le, {
213
+ listbox: J,
214
+ layerId: et,
215
+ surfaceRef: nt,
216
+ floatingProps: rt,
217
+ open: F,
218
+ expanded: Y,
219
+ showCheck: !1,
220
+ emptyContent: I === "" ? void 0 : /* @__PURE__ */ m("div", {
221
+ "aria-hidden": "true",
222
+ className: "px-3 py-1.5 text-body-1 text-muted-foreground",
223
+ children: X
224
+ }),
225
+ "aria-label": k["aria-label"],
226
+ "aria-labelledby": ct,
227
+ children: Y && J.items.map((e) => /* @__PURE__ */ m(ue, {
228
+ value: e.value,
229
+ label: e.label,
230
+ children: e.label
231
+ }, e.value))
232
+ }),
233
+ /* @__PURE__ */ m(se, {
234
+ name: Ce,
235
+ form: b,
236
+ disabled: y,
237
+ value: A,
238
+ type: "text",
239
+ required: Ge,
240
+ onInvalid: K
241
+ })
242
+ ]
243
+ });
244
+ };
245
+ _.displayName = "TagPicker";
246
+ //#endregion
247
+ export { _ as TagPicker };
248
+
249
+ //# sourceMappingURL=TagPicker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagPicker.mjs","names":["useId","useId$1","React","defaultRemoveLabel","label","defaultSummaryLabel","labels","defaultAddedLabel","count","defaultRemovedLabel","EMPTY","sameTags","a","b","value","index","TagRemoveButton","ref","usePreserveFocus","getFallback","cn","focusRing","DismissIcon","TagPicker","valueProp","openProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onChange","warnDeprecated","field","useFieldContext","validates","required","readOnly","fieldProps","useFieldControl","invalidLook","isInvalidLook","selected","setSelected","useControllable","defaultValue","list","next","onValueChange","interactive","disabled","openState","setOpen","defaultOpen","onOpenChange","isClient","useIsClient","open","query","setQuery","wasInteractive","setWasInteractive","lockedOpen","announce","useAnnounce","rootRef","inputRef","summaryId","labelByValue","map","option","options","labelOf","available","chosen","filter","item","unknownValues","warnOnce","v","getInput","focusInput","addTag","removeTag","listbox","useListbox","expanded","noMatchesText","surfaceOpen","noMatches","useListboxPopup","rootMergedRef","useMergedRefs","inputMergedRef","controlRef","initial","current","form","removeButtons","from","handleInputKeyDown","event","handleTagKeyDown","buttons","intent","getArrowIntent","getDirection","listLabelledBy","className","setReference","inputFocusWithin","joinIds","placeholder","composeEventHandlers","onKeyDown","onKeyUp","ListboxSurface","Option","HiddenInput"],"sources":["../../../src/components/input/TagPicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport { DismissIcon } from '../../lib/icons';\nimport { focusRing, inputFocusWithin, inputInvalidWithin } from '../../lib/styles';\nimport { useAnnounce } from '../../hooks/useAnnounce';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useListbox, type ListboxItem } from '../../hooks/useListbox';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePreserveFocus } from '../../hooks/usePreserveFocus';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { isInvalidLook } from './Input';\nimport { ListboxSurface, Option, useListboxPopup } from './Option';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/** Represents a single selectable tag option. */\nexport interface TagPickerOption {\n /** Unique identifier for the option. */\n value: string;\n /** Display label for the option. */\n label: string;\n}\n\n/**\n * The TagPicker's built-in names, descriptions and announcements, for localization. Each member is\n * optional and falls back to its English default.\n */\nexport interface TagPickerLabels {\n /** Name of a tag's remove button.\n * @default (label) => `Remove ${label}`\n */\n remove?: (label: string) => string;\n /** Name of the list of selected tags.\n * @default 'Selected'\n */\n selected?: string;\n /** Description of the input that sums up the selected tags (their labels, in order).\n * @default (labels) => `Selected: ${labels.join(', ')}`\n */\n summary?: (labels: string[]) => string;\n /** Announcement when a tag is added; `count` is the number of tags after the change.\n * @default (label, count) => `${label} added, ${count} selected`\n */\n added?: (label: string, count: number) => string;\n /** Announcement when a tag is removed; `count` is the number of tags after the change.\n * @default (label, count) => `${label} removed, ${count} selected`\n */\n removed?: (label: string, count: number) => string;\n /** Status text (announced, and shown in the popup) when the typed text matches no option.\n * @default 'No matches'\n */\n noMatches?: string;\n}\n\nconst defaultRemoveLabel = (label: string) => `Remove ${label}`;\nconst defaultSummaryLabel = (labels: string[]) => `Selected: ${labels.join(', ')}`;\nconst defaultAddedLabel = (label: string, count: number) => `${label} added, ${count} selected`;\nconst defaultRemovedLabel = (label: string, count: number) => `${label} removed, ${count} selected`;\n\n/** Properties for the TagPicker component. */\nexport interface TagPickerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | RoutedHandlers\n> {\n /** Available options to choose from. */\n options: readonly TagPickerOption[];\n /** Controlled array of selected option values (`[]` for none). */\n value?: readonly string[];\n /**\n * Initial selected values for uncontrolled usage; a form reset restores them.\n * @default []\n */\n defaultValue?: readonly string[];\n /**\n * Called with the new selection when it changes: a tag is added or removed, or a form reset\n * restores different tags.\n */\n onValueChange?: (value: string[]) => void;\n /**\n * Called with the new selection when it changes: a tag is added or removed, or a form reset\n * restores different tags.\n * @deprecated Use `onValueChange`.\n */\n onChange?: (value: string[]) => void;\n /**\n * Controlled open state of the option list. The list renders only in the browser: an open\n * picker is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Initial open state for uncontrolled usage. A picker that starts disabled or read-only starts\n * closed. The list renders only in the browser: it is closed in the server HTML and opens once\n * the picker has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the option list opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Placeholder text shown when no tags are selected.\n * @default 'Select...'\n */\n placeholder?: string;\n /**\n * Whether the tag picker is disabled: nothing can be added or removed, and the remove buttons\n * leave the tab order.\n * @default false\n */\n disabled?: boolean;\n /** Name of the values in form submissions (one hidden input per value). */\n name?: string;\n /** Id of the form the values belong to, when the TagPicker is outside it. */\n form?: string;\n /**\n * At least one tag is required to submit the form (native constraint validation). Like a native\n * readonly input, a `readOnly` TagPicker does not block submission.\n */\n required?: boolean;\n /**\n * The `autocomplete` attribute of the `<input role=\"combobox\">`. Browser autofill is off unless\n * you set it (for example `'on'`).\n * @default 'off'\n */\n autoComplete?: string;\n /** The maximum length of the typed text (`maxlength` of the `<input role=\"combobox\">`). */\n maxLength?: number;\n /**\n * The selection cannot be changed: the input is read-only, the tags have no remove buttons, and\n * the option list neither opens (click, keyboard, a controlled `open`) nor adds tags; Escape is\n * left to the page. Turning it (or `disabled`) on while the list is open closes it\n * (`onOpenChange(false)`); a focused remove button hands focus to the input.\n */\n readOnly?: boolean;\n /**\n * Names of the remove buttons and the tag list, the summary that describes the input, the\n * announcements and the \"No matches\" text, for localization. Unset members keep their English\n * defaults.\n */\n labels?: TagPickerLabels;\n /** Called when the `<input role=\"combobox\">` receives focus (the root keeps other handlers). */\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n /** Called when the `<input role=\"combobox\">` loses focus. */\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n /**\n * Called on a key press in the `<input role=\"combobox\">`, before the built-in listbox and tag\n * keys; `event.preventDefault()` skips them.\n */\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Called when a key is released in the `<input role=\"combobox\">`. */\n onKeyUp?: React.KeyboardEventHandler<HTMLInputElement>;\n /** Ref to the `<input role=\"combobox\">` (the focusable element). */\n controlRef?: React.Ref<HTMLInputElement>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst EMPTY: readonly string[] = [];\n\n/** Whether two selections hold the same values in the same order. */\nfunction sameTags(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((value, index) => value === b[index]);\n}\n\ninterface TagRemoveButtonProps {\n /** The accessible name of the button. */\n label: string;\n disabled: boolean;\n onClick: () => void;\n onKeyDown: React.KeyboardEventHandler<HTMLButtonElement>;\n /** The element that receives focus when this button unmounts while focused (the input). */\n getFallback: () => HTMLElement | null;\n}\n\n/**\n * A tag's remove button. When it unmounts while focused (`readOnly` turned on, or a controlled\n * value dropped its tag), focus moves to the input instead of falling to `<body>` (C-DISABLED).\n */\nfunction TagRemoveButton({\n label,\n disabled,\n onClick,\n onKeyDown,\n getFallback,\n}: TagRemoveButtonProps) {\n const ref = React.useRef<HTMLButtonElement | null>(null);\n usePreserveFocus(ref, getFallback);\n return (\n <button\n ref={ref}\n type=\"button\"\n data-wave-tagpicker-remove=\"\"\n disabled={disabled}\n aria-label={label}\n className={cn(\n // Padding and background set here (C-NATIVE), not left to an app-wide rule.\n 'ms-0.5 inline-flex rounded-sm bg-transparent p-0 text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground disabled:cursor-not-allowed',\n focusRing,\n )}\n onClick={onClick}\n onKeyDown={onKeyDown}\n >\n <DismissIcon size={12} />\n </button>\n );\n}\n\n/**\n * A multi-select combobox that shows the selected values as removable tags. Typing filters the\n * options and makes the first match active; ArrowDown/ArrowUp move the highlight\n * (`aria-activedescendant`), Enter adds the highlighted option and keeps the list open (with\n * nothing highlighted — no typed text, or text that matches no option — Enter is left to the\n * surrounding form), Escape closes the list (and then clears the typed text). Backspace in the\n * empty input moves focus to the last tag; Backspace or Delete there removes it. Additions and\n * removals are announced (\"Cherry removed, 2 selected\"), and so is \"No matches\" for text that\n * matches no option.\n *\n * The tags form a list named \"Selected\"; the input is described by a summary of the selected\n * labels (\"Selected: Apple, Banana\"). These built-in texts are English; `labels` localizes them.\n * The `<input>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`,\n * `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp` and the text input attributes `autoComplete`,\n * `autoCapitalize`, `autoCorrect`, `maxLength`, `inputMode`, `spellCheck` and `enterKeyHint`.\n * `ref`, `className`, `style`, other `aria-*` attributes and the remaining props stay on the root\n * `<div>`. Inside a `Field` the input is labelled and described by it. The tag area shows the\n * error look whenever the input ends up `aria-invalid` (its own `aria-invalid` or a `Field`\n * error). With `name`/`required` the values take part in form submission, validation and reset.\n * Selected values without a matching option are shown with their raw value. The open list renders\n * only in the browser: an open list (`defaultOpen`, `open`) is closed in the server HTML and opens\n * once the picker has hydrated.\n */\nexport const TagPicker = (props: TagPickerProps) => {\n const {\n options,\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n open: openProp,\n defaultOpen,\n onOpenChange,\n placeholder = 'Select...',\n disabled = false,\n name,\n form,\n required,\n autoComplete = 'off',\n autoCapitalize,\n autoCorrect,\n maxLength,\n readOnly,\n labels,\n inputMode,\n spellCheck,\n enterKeyHint,\n autoFocus,\n tabIndex,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n ref,\n ...rest\n } = props;\n\n if (onChange !== undefined) warnDeprecated('TagPicker', 'onChange', 'onValueChange');\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\n // Like a native readonly input, a read-only TagPicker is barred from constraint validation (the\n // user could not fix it); its values are still submitted.\n const validates = isRequired && !readOnly;\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n });\n // The error look follows the resolved state: the consumer's `aria-invalid` or the Field's.\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n\n const [selected, setSelected] = useControllable<readonly string[]>(\n valueProp,\n defaultValue ?? EMPTY,\n (next) => {\n // The props are read only; the callbacks receive an array of their own.\n const list = [...next];\n onValueChange?.(list);\n onChange?.(list);\n },\n );\n const interactive = !disabled && !readOnly;\n // A picker that starts disabled or read-only never shows its list, so it starts closed (no close\n // to report later).\n const [openState, setOpen] = useControllable(\n openProp,\n (defaultOpen ?? false) && interactive,\n onOpenChange,\n );\n // The open list lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the picker shows the closed inline list and reports it closed, so\n // aria-controls and aria-activedescendant never name a missing element.\n const isClient = useIsClient();\n const open = openState && interactive && isClient;\n const [query, setQuery] = React.useState('');\n // Locking the control (readOnly/disabled) while typing drops the typed text (adjust-during-render\n // pattern, C-HOOKS).\n const [wasInteractive, setWasInteractive] = React.useState(interactive);\n if (wasInteractive !== interactive) {\n setWasInteractive(interactive);\n if (!interactive) setQuery('');\n }\n // Locking also closes the list itself, not only the derived `open`, so unlocking does not reopen\n // it without a user action. The close is reported through onOpenChange (a consumer callback from\n // an effect, C-HOOKS); a controlled `open` that stays true is still not shown while locked.\n const lockedOpen = !interactive && openState;\n React.useEffect(() => {\n if (lockedOpen) setOpen(false);\n }, [lockedOpen, setOpen]);\n const announce = useAnnounce();\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const summaryId = useId('tagpicker-summary');\n\n const labelByValue = React.useMemo(() => {\n const map = new Map<string, string>();\n for (const option of options) if (!map.has(option.value)) map.set(option.value, option.label);\n return map;\n }, [options]);\n const labelOf = (value: string) => labelByValue.get(value) ?? value;\n\n const available = React.useMemo<ListboxItem[]>(() => {\n const chosen = new Set(selected);\n return options\n .filter((option) => !chosen.has(option.value))\n .map((option) => ({ value: option.value, label: option.label }));\n }, [options, selected]);\n const filter = React.useMemo(\n () =>\n query\n ? (item: ListboxItem) => item.label.toLowerCase().includes(query.toLowerCase())\n : undefined,\n [query],\n );\n\n // Unknown values render as tags labelled by the raw value (input-pickers#22).\n const unknownValues = selected.filter((value) => !labelByValue.has(value)).join('\\u0000');\n React.useEffect(() => {\n if (!unknownValues) return;\n warnOnce(\n 'TagPicker:unknown-value',\n `TagPicker: the selected value(s) ${unknownValues\n .split('\\u0000')\n .map((v) => `\"${v}\"`)\n .join(', ')} match no option; the raw value is shown as the tag label.`,\n );\n }, [unknownValues]);\n\n const getInput = () => inputRef.current;\n const focusInput = () => inputRef.current?.focus();\n\n const addTag = (value: string) => {\n if (!interactive || selected.includes(value)) return;\n const next = [...selected, value];\n setSelected(next);\n setQuery('');\n announce((labels?.added ?? defaultAddedLabel)(labelOf(value), next.length));\n };\n\n const removeTag = (value: string) => {\n if (!interactive) return;\n const next = selected.filter((v) => v !== value);\n setSelected(next);\n announce((labels?.removed ?? defaultRemovedLabel)(labelOf(value), next.length));\n focusInput();\n };\n\n const listbox = useListbox({\n open,\n onOpenChange: (next) => setOpen(next),\n mode: 'editable',\n multiple: true,\n selectedValues: selected,\n onSelect: (value) => addTag(value),\n items: available,\n filter,\n // Typing a filter makes its first match active (as in Combobox), so Enter adds what the list\n // shows instead of submitting the form. Nothing is active on open or with the text cleared.\n autoHighlight: query ? 'first' : false,\n idPrefix: 'tagpicker-listbox',\n onClearDraft: query ? () => setQuery('') : undefined,\n });\n\n // aria-expanded only while a listbox with options is shown (input-pickers#21).\n const expanded = open && listbox.items.length > 0;\n const noMatchesText = labels?.noMatches ?? 'No matches';\n // The popup shows the options, or \"No matches\" for a query.\n const surfaceOpen = open && (expanded || query !== '');\n const noMatches = surfaceOpen && !expanded;\n const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({\n open,\n surfaceOpen,\n onDismiss: () => setOpen(false),\n rootRef,\n anchorRef: inputRef,\n });\n\n const rootMergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const inputMergedRef = useMergedRefs<HTMLInputElement>(inputRef, controlRef);\n\n useFormReset(\n inputRef,\n () => {\n // Compared by content (C-FORMS): an inline default is a new array on every render, and a\n // reset that keeps the same tags reports nothing.\n const initial = defaultValue ?? EMPTY;\n setSelected((current) => (sameTags(current, initial) ? current : [...initial]));\n setQuery('');\n },\n form,\n );\n\n /** The tags' remove buttons, found from an element inside the component (no ref read). */\n const removeButtons = (from: Element) =>\n Array.from(\n from\n .closest('[data-wave-tagpicker-control]')\n ?.querySelectorAll<HTMLButtonElement>('[data-wave-tagpicker-remove]') ?? [],\n );\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Read-only: no listbox keys at all (they would open the list, add or remove tags).\n if (!interactive) return;\n if (event.key === 'Escape' && open && !surfaceOpen && !event.nativeEvent.isComposing) {\n // Open with nothing shown (every option selected, no query): close, but leave Escape to an\n // enclosing layer (overlays#1) instead of consuming it for an invisible list.\n setOpen(false);\n return;\n }\n if (event.key === 'Backspace' && query === '' && selected.length > 0) {\n // First Backspace moves to the last tag; Backspace/Delete there removes it (input-pickers#14).\n event.preventDefault();\n removeButtons(event.currentTarget).at(-1)?.focus();\n return;\n }\n listbox.onKeyDown(event);\n };\n\n const handleTagKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>, value: string) => {\n if (!interactive) return;\n const buttons = removeButtons(event.currentTarget);\n const index = buttons.indexOf(event.currentTarget);\n if (event.key === 'Backspace' || event.key === 'Delete') {\n event.preventDefault();\n removeTag(value);\n return;\n }\n if (event.key === 'Escape') {\n // Consumed here, so an enclosing layer ignores it (spec §5.4).\n event.preventDefault();\n focusInput();\n return;\n }\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(event.currentTarget),\n });\n if (intent === 'prev' && index > 0) {\n event.preventDefault();\n buttons[index - 1].focus();\n } else if (intent === 'next') {\n event.preventDefault();\n if (index < buttons.length - 1) buttons[index + 1].focus();\n else focusInput();\n }\n };\n\n const listLabelledBy =\n fieldProps['aria-label'] === undefined\n ? (fieldProps['aria-labelledby'] ?? field?.labelId)\n : fieldProps['aria-labelledby'];\n\n return (\n <div {...rest} ref={rootMergedRef} className={cn('relative', className)}>\n <div\n ref={setReference}\n data-wave-tagpicker-control=\"\"\n role=\"group\"\n aria-disabled={disabled || undefined}\n className={cn(\n 'flex flex-wrap items-center gap-1 rounded border border-input border-b-stroke-accessible bg-background px-2 py-1.5',\n inputFocusWithin,\n invalidLook && inputInvalidWithin,\n disabled && 'cursor-not-allowed opacity-50',\n )}\n onClick={(event) => {\n if (disabled || (event.target as Element).closest('button')) return;\n focusInput();\n if (!open && interactive) setOpen(true);\n }}\n >\n {selected.length > 0 && (\n <div\n role=\"list\"\n aria-label={labels?.selected ?? 'Selected'}\n className=\"flex flex-wrap items-center gap-1\"\n >\n {selected.map((value) => {\n const label = labelOf(value);\n return (\n <div\n key={value}\n role=\"listitem\"\n className=\"inline-flex items-center gap-1 rounded bg-muted px-2 py-0.5 text-body-1 text-foreground\"\n >\n {label}\n {!readOnly && (\n <TagRemoveButton\n label={(labels?.remove ?? defaultRemoveLabel)(label)}\n disabled={disabled}\n onClick={() => removeTag(value)}\n onKeyDown={(event) => handleTagKeyDown(event, value)}\n getFallback={getInput}\n />\n )}\n </div>\n );\n })}\n </div>\n )}\n {selected.length > 0 && (\n // Describes the input. The list itself would read every \"Remove …\" button name too.\n <span id={summaryId} hidden>\n {(labels?.summary ?? defaultSummaryLabel)(selected.map(labelOf))}\n </span>\n )}\n <input\n type=\"text\"\n autoComplete={autoComplete}\n {...fieldProps}\n {...listbox.getComboboxProps()}\n aria-expanded={expanded}\n aria-describedby={joinIds(\n fieldProps['aria-describedby'],\n selected.length > 0 ? summaryId : undefined,\n )}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n ref={inputMergedRef}\n disabled={disabled}\n readOnly={readOnly}\n placeholder={selected.length === 0 ? placeholder : ''}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n maxLength={maxLength}\n inputMode={inputMode}\n spellCheck={spellCheck}\n enterKeyHint={enterKeyHint}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n value={query}\n onChange={(event) => {\n if (!interactive) return;\n setQuery(event.target.value);\n if (!open) setOpen(true);\n }}\n onKeyDown={composeEventHandlers(onKeyDown, handleInputKeyDown)}\n onKeyUp={composeEventHandlers(onKeyUp, listbox.onKeyUp)}\n onFocus={onFocus}\n onBlur={onBlur}\n className=\"min-w-15 flex-1 bg-transparent py-0.5 text-body-1 text-foreground placeholder:text-muted-foreground focus:outline-hidden\"\n />\n </div>\n {/* Mounted before its text: a live region added together with its text is not announced by\n every screen reader. The row in the popup is the visible copy. */}\n <span role=\"status\" className=\"sr-only\">\n {noMatches && noMatchesText}\n </span>\n <ListboxSurface\n listbox={listbox}\n layerId={layerId}\n surfaceRef={surfaceRef}\n floatingProps={floatingProps}\n open={open}\n expanded={expanded}\n showCheck={false}\n emptyContent={\n query !== '' ? (\n <div aria-hidden=\"true\" className=\"px-3 py-1.5 text-body-1 text-muted-foreground\">\n {noMatchesText}\n </div>\n ) : undefined\n }\n aria-label={fieldProps['aria-label']}\n aria-labelledby={listLabelledBy}\n >\n {expanded &&\n listbox.items.map((item) => (\n <Option key={item.value} value={item.value} label={item.label}>\n {item.label}\n </Option>\n ))}\n </ListboxSurface>\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={selected}\n type=\"text\"\n required={validates}\n onInvalid={focusInput}\n />\n </div>\n );\n};\nTagPicker.displayName = 'TagPicker';\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/aria.cjs"),r=require("../../hooks/useFieldControl.cjs"),i=require("../../lib/styles.cjs"),a=require("./Input.cjs");let o=require("react");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=({error:e,errorMessageProps:o,className:c,ref:l,id:u,"aria-label":d,"aria-labelledby":f,"aria-describedby":p,"aria-invalid":m,"aria-required":h,"aria-errormessage":g,required:_,...v})=>{let{invalid:y,messageId:b,message:x}=a.useControlErrorMessage(e,o,m),S=r.useFieldControl({id:u,"aria-label":d,"aria-labelledby":f,"aria-describedby":n.joinIds(p,b),"aria-invalid":m??(y||void 0),"aria-required":h,required:_},{nativeRequired:!0}),C=a.isInvalidLook(y,S[`aria-invalid`]),w=(0,s.jsx)(`textarea`,{ref:l,className:t.cn(`min-h-20 w-full resize-y rounded border border-input border-b-stroke-accessible bg-background px-3 py-2 text-body-1 text-foreground`,`placeholder:text-muted-foreground`,i.inputFocus,`disabled:cursor-not-allowed disabled:opacity-50`,C&&`border-destructive focus:border-b-destructive`,c),...v,...S,"aria-errormessage":n.joinIds(g,b)});return x?(0,s.jsxs)(s.Fragment,{children:[w,x]}):w};c.displayName=`Textarea`,exports.Textarea=c;
2
+ //# sourceMappingURL=Textarea.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.cjs","names":["useControlErrorMessage","useFieldControl","joinIds","isInvalidLook","cn","inputFocus","_Fragment","require_runtime","require_cn","require_aria","require_useFieldControl","require_styles","require_Input","react","react_jsx_runtime","Textarea","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","props","error","errorMessageProps","fieldProps","messageId","invalid","invalidLook","control","className","message"],"sources":["../../../src/components/input/Textarea.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { inputFocus, inputInvalid } from '../../lib/styles';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { isInvalidLook, useControlErrorMessage, type InputErrorMessageProps } from './Input';\n\n/** Properties for the Textarea component. */\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n /**\n * Validation error.\n * - A non-empty string renders the message in a `role=\"alert\"` element **after** the textarea\n * (a sibling, so `ref` and `className` stay on the textarea) and links it through\n * `aria-describedby` and `aria-errormessage`. Inside a `Field` that renders its own `error`,\n * the message is not repeated.\n * - `true` only marks the textarea invalid (`aria-invalid` and the error border), as in 0.4.\n *\n * The error border also shows whenever the textarea ends up `aria-invalid=\"true\"` without this\n * prop (an `error` on the surrounding `Field`, or your own `aria-invalid`).\n * Your own `aria-invalid={false}` (or `\"false\"`) wins over this prop: the textarea is reported\n * valid and shows neither the error border nor the message.\n */\n error?: string | boolean;\n /** Props of the error message element (`id`, `className`, …) rendered for a string `error`. */\n errorMessageProps?: InputErrorMessageProps;\n /** Ref to the `<textarea>` element. */\n ref?: React.Ref<HTMLTextAreaElement>;\n}\n\n/**\n * A multi-line text input with Fluent styling (vertical resize, accessible bottom stroke, primary\n * bottom border while focused). Inside a `Field` it picks up the label, hint, error, `required`\n * (native attribute) and invalid state automatically.\n *\n * @example\n * <Field label=\"Description\" hint=\"Markdown is supported\">\n * <Textarea rows={4} />\n * </Field>\n */\nexport const Textarea = ({\n error,\n errorMessageProps,\n className,\n ref,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n required,\n ...props\n}: TextareaProps) => {\n const { invalid, messageId, message } = useControlErrorMessage(\n error,\n errorMessageProps,\n ariaInvalid,\n );\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': joinIds(ariaDescribedBy, messageId),\n 'aria-invalid': ariaInvalid ?? (invalid || undefined),\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n const invalidLook = isInvalidLook(invalid, fieldProps['aria-invalid']);\n\n const control = (\n <textarea\n ref={ref}\n className={cn(\n 'min-h-20 w-full resize-y rounded border border-input border-b-stroke-accessible bg-background px-3 py-2 text-body-1 text-foreground',\n 'placeholder:text-muted-foreground',\n inputFocus,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalidLook && inputInvalid,\n className,\n )}\n {...props}\n {...fieldProps}\n aria-errormessage={joinIds(ariaErrorMessage, messageId)}\n />\n );\n\n if (!message) return control;\n return (\n <>\n {control}\n {message}\n </>\n );\n};\n\nTextarea.displayName = 'Textarea';\n"],"mappings":"sTAuCA,IAAae,GAAY,CACvB,QACA,oBACA,YACA,MACA,KACA,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,EAChB,gBAAiBC,EACjB,oBAAqBC,EACrB,WACA,GAAGC,KACgB,CACnB,GAAM,CAAE,UAAS,YAAW,WAAYtB,EAAAA,uBACtCuB,EACAC,EACAL,CACF,EACMM,EAAaxB,EAAAA,gBACjB,CACE,KACA,aAAce,EACd,kBAAmBC,EACnB,mBAAoBf,EAAAA,QAAQgB,EAAiBQ,CAAS,EACtD,eAAgBP,IAAgBQ,GAAW,IAAA,IAC3C,gBAAiBP,EACjB,UACF,EACA,CAAE,eAAgB,EAAK,CACzB,EACMQ,EAAczB,EAAAA,cAAcwB,EAASF,EAAW,eAAe,EAE/DI,GACJ,EAAAf,EAAA,IAAA,CAAC,WAAD,CACO,MACL,UAAWV,EAAAA,GACT,sIACA,oCACAC,EAAAA,WACA,kDACAuB,GAAA,gDACAE,CACF,EACA,GAAIR,EACJ,GAAIG,EACJ,oBAAmBvB,EAAAA,QAAQmB,EAAkBK,CAAS,CACvD,CAAA,EAIH,OADKK,GAEH,EAAAjB,EAAA,KAAA,CAAAR,EAAAA,SAAA,CAAA,SAAA,CACGuB,EACAE,CACD,CAAA,CAAA,EALiBF,CAOvB,EAEA,EAAS,YAAc"}