@wordpress/components 25.9.1 → 25.11.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 (369) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/build/alignment-matrix-control/cell.js +8 -5
  3. package/build/alignment-matrix-control/cell.js.map +1 -1
  4. package/build/alignment-matrix-control/index.js +27 -43
  5. package/build/alignment-matrix-control/index.js.map +1 -1
  6. package/build/alignment-matrix-control/utils.js +29 -9
  7. package/build/alignment-matrix-control/utils.js.map +1 -1
  8. package/build/autocomplete/index.js +104 -52
  9. package/build/autocomplete/index.js.map +1 -1
  10. package/build/circular-option-picker/circular-option-picker-option.js +20 -39
  11. package/build/circular-option-picker/circular-option-picker-option.js.map +1 -1
  12. package/build/circular-option-picker/circular-option-picker.js +11 -32
  13. package/build/circular-option-picker/circular-option-picker.js.map +1 -1
  14. package/build/circular-option-picker/types.js.map +1 -1
  15. package/build/color-palette/index.js +7 -2
  16. package/build/color-palette/index.js.map +1 -1
  17. package/build/color-picker/component.js +12 -2
  18. package/build/color-picker/component.js.map +1 -1
  19. package/build/color-picker/picker.js +77 -1
  20. package/build/color-picker/picker.js.map +1 -1
  21. package/build/color-picker/styles.js +8 -8
  22. package/build/color-picker/styles.js.map +1 -1
  23. package/build/color-picker/types.js.map +1 -1
  24. package/build/composite/v2.js +43 -0
  25. package/build/composite/v2.js.map +1 -0
  26. package/build/confirm-dialog/component.js +74 -8
  27. package/build/confirm-dialog/component.js.map +1 -1
  28. package/build/confirm-dialog/types.js.map +1 -1
  29. package/build/custom-gradient-picker/gradient-bar/control-points.js +13 -4
  30. package/build/custom-gradient-picker/gradient-bar/control-points.js.map +1 -1
  31. package/build/dropdown-menu-v2-ariakit/index.js +217 -0
  32. package/build/dropdown-menu-v2-ariakit/index.js.map +1 -0
  33. package/build/dropdown-menu-v2-ariakit/styles.js +157 -0
  34. package/build/dropdown-menu-v2-ariakit/styles.js.map +1 -0
  35. package/build/dropdown-menu-v2-ariakit/types.js +6 -0
  36. package/build/dropdown-menu-v2-ariakit/types.js.map +1 -0
  37. package/build/font-size-picker/utils.js +1 -1
  38. package/build/font-size-picker/utils.js.map +1 -1
  39. package/build/input-control/styles/input-control-styles.js +23 -23
  40. package/build/input-control/styles/input-control-styles.js.map +1 -1
  41. package/build/mobile/global-styles-context/utils.native.js +1 -1
  42. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  43. package/build/modal/index.js +45 -16
  44. package/build/modal/index.js.map +1 -1
  45. package/build/palette-edit/index.js +4 -0
  46. package/build/palette-edit/index.js.map +1 -1
  47. package/build/popover/index.js +34 -6
  48. package/build/popover/index.js.map +1 -1
  49. package/build/private-apis.js +18 -2
  50. package/build/private-apis.js.map +1 -1
  51. package/build/progress-bar/styles.js +5 -5
  52. package/build/progress-bar/styles.js.map +1 -1
  53. package/build/sandbox/index.js +1 -1
  54. package/build/sandbox/index.js.map +1 -1
  55. package/build/sandbox/index.native.js +1 -1
  56. package/build/sandbox/index.native.js.map +1 -1
  57. package/build/select-control/styles/select-control-styles.js +8 -8
  58. package/build/select-control/styles/select-control-styles.js.map +1 -1
  59. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
  60. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  61. package/build/tabs/context.js +16 -0
  62. package/build/tabs/context.js.map +1 -0
  63. package/build/tabs/index.js +147 -0
  64. package/build/tabs/index.js.map +1 -0
  65. package/build/tabs/styles.js +38 -0
  66. package/build/tabs/styles.js.map +1 -0
  67. package/build/tabs/tab.js +46 -0
  68. package/build/tabs/tab.js.map +1 -0
  69. package/build/tabs/tablist.js +47 -0
  70. package/build/tabs/tablist.js.map +1 -0
  71. package/build/tabs/tabpanel.js +48 -0
  72. package/build/tabs/tabpanel.js.map +1 -0
  73. package/build/tabs/types.js +6 -0
  74. package/build/tabs/types.js.map +1 -0
  75. package/build/text/component.js +7 -6
  76. package/build/text/component.js.map +1 -1
  77. package/build/text/hook.js +6 -15
  78. package/build/text/hook.js.map +1 -1
  79. package/build/text/index.js.map +1 -1
  80. package/build/text/styles.js +7 -7
  81. package/build/text/styles.js.map +1 -1
  82. package/build/text/types.js.map +1 -1
  83. package/build/text/utils.js +17 -33
  84. package/build/text/utils.js.map +1 -1
  85. package/build/toggle-group-control/toggle-group-control-option-base/component.js +1 -0
  86. package/build/toggle-group-control/toggle-group-control-option-base/component.js.map +1 -1
  87. package/build/toolbar/toolbar/index.js +17 -10
  88. package/build/toolbar/toolbar/index.js.map +1 -1
  89. package/build/toolbar/toolbar/types.js.map +1 -1
  90. package/build/tools-panel/tools-panel-item/hook.js +2 -2
  91. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  92. package/build/tools-panel/types.js.map +1 -1
  93. package/build/tooltip/index.js +2 -2
  94. package/build/tooltip/index.js.map +1 -1
  95. package/build/unit-control/utils.js +108 -0
  96. package/build/unit-control/utils.js.map +1 -1
  97. package/build/utils/unit-values.js +1 -1
  98. package/build/utils/unit-values.js.map +1 -1
  99. package/build-module/alignment-matrix-control/cell.js +7 -4
  100. package/build-module/alignment-matrix-control/cell.js.map +1 -1
  101. package/build-module/alignment-matrix-control/index.js +27 -43
  102. package/build-module/alignment-matrix-control/index.js.map +1 -1
  103. package/build-module/alignment-matrix-control/utils.js +29 -8
  104. package/build-module/alignment-matrix-control/utils.js.map +1 -1
  105. package/build-module/autocomplete/index.js +104 -52
  106. package/build-module/autocomplete/index.js.map +1 -1
  107. package/build-module/circular-option-picker/circular-option-picker-option.js +20 -39
  108. package/build-module/circular-option-picker/circular-option-picker-option.js.map +1 -1
  109. package/build-module/circular-option-picker/circular-option-picker.js +10 -31
  110. package/build-module/circular-option-picker/circular-option-picker.js.map +1 -1
  111. package/build-module/circular-option-picker/types.js.map +1 -1
  112. package/build-module/color-palette/index.js +7 -2
  113. package/build-module/color-palette/index.js.map +1 -1
  114. package/build-module/color-picker/component.js +13 -3
  115. package/build-module/color-picker/component.js.map +1 -1
  116. package/build-module/color-picker/picker.js +78 -2
  117. package/build-module/color-picker/picker.js.map +1 -1
  118. package/build-module/color-picker/styles.js +8 -8
  119. package/build-module/color-picker/styles.js.map +1 -1
  120. package/build-module/color-picker/types.js.map +1 -1
  121. package/build-module/composite/v2.js +15 -0
  122. package/build-module/composite/v2.js.map +1 -0
  123. package/build-module/confirm-dialog/component.js +72 -7
  124. package/build-module/confirm-dialog/component.js.map +1 -1
  125. package/build-module/confirm-dialog/types.js.map +1 -1
  126. package/build-module/custom-gradient-picker/gradient-bar/control-points.js +13 -4
  127. package/build-module/custom-gradient-picker/gradient-bar/control-points.js.map +1 -1
  128. package/build-module/dropdown-menu-v2-ariakit/index.js +199 -0
  129. package/build-module/dropdown-menu-v2-ariakit/index.js.map +1 -0
  130. package/build-module/dropdown-menu-v2-ariakit/styles.js +136 -0
  131. package/build-module/dropdown-menu-v2-ariakit/styles.js.map +1 -0
  132. package/build-module/dropdown-menu-v2-ariakit/types.js +2 -0
  133. package/build-module/dropdown-menu-v2-ariakit/types.js.map +1 -0
  134. package/build-module/font-size-picker/utils.js +1 -1
  135. package/build-module/font-size-picker/utils.js.map +1 -1
  136. package/build-module/input-control/styles/input-control-styles.js +23 -23
  137. package/build-module/input-control/styles/input-control-styles.js.map +1 -1
  138. package/build-module/mobile/global-styles-context/utils.native.js +2 -2
  139. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  140. package/build-module/modal/index.js +47 -18
  141. package/build-module/modal/index.js.map +1 -1
  142. package/build-module/palette-edit/index.js +4 -0
  143. package/build-module/palette-edit/index.js.map +1 -1
  144. package/build-module/popover/index.js +34 -6
  145. package/build-module/popover/index.js.map +1 -1
  146. package/build-module/private-apis.js +18 -2
  147. package/build-module/private-apis.js.map +1 -1
  148. package/build-module/progress-bar/styles.js +5 -5
  149. package/build-module/progress-bar/styles.js.map +1 -1
  150. package/build-module/sandbox/index.js +1 -1
  151. package/build-module/sandbox/index.js.map +1 -1
  152. package/build-module/sandbox/index.native.js +1 -1
  153. package/build-module/sandbox/index.native.js.map +1 -1
  154. package/build-module/select-control/styles/select-control-styles.js +8 -8
  155. package/build-module/select-control/styles/select-control-styles.js.map +1 -1
  156. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
  157. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  158. package/build-module/tabs/context.js +12 -0
  159. package/build-module/tabs/context.js.map +1 -0
  160. package/build-module/tabs/index.js +142 -0
  161. package/build-module/tabs/index.js.map +1 -0
  162. package/build-module/tabs/styles.js +36 -0
  163. package/build-module/tabs/styles.js.map +1 -0
  164. package/build-module/tabs/tab.js +43 -0
  165. package/build-module/tabs/tab.js.map +1 -0
  166. package/build-module/tabs/tablist.js +41 -0
  167. package/build-module/tabs/tablist.js.map +1 -0
  168. package/build-module/tabs/tabpanel.js +43 -0
  169. package/build-module/tabs/tabpanel.js.map +1 -0
  170. package/build-module/tabs/types.js +2 -0
  171. package/build-module/tabs/types.js.map +1 -0
  172. package/build-module/text/component.js +6 -6
  173. package/build-module/text/component.js.map +1 -1
  174. package/build-module/text/hook.js +11 -19
  175. package/build-module/text/hook.js.map +1 -1
  176. package/build-module/text/index.js.map +1 -1
  177. package/build-module/text/styles.js +7 -7
  178. package/build-module/text/styles.js.map +1 -1
  179. package/build-module/text/types.js.map +1 -1
  180. package/build-module/text/utils.js +17 -10
  181. package/build-module/text/utils.js.map +1 -1
  182. package/build-module/toggle-group-control/toggle-group-control-option-base/component.js +1 -0
  183. package/build-module/toggle-group-control/toggle-group-control-option-base/component.js.map +1 -1
  184. package/build-module/toolbar/toolbar/index.js +18 -11
  185. package/build-module/toolbar/toolbar/index.js.map +1 -1
  186. package/build-module/toolbar/toolbar/types.js.map +1 -1
  187. package/build-module/tools-panel/tools-panel-item/hook.js +2 -2
  188. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  189. package/build-module/tools-panel/types.js.map +1 -1
  190. package/build-module/tooltip/index.js +2 -2
  191. package/build-module/tooltip/index.js.map +1 -1
  192. package/build-module/unit-control/utils.js +108 -0
  193. package/build-module/unit-control/utils.js.map +1 -1
  194. package/build-module/utils/unit-values.js +1 -1
  195. package/build-module/utils/unit-values.js.map +1 -1
  196. package/build-style/style-rtl.css +17 -5
  197. package/build-style/style.css +17 -5
  198. package/build-types/alignment-matrix-control/cell.d.ts +1 -1
  199. package/build-types/alignment-matrix-control/cell.d.ts.map +1 -1
  200. package/build-types/alignment-matrix-control/index.d.ts.map +1 -1
  201. package/build-types/alignment-matrix-control/stories/index.story.d.ts.map +1 -1
  202. package/build-types/alignment-matrix-control/utils.d.ts +9 -9
  203. package/build-types/alignment-matrix-control/utils.d.ts.map +1 -1
  204. package/build-types/autocomplete/index.d.ts.map +1 -1
  205. package/build-types/circular-option-picker/circular-option-picker-option.d.ts.map +1 -1
  206. package/build-types/circular-option-picker/circular-option-picker.d.ts.map +1 -1
  207. package/build-types/circular-option-picker/types.d.ts +4 -6
  208. package/build-types/circular-option-picker/types.d.ts.map +1 -1
  209. package/build-types/color-palette/index.d.ts.map +1 -1
  210. package/build-types/color-picker/component.d.ts.map +1 -1
  211. package/build-types/color-picker/picker.d.ts +1 -1
  212. package/build-types/color-picker/picker.d.ts.map +1 -1
  213. package/build-types/color-picker/styles.d.ts.map +1 -1
  214. package/build-types/color-picker/types.d.ts +3 -0
  215. package/build-types/color-picker/types.d.ts.map +1 -1
  216. package/build-types/composite/v2.d.ts +12 -0
  217. package/build-types/composite/v2.d.ts.map +1 -0
  218. package/build-types/confirm-dialog/component.d.ts +70 -29
  219. package/build-types/confirm-dialog/component.d.ts.map +1 -1
  220. package/build-types/confirm-dialog/stories/index.story.d.ts +11 -0
  221. package/build-types/confirm-dialog/stories/index.story.d.ts.map +1 -0
  222. package/build-types/confirm-dialog/test/index.d.ts +2 -0
  223. package/build-types/confirm-dialog/test/index.d.ts.map +1 -0
  224. package/build-types/confirm-dialog/types.d.ts +32 -10
  225. package/build-types/confirm-dialog/types.d.ts.map +1 -1
  226. package/build-types/custom-gradient-picker/gradient-bar/control-points.d.ts.map +1 -1
  227. package/build-types/dropdown-menu-v2-ariakit/index.d.ts +11 -0
  228. package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +1 -0
  229. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts +16 -0
  230. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +1 -0
  231. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +88 -0
  232. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +1 -0
  233. package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts +2 -0
  234. package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts.map +1 -0
  235. package/build-types/dropdown-menu-v2-ariakit/types.d.ts +174 -0
  236. package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +1 -0
  237. package/build-types/font-size-picker/utils.d.ts.map +1 -1
  238. package/build-types/heading/stories/index.story.d.ts.map +1 -1
  239. package/build-types/modal/index.d.ts.map +1 -1
  240. package/build-types/palette-edit/index.d.ts.map +1 -1
  241. package/build-types/popover/index.d.ts +1 -1
  242. package/build-types/popover/index.d.ts.map +1 -1
  243. package/build-types/popover/stories/e2e/index.story.d.ts +1 -1
  244. package/build-types/private-apis.d.ts.map +1 -1
  245. package/build-types/progress-bar/styles.d.ts.map +1 -1
  246. package/build-types/sandbox/index.d.ts.map +1 -1
  247. package/build-types/tabs/context.d.ts +8 -0
  248. package/build-types/tabs/context.d.ts.map +1 -0
  249. package/build-types/tabs/index.d.ts +13 -0
  250. package/build-types/tabs/index.d.ts.map +1 -0
  251. package/build-types/tabs/stories/index.story.d.ts +20 -0
  252. package/build-types/tabs/stories/index.story.d.ts.map +1 -0
  253. package/build-types/tabs/styles.d.ts +17 -0
  254. package/build-types/tabs/styles.d.ts.map +1 -0
  255. package/build-types/tabs/tab.d.ts +10 -0
  256. package/build-types/tabs/tab.d.ts.map +1 -0
  257. package/build-types/tabs/tablist.d.ts +7 -0
  258. package/build-types/tabs/tablist.d.ts.map +1 -0
  259. package/build-types/tabs/tabpanel.d.ts +7 -0
  260. package/build-types/tabs/tabpanel.d.ts.map +1 -0
  261. package/build-types/tabs/test/index.d.ts +2 -0
  262. package/build-types/tabs/test/index.d.ts.map +1 -0
  263. package/build-types/tabs/types.d.ts +134 -0
  264. package/build-types/tabs/types.d.ts.map +1 -0
  265. package/build-types/text/component.d.ts +4 -2
  266. package/build-types/text/component.d.ts.map +1 -1
  267. package/build-types/text/hook.d.ts +171 -165
  268. package/build-types/text/hook.d.ts.map +1 -1
  269. package/build-types/text/index.d.ts +2 -2
  270. package/build-types/text/index.d.ts.map +1 -1
  271. package/build-types/text/stories/index.story.d.ts +21 -0
  272. package/build-types/text/stories/index.story.d.ts.map +1 -0
  273. package/build-types/text/styles.d.ts +7 -7
  274. package/build-types/text/styles.d.ts.map +1 -1
  275. package/build-types/text/types.d.ts +1 -1
  276. package/build-types/text/types.d.ts.map +1 -1
  277. package/build-types/text/utils.d.ts +56 -61
  278. package/build-types/text/utils.d.ts.map +1 -1
  279. package/build-types/toggle-group-control/toggle-group-control-option-base/component.d.ts.map +1 -1
  280. package/build-types/toolbar/stories/index.story.d.ts +5 -0
  281. package/build-types/toolbar/stories/index.story.d.ts.map +1 -1
  282. package/build-types/toolbar/toolbar/index.d.ts.map +1 -1
  283. package/build-types/toolbar/toolbar/types.d.ts +10 -0
  284. package/build-types/toolbar/toolbar/types.d.ts.map +1 -1
  285. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  286. package/build-types/tools-panel/types.d.ts +2 -0
  287. package/build-types/tools-panel/types.d.ts.map +1 -1
  288. package/build-types/tooltip/index.d.ts.map +1 -1
  289. package/build-types/unit-control/utils.d.ts.map +1 -1
  290. package/package.json +21 -20
  291. package/src/alignment-matrix-control/cell.tsx +6 -2
  292. package/src/alignment-matrix-control/index.tsx +31 -54
  293. package/src/alignment-matrix-control/stories/index.story.tsx +3 -7
  294. package/src/alignment-matrix-control/test/index.tsx +117 -18
  295. package/src/alignment-matrix-control/utils.tsx +33 -9
  296. package/src/autocomplete/index.tsx +136 -77
  297. package/src/button/style.scss +1 -2
  298. package/src/circular-option-picker/circular-option-picker-option.tsx +24 -38
  299. package/src/circular-option-picker/circular-option-picker.tsx +11 -28
  300. package/src/circular-option-picker/types.ts +6 -5
  301. package/src/color-palette/index.tsx +6 -1
  302. package/src/color-picker/component.tsx +25 -3
  303. package/src/color-picker/picker.tsx +96 -2
  304. package/src/color-picker/styles.ts +0 -1
  305. package/src/color-picker/types.ts +3 -0
  306. package/src/composite/v2.ts +22 -0
  307. package/src/confirm-dialog/README.md +1 -1
  308. package/src/confirm-dialog/component.tsx +79 -13
  309. package/src/confirm-dialog/stories/{index.story.js → index.story.tsx} +26 -24
  310. package/src/confirm-dialog/test/{index.js → index.tsx} +3 -3
  311. package/src/confirm-dialog/types.ts +32 -12
  312. package/src/custom-gradient-picker/gradient-bar/control-points.tsx +32 -25
  313. package/src/dimension-control/test/__snapshots__/index.test.js.snap +8 -8
  314. package/src/dropdown-menu-v2-ariakit/README.md +324 -0
  315. package/src/dropdown-menu-v2-ariakit/index.tsx +318 -0
  316. package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +506 -0
  317. package/src/dropdown-menu-v2-ariakit/styles.ts +297 -0
  318. package/src/dropdown-menu-v2-ariakit/test/index.tsx +1139 -0
  319. package/src/dropdown-menu-v2-ariakit/types.ts +186 -0
  320. package/src/font-size-picker/utils.ts +2 -1
  321. package/src/heading/stories/index.story.tsx +2 -4
  322. package/src/input-control/styles/input-control-styles.tsx +2 -2
  323. package/src/mobile/global-styles-context/utils.native.js +2 -2
  324. package/src/modal/index.tsx +58 -22
  325. package/src/modal/test/index.tsx +29 -0
  326. package/src/notice/style.scss +0 -1
  327. package/src/palette-edit/index.tsx +4 -0
  328. package/src/popover/index.tsx +99 -57
  329. package/src/popover/style.scss +9 -0
  330. package/src/private-apis.ts +31 -1
  331. package/src/progress-bar/styles.ts +19 -4
  332. package/src/sandbox/index.native.js +1 -1
  333. package/src/sandbox/index.tsx +3 -1
  334. package/src/select-control/styles/select-control-styles.ts +2 -2
  335. package/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx +1 -1
  336. package/src/tabs/README.md +242 -0
  337. package/src/tabs/context.ts +13 -0
  338. package/src/tabs/index.tsx +167 -0
  339. package/src/tabs/stories/index.story.tsx +352 -0
  340. package/src/tabs/styles.ts +103 -0
  341. package/src/tabs/tab.tsx +39 -0
  342. package/src/tabs/tablist.tsx +40 -0
  343. package/src/tabs/tabpanel.tsx +42 -0
  344. package/src/tabs/test/index.tsx +1133 -0
  345. package/src/tabs/types.ts +142 -0
  346. package/src/text/README.md +2 -2
  347. package/src/text/{component.js → component.tsx} +10 -6
  348. package/src/text/{hook.js → hook.ts} +12 -15
  349. package/src/text/stories/index.story.tsx +80 -0
  350. package/src/text/types.ts +1 -6
  351. package/src/text/{utils.js → utils.ts} +40 -14
  352. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +16 -0
  353. package/src/toggle-group-control/toggle-group-control-option-base/component.tsx +1 -0
  354. package/src/toolbar/stories/index.story.tsx +15 -0
  355. package/src/toolbar/test/index.tsx +8 -0
  356. package/src/toolbar/toolbar/README.md +9 -0
  357. package/src/toolbar/toolbar/index.tsx +21 -12
  358. package/src/toolbar/toolbar/style.scss +9 -0
  359. package/src/toolbar/toolbar/types.ts +10 -0
  360. package/src/tools-panel/tools-panel/README.md +3 -0
  361. package/src/tools-panel/tools-panel-item/hook.ts +4 -6
  362. package/src/tools-panel/types.ts +2 -0
  363. package/src/tooltip/index.tsx +2 -3
  364. package/src/unit-control/utils.ts +124 -0
  365. package/src/utils/unit-values.ts +1 -1
  366. package/tsconfig.tsbuildinfo +1 -1
  367. package/src/text/stories/index.story.js +0 -53
  368. /package/src/text/{index.js → index.ts} +0 -0
  369. /package/src/text/{styles.js → styles.ts} +0 -0
