@mortenbrudvik/waveui 0.7.0 → 0.9.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 (439) hide show
  1. package/README.md +564 -155
  2. package/dist/components/button/Button.cjs +1 -1
  3. package/dist/components/button/Button.cjs.map +1 -1
  4. package/dist/components/button/Button.mjs +36 -35
  5. package/dist/components/button/Button.mjs.map +1 -1
  6. package/dist/components/button/Button.slots.cjs +1 -1
  7. package/dist/components/button/Button.slots.cjs.map +1 -1
  8. package/dist/components/button/Button.slots.mjs +31 -21
  9. package/dist/components/button/Button.slots.mjs.map +1 -1
  10. package/dist/components/button/CompoundButton.cjs +1 -1
  11. package/dist/components/button/CompoundButton.cjs.map +1 -1
  12. package/dist/components/button/CompoundButton.mjs +31 -29
  13. package/dist/components/button/CompoundButton.mjs.map +1 -1
  14. package/dist/components/button/Link.cjs +1 -1
  15. package/dist/components/button/Link.cjs.map +1 -1
  16. package/dist/components/button/Link.mjs +24 -23
  17. package/dist/components/button/Link.mjs.map +1 -1
  18. package/dist/components/button/MenuButton.cjs +1 -1
  19. package/dist/components/button/MenuButton.cjs.map +1 -1
  20. package/dist/components/button/MenuButton.mjs +29 -28
  21. package/dist/components/button/MenuButton.mjs.map +1 -1
  22. package/dist/components/button/SplitButton.cjs +1 -1
  23. package/dist/components/button/SplitButton.cjs.map +1 -1
  24. package/dist/components/button/SplitButton.mjs +46 -45
  25. package/dist/components/button/SplitButton.mjs.map +1 -1
  26. package/dist/components/button/ToggleButton.cjs +1 -1
  27. package/dist/components/button/ToggleButton.cjs.map +1 -1
  28. package/dist/components/button/ToggleButton.mjs +38 -35
  29. package/dist/components/button/ToggleButton.mjs.map +1 -1
  30. package/dist/components/button/Toolbar.cjs +1 -1
  31. package/dist/components/button/Toolbar.cjs.map +1 -1
  32. package/dist/components/button/Toolbar.mjs +43 -42
  33. package/dist/components/button/Toolbar.mjs.map +1 -1
  34. package/dist/components/button/Toolbar.parts.cjs +1 -1
  35. package/dist/components/button/Toolbar.parts.cjs.map +1 -1
  36. package/dist/components/button/Toolbar.parts.mjs +76 -81
  37. package/dist/components/button/Toolbar.parts.mjs.map +1 -1
  38. package/dist/components/data-display/Avatar.cjs +1 -1
  39. package/dist/components/data-display/Avatar.cjs.map +1 -1
  40. package/dist/components/data-display/Avatar.mjs +72 -67
  41. package/dist/components/data-display/Avatar.mjs.map +1 -1
  42. package/dist/components/data-display/AvatarGroup.cjs +1 -1
  43. package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
  44. package/dist/components/data-display/AvatarGroup.mjs +89 -88
  45. package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
  46. package/dist/components/data-display/Badge.cjs +1 -1
  47. package/dist/components/data-display/Badge.cjs.map +1 -1
  48. package/dist/components/data-display/Badge.mjs +17 -16
  49. package/dist/components/data-display/Badge.mjs.map +1 -1
  50. package/dist/components/data-display/CounterBadge.cjs +1 -1
  51. package/dist/components/data-display/CounterBadge.cjs.map +1 -1
  52. package/dist/components/data-display/CounterBadge.mjs +18 -17
  53. package/dist/components/data-display/CounterBadge.mjs.map +1 -1
  54. package/dist/components/data-display/Divider.cjs +1 -1
  55. package/dist/components/data-display/Divider.cjs.map +1 -1
  56. package/dist/components/data-display/Divider.mjs +31 -30
  57. package/dist/components/data-display/Divider.mjs.map +1 -1
  58. package/dist/components/data-display/Image.cjs +1 -1
  59. package/dist/components/data-display/Image.cjs.map +1 -1
  60. package/dist/components/data-display/Image.mjs +16 -15
  61. package/dist/components/data-display/Image.mjs.map +1 -1
  62. package/dist/components/data-display/InfoButton.cjs +2 -0
  63. package/dist/components/data-display/InfoButton.cjs.map +1 -0
  64. package/dist/components/data-display/InfoButton.mjs +173 -0
  65. package/dist/components/data-display/InfoButton.mjs.map +1 -0
  66. package/dist/components/data-display/InfoLabel.cjs +1 -1
  67. package/dist/components/data-display/InfoLabel.cjs.map +1 -1
  68. package/dist/components/data-display/InfoLabel.mjs +36 -92
  69. package/dist/components/data-display/InfoLabel.mjs.map +1 -1
  70. package/dist/components/data-display/List.cjs +1 -1
  71. package/dist/components/data-display/List.cjs.map +1 -1
  72. package/dist/components/data-display/List.mjs +175 -174
  73. package/dist/components/data-display/List.mjs.map +1 -1
  74. package/dist/components/data-display/Persona.cjs +1 -1
  75. package/dist/components/data-display/Persona.cjs.map +1 -1
  76. package/dist/components/data-display/Persona.mjs +31 -29
  77. package/dist/components/data-display/Persona.mjs.map +1 -1
  78. package/dist/components/data-display/PresenceBadge.cjs +1 -1
  79. package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
  80. package/dist/components/data-display/PresenceBadge.mjs +25 -24
  81. package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
  82. package/dist/components/data-display/Tag.cjs +1 -1
  83. package/dist/components/data-display/Tag.cjs.map +1 -1
  84. package/dist/components/data-display/Tag.mjs +87 -82
  85. package/dist/components/data-display/Tag.mjs.map +1 -1
  86. package/dist/components/feedback/MessageBar.cjs +1 -1
  87. package/dist/components/feedback/MessageBar.cjs.map +1 -1
  88. package/dist/components/feedback/MessageBar.mjs +129 -71
  89. package/dist/components/feedback/MessageBar.mjs.map +1 -1
  90. package/dist/components/feedback/MessageBar.parts.cjs +2 -0
  91. package/dist/components/feedback/MessageBar.parts.cjs.map +1 -0
  92. package/dist/components/feedback/MessageBar.parts.mjs +84 -0
  93. package/dist/components/feedback/MessageBar.parts.mjs.map +1 -0
  94. package/dist/components/feedback/MessageBar.reflow.cjs +2 -0
  95. package/dist/components/feedback/MessageBar.reflow.cjs.map +1 -0
  96. package/dist/components/feedback/MessageBar.reflow.mjs +74 -0
  97. package/dist/components/feedback/MessageBar.reflow.mjs.map +1 -0
  98. package/dist/components/feedback/MessageBar.status.cjs +1 -1
  99. package/dist/components/feedback/MessageBar.status.cjs.map +1 -1
  100. package/dist/components/feedback/MessageBar.status.mjs +2 -1
  101. package/dist/components/feedback/MessageBar.status.mjs.map +1 -1
  102. package/dist/components/feedback/ProgressBar.cjs +1 -1
  103. package/dist/components/feedback/ProgressBar.cjs.map +1 -1
  104. package/dist/components/feedback/ProgressBar.mjs +44 -43
  105. package/dist/components/feedback/ProgressBar.mjs.map +1 -1
  106. package/dist/components/feedback/Skeleton.cjs +1 -1
  107. package/dist/components/feedback/Skeleton.cjs.map +1 -1
  108. package/dist/components/feedback/Skeleton.mjs +26 -24
  109. package/dist/components/feedback/Skeleton.mjs.map +1 -1
  110. package/dist/components/feedback/Spinner.cjs +1 -1
  111. package/dist/components/feedback/Spinner.cjs.map +1 -1
  112. package/dist/components/feedback/Spinner.mjs +32 -31
  113. package/dist/components/feedback/Spinner.mjs.map +1 -1
  114. package/dist/components/feedback/Toast.cjs +1 -1
  115. package/dist/components/feedback/Toast.cjs.map +1 -1
  116. package/dist/components/feedback/Toast.context.cjs +2 -0
  117. package/dist/components/feedback/Toast.context.cjs.map +1 -0
  118. package/dist/components/feedback/Toast.context.mjs +23 -0
  119. package/dist/components/feedback/Toast.context.mjs.map +1 -0
  120. package/dist/components/feedback/Toast.mjs +10 -342
  121. package/dist/components/feedback/Toast.mjs.map +1 -1
  122. package/dist/components/feedback/Toast.parts.cjs +2 -0
  123. package/dist/components/feedback/Toast.parts.cjs.map +1 -0
  124. package/dist/components/feedback/Toast.parts.mjs +98 -0
  125. package/dist/components/feedback/Toast.parts.mjs.map +1 -0
  126. package/dist/components/feedback/Toast.root.cjs +2 -0
  127. package/dist/components/feedback/Toast.root.cjs.map +1 -0
  128. package/dist/components/feedback/Toast.root.mjs +109 -0
  129. package/dist/components/feedback/Toast.root.mjs.map +1 -0
  130. package/dist/components/feedback/Toaster.cjs +2 -0
  131. package/dist/components/feedback/Toaster.cjs.map +1 -0
  132. package/dist/components/feedback/Toaster.mjs +564 -0
  133. package/dist/components/feedback/Toaster.mjs.map +1 -0
  134. package/dist/components/input/AlphaSlider.cjs +2 -0
  135. package/dist/components/input/AlphaSlider.cjs.map +1 -0
  136. package/dist/components/input/AlphaSlider.mjs +115 -0
  137. package/dist/components/input/AlphaSlider.mjs.map +1 -0
  138. package/dist/components/input/Checkbox.cjs +1 -1
  139. package/dist/components/input/Checkbox.cjs.map +1 -1
  140. package/dist/components/input/Checkbox.mjs +87 -70
  141. package/dist/components/input/Checkbox.mjs.map +1 -1
  142. package/dist/components/input/ColorArea.cjs +2 -0
  143. package/dist/components/input/ColorArea.cjs.map +1 -0
  144. package/dist/components/input/ColorArea.mjs +204 -0
  145. package/dist/components/input/ColorArea.mjs.map +1 -0
  146. package/dist/components/input/ColorPicker.cjs +5 -5
  147. package/dist/components/input/ColorPicker.cjs.map +1 -1
  148. package/dist/components/input/ColorPicker.mjs +142 -165
  149. package/dist/components/input/ColorPicker.mjs.map +1 -1
  150. package/dist/components/input/ColorPicker.parts.cjs +2 -0
  151. package/dist/components/input/ColorPicker.parts.cjs.map +1 -0
  152. package/dist/components/input/ColorPicker.parts.mjs +192 -0
  153. package/dist/components/input/ColorPicker.parts.mjs.map +1 -0
  154. package/dist/components/input/ColorSlider.cjs +2 -0
  155. package/dist/components/input/ColorSlider.cjs.map +1 -0
  156. package/dist/components/input/ColorSlider.mjs +138 -0
  157. package/dist/components/input/ColorSlider.mjs.map +1 -0
  158. package/dist/components/input/Combobox.cjs +1 -1
  159. package/dist/components/input/Combobox.cjs.map +1 -1
  160. package/dist/components/input/Combobox.expand.cjs +1 -1
  161. package/dist/components/input/Combobox.expand.cjs.map +1 -1
  162. package/dist/components/input/Combobox.expand.mjs +22 -22
  163. package/dist/components/input/Combobox.expand.mjs.map +1 -1
  164. package/dist/components/input/Combobox.mjs +151 -141
  165. package/dist/components/input/Combobox.mjs.map +1 -1
  166. package/dist/components/input/DatePicker.cjs +1 -1
  167. package/dist/components/input/DatePicker.cjs.map +1 -1
  168. package/dist/components/input/DatePicker.mjs +239 -234
  169. package/dist/components/input/DatePicker.mjs.map +1 -1
  170. package/dist/components/input/Dropdown.cjs +1 -1
  171. package/dist/components/input/Dropdown.cjs.map +1 -1
  172. package/dist/components/input/Dropdown.mjs +109 -100
  173. package/dist/components/input/Dropdown.mjs.map +1 -1
  174. package/dist/components/input/Field.cjs +1 -1
  175. package/dist/components/input/Field.cjs.map +1 -1
  176. package/dist/components/input/Field.mjs +139 -105
  177. package/dist/components/input/Field.mjs.map +1 -1
  178. package/dist/components/input/Input.cjs +1 -1
  179. package/dist/components/input/Input.cjs.map +1 -1
  180. package/dist/components/input/Input.mjs +80 -55
  181. package/dist/components/input/Input.mjs.map +1 -1
  182. package/dist/components/input/Label.cjs +1 -1
  183. package/dist/components/input/Label.cjs.map +1 -1
  184. package/dist/components/input/Label.mjs +19 -12
  185. package/dist/components/input/Label.mjs.map +1 -1
  186. package/dist/components/input/Option.cjs +1 -1
  187. package/dist/components/input/Option.cjs.map +1 -1
  188. package/dist/components/input/Option.mjs +100 -98
  189. package/dist/components/input/Option.mjs.map +1 -1
  190. package/dist/components/input/RadioGroup.cjs +1 -1
  191. package/dist/components/input/RadioGroup.cjs.map +1 -1
  192. package/dist/components/input/RadioGroup.mjs +89 -88
  193. package/dist/components/input/RadioGroup.mjs.map +1 -1
  194. package/dist/components/input/Rating.cjs +1 -1
  195. package/dist/components/input/Rating.cjs.map +1 -1
  196. package/dist/components/input/Rating.item.cjs +2 -0
  197. package/dist/components/input/Rating.item.cjs.map +1 -0
  198. package/dist/components/input/Rating.item.mjs +255 -0
  199. package/dist/components/input/Rating.item.mjs.map +1 -0
  200. package/dist/components/input/Rating.mjs +152 -152
  201. package/dist/components/input/Rating.mjs.map +1 -1
  202. package/dist/components/input/SearchBox.cjs +1 -1
  203. package/dist/components/input/SearchBox.cjs.map +1 -1
  204. package/dist/components/input/SearchBox.mjs +162 -132
  205. package/dist/components/input/SearchBox.mjs.map +1 -1
  206. package/dist/components/input/Select.cjs +1 -1
  207. package/dist/components/input/Select.cjs.map +1 -1
  208. package/dist/components/input/Select.mjs +34 -24
  209. package/dist/components/input/Select.mjs.map +1 -1
  210. package/dist/components/input/Slider.cjs +1 -1
  211. package/dist/components/input/Slider.cjs.map +1 -1
  212. package/dist/components/input/Slider.mjs +78 -54
  213. package/dist/components/input/Slider.mjs.map +1 -1
  214. package/dist/components/input/SpinButton.cjs +1 -1
  215. package/dist/components/input/SpinButton.cjs.map +1 -1
  216. package/dist/components/input/SpinButton.mjs +202 -99
  217. package/dist/components/input/SpinButton.mjs.map +1 -1
  218. package/dist/components/input/SwatchPicker.cjs +1 -1
  219. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  220. package/dist/components/input/SwatchPicker.mjs +38 -37
  221. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  222. package/dist/components/input/Switch.cjs +1 -1
  223. package/dist/components/input/Switch.cjs.map +1 -1
  224. package/dist/components/input/Switch.mjs +75 -58
  225. package/dist/components/input/Switch.mjs.map +1 -1
  226. package/dist/components/input/TagPicker.cjs +1 -1
  227. package/dist/components/input/TagPicker.cjs.map +1 -1
  228. package/dist/components/input/TagPicker.mjs +199 -169
  229. package/dist/components/input/TagPicker.mjs.map +1 -1
  230. package/dist/components/input/Textarea.cjs +1 -1
  231. package/dist/components/input/Textarea.cjs.map +1 -1
  232. package/dist/components/input/Textarea.mjs +31 -23
  233. package/dist/components/input/Textarea.mjs.map +1 -1
  234. package/dist/components/input/TimePicker.cjs +1 -1
  235. package/dist/components/input/TimePicker.cjs.map +1 -1
  236. package/dist/components/input/TimePicker.mjs +185 -177
  237. package/dist/components/input/TimePicker.mjs.map +1 -1
  238. package/dist/components/input/colorName.cjs +2 -0
  239. package/dist/components/input/colorName.cjs.map +1 -0
  240. package/dist/components/input/colorName.mjs +30 -0
  241. package/dist/components/input/colorName.mjs.map +1 -0
  242. package/dist/components/input/colorUtils.cjs +1 -1
  243. package/dist/components/input/colorUtils.cjs.map +1 -1
  244. package/dist/components/input/colorUtils.mjs +154 -56
  245. package/dist/components/input/colorUtils.mjs.map +1 -1
  246. package/dist/components/input/fieldLabel.cjs +2 -0
  247. package/dist/components/input/fieldLabel.cjs.map +1 -0
  248. package/dist/components/input/fieldLabel.mjs +17 -0
  249. package/dist/components/input/fieldLabel.mjs.map +1 -0
  250. package/dist/components/input/inputLook.cjs +2 -0
  251. package/dist/components/input/inputLook.cjs.map +1 -0
  252. package/dist/components/input/inputLook.mjs +28 -0
  253. package/dist/components/input/inputLook.mjs.map +1 -0
  254. package/dist/components/input/pickerStyles.cjs +1 -1
  255. package/dist/components/input/pickerStyles.cjs.map +1 -1
  256. package/dist/components/input/pickerStyles.mjs +42 -4
  257. package/dist/components/input/pickerStyles.mjs.map +1 -1
  258. package/dist/components/layout/Accordion.cjs +1 -1
  259. package/dist/components/layout/Accordion.cjs.map +1 -1
  260. package/dist/components/layout/Accordion.mjs +130 -129
  261. package/dist/components/layout/Accordion.mjs.map +1 -1
  262. package/dist/components/layout/Card.cjs +1 -1
  263. package/dist/components/layout/Card.cjs.map +1 -1
  264. package/dist/components/layout/Card.mjs +78 -77
  265. package/dist/components/layout/Card.mjs.map +1 -1
  266. package/dist/components/layout/Carousel.cjs +1 -1
  267. package/dist/components/layout/Carousel.cjs.map +1 -1
  268. package/dist/components/layout/Carousel.mjs +111 -110
  269. package/dist/components/layout/Carousel.mjs.map +1 -1
  270. package/dist/components/layout/Flex.cjs +1 -1
  271. package/dist/components/layout/Flex.cjs.map +1 -1
  272. package/dist/components/layout/Flex.mjs +22 -21
  273. package/dist/components/layout/Flex.mjs.map +1 -1
  274. package/dist/components/layout/Grid.cjs +1 -1
  275. package/dist/components/layout/Grid.cjs.map +1 -1
  276. package/dist/components/layout/Grid.mjs +19 -18
  277. package/dist/components/layout/Grid.mjs.map +1 -1
  278. package/dist/components/layout/Overflow.cjs +1 -1
  279. package/dist/components/layout/Overflow.cjs.map +1 -1
  280. package/dist/components/layout/Overflow.mjs +92 -91
  281. package/dist/components/layout/Overflow.mjs.map +1 -1
  282. package/dist/components/layout/Stack.cjs +1 -1
  283. package/dist/components/layout/Stack.cjs.map +1 -1
  284. package/dist/components/layout/Stack.mjs +14 -13
  285. package/dist/components/layout/Stack.mjs.map +1 -1
  286. package/dist/components/layout/TabList.cjs +1 -1
  287. package/dist/components/layout/TabList.cjs.map +1 -1
  288. package/dist/components/layout/TabList.mjs +118 -117
  289. package/dist/components/layout/TabList.mjs.map +1 -1
  290. package/dist/components/layout/Tree.cjs +1 -1
  291. package/dist/components/layout/Tree.cjs.map +1 -1
  292. package/dist/components/layout/Tree.context.cjs +2 -0
  293. package/dist/components/layout/Tree.context.cjs.map +1 -0
  294. package/dist/components/layout/Tree.context.mjs +33 -0
  295. package/dist/components/layout/Tree.context.mjs.map +1 -0
  296. package/dist/components/layout/Tree.core.cjs +2 -0
  297. package/dist/components/layout/Tree.core.cjs.map +1 -0
  298. package/dist/components/layout/Tree.core.mjs +416 -0
  299. package/dist/components/layout/Tree.core.mjs.map +1 -0
  300. package/dist/components/layout/Tree.itemPersonaLayout.cjs +2 -0
  301. package/dist/components/layout/Tree.itemPersonaLayout.cjs.map +1 -0
  302. package/dist/components/layout/Tree.itemPersonaLayout.mjs +46 -0
  303. package/dist/components/layout/Tree.itemPersonaLayout.mjs.map +1 -0
  304. package/dist/components/layout/Tree.mjs +7 -215
  305. package/dist/components/layout/Tree.mjs.map +1 -1
  306. package/dist/components/layout/Tree.selection.cjs +2 -0
  307. package/dist/components/layout/Tree.selection.cjs.map +1 -0
  308. package/dist/components/layout/Tree.selection.mjs +73 -0
  309. package/dist/components/layout/Tree.selection.mjs.map +1 -0
  310. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  311. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  312. package/dist/components/navigation/Breadcrumb.mjs +76 -75
  313. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  314. package/dist/components/navigation/Menu.group.cjs +1 -1
  315. package/dist/components/navigation/Menu.group.cjs.map +1 -1
  316. package/dist/components/navigation/Menu.group.mjs +39 -37
  317. package/dist/components/navigation/Menu.group.mjs.map +1 -1
  318. package/dist/components/navigation/Menu.items.cjs +1 -1
  319. package/dist/components/navigation/Menu.items.cjs.map +1 -1
  320. package/dist/components/navigation/Menu.items.mjs +67 -61
  321. package/dist/components/navigation/Menu.items.mjs.map +1 -1
  322. package/dist/components/navigation/Menu.link.cjs +1 -1
  323. package/dist/components/navigation/Menu.link.cjs.map +1 -1
  324. package/dist/components/navigation/Menu.link.mjs +34 -28
  325. package/dist/components/navigation/Menu.link.mjs.map +1 -1
  326. package/dist/components/navigation/Menu.popover.cjs +1 -1
  327. package/dist/components/navigation/Menu.popover.cjs.map +1 -1
  328. package/dist/components/navigation/Menu.popover.mjs +114 -113
  329. package/dist/components/navigation/Menu.popover.mjs.map +1 -1
  330. package/dist/components/navigation/Menu.root.cjs +1 -1
  331. package/dist/components/navigation/Menu.root.cjs.map +1 -1
  332. package/dist/components/navigation/Menu.root.mjs +171 -170
  333. package/dist/components/navigation/Menu.root.mjs.map +1 -1
  334. package/dist/components/navigation/Menu.selectable.cjs +1 -1
  335. package/dist/components/navigation/Menu.selectable.cjs.map +1 -1
  336. package/dist/components/navigation/Menu.selectable.mjs +85 -63
  337. package/dist/components/navigation/Menu.selectable.mjs.map +1 -1
  338. package/dist/components/navigation/Menu.splitGroup.cjs +1 -1
  339. package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -1
  340. package/dist/components/navigation/Menu.splitGroup.mjs +27 -26
  341. package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -1
  342. package/dist/components/navigation/Menu.trigger.cjs +1 -1
  343. package/dist/components/navigation/Menu.trigger.cjs.map +1 -1
  344. package/dist/components/navigation/Menu.trigger.mjs +6 -6
  345. package/dist/components/navigation/Nav.cjs +1 -1
  346. package/dist/components/navigation/Nav.cjs.map +1 -1
  347. package/dist/components/navigation/Nav.mjs +170 -155
  348. package/dist/components/navigation/Nav.mjs.map +1 -1
  349. package/dist/components/navigation/Pagination.cjs +1 -1
  350. package/dist/components/navigation/Pagination.cjs.map +1 -1
  351. package/dist/components/navigation/Pagination.mjs +73 -65
  352. package/dist/components/navigation/Pagination.mjs.map +1 -1
  353. package/dist/components/navigation/Stepper.cjs +1 -1
  354. package/dist/components/navigation/Stepper.cjs.map +1 -1
  355. package/dist/components/navigation/Stepper.mjs +110 -109
  356. package/dist/components/navigation/Stepper.mjs.map +1 -1
  357. package/dist/components/overlays/Dialog.cjs +1 -1
  358. package/dist/components/overlays/Dialog.cjs.map +1 -1
  359. package/dist/components/overlays/Dialog.mjs +109 -108
  360. package/dist/components/overlays/Dialog.mjs.map +1 -1
  361. package/dist/components/overlays/Drawer.cjs +1 -1
  362. package/dist/components/overlays/Drawer.cjs.map +1 -1
  363. package/dist/components/overlays/Drawer.mjs +110 -109
  364. package/dist/components/overlays/Drawer.mjs.map +1 -1
  365. package/dist/components/overlays/Popover.cjs +1 -1
  366. package/dist/components/overlays/Popover.cjs.map +1 -1
  367. package/dist/components/overlays/Popover.mjs +148 -151
  368. package/dist/components/overlays/Popover.mjs.map +1 -1
  369. package/dist/components/overlays/Popover.shared.cjs +1 -1
  370. package/dist/components/overlays/Popover.shared.cjs.map +1 -1
  371. package/dist/components/overlays/Popover.shared.mjs +82 -77
  372. package/dist/components/overlays/Popover.shared.mjs.map +1 -1
  373. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  374. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  375. package/dist/components/overlays/TeachingPopover.mjs +41 -37
  376. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  377. package/dist/components/overlays/Tooltip.cjs +1 -1
  378. package/dist/components/overlays/Tooltip.cjs.map +1 -1
  379. package/dist/components/overlays/Tooltip.mjs +87 -86
  380. package/dist/components/overlays/Tooltip.mjs.map +1 -1
  381. package/dist/components/portal/Portal.cjs +1 -1
  382. package/dist/components/portal/Portal.cjs.map +1 -1
  383. package/dist/components/portal/Portal.mjs +33 -32
  384. package/dist/components/portal/Portal.mjs.map +1 -1
  385. package/dist/components/provider/WaveProvider.cjs +1 -1
  386. package/dist/components/provider/WaveProvider.cjs.map +1 -1
  387. package/dist/components/provider/WaveProvider.mjs +36 -29
  388. package/dist/components/provider/WaveProvider.mjs.map +1 -1
  389. package/dist/components/table/DataGrid.cjs +1 -1
  390. package/dist/components/table/DataGrid.cjs.map +1 -1
  391. package/dist/components/table/DataGrid.mjs +228 -227
  392. package/dist/components/table/DataGrid.mjs.map +1 -1
  393. package/dist/components/table/Table.cjs +1 -1
  394. package/dist/components/table/Table.cjs.map +1 -1
  395. package/dist/components/table/Table.mjs +60 -59
  396. package/dist/components/table/Table.mjs.map +1 -1
  397. package/dist/components/typography/Text.cjs +1 -1
  398. package/dist/components/typography/Text.cjs.map +1 -1
  399. package/dist/components/typography/Text.mjs +12 -11
  400. package/dist/components/typography/Text.mjs.map +1 -1
  401. package/dist/hooks/useFieldControl.cjs.map +1 -1
  402. package/dist/hooks/useFieldControl.mjs.map +1 -1
  403. package/dist/hooks/useMediaQuery.cjs +2 -0
  404. package/dist/hooks/useMediaQuery.cjs.map +1 -0
  405. package/dist/hooks/useMediaQuery.mjs +20 -0
  406. package/dist/hooks/useMediaQuery.mjs.map +1 -0
  407. package/dist/hooks/usePrefersReducedMotion.cjs +1 -1
  408. package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -1
  409. package/dist/hooks/usePrefersReducedMotion.mjs +4 -18
  410. package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -1
  411. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  412. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  413. package/dist/hooks/useRovingTabIndex.mjs +3 -3
  414. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  415. package/dist/index.cjs +1 -1
  416. package/dist/index.d.cts +2890 -197
  417. package/dist/index.d.ts +2890 -197
  418. package/dist/index.mjs +101 -87
  419. package/dist/lib/classNames.cjs +2 -0
  420. package/dist/lib/classNames.cjs.map +1 -0
  421. package/dist/lib/classNames.mjs +423 -0
  422. package/dist/lib/classNames.mjs.map +1 -0
  423. package/dist/lib/color.cjs +2 -0
  424. package/dist/lib/color.cjs.map +1 -0
  425. package/dist/lib/color.mjs +86 -0
  426. package/dist/lib/color.mjs.map +1 -0
  427. package/dist/lib/globalRegistry.cjs.map +1 -1
  428. package/dist/lib/globalRegistry.mjs.map +1 -1
  429. package/dist/lib/styles.cjs +1 -1
  430. package/dist/lib/styles.cjs.map +1 -1
  431. package/dist/lib/styles.mjs +21 -4
  432. package/dist/lib/styles.mjs.map +1 -1
  433. package/dist/lib/toaster.cjs +2 -0
  434. package/dist/lib/toaster.cjs.map +1 -0
  435. package/dist/lib/toaster.mjs +77 -0
  436. package/dist/lib/toaster.mjs.map +1 -0
  437. package/dist/styles.css +1 -1
  438. package/package.json +1 -1
  439. package/src/styles/tokens.css +13 -0
@@ -1,128 +1,137 @@
1
1
  "use client";
2
2
  import { cn as e } from "../../lib/cn.mjs";
3
- import { warnDeprecated as t } from "../../lib/dev.mjs";
4
- import { composeEventHandlers as n } from "../../lib/composeEventHandlers.mjs";
3
+ import { warnDeprecated as ee } from "../../lib/dev.mjs";
4
+ import { composeEventHandlers as t } from "../../lib/composeEventHandlers.mjs";
5
+ import { dropdownClassNames as n } from "../../lib/classNames.mjs";
5
6
  import { useControllable as r } from "../../hooks/useControllable.mjs";
6
7
  import { useMergedRefs as i } from "../../hooks/useMergedRefs.mjs";
7
- import { useFieldContext as ee, useFieldControl as te } from "../../hooks/useFieldControl.mjs";
8
- import { disabledStyles as a, inputFocus as o } from "../../lib/styles.mjs";
9
- import { ChevronDownIcon as ne, DismissIcon as re } from "../../lib/icons.mjs";
10
- import { isInvalidLook as s } from "./Input.mjs";
11
- import { useFormReset as ie } from "../../hooks/useFormReset.mjs";
12
- import { HiddenInput as ae } from "../internal/HiddenInput.mjs";
13
- import { collectOptionLabels as oe, useListbox as se } from "../../hooks/useListbox.mjs";
14
- import { pickerEndPadding as ce } from "./pickerStyles.mjs";
15
- import { ListboxSurface as le, Option as c, OptionGroup as l, useListboxPopup as ue } from "./Option.mjs";
16
- import * as u from "react";
17
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ import { useFieldContext as te, useFieldControl as ne } from "../../hooks/useFieldControl.mjs";
9
+ import { disabledStyles as re, inputAppearanceClasses as ie, inputFocus as ae, inputHeightClasses as oe, inputPaddingClasses as se, inputTextClasses as ce } from "../../lib/styles.mjs";
10
+ import { ChevronDownIcon as le, DismissIcon as ue } from "../../lib/icons.mjs";
11
+ import { useInputLook as a } from "./inputLook.mjs";
12
+ import { isInvalidLook as o } from "./Input.mjs";
13
+ import { useFormReset as s } from "../../hooks/useFormReset.mjs";
14
+ import { HiddenInput as de } from "../internal/HiddenInput.mjs";
15
+ import { collectOptionLabels as fe, useListbox as pe } from "../../hooks/useListbox.mjs";
16
+ import { pickerButtonOffset as me, pickerEndPadding as he, pickerGlyphSize as c, pickerIconButtonClasses as ge } from "./pickerStyles.mjs";
17
+ import { ListboxSurface as _e, Option as l, OptionGroup as u, useListboxPopup as ve } from "./Option.mjs";
18
+ import * as d from "react";
19
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
18
20
  //#region src/components/input/Dropdown.tsx
19
- var p = (c) => {
20
- let { value: l, defaultValue: p, onValueChange: m, onOptionSelect: h, open: g, defaultOpen: de, onOpenChange: fe, placeholder: pe = "Select an option", disabled: _ = !1, name: me, form: v, required: y, clearable: b = !1, labels: x, autoFocus: S, tabIndex: C, id: w, "aria-label": T, "aria-labelledby": E, "aria-describedby": D, "aria-invalid": O, "aria-required": k, "aria-errormessage": A, "aria-details": j, onFocus: M, onBlur: N, onKeyDown: P, onKeyUp: F, controlRef: I, className: L, children: R, ref: z, ...he } = c;
21
- h !== void 0 && t("Dropdown", "onOptionSelect", "onValueChange");
22
- let B = ee(), ge = y ?? B?.required ?? !1, V = te({
23
- id: w,
24
- "aria-label": T,
25
- "aria-labelledby": E,
26
- "aria-describedby": D,
27
- "aria-invalid": O,
28
- "aria-required": k ?? y
29
- }), _e = s(!1, V["aria-invalid"]), [H, U] = r(l, p ?? "", m), [W, G] = r(g, (de ?? !1) && !_, fe), K = W && !_, q = _ && W;
30
- u.useEffect(() => {
31
- q && G(!1);
32
- }, [q, G]);
33
- let J = u.useRef(null), Y = u.useRef(null), ve = u.useMemo(() => oe(R), [R]), X = se({
34
- open: K,
35
- onOpenChange: (e) => G(e),
21
+ var m = (l) => {
22
+ let { value: u, defaultValue: m, onValueChange: h, onOptionSelect: g, open: _, defaultOpen: v, onOpenChange: y, placeholder: b = "Select an option", disabled: x = !1, size: S, appearance: C, name: w, form: T, required: E, clearable: D = !1, labels: O, autoFocus: k, tabIndex: A, id: j, "aria-label": M, "aria-labelledby": N, "aria-describedby": P, "aria-invalid": F, "aria-required": ye, "aria-errormessage": be, "aria-details": xe, onFocus: Se, onBlur: Ce, onKeyDown: we, onKeyUp: Te, controlRef: Ee, className: De, children: I, ref: Oe, ...ke } = l;
23
+ g !== void 0 && ee("Dropdown", "onOptionSelect", "onValueChange");
24
+ let L = te(), Ae = E ?? L?.required ?? !1, R = ne({
25
+ id: j,
26
+ "aria-label": M,
27
+ "aria-labelledby": N,
28
+ "aria-describedby": P,
29
+ "aria-invalid": F,
30
+ "aria-required": ye ?? E
31
+ }), je = o(!1, R["aria-invalid"]), { size: z, appearance: B } = a(S, C), [V, H] = r(u, m ?? "", h), [U, W] = r(_, (v ?? !1) && !x, y), G = U && !x, K = x && U;
32
+ d.useEffect(() => {
33
+ K && W(!1);
34
+ }, [K, W]);
35
+ let q = d.useRef(null), J = d.useRef(null), Me = d.useMemo(() => fe(I), [I]), Y = pe({
36
+ open: G,
37
+ onOpenChange: (e) => W(e),
36
38
  mode: "select-only",
37
- selectedValues: H ? [H] : [],
39
+ selectedValues: V ? [V] : [],
38
40
  onSelect: (e) => {
39
- U(e), h?.(e);
41
+ H(e), g?.(e);
40
42
  },
41
43
  idPrefix: "dropdown-listbox"
42
- }), Z = K && X.items.length > 0, { layerId: ye, setReference: be, surfaceRef: xe, floatingProps: Se } = ue({
43
- open: K,
44
- surfaceOpen: Z,
45
- onDismiss: () => G(!1),
46
- rootRef: J,
47
- anchorRef: Y
48
- }), Ce = i(J, z), we = i(Y, I, be);
49
- ie(Y, () => U(p ?? ""), v);
50
- let Q = H ? X.getItem(H)?.label ?? ve.get(H) ?? "" : "", Te = (e) => {
51
- if (e.key === "Escape" && K && !Z && !e.nativeEvent.isComposing) {
52
- G(!1);
44
+ }), X = G && Y.items.length > 0, { layerId: Z, setReference: Ne, surfaceRef: Pe, floatingProps: Fe } = ve({
45
+ open: G,
46
+ surfaceOpen: X,
47
+ onDismiss: () => W(!1),
48
+ rootRef: q,
49
+ anchorRef: J
50
+ }), Ie = i(q, Oe), Le = i(J, Ee, Ne);
51
+ s(J, () => H(m ?? ""), T);
52
+ let Q = V ? Y.getItem(V)?.label ?? Me.get(V) ?? "" : "", Re = (e) => {
53
+ if (e.key === "Escape" && G && !X && !e.nativeEvent.isComposing) {
54
+ W(!1);
53
55
  return;
54
56
  }
55
- X.onKeyDown(e);
56
- }, Ee = () => {
57
- U(""), G(!1), Y.current?.focus();
58
- }, $ = b && H !== "", De = V["aria-label"] === void 0 ? V["aria-labelledby"] ?? B?.labelId : V["aria-labelledby"];
59
- return /* @__PURE__ */ f("div", {
60
- ...he,
61
- ref: Ce,
62
- className: e("relative inline-flex flex-col", L),
57
+ Y.onKeyDown(e);
58
+ }, ze = () => {
59
+ H(""), W(!1), J.current?.focus();
60
+ }, $ = D && V !== "", Be = R["aria-label"] === void 0 ? R["aria-labelledby"] ?? L?.labelId : R["aria-labelledby"];
61
+ return /* @__PURE__ */ p("div", {
62
+ "data-size": z,
63
+ "data-appearance": B,
64
+ ...ke,
65
+ ref: Ie,
66
+ className: e(n.root, "relative inline-flex flex-col", De),
63
67
  children: [
64
- /* @__PURE__ */ f("div", {
68
+ /* @__PURE__ */ p("div", {
65
69
  className: "relative flex items-center",
66
- children: [/* @__PURE__ */ f("button", {
70
+ children: [/* @__PURE__ */ p("button", {
67
71
  type: "button",
68
- ...V,
69
- ...X.getComboboxProps(),
70
- "aria-expanded": Z,
71
- "aria-errormessage": A,
72
- "aria-details": j,
73
- ref: we,
74
- disabled: _,
75
- autoFocus: S,
76
- tabIndex: C,
77
- onClick: () => G((e) => !e),
78
- onKeyDown: n(P, Te),
79
- onKeyUp: n(F, X.onKeyUp),
80
- onFocus: M,
81
- onBlur: N,
82
- className: e("relative flex h-8 w-full items-center justify-between rounded border border-input border-b-stroke-accessible bg-background px-3 py-0 text-start text-body-1 text-foreground", ce($ ? 2 : 1), o, a, _e && "border-destructive focus:border-b-destructive"),
83
- children: [/* @__PURE__ */ d("span", {
84
- className: e("truncate", !Q && "text-muted-foreground"),
85
- children: Q || pe
86
- }), /* @__PURE__ */ d(ne, { className: e("absolute end-3 transition-transform motion-reduce:transition-none", Z && "rotate-180") })]
87
- }), $ && /* @__PURE__ */ d("button", {
72
+ ...R,
73
+ ...Y.getComboboxProps(),
74
+ "aria-expanded": X,
75
+ "aria-errormessage": be,
76
+ "aria-details": xe,
77
+ ref: Le,
78
+ disabled: x,
79
+ autoFocus: k,
80
+ tabIndex: A,
81
+ onClick: () => W((e) => !e),
82
+ onKeyDown: t(we, Re),
83
+ onKeyUp: t(Te, Y.onKeyUp),
84
+ onFocus: Se,
85
+ onBlur: Ce,
86
+ className: e(n.button, "relative flex w-full items-center justify-between py-0 text-start", oe[z], se[z], ce[z], ie[B], "text-foreground", he($ ? 2 : 1, z), ae, re, je && "border-destructive"),
87
+ children: [/* @__PURE__ */ f("span", {
88
+ className: e(n.value, "truncate", !Q && "text-muted-foreground"),
89
+ children: Q || b
90
+ }), /* @__PURE__ */ f(le, {
91
+ size: c(z, "chevron"),
92
+ className: e(n.expandIcon, "absolute transition-transform motion-reduce:transition-none", z === "small" ? "end-2" : "end-3", X && "rotate-180")
93
+ })]
94
+ }), $ && /* @__PURE__ */ f("button", {
88
95
  type: "button",
89
- "aria-label": x?.clear ?? "Clear selection",
90
- disabled: _,
96
+ "aria-label": O?.clear ?? "Clear selection",
97
+ disabled: x,
91
98
  onMouseDown: (e) => e.preventDefault(),
92
- onClick: Ee,
93
- className: e("absolute flex h-6 w-6 items-center justify-center rounded bg-transparent p-0 text-muted-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:hover:text-foreground", "end-7", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", "disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100"),
94
- children: /* @__PURE__ */ d(re, {})
99
+ onClick: ze,
100
+ className: e(n.clearButton, ge(z, B), me(z, 2), "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", "disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:focus-visible:opacity-100"),
101
+ children: /* @__PURE__ */ f(ue, { size: c(z, "icon") })
95
102
  })]
96
103
  }),
97
- /* @__PURE__ */ d(le, {
98
- listbox: X,
99
- layerId: ye,
100
- surfaceRef: xe,
101
- floatingProps: Se,
102
- open: K,
103
- expanded: Z,
104
- "aria-label": V["aria-label"],
105
- "aria-labelledby": De,
106
- children: R
104
+ /* @__PURE__ */ f(_e, {
105
+ listbox: Y,
106
+ layerId: Z,
107
+ surfaceRef: Pe,
108
+ floatingProps: Fe,
109
+ open: G,
110
+ expanded: X,
111
+ listboxClassName: n.listbox,
112
+ surfaceClassName: n.surface,
113
+ "aria-label": R["aria-label"],
114
+ "aria-labelledby": Be,
115
+ children: I
107
116
  }),
108
- /* @__PURE__ */ d(ae, {
109
- name: me,
110
- form: v,
111
- disabled: _,
112
- value: H,
117
+ /* @__PURE__ */ f(de, {
118
+ name: w,
119
+ form: T,
120
+ disabled: x,
121
+ value: V,
113
122
  type: "text",
114
- required: ge,
115
- onInvalid: () => Y.current?.focus()
123
+ required: Ae,
124
+ onInvalid: () => J.current?.focus()
116
125
  })
117
126
  ]
118
127
  });
119
128
  };
120
- p.displayName = "Dropdown";
121
- var m = c, h = l, g = /* @__PURE__ */ Object.assign(p, {
122
- Option: c,
123
- OptionGroup: l
129
+ m.displayName = "Dropdown";
130
+ var h = l, g = u, _ = /* @__PURE__ */ Object.assign(m, {
131
+ Option: l,
132
+ OptionGroup: u
124
133
  });
125
134
  //#endregion
126
- export { g as Dropdown, m as DropdownOption, h as DropdownOptionGroup };
135
+ export { _ as Dropdown, h as DropdownOption, g as DropdownOptionGroup };
127
136
 
128
137
  //# sourceMappingURL=Dropdown.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.mjs","names":["React","DropdownRoot","valueProp","openProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onOptionSelect","warnDeprecated","field","useFieldContext","isRequired","required","fieldProps","useFieldControl","invalidLook","isInvalidLook","value","setValue","useControllable","defaultValue","onValueChange","openState","setOpen","defaultOpen","disabled","onOpenChange","open","lockedOpen","rootRef","buttonRef","optionLabels","collectOptionLabels","children","listbox","useListbox","next","expanded","useListboxPopup","rootMergedRef","useMergedRefs","ref","buttonMergedRef","controlRef","setReference","form","displayText","handleKeyDown","event","handleClear","showClear","clearable","listLabelledBy","cn","className","current","composeEventHandlers","onKeyDown","onKeyUp","pickerEndPadding","inputFocus","disabledStyles","placeholder","ChevronDownIcon","labels","DismissIcon","ListboxSurface","HiddenInput","DropdownOption","Option","DropdownOptionGroup","OptionGroup","Dropdown"],"sources":["../../../src/components/input/Dropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated } from '../../lib/dev';\nimport { ChevronDownIcon, DismissIcon } from '../../lib/icons';\nimport { disabledStyles, focusRing, inputFocus, inputInvalid } from '../../lib/styles';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { collectOptionLabels, useListbox } from '../../hooks/useListbox';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { isInvalidLook } from './Input';\nimport { ListboxSurface, Option, OptionGroup, useListboxPopup } from './Option';\nimport { PICKER_ICON_BUTTON_CLASSES, pickerEndPadding } from './pickerStyles';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/* ------------------------------------------------------------------ */\n/* Dropdown */\n/* ------------------------------------------------------------------ */\n\n/**\n * The Dropdown's built-in texts, for localization. Each member is optional and falls back to its\n * English default.\n */\nexport interface DropdownLabels {\n /** Name of the clear button (`clearable`).\n * @default 'Clear selection'\n */\n clear?: string;\n}\n\n/** Properties for the Dropdown component. */\nexport interface DropdownProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | RoutedHandlers\n> {\n /** Controlled selected value (`''` for none). */\n value?: string;\n /**\n * Initial selected value for uncontrolled usage.\n * @default ''\n */\n defaultValue?: string;\n /** Called with the new value when a different option is selected. */\n onValueChange?: (value: string) => void;\n /**\n * Called on every option activation, also when the current option is selected again.\n * @deprecated Use `onValueChange`.\n */\n onOptionSelect?: (value: string) => void;\n /**\n * Controlled open state of the listbox. The list renders only in the browser: an open dropdown\n * 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 dropdown that starts disabled starts closed. The\n * list renders only in the browser: it is closed in the server HTML and opens once the dropdown\n * has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the listbox opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Placeholder text shown when no value is selected. It is not an accessible name: label the\n * Dropdown with a `Field`, `aria-label` or `aria-labelledby`.\n * @default 'Select an option'\n */\n placeholder?: string;\n /**\n * Whether the dropdown is disabled and non-interactive. Turning it on while the listbox is open\n * closes it (`onOpenChange(false)`).\n * @default false\n */\n disabled?: boolean;\n /** Name of the value in form submissions (renders a hidden input). */\n name?: string;\n /** Id of the form the value belongs to, when the Dropdown is outside it. */\n form?: string;\n /** A value is required to submit the form (native constraint validation). */\n required?: boolean;\n /**\n * Shows a clear button while a value is selected (shown disabled while `disabled`). It clears\n * the value, closes the list and moves focus to the combobox button. It is a tab stop after it.\n * @default false\n */\n clearable?: boolean;\n /** The name of the clear button, for localization. Unset members keep their English defaults. */\n labels?: DropdownLabels;\n /** Called when the `<button role=\"combobox\">` receives focus (the root keeps other handlers). */\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n /** Called when the `<button role=\"combobox\">` loses focus. */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /**\n * Called on a key press on the `<button role=\"combobox\">`, before the built-in listbox keys;\n * `event.preventDefault()` skips them.\n */\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Called when a key is released on the `<button role=\"combobox\">`. */\n onKeyUp?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Ref to the `<button role=\"combobox\">` (the focusable element). */\n controlRef?: React.Ref<HTMLButtonElement>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst DropdownRoot = (props: DropdownProps) => {\n const {\n value: valueProp,\n defaultValue,\n onValueChange,\n onOptionSelect,\n open: openProp,\n defaultOpen,\n onOpenChange,\n placeholder = 'Select an option',\n disabled = false,\n name,\n form,\n required,\n clearable = false,\n labels,\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 children,\n ref,\n ...rest\n } = props;\n\n if (onOptionSelect !== undefined) warnDeprecated('Dropdown', 'onOptionSelect', 'onValueChange');\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\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 [value, setValue] = useControllable(valueProp, defaultValue ?? '', onValueChange);\n // A dropdown that starts disabled never shows its list, so it starts closed (no close to report\n // later).\n const [openState, setOpen] = useControllable(\n openProp,\n (defaultOpen ?? false) && !disabled,\n onOpenChange,\n );\n const open = openState && !disabled;\n // Disabling also closes the list itself, not only the derived `open`, so enabling it again does\n // not reopen it without a user action. The close is reported through onOpenChange (a consumer\n // callback from an effect, C-HOOKS); a controlled `open` that stays true is not shown meanwhile.\n const lockedOpen = disabled && openState;\n React.useEffect(() => {\n if (lockedOpen) setOpen(false);\n }, [lockedOpen, setOpen]);\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const buttonRef = React.useRef<HTMLButtonElement | null>(null);\n\n const optionLabels = React.useMemo(() => collectOptionLabels(children), [children]);\n\n const listbox = useListbox({\n open,\n onOpenChange: (next) => setOpen(next),\n mode: 'select-only',\n selectedValues: value ? [value] : [],\n onSelect: (next) => {\n setValue(next);\n onOptionSelect?.(next);\n },\n idPrefix: 'dropdown-listbox',\n });\n\n const expanded = open && listbox.items.length > 0;\n const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({\n open,\n surfaceOpen: expanded,\n onDismiss: () => setOpen(false),\n rootRef,\n anchorRef: buttonRef,\n });\n\n const rootMergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const buttonMergedRef = useMergedRefs<HTMLButtonElement>(buttonRef, controlRef, setReference);\n\n useFormReset(buttonRef, () => setValue(defaultValue ?? ''), form);\n\n const displayText = value ? (listbox.getItem(value)?.label ?? optionLabels.get(value) ?? '') : '';\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Escape' && open && !expanded && !event.nativeEvent.isComposing) {\n // Open with nothing shown (no options): close, but leave Escape to an enclosing layer\n // (overlays#1) instead of consuming it for an invisible list.\n setOpen(false);\n return;\n }\n listbox.onKeyDown(event);\n };\n\n // The button disappears with the value, so focus moves to the combobox explicitly (C-DISABLED).\n const handleClear = () => {\n setValue('');\n setOpen(false);\n buttonRef.current?.focus();\n };\n\n const showClear = clearable && value !== '';\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 inline-flex flex-col', className)}>\n <div className=\"relative flex items-center\">\n <button\n type=\"button\"\n {...fieldProps}\n {...listbox.getComboboxProps()}\n aria-expanded={expanded}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n ref={buttonMergedRef}\n disabled={disabled}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n onClick={() => setOpen((current) => !current)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={composeEventHandlers(onKeyUp, listbox.onKeyUp)}\n onFocus={onFocus}\n onBlur={onBlur}\n className={cn(\n // Every padding is set here (C-NATIVE), not left to an app-wide `button` rule. The end\n // padding keeps the text clear of the chevron (and of the clear button while it shows).\n 'relative flex h-8 w-full items-center justify-between rounded border border-input border-b-stroke-accessible bg-background px-3 py-0 text-start text-body-1 text-foreground',\n pickerEndPadding(showClear ? 2 : 1),\n inputFocus,\n disabledStyles,\n invalidLook && inputInvalid,\n )}\n >\n <span className={cn('truncate', !displayText && 'text-muted-foreground')}>\n {displayText || placeholder}\n </span>\n <ChevronDownIcon\n className={cn(\n 'absolute end-3 transition-transform motion-reduce:transition-none',\n expanded && 'rotate-180',\n )}\n />\n </button>\n {showClear && (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear selection'}\n disabled={disabled}\n // Keeps focus on the combobox while the pointer clears it.\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n className={cn(PICKER_ICON_BUTTON_CLASSES, 'end-7', focusRing, disabledStyles)}\n >\n <DismissIcon />\n </button>\n )}\n </div>\n <ListboxSurface\n listbox={listbox}\n layerId={layerId}\n surfaceRef={surfaceRef}\n floatingProps={floatingProps}\n open={open}\n expanded={expanded}\n aria-label={fieldProps['aria-label']}\n aria-labelledby={listLabelledBy}\n >\n {children}\n </ListboxSurface>\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={value}\n type=\"text\"\n required={isRequired}\n onInvalid={() => buttonRef.current?.focus()}\n />\n </div>\n );\n};\nDropdownRoot.displayName = 'Dropdown';\n\n/** Flat name of `Dropdown.Option` for React Server Components. */\nexport const DropdownOption = Option;\n/** Flat name of `Dropdown.OptionGroup` for React Server Components. */\nexport const DropdownOptionGroup = OptionGroup;\n\n/**\n * A select-only combobox (APG): a button that opens a listbox of `Option`s. Enter, Space,\n * ArrowDown/ArrowUp, Home/End and typing a character open it and move the highlight\n * (`aria-activedescendant`); Enter/Space select, Tab selects the highlighted option and moves on,\n * Escape closes. `clearable` adds a clear button, a tab stop after the combobox button; both sit\n * in a wrapper `<div>` inside the root.\n *\n * The `<button>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`\n * and `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp`. `ref`, `className`, `style`, other `aria-*`\n * attributes and the remaining props stay on the root `<div>`. Inside a `Field` the button is\n * labelled and described by it — otherwise give it an `aria-label`. It shows the error look\n * whenever it ends up `aria-invalid` (its own `aria-invalid` or a `Field` error). With\n * `name`/`required` the value takes part in form submission, validation and reset. The open\n * listbox renders in a portal; while closed it stays in the DOM, hidden.\n *\n * Sub-components: `Dropdown.Option`, `Dropdown.OptionGroup`. React Server Components import the\n * flat names `DropdownOption` / `DropdownOptionGroup` (dotted access needs a client file).\n */\nexport const Dropdown = /* @__PURE__ */ Object.assign(DropdownRoot, {\n Option,\n OptionGroup,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Dropdown.mjs","names":["React","DropdownRoot","valueProp","openProp","sizeProp","appearanceProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","props","onOptionSelect","warnDeprecated","field","useFieldContext","isRequired","required","fieldProps","useFieldControl","invalidLook","isInvalidLook","useInputLook","value","setValue","useControllable","defaultValue","onValueChange","openState","setOpen","defaultOpen","disabled","onOpenChange","open","lockedOpen","rootRef","buttonRef","optionLabels","collectOptionLabels","children","listbox","useListbox","next","expanded","useListboxPopup","rootMergedRef","useMergedRefs","ref","buttonMergedRef","controlRef","setReference","form","displayText","handleKeyDown","event","handleClear","showClear","clearable","listLabelledBy","size","appearance","cn","dropdownClassNames","className","current","composeEventHandlers","onKeyDown","onKeyUp","inputHeightClasses","inputPaddingClasses","inputTextClasses","inputAppearanceClasses","pickerEndPadding","inputFocus","disabledStyles","placeholder","ChevronDownIcon","pickerGlyphSize","labels","pickerIconButtonClasses","pickerButtonOffset","DismissIcon","ListboxSurface","HiddenInput","DropdownOption","Option","DropdownOptionGroup","OptionGroup","Dropdown"],"sources":["../../../src/components/input/Dropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { dropdownClassNames } from '../../lib/classNames';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated } from '../../lib/dev';\nimport { ChevronDownIcon, DismissIcon } from '../../lib/icons';\nimport {\n disabledStyles,\n focusRing,\n inputAppearanceClasses,\n inputFocus,\n inputHeightClasses,\n inputInvalid,\n inputPaddingClasses,\n inputTextClasses,\n} from '../../lib/styles';\nimport type { CoreSize, InputAppearance } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { collectOptionLabels, useListbox } from '../../hooks/useListbox';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { useInputLook } from './inputLook';\nimport { isInvalidLook } from './Input';\nimport { ListboxSurface, Option, OptionGroup, useListboxPopup } from './Option';\nimport {\n pickerButtonOffset,\n pickerEndPadding,\n pickerGlyphSize,\n pickerIconButtonClasses,\n} from './pickerStyles';\nimport type { RoutedHandlers } from './routedHandlers';\n\n/* ------------------------------------------------------------------ */\n/* Dropdown */\n/* ------------------------------------------------------------------ */\n\n/**\n * The Dropdown's built-in texts, for localization. Each member is optional and falls back to its\n * English default.\n */\nexport interface DropdownLabels {\n /** Name of the clear button (`clearable`).\n * @default 'Clear selection'\n */\n clear?: string;\n}\n\n/** Properties for the Dropdown component. */\nexport interface DropdownProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | RoutedHandlers\n> {\n /** Controlled selected value (`''` for none). */\n value?: string;\n /**\n * Initial selected value for uncontrolled usage.\n * @default ''\n */\n defaultValue?: string;\n /** Called with the new value when a different option is selected. */\n onValueChange?: (value: string) => void;\n /**\n * Called on every option activation, also when the current option is selected again.\n * @deprecated Use `onValueChange`.\n */\n onOptionSelect?: (value: string) => void;\n /**\n * Controlled open state of the listbox. The list renders only in the browser: an open dropdown\n * 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 dropdown that starts disabled starts closed. The\n * list renders only in the browser: it is closed in the server HTML and opens once the dropdown\n * has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /** Called when the listbox opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Placeholder text shown when no value is selected. It is not an accessible name: label the\n * Dropdown with a `Field`, `aria-label` or `aria-labelledby`.\n * @default 'Select an option'\n */\n placeholder?: string;\n /**\n * Whether the dropdown is disabled and non-interactive. Turning it on while the listbox is open\n * closes it (`onOpenChange(false)`).\n * @default false\n */\n disabled?: boolean;\n /**\n * Size of the field: `small` (24px tall), `medium` (32px) or `large` (40px). Default: the\n * surrounding Field's `size`, else `WaveProvider inputDefaults.size`, else `'medium'`. The\n * listbox keeps its size.\n */\n size?: CoreSize;\n /**\n * Look of the field: `outline` (a full border), `underline` (a bottom stroke only),\n * `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible\n * label). Default: `WaveProvider inputDefaults.appearance`, else `'outline'`.\n */\n appearance?: InputAppearance;\n /** Name of the value in form submissions (renders a hidden input). */\n name?: string;\n /** Id of the form the value belongs to, when the Dropdown is outside it. */\n form?: string;\n /** A value is required to submit the form (native constraint validation). */\n required?: boolean;\n /**\n * Shows a clear button while a value is selected (shown disabled while `disabled`). It clears\n * the value, closes the list and moves focus to the combobox button. It is a tab stop after it.\n * @default false\n */\n clearable?: boolean;\n /** The name of the clear button, for localization. Unset members keep their English defaults. */\n labels?: DropdownLabels;\n /** Called when the `<button role=\"combobox\">` receives focus (the root keeps other handlers). */\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n /** Called when the `<button role=\"combobox\">` loses focus. */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /**\n * Called on a key press on the `<button role=\"combobox\">`, before the built-in listbox keys;\n * `event.preventDefault()` skips them.\n */\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Called when a key is released on the `<button role=\"combobox\">`. */\n onKeyUp?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Ref to the `<button role=\"combobox\">` (the focusable element). */\n controlRef?: React.Ref<HTMLButtonElement>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst DropdownRoot = (props: DropdownProps) => {\n const {\n value: valueProp,\n defaultValue,\n onValueChange,\n onOptionSelect,\n open: openProp,\n defaultOpen,\n onOpenChange,\n placeholder = 'Select an option',\n disabled = false,\n size: sizeProp,\n appearance: appearanceProp,\n name,\n form,\n required,\n clearable = false,\n labels,\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 children,\n ref,\n ...rest\n } = props;\n\n if (onOptionSelect !== undefined) warnDeprecated('Dropdown', 'onOptionSelect', 'onValueChange');\n\n const field = useFieldContext();\n const isRequired = required ?? field?.required ?? false;\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 const { size, appearance } = useInputLook(sizeProp, appearanceProp);\n\n const [value, setValue] = useControllable(valueProp, defaultValue ?? '', onValueChange);\n // A dropdown that starts disabled never shows its list, so it starts closed (no close to report\n // later).\n const [openState, setOpen] = useControllable(\n openProp,\n (defaultOpen ?? false) && !disabled,\n onOpenChange,\n );\n const open = openState && !disabled;\n // Disabling also closes the list itself, not only the derived `open`, so enabling it again does\n // not reopen it without a user action. The close is reported through onOpenChange (a consumer\n // callback from an effect, C-HOOKS); a controlled `open` that stays true is not shown meanwhile.\n const lockedOpen = disabled && openState;\n React.useEffect(() => {\n if (lockedOpen) setOpen(false);\n }, [lockedOpen, setOpen]);\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const buttonRef = React.useRef<HTMLButtonElement | null>(null);\n\n const optionLabels = React.useMemo(() => collectOptionLabels(children), [children]);\n\n const listbox = useListbox({\n open,\n onOpenChange: (next) => setOpen(next),\n mode: 'select-only',\n selectedValues: value ? [value] : [],\n onSelect: (next) => {\n setValue(next);\n onOptionSelect?.(next);\n },\n idPrefix: 'dropdown-listbox',\n });\n\n const expanded = open && listbox.items.length > 0;\n const { layerId, setReference, surfaceRef, floatingProps } = useListboxPopup({\n open,\n surfaceOpen: expanded,\n onDismiss: () => setOpen(false),\n rootRef,\n anchorRef: buttonRef,\n });\n\n const rootMergedRef = useMergedRefs<HTMLDivElement>(rootRef, ref);\n const buttonMergedRef = useMergedRefs<HTMLButtonElement>(buttonRef, controlRef, setReference);\n\n useFormReset(buttonRef, () => setValue(defaultValue ?? ''), form);\n\n const displayText = value ? (listbox.getItem(value)?.label ?? optionLabels.get(value) ?? '') : '';\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Escape' && open && !expanded && !event.nativeEvent.isComposing) {\n // Open with nothing shown (no options): close, but leave Escape to an enclosing layer\n // (overlays#1) instead of consuming it for an invisible list.\n setOpen(false);\n return;\n }\n listbox.onKeyDown(event);\n };\n\n // The button disappears with the value, so focus moves to the combobox explicitly (C-DISABLED).\n const handleClear = () => {\n setValue('');\n setOpen(false);\n buttonRef.current?.focus();\n };\n\n const showClear = clearable && value !== '';\n\n const listLabelledBy =\n fieldProps['aria-label'] === undefined\n ? (fieldProps['aria-labelledby'] ?? field?.labelId)\n : fieldProps['aria-labelledby'];\n\n return (\n <div\n data-size={size}\n data-appearance={appearance}\n {...rest}\n ref={rootMergedRef}\n className={cn(dropdownClassNames.root, 'relative inline-flex flex-col', className)}\n >\n <div className=\"relative flex items-center\">\n <button\n type=\"button\"\n {...fieldProps}\n {...listbox.getComboboxProps()}\n aria-expanded={expanded}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n ref={buttonMergedRef}\n disabled={disabled}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n onClick={() => setOpen((current) => !current)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={composeEventHandlers(onKeyUp, listbox.onKeyUp)}\n onFocus={onFocus}\n onBlur={onBlur}\n className={cn(\n dropdownClassNames.button,\n // Every padding is set here (C-NATIVE), not left to an app-wide `button` rule. The end\n // padding keeps the text clear of the chevron (and of the clear button while it shows).\n 'relative flex w-full items-center justify-between py-0 text-start',\n inputHeightClasses[size],\n inputPaddingClasses[size],\n inputTextClasses[size],\n inputAppearanceClasses[appearance],\n 'text-foreground',\n pickerEndPadding(showClear ? 2 : 1, size),\n inputFocus,\n disabledStyles,\n invalidLook && inputInvalid,\n )}\n >\n <span\n className={cn(\n dropdownClassNames.value,\n 'truncate',\n !displayText && 'text-muted-foreground',\n )}\n >\n {displayText || placeholder}\n </span>\n <ChevronDownIcon\n size={pickerGlyphSize(size, 'chevron')}\n className={cn(\n dropdownClassNames.expandIcon,\n 'absolute transition-transform motion-reduce:transition-none',\n size === 'small' ? 'end-2' : 'end-3',\n expanded && 'rotate-180',\n )}\n />\n </button>\n {showClear && (\n <button\n type=\"button\"\n aria-label={labels?.clear ?? 'Clear selection'}\n disabled={disabled}\n // Keeps focus on the combobox while the pointer clears it.\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n className={cn(\n dropdownClassNames.clearButton,\n pickerIconButtonClasses(size, appearance),\n pickerButtonOffset(size, 2),\n focusRing,\n disabledStyles,\n )}\n >\n <DismissIcon size={pickerGlyphSize(size, 'icon')} />\n </button>\n )}\n </div>\n <ListboxSurface\n listbox={listbox}\n layerId={layerId}\n surfaceRef={surfaceRef}\n floatingProps={floatingProps}\n open={open}\n expanded={expanded}\n listboxClassName={dropdownClassNames.listbox}\n surfaceClassName={dropdownClassNames.surface}\n aria-label={fieldProps['aria-label']}\n aria-labelledby={listLabelledBy}\n >\n {children}\n </ListboxSurface>\n <HiddenInput\n name={name}\n form={form}\n disabled={disabled}\n value={value}\n type=\"text\"\n required={isRequired}\n onInvalid={() => buttonRef.current?.focus()}\n />\n </div>\n );\n};\nDropdownRoot.displayName = 'Dropdown';\n\n/** Flat name of `Dropdown.Option` for React Server Components. */\nexport const DropdownOption = Option;\n/** Flat name of `Dropdown.OptionGroup` for React Server Components. */\nexport const DropdownOptionGroup = OptionGroup;\n\n/**\n * A select-only combobox (APG): a button that opens a listbox of `Option`s. Enter, Space,\n * ArrowDown/ArrowUp, Home/End and typing a character open it and move the highlight\n * (`aria-activedescendant`); Enter/Space select, Tab selects the highlighted option and moves on,\n * Escape closes. `clearable` adds a clear button, a tab stop after the combobox button; both sit\n * in a wrapper `<div>` inside the root.\n *\n * The `<button>` receives `id`, `aria-label`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, `aria-required`, `aria-errormessage`, `aria-details`, `tabIndex`, `autoFocus`\n * and `onFocus`/`onBlur`/`onKeyDown`/`onKeyUp`. `ref`, `className`, `style`, other `aria-*`\n * attributes and the remaining props stay on the root `<div>`. Inside a `Field` the button is\n * labelled and described by it — otherwise give it an `aria-label`. It shows the error look\n * whenever it ends up `aria-invalid` (its own `aria-invalid` or a `Field` error). With\n * `name`/`required` the value takes part in form submission, validation and reset. The open\n * listbox renders in a portal; while closed it stays in the DOM, hidden.\n *\n * **Size and appearance**: `size` resolves from its own prop, then the surrounding `Field`'s\n * `size`, then `WaveProvider inputDefaults.size`, else `'medium'`; `appearance` from its own prop,\n * then `WaveProvider inputDefaults.appearance`, else `'outline'`; both render as `data-size` and\n * `data-appearance` on the root `<div>`. The listbox keeps its size.\n *\n * Sub-components: `Dropdown.Option`, `Dropdown.OptionGroup`. React Server Components import the\n * flat names `DropdownOption` / `DropdownOptionGroup` (dotted access needs a client file).\n */\nexport const Dropdown = /* @__PURE__ */ Object.assign(DropdownRoot, {\n Option,\n OptionGroup,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyIA,IAAMC,KAAgB,MAAyB;CAC7C,IAAM,EACJ,OAAOC,GACP,iBACA,kBACA,mBACA,MAAMC,GACN,gBACA,iBACA,iBAAc,oBACd,cAAW,IACX,MAAMC,GACN,YAAYC,GACZ,SACA,SACA,aACA,eAAY,IACZ,WACA,cACA,aACA,OACA,cAAcC,GACd,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,iBAAiBC,IACjB,qBAAqBC,IACrB,gBAAgBC,IAChB,aACA,YACA,eACA,aACA,gBACA,eACA,aACA,SACA,GAAGC,OACDC;CAEJ,AAAIC,MAAmB,KAAA,KAAWC,GAAe,YAAY,kBAAkB,eAAe;CAE9F,IAAMC,IAAQC,GAAgB,GACxBC,KAAaC,KAAYH,GAAO,YAAY,IAC5CI,IAAaC,GAAgB;EACjC;EACA,cAAchB;EACd,mBAAmBC;EACnB,oBAAoBC;EACpB,gBAAgBC;EAGhB,iBAAiBC,MAAgBU;CACnC,CAAC,GAEKG,KAAcC,EAAc,IAAOH,EAAW,eAAe,GAC7D,EAAE,SAAM,kBAAeI,EAAarB,GAAUC,CAAc,GAE5D,CAACqB,GAAOC,KAAYC,EAAgB1B,GAAW2B,KAAgB,IAAIC,CAAa,GAGhF,CAACC,GAAWC,KAAWJ,EAC3BzB,IACC8B,KAAe,OAAU,CAACC,GAC3BC,CACF,GACMC,IAAOL,KAAa,CAACG,GAIrBG,IAAaH,KAAYH;CAC/B,EAAM,gBAAgB;EACpB,AAAIM,KAAYL,EAAQ,EAAK;CAC/B,GAAG,CAACK,GAAYL,CAAO,CAAC;CAExB,IAAMM,IAAUtC,EAAM,OAA8B,IAAI,GAClDuC,IAAYvC,EAAM,OAAiC,IAAI,GAEvDwC,KAAexC,EAAM,cAAcyC,GAAoBC,CAAQ,GAAG,CAACA,CAAQ,CAAC,GAE5EC,IAAUC,GAAW;EACzB;EACA,eAAe,MAASZ,EAAQa,CAAI;EACpC,MAAM;EACN,gBAAgBnB,IAAQ,CAACA,CAAK,IAAI,CAAC;EACnC,WAAW,MAAS;GAElB,AADAC,EAASkB,CAAI,GACb9B,IAAiB8B,CAAI;EACvB;EACA,UAAU;CACZ,CAAC,GAEKC,IAAWV,KAAQO,EAAQ,MAAM,SAAS,GAC1C,EAAE,YAAS,kBAAc,gBAAY,sBAAkBI,GAAgB;EAC3E;EACA,aAAaD;EACb,iBAAiBd,EAAQ,EAAK;EAC9B;EACA,WAAWO;CACb,CAAC,GAEKS,KAAgBC,EAA8BX,GAASY,EAAG,GAC1DC,KAAkBF,EAAiCV,GAAWa,IAAYC,EAAY;CAE5F,EAAad,SAAiBZ,EAASE,KAAgB,EAAE,GAAGyB,CAAI;CAEhE,IAAMC,IAAc7B,IAASiB,EAAQ,QAAQjB,CAAK,CAAC,EAAE,SAASc,GAAa,IAAId,CAAK,KAAK,KAAM,IAEzF8B,MAAiB,MAAkD;EACvE,IAAIC,EAAM,QAAQ,YAAYrB,KAAQ,CAACU,KAAY,CAACW,EAAM,YAAY,aAAa;GAGjF,EAAQ,EAAK;GACb;EACF;EACA,EAAQ,UAAUA,CAAK;CACzB,GAGMC,WAAoB;EAGxB,AAFA/B,EAAS,EAAE,GACXK,EAAQ,EAAK,GACbO,EAAU,SAAS,MAAM;CAC3B,GAEMoB,IAAYC,KAAalC,MAAU,IAEnCmC,KACJxC,EAAW,kBAAkB,KAAA,IACxBA,EAAW,sBAAsBJ,GAAO,UACzCI,EAAW;CAEjB,OACE,kBAAC,OAAD;EACE,aAAWyC;EACX,mBAAiBC;EACjB,GAAIlD;EACJ,KAAKmC;EACL,WAAWgB,EAAGC,EAAmB,MAAM,iCAAiCC,EAAS;EALnF,UAAA;GAOE,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,GAAI7C;KACJ,GAAIsB,EAAQ,iBAAiB;KAC7B,iBAAeG;KACf,qBAAmBnC;KACnB,gBAAcC;KACd,KAAKuC;KACK;KACC;KACD;KACV,eAAenB,GAAS,MAAY,CAACmC,CAAO;KAC5C,WAAWC,EAAqBC,IAAWb,EAAa;KACxD,SAASY,EAAqBE,IAAS3B,EAAQ,OAAO;KAC7C;KACD;KACR,WAAWqB,EACTC,EAAmB,QAGnB,qEACAM,GAAmBT,IACnBU,GAAoBV,IACpBW,GAAiBX,IACjBY,GAAuBX,IACvB,mBACAY,GAAiBhB,IAAY,IAAI,GAAGG,CAAI,GACxCc,IACAC,IACAtD,MAAA,oBACF;KA9BF,UAAA,CAgCE,kBAAC,QAAD;MACE,WAAWyC,EACTC,EAAmB,OACnB,YACA,CAACV,KAAe,uBAClB;MAEC,UAAAA,KAAeuB;KACZ,CAAA,GACN,kBAACC,IAAD;MACE,MAAMC,EAAgBlB,GAAM,SAAS;MACrC,WAAWE,EACTC,EAAmB,YACnB,+DACAH,MAAS,UAAU,UAAU,SAC7BhB,KAAY,YACd;KACD,CAAA,CACK;IACP,CAAA,GAAAa,KACC,kBAAC,UAAD;KACE,MAAK;KACL,cAAYsB,GAAQ,SAAS;KACnB;KAEV,cAAc,MAAUxB,EAAM,eAAe;KAC7C,SAASC;KACT,WAAWM,EACTC,EAAmB,aACnBiB,GAAwBpB,GAAMC,CAAU,GACxCoB,GAAmBrB,GAAM,CAAC,GAAA,qFAAA,mJAG5B;KAEA,UAAA,kBAACsB,IAAD,EAAa,MAAMJ,EAAgBlB,GAAM,MAAM,EAAI,CAAA;IAC7C,CAAA,CAEP;;GACL,kBAACuB,IAAD;IACW;IACA;IACG;IACG;IACT;IACI;IACV,kBAAkBpB,EAAmB;IACrC,kBAAkBA,EAAmB;IACrC,cAAY5C,EAAW;IACvB,mBAAiBwC;IAEhB;GACa,CAAA;GAChB,kBAACyB,IAAD;IACQ;IACA;IACI;IACH;IACP,MAAK;IACL,UAAUnE;IACV,iBAAiBoB,EAAU,SAAS,MAAM;GAC3C,CAAA;EACE;;AAET;AACA,EAAa,cAAc;AAG3B,IAAagD,IAAiBC,GAEjBC,IAAsBC,GA0BtBC,IAA2B,uBAAO,OAAO1F,GAAc;CAClE;CACA;AACF,CAAC"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../hooks/useId.cjs"),a=require("../../lib/aria.cjs"),o=require("../../hooks/useFieldControl.cjs"),s=require("../../lib/icons.cjs");let c=require("react");c=e.__toESM(c,1);let l=require("react/jsx-runtime");var u=new Set([`button`,`input`,`meter`,`output`,`progress`,`select`,`textarea`]),d=new Set([`button`,`image`,`reset`,`submit`]),f=new Set([`caption`,`code`,`deletion`,`emphasis`,`generic`,`insertion`,`none`,`paragraph`,`presentation`,`strong`,`subscript`,`superscript`]),p=new Set([`checkbox`,`columnheader`,`combobox`,`gridcell`,`listbox`,`radiogroup`,`rowheader`,`searchbox`,`spinbutton`,`switch`,`textbox`,`tree`,`treegrid`]);function m(e){if(typeof e==`string`)return e.trim().split(/\s+/)[0]?.toLowerCase()||void 0}function h(e){return typeof e==`string`&&e.includes(`-`)}function g(e,t){return e===`select`||e===`textarea`?!0:e===`input`?typeof t!=`string`||!d.has(t.trim().toLowerCase()):!1}function _(e){if(typeof e.type!=`string`)return!0;let t=m(e.props.role);return t===void 0?g(e.type,e.props.type):p.has(t)}function v(e){if(e.type===c.Fragment)return;if(typeof e.type!=`string`||u.has(e.type))return`label-for`;let t=m(e.props.role);return t===void 0?h(e.type)?`label-for`:void 0:f.has(t)?void 0:`labelledby`}function y(e){let t,n=0;c.Children.forEach(e,e=>{c.isValidElement(e)&&(n+=1,t===void 0&&(t=e))});let r=t?v(t):void 0;return{target:r?t:void 0,mode:r,elementCount:n}}function b(e,t){let{target:n,mode:r}=y(e);if(!n||!r)return c.Children.map(e,e=>e);let i=n.props,o=!h(n.type)||`true`,s={};return r===`label-for`?i.id===void 0&&(s.id=t.controlId):t.labelId!==void 0&&i[`aria-label`]===void 0&&(s[`aria-labelledby`]=a.joinIds(i[`aria-labelledby`],t.labelId)),(t.messageId||t.hintId)&&(s[`aria-describedby`]=a.joinIds(i[`aria-describedby`],t.messageId,t.hintId)),t.invalid&&i[`aria-invalid`]===void 0&&(s[`aria-invalid`]=o),t.required&&i.required!==!1&&(i[`aria-required`]===void 0&&_(n)&&(s[`aria-required`]=o),typeof n.type==`string`&&g(n.type,i.type)&&i.required===void 0&&(s.required=!0)),c.Children.map(e,e=>e===n?c.cloneElement(n,s):e)}function x(e){let{target:t,mode:n,elementCount:r}=y(e),i=n===`label-for`;return{elementCount:r,targetId:i?t?.props.id:void 0,controlIdAssigned:i}}var S={error:s.ErrorIcon,warning:s.WarningIcon,success:s.SuccessIcon,none:null},C={error:`text-error`,warning:`text-warning-tint-foreground`,success:`text-success-tint-foreground`,none:`text-muted-foreground`},w=`[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-1.5`,T=`mt-0.5 inline-flex shrink-0`;function E(e,t){if(t!==void 0)return r.slotRendersContent(t)?r.renderSlot(t,`span`,T,{"aria-hidden":!0}):null;let n=S[e];return n?(0,l.jsx)(`span`,{"aria-hidden":`true`,className:T,children:(0,l.jsx)(n,{size:12})}):null}var D=({label:e,hint:a,error:s,validationState:u,validationMessage:d,validationMessageIcon:f,orientation:p=`vertical`,required:m=!1,htmlFor:h,className:g,children:_,ref:v,...y})=>{let S=i.useId(`field`),[T]=c.useState(o.createFieldControlIdClaim),{elementCount:D,targetId:O,controlIdAssigned:k}=x(_),A=r.slotRendersContent(s),j=s===!0||A,M=r.slotRendersContent(d),N=j?`error`:u??(M?`error`:`none`),P=j?A?s:void 0:d,F=j?A:M,I=N===`error`,L=r.slotRendersContent(a),R=j&&(M||u!==void 0&&u!==`error`),z=O??h??S,B=r.slotRendersContent(e),V=B?`${S}-label`:void 0,H=F?`${S}-${I?`error`:`message`}`:void 0,U=I?H:void 0,W=I&&F,G=L?`${S}-hint`:void 0;c.useEffect(()=>{D>1&&n.warnOnce(`Field:multiple-children`,`Field: only the first element child receives the Field's id and ARIA attributes; the other ${D-1} element child(ren) are rendered unchanged. Wrap each control in its own Field.`)},[D]),c.useEffect(()=>{R&&n.warnOnce(`Field:error-and-validation`,"Field: `error` and `validationMessage`/`validationState` are both set; `error` wins. Use one of them.")},[R]);let K=c.useMemo(()=>({controlId:z,labelId:V,hintId:G,errorId:U,invalid:I,required:m,hasErrorMessage:W,controlIdAssigned:k,controlIdClaim:T,validationState:N,validationMessageId:H}),[z,V,G,U,I,m,W,k,T,N,H]),q=b(_,{controlId:z,labelId:V,messageId:H,hintId:G,invalid:I,required:m}),J=p===`horizontal`,Y=(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(o.FieldContext.Provider,{value:K,children:q}),F?(0,l.jsxs)(`p`,{id:H,role:N===`error`||N===`warning`?`alert`:void 0,"data-validation-state":N,className:t.cn(`mt-1 flex items-start gap-1 text-caption-1`,C[N]),children:[E(N,f),(0,l.jsx)(`span`,{children:r.materialiseSlotContent(P)})]},`message-${N}`):null,L?(0,l.jsx)(`p`,{id:G,className:`mt-1 text-caption-1 text-muted-foreground`,children:r.materialiseSlotContent(a)},`hint`):null]});return(0,l.jsxs)(`div`,{ref:v,"data-orientation":p,"data-validation-state":N,className:t.cn(`flex`,J?`flex-row items-start gap-x-3`:`flex-col`,g),...y,children:[B?(0,l.jsxs)(`label`,{id:V,htmlFor:z,className:t.cn(`mb-1 text-body-1 font-semibold text-foreground`,J&&`mb-0 shrink-0 basis-1/3 pt-1.5`),children:[r.materialiseSlotContent(e),m&&(0,l.jsx)(`span`,{"aria-hidden":`true`,className:`ms-0.5 text-error`,children:`*`})]}):null,J?(0,l.jsx)(`div`,{className:t.cn(`flex min-w-0 flex-1 flex-col`,w),children:Y}):Y]})};D.displayName=`Field`,exports.Field=D;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useId.cjs"),o=require("../../lib/aria.cjs"),s=require("../../hooks/useFieldControl.cjs"),c=require("../provider/WaveProvider.cjs"),l=require("../../lib/icons.cjs"),ee=require("./fieldLabel.cjs");let u=require("react");u=e.__toESM(u,1);let d=require("react/jsx-runtime");var f=new Set([`button`,`input`,`meter`,`output`,`progress`,`select`,`textarea`]),p=new Set([`button`,`image`,`reset`,`submit`]),m=new Set([`caption`,`code`,`deletion`,`emphasis`,`generic`,`insertion`,`none`,`paragraph`,`presentation`,`strong`,`subscript`,`superscript`]),h=new Set([`checkbox`,`columnheader`,`combobox`,`gridcell`,`listbox`,`radiogroup`,`rowheader`,`searchbox`,`spinbutton`,`switch`,`textbox`,`tree`,`treegrid`]);function g(e){if(typeof e==`string`)return e.trim().split(/\s+/)[0]?.toLowerCase()||void 0}function _(e){return typeof e==`string`&&e.includes(`-`)}function v(e,t){return e===`select`||e===`textarea`?!0:e===`input`?typeof t!=`string`||!p.has(t.trim().toLowerCase()):!1}function y(e){if(typeof e.type!=`string`)return!0;let t=g(e.props.role);return t===void 0?v(e.type,e.props.type):h.has(t)}function b(e){if(e.type===u.Fragment)return;if(typeof e.type!=`string`||f.has(e.type))return`label-for`;let t=g(e.props.role);return t===void 0?_(e.type)?`label-for`:void 0:m.has(t)?void 0:`labelledby`}function x(e){let t,n=0;u.Children.forEach(e,e=>{u.isValidElement(e)&&(n+=1,t===void 0&&(t=e))});let r=t?b(t):void 0;return{target:r?t:void 0,mode:r,elementCount:n}}function S(e,t){let{target:n,mode:r}=x(e);if(!n||!r)return u.Children.map(e,e=>e);let i=n.props,a=!_(n.type)||`true`,s={};return r===`label-for`?i.id===void 0&&(s.id=t.controlId):t.labelId!==void 0&&i[`aria-label`]===void 0&&(s[`aria-labelledby`]=o.joinIds(i[`aria-labelledby`],t.labelId)),(t.messageId||t.hintId)&&(s[`aria-describedby`]=o.joinIds(i[`aria-describedby`],t.messageId,t.hintId)),t.invalid&&i[`aria-invalid`]===void 0&&(s[`aria-invalid`]=a),t.required&&i.required!==!1&&(i[`aria-required`]===void 0&&y(n)&&(s[`aria-required`]=a),typeof n.type==`string`&&v(n.type,i.type)&&i.required===void 0&&(s.required=!0)),u.Children.map(e,e=>e===n?u.cloneElement(n,s):e)}function te(e){let{target:t,mode:n,elementCount:r}=x(e),i=n===`label-for`;return{elementCount:r,targetId:i?t?.props.id:void 0,controlIdAssigned:i}}var C={error:l.ErrorIcon,warning:l.WarningIcon,success:l.SuccessIcon,none:null},w={error:`text-error`,warning:`text-warning-tint-foreground`,success:`text-success-tint-foreground`,none:`text-muted-foreground`},T={small:`text-caption-1`,medium:`text-body-1`,large:`text-body-2`},ne={small:`pt-1`,medium:`pt-1.5`,large:`pt-2.25`},re={small:`[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-0.5`,medium:`[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-1.5`,large:`[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-2.5`};function E(e,n){let r=e.props,i={htmlFor:n.controlId,className:t.cn(n.className,r.className)};return r.id||(i.id=n.labelId),r.required===void 0&&n.required&&(i.required=!0),r.size===void 0&&(i.size=n.size),r.weight===void 0&&(i.weight=`semibold`),u.cloneElement(e,i)}var D=`mt-0.5 inline-flex shrink-0`;function ie(e,n){if(n!==void 0)return r.slotRendersContent(n)?r.renderSlot(n,`span`,t.cn(i.fieldClassNames.validationMessageIcon,D),{"aria-hidden":!0}):null;let a=C[e];return a?(0,d.jsx)(`span`,{"aria-hidden":`true`,className:t.cn(i.fieldClassNames.validationMessageIcon,D),children:(0,d.jsx)(a,{size:12})}):null}var O=({label:e,hint:o,error:l,validationState:f,validationMessage:p,validationMessageIcon:m,orientation:h=`vertical`,size:g,required:_=!1,htmlFor:v,className:y,children:b,ref:x,...C})=>{let D=a.useId(`field`),[O]=u.useState(s.createFieldControlIdClaim),{elementCount:k,targetId:ae,controlIdAssigned:A}=te(b),{inputDefaults:oe}=c.useWaveTheme(),j=g??oe.size??`medium`,M=r.slotRendersContent(l),N=l===!0||M,P=r.slotRendersContent(p),F=N?`error`:f??(P?`error`:`none`),I=N?M?l:void 0:p,L=N?M:P,R=F===`error`,z=r.slotRendersContent(o),B=N&&(P||f!==void 0&&f!==`error`),V=ee.isFieldLabelElement(e)?e:void 0,H=V?.props.htmlFor||void 0,U=ae??v??H??D,W=H!==void 0&&H!==U,G=r.slotRendersContent(e),K=G?V?.props.id||`${D}-label`:void 0,q=L?`${D}-${R?`error`:`message`}`:void 0,J=R?q:void 0,Y=R&&L,X=z?`${D}-hint`:void 0;u.useEffect(()=>{k>1&&n.warnOnce(`Field:multiple-children`,`Field: only the first element child receives the Field's id and ARIA attributes; the other ${k-1} element child(ren) are rendered unchanged. Wrap each control in its own Field.`)},[k]),u.useEffect(()=>{B&&n.warnOnce(`Field:error-and-validation`,"Field: `error` and `validationMessage`/`validationState` are both set; `error` wins. Use one of them.")},[B]),u.useEffect(()=>{W&&n.warnOnce(`Field:label-htmlFor`,"Field: the label element's `htmlFor` points at a different element than the Field's control, which would leave the control unnamed; Field points it at the control. Remove it, or give the control that id.")},[W]);let se=u.useMemo(()=>({controlId:U,labelId:K,hintId:X,errorId:J,invalid:R,required:_,hasErrorMessage:Y,controlIdAssigned:A,controlIdClaim:O,validationState:F,validationMessageId:q,size:g}),[U,K,X,J,R,_,Y,A,O,F,q,g]),ce=S(b,{controlId:U,labelId:K,messageId:q,hintId:X,invalid:R,required:_}),Z=h===`horizontal`,Q=Z&&t.cn(`mb-0 shrink-0 basis-1/3`,ne[j]),$=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(s.FieldContext.Provider,{value:se,children:ce}),L?(0,d.jsxs)(`p`,{id:q,role:F===`error`||F===`warning`?`alert`:void 0,"data-validation-state":F,className:t.cn(i.fieldClassNames.validationMessage,`mt-1 flex items-start gap-1 text-caption-1`,w[F]),children:[ie(F,m),(0,d.jsx)(`span`,{children:r.materialiseSlotContent(I)})]},`message-${F}`):null,z?(0,d.jsx)(`p`,{id:X,className:t.cn(i.fieldClassNames.hint,`mt-1 text-caption-1 text-muted-foreground`),children:r.materialiseSlotContent(o)},`hint`):null]});return(0,d.jsxs)(`div`,{ref:x,"data-orientation":h,"data-size":j,"data-validation-state":F,className:t.cn(i.fieldClassNames.root,`flex`,Z?`flex-row items-start gap-x-3`:`flex-col`,y),...C,children:[V?E(V,{controlId:U,labelId:K,required:_,size:j,className:t.cn(i.fieldClassNames.label,`mb-1`,Q)}):G?(0,d.jsxs)(`label`,{id:K,htmlFor:U,className:t.cn(i.fieldClassNames.label,`mb-1 font-semibold text-foreground`,T[j],Q),children:[r.materialiseSlotContent(e),_&&(0,d.jsx)(`span`,{"aria-hidden":`true`,className:t.cn(i.fieldClassNames.required,`ms-0.5 text-error`),children:`*`})]}):null,Z?(0,d.jsx)(`div`,{className:t.cn(`flex min-w-0 flex-1 flex-col`,re[j]),children:$}):$]})};O.displayName=`Field`,exports.Field=O;
2
2
  //# sourceMappingURL=Field.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Field.cjs","names":["React","joinIds","ErrorIcon","WarningIcon","SuccessIcon","slotRendersContent","renderSlot","useId","createFieldControlIdClaim","_Fragment","FieldContext","cn","materialiseSlotContent","require_runtime","require_cn","require_dev","require_slot","require_useId","require_aria","require_useFieldControl","require_icons","react","react_jsx_runtime","LABELABLE_ELEMENTS","BUTTON_INPUT_TYPES","UNNAMED_ROLES","ARIA_REQUIRED_ROLES","explicitRole","role","isCustomElement","type","isNativeValueControl","tag","inputType","supportsAriaRequired","child","getMergeMode","inspectChildren","first","elementCount","children","mode","mergeIntoFirstChild","target","childProps","ariaTrue","injected","state","getChildInfo","assigned","MESSAGE_ICONS","MESSAGE_COLORS","SHORT_ROW_FIRST_CHILD","MESSAGE_ICON_CLASSES","renderMessageIcon","icon","Icon","Field","rest","fieldId","controlIdClaim","errorRendersContent","error","usesError","validationMessageRendersContent","validationMessage","validationState","message","hasMessage","invalid","hasHint","hint","errorAndValidation","controlId","targetId","htmlFor","hasLabel","label","labelId","messageId","errorId","hasErrorMessage","hintId","context","required","controlIdAssigned","content","horizontal","orientation","control","validationMessageIcon","className"],"sources":["../../../src/components/input/Field.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { warnOnce } from '../../lib/dev';\nimport { ErrorIcon, SuccessIcon, WarningIcon, type IconComponent } from '../../lib/icons';\nimport { materialiseSlotContent, renderSlot, slotRendersContent, type Slot } from '../../lib/slot';\nimport type { Orientation, ValidationState } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport {\n FieldContext,\n createFieldControlIdClaim,\n type FieldContextValue,\n} from '../../hooks/useFieldControl';\n\n/** Props Field reads from and merges into its first element child. */\ninterface InjectedFieldProps {\n id?: string;\n role?: string;\n type?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Properties for the Field component. */\nexport interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Label displayed above the control (beside it with `orientation=\"horizontal\"`); names the\n * control.\n */\n label?: React.ReactNode;\n /** Hint shown below the control, after any validation message; describes the control. */\n hint?: React.ReactNode;\n /**\n * Validation error. Content is rendered below the control in a `role=\"alert\"` element that\n * describes the control, and the control is marked `aria-invalid`. `true` marks the control\n * invalid without a message. A value that renders nothing (`null`, `false`, `''`, or an array of\n * only those, such as an empty `errors.map(…)`) is no error; `0` is content.\n *\n * Shorthand for `validationState=\"error\"` with this message; wins over `validationMessage` and\n * `validationState` (development warning when both are set).\n */\n error?: React.ReactNode;\n /**\n * Validation state of `validationMessage`: `error` marks the control invalid (`aria-invalid`) and\n * announces the message (`role=\"alert\"`); `warning` announces it without marking the control\n * invalid; `success` and `none` show it without announcing. Default: `'error'` when\n * `validationMessage` renders content, else `'none'`. Ignored while `error` is set.\n */\n validationState?: ValidationState;\n /**\n * Message below the control, styled and announced by `validationState`; it describes the control\n * (`aria-describedby`). `error` is the shorthand for an error message and wins over this prop.\n */\n validationMessage?: React.ReactNode;\n /**\n * Icon before the message. Default: an error, warning or success glyph per state; none for\n * `'none'`. `null` (or content that renders nothing) shows no icon. Decorative (`aria-hidden`).\n */\n validationMessageIcon?: Slot<'span'>;\n /**\n * `vertical`: the label above the control. `horizontal`: the label in a start column (a third\n * of the width) beside the control; the message and the hint stay below the control. The\n * label's first line lines up with a 32px control (Input, Select, …) and with the first line of\n * a Checkbox, Switch or RadioGroup, which gets 6px of padding above and below for it. The\n * horizontal layout wraps the control in a column, so changing `orientation` on a mounted Field\n * remounts the control: an uncontrolled control loses its state and focus (control it, or keep\n * one orientation while the Field is mounted).\n * @default 'vertical'\n */\n orientation?: Orientation;\n /**\n * Whether the field is required: shows a decorative asterisk next to the label, sets\n * `aria-required`, and turns on native constraint validation. `<input>`, `<select>`,\n * `<textarea>` and Input, Select, Textarea, Slider, SearchBox and SpinButton get the native\n * `required` attribute. Checkbox, Switch, RadioGroup, Rating, ColorPicker, SwatchPicker,\n * Combobox, Dropdown, TagPicker, DatePicker and TimePicker render a hidden required input (with\n * or without `name`), so submit is blocked until they are checked, switched on or have a value.\n * An explicit `required={false}` on the control wins, including for `aria-required`.\n */\n required?: boolean;\n /**\n * The id of the control the label points at, when the control has no `id` of its own\n * (default: a generated id).\n */\n htmlFor?: string;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Intrinsic elements a `<label htmlFor>` can name (HTML \"labelable elements\"). */\nconst LABELABLE_ELEMENTS: ReadonlySet<string> = new Set([\n 'button',\n 'input',\n 'meter',\n 'output',\n 'progress',\n 'select',\n 'textarea',\n]);\n\n/** `<input>` types whose implicit role is `button`: they take neither `aria-required` nor `required`. */\nconst BUTTON_INPUT_TYPES: ReadonlySet<string> = new Set(['button', 'image', 'reset', 'submit']);\n\n/**\n * Roles that cannot be named (ARIA 1.2 \"name prohibited\") or that remove semantics: an element\n * with one of them is a layout wrapper, not a widget, and Field leaves it alone.\n */\nconst UNNAMED_ROLES: ReadonlySet<string> = new Set([\n 'caption',\n 'code',\n 'deletion',\n 'emphasis',\n 'generic',\n 'insertion',\n 'none',\n 'paragraph',\n 'presentation',\n 'strong',\n 'subscript',\n 'superscript',\n]);\n\n/** Roles that support `aria-required` (ARIA 1.2, including the roles that inherit it). */\nconst ARIA_REQUIRED_ROLES: ReadonlySet<string> = new Set([\n 'checkbox',\n 'columnheader',\n 'combobox',\n 'gridcell',\n 'listbox',\n 'radiogroup',\n 'rowheader',\n 'searchbox',\n 'spinbutton',\n 'switch',\n 'textbox',\n 'tree',\n 'treegrid',\n]);\n\n/**\n * How Field merges into its first element child:\n * - `label-for`: components (library controls, consumer inputs, wrappers such as Tooltip),\n * labelable intrinsic elements (`<input>`, `<select>`, `<button>`, …) and role-less custom\n * elements (`<my-text-field>`, possibly form-associated). The child receives the `id` the\n * `<label htmlFor>` points at (unless it has its own id, which the label then uses).\n * - `labelledby`: an intrinsic element with an explicit widget `role` (a consumer's own\n * `<div role=\"radiogroup\">`). A `<label htmlFor>` cannot name it, so it is named through\n * `aria-labelledby` and receives no `id` (a library control inside it keeps the control id).\n */\ntype MergeMode = 'label-for' | 'labelledby';\n\n/** The first token of an explicit `role` attribute (lower case), or `undefined`. */\nfunction explicitRole(role: unknown): string | undefined {\n if (typeof role !== 'string') return undefined;\n return role.trim().split(/\\s+/)[0]?.toLowerCase() || undefined;\n}\n\n/** Whether `type` is an autonomous custom element (`<my-text-field>`): its tag name has a hyphen. */\nfunction isCustomElement(type: unknown): type is string {\n return typeof type === 'string' && type.includes('-');\n}\n\n/**\n * Whether an intrinsic element is a native form control that takes a value (`<select>`,\n * `<textarea>`, or an `<input>` that is not a button): it takes the native `required` attribute\n * and, without an explicit role, `aria-required`.\n */\nfunction isNativeValueControl(tag: string, inputType: unknown): boolean {\n if (tag === 'select' || tag === 'textarea') return true;\n if (tag !== 'input') return false;\n return typeof inputType !== 'string' || !BUTTON_INPUT_TYPES.has(inputType.trim().toLowerCase());\n}\n\n/**\n * Whether Field may add `aria-required` to `child`: a component (it may render any control and\n * decides where the attribute goes), an element whose explicit role supports it, or a native form\n * control that takes a value. Never a `<button>`, `<meter>`, `<output>`, `<progress>`, button-type\n * `<input>` or role-less custom element, where axe reports `aria-allowed-attr`.\n */\nfunction supportsAriaRequired(child: React.ReactElement<InjectedFieldProps>): boolean {\n if (typeof child.type !== 'string') return true;\n const role = explicitRole(child.props.role);\n if (role !== undefined) return ARIA_REQUIRED_ROLES.has(role);\n return isNativeValueControl(child.type, child.props.type);\n}\n\n/**\n * Whether and how Field merges its props into `child` (see {@link MergeMode}). A Fragment and a\n * role-less (or presentational) non-labelable intrinsic wrapper (`<div>`, `<span>`) are left\n * alone; the library control inside them reads `FieldContext`. A role-less custom element\n * (`<my-text-field>`) is treated like a component: it may be a form-associated element, which a\n * `<label htmlFor>` names.\n */\nfunction getMergeMode(child: React.ReactElement<InjectedFieldProps>): MergeMode | undefined {\n if (child.type === React.Fragment) return undefined;\n if (typeof child.type !== 'string' || LABELABLE_ELEMENTS.has(child.type)) return 'label-for';\n const role = explicitRole(child.props.role);\n if (role !== undefined) return UNNAMED_ROLES.has(role) ? undefined : 'labelledby';\n return isCustomElement(child.type) ? 'label-for' : undefined;\n}\n\ninterface FieldChildren {\n /** The element child Field merges into, or `undefined`. */\n target: React.ReactElement<InjectedFieldProps> | undefined;\n /** How Field merges into `target` (`undefined` when there is no target). */\n mode: MergeMode | undefined;\n /** How many element children there are (only the first one is merged). */\n elementCount: number;\n}\n\nfunction inspectChildren(children: React.ReactNode): FieldChildren {\n let first: React.ReactElement<InjectedFieldProps> | undefined;\n let elementCount = 0;\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement<InjectedFieldProps>(child)) return;\n elementCount += 1;\n if (first === undefined) first = child;\n });\n const mode = first ? getMergeMode(first) : undefined;\n return { target: mode ? first : undefined, mode, elementCount };\n}\n\n/** What Field merges into its first element child. */\ninterface FieldMergeState {\n controlId: string;\n labelId: string | undefined;\n /** The id of the rendered validation message, in any state. */\n messageId: string | undefined;\n hintId: string | undefined;\n /** Only the `error` validation state is invalid. */\n invalid: boolean;\n required: boolean;\n}\n\n/**\n * Returns `children` with Field's props merged into the merge target (only defined keys; the\n * child's own `id`, `aria-label`, `aria-invalid`, `aria-required` and `required` are kept, its\n * `aria-labelledby` and `aria-describedby` are joined with the message and the hint).\n */\nfunction mergeIntoFirstChild(children: React.ReactNode, state: FieldMergeState): React.ReactNode {\n const { target, mode } = inspectChildren(children);\n // Always map, so the children keep the same keys whether or not one of them is merged.\n if (!target || !mode) return React.Children.map(children, (child) => child);\n\n const childProps = target.props;\n // React renders a boolean `true` on a custom element as an empty attribute (`aria-invalid=\"\"`).\n const ariaTrue = isCustomElement(target.type) ? 'true' : true;\n const injected: InjectedFieldProps = {};\n if (mode === 'label-for') {\n if (childProps.id === undefined) injected.id = state.controlId;\n } else if (state.labelId !== undefined && childProps['aria-label'] === undefined) {\n injected['aria-labelledby'] = joinIds(childProps['aria-labelledby'], state.labelId);\n }\n if (state.messageId || state.hintId) {\n injected['aria-describedby'] = joinIds(\n childProps['aria-describedby'],\n state.messageId,\n state.hintId,\n );\n }\n // The child's own `aria-invalid` wins, as `useFieldControl` lets it win for a nested control.\n if (state.invalid && childProps['aria-invalid'] === undefined) {\n injected['aria-invalid'] = ariaTrue;\n }\n // A child's own `required={false}` wins: it gets neither `aria-required` nor `required`, so what\n // is announced matches what is validated.\n if (state.required && childProps.required !== false) {\n if (childProps['aria-required'] === undefined && supportsAriaRequired(target)) {\n injected['aria-required'] = ariaTrue;\n }\n if (\n typeof target.type === 'string' &&\n isNativeValueControl(target.type, childProps.type) &&\n childProps.required === undefined\n ) {\n injected.required = true;\n }\n }\n return React.Children.map(children, (child) =>\n child === target ? React.cloneElement(target, injected) : child,\n );\n}\n\n/** Primitive facts about the children, read during render (no element objects escape). */\nfunction getChildInfo(children: React.ReactNode): {\n elementCount: number;\n targetId: string | undefined;\n controlIdAssigned: boolean;\n} {\n const { target, mode, elementCount } = inspectChildren(children);\n // Only a label-for target holds the control id (Field merges it, or the target's own id becomes\n // the control id). A <label htmlFor> cannot name a role widget, so the library control inside\n // one keeps the control id. With `controlIdAssigned`, a library control that receives no id is\n // nested in the target or is a later sibling: useFieldControl gives it an id of its own and\n // names it through aria-labelledby.\n const assigned = mode === 'label-for';\n return {\n elementCount,\n targetId: assigned ? target?.props.id : undefined,\n controlIdAssigned: assigned,\n };\n}\n\n/** The default glyph of each message state (`none` has none). */\nconst MESSAGE_ICONS: Readonly<Record<ValidationState, IconComponent | null>> = {\n error: ErrorIcon,\n warning: WarningIcon,\n success: SuccessIcon,\n none: null,\n};\n\n/** Text color of each message state (the `*-tint-foreground` tokens keep 4.5:1 on page and card). */\nconst MESSAGE_COLORS: Readonly<Record<ValidationState, string>> = {\n error: 'text-error',\n warning: 'text-warning-tint-foreground',\n success: 'text-success-tint-foreground',\n none: 'text-muted-foreground',\n};\n\n/**\n * Horizontal layout: the label's first line is centred on a 32px row, the height of an Input, a\n * Select and the other text controls. Checkbox, Switch and RadioGroup rows are one 20px line, so a\n * first child that holds one (also a wrapper of several) gets 6px above and below: its first line\n * then lines up with the label's, also when its label wraps or a group lists its items one below\n * the other.\n */\nconst SHORT_ROW_FIRST_CHILD =\n '[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-1.5';\n\n/** The icon box before a message: 12px glyphs line up with the first line of caption text. */\nconst MESSAGE_ICON_CLASSES = 'mt-0.5 inline-flex shrink-0';\n\n/**\n * The icon before a message: the state's glyph while `icon` is `undefined`, else the consumer's\n * slot (`null` or content that renders nothing shows none).\n */\nfunction renderMessageIcon(state: ValidationState, icon: Slot<'span'> | undefined) {\n if (icon !== undefined) {\n return slotRendersContent(icon)\n ? renderSlot(icon, 'span', MESSAGE_ICON_CLASSES, { 'aria-hidden': true })\n : null;\n }\n const Icon = MESSAGE_ICONS[state];\n return Icon ? (\n <span aria-hidden=\"true\" className={MESSAGE_ICON_CLASSES}>\n <Icon size={12} />\n </span>\n ) : null;\n}\n\n/**\n * Lays out a form control with a label, a validation message, a hint and a required indicator,\n * and wires them to the control.\n *\n * - Validation: `validationMessage` with a `validationState` (`error`, `warning`, `success`,\n * `none`), or `error`, the shorthand for an error message. The message renders below the\n * control with the state's icon and color, followed by the hint (which stays visible); both\n * describe the control. Only the `error` state marks the control `aria-invalid`; `error` and\n * `warning` messages are announced (`role=\"alert\"`). The root carries `data-validation-state`\n * and `data-orientation`.\n * - `orientation=\"horizontal\"` puts the label in a start column beside the control, with the\n * message and the hint below the control. The label lines up with the first line of the\n * control (a Checkbox, Switch or RadioGroup gets 6px of padding above and below for it).\n * - Provides `FieldContext`: the library's inputs (Input, Select, Textarea, Slider, SearchBox,\n * Checkbox, Switch, RadioGroup, Rating, SpinButton, pickers, …) read it wherever they are inside\n * the Field and are named by the label, described by the message and the hint and marked\n * invalid/required.\n * - Merges into its **first** element child (a native `<input>`/`<select>`/`<textarea>`, a\n * library control or your own component): `id` (unless the child has one — the label then\n * points at the child's id), `aria-describedby` (joined with the child's own ids),\n * `aria-invalid` (in the error state), `aria-required` and, for native form controls that take a\n * value, `required`. Only defined values are merged; the child's own values are kept, so a\n * child's `aria-invalid={false}` stays valid while the Field error still describes it (as for a\n * library control nested deeper). Further element children are rendered as they are.\n * - `aria-required` is added only where it is allowed: components (Field cannot see what they\n * render, so they decide where it goes — see the wrapper note below), `<input>` (not\n * `type=\"button\"`/`\"submit\"`/`\"reset\"`/`\"image\"`), `<select>`, `<textarea>`, and elements\n * whose explicit `role` supports it (`checkbox`, `combobox`, `switch`, `textbox`, …). A\n * `<button>`, `<meter>`, `<output>` or `<progress>` is labelled and described but not marked\n * required.\n * - Your own widget built on an element with an explicit `role` (`<div role=\"radiogroup\">`) is\n * named through `aria-labelledby` (joined with its own; not added when it has an\n * `aria-label`), described, marked invalid, and gets `aria-required` when its role supports\n * it. It receives no `id`, because a `<label htmlFor>` cannot name it. A role-less `<div>` or\n * `<span>` wrapper (or a `role=\"presentation\"`/`\"none\"` one) is left alone: the library\n * control inside it reads `FieldContext`.\n * - A custom element (`<my-text-field>`) without a role is treated like a component: it receives\n * the `id`, the description and `aria-invalid` (a form-associated custom element is named by\n * the label). Field does not guess its semantics: pass `required`/`aria-required` or an\n * explicit `role` yourself.\n * - **One control per Field.** A Field labels and describes a single control; wrap each control\n * in its own Field (a development warning is logged when a Field has more than one element\n * child). Further element children are rendered as they are. A library control among them\n * still reads `FieldContext`, so it shares the Field's name and description (when the first\n * child holds the control id, it gets an id of its own and is named through\n * `aria-labelledby`). Several library controls inside one plain wrapper element (`<div>`) are\n * all named and described too: the first one takes the control id the label points at, the\n * others get ids of their own and are named through `aria-labelledby` (when the first one is\n * removed, the next one takes the control id over).\n * - **Wrapper and layout components around a library control** (a `Tooltip`, your own `Row`):\n * put them inside a plain element (`<div>`, `<div className=\"flex\">`), which Field leaves\n * alone; the library control inside then holds the control id and is labelled, described and\n * marked invalid/required through `FieldContext`. Field cannot see inside a component, so a\n * component **first child** is treated as the control (it may be your own input): it receives\n * the control `id`, `aria-describedby`, `aria-invalid` and, with `required`, `aria-required`,\n * and a wrapper puts them on its own element (Tooltip's `<span>`, the layout `<div>`). The\n * library control inside still gets an id of its own and is named by the label through\n * `aria-labelledby`, but clicking the label does not focus it, and with `required`,\n * `aria-required` on the wrapper's non-widget element is an ARIA error (axe\n * `aria-allowed-attr`), even though the control inside is correctly marked required.\n *\n * @example\n * <Field label=\"Email\" hint=\"We never share it\" error={errors.email} required>\n * <Input type=\"email\" value={email} onValueChange={setEmail} />\n * </Field>\n *\n * @example\n * <Field label=\"Password\" hint=\"At least 12 characters\" validationState=\"warning\"\n * validationMessage=\"This password is common\">\n * <Input type=\"password\" />\n * </Field>\n *\n * @example\n * // A wrapper component goes inside a plain element.\n * <Field label=\"Name\" required>\n * <div>\n * <Tooltip content=\"As on your passport\">\n * <Input />\n * </Tooltip>\n * </div>\n * </Field>\n */\nexport const Field = ({\n label,\n hint,\n error,\n validationState,\n validationMessage,\n validationMessageIcon,\n orientation = 'vertical',\n required = false,\n htmlFor,\n className,\n children,\n ref,\n ...rest\n}: FieldProps) => {\n const fieldId = useId('field');\n // Hands the control id to one library control when Field leaves its first child alone.\n const [controlIdClaim] = React.useState(createFieldControlIdClaim);\n const { elementCount, targetId, controlIdAssigned } = getChildInfo(children);\n\n // The library's \"renders nothing\" rule: nullish, booleans, '' and collections of only those (an\n // empty `errors.map(…)`) are no label, hint or message; `0` is content.\n const errorRendersContent = slotRendersContent(error);\n const usesError = error === true || errorRendersContent;\n const validationMessageRendersContent = slotRendersContent(validationMessage);\n // `error` is the shorthand for an error message and wins over the validation props.\n const state: ValidationState = usesError\n ? 'error'\n : (validationState ?? (validationMessageRendersContent ? 'error' : 'none'));\n const message = usesError ? (errorRendersContent ? error : undefined) : validationMessage;\n const hasMessage = usesError ? errorRendersContent : validationMessageRendersContent;\n const invalid = state === 'error';\n const hasHint = slotRendersContent(hint);\n const errorAndValidation =\n usesError &&\n (validationMessageRendersContent ||\n (validationState !== undefined && validationState !== 'error'));\n\n const controlId = targetId ?? htmlFor ?? fieldId;\n const hasLabel = slotRendersContent(label);\n const labelId = hasLabel ? `${fieldId}-label` : undefined;\n // The error message keeps its 0.5 id; the other states get their own.\n const messageId = hasMessage ? `${fieldId}-${invalid ? 'error' : 'message'}` : undefined;\n const errorId = invalid ? messageId : undefined;\n const hasErrorMessage = invalid && hasMessage;\n const hintId = hasHint ? `${fieldId}-hint` : undefined;\n\n React.useEffect(() => {\n if (elementCount > 1) {\n warnOnce(\n 'Field:multiple-children',\n \"Field: only the first element child receives the Field's id and ARIA attributes; the other \" +\n `${elementCount - 1} element child(ren) are rendered unchanged. Wrap each control in its own Field.`,\n );\n }\n }, [elementCount]);\n\n React.useEffect(() => {\n if (errorAndValidation) {\n warnOnce(\n 'Field:error-and-validation',\n 'Field: `error` and `validationMessage`/`validationState` are both set; `error` wins. Use one of them.',\n );\n }\n }, [errorAndValidation]);\n\n const context = React.useMemo<FieldContextValue>(\n () => ({\n controlId,\n labelId,\n hintId,\n errorId,\n invalid,\n required,\n hasErrorMessage,\n controlIdAssigned,\n controlIdClaim,\n validationState: state,\n validationMessageId: messageId,\n }),\n [\n controlId,\n labelId,\n hintId,\n errorId,\n invalid,\n required,\n hasErrorMessage,\n controlIdAssigned,\n controlIdClaim,\n state,\n messageId,\n ],\n );\n\n const content = mergeIntoFirstChild(children, {\n controlId,\n labelId,\n messageId,\n hintId,\n invalid,\n required,\n });\n\n const horizontal = orientation === 'horizontal';\n const control = (\n <>\n <FieldContext.Provider value={context}>{content}</FieldContext.Provider>\n {/* Keyed by state: a message whose state changes (a hint-only Field that gets an error, a\n warning that becomes an error) is a newly inserted element, which screen readers\n announce reliably as an alert, not an existing node with a new role. */}\n {hasMessage ? (\n <p\n key={`message-${state}`}\n id={messageId}\n role={state === 'error' || state === 'warning' ? 'alert' : undefined}\n data-validation-state={state}\n className={cn('mt-1 flex items-start gap-1 text-caption-1', MESSAGE_COLORS[state])}\n >\n {renderMessageIcon(state, validationMessageIcon)}\n <span>{materialiseSlotContent(message)}</span>\n </p>\n ) : null}\n {hasHint ? (\n <p key=\"hint\" id={hintId} className=\"mt-1 text-caption-1 text-muted-foreground\">\n {materialiseSlotContent(hint)}\n </p>\n ) : null}\n </>\n );\n\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n data-validation-state={state}\n className={cn('flex', horizontal ? 'flex-row items-start gap-x-3' : 'flex-col', className)}\n {...rest}\n >\n {hasLabel ? (\n <label\n id={labelId}\n htmlFor={controlId}\n className={cn(\n 'mb-1 text-body-1 font-semibold text-foreground',\n // Beside the control: a third of the width, its first line centred on a 32px row.\n horizontal && 'mb-0 shrink-0 basis-1/3 pt-1.5',\n )}\n >\n {materialiseSlotContent(label)}\n {required && (\n <span aria-hidden=\"true\" className=\"ms-0.5 text-error\">\n *\n </span>\n )}\n </label>\n ) : null}\n {horizontal ? (\n <div className={cn('flex min-w-0 flex-1 flex-col', SHORT_ROW_FIRST_CHILD)}>{control}</div>\n ) : (\n control\n )}\n </div>\n );\n};\n\nField.displayName = 'Field';\n"],"mappings":"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"}
1
+ {"version":3,"file":"Field.cjs","names":["React","joinIds","ErrorIcon","WarningIcon","SuccessIcon","cn","slotRendersContent","renderSlot","fieldClassNames","useId","createFieldControlIdClaim","useWaveTheme","isFieldLabelElement","_Fragment","FieldContext","materialiseSlotContent","require_runtime","require_cn","require_dev","require_slot","require_classNames","require_useId","require_aria","require_useFieldControl","require_WaveProvider","require_icons","require_fieldLabel","react","react_jsx_runtime","LABELABLE_ELEMENTS","BUTTON_INPUT_TYPES","UNNAMED_ROLES","ARIA_REQUIRED_ROLES","explicitRole","role","isCustomElement","type","isNativeValueControl","tag","inputType","supportsAriaRequired","child","getMergeMode","inspectChildren","first","elementCount","children","mode","mergeIntoFirstChild","target","childProps","ariaTrue","injected","state","getChildInfo","assigned","MESSAGE_ICONS","MESSAGE_COLORS","LABEL_TEXT","LABEL_TOP","SHORT_ROW_FIRST_CHILD","mergeIntoLabelElement","own","element","merged","MESSAGE_ICON_CLASSES","renderMessageIcon","icon","Icon","Field","rest","fieldId","controlIdClaim","labelSize","size","inputDefaults","errorRendersContent","error","usesError","validationMessageRendersContent","validationMessage","validationState","message","hasMessage","invalid","hasHint","hint","errorAndValidation","labelElement","label","labelHtmlFor","controlId","targetId","htmlFor","labelPointsElsewhere","hasLabel","labelId","messageId","errorId","hasErrorMessage","hintId","context","required","controlIdAssigned","content","horizontal","orientation","labelColumn","control","validationMessageIcon","className"],"sources":["../../../src/components/input/Field.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { fieldClassNames } from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { ErrorIcon, SuccessIcon, WarningIcon, type IconComponent } from '../../lib/icons';\nimport { materialiseSlotContent, renderSlot, slotRendersContent, type Slot } from '../../lib/slot';\nimport type { CoreSize, Orientation, ValidationState } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport {\n FieldContext,\n createFieldControlIdClaim,\n type FieldContextValue,\n} from '../../hooks/useFieldControl';\nimport { useWaveTheme } from '../provider/WaveProvider';\nimport { isFieldLabelElement, type FieldLabelElementProps } from './fieldLabel';\n\n/** Props Field reads from and merges into its first element child. */\ninterface InjectedFieldProps {\n id?: string;\n role?: string;\n type?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Properties for the Field component. */\nexport interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Label displayed above the control (beside it with `orientation=\"horizontal\"`); names the\n * control.\n *\n * A `Label` or `InfoLabel` element passed as `label` renders in place of Field's own `<label>`,\n * never inside it, and names the control by its label text alone (an InfoLabel's info button\n * sits next to the `<label>`, outside it). Field always points it at the control (`htmlFor`),\n * and gives it the Field's label id, `required`, label `size` and `weight=\"semibold\"` (the look\n * of Field's own label), each only where the element leaves it unset; Field's layout classes go\n * before the element's `className`, so the element's classes win. The element's own `htmlFor`\n * is read like the Field's `htmlFor` (which wins over it): it becomes the control's id when the\n * control has none, and one that points at another element is replaced, with a development\n * warning. Field shows no asterisk of its own next to such an element: the element shows its\n * `required` indicator. Only the element itself is recognized, not one inside a Fragment, an\n * array or another element.\n */\n label?: React.ReactNode;\n /** Hint shown below the control, after any validation message; describes the control. */\n hint?: React.ReactNode;\n /**\n * Validation error. Content is rendered below the control in a `role=\"alert\"` element that\n * describes the control, and the control is marked `aria-invalid`. `true` marks the control\n * invalid without a message. A value that renders nothing (`null`, `false`, `''`, or an array of\n * only those, such as an empty `errors.map(…)`) is no error; `0` is content.\n *\n * Shorthand for `validationState=\"error\"` with this message; wins over `validationMessage` and\n * `validationState` (development warning when both are set).\n */\n error?: React.ReactNode;\n /**\n * Validation state of `validationMessage`: `error` marks the control invalid (`aria-invalid`) and\n * announces the message (`role=\"alert\"`); `warning` announces it without marking the control\n * invalid; `success` and `none` show it without announcing. Default: `'error'` when\n * `validationMessage` renders content, else `'none'`. Ignored while `error` is set.\n */\n validationState?: ValidationState;\n /**\n * Message below the control, styled and announced by `validationState`; it describes the control\n * (`aria-describedby`). `error` is the shorthand for an error message and wins over this prop.\n */\n validationMessage?: React.ReactNode;\n /**\n * Icon before the message. Default: an error, warning or success glyph per state; none for\n * `'none'`. `null` (or content that renders nothing) shows no icon. Decorative (`aria-hidden`).\n */\n validationMessageIcon?: Slot<'span'>;\n /**\n * `vertical`: the label above the control. `horizontal`: the label in a start column (a third\n * of the width) beside the control; the message and the hint stay below the control. The\n * label's first line lines up with a 32px control (Input, Select, …) and with the first line of\n * a Checkbox, Switch or RadioGroup, which gets 6px of padding above and below for it. The\n * horizontal layout wraps the control in a column, so changing `orientation` on a mounted Field\n * remounts the control: an uncontrolled control loses its state and focus (control it, or keep\n * one orientation while the Field is mounted).\n * @default 'vertical'\n */\n orientation?: Orientation;\n /**\n * The label's size and the default `size` of the text inputs and pickers inside the Field\n * (their own `size` wins; choice controls keep theirs). The message and the hint stay small.\n * @default `WaveProvider` `inputDefaults.size`, else `'medium'`.\n */\n size?: CoreSize;\n /**\n * Whether the field is required: shows a decorative asterisk next to the label, sets\n * `aria-required`, and turns on native constraint validation. `<input>`, `<select>`,\n * `<textarea>` and Input, Select, Textarea, Slider, SearchBox and SpinButton get the native\n * `required` attribute. Checkbox, Switch, RadioGroup, Rating, ColorPicker, SwatchPicker,\n * Combobox, Dropdown, TagPicker, DatePicker and TimePicker render a hidden required input (with\n * or without `name`), so submit is blocked until they are checked, switched on or have a value.\n * An explicit `required={false}` on the control wins, including for `aria-required`.\n */\n required?: boolean;\n /**\n * The id of the control the label points at, when the control has no `id` of its own\n * (default: the `htmlFor` of a `Label` or `InfoLabel` element passed as `label`, else a\n * generated id).\n */\n htmlFor?: string;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Intrinsic elements a `<label htmlFor>` can name (HTML \"labelable elements\"). */\nconst LABELABLE_ELEMENTS: ReadonlySet<string> = new Set([\n 'button',\n 'input',\n 'meter',\n 'output',\n 'progress',\n 'select',\n 'textarea',\n]);\n\n/** `<input>` types whose implicit role is `button`: they take neither `aria-required` nor `required`. */\nconst BUTTON_INPUT_TYPES: ReadonlySet<string> = new Set(['button', 'image', 'reset', 'submit']);\n\n/**\n * Roles that cannot be named (ARIA 1.2 \"name prohibited\") or that remove semantics: an element\n * with one of them is a layout wrapper, not a widget, and Field leaves it alone.\n */\nconst UNNAMED_ROLES: ReadonlySet<string> = new Set([\n 'caption',\n 'code',\n 'deletion',\n 'emphasis',\n 'generic',\n 'insertion',\n 'none',\n 'paragraph',\n 'presentation',\n 'strong',\n 'subscript',\n 'superscript',\n]);\n\n/** Roles that support `aria-required` (ARIA 1.2, including the roles that inherit it). */\nconst ARIA_REQUIRED_ROLES: ReadonlySet<string> = new Set([\n 'checkbox',\n 'columnheader',\n 'combobox',\n 'gridcell',\n 'listbox',\n 'radiogroup',\n 'rowheader',\n 'searchbox',\n 'spinbutton',\n 'switch',\n 'textbox',\n 'tree',\n 'treegrid',\n]);\n\n/**\n * How Field merges into its first element child:\n * - `label-for`: components (library controls, consumer inputs, wrappers such as Tooltip),\n * labelable intrinsic elements (`<input>`, `<select>`, `<button>`, …) and role-less custom\n * elements (`<my-text-field>`, possibly form-associated). The child receives the `id` the\n * `<label htmlFor>` points at (unless it has its own id, which the label then uses).\n * - `labelledby`: an intrinsic element with an explicit widget `role` (a consumer's own\n * `<div role=\"radiogroup\">`). A `<label htmlFor>` cannot name it, so it is named through\n * `aria-labelledby` and receives no `id` (a library control inside it keeps the control id).\n */\ntype MergeMode = 'label-for' | 'labelledby';\n\n/** The first token of an explicit `role` attribute (lower case), or `undefined`. */\nfunction explicitRole(role: unknown): string | undefined {\n if (typeof role !== 'string') return undefined;\n return role.trim().split(/\\s+/)[0]?.toLowerCase() || undefined;\n}\n\n/** Whether `type` is an autonomous custom element (`<my-text-field>`): its tag name has a hyphen. */\nfunction isCustomElement(type: unknown): type is string {\n return typeof type === 'string' && type.includes('-');\n}\n\n/**\n * Whether an intrinsic element is a native form control that takes a value (`<select>`,\n * `<textarea>`, or an `<input>` that is not a button): it takes the native `required` attribute\n * and, without an explicit role, `aria-required`.\n */\nfunction isNativeValueControl(tag: string, inputType: unknown): boolean {\n if (tag === 'select' || tag === 'textarea') return true;\n if (tag !== 'input') return false;\n return typeof inputType !== 'string' || !BUTTON_INPUT_TYPES.has(inputType.trim().toLowerCase());\n}\n\n/**\n * Whether Field may add `aria-required` to `child`: a component (it may render any control and\n * decides where the attribute goes), an element whose explicit role supports it, or a native form\n * control that takes a value. Never a `<button>`, `<meter>`, `<output>`, `<progress>`, button-type\n * `<input>` or role-less custom element, where axe reports `aria-allowed-attr`.\n */\nfunction supportsAriaRequired(child: React.ReactElement<InjectedFieldProps>): boolean {\n if (typeof child.type !== 'string') return true;\n const role = explicitRole(child.props.role);\n if (role !== undefined) return ARIA_REQUIRED_ROLES.has(role);\n return isNativeValueControl(child.type, child.props.type);\n}\n\n/**\n * Whether and how Field merges its props into `child` (see {@link MergeMode}). A Fragment and a\n * role-less (or presentational) non-labelable intrinsic wrapper (`<div>`, `<span>`) are left\n * alone; the library control inside them reads `FieldContext`. A role-less custom element\n * (`<my-text-field>`) is treated like a component: it may be a form-associated element, which a\n * `<label htmlFor>` names.\n */\nfunction getMergeMode(child: React.ReactElement<InjectedFieldProps>): MergeMode | undefined {\n if (child.type === React.Fragment) return undefined;\n if (typeof child.type !== 'string' || LABELABLE_ELEMENTS.has(child.type)) return 'label-for';\n const role = explicitRole(child.props.role);\n if (role !== undefined) return UNNAMED_ROLES.has(role) ? undefined : 'labelledby';\n return isCustomElement(child.type) ? 'label-for' : undefined;\n}\n\ninterface FieldChildren {\n /** The element child Field merges into, or `undefined`. */\n target: React.ReactElement<InjectedFieldProps> | undefined;\n /** How Field merges into `target` (`undefined` when there is no target). */\n mode: MergeMode | undefined;\n /** How many element children there are (only the first one is merged). */\n elementCount: number;\n}\n\nfunction inspectChildren(children: React.ReactNode): FieldChildren {\n let first: React.ReactElement<InjectedFieldProps> | undefined;\n let elementCount = 0;\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement<InjectedFieldProps>(child)) return;\n elementCount += 1;\n if (first === undefined) first = child;\n });\n const mode = first ? getMergeMode(first) : undefined;\n return { target: mode ? first : undefined, mode, elementCount };\n}\n\n/** What Field merges into its first element child. */\ninterface FieldMergeState {\n controlId: string;\n labelId: string | undefined;\n /** The id of the rendered validation message, in any state. */\n messageId: string | undefined;\n hintId: string | undefined;\n /** Only the `error` validation state is invalid. */\n invalid: boolean;\n required: boolean;\n}\n\n/**\n * Returns `children` with Field's props merged into the merge target (only defined keys; the\n * child's own `id`, `aria-label`, `aria-invalid`, `aria-required` and `required` are kept, its\n * `aria-labelledby` and `aria-describedby` are joined with the message and the hint).\n */\nfunction mergeIntoFirstChild(children: React.ReactNode, state: FieldMergeState): React.ReactNode {\n const { target, mode } = inspectChildren(children);\n // Always map, so the children keep the same keys whether or not one of them is merged.\n if (!target || !mode) return React.Children.map(children, (child) => child);\n\n const childProps = target.props;\n // React renders a boolean `true` on a custom element as an empty attribute (`aria-invalid=\"\"`).\n const ariaTrue = isCustomElement(target.type) ? 'true' : true;\n const injected: InjectedFieldProps = {};\n if (mode === 'label-for') {\n if (childProps.id === undefined) injected.id = state.controlId;\n } else if (state.labelId !== undefined && childProps['aria-label'] === undefined) {\n injected['aria-labelledby'] = joinIds(childProps['aria-labelledby'], state.labelId);\n }\n if (state.messageId || state.hintId) {\n injected['aria-describedby'] = joinIds(\n childProps['aria-describedby'],\n state.messageId,\n state.hintId,\n );\n }\n // The child's own `aria-invalid` wins, as `useFieldControl` lets it win for a nested control.\n if (state.invalid && childProps['aria-invalid'] === undefined) {\n injected['aria-invalid'] = ariaTrue;\n }\n // A child's own `required={false}` wins: it gets neither `aria-required` nor `required`, so what\n // is announced matches what is validated.\n if (state.required && childProps.required !== false) {\n if (childProps['aria-required'] === undefined && supportsAriaRequired(target)) {\n injected['aria-required'] = ariaTrue;\n }\n if (\n typeof target.type === 'string' &&\n isNativeValueControl(target.type, childProps.type) &&\n childProps.required === undefined\n ) {\n injected.required = true;\n }\n }\n return React.Children.map(children, (child) =>\n child === target ? React.cloneElement(target, injected) : child,\n );\n}\n\n/** Primitive facts about the children, read during render (no element objects escape). */\nfunction getChildInfo(children: React.ReactNode): {\n elementCount: number;\n targetId: string | undefined;\n controlIdAssigned: boolean;\n} {\n const { target, mode, elementCount } = inspectChildren(children);\n // Only a label-for target holds the control id (Field merges it, or the target's own id becomes\n // the control id). A <label htmlFor> cannot name a role widget, so the library control inside\n // one keeps the control id. With `controlIdAssigned`, a library control that receives no id is\n // nested in the target or is a later sibling: useFieldControl gives it an id of its own and\n // names it through aria-labelledby.\n const assigned = mode === 'label-for';\n return {\n elementCount,\n targetId: assigned ? target?.props.id : undefined,\n controlIdAssigned: assigned,\n };\n}\n\n/** The default glyph of each message state (`none` has none). */\nconst MESSAGE_ICONS: Readonly<Record<ValidationState, IconComponent | null>> = {\n error: ErrorIcon,\n warning: WarningIcon,\n success: SuccessIcon,\n none: null,\n};\n\n/** Text color of each message state (the `*-tint-foreground` tokens keep 4.5:1 on page and card). */\nconst MESSAGE_COLORS: Readonly<Record<ValidationState, string>> = {\n error: 'text-error',\n warning: 'text-warning-tint-foreground',\n success: 'text-success-tint-foreground',\n none: 'text-muted-foreground',\n};\n\n/** The label's type ramp per Field size (0.7 default: medium). */\nconst LABEL_TEXT: Readonly<Record<CoreSize, string>> = {\n small: 'text-caption-1',\n medium: 'text-body-1',\n large: 'text-body-2',\n};\n\n/** Horizontal layout: the label's first line centred on a 24, 32 or 40px control. */\nconst LABEL_TOP: Readonly<Record<CoreSize, string>> = {\n small: 'pt-1',\n medium: 'pt-1.5',\n large: 'pt-2.25',\n};\n\n/** Horizontal layout: a Checkbox, Switch or RadioGroup row lined up with the label. */\nconst SHORT_ROW_FIRST_CHILD: Readonly<Record<CoreSize, string>> = {\n small: '[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-0.5',\n medium: '[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-1.5',\n large: '[&>:first-child:has([role=checkbox],[role=switch],label>[role=radio])]:py-2.5',\n};\n\n/** What Field merges into a `Label` or `InfoLabel` element passed as its `label` (D32). */\ninterface LabelElementState {\n /** The id the element always points at (`htmlFor`). */\n controlId: string;\n /** The Field's label id, for an element without an `id` of its own. */\n labelId: string | undefined;\n /** Whether the Field is required. */\n required: boolean;\n /** The label size: the Field's `size`, else the provider default, else medium. */\n size: CoreSize;\n /** Field's layout classes for its label, merged before the element's own `className`. */\n className: string;\n}\n\n/**\n * Returns the `Label` or `InfoLabel` element passed as Field's `label` with Field's props merged\n * in, to render in place of Field's own `<label>` (D32): `htmlFor` always points at the control;\n * `id`, `required`, `size` and the semibold `weight` of Field's own label are given only where the\n * element leaves them unset; Field's layout classes go before the element's own `className`, so\n * its classes win.\n */\nfunction mergeIntoLabelElement(\n element: React.ReactElement<FieldLabelElementProps>,\n state: LabelElementState,\n): React.ReactElement<FieldLabelElementProps> {\n const own = element.props;\n const merged: FieldLabelElementProps = {\n htmlFor: state.controlId,\n className: cn(state.className, own.className),\n };\n if (!own.id) merged.id = state.labelId;\n // The element's own `required` (`false` included) wins; else a required Field makes it show its\n // indicator.\n if (own.required === undefined && state.required) merged.required = true;\n if (own.size === undefined) merged.size = state.size;\n if (own.weight === undefined) merged.weight = 'semibold';\n return React.cloneElement(element, merged);\n}\n\n/** The icon box before a message: 12px glyphs line up with the first line of caption text. */\nconst MESSAGE_ICON_CLASSES = 'mt-0.5 inline-flex shrink-0';\n\n/**\n * The icon before a message: the state's glyph while `icon` is `undefined`, else the consumer's\n * slot (`null` or content that renders nothing shows none).\n */\nfunction renderMessageIcon(state: ValidationState, icon: Slot<'span'> | undefined) {\n if (icon !== undefined) {\n return slotRendersContent(icon)\n ? renderSlot(icon, 'span', cn(fieldClassNames.validationMessageIcon, MESSAGE_ICON_CLASSES), {\n 'aria-hidden': true,\n })\n : null;\n }\n const Icon = MESSAGE_ICONS[state];\n return Icon ? (\n <span\n aria-hidden=\"true\"\n className={cn(fieldClassNames.validationMessageIcon, MESSAGE_ICON_CLASSES)}\n >\n <Icon size={12} />\n </span>\n ) : null;\n}\n\n/**\n * Lays out a form control with a label, a validation message, a hint and a required indicator,\n * and wires them to the control.\n *\n * - Validation: `validationMessage` with a `validationState` (`error`, `warning`, `success`,\n * `none`), or `error`, the shorthand for an error message. The message renders below the\n * control with the state's icon and color, followed by the hint (which stays visible); both\n * describe the control. Only the `error` state marks the control `aria-invalid`; `error` and\n * `warning` messages are announced (`role=\"alert\"`). The root carries `data-validation-state`\n * and `data-orientation`.\n * - `orientation=\"horizontal\"` puts the label in a start column beside the control, with the\n * message and the hint below the control. The label lines up with the first line of the\n * control (a Checkbox, Switch or RadioGroup gets 6px of padding above and below for it).\n * - `size` sets the label's type ramp and, in the horizontal layout, its top padding and the\n * padding that lines a Checkbox, Switch or RadioGroup row up with it, so the label's first\n * line keeps lining up with a 24, 32 or 40px control. The message and the hint stay small.\n * Controls inside read the prop from `FieldContext` as their own default `size` (their own\n * `size` wins); the Field's own label falls back to `WaveProvider inputDefaults.size`, else\n * `medium`, and the root always renders that resolved value as `data-size`.\n * - `label` also takes a `Label` or `InfoLabel` element, which renders in place of Field's own\n * `<label>` with the Field's wiring (see `label`); an InfoLabel's info button sits next to the\n * label text, outside the `<label>`, so the control is named by the text alone. A group control\n * (RadioGroup, your own `<div role=\"radiogroup\">`) is named through `aria-labelledby` pointing\n * at that `<label>`.\n * - Provides `FieldContext`: the library's inputs (Input, Select, Textarea, Slider, SearchBox,\n * Checkbox, Switch, RadioGroup, Rating, SpinButton, pickers, …) read it wherever they are inside\n * the Field and are named by the label, described by the message and the hint and marked\n * invalid/required.\n * - Merges into its **first** element child (a native `<input>`/`<select>`/`<textarea>`, a\n * library control or your own component): `id` (unless the child has one — the label then\n * points at the child's id), `aria-describedby` (joined with the child's own ids),\n * `aria-invalid` (in the error state), `aria-required` and, for native form controls that take a\n * value, `required`. Only defined values are merged; the child's own values are kept, so a\n * child's `aria-invalid={false}` stays valid while the Field error still describes it (as for a\n * library control nested deeper). Further element children are rendered as they are.\n * - `aria-required` is added only where it is allowed: components (Field cannot see what they\n * render, so they decide where it goes — see the wrapper note below), `<input>` (not\n * `type=\"button\"`/`\"submit\"`/`\"reset\"`/`\"image\"`), `<select>`, `<textarea>`, and elements\n * whose explicit `role` supports it (`checkbox`, `combobox`, `switch`, `textbox`, …). A\n * `<button>`, `<meter>`, `<output>` or `<progress>` is labelled and described but not marked\n * required.\n * - Your own widget built on an element with an explicit `role` (`<div role=\"radiogroup\">`) is\n * named through `aria-labelledby` (joined with its own; not added when it has an\n * `aria-label`), described, marked invalid, and gets `aria-required` when its role supports\n * it. It receives no `id`, because a `<label htmlFor>` cannot name it. A role-less `<div>` or\n * `<span>` wrapper (or a `role=\"presentation\"`/`\"none\"` one) is left alone: the library\n * control inside it reads `FieldContext`.\n * - A custom element (`<my-text-field>`) without a role is treated like a component: it receives\n * the `id`, the description and `aria-invalid` (a form-associated custom element is named by\n * the label). Field does not guess its semantics: pass `required`/`aria-required` or an\n * explicit `role` yourself.\n * - **One control per Field.** A Field labels and describes a single control; wrap each control\n * in its own Field (a development warning is logged when a Field has more than one element\n * child). Further element children are rendered as they are. A library control among them\n * still reads `FieldContext`, so it shares the Field's name and description (when the first\n * child holds the control id, it gets an id of its own and is named through\n * `aria-labelledby`). Several library controls inside one plain wrapper element (`<div>`) are\n * all named and described too: the first one takes the control id the label points at, the\n * others get ids of their own and are named through `aria-labelledby` (when the first one is\n * removed, the next one takes the control id over).\n * - **Wrapper and layout components around a library control** (a `Tooltip`, your own `Row`):\n * put them inside a plain element (`<div>`, `<div className=\"flex\">`), which Field leaves\n * alone; the library control inside then holds the control id and is labelled, described and\n * marked invalid/required through `FieldContext`. Field cannot see inside a component, so a\n * component **first child** is treated as the control (it may be your own input): it receives\n * the control `id`, `aria-describedby`, `aria-invalid` and, with `required`, `aria-required`,\n * and a wrapper puts them on its own element (Tooltip's `<span>`, the layout `<div>`). The\n * library control inside still gets an id of its own and is named by the label through\n * `aria-labelledby`, but clicking the label does not focus it, and with `required`,\n * `aria-required` on the wrapper's non-widget element is an ARIA error (axe\n * `aria-allowed-attr`), even though the control inside is correctly marked required.\n *\n * @example\n * <Field label=\"Email\" hint=\"We never share it\" error={errors.email} required>\n * <Input type=\"email\" value={email} onValueChange={setEmail} />\n * </Field>\n *\n * @example\n * <Field label=\"Password\" hint=\"At least 12 characters\" validationState=\"warning\"\n * validationMessage=\"This password is common\">\n * <Input type=\"password\" />\n * </Field>\n *\n * @example\n * // An InfoLabel as the label: the input is named \"Password\", the info button\n * // \"Password Information\".\n * <Field label={<InfoLabel info=\"Use 12 characters or more.\">Password</InfoLabel>} required>\n * <Input type=\"password\" />\n * </Field>\n *\n * @example\n * // A wrapper component goes inside a plain element.\n * <Field label=\"Name\" required>\n * <div>\n * <Tooltip content=\"As on your passport\">\n * <Input />\n * </Tooltip>\n * </div>\n * </Field>\n */\nexport const Field = ({\n label,\n hint,\n error,\n validationState,\n validationMessage,\n validationMessageIcon,\n orientation = 'vertical',\n size,\n required = false,\n htmlFor,\n className,\n children,\n ref,\n ...rest\n}: FieldProps) => {\n const fieldId = useId('field');\n // Hands the control id to one library control when Field leaves its first child alone.\n const [controlIdClaim] = React.useState(createFieldControlIdClaim);\n const { elementCount, targetId, controlIdAssigned } = getChildInfo(children);\n // Own prop, else the provider default, else medium (D8); called unconditionally (C-HOOKS), so\n // the provider fallback still applies while `size` is unset.\n const { inputDefaults } = useWaveTheme();\n const labelSize = size ?? inputDefaults.size ?? 'medium';\n\n // The library's \"renders nothing\" rule: nullish, booleans, '' and collections of only those (an\n // empty `errors.map(…)`) are no label, hint or message; `0` is content.\n const errorRendersContent = slotRendersContent(error);\n const usesError = error === true || errorRendersContent;\n const validationMessageRendersContent = slotRendersContent(validationMessage);\n // `error` is the shorthand for an error message and wins over the validation props.\n const state: ValidationState = usesError\n ? 'error'\n : (validationState ?? (validationMessageRendersContent ? 'error' : 'none'));\n const message = usesError ? (errorRendersContent ? error : undefined) : validationMessage;\n const hasMessage = usesError ? errorRendersContent : validationMessageRendersContent;\n const invalid = state === 'error';\n const hasHint = slotRendersContent(hint);\n const errorAndValidation =\n usesError &&\n (validationMessageRendersContent ||\n (validationState !== undefined && validationState !== 'error'));\n\n // A Label or InfoLabel element renders in place of Field's own <label> (D32). Recognized by its\n // marker: Field imports neither component, so a Field-only bundle has no info button code.\n const labelElement = isFieldLabelElement(label) ? label : undefined;\n // An empty `htmlFor` or `id` on the element counts as unset (`||`); Field's own `htmlFor` keeps\n // its 0.7 meaning (`??`).\n const labelHtmlFor = labelElement?.props.htmlFor || undefined;\n const controlId = targetId ?? htmlFor ?? labelHtmlFor ?? fieldId;\n // A label pointing at another element would leave the control unnamed.\n const labelPointsElsewhere = labelHtmlFor !== undefined && labelHtmlFor !== controlId;\n const hasLabel = slotRendersContent(label);\n const labelId = hasLabel ? labelElement?.props.id || `${fieldId}-label` : undefined;\n // The error message keeps its 0.5 id; the other states get their own.\n const messageId = hasMessage ? `${fieldId}-${invalid ? 'error' : 'message'}` : undefined;\n const errorId = invalid ? messageId : undefined;\n const hasErrorMessage = invalid && hasMessage;\n const hintId = hasHint ? `${fieldId}-hint` : undefined;\n\n React.useEffect(() => {\n if (elementCount > 1) {\n warnOnce(\n 'Field:multiple-children',\n \"Field: only the first element child receives the Field's id and ARIA attributes; the other \" +\n `${elementCount - 1} element child(ren) are rendered unchanged. Wrap each control in its own Field.`,\n );\n }\n }, [elementCount]);\n\n React.useEffect(() => {\n if (errorAndValidation) {\n warnOnce(\n 'Field:error-and-validation',\n 'Field: `error` and `validationMessage`/`validationState` are both set; `error` wins. Use one of them.',\n );\n }\n }, [errorAndValidation]);\n\n React.useEffect(() => {\n if (labelPointsElsewhere) {\n warnOnce(\n 'Field:label-htmlFor',\n \"Field: the label element's `htmlFor` points at a different element than the Field's control, \" +\n 'which would leave the control unnamed; Field points it at the control. Remove it, or give ' +\n 'the control that id.',\n );\n }\n }, [labelPointsElsewhere]);\n\n const context = React.useMemo<FieldContextValue>(\n () => ({\n controlId,\n labelId,\n hintId,\n errorId,\n invalid,\n required,\n hasErrorMessage,\n controlIdAssigned,\n controlIdClaim,\n validationState: state,\n validationMessageId: messageId,\n size,\n }),\n [\n controlId,\n labelId,\n hintId,\n errorId,\n invalid,\n required,\n hasErrorMessage,\n controlIdAssigned,\n controlIdClaim,\n state,\n messageId,\n size,\n ],\n );\n\n const content = mergeIntoFirstChild(children, {\n controlId,\n labelId,\n messageId,\n hintId,\n invalid,\n required,\n });\n\n const horizontal = orientation === 'horizontal';\n // Beside the control: a third of the width, its first line lined up with LABEL_TOP.\n const labelColumn = horizontal && cn('mb-0 shrink-0 basis-1/3', LABEL_TOP[labelSize]);\n const control = (\n <>\n <FieldContext.Provider value={context}>{content}</FieldContext.Provider>\n {/* Keyed by state: a message whose state changes (a hint-only Field that gets an error, a\n warning that becomes an error) is a newly inserted element, which screen readers\n announce reliably as an alert, not an existing node with a new role. */}\n {hasMessage ? (\n <p\n key={`message-${state}`}\n id={messageId}\n role={state === 'error' || state === 'warning' ? 'alert' : undefined}\n data-validation-state={state}\n className={cn(\n fieldClassNames.validationMessage,\n 'mt-1 flex items-start gap-1 text-caption-1',\n MESSAGE_COLORS[state],\n )}\n >\n {renderMessageIcon(state, validationMessageIcon)}\n <span>{materialiseSlotContent(message)}</span>\n </p>\n ) : null}\n {hasHint ? (\n <p\n key=\"hint\"\n id={hintId}\n className={cn(fieldClassNames.hint, 'mt-1 text-caption-1 text-muted-foreground')}\n >\n {materialiseSlotContent(hint)}\n </p>\n ) : null}\n </>\n );\n\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n data-size={labelSize}\n data-validation-state={state}\n className={cn(\n fieldClassNames.root,\n 'flex',\n horizontal ? 'flex-row items-start gap-x-3' : 'flex-col',\n className,\n )}\n {...rest}\n >\n {labelElement ? (\n mergeIntoLabelElement(labelElement, {\n controlId,\n labelId,\n required,\n size: labelSize,\n className: cn(fieldClassNames.label, 'mb-1', labelColumn),\n })\n ) : hasLabel ? (\n <label\n id={labelId}\n htmlFor={controlId}\n className={cn(\n fieldClassNames.label,\n 'mb-1 font-semibold text-foreground',\n LABEL_TEXT[labelSize],\n labelColumn,\n )}\n >\n {materialiseSlotContent(label)}\n {required && (\n <span aria-hidden=\"true\" className={cn(fieldClassNames.required, 'ms-0.5 text-error')}>\n *\n </span>\n )}\n </label>\n ) : null}\n {horizontal ? (\n <div className={cn('flex min-w-0 flex-1 flex-col', SHORT_ROW_FIRST_CHILD[labelSize])}>\n {control}\n </div>\n ) : (\n control\n )}\n </div>\n );\n};\n\nField.displayName = 'Field';\n"],"mappings":"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"}