@wordpress/ui 0.12.0 → 0.13.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 (521) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/CONTRIBUTING.md +34 -0
  3. package/build/alert-dialog/popup.cjs +92 -22
  4. package/build/alert-dialog/popup.cjs.map +3 -3
  5. package/build/badge/badge.cjs +84 -5
  6. package/build/badge/badge.cjs.map +3 -3
  7. package/build/button/button.cjs +90 -20
  8. package/build/button/button.cjs.map +3 -3
  9. package/build/button/icon.cjs.map +2 -2
  10. package/build/button/index.cjs +1 -0
  11. package/build/button/index.cjs.map +3 -3
  12. package/build/button/types.cjs.map +1 -1
  13. package/build/card/content.cjs +84 -5
  14. package/build/card/content.cjs.map +3 -3
  15. package/build/card/full-bleed.cjs +84 -5
  16. package/build/card/full-bleed.cjs.map +3 -3
  17. package/build/card/header.cjs +84 -5
  18. package/build/card/header.cjs.map +3 -3
  19. package/build/card/root.cjs +86 -10
  20. package/build/card/root.cjs.map +3 -3
  21. package/build/collapsible-card/content.cjs +85 -6
  22. package/build/collapsible-card/content.cjs.map +3 -3
  23. package/build/collapsible-card/header.cjs +131 -52
  24. package/build/collapsible-card/header.cjs.map +3 -3
  25. package/build/dialog/content.cjs +86 -10
  26. package/build/dialog/content.cjs.map +3 -3
  27. package/build/dialog/description.cjs +84 -5
  28. package/build/dialog/description.cjs.map +3 -3
  29. package/build/dialog/footer.cjs +84 -5
  30. package/build/dialog/footer.cjs.map +3 -3
  31. package/build/dialog/header.cjs +84 -5
  32. package/build/dialog/header.cjs.map +3 -3
  33. package/build/dialog/popup.cjs +86 -7
  34. package/build/dialog/popup.cjs.map +3 -3
  35. package/build/dialog/title.cjs +84 -5
  36. package/build/dialog/title.cjs.map +3 -3
  37. package/build/drawer/content.cjs +103 -19
  38. package/build/drawer/content.cjs.map +4 -4
  39. package/build/drawer/footer.cjs +84 -5
  40. package/build/drawer/footer.cjs.map +3 -3
  41. package/build/drawer/header.cjs +84 -5
  42. package/build/drawer/header.cjs.map +3 -3
  43. package/build/drawer/popup.cjs +86 -7
  44. package/build/drawer/popup.cjs.map +3 -3
  45. package/build/drawer/title.cjs +84 -5
  46. package/build/drawer/title.cjs.map +3 -3
  47. package/build/drawer/types.cjs.map +1 -1
  48. package/build/empty-state/actions.cjs +84 -5
  49. package/build/empty-state/actions.cjs.map +3 -3
  50. package/build/empty-state/description.cjs +84 -5
  51. package/build/empty-state/description.cjs.map +3 -3
  52. package/build/empty-state/icon.cjs +84 -5
  53. package/build/empty-state/icon.cjs.map +3 -3
  54. package/build/empty-state/root.cjs +84 -5
  55. package/build/empty-state/root.cjs.map +3 -3
  56. package/build/empty-state/title.cjs +84 -5
  57. package/build/empty-state/title.cjs.map +3 -3
  58. package/build/empty-state/visual.cjs +84 -5
  59. package/build/empty-state/visual.cjs.map +3 -3
  60. package/build/form/index.cjs +3 -1
  61. package/build/form/index.cjs.map +2 -2
  62. package/build/form/primitives/autocomplete/empty.cjs +84 -5
  63. package/build/form/primitives/autocomplete/empty.cjs.map +3 -3
  64. package/build/form/primitives/autocomplete/item.cjs +86 -10
  65. package/build/form/primitives/autocomplete/item.cjs.map +3 -3
  66. package/build/form/primitives/autocomplete/list-body.cjs +84 -5
  67. package/build/form/primitives/autocomplete/list-body.cjs.map +3 -3
  68. package/build/form/primitives/autocomplete/list.cjs +84 -5
  69. package/build/form/primitives/autocomplete/list.cjs.map +3 -3
  70. package/build/form/primitives/autocomplete/popup.cjs +90 -17
  71. package/build/form/primitives/autocomplete/popup.cjs.map +3 -3
  72. package/build/form/primitives/field/description.cjs +86 -10
  73. package/build/form/primitives/field/description.cjs.map +3 -3
  74. package/build/form/primitives/field/details.cjs +84 -5
  75. package/build/form/primitives/field/details.cjs.map +3 -3
  76. package/build/form/primitives/field/label.cjs +84 -5
  77. package/build/form/primitives/field/label.cjs.map +3 -3
  78. package/build/form/primitives/field/root.cjs +84 -5
  79. package/build/form/primitives/field/root.cjs.map +3 -3
  80. package/build/form/primitives/fieldset/description.cjs +86 -10
  81. package/build/form/primitives/fieldset/description.cjs.map +3 -3
  82. package/build/form/primitives/fieldset/details.cjs +84 -5
  83. package/build/form/primitives/fieldset/details.cjs.map +3 -3
  84. package/build/form/primitives/fieldset/legend.cjs +84 -5
  85. package/build/form/primitives/fieldset/legend.cjs.map +3 -3
  86. package/build/form/primitives/fieldset/root.cjs +84 -5
  87. package/build/form/primitives/fieldset/root.cjs.map +3 -3
  88. package/build/form/primitives/input/input.cjs +88 -15
  89. package/build/form/primitives/input/input.cjs.map +3 -3
  90. package/build/form/primitives/input-layout/input-layout.cjs +88 -15
  91. package/build/form/primitives/input-layout/input-layout.cjs.map +3 -3
  92. package/build/form/primitives/input-layout/slot.cjs +84 -5
  93. package/build/form/primitives/input-layout/slot.cjs.map +3 -3
  94. package/build/form/primitives/select/item.cjs +87 -11
  95. package/build/form/primitives/select/item.cjs.map +3 -3
  96. package/build/form/primitives/select/popup.cjs +90 -17
  97. package/build/form/primitives/select/popup.cjs.map +3 -3
  98. package/build/form/primitives/select/root.cjs.map +2 -2
  99. package/build/form/primitives/select/trigger.cjs +98 -16
  100. package/build/form/primitives/select/trigger.cjs.map +3 -3
  101. package/build/form/primitives/select/types.cjs.map +1 -1
  102. package/build/form/primitives/textarea/textarea.cjs +86 -10
  103. package/build/form/primitives/textarea/textarea.cjs.map +3 -3
  104. package/build/form/select-control/context.cjs +37 -0
  105. package/build/form/select-control/context.cjs.map +7 -0
  106. package/build/form/select-control/index.cjs +39 -0
  107. package/build/form/select-control/index.cjs.map +7 -0
  108. package/build/form/select-control/item.cjs +41 -0
  109. package/build/form/select-control/item.cjs.map +7 -0
  110. package/build/form/select-control/select-control.cjs +75 -0
  111. package/build/form/select-control/select-control.cjs.map +7 -0
  112. package/build/form/select-control/types.cjs +19 -0
  113. package/build/form/select-control/types.cjs.map +7 -0
  114. package/build/form/types.cjs.map +1 -1
  115. package/build/icon-button/icon-button.cjs +86 -6
  116. package/build/icon-button/icon-button.cjs.map +3 -3
  117. package/build/icon-button/types.cjs.map +1 -1
  118. package/build/link/link.cjs +90 -20
  119. package/build/link/link.cjs.map +3 -3
  120. package/build/notice/action-button.cjs +84 -5
  121. package/build/notice/action-button.cjs.map +3 -3
  122. package/build/notice/action-link.cjs +84 -5
  123. package/build/notice/action-link.cjs.map +3 -3
  124. package/build/notice/actions.cjs +84 -5
  125. package/build/notice/actions.cjs.map +3 -3
  126. package/build/notice/close-icon.cjs +84 -5
  127. package/build/notice/close-icon.cjs.map +3 -3
  128. package/build/notice/description.cjs +84 -5
  129. package/build/notice/description.cjs.map +3 -3
  130. package/build/notice/root.cjs +86 -10
  131. package/build/notice/root.cjs.map +3 -3
  132. package/build/notice/title.cjs +84 -5
  133. package/build/notice/title.cjs.map +3 -3
  134. package/build/popover/arrow.cjs +84 -5
  135. package/build/popover/arrow.cjs.map +3 -3
  136. package/build/popover/popup.cjs +88 -12
  137. package/build/popover/popup.cjs.map +3 -3
  138. package/build/popover/title.cjs +84 -5
  139. package/build/popover/title.cjs.map +3 -3
  140. package/build/stack/stack.cjs +84 -5
  141. package/build/stack/stack.cjs.map +3 -3
  142. package/build/tabs/list.cjs +84 -5
  143. package/build/tabs/list.cjs.map +3 -3
  144. package/build/tabs/panel.cjs +86 -10
  145. package/build/tabs/panel.cjs.map +3 -3
  146. package/build/tabs/tab.cjs +84 -5
  147. package/build/tabs/tab.cjs.map +3 -3
  148. package/build/text/text.cjs +86 -10
  149. package/build/text/text.cjs.map +3 -3
  150. package/build/tooltip/index.cjs +3 -0
  151. package/build/tooltip/index.cjs.map +2 -2
  152. package/build/tooltip/popup.cjs +111 -40
  153. package/build/tooltip/popup.cjs.map +3 -3
  154. package/build/tooltip/positioner.cjs +159 -0
  155. package/build/tooltip/positioner.cjs.map +7 -0
  156. package/build/tooltip/types.cjs.map +1 -1
  157. package/build/utils/{render-portal-with-children.cjs → render-slot-with-children.cjs} +9 -12
  158. package/build/utils/render-slot-with-children.cjs.map +7 -0
  159. package/build/visually-hidden/visually-hidden.cjs +84 -5
  160. package/build/visually-hidden/visually-hidden.cjs.map +3 -3
  161. package/build-module/alert-dialog/popup.mjs +92 -22
  162. package/build-module/alert-dialog/popup.mjs.map +3 -3
  163. package/build-module/badge/badge.mjs +84 -5
  164. package/build-module/badge/badge.mjs.map +3 -3
  165. package/build-module/button/button.mjs +90 -20
  166. package/build-module/button/button.mjs.map +3 -3
  167. package/build-module/button/icon.mjs.map +2 -2
  168. package/build-module/button/index.mjs +3 -2
  169. package/build-module/button/index.mjs.map +2 -2
  170. package/build-module/card/content.mjs +84 -5
  171. package/build-module/card/content.mjs.map +3 -3
  172. package/build-module/card/full-bleed.mjs +84 -5
  173. package/build-module/card/full-bleed.mjs.map +3 -3
  174. package/build-module/card/header.mjs +84 -5
  175. package/build-module/card/header.mjs.map +3 -3
  176. package/build-module/card/root.mjs +86 -10
  177. package/build-module/card/root.mjs.map +3 -3
  178. package/build-module/collapsible-card/content.mjs +85 -6
  179. package/build-module/collapsible-card/content.mjs.map +3 -3
  180. package/build-module/collapsible-card/header.mjs +131 -52
  181. package/build-module/collapsible-card/header.mjs.map +3 -3
  182. package/build-module/dialog/content.mjs +86 -10
  183. package/build-module/dialog/content.mjs.map +3 -3
  184. package/build-module/dialog/description.mjs +84 -5
  185. package/build-module/dialog/description.mjs.map +3 -3
  186. package/build-module/dialog/footer.mjs +84 -5
  187. package/build-module/dialog/footer.mjs.map +3 -3
  188. package/build-module/dialog/header.mjs +84 -5
  189. package/build-module/dialog/header.mjs.map +3 -3
  190. package/build-module/dialog/popup.mjs +86 -7
  191. package/build-module/dialog/popup.mjs.map +3 -3
  192. package/build-module/dialog/title.mjs +84 -5
  193. package/build-module/dialog/title.mjs.map +3 -3
  194. package/build-module/drawer/content.mjs +103 -19
  195. package/build-module/drawer/content.mjs.map +3 -3
  196. package/build-module/drawer/footer.mjs +84 -5
  197. package/build-module/drawer/footer.mjs.map +3 -3
  198. package/build-module/drawer/header.mjs +84 -5
  199. package/build-module/drawer/header.mjs.map +3 -3
  200. package/build-module/drawer/popup.mjs +86 -7
  201. package/build-module/drawer/popup.mjs.map +3 -3
  202. package/build-module/drawer/title.mjs +84 -5
  203. package/build-module/drawer/title.mjs.map +3 -3
  204. package/build-module/empty-state/actions.mjs +84 -5
  205. package/build-module/empty-state/actions.mjs.map +3 -3
  206. package/build-module/empty-state/description.mjs +84 -5
  207. package/build-module/empty-state/description.mjs.map +3 -3
  208. package/build-module/empty-state/icon.mjs +84 -5
  209. package/build-module/empty-state/icon.mjs.map +3 -3
  210. package/build-module/empty-state/root.mjs +84 -5
  211. package/build-module/empty-state/root.mjs.map +3 -3
  212. package/build-module/empty-state/title.mjs +84 -5
  213. package/build-module/empty-state/title.mjs.map +3 -3
  214. package/build-module/empty-state/visual.mjs +84 -5
  215. package/build-module/empty-state/visual.mjs.map +3 -3
  216. package/build-module/form/index.mjs +1 -0
  217. package/build-module/form/index.mjs.map +2 -2
  218. package/build-module/form/primitives/autocomplete/empty.mjs +84 -5
  219. package/build-module/form/primitives/autocomplete/empty.mjs.map +3 -3
  220. package/build-module/form/primitives/autocomplete/item.mjs +86 -10
  221. package/build-module/form/primitives/autocomplete/item.mjs.map +3 -3
  222. package/build-module/form/primitives/autocomplete/list-body.mjs +84 -5
  223. package/build-module/form/primitives/autocomplete/list-body.mjs.map +3 -3
  224. package/build-module/form/primitives/autocomplete/list.mjs +84 -5
  225. package/build-module/form/primitives/autocomplete/list.mjs.map +3 -3
  226. package/build-module/form/primitives/autocomplete/popup.mjs +90 -17
  227. package/build-module/form/primitives/autocomplete/popup.mjs.map +3 -3
  228. package/build-module/form/primitives/field/description.mjs +86 -10
  229. package/build-module/form/primitives/field/description.mjs.map +3 -3
  230. package/build-module/form/primitives/field/details.mjs +84 -5
  231. package/build-module/form/primitives/field/details.mjs.map +3 -3
  232. package/build-module/form/primitives/field/label.mjs +84 -5
  233. package/build-module/form/primitives/field/label.mjs.map +3 -3
  234. package/build-module/form/primitives/field/root.mjs +84 -5
  235. package/build-module/form/primitives/field/root.mjs.map +3 -3
  236. package/build-module/form/primitives/fieldset/description.mjs +86 -10
  237. package/build-module/form/primitives/fieldset/description.mjs.map +3 -3
  238. package/build-module/form/primitives/fieldset/details.mjs +84 -5
  239. package/build-module/form/primitives/fieldset/details.mjs.map +3 -3
  240. package/build-module/form/primitives/fieldset/legend.mjs +84 -5
  241. package/build-module/form/primitives/fieldset/legend.mjs.map +3 -3
  242. package/build-module/form/primitives/fieldset/root.mjs +84 -5
  243. package/build-module/form/primitives/fieldset/root.mjs.map +3 -3
  244. package/build-module/form/primitives/input/input.mjs +88 -15
  245. package/build-module/form/primitives/input/input.mjs.map +3 -3
  246. package/build-module/form/primitives/input-layout/input-layout.mjs +88 -15
  247. package/build-module/form/primitives/input-layout/input-layout.mjs.map +3 -3
  248. package/build-module/form/primitives/input-layout/slot.mjs +84 -5
  249. package/build-module/form/primitives/input-layout/slot.mjs.map +3 -3
  250. package/build-module/form/primitives/select/item.mjs +87 -11
  251. package/build-module/form/primitives/select/item.mjs.map +3 -3
  252. package/build-module/form/primitives/select/popup.mjs +90 -17
  253. package/build-module/form/primitives/select/popup.mjs.map +3 -3
  254. package/build-module/form/primitives/select/root.mjs.map +2 -2
  255. package/build-module/form/primitives/select/trigger.mjs +98 -16
  256. package/build-module/form/primitives/select/trigger.mjs.map +3 -3
  257. package/build-module/form/primitives/textarea/textarea.mjs +86 -10
  258. package/build-module/form/primitives/textarea/textarea.mjs.map +3 -3
  259. package/build-module/form/select-control/context.mjs +11 -0
  260. package/build-module/form/select-control/context.mjs.map +7 -0
  261. package/build-module/form/select-control/index.mjs +14 -0
  262. package/build-module/form/select-control/index.mjs.map +7 -0
  263. package/build-module/form/select-control/item.mjs +16 -0
  264. package/build-module/form/select-control/item.mjs.map +7 -0
  265. package/build-module/form/select-control/select-control.mjs +50 -0
  266. package/build-module/form/select-control/select-control.mjs.map +7 -0
  267. package/build-module/form/select-control/types.mjs +1 -0
  268. package/build-module/form/select-control/types.mjs.map +7 -0
  269. package/build-module/icon-button/icon-button.mjs +86 -6
  270. package/build-module/icon-button/icon-button.mjs.map +3 -3
  271. package/build-module/link/link.mjs +90 -20
  272. package/build-module/link/link.mjs.map +3 -3
  273. package/build-module/notice/action-button.mjs +84 -5
  274. package/build-module/notice/action-button.mjs.map +3 -3
  275. package/build-module/notice/action-link.mjs +84 -5
  276. package/build-module/notice/action-link.mjs.map +3 -3
  277. package/build-module/notice/actions.mjs +84 -5
  278. package/build-module/notice/actions.mjs.map +3 -3
  279. package/build-module/notice/close-icon.mjs +84 -5
  280. package/build-module/notice/close-icon.mjs.map +3 -3
  281. package/build-module/notice/description.mjs +84 -5
  282. package/build-module/notice/description.mjs.map +3 -3
  283. package/build-module/notice/root.mjs +86 -10
  284. package/build-module/notice/root.mjs.map +3 -3
  285. package/build-module/notice/title.mjs +84 -5
  286. package/build-module/notice/title.mjs.map +3 -3
  287. package/build-module/popover/arrow.mjs +84 -5
  288. package/build-module/popover/arrow.mjs.map +3 -3
  289. package/build-module/popover/popup.mjs +88 -12
  290. package/build-module/popover/popup.mjs.map +3 -3
  291. package/build-module/popover/title.mjs +84 -5
  292. package/build-module/popover/title.mjs.map +3 -3
  293. package/build-module/stack/stack.mjs +84 -5
  294. package/build-module/stack/stack.mjs.map +3 -3
  295. package/build-module/tabs/list.mjs +84 -5
  296. package/build-module/tabs/list.mjs.map +3 -3
  297. package/build-module/tabs/panel.mjs +86 -10
  298. package/build-module/tabs/panel.mjs.map +3 -3
  299. package/build-module/tabs/tab.mjs +84 -5
  300. package/build-module/tabs/tab.mjs.map +3 -3
  301. package/build-module/text/text.mjs +86 -10
  302. package/build-module/text/text.mjs.map +3 -3
  303. package/build-module/tooltip/index.mjs +2 -0
  304. package/build-module/tooltip/index.mjs.map +2 -2
  305. package/build-module/tooltip/popup.mjs +111 -40
  306. package/build-module/tooltip/popup.mjs.map +3 -3
  307. package/build-module/tooltip/positioner.mjs +124 -0
  308. package/build-module/tooltip/positioner.mjs.map +7 -0
  309. package/build-module/utils/render-slot-with-children.mjs +9 -0
  310. package/build-module/utils/render-slot-with-children.mjs.map +7 -0
  311. package/build-module/visually-hidden/visually-hidden.mjs +84 -5
  312. package/build-module/visually-hidden/visually-hidden.mjs.map +3 -3
  313. package/build-types/alert-dialog/portal.d.ts +1 -1
  314. package/build-types/alert-dialog/portal.d.ts.map +1 -1
  315. package/build-types/alert-dialog/root.d.ts +1 -1
  316. package/build-types/alert-dialog/root.d.ts.map +1 -1
  317. package/build-types/alert-dialog/stories/index.story.d.ts.map +1 -1
  318. package/build-types/badge/stories/choosing-intent.story.d.ts.map +1 -1
  319. package/build-types/badge/stories/index.story.d.ts.map +1 -1
  320. package/build-types/button/button.d.ts +3 -0
  321. package/build-types/button/button.d.ts.map +1 -1
  322. package/build-types/button/icon.d.ts +1 -8
  323. package/build-types/button/icon.d.ts.map +1 -1
  324. package/build-types/button/index.d.ts +6 -5
  325. package/build-types/button/index.d.ts.map +1 -1
  326. package/build-types/button/stories/index.story.d.ts.map +1 -1
  327. package/build-types/button/types.d.ts +7 -0
  328. package/build-types/button/types.d.ts.map +1 -1
  329. package/build-types/card/stories/index.story.d.ts.map +1 -1
  330. package/build-types/collapsible/panel.d.ts +1 -1
  331. package/build-types/collapsible/root.d.ts +1 -1
  332. package/build-types/collapsible/stories/index.story.d.ts.map +1 -1
  333. package/build-types/collapsible/trigger.d.ts +1 -1
  334. package/build-types/collapsible-card/header.d.ts +6 -0
  335. package/build-types/collapsible-card/header.d.ts.map +1 -1
  336. package/build-types/collapsible-card/stories/index.story.d.ts +8 -0
  337. package/build-types/collapsible-card/stories/index.story.d.ts.map +1 -1
  338. package/build-types/dialog/context.d.ts +2 -2
  339. package/build-types/dialog/popup.d.ts +1 -2
  340. package/build-types/dialog/popup.d.ts.map +1 -1
  341. package/build-types/dialog/portal.d.ts +1 -1
  342. package/build-types/dialog/portal.d.ts.map +1 -1
  343. package/build-types/dialog/stories/index.story.d.ts.map +1 -1
  344. package/build-types/drawer/content.d.ts +7 -4
  345. package/build-types/drawer/content.d.ts.map +1 -1
  346. package/build-types/drawer/context.d.ts +2 -2
  347. package/build-types/drawer/popup.d.ts +1 -2
  348. package/build-types/drawer/popup.d.ts.map +1 -1
  349. package/build-types/drawer/stories/index.story.d.ts.map +1 -1
  350. package/build-types/drawer/types.d.ts +1 -1
  351. package/build-types/empty-state/stories/index.story.d.ts.map +1 -1
  352. package/build-types/form/index.d.ts +1 -0
  353. package/build-types/form/index.d.ts.map +1 -1
  354. package/build-types/form/input-control/stories/index.story.d.ts.map +1 -1
  355. package/build-types/form/primitives/autocomplete/clear.d.ts +1 -1
  356. package/build-types/form/primitives/autocomplete/empty.d.ts +1 -1
  357. package/build-types/form/primitives/autocomplete/input-group.d.ts +1 -1
  358. package/build-types/form/primitives/autocomplete/item.d.ts +1 -1
  359. package/build-types/form/primitives/autocomplete/list-body.d.ts +1 -1
  360. package/build-types/form/primitives/autocomplete/list.d.ts +2 -2
  361. package/build-types/form/primitives/autocomplete/popup.d.ts +2 -2
  362. package/build-types/form/primitives/autocomplete/portal.d.ts +1 -1
  363. package/build-types/form/primitives/autocomplete/portal.d.ts.map +1 -1
  364. package/build-types/form/primitives/autocomplete/stories/index.story.d.ts.map +1 -1
  365. package/build-types/form/primitives/field/control.d.ts +2 -2
  366. package/build-types/form/primitives/field/description.d.ts +1 -1
  367. package/build-types/form/primitives/field/details.d.ts +1 -1
  368. package/build-types/form/primitives/field/label.d.ts +3 -3
  369. package/build-types/form/primitives/field/root.d.ts +3 -3
  370. package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
  371. package/build-types/form/primitives/fieldset/description.d.ts +1 -1
  372. package/build-types/form/primitives/fieldset/details.d.ts +1 -1
  373. package/build-types/form/primitives/fieldset/legend.d.ts +1 -1
  374. package/build-types/form/primitives/fieldset/root.d.ts +1 -1
  375. package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
  376. package/build-types/form/primitives/input/input.d.ts +5 -5
  377. package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -1
  378. package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -1
  379. package/build-types/form/primitives/select/item.d.ts +3 -3
  380. package/build-types/form/primitives/select/popup.d.ts +2 -2
  381. package/build-types/form/primitives/select/root.d.ts +12 -1
  382. package/build-types/form/primitives/select/root.d.ts.map +1 -1
  383. package/build-types/form/primitives/select/stories/index.story.d.ts +9 -6
  384. package/build-types/form/primitives/select/stories/index.story.d.ts.map +1 -1
  385. package/build-types/form/primitives/select/trigger.d.ts +5 -4
  386. package/build-types/form/primitives/select/trigger.d.ts.map +1 -1
  387. package/build-types/form/primitives/select/types.d.ts +12 -4
  388. package/build-types/form/primitives/select/types.d.ts.map +1 -1
  389. package/build-types/form/primitives/textarea/stories/index.story.d.ts.map +1 -1
  390. package/build-types/form/primitives/textarea/textarea.d.ts +2 -2
  391. package/build-types/form/select-control/context.d.ts +3 -0
  392. package/build-types/form/select-control/context.d.ts.map +1 -0
  393. package/build-types/form/select-control/index.d.ts +20 -0
  394. package/build-types/form/select-control/index.d.ts.map +1 -0
  395. package/build-types/form/select-control/item.d.ts +6 -0
  396. package/build-types/form/select-control/item.d.ts.map +1 -0
  397. package/build-types/form/select-control/select-control.d.ts +11 -0
  398. package/build-types/form/select-control/select-control.d.ts.map +1 -0
  399. package/build-types/form/select-control/stories/index.story.d.ts +40 -0
  400. package/build-types/form/select-control/stories/index.story.d.ts.map +1 -0
  401. package/build-types/form/select-control/test/index.test.d.ts +2 -0
  402. package/build-types/form/select-control/test/index.test.d.ts.map +1 -0
  403. package/build-types/form/select-control/types.d.ts +40 -0
  404. package/build-types/form/select-control/types.d.ts.map +1 -0
  405. package/build-types/form/types.d.ts +1 -1
  406. package/build-types/form/types.d.ts.map +1 -1
  407. package/build-types/icon/stories/index.story.d.ts.map +1 -1
  408. package/build-types/icon-button/icon-button.d.ts +2 -1
  409. package/build-types/icon-button/icon-button.d.ts.map +1 -1
  410. package/build-types/icon-button/stories/index.story.d.ts +5 -0
  411. package/build-types/icon-button/stories/index.story.d.ts.map +1 -1
  412. package/build-types/icon-button/types.d.ts +8 -0
  413. package/build-types/icon-button/types.d.ts.map +1 -1
  414. package/build-types/link/stories/index.story.d.ts.map +1 -1
  415. package/build-types/notice/stories/index.story.d.ts.map +1 -1
  416. package/build-types/popover/stories/index.story.d.ts.map +1 -1
  417. package/build-types/stack/stories/index.story.d.ts.map +1 -1
  418. package/build-types/tabs/context.d.ts +1 -1
  419. package/build-types/tabs/context.d.ts.map +1 -1
  420. package/build-types/tabs/list.d.ts +2 -2
  421. package/build-types/tabs/panel.d.ts +1 -1
  422. package/build-types/tabs/root.d.ts +1 -1
  423. package/build-types/tabs/stories/index.story.d.ts.map +1 -1
  424. package/build-types/tabs/tab.d.ts +1 -1
  425. package/build-types/text/stories/index.story.d.ts.map +1 -1
  426. package/build-types/tooltip/index.d.ts +2 -1
  427. package/build-types/tooltip/index.d.ts.map +1 -1
  428. package/build-types/tooltip/popup.d.ts.map +1 -1
  429. package/build-types/tooltip/positioner.d.ts +9 -0
  430. package/build-types/tooltip/positioner.d.ts.map +1 -0
  431. package/build-types/tooltip/stories/index.story.d.ts +11 -2
  432. package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
  433. package/build-types/tooltip/stories/usage-guidelines.story.d.ts.map +1 -1
  434. package/build-types/tooltip/types.d.ts +10 -1
  435. package/build-types/tooltip/types.d.ts.map +1 -1
  436. package/build-types/utils/create-overlay-modal-context.d.ts.map +1 -1
  437. package/build-types/utils/render-slot-with-children.d.ts +24 -0
  438. package/build-types/utils/render-slot-with-children.d.ts.map +1 -0
  439. package/build-types/utils/use-deprioritized-initial-focus.d.ts +1 -1
  440. package/build-types/utils/use-deprioritized-initial-focus.d.ts.map +1 -1
  441. package/build-types/visually-hidden/stories/index.story.d.ts.map +1 -1
  442. package/package.json +13 -12
  443. package/src/alert-dialog/popup.tsx +2 -2
  444. package/src/alert-dialog/stories/index.story.tsx +8 -0
  445. package/src/badge/stories/index.story.tsx +6 -0
  446. package/src/button/button.tsx +3 -0
  447. package/src/button/icon.tsx +1 -8
  448. package/src/button/index.ts +5 -6
  449. package/src/button/stories/index.story.tsx +10 -0
  450. package/src/button/types.ts +8 -0
  451. package/src/card/stories/index.story.tsx +6 -0
  452. package/src/collapsible/stories/index.story.tsx +6 -0
  453. package/src/collapsible-card/header.tsx +55 -42
  454. package/src/collapsible-card/stories/index.story.tsx +61 -0
  455. package/src/collapsible-card/style.module.css +20 -0
  456. package/src/collapsible-card/test/index.test.tsx +60 -1
  457. package/src/dialog/popup.tsx +3 -4
  458. package/src/dialog/stories/index.story.tsx +8 -0
  459. package/src/dialog/style.module.css +3 -9
  460. package/src/drawer/content.tsx +31 -16
  461. package/src/drawer/popup.tsx +3 -4
  462. package/src/drawer/stories/index.story.tsx +7 -0
  463. package/src/drawer/style.module.css +41 -9
  464. package/src/drawer/test/index.test.tsx +56 -0
  465. package/src/drawer/types.ts +1 -1
  466. package/src/empty-state/stories/index.story.tsx +7 -0
  467. package/src/form/index.ts +1 -0
  468. package/src/form/input-control/stories/index.story.tsx +7 -0
  469. package/src/form/primitives/autocomplete/popup.tsx +2 -2
  470. package/src/form/primitives/autocomplete/stories/index.story.tsx +18 -10
  471. package/src/form/primitives/field/stories/index.story.tsx +12 -5
  472. package/src/form/primitives/fieldset/stories/index.story.tsx +10 -3
  473. package/src/form/primitives/input/stories/index.story.tsx +7 -0
  474. package/src/form/primitives/input-layout/stories/index.story.tsx +8 -1
  475. package/src/form/primitives/select/item.tsx +1 -1
  476. package/src/form/primitives/select/popup.tsx +2 -2
  477. package/src/form/primitives/select/root.tsx +13 -2
  478. package/src/form/primitives/select/stories/index.story.tsx +132 -61
  479. package/src/form/primitives/select/test/index.test.tsx +123 -5
  480. package/src/form/primitives/select/trigger.tsx +11 -8
  481. package/src/form/primitives/select/types.ts +13 -5
  482. package/src/form/primitives/textarea/stories/index.story.tsx +7 -0
  483. package/src/form/select-control/context.tsx +9 -0
  484. package/src/form/select-control/index.ts +14 -0
  485. package/src/form/select-control/item.tsx +13 -0
  486. package/src/form/select-control/select-control.tsx +65 -0
  487. package/src/form/select-control/stories/index.story.tsx +220 -0
  488. package/src/form/select-control/test/index.test.tsx +196 -0
  489. package/src/form/select-control/types.ts +50 -0
  490. package/src/form/types.ts +1 -1
  491. package/src/icon/stories/index.story.tsx +7 -0
  492. package/src/icon-button/icon-button.tsx +2 -1
  493. package/src/icon-button/stories/index.story.tsx +20 -0
  494. package/src/icon-button/types.ts +9 -0
  495. package/src/link/stories/index.story.tsx +6 -0
  496. package/src/link/style.module.css +1 -0
  497. package/src/notice/stories/index.story.tsx +7 -0
  498. package/src/popover/popup.tsx +2 -2
  499. package/src/popover/stories/index.story.tsx +7 -0
  500. package/src/stack/stories/index.story.tsx +6 -0
  501. package/src/tabs/stories/index.story.tsx +15 -1
  502. package/src/text/stories/index.story.tsx +6 -0
  503. package/src/text/style.module.css +25 -0
  504. package/src/tooltip/index.ts +2 -1
  505. package/src/tooltip/popup.tsx +30 -38
  506. package/src/tooltip/positioner.tsx +36 -0
  507. package/src/tooltip/stories/index.story.tsx +61 -10
  508. package/src/tooltip/stories/usage-guidelines.story.tsx +5 -0
  509. package/src/tooltip/types.ts +14 -3
  510. package/src/utils/css/dropdown-motion.module.css +3 -3
  511. package/src/utils/css/item-popup.module.css +5 -1
  512. package/src/utils/css/overlay-chrome.module.css +21 -4
  513. package/src/utils/css/select-trigger.module.css +5 -2
  514. package/src/utils/render-slot-with-children.ts +31 -0
  515. package/src/visually-hidden/stories/index.story.tsx +6 -0
  516. package/build/utils/render-portal-with-children.cjs.map +0 -7
  517. package/build-module/utils/render-portal-with-children.mjs +0 -12
  518. package/build-module/utils/render-portal-with-children.mjs.map +0 -7
  519. package/build-types/utils/render-portal-with-children.d.ts +0 -16
  520. package/build-types/utils/render-portal-with-children.d.ts.map +0 -1
  521. package/src/utils/render-portal-with-children.ts +0 -27
@@ -5,26 +5,39 @@ const meta: Meta< typeof Select.Root > = {
5
5
  title: 'Design System/Components/Form/Primitives/Select',
6
6
  component: Select.Root,
7
7
  subcomponents: {
8
- Trigger: Select.Trigger,
9
- Popup: Select.Popup,
10
- Item: Select.Item,
8
+ 'Select.Trigger': Select.Trigger,
9
+ 'Select.Portal': Select.Portal,
10
+ 'Select.Popup': Select.Popup,
11
+ 'Select.Item': Select.Item,
12
+ },
13
+ parameters: {
14
+ componentStatus: {
15
+ status: 'use-with-caution',
16
+ whereUsed: 'global',
17
+ notes: 'Not yet recommended for use alongside components from `@wordpress/components`, pending review of style consistency with `@wordpress/components`, overlays compatibility, and component set completeness. See [WordPress/gutenberg#76135](https://github.com/WordPress/gutenberg/issues/76135).',
18
+ },
11
19
  },
12
20
  };
13
21
  export default meta;
14
22
 
15
23
  type Story = StoryObj< typeof Select.Root >;
16
24
 
25
+ const defaultItems = Array.from( { length: 6 }, ( _, index ) => ( {
26
+ value: `item-${ index + 1 }`,
27
+ label: `Item ${ index + 1 }`,
28
+ } ) );
29
+
17
30
  export const Default: Story = {
18
31
  args: {
32
+ items: defaultItems,
19
33
  children: (
20
34
  <>
21
35
  <Select.Trigger />
22
36
  <Select.Popup>
23
- { Array.from( { length: 6 }, ( _, index ) => (
24
- <Select.Item
25
- key={ index }
26
- value={ `Item ${ index + 1 }` }
27
- />
37
+ { defaultItems.map( ( item ) => (
38
+ <Select.Item key={ item.value } value={ item }>
39
+ { item.label }
40
+ </Select.Item>
28
41
  ) ) }
29
42
  </Select.Popup>
30
43
  </>
@@ -34,21 +47,23 @@ export const Default: Story = {
34
47
 
35
48
  export const Compact: Story = {
36
49
  args: {
50
+ ...Default.args,
37
51
  children: (
38
52
  <>
39
53
  <Select.Trigger size="compact" />
40
54
  <Select.Popup>
41
- { Array.from( { length: 6 }, ( _, index ) => (
55
+ { defaultItems.map( ( item ) => (
42
56
  <Select.Item
43
- key={ index }
44
- value={ `Item ${ index + 1 }` }
57
+ key={ item.value }
58
+ value={ item }
45
59
  size="compact"
46
- />
60
+ >
61
+ { item.label }
62
+ </Select.Item>
47
63
  ) ) }
48
64
  </Select.Popup>
49
65
  </>
50
66
  ),
51
- defaultValue: 'Item 1',
52
67
  },
53
68
  };
54
69
 
@@ -71,7 +86,9 @@ export const Minimal: Story = {
71
86
  key={ index }
72
87
  value={ `${ index + 1 }` }
73
88
  size="small"
74
- />
89
+ >
90
+ { `${ index + 1 }` }
91
+ </Select.Item>
75
92
  ) ) }
76
93
  </Select.Popup>
77
94
  </>
@@ -80,38 +97,51 @@ export const Minimal: Story = {
80
97
  },
81
98
  };
82
99
 
83
- const withEmptyOptionItems = [
84
- {
85
- value: '',
86
- label: 'Select',
87
- disabled: true,
88
- },
89
- {
90
- value: 'Item 2',
91
- label: 'Item 2',
100
+ /**
101
+ * Use the `placeholder` prop on `Select.Trigger` to show text when no
102
+ * value is selected. The default placeholder is `"Select"`.
103
+ */
104
+ export const WithCustomPlaceholder: Story = {
105
+ args: {
106
+ items: defaultItems,
107
+ children: (
108
+ <>
109
+ <Select.Trigger placeholder="Choose an item" />
110
+ <Select.Popup>
111
+ { defaultItems.map( ( item ) => (
112
+ <Select.Item key={ item.value } value={ item }>
113
+ { item.label }
114
+ </Select.Item>
115
+ ) ) }
116
+ </Select.Popup>
117
+ </>
118
+ ),
92
119
  },
120
+ };
121
+
122
+ const nullValueOptionItems = [
123
+ { value: null, label: 'Select theme' },
124
+ { value: 'system', label: 'System default' },
125
+ { value: 'light', label: 'Light' },
126
+ { value: 'dark', label: 'Dark' },
93
127
  ];
94
128
 
95
129
  /**
96
- * By passing an `items` array to `Select.Root`, the `Select.Trigger` will be able to
97
- * render a `label` string for each item rather than the raw `value` string. In this
98
- * case, the option with an empty string value has a `"Select"` label string.
99
- *
100
- * This may be easier than writing a custom render function for the `Select.Trigger`.
130
+ * Use a `null` item when users should be able to clear the selected value from
131
+ * the popup. When `items` includes a `null` item, its label is used as the
132
+ * placeholder text.
101
133
  */
102
- export const WithEmptyValueOption: Story = {
134
+ export const WithNullValueOption: Story = {
103
135
  args: {
104
- items: withEmptyOptionItems,
136
+ items: nullValueOptionItems,
105
137
  children: (
106
138
  <>
107
139
  <Select.Trigger />
108
140
  <Select.Popup>
109
- { withEmptyOptionItems.map( ( item ) => (
141
+ { nullValueOptionItems.map( ( item ) => (
110
142
  <Select.Item
111
- key={ item.value }
143
+ key={ item.value ?? 'null' }
112
144
  value={ item.value }
113
- label={ item.label }
114
- disabled={ item.disabled }
115
145
  >
116
146
  { item.label }
117
147
  </Select.Item>
@@ -119,7 +149,6 @@ export const WithEmptyValueOption: Story = {
119
149
  </Select.Popup>
120
150
  </>
121
151
  ),
122
- defaultValue: '',
123
152
  },
124
153
  };
125
154
 
@@ -131,75 +160,117 @@ export const WithEmptyValueOption: Story = {
131
160
  */
132
161
  export const Labeling: Story = {
133
162
  args: {
163
+ ...Default.args,
134
164
  children: (
135
165
  <>
136
166
  <Select.Trigger aria-label="User role" />
137
167
  <Select.Popup>
138
- <Select.Item value="Administrator" />
139
- <Select.Item value="Editor" />
168
+ { defaultItems.map( ( item ) => (
169
+ <Select.Item key={ item.value } value={ item }>
170
+ { item.label }
171
+ </Select.Item>
172
+ ) ) }
140
173
  </Select.Popup>
141
174
  </>
142
175
  ),
143
- defaultValue: 'Administrator',
144
176
  },
145
177
  };
146
178
 
147
179
  const longItemValue =
148
180
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.';
149
181
 
182
+ const overflowItems = [
183
+ {
184
+ value: 'long-item',
185
+ label: longItemValue,
186
+ },
187
+ {
188
+ value: 'item-2',
189
+ label: 'Item 2',
190
+ },
191
+ ];
192
+
150
193
  export const WithOverflow: Story = {
151
194
  args: {
195
+ items: overflowItems,
152
196
  children: (
153
197
  <>
154
198
  <Select.Trigger />
155
199
  <Select.Popup>
156
- <Select.Item value={ longItemValue } />
157
- <Select.Item value="Item 2" />
200
+ { overflowItems.map( ( item ) => (
201
+ <Select.Item key={ item.value } value={ item }>
202
+ { item.label }
203
+ </Select.Item>
204
+ ) ) }
158
205
  </Select.Popup>
159
206
  </>
160
207
  ),
161
- defaultValue: longItemValue,
208
+ defaultValue: overflowItems[ 0 ],
162
209
  },
163
210
  };
164
211
 
165
212
  export const Disabled: Story = {
166
213
  args: {
214
+ ...Default.args,
167
215
  children: (
168
216
  <>
169
217
  <Select.Trigger />
170
218
  <Select.Popup>
171
- <Select.Item value="Item 1" />
172
- <Select.Item value="Item 2" />
219
+ { defaultItems.map( ( item ) => (
220
+ <Select.Item key={ item.value } value={ item }>
221
+ { item.label }
222
+ </Select.Item>
223
+ ) ) }
173
224
  </Select.Popup>
174
225
  </>
175
226
  ),
176
- defaultValue: 'Item 1',
227
+ defaultValue: defaultItems[ 0 ],
177
228
  disabled: true,
178
229
  },
179
230
  };
180
231
 
232
+ const disabledItemItems = [
233
+ {
234
+ value: 'item-1',
235
+ label: 'Item 1',
236
+ },
237
+ {
238
+ value: 'item-2',
239
+ label: 'Item 2',
240
+ disabled: true,
241
+ },
242
+ ];
243
+
181
244
  export const WithDisabledItem: Story = {
182
245
  args: {
246
+ items: disabledItemItems,
183
247
  children: (
184
248
  <>
185
249
  <Select.Trigger />
186
250
  <Select.Popup>
187
- <Select.Item value="Item 1" />
188
- <Select.Item value="Item 2" disabled />
251
+ { disabledItemItems.map( ( item ) => (
252
+ <Select.Item
253
+ key={ item.value }
254
+ value={ item }
255
+ disabled={ item.disabled }
256
+ >
257
+ { item.label }
258
+ </Select.Item>
259
+ ) ) }
189
260
  </Select.Popup>
190
261
  </>
191
262
  ),
192
- defaultValue: 'Item 1',
263
+ defaultValue: disabledItemItems[ 0 ],
193
264
  },
194
265
  };
195
266
 
196
267
  const customOptions = [
197
268
  {
198
- value: 'User 1',
269
+ value: 'user-1',
199
270
  label: 'User 1 (Admin)',
200
271
  },
201
272
  {
202
- value: 'User 2',
273
+ value: 'user-2',
203
274
  label: 'User 2 (Editor)',
204
275
  },
205
276
  ];
@@ -210,10 +281,11 @@ const customOptions = [
210
281
  */
211
282
  export const WithCustomTriggerAndItem: Story = {
212
283
  args: {
284
+ items: customOptions,
213
285
  children: (
214
286
  <>
215
287
  <Select.Trigger>
216
- { ( value ) => (
288
+ { ( item ) => (
217
289
  <span
218
290
  style={ {
219
291
  display: 'flex',
@@ -222,31 +294,27 @@ export const WithCustomTriggerAndItem: Story = {
222
294
  } }
223
295
  >
224
296
  <img
225
- src={ `https://gravatar.com/avatar/?d=initials&name=${ value }` }
297
+ src={ `https://gravatar.com/avatar/?d=initials&name=${ item.value }` }
226
298
  alt=""
227
299
  width="20"
228
300
  style={ {
229
301
  borderRadius: '50%',
230
302
  } }
231
303
  />
232
- { value }
304
+ { item.label }
233
305
  </span>
234
306
  ) }
235
307
  </Select.Trigger>
236
308
  <Select.Popup>
237
309
  { customOptions.map( ( item ) => (
238
- <Select.Item
239
- key={ item.value }
240
- value={ item.value }
241
- label={ item.label }
242
- >
310
+ <Select.Item key={ item.value } value={ item }>
243
311
  { item.label }
244
312
  </Select.Item>
245
313
  ) ) }
246
314
  </Select.Popup>
247
315
  </>
248
316
  ),
249
- defaultValue: 'User 1',
317
+ defaultValue: customOptions[ 0 ],
250
318
  },
251
319
  };
252
320
 
@@ -269,6 +337,7 @@ export const WithCustomTriggerAndItem: Story = {
269
337
  export const WithCustomZIndex: Story = {
270
338
  name: 'With Custom z-index',
271
339
  args: {
340
+ ...Default.args,
272
341
  children: (
273
342
  <>
274
343
  <Select.Trigger />
@@ -279,11 +348,13 @@ export const WithCustomZIndex: Story = {
279
348
  />
280
349
  }
281
350
  >
282
- <Select.Item value="Item 1" />
283
- <Select.Item value="Item 2" />
351
+ { defaultItems.map( ( item ) => (
352
+ <Select.Item key={ item.value } value={ item }>
353
+ { item.label }
354
+ </Select.Item>
355
+ ) ) }
284
356
  </Select.Popup>
285
357
  </>
286
358
  ),
287
- defaultValue: 'Item 1',
288
359
  },
289
360
  };
@@ -1,9 +1,125 @@
1
- import { render, screen } from '@testing-library/react';
1
+ import { render, screen, within } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
  import { createRef } from '@wordpress/element';
4
4
  import * as Select from '../index';
5
5
 
6
6
  describe( 'Select', () => {
7
+ it( 'supports object item values', async () => {
8
+ const user = userEvent.setup();
9
+ const onValueChange = jest.fn();
10
+ const users = [
11
+ { value: '1', label: 'User 1' },
12
+ { value: '2', label: 'User 2' },
13
+ ];
14
+
15
+ render(
16
+ <Select.Root
17
+ defaultValue={ users[ 0 ] }
18
+ items={ users }
19
+ onValueChange={ onValueChange }
20
+ >
21
+ <Select.Trigger>{ ( value ) => value?.label }</Select.Trigger>
22
+ <Select.Popup>
23
+ { users.map( ( option ) => (
24
+ <Select.Item key={ option.value } value={ option }>
25
+ { option.label }
26
+ </Select.Item>
27
+ ) ) }
28
+ </Select.Popup>
29
+ </Select.Root>
30
+ );
31
+
32
+ const trigger = screen.getByRole( 'combobox' );
33
+
34
+ expect( trigger ).toHaveTextContent( 'User 1' );
35
+
36
+ await user.click( trigger );
37
+ await user.click(
38
+ await screen.findByRole( 'option', { name: 'User 2' } )
39
+ );
40
+
41
+ expect( trigger ).toHaveTextContent( 'User 2' );
42
+ expect( onValueChange ).toHaveBeenCalledTimes( 1 );
43
+ expect( onValueChange ).toHaveBeenLastCalledWith(
44
+ users[ 1 ],
45
+ expect.objectContaining( { reason: expect.any( String ) } )
46
+ );
47
+ } );
48
+
49
+ it( 'auto-resolves trigger label from items when value is an object', () => {
50
+ const users = [
51
+ { value: '1', label: 'User 1' },
52
+ { value: '2', label: 'User 2' },
53
+ ];
54
+
55
+ render(
56
+ <Select.Root defaultValue={ users[ 0 ] } items={ users }>
57
+ <Select.Trigger />
58
+ <Select.Popup>
59
+ { users.map( ( option ) => (
60
+ <Select.Item key={ option.value } value={ option }>
61
+ { option.label }
62
+ </Select.Item>
63
+ ) ) }
64
+ </Select.Popup>
65
+ </Select.Root>
66
+ );
67
+
68
+ expect( screen.getByRole( 'combobox' ) ).toHaveTextContent( 'User 1' );
69
+ } );
70
+
71
+ it( 'renders a default placeholder when no value is selected', () => {
72
+ render(
73
+ <Select.Root>
74
+ <Select.Trigger />
75
+ <Select.Popup>
76
+ <Select.Item value="Item 1" />
77
+ </Select.Popup>
78
+ </Select.Root>
79
+ );
80
+
81
+ const placeholder = screen.getByText( 'Select' );
82
+
83
+ expect( screen.getByRole( 'combobox' ) ).toHaveTextContent( 'Select' );
84
+ expect( placeholder ).toHaveAttribute( 'data-placeholder' );
85
+ } );
86
+
87
+ it( 'supports custom placeholder text', () => {
88
+ render(
89
+ <Select.Root>
90
+ <Select.Trigger placeholder="Choose an item" />
91
+ <Select.Popup>
92
+ <Select.Item value="Item 1" />
93
+ </Select.Popup>
94
+ </Select.Root>
95
+ );
96
+
97
+ const placeholder = screen.getByText( 'Choose an item' );
98
+
99
+ expect( screen.getByRole( 'combobox' ) ).toHaveTextContent(
100
+ 'Choose an item'
101
+ );
102
+ expect( placeholder ).toHaveAttribute( 'data-placeholder' );
103
+ } );
104
+
105
+ it( 'does not use placeholder styling when a value is selected', () => {
106
+ render(
107
+ <Select.Root defaultValue="Item 1">
108
+ <Select.Trigger />
109
+ <Select.Popup>
110
+ <Select.Item value="Item 1" />
111
+ </Select.Popup>
112
+ </Select.Root>
113
+ );
114
+
115
+ const trigger = screen.getByRole( 'combobox' );
116
+
117
+ expect( trigger ).toHaveTextContent( 'Item 1' );
118
+ expect( within( trigger ).getByText( 'Item 1' ) ).not.toHaveAttribute(
119
+ 'data-placeholder'
120
+ );
121
+ } );
122
+
7
123
  it( 'forwards ref', async () => {
8
124
  const user = userEvent.setup();
9
125
  const triggerRef = createRef< HTMLButtonElement >();
@@ -14,8 +130,10 @@ describe( 'Select', () => {
14
130
  <Select.Root>
15
131
  <Select.Trigger ref={ triggerRef } />
16
132
  <Select.Popup ref={ popupRef }>
17
- <Select.Item ref={ itemRef } value="Item 1" />
18
- <Select.Item value="Item 2" />
133
+ <Select.Item ref={ itemRef } value="Item 1">
134
+ Item 1
135
+ </Select.Item>
136
+ <Select.Item value="Item 2">Item 2</Select.Item>
19
137
  </Select.Popup>
20
138
  </Select.Root>
21
139
  );
@@ -49,7 +167,7 @@ describe( 'Select', () => {
49
167
  <Select.Portal container={ containerRef } />
50
168
  }
51
169
  >
52
- <Select.Item value="Item 1" />
170
+ <Select.Item value="Item 1">Item 1</Select.Item>
53
171
  </Select.Popup>
54
172
  </Select.Root>
55
173
  </div>
@@ -75,7 +193,7 @@ describe( 'Select', () => {
75
193
  <Select.Root>
76
194
  <Select.Trigger />
77
195
  <Select.Popup>
78
- <Select.Item value="Item 1" />
196
+ <Select.Item value="Item 1">Item 1</Select.Item>
79
197
  </Select.Popup>
80
198
  </Select.Root>
81
199
  </div>
@@ -2,6 +2,7 @@ import { Select as _Select } from '@base-ui/react/select';
2
2
  import clsx from 'clsx';
3
3
  import { forwardRef } from '@wordpress/element';
4
4
  import { chevronDown } from '@wordpress/icons';
5
+ import { __ } from '@wordpress/i18n';
5
6
  import focusStyles from '../../../utils/css/focus.module.css';
6
7
  import selectTriggerStyles from '../../../utils/css/select-trigger.module.css';
7
8
  import { InputLayout } from '../input-layout';
@@ -10,7 +11,14 @@ import type { SelectTriggerProps } from './types';
10
11
 
11
12
  export const Trigger = forwardRef< HTMLButtonElement, SelectTriggerProps >(
12
13
  function Trigger(
13
- { className, size, variant, children, ...restProps },
14
+ {
15
+ className,
16
+ size,
17
+ variant,
18
+ children,
19
+ placeholder = __( 'Select' ),
20
+ ...restProps
21
+ },
14
22
  ref
15
23
  ) {
16
24
  return (
@@ -36,13 +44,8 @@ export const Trigger = forwardRef< HTMLButtonElement, SelectTriggerProps >(
36
44
  ref={ ref }
37
45
  >
38
46
  <_Select.Value
39
- className={ ( state ) =>
40
- clsx(
41
- selectTriggerStyles[ 'trigger-value' ],
42
- state.value === '' &&
43
- selectTriggerStyles[ 'is-placeholder' ]
44
- )
45
- }
47
+ placeholder={ placeholder }
48
+ className={ selectTriggerStyles[ 'trigger-value' ] }
46
49
  >
47
50
  { children }
48
51
  </_Select.Value>
@@ -7,8 +7,8 @@ import type { InputLayoutProps } from '../input-layout/types';
7
7
  export type PortalProps = ComponentPropsWithoutRef< typeof _Select.Portal >;
8
8
 
9
9
  // The second type parameter is the `multiple` flag (currently disabled).
10
- export type SelectRootProps = Omit<
11
- _Select.Root.Props< string, false >,
10
+ export type SelectRootProps< Value = unknown > = Omit<
11
+ _Select.Root.Props< Value, false >,
12
12
  'multiple'
13
13
  >;
14
14
 
@@ -25,9 +25,19 @@ export type SelectTriggerProps = ComponentProps< typeof _Select.Trigger > & {
25
25
  * @default 'default'
26
26
  */
27
27
  variant?: 'default' | 'minimal';
28
+ /**
29
+ * Text to show when no value is selected.
30
+ * This is overridden by `children` if specified, or by a null item's label in `items`.
31
+ *
32
+ * @default __( 'Select' )
33
+ */
34
+ placeholder?: _Select.Value.Props[ 'placeholder' ];
28
35
  /**
29
36
  * A function that gets called with the current value as an argument.
30
37
  * Use this to customize the trigger content.
38
+ *
39
+ * When no value is selected, the rendered content inherits the
40
+ * placeholder text color.
31
41
  */
32
42
  children?: _Select.Value.Props[ 'children' ];
33
43
  };
@@ -53,7 +63,7 @@ export type SelectItemProps = Omit<
53
63
  /**
54
64
  * A unique value that identifies this select item.
55
65
  */
56
- value?: string;
66
+ value?: unknown;
57
67
  /**
58
68
  * The size of the item.
59
69
  *
@@ -62,8 +72,6 @@ export type SelectItemProps = Omit<
62
72
  size?: InputLayoutProps[ 'size' ];
63
73
  /**
64
74
  * The content of the item.
65
- *
66
- * @default `value`
67
75
  */
68
76
  children?: _Select.Item.Props[ 'children' ];
69
77
  };
@@ -4,6 +4,13 @@ import { Textarea } from '../index';
4
4
  const meta: Meta< typeof Textarea > = {
5
5
  title: 'Design System/Components/Form/Primitives/Textarea',
6
6
  component: Textarea,
7
+ parameters: {
8
+ componentStatus: {
9
+ status: 'use-with-caution',
10
+ whereUsed: 'global',
11
+ notes: 'Not yet recommended for use alongside components from `@wordpress/components`, pending review of style consistency with `@wordpress/components` and component set completeness. See [WordPress/gutenberg#76135](https://github.com/WordPress/gutenberg/issues/76135).',
12
+ },
13
+ },
7
14
  };
8
15
  export default meta;
9
16
 
@@ -0,0 +1,9 @@
1
+ import { createContext, useContext } from '@wordpress/element';
2
+ import type { SelectTriggerProps } from '../primitives/select/types';
3
+
4
+ export const SelectControlSizeContext =
5
+ createContext< SelectTriggerProps[ 'size' ] >( undefined );
6
+
7
+ export const useSelectControlSizeContext = () => {
8
+ return useContext( SelectControlSizeContext );
9
+ };
@@ -0,0 +1,14 @@
1
+ import { SelectControl as _SelectControl } from './select-control';
2
+ import { Item } from './item';
3
+
4
+ Item.displayName = 'SelectControl.Item';
5
+
6
+ /**
7
+ * A complete select field with integrated label and description.
8
+ */
9
+ export const SelectControl = Object.assign( _SelectControl, {
10
+ /**
11
+ * An item rendered inside a `SelectControl` popup.
12
+ */
13
+ Item,
14
+ } );
@@ -0,0 +1,13 @@
1
+ import { forwardRef } from '@wordpress/element';
2
+ import { Select } from '../primitives';
3
+ import { useSelectControlSizeContext } from './context';
4
+ import type { SelectItemProps } from '../primitives/select/types';
5
+
6
+ export const Item = forwardRef< HTMLDivElement, SelectItemProps >(
7
+ function Item( { size: sizeProp, ...restProps }, ref ) {
8
+ const contextSize = useSelectControlSizeContext();
9
+ const size = sizeProp ?? contextSize;
10
+
11
+ return <Select.Item size={ size } ref={ ref } { ...restProps } />;
12
+ }
13
+ );