@@ -0,0 +1,324 @@
1
+ # `DropdownMenu` (v2)
2
+
3
+ <div class="callout callout-alert">
4
+ This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes.
5
+ </div>
6
+
7
+ `DropdownMenu` displays a menu to the user (such as a set of actions or functions) triggered by a button.
8
+
9
+
10
+ ## Design guidelines
11
+
12
+ ### Usage
13
+
14
+ #### When to use a DropdownMenu
15
+
16
+ Use a DropdownMenu when you want users to:
17
+
18
+ - Choose an action or change a setting from a list, AND
19
+ - Only see the available choices contextually.
20
+
21
+ `DropdownMenu` is a React component to render an expandable menu of buttons. It is similar in purpose to a `<select>` element, with the distinction that it does not maintain a value. Instead, each option behaves as an action button.
22
+
23
+ If you need to display all the available options at all times, consider using a Toolbar instead. Use a `DropdownMenu` to display a list of actions after the user interacts with a button.
24
+
25
+ **Do**
26
+ Use a `DropdownMenu` to display a list of actions after the user interacts with an icon.
27
+
28
+ **Don’t** use a `DropdownMenu` for important actions that should always be visible. Use a `Toolbar` instead.
29
+
30
+ **Don’t**
31
+ Don’t use a `DropdownMenu` for frequently used actions. Use a `Toolbar` instead.
32
+
33
+ #### Behavior
34
+
35
+ Generally, the parent button should indicate that interacting with it will show a `DropdownMenu`.
36
+
37
+ The parent button should retain the same visual styling regardless of whether the `DropdownMenu` is displayed or not.
38
+
39
+ #### Placement
40
+
41
+ The `DropdownMenu` should typically appear directly below, or below and to the left of, the parent button. If there isn’t enough space below to display the full `DropdownMenu`, it can be displayed instead above the parent button.
42
+
43
+ ## Development guidelines
44
+
45
+ This component is still highly experimental, and it's not normally accessible to consumers of the `@wordpress/components` package.
46
+
47
+ The component exposes a set of components that are meant to be used in combination with each other in order to implement a `DropdownMenu` correctly.
48
+
49
+ ### `DropdownMenu`
50
+
51
+ The root component, used to specify the menu's trigger and its contents.
52
+
53
+ #### Props
54
+
55
+ The component accepts the following props:
56
+
57
+ ##### `trigger`: `React.ReactNode`
58
+
59
+ The trigger button
60
+
61
+ - Required: yes
62
+
63
+ ##### `children`: `React.ReactNode`
64
+
65
+ The contents of the dropdown
66
+
67
+ - Required: yes
68
+
69
+ ##### `defaultOpen`: `boolean`
70
+
71
+ The open state of the dropdown menu when it is initially rendered. Use when not wanting to control its open state.
72
+
73
+ - Required: no
74
+ - Default: `false`
75
+
76
+ ##### `open`: `boolean`
77
+
78
+ The controlled open state of the dropdown menu. Must be used in conjunction with `onOpenChange`.
79
+
80
+ - Required: no
81
+
82
+ ##### `onOpenChange`: `(open: boolean) => void`
83
+
84
+ Event handler called when the open state of the dropdown menu changes.
85
+
86
+ - Required: no
87
+
88
+ ##### `modal`: `boolean`
89
+
90
+ The modality of the dropdown menu. When set to true, interaction with outside elements will be disabled and only menu content will be visible to screen readers.
91
+
92
+ - Required: no
93
+ - Default: `true`
94
+
95
+ ##### `placement`: ``'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end'`
96
+
97
+ The placement of the dropdown menu popover.
98
+
99
+ - Required: no
100
+ - Default: `'bottom-start'` for root-level menus, `'right-start'` for nested menus
101
+
102
+ ##### `gutter`: `number`
103
+
104
+ The distance in pixels from the trigger.
105
+
106
+ - Required: no
107
+ - Default: `8` for root-level menus, `16` for nested menus
108
+
109
+ ##### `shift`: `number`
110
+
111
+ The skidding of the popover along the anchor element. Can be set to negative values to make the popover shift to the opposite side.
112
+
113
+ - Required: no
114
+ - Default: `0` for root-level menus, `-8` for nested menus
115
+
116
+ ##### `hideOnEscape`: `boolean | ( ( event: KeyboardEvent | React.KeyboardEvent< Element > ) => boolean )`
117
+
118
+ Determines whether the menu popover will be hidden when the user presses the Escape key.
119
+
120
+ - Required: no
121
+ - Default: `true`
122
+
123
+ ### `DropdownMenuItem`
124
+
125
+ Used to render a menu item.
126
+
127
+ #### Props
128
+
129
+ The component accepts the following props:
130
+
131
+ ##### `children`: `React.ReactNode`
132
+
133
+ The contents of the item
134
+
135
+ - Required: yes
136
+
137
+ ##### `prefix`: `React.ReactNode`
138
+
139
+ The contents of the item's prefix.
140
+
141
+ - Required: no
142
+
143
+ ##### `suffix`: `React.ReactNode`
144
+
145
+ The contents of the item's suffix.
146
+
147
+ - Required: no
148
+
149
+ ##### `hideOnClick`: `boolean`
150
+
151
+ Whether to hide the dropdown menu when the menu item is clicked.
152
+
153
+ - Required: no
154
+ - Default: `true`
155
+
156
+ ##### `disabled`: `boolean`
157
+
158
+ Determines if the element is disabled.
159
+
160
+ - Required: no
161
+ - Default: `false`
162
+
163
+ ### `DropdownMenuCheckboxItem`
164
+
165
+ Used to render a checkbox item.
166
+
167
+ #### Props
168
+
169
+ The component accepts the following props:
170
+
171
+ ##### `children`: `React.ReactNode`
172
+
173
+ The contents of the item
174
+
175
+ - Required: yes
176
+
177
+ ##### `suffix`: `React.ReactNode`
178
+
179
+ The contents of the item's suffix.
180
+
181
+ - Required: no
182
+
183
+ ##### `hideOnClick`: `boolean`
184
+
185
+ Whether to hide the dropdown menu when the menu item is clicked.
186
+
187
+ - Required: no
188
+ - Default: `false`
189
+
190
+ ##### `disabled`: `boolean`
191
+
192
+ Determines if the element is disabled.
193
+
194
+ - Required: no
195
+ - Default: `false`
196
+
197
+ ##### `name`: `string`
198
+
199
+ The checkbox item's name.
200
+
201
+ - Required: yes
202
+
203
+ ##### `value`: `string`
204
+
205
+ The checkbox item's value, useful when using multiple checkbox items
206
+ associated to the same `name`.
207
+
208
+ - Required: no
209
+
210
+ ##### `checked`: `boolean`
211
+
212
+ The checkbox item's value, useful when using multiple checkbox items
213
+ associated to the same `name`.
214
+
215
+ - Required: no
216
+
217
+ ##### `defaultChecked`: `boolean`
218
+
219
+ The checked state of the checkbox menu item when it is initially rendered. Use when not wanting to control its checked state.
220
+
221
+ - Required: no
222
+
223
+ ##### `onChange`: `( event: React.ChangeEvent< HTMLInputElement > ) => void;`
224
+
225
+ Event handler called when the checked state of the checkbox menu item changes.
226
+
227
+ - Required: no
228
+
229
+ ### `DropdownMenuRadioItem`
230
+
231
+ Used to render a radio item.
232
+
233
+ #### Props
234
+
235
+ The component accepts the following props:
236
+
237
+ ##### `children`: `React.ReactNode`
238
+
239
+ The contents of the item
240
+
241
+ - Required: yes
242
+
243
+ ##### `suffix`: `React.ReactNode`
244
+
245
+ The contents of the item's suffix.
246
+
247
+ - Required: no
248
+
249
+ ##### `hideOnClick`: `boolean`
250
+
251
+ Whether to hide the dropdown menu when the menu item is clicked.
252
+
253
+ - Required: no
254
+ - Default: `false`
255
+
256
+ ##### `disabled`: `boolean`
257
+
258
+ Determines if the element is disabled.
259
+
260
+ - Required: no
261
+ - Default: `false`
262
+
263
+ ##### `name`: `string`
264
+
265
+ The radio item's name.
266
+
267
+ - Required: yes
268
+
269
+ ##### `value`: `string | number`
270
+
271
+ The radio item's value.
272
+
273
+ - Required: yes
274
+
275
+ ##### `checked`: `boolean`
276
+
277
+ The checkbox item's value, useful when using multiple checkbox items
278
+ associated to the same `name`.
279
+
280
+ - Required: no
281
+
282
+ ##### `defaultChecked`: `boolean`
283
+
284
+ The checked state of the radio menu item when it is initially rendered. Use when not wanting to control its checked state.
285
+
286
+ - Required: no
287
+
288
+ ##### `onChange`: `( event: React.ChangeEvent< HTMLInputElement > ) => void;`
289
+
290
+ Event handler called when the checked radio menu item changes.
291
+
292
+ - Required: no
293
+
294
+ ### `DropdownMenuGroup`
295
+
296
+ Used to group menu items.
297
+
298
+ #### Props
299
+
300
+ The component accepts the following props:
301
+
302
+ ##### `children`: `React.ReactNode`
303
+
304
+ The contents of the group.
305
+
306
+ - Required: yes
307
+
308
+ ### `DropdownMenuGroupLabel`
309
+
310
+ Used to render a group label.
311
+
312
+ #### Props
313
+
314
+ The component accepts the following props:
315
+
316
+ ##### `children`: `React.ReactNode`
317
+
318
+ The contents of the group.
319
+
320
+ - Required: yes
321
+
322
+ ### `DropdownMenuSeparatorProps`
323
+
324
+ Used to render a visual separator.
@@ -0,0 +1,318 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ // eslint-disable-next-line no-restricted-imports
5
+ import * as Ariakit from '@ariakit/react';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import {
11
+ forwardRef,
12
+ createContext,
13
+ useContext,
14
+ useMemo,
15
+ cloneElement,
16
+ isValidElement,
17
+ } from '@wordpress/element';
18
+ import { isRTL } from '@wordpress/i18n';
19
+ import { check, chevronRightSmall } from '@wordpress/icons';
20
+ import { SVG, Circle } from '@wordpress/primitives';
21
+
22
+ /**
23
+ * Internal dependencies
24
+ */
25
+ import { useContextSystem, contextConnect } from '../context';
26
+ import type { WordPressComponentProps } from '../context';
27
+ import Icon from '../icon';
28
+ import type {
29
+ DropdownMenuContext as DropdownMenuContextType,
30
+ DropdownMenuProps,
31
+ DropdownMenuGroupProps,
32
+ DropdownMenuGroupLabelProps,
33
+ DropdownMenuItemProps,
34
+ DropdownMenuCheckboxItemProps,
35
+ DropdownMenuRadioItemProps,
36
+ DropdownMenuSeparatorProps,
37
+ } from './types';
38
+ import * as Styled from './styles';
39
+
40
+ export const DropdownMenuContext = createContext<
41
+ DropdownMenuContextType | undefined
42
+ >( undefined );
43
+
44
+ export const DropdownMenuItem = forwardRef<
45
+ HTMLDivElement,
46
+ WordPressComponentProps< DropdownMenuItemProps, 'div', false >
47
+ >( function DropdownMenuItem(
48
+ { prefix, suffix, children, hideOnClick = true, ...props },
49
+ ref
50
+ ) {
51
+ const dropdownMenuContext = useContext( DropdownMenuContext );
52
+
53
+ return (
54
+ <Styled.DropdownMenuItem
55
+ ref={ ref }
56
+ { ...props }
57
+ hideOnClick={ hideOnClick }
58
+ store={ dropdownMenuContext?.store }
59
+ >
60
+ { prefix && (
61
+ <Styled.ItemPrefixWrapper>{ prefix }</Styled.ItemPrefixWrapper>
62
+ ) }
63
+ { children }
64
+ { suffix && (
65
+ <Styled.ItemSuffixWrapper>{ suffix }</Styled.ItemSuffixWrapper>
66
+ ) }
67
+ </Styled.DropdownMenuItem>
68
+ );
69
+ } );
70
+
71
+ export const DropdownMenuCheckboxItem = forwardRef<
72
+ HTMLDivElement,
73
+ WordPressComponentProps< DropdownMenuCheckboxItemProps, 'div', false >
74
+ >( function DropdownMenuCheckboxItem(
75
+ { suffix, children, hideOnClick = false, ...props },
76
+ ref
77
+ ) {
78
+ const dropdownMenuContext = useContext( DropdownMenuContext );
79
+
80
+ return (
81
+ <Styled.DropdownMenuCheckboxItem
82
+ ref={ ref }
83
+ { ...props }
84
+ hideOnClick={ hideOnClick }
85
+ store={ dropdownMenuContext?.store }
86
+ >
87
+ <Ariakit.MenuItemCheck
88
+ store={ dropdownMenuContext?.store }
89
+ render={ <Styled.ItemPrefixWrapper /> }
90
+ >
91
+ <Icon icon={ check } size={ 24 } />
92
+ </Ariakit.MenuItemCheck>
93
+
94
+ { children }
95
+ { suffix && (
96
+ <Styled.ItemSuffixWrapper>{ suffix }</Styled.ItemSuffixWrapper>
97
+ ) }
98
+ </Styled.DropdownMenuCheckboxItem>
99
+ );
100
+ } );
101
+
102
+ export const DropdownMenuRadioItem = forwardRef<
103
+ HTMLDivElement,
104
+ WordPressComponentProps< DropdownMenuRadioItemProps, 'div', false >
105
+ >( function DropdownMenuRadioItem(
106
+ { suffix, children, hideOnClick = false, ...props },
107
+ ref
108
+ ) {
109
+ const dropdownMenuContext = useContext( DropdownMenuContext );
110
+
111
+ return (
112
+ <Styled.DropdownMenuRadioItem
113
+ ref={ ref }
114
+ { ...props }
115
+ hideOnClick={ hideOnClick }
116
+ store={ dropdownMenuContext?.store }
117
+ >
118
+ <Ariakit.MenuItemCheck
119
+ store={ dropdownMenuContext?.store }
120
+ render={ <Styled.ItemPrefixWrapper /> }
121
+ >
122
+ <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
123
+ <Circle
124
+ cx={ 12 }
125
+ cy={ 12 }
126
+ r={ 3 }
127
+ fill="currentColor"
128
+ ></Circle>
129
+ </SVG>
130
+ </Ariakit.MenuItemCheck>
131
+ { children }
132
+ { suffix }
133
+ </Styled.DropdownMenuRadioItem>
134
+ );
135
+ } );
136
+
137
+ export const DropdownMenuGroup = forwardRef<
138
+ HTMLDivElement,
139
+ WordPressComponentProps< DropdownMenuGroupProps, 'div', false >
140
+ >( function DropdownMenuGroup( props, ref ) {
141
+ const dropdownMenuContext = useContext( DropdownMenuContext );
142
+ return (
143
+ <Styled.DropdownMenuGroup
144
+ ref={ ref }
145
+ { ...props }
146
+ store={ dropdownMenuContext?.store }
147
+ />
148
+ );
149
+ } );
150
+
151
+ export const DropdownMenuGroupLabel = forwardRef<
152
+ HTMLDivElement,
153
+ WordPressComponentProps< DropdownMenuGroupLabelProps, 'div', false >
154
+ >( function DropdownMenuGroupLabel( props, ref ) {
155
+ const dropdownMenuContext = useContext( DropdownMenuContext );
156
+ return (
157
+ <Styled.DropdownMenuGroupLabel
158
+ ref={ ref }
159
+ { ...props }
160
+ store={ dropdownMenuContext?.store }
161
+ />
162
+ );
163
+ } );
164
+
165
+ const UnconnectedDropdownMenu = (
166
+ props: WordPressComponentProps< DropdownMenuProps, 'div', false >,
167
+ ref: React.ForwardedRef< HTMLDivElement >
168
+ ) => {
169
+ const {
170
+ // Store props
171
+ open,
172
+ defaultOpen = false,
173
+ onOpenChange,
174
+ placement,
175
+
176
+ // Menu trigger props
177
+ trigger,
178
+
179
+ // Menu props
180
+ gutter,
181
+ children,
182
+ shift,
183
+ modal = true,
184
+ hideOnEscape = true,
185
+
186
+ // From internal components context
187
+ variant,
188
+
189
+ // Rest
190
+ ...otherProps
191
+ } = useContextSystem<
192
+ typeof props & Pick< DropdownMenuContextType, 'variant' >
193
+ >( props, 'DropdownMenu' );
194
+
195
+ const parentContext = useContext( DropdownMenuContext );
196
+
197
+ const computedDirection = isRTL() ? 'rtl' : 'ltr';
198
+
199
+ // If an explicit value for the `placement` prop is not passed,
200
+ // apply a default placement of `bottom-start` for the root dropdown,
201
+ // and of `right-start` for nested dropdowns.
202
+ let computedPlacement =
203
+ props.placement ??
204
+ ( parentContext?.store ? 'right-start' : 'bottom-start' );
205
+ // Swap left/right in case of RTL direction
206
+ if ( computedDirection === 'rtl' ) {
207
+ if ( /right/.test( computedPlacement ) ) {
208
+ computedPlacement = computedPlacement.replace(
209
+ 'right',
210
+ 'left'
211
+ ) as typeof computedPlacement;
212
+ } else if ( /left/.test( computedPlacement ) ) {
213
+ computedPlacement = computedPlacement.replace(
214
+ 'left',
215
+ 'right'
216
+ ) as typeof computedPlacement;
217
+ }
218
+ }
219
+
220
+ const dropdownMenuStore = Ariakit.useMenuStore( {
221
+ parent: parentContext?.store,
222
+ open,
223
+ defaultOpen,
224
+ placement: computedPlacement,
225
+ focusLoop: true,
226
+ setOpen( willBeOpen ) {
227
+ onOpenChange?.( willBeOpen );
228
+ },
229
+ rtl: computedDirection === 'rtl',
230
+ } );
231
+
232
+ const contextValue = useMemo(
233
+ () => ( { store: dropdownMenuStore, variant } ),
234
+ [ dropdownMenuStore, variant ]
235
+ );
236
+
237
+ // Extract the side from the applied placement — useful for animations.
238
+ const appliedPlacementSide = dropdownMenuStore
239
+ .useState( 'placement' )
240
+ .split( '-' )[ 0 ];
241
+
242
+ if (
243
+ dropdownMenuStore.parent &&
244
+ ! ( isValidElement( trigger ) && DropdownMenuItem === trigger.type )
245
+ ) {
246
+ // eslint-disable-next-line no-console
247
+ console.warn(
248
+ 'For nested DropdownMenus, the `trigger` should always be a `DropdownMenuItem`.'
249
+ );
250
+ }
251
+
252
+ return (
253
+ <>
254
+ { /* Menu trigger */ }
255
+ <Ariakit.MenuButton
256
+ ref={ ref }
257
+ store={ dropdownMenuStore }
258
+ render={
259
+ dropdownMenuStore.parent
260
+ ? cloneElement( trigger, {
261
+ // Add submenu arrow, unless a `suffix` is explicitly specified
262
+ suffix: trigger.props.suffix ?? (
263
+ <Styled.SubmenuChevronIcon
264
+ aria-hidden="true"
265
+ icon={ chevronRightSmall }
266
+ size={ 24 }
267
+ />
268
+ ),
269
+ } )
270
+ : trigger
271
+ }
272
+ />
273
+
274
+ { /* Menu popover */ }
275
+ <Styled.DropdownMenu
276
+ { ...otherProps }
277
+ modal={ modal }
278
+ store={ dropdownMenuStore }
279
+ gutter={ gutter ?? ( dropdownMenuStore.parent ? 16 : 8 ) }
280
+ shift={ shift ?? ( dropdownMenuStore.parent ? -8 : 0 ) }
281
+ hideOnHoverOutside={ false }
282
+ data-side={ appliedPlacementSide }
283
+ variant={ variant }
284
+ wrapperProps={ {
285
+ dir: computedDirection,
286
+ style: {
287
+ direction: computedDirection,
288
+ },
289
+ } }
290
+ hideOnEscape={ hideOnEscape }
291
+ unmountOnHide
292
+ >
293
+ <DropdownMenuContext.Provider value={ contextValue }>
294
+ { children }
295
+ </DropdownMenuContext.Provider>
296
+ </Styled.DropdownMenu>
297
+ </>
298
+ );
299
+ };
300
+ export const DropdownMenu = contextConnect(
301
+ UnconnectedDropdownMenu,
302
+ 'DropdownMenu'
303
+ );
304
+
305
+ export const DropdownMenuSeparator = forwardRef<
306
+ HTMLHRElement,
307
+ WordPressComponentProps< DropdownMenuSeparatorProps, 'hr', false >
308
+ >( function DropdownMenuSeparator( props, ref ) {
309
+ const dropdownMenuContext = useContext( DropdownMenuContext );
310
+ return (
311
+ <Styled.DropdownMenuSeparator
312
+ ref={ ref }
313
+ { ...props }
314
+ store={ dropdownMenuContext?.store }
315
+ variant={ dropdownMenuContext?.variant }
316
+ />
317
+ );
318
+ } );