@wordpress/components 25.11.1-next.f8d8eceb.0 → 25.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 (317) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/build/angle-picker-control/index.js +0 -1
  3. package/build/angle-picker-control/index.js.map +1 -1
  4. package/build/custom-select-control-v2/index.js +87 -0
  5. package/build/custom-select-control-v2/index.js.map +1 -0
  6. package/build/custom-select-control-v2/styles.js +85 -0
  7. package/build/custom-select-control-v2/styles.js.map +1 -0
  8. package/build/custom-select-control-v2/types.js +6 -0
  9. package/build/custom-select-control-v2/types.js.map +1 -0
  10. package/build/disclosure/index.js +37 -7
  11. package/build/disclosure/index.js.map +1 -1
  12. package/build/disclosure/types.js +6 -0
  13. package/build/disclosure/types.js.map +1 -0
  14. package/build/divider/component.js +5 -3
  15. package/build/divider/component.js.map +1 -1
  16. package/build/divider/types.js.map +1 -1
  17. package/build/dropdown-menu-v2-ariakit/index.js +74 -35
  18. package/build/dropdown-menu-v2-ariakit/index.js.map +1 -1
  19. package/build/dropdown-menu-v2-ariakit/styles.js +82 -59
  20. package/build/dropdown-menu-v2-ariakit/styles.js.map +1 -1
  21. package/build/dropdown-menu-v2-ariakit/types.js.map +1 -1
  22. package/build/form-token-field/index.js +6 -2
  23. package/build/form-token-field/index.js.map +1 -1
  24. package/build/form-token-field/token-input.js.map +1 -1
  25. package/build/form-token-field/types.js.map +1 -1
  26. package/build/gradient-picker/index.js +1 -1
  27. package/build/gradient-picker/index.js.map +1 -1
  28. package/build/heading/hook.js +6 -3
  29. package/build/heading/hook.js.map +1 -1
  30. package/build/heading/types.js.map +1 -1
  31. package/build/index.native.js +8 -1
  32. package/build/index.native.js.map +1 -1
  33. package/build/mobile/audio-player/index.native.js +8 -9
  34. package/build/mobile/audio-player/index.native.js.map +1 -1
  35. package/build/mobile/global-styles-context/utils.native.js +44 -3
  36. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  37. package/build/mobile/utils/alignments.native.js +1 -1
  38. package/build/mobile/utils/alignments.native.js.map +1 -1
  39. package/build/private-apis.js +3 -2
  40. package/build/private-apis.js.map +1 -1
  41. package/build/radio-group/context.js +22 -0
  42. package/build/radio-group/context.js.map +1 -0
  43. package/build/radio-group/index.js +27 -23
  44. package/build/radio-group/index.js.map +1 -1
  45. package/build/radio-group/radio.js +58 -0
  46. package/build/radio-group/radio.js.map +1 -0
  47. package/build/radio-group/types.js +6 -0
  48. package/build/radio-group/types.js.map +1 -0
  49. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
  50. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  51. package/build/slot-fill/types.js.map +1 -1
  52. package/build/tabs/index.js +6 -4
  53. package/build/tabs/index.js.map +1 -1
  54. package/build/tabs/styles.js +14 -7
  55. package/build/tabs/styles.js.map +1 -1
  56. package/build/tabs/tab.js +5 -7
  57. package/build/tabs/tab.js.map +1 -1
  58. package/build/tabs/tablist.js +3 -5
  59. package/build/tabs/tablist.js.map +1 -1
  60. package/build/tabs/tabpanel.js +7 -10
  61. package/build/tabs/tabpanel.js.map +1 -1
  62. package/build/tabs/types.js.map +1 -1
  63. package/build/text/types.js.map +1 -1
  64. package/build/text-control/index.js +5 -1
  65. package/build/text-control/index.js.map +1 -1
  66. package/build/text-control/types.js.map +1 -1
  67. package/build/toggle-group-control/toggle-group-control/component.js +4 -2
  68. package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
  69. package/build/toggle-group-control/toggle-group-control/styles.js +13 -9
  70. package/build/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  71. package/build/toggle-group-control/types.js.map +1 -1
  72. package/build/tools-panel/tools-panel-item/hook.js +5 -1
  73. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  74. package/build-module/angle-picker-control/index.js +0 -1
  75. package/build-module/angle-picker-control/index.js.map +1 -1
  76. package/build-module/custom-select-control-v2/index.js +74 -0
  77. package/build-module/custom-select-control-v2/index.js.map +1 -0
  78. package/build-module/custom-select-control-v2/styles.js +71 -0
  79. package/build-module/custom-select-control-v2/styles.js.map +1 -0
  80. package/build-module/custom-select-control-v2/types.js +2 -0
  81. package/build-module/custom-select-control-v2/types.js.map +1 -0
  82. package/build-module/disclosure/index.js +33 -8
  83. package/build-module/disclosure/index.js.map +1 -1
  84. package/build-module/disclosure/types.js +2 -0
  85. package/build-module/disclosure/types.js.map +1 -0
  86. package/build-module/divider/component.js +3 -3
  87. package/build-module/divider/component.js.map +1 -1
  88. package/build-module/divider/types.js.map +1 -1
  89. package/build-module/dropdown-menu-v2-ariakit/index.js +72 -34
  90. package/build-module/dropdown-menu-v2-ariakit/index.js.map +1 -1
  91. package/build-module/dropdown-menu-v2-ariakit/styles.js +69 -40
  92. package/build-module/dropdown-menu-v2-ariakit/styles.js.map +1 -1
  93. package/build-module/dropdown-menu-v2-ariakit/types.js.map +1 -1
  94. package/build-module/form-token-field/index.js +6 -2
  95. package/build-module/form-token-field/index.js.map +1 -1
  96. package/build-module/form-token-field/token-input.js.map +1 -1
  97. package/build-module/form-token-field/types.js.map +1 -1
  98. package/build-module/gradient-picker/index.js +1 -1
  99. package/build-module/gradient-picker/index.js.map +1 -1
  100. package/build-module/heading/hook.js +6 -3
  101. package/build-module/heading/hook.js.map +1 -1
  102. package/build-module/heading/types.js.map +1 -1
  103. package/build-module/index.native.js +1 -1
  104. package/build-module/index.native.js.map +1 -1
  105. package/build-module/mobile/audio-player/index.native.js +9 -10
  106. package/build-module/mobile/audio-player/index.native.js.map +1 -1
  107. package/build-module/mobile/global-styles-context/utils.native.js +43 -4
  108. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  109. package/build-module/mobile/utils/alignments.native.js +1 -1
  110. package/build-module/mobile/utils/alignments.native.js.map +1 -1
  111. package/build-module/private-apis.js +4 -3
  112. package/build-module/private-apis.js.map +1 -1
  113. package/build-module/radio-group/context.js +14 -0
  114. package/build-module/radio-group/context.js.map +1 -0
  115. package/build-module/radio-group/index.js +24 -23
  116. package/build-module/radio-group/index.js.map +1 -1
  117. package/build-module/radio-group/radio.js +46 -0
  118. package/build-module/radio-group/radio.js.map +1 -0
  119. package/build-module/radio-group/types.js +2 -0
  120. package/build-module/radio-group/types.js.map +1 -0
  121. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
  122. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  123. package/build-module/slot-fill/types.js.map +1 -1
  124. package/build-module/tabs/index.js +7 -5
  125. package/build-module/tabs/index.js.map +1 -1
  126. package/build-module/tabs/styles.js +11 -5
  127. package/build-module/tabs/styles.js.map +1 -1
  128. package/build-module/tabs/tab.js +7 -9
  129. package/build-module/tabs/tab.js.map +1 -1
  130. package/build-module/tabs/tablist.js +3 -5
  131. package/build-module/tabs/tablist.js.map +1 -1
  132. package/build-module/tabs/tabpanel.js +9 -10
  133. package/build-module/tabs/tabpanel.js.map +1 -1
  134. package/build-module/tabs/types.js.map +1 -1
  135. package/build-module/text/types.js.map +1 -1
  136. package/build-module/text-control/index.js +6 -1
  137. package/build-module/text-control/index.js.map +1 -1
  138. package/build-module/text-control/types.js.map +1 -1
  139. package/build-module/toggle-group-control/toggle-group-control/component.js +4 -2
  140. package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
  141. package/build-module/toggle-group-control/toggle-group-control/styles.js +13 -9
  142. package/build-module/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  143. package/build-module/toggle-group-control/types.js.map +1 -1
  144. package/build-module/tools-panel/tools-panel-item/hook.js +6 -2
  145. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  146. package/build-style/style-rtl.css +52 -8
  147. package/build-style/style.css +52 -8
  148. package/build-types/angle-picker-control/index.d.ts.map +1 -1
  149. package/build-types/box-control/stories/index.story.d.ts +1944 -0
  150. package/build-types/box-control/stories/index.story.d.ts.map +1 -0
  151. package/build-types/card/card-divider/component.d.ts +1 -1
  152. package/build-types/card/card-divider/hook.d.ts +162 -162
  153. package/build-types/color-palette/styles.d.ts +4 -1
  154. package/build-types/color-palette/styles.d.ts.map +1 -1
  155. package/build-types/custom-select-control-v2/index.d.ts +6 -0
  156. package/build-types/custom-select-control-v2/index.d.ts.map +1 -0
  157. package/build-types/custom-select-control-v2/stories/index.story.d.ts +19 -0
  158. package/build-types/custom-select-control-v2/stories/index.story.d.ts.map +1 -0
  159. package/build-types/custom-select-control-v2/styles.d.ts +47 -0
  160. package/build-types/custom-select-control-v2/styles.d.ts.map +1 -0
  161. package/build-types/custom-select-control-v2/types.d.ts +57 -0
  162. package/build-types/custom-select-control-v2/types.d.ts.map +1 -0
  163. package/build-types/date-time/date/styles.d.ts +4 -1
  164. package/build-types/date-time/date/styles.d.ts.map +1 -1
  165. package/build-types/disclosure/index.d.ts +7 -1
  166. package/build-types/disclosure/index.d.ts.map +1 -1
  167. package/build-types/disclosure/types.d.ts +12 -0
  168. package/build-types/disclosure/types.d.ts.map +1 -0
  169. package/build-types/divider/component.d.ts +5 -1
  170. package/build-types/divider/component.d.ts.map +1 -1
  171. package/build-types/divider/stories/index.story.d.ts.map +1 -1
  172. package/build-types/divider/styles.d.ts +1 -1
  173. package/build-types/divider/types.d.ts +2 -2
  174. package/build-types/divider/types.d.ts.map +1 -1
  175. package/build-types/dropdown-menu-v2-ariakit/index.d.ts +11 -2
  176. package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +1 -1
  177. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +1 -1
  178. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +26 -18
  179. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +1 -1
  180. package/build-types/dropdown-menu-v2-ariakit/types.d.ts +1 -7
  181. package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +1 -1
  182. package/build-types/form-token-field/index.d.ts.map +1 -1
  183. package/build-types/form-token-field/token-input.d.ts.map +1 -1
  184. package/build-types/form-token-field/types.d.ts +1 -1
  185. package/build-types/form-token-field/types.d.ts.map +1 -1
  186. package/build-types/heading/component.d.ts +4 -1
  187. package/build-types/heading/component.d.ts.map +1 -1
  188. package/build-types/heading/hook.d.ts.map +1 -1
  189. package/build-types/heading/types.d.ts +20 -1
  190. package/build-types/heading/types.d.ts.map +1 -1
  191. package/build-types/navigation/styles/navigation-styles.d.ts +4 -1
  192. package/build-types/navigation/styles/navigation-styles.d.ts.map +1 -1
  193. package/build-types/palette-edit/styles.d.ts +4 -1
  194. package/build-types/palette-edit/styles.d.ts.map +1 -1
  195. package/build-types/private-apis.d.ts.map +1 -1
  196. package/build-types/radio-group/context.d.ts +10 -0
  197. package/build-types/radio-group/context.d.ts.map +1 -0
  198. package/build-types/radio-group/index.d.ts +7 -9
  199. package/build-types/radio-group/index.d.ts.map +1 -1
  200. package/build-types/radio-group/radio.d.ts +8 -0
  201. package/build-types/radio-group/radio.d.ts.map +1 -0
  202. package/build-types/radio-group/stories/index.story.d.ts +14 -0
  203. package/build-types/radio-group/stories/index.story.d.ts.map +1 -0
  204. package/build-types/radio-group/types.d.ts +40 -0
  205. package/build-types/radio-group/types.d.ts.map +1 -0
  206. package/build-types/slot-fill/bubbles-virtually/slot.d.ts +1 -1
  207. package/build-types/slot-fill/types.d.ts +16 -6
  208. package/build-types/slot-fill/types.d.ts.map +1 -1
  209. package/build-types/tabs/index.d.ts +4 -3
  210. package/build-types/tabs/index.d.ts.map +1 -1
  211. package/build-types/tabs/stories/index.story.d.ts.map +1 -1
  212. package/build-types/tabs/styles.d.ts +10 -0
  213. package/build-types/tabs/styles.d.ts.map +1 -1
  214. package/build-types/tabs/tab.d.ts +1 -1
  215. package/build-types/tabs/tab.d.ts.map +1 -1
  216. package/build-types/tabs/tablist.d.ts +1 -1
  217. package/build-types/tabs/tablist.d.ts.map +1 -1
  218. package/build-types/tabs/tabpanel.d.ts +4 -1
  219. package/build-types/tabs/tabpanel.d.ts.map +1 -1
  220. package/build-types/tabs/types.d.ts +7 -31
  221. package/build-types/tabs/types.d.ts.map +1 -1
  222. package/build-types/text/types.d.ts +15 -2
  223. package/build-types/text/types.d.ts.map +1 -1
  224. package/build-types/text-control/index.d.ts +2 -1
  225. package/build-types/text-control/index.d.ts.map +1 -1
  226. package/build-types/text-control/types.d.ts +6 -0
  227. package/build-types/text-control/types.d.ts.map +1 -1
  228. package/build-types/toggle-group-control/toggle-group-control/component.d.ts +1 -0
  229. package/build-types/toggle-group-control/toggle-group-control/component.d.ts.map +1 -1
  230. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts +2 -2
  231. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts.map +1 -1
  232. package/build-types/toggle-group-control/types.d.ts +6 -0
  233. package/build-types/toggle-group-control/types.d.ts.map +1 -1
  234. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  235. package/package.json +19 -20
  236. package/src/angle-picker-control/index.tsx +0 -1
  237. package/src/box-control/stories/index.story.tsx +82 -0
  238. package/src/button/style.scss +10 -2
  239. package/src/combobox-control/README.md +1 -3
  240. package/src/custom-select-control-v2/README.md +73 -0
  241. package/src/custom-select-control-v2/index.tsx +99 -0
  242. package/src/custom-select-control-v2/stories/index.story.tsx +149 -0
  243. package/src/custom-select-control-v2/styles.ts +76 -0
  244. package/src/custom-select-control-v2/types.ts +63 -0
  245. package/src/disclosure/index.tsx +44 -0
  246. package/src/disclosure/types.tsx +10 -0
  247. package/src/divider/component.tsx +3 -3
  248. package/src/divider/stories/index.story.tsx +8 -0
  249. package/src/divider/types.ts +2 -2
  250. package/src/dropdown-menu/style.scss +4 -0
  251. package/src/dropdown-menu-v2-ariakit/README.md +19 -12
  252. package/src/dropdown-menu-v2-ariakit/index.tsx +116 -51
  253. package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +205 -94
  254. package/src/dropdown-menu-v2-ariakit/styles.ts +153 -117
  255. package/src/dropdown-menu-v2-ariakit/test/index.tsx +5 -36
  256. package/src/dropdown-menu-v2-ariakit/types.ts +1 -8
  257. package/src/form-toggle/style.scss +37 -7
  258. package/src/form-token-field/index.tsx +11 -3
  259. package/src/form-token-field/token-input.tsx +1 -3
  260. package/src/form-token-field/types.ts +1 -0
  261. package/src/gradient-picker/index.tsx +1 -1
  262. package/src/heading/README.md +6 -1
  263. package/src/heading/hook.ts +6 -3
  264. package/src/heading/types.ts +23 -1
  265. package/src/index.native.js +1 -0
  266. package/src/mobile/audio-player/index.native.js +9 -13
  267. package/src/mobile/global-styles-context/utils.native.js +52 -3
  268. package/src/mobile/utils/alignments.native.js +1 -0
  269. package/src/navigable-container/README.md +1 -1
  270. package/src/private-apis.ts +4 -2
  271. package/src/radio-group/context.tsx +18 -0
  272. package/src/radio-group/index.tsx +65 -0
  273. package/src/radio-group/radio.tsx +55 -0
  274. package/src/radio-group/stories/index.story.tsx +90 -0
  275. package/src/radio-group/types.ts +39 -0
  276. package/src/slot-fill/README.md +1 -1
  277. package/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx +1 -1
  278. package/src/slot-fill/types.ts +18 -6
  279. package/src/tabs/README.md +3 -33
  280. package/src/tabs/index.tsx +12 -2
  281. package/src/tabs/stories/index.story.tsx +17 -1
  282. package/src/tabs/styles.ts +16 -0
  283. package/src/tabs/tab.tsx +10 -10
  284. package/src/tabs/tablist.tsx +21 -20
  285. package/src/tabs/tabpanel.tsx +26 -25
  286. package/src/tabs/test/index.tsx +90 -16
  287. package/src/tabs/types.ts +7 -32
  288. package/src/text/README.md +5 -1
  289. package/src/text/types.ts +15 -2
  290. package/src/text-control/index.tsx +5 -1
  291. package/src/text-control/style.scss +5 -0
  292. package/src/text-control/types.ts +6 -0
  293. package/src/toggle-control/README.md +2 -2
  294. package/src/toggle-group-control/toggle-group-control/component.tsx +8 -2
  295. package/src/toggle-group-control/toggle-group-control/styles.ts +13 -4
  296. package/src/toggle-group-control/types.ts +6 -0
  297. package/src/toolbar/toolbar-button/style.scss +0 -5
  298. package/src/tools-panel/tools-panel-item/hook.ts +11 -2
  299. package/tsconfig.tsbuildinfo +1 -1
  300. package/build/radio-group/radio/index.js +0 -49
  301. package/build/radio-group/radio/index.js.map +0 -1
  302. package/build/radio-group/radio-context/index.js +0 -18
  303. package/build/radio-group/radio-context/index.js.map +0 -1
  304. package/build-module/radio-group/radio/index.js +0 -40
  305. package/build-module/radio-group/radio/index.js.map +0 -1
  306. package/build-module/radio-group/radio-context/index.js +0 -10
  307. package/build-module/radio-group/radio-context/index.js.map +0 -1
  308. package/build-types/radio-group/radio/index.d.ts +0 -7
  309. package/build-types/radio-group/radio/index.d.ts.map +0 -1
  310. package/build-types/radio-group/radio-context/index.d.ts +0 -6
  311. package/build-types/radio-group/radio-context/index.d.ts.map +0 -1
  312. package/src/box-control/stories/index.story.js +0 -75
  313. package/src/disclosure/index.js +0 -11
  314. package/src/radio-group/index.js +0 -51
  315. package/src/radio-group/radio/index.js +0 -40
  316. package/src/radio-group/radio-context/index.js +0 -11
  317. package/src/radio-group/stories/index.story.js +0 -83
@@ -12,6 +12,7 @@ import styled from '@emotion/styled';
12
12
  import { COLORS, font, rtl, CONFIG } from '../utils';
13
13
  import { space } from '../utils/space';
14
14
  import Icon from '../icon';
15
+ import { Truncate } from '../truncate';
15
16
  import type { DropdownMenuContext } from './types';
16
17
 
17
18
  const ANIMATION_PARAMS = {
@@ -20,13 +21,16 @@ const ANIMATION_PARAMS = {
20
21
  EASING: 'cubic-bezier( 0.16, 1, 0.3, 1 )',
21
22
  };
22
23
 
23
- const CONTENT_WRAPPER_PADDING = space( 2 );
24
- const ITEM_PREFIX_WIDTH = space( 7 );
25
- const ITEM_PADDING_INLINE_START = space( 2 );
26
- const ITEM_PADDING_INLINE_END = space( 2.5 );
24
+ const CONTENT_WRAPPER_PADDING = space( 1 );
25
+ const ITEM_PADDING_BLOCK = space( 2 );
26
+ const ITEM_PADDING_INLINE = space( 3 );
27
27
 
28
- // TODO: should bring this into the config, and make themeable
29
- const DEFAULT_BORDER_COLOR = COLORS.ui.borderDisabled;
28
+ // TODO:
29
+ // - those values are different from saved variables?
30
+ // - should bring this into the config, and make themeable
31
+ // - border color and divider color are different?
32
+ const DEFAULT_BORDER_COLOR = COLORS.gray[ 300 ];
33
+ const DIVIDER_COLOR = COLORS.gray[ 200 ];
30
34
  const TOOLBAR_VARIANT_BORDER_COLOR = COLORS.gray[ '900' ];
31
35
  const DEFAULT_BOX_SHADOW = `0 0 0 ${ CONFIG.borderWidth } ${ DEFAULT_BORDER_COLOR }, ${ CONFIG.popoverShadow }`;
32
36
  const TOOLBAR_VARIANT_BOX_SHADOW = `0 0 0 ${ CONFIG.borderWidth } ${ TOOLBAR_VARIANT_BORDER_COLOR }`;
@@ -71,12 +75,18 @@ export const DropdownMenu = styled( Ariakit.Menu )<
71
75
  /* TODO: is there a way to read the sass variable? */
72
76
  z-index: 1000000;
73
77
 
74
- min-width: 220px;
78
+ display: grid;
79
+ grid-template-columns: minmax( 0, max-content ) 1fr;
80
+ grid-template-rows: auto;
81
+
82
+ box-sizing: border-box;
83
+ min-width: 160px;
84
+ max-width: 320px;
75
85
  max-height: var( --popover-available-height );
76
86
  padding: ${ CONTENT_WRAPPER_PADDING };
77
87
 
78
88
  background-color: ${ COLORS.ui.background };
79
- border-radius: ${ CONFIG.radiusBlockUi };
89
+ border-radius: 4px;
80
90
  ${ ( props ) => css`
81
91
  box-shadow: ${ props.variant === 'toolbar'
82
92
  ? TOOLBAR_VARIANT_BOX_SHADOW
@@ -110,102 +120,55 @@ export const DropdownMenu = styled( Ariakit.Menu )<
110
120
  }
111
121
  `;
112
122
 
113
- const itemPrefix = css`
114
- /* !important is to override some inline styles set by Ariakit */
115
- width: ${ ITEM_PREFIX_WIDTH } !important;
116
- /* !important is to override some inline styles set by Ariakit */
117
- height: auto !important;
118
- display: inline-flex;
119
- align-items: center;
120
- justify-content: center;
121
- /* Prefixes don't get affected by the item's inline start padding */
122
- margin-inline-start: calc( -1 * ${ ITEM_PADDING_INLINE_START } );
123
- /*
124
- Negative margin allows the suffix to be as tall as the whole item
125
- (incl. padding) before increasing the items' height. This can be useful,
126
- e.g., when using icons that are bigger than 20x20 px
127
- */
128
- margin-top: ${ space( -2 ) };
129
- margin-bottom: ${ space( -2 ) };
130
- `;
131
-
132
- const itemSuffix = css`
133
- width: max-content;
134
- display: inline-flex;
135
- align-items: center;
136
- justify-content: center;
137
- /* Push prefix to the inline-end of the item */
138
- margin-inline-start: auto;
139
- /* Minimum space between the item's content and suffix */
140
- padding-inline-start: ${ space( 6 ) };
141
- /*
142
- Negative margin allows the suffix to be as tall as the whole item
143
- (incl. padding) before increasing the items' height. This can be useful,
144
- e.g., when using icons that are bigger than 20x20 px
145
- */
146
- margin-top: ${ space( -2 ) };
147
- margin-bottom: ${ space( -2 ) };
148
-
149
- /*
150
- Override color in normal conditions, but inherit the item's color
151
- for altered conditions.
152
-
153
- TODO:
154
- - For now, used opacity like for disabled item, which makes it work
155
- regardless of the theme
156
- - how do we translate this for themes? Should we have a new variable
157
- for "secondary" text?
158
- */
159
- opacity: 0.6;
123
+ const baseItem = css`
124
+ all: unset;
160
125
 
161
- /* when the parent item is hovered / focused */
162
- [data-active-item] > &,
163
- /* when the parent item is a submenu trigger and the submenu is open */
164
- [aria-expanded='true'] > &,
165
- /* when the parent item is disabled */
166
- [aria-disabled='true'] > & {
167
- opacity: 1;
168
- }
169
- `;
126
+ position: relative;
127
+ min-height: ${ space( 10 ) };
128
+ box-sizing: border-box;
170
129
 
171
- export const ItemPrefixWrapper = styled.span`
172
- ${ itemPrefix }
173
- `;
130
+ /* Occupy the width of all grid columns (ie. full width) */
131
+ grid-column: 1 / -1;
174
132
 
175
- export const ItemSuffixWrapper = styled.span`
176
- ${ itemSuffix }
177
- `;
133
+ /*
134
+ * Define a grid layout which inherits the same columns configuration
135
+ * from the parent layout (ie. subgrid).
136
+ */
137
+ display: grid;
138
+ grid-template-columns: subgrid;
139
+ align-items: center;
178
140
 
179
- const baseItem = css`
180
- all: unset;
181
141
  font-size: ${ font( 'default.fontSize' ) };
182
142
  font-family: inherit;
183
143
  font-weight: normal;
184
144
  line-height: 20px;
145
+
185
146
  color: ${ COLORS.gray[ 900 ] };
186
147
  border-radius: ${ CONFIG.radiusBlockUi };
187
- display: flex;
188
- align-items: center;
189
- padding: ${ space( 2 ) } ${ ITEM_PADDING_INLINE_END } ${ space( 2 ) }
190
- ${ ITEM_PADDING_INLINE_START };
191
- position: relative;
148
+
149
+ padding-block: ${ ITEM_PADDING_BLOCK };
150
+ padding-inline: ${ ITEM_PADDING_INLINE };
151
+
152
+ /*
153
+ * Make sure that, when an item is scrolled into view (eg. while using the
154
+ * keyboard to move focus), the whole item comes into view
155
+ */
156
+ scroll-margin: ${ CONTENT_WRAPPER_PADDING };
157
+
192
158
  user-select: none;
193
159
  outline: none;
194
160
 
195
161
  &[aria-disabled='true'] {
196
- /*
197
- TODO:
198
- - we need a disabled color in the Theme variables
199
- - design specs use opacity instead of setting a new text color
200
- */
201
- opacity: 0.5;
202
- pointer-events: none;
162
+ color: ${ COLORS.ui.textDisabled };
163
+ cursor: not-allowed;
203
164
  }
204
165
 
205
166
  /* Hover */
206
- &[data-active-item] {
207
- /* TODO: reconcile with global focus styles */
208
- background-color: ${ COLORS.gray[ '100' ] };
167
+ &[data-active-item]:not( [data-focus-visible] ):not(
168
+ [aria-disabled='true']
169
+ ) {
170
+ background-color: ${ COLORS.theme.accent };
171
+ color: ${ COLORS.white };
209
172
  }
210
173
 
211
174
  /* Keyboard focus (focus-visible) */
@@ -224,74 +187,147 @@ const baseItem = css`
224
187
 
225
188
  /* When the item is the trigger of an open submenu */
226
189
  ${ DropdownMenu }:not(:focus) &:not(:focus)[aria-expanded="true"] {
227
- /* TODO: should we style submenu triggers any different? */
190
+ background-color: ${ COLORS.gray[ 100 ] };
191
+ color: ${ COLORS.gray[ 900 ] };
228
192
  }
229
193
 
230
194
  svg {
231
195
  fill: currentColor;
232
196
  }
233
-
234
- &:not( :has( ${ ItemPrefixWrapper } ) ) {
235
- padding-inline-start: ${ ITEM_PREFIX_WIDTH };
236
- }
237
197
  `;
238
198
 
239
199
  export const DropdownMenuItem = styled( Ariakit.MenuItem )`
240
- ${ baseItem }
200
+ ${ baseItem };
241
201
  `;
242
202
 
243
203
  export const DropdownMenuCheckboxItem = styled( Ariakit.MenuItemCheckbox )`
244
- ${ baseItem }
204
+ ${ baseItem };
245
205
  `;
246
206
 
247
207
  export const DropdownMenuRadioItem = styled( Ariakit.MenuItemRadio )`
248
- ${ baseItem }
208
+ ${ baseItem };
249
209
  `;
250
210
 
251
- export const DropdownMenuGroup = styled( Ariakit.MenuGroup )``;
211
+ export const ItemPrefixWrapper = styled.span`
212
+ /* Always occupy the first column, even when auto-collapsing */
213
+ grid-column: 1;
214
+
215
+ &:not( :empty ) {
216
+ margin-inline-end: ${ space( 2 ) };
217
+ }
252
218
 
253
- export const DropdownMenuGroupLabel = styled( Ariakit.MenuGroupLabel )`
254
- box-sizing: border-box;
255
219
  display: flex;
256
220
  align-items: center;
257
- min-height: ${ space( 8 ) };
258
-
259
- padding: ${ space( 2 ) } ${ ITEM_PADDING_INLINE_END } ${ space( 2 ) }
260
- ${ ITEM_PREFIX_WIDTH };
261
- /* TODO: color doesn't match available UI variables */
262
- color: ${ COLORS.gray[ 700 ] };
263
-
264
- /* TODO: font size doesn't match available ones via "font" utils */
265
- font-size: 11px;
266
- line-height: 1.4;
267
- font-weight: 500;
268
- text-transform: uppercase;
221
+ justify-content: center;
222
+
223
+ color: ${ COLORS.gray[ '700' ] };
224
+
225
+ /*
226
+ * When the parent menu item is active, except when it's a non-focused/hovered
227
+ * submenu trigger (in that case, color should not be inherited)
228
+ */
229
+ [data-active-item]:not( [data-focus-visible] ) > &,
230
+ /* When the parent menu item is disabled */
231
+ [aria-disabled='true'] > & {
232
+ color: inherit;
233
+ }
234
+ `;
235
+
236
+ export const DropdownMenuItemContentWrapper = styled.div`
237
+ /*
238
+ * Always occupy the second column, since the first column
239
+ * is taken by the prefix wrapper (when displayed).
240
+ */
241
+ grid-column: 2;
242
+
243
+ display: flex;
244
+ align-items: center;
245
+ justify-content: space-between;
246
+ gap: ${ space( 3 ) };
247
+
248
+ pointer-events: none;
249
+ `;
250
+
251
+ export const DropdownMenuItemChildrenWrapper = styled.div`
252
+ flex: 1;
253
+
254
+ display: inline-flex;
255
+ flex-direction: column;
256
+ gap: ${ space( 1 ) };
257
+ `;
258
+
259
+ export const ItemSuffixWrapper = styled.span`
260
+ flex: 0;
261
+ width: max-content;
262
+
263
+ display: flex;
264
+ align-items: center;
265
+ justify-content: center;
266
+ gap: ${ space( 3 ) };
267
+
268
+ color: ${ COLORS.gray[ '700' ] };
269
+
270
+ /*
271
+ * When the parent menu item is active, except when it's a non-focused/hovered
272
+ * submenu trigger (in that case, color should not be inherited)
273
+ */
274
+ [data-active-item]:not( [data-focus-visible] ) *:not(${ DropdownMenu }) &,
275
+ /* When the parent menu item is disabled */
276
+ [aria-disabled='true'] *:not(${ DropdownMenu }) & {
277
+ color: inherit;
278
+ }
279
+ `;
280
+
281
+ export const DropdownMenuGroup = styled( Ariakit.MenuGroup )`
282
+ /* Ignore this element when calculating the layout. Useful for subgrid */
283
+ display: contents;
269
284
  `;
270
285
 
271
286
  export const DropdownMenuSeparator = styled( Ariakit.MenuSeparator )<
272
287
  Pick< DropdownMenuContext, 'variant' >
273
288
  >`
289
+ /* Occupy the width of all grid columns (ie. full width) */
290
+ grid-column: 1 / -1;
291
+
274
292
  border: none;
275
293
  height: ${ CONFIG.borderWidth };
276
- /* TODO: doesn't match border color from variables */
277
294
  background-color: ${ ( props ) =>
278
295
  props.variant === 'toolbar'
279
296
  ? TOOLBAR_VARIANT_BORDER_COLOR
280
- : DEFAULT_BORDER_COLOR };
281
- /* Negative horizontal margin to make separator go from side to side */
282
- margin: ${ space( 2 ) } calc( -1 * ${ CONTENT_WRAPPER_PADDING } );
297
+ : DIVIDER_COLOR };
298
+ /* Align with menu items' content */
299
+ margin-block: ${ space( 2 ) };
300
+ margin-inline: ${ ITEM_PADDING_INLINE };
283
301
 
284
302
  /* Only visible in Windows High Contrast mode */
285
303
  outline: 2px solid transparent;
286
304
  `;
287
305
 
288
306
  export const SubmenuChevronIcon = styled( Icon )`
307
+ width: ${ space( 1.5 ) };
289
308
  ${ rtl(
290
309
  {
291
- transform: `scaleX(1) translateX(${ space( 2 ) })`,
310
+ transform: `scaleX(1)`,
292
311
  },
293
312
  {
294
- transform: `scaleX(-1) translateX(${ space( 2 ) })`,
313
+ transform: `scaleX(-1)`,
295
314
  }
296
- ) }
315
+ ) };
316
+ `;
317
+
318
+ export const DropdownMenuItemLabel = styled( Truncate )`
319
+ font-size: ${ font( 'default.fontSize' ) };
320
+ line-height: 20px;
321
+ color: inherit;
322
+ `;
323
+
324
+ export const DropdownMenuItemHelpText = styled( Truncate )`
325
+ font-size: ${ font( 'helpText.fontSize' ) };
326
+ line-height: 16px;
327
+ color: ${ COLORS.gray[ '700' ] };
328
+
329
+ [data-active-item]:not( [data-focus-visible] ) *:not( ${ DropdownMenu } ) &,
330
+ [aria-disabled='true'] *:not( ${ DropdownMenu } ) & {
331
+ color: inherit;
332
+ }
297
333
  `;
@@ -16,7 +16,6 @@ import {
16
16
  DropdownMenu,
17
17
  DropdownMenuCheckboxItem,
18
18
  DropdownMenuItem,
19
- DropdownMenuGroupLabel,
20
19
  DropdownMenuRadioItem,
21
20
  DropdownMenuSeparator,
22
21
  DropdownMenuGroup,
@@ -134,8 +133,9 @@ describe( 'DropdownMenu', () => {
134
133
  await press.ArrowDown();
135
134
 
136
135
  // DropdownMenu open, focus is on the first focusable item
136
+ // (disabled items are still focusable and accessible)
137
137
  expect(
138
- screen.getByRole( 'menuitem', { name: 'Second item' } )
138
+ screen.getByRole( 'menuitem', { name: 'First item' } )
139
139
  ).toHaveFocus();
140
140
  } );
141
141
 
@@ -163,8 +163,9 @@ describe( 'DropdownMenu', () => {
163
163
  await press.Space();
164
164
 
165
165
  // DropdownMenu open, focus is on the first focusable item
166
+ // (disabled items are still focusable and accessible
166
167
  expect(
167
- screen.getByRole( 'menuitem', { name: 'Second item' } )
168
+ screen.getByRole( 'menuitem', { name: 'First item' } )
168
169
  ).toHaveFocus();
169
170
  } );
170
171
 
@@ -197,32 +198,6 @@ describe( 'DropdownMenu', () => {
197
198
  );
198
199
  } );
199
200
 
200
- it( 'should not close when pressing the escape key if the `hideOnEscape` prop is set to `false`', async () => {
201
- render(
202
- <DropdownMenu
203
- trigger={ <button>Open dropdown</button> }
204
- hideOnEscape={ false }
205
- >
206
- <DropdownMenuItem>Dropdown menu item</DropdownMenuItem>
207
- </DropdownMenu>
208
- );
209
-
210
- const trigger = screen.getByRole( 'button', {
211
- name: 'Open dropdown',
212
- } );
213
-
214
- await click( trigger );
215
-
216
- // Focuses menu on mouse click, focuses first item on keyboard press
217
- // Can be changed with a custom useEffect
218
- expect( screen.getByRole( 'menu' ) ).toHaveFocus();
219
-
220
- // Pressing esc will close the menu and move focus to the toggle
221
- await press.Escape();
222
-
223
- expect( screen.getByRole( 'menu' ) ).toHaveFocus();
224
- } );
225
-
226
201
  it( 'should close when clicking outside of the content', async () => {
227
202
  render(
228
203
  <DropdownMenu
@@ -478,9 +453,6 @@ describe( 'DropdownMenu', () => {
478
453
  return (
479
454
  <DropdownMenu trigger={ <button>Open dropdown</button> }>
480
455
  <DropdownMenuGroup>
481
- <DropdownMenuGroupLabel>
482
- Radio group label
483
- </DropdownMenuGroupLabel>
484
456
  <DropdownMenuRadioItem
485
457
  name="radio-test"
486
458
  value="radio-one"
@@ -558,9 +530,6 @@ describe( 'DropdownMenu', () => {
558
530
  render(
559
531
  <DropdownMenu trigger={ <button>Open dropdown</button> }>
560
532
  <DropdownMenuGroup>
561
- <DropdownMenuGroupLabel>
562
- Radio group label
563
- </DropdownMenuGroupLabel>
564
533
  <DropdownMenuRadioItem
565
534
  name="radio-test"
566
535
  value="radio-one"
@@ -1017,7 +986,7 @@ describe( 'DropdownMenu', () => {
1017
986
  // The contents of the suffix are rendered after the item's children
1018
987
  expect(
1019
988
  screen.getByRole( 'menuitemradio', {
1020
- name: 'Radio item oneRadio suffix',
989
+ name: 'Radio item one Radio suffix',
1021
990
  } )
1022
991
  ).toBeInTheDocument();
1023
992
  } );
@@ -72,7 +72,7 @@ export interface DropdownMenuProps {
72
72
  * Determines whether the menu popover will be hidden when the user presses
73
73
  * the Escape key.
74
74
  *
75
- * @default true
75
+ * @default `( event ) => { event.preventDefault(); return true; }`
76
76
  */
77
77
  hideOnEscape?:
78
78
  | boolean
@@ -88,13 +88,6 @@ export interface DropdownMenuGroupProps {
88
88
  children: React.ReactNode;
89
89
  }
90
90
 
91
- export interface DropdownMenuGroupLabelProps {
92
- /**
93
- * The contents of the dropdown menu group label.
94
- */
95
- children: React.ReactNode;
96
- }
97
-
98
91
  export interface DropdownMenuItemProps {
99
92
  /**
100
93
  * The contents of the menu item.
@@ -1,6 +1,9 @@
1
1
  $toggle-width: 36px;
2
2
  $toggle-height: 18px;
3
3
  $toggle-border-width: 1px;
4
+ $thumb-size: $toggle-height - ($toggle-border-width * 6);
5
+
6
+ $transition-duration: 0.2s;
4
7
 
5
8
  .components-form-toggle {
6
9
  position: relative;
@@ -8,6 +11,7 @@ $toggle-border-width: 1px;
8
11
 
9
12
  // Unchecked state.
10
13
  .components-form-toggle__track {
14
+ position: relative;
11
15
  content: "";
12
16
  display: inline-block;
13
17
  box-sizing: border-box;
@@ -17,8 +21,26 @@ $toggle-border-width: 1px;
17
21
  width: $toggle-width;
18
22
  height: $toggle-height;
19
23
  border-radius: $toggle-height * 0.5;
20
- transition: 0.2s background ease;
24
+ transition:
25
+ $transition-duration background-color ease,
26
+ $transition-duration border-color ease;
21
27
  @include reduce-motion("transition");
28
+ overflow: hidden;
29
+
30
+ // Windows High Contrast Mode
31
+ &::after {
32
+ content: "";
33
+ position: absolute;
34
+ inset: 0;
35
+ box-sizing: border-box;
36
+ // Expand the border to fake a solid in Windows High Contrast Mode.
37
+ border-top: #{ $toggle-height } solid transparent;
38
+
39
+ transition: $transition-duration opacity ease;
40
+ @include reduce-motion("transition");
41
+
42
+ opacity: 0;
43
+ }
22
44
  }
23
45
 
24
46
  .components-form-toggle__thumb {
@@ -27,20 +49,28 @@ $toggle-border-width: 1px;
27
49
  box-sizing: border-box;
28
50
  top: $toggle-border-width * 3;
29
51
  left: $toggle-border-width * 3;
30
- width: $toggle-height - ($toggle-border-width * 6);
31
- height: $toggle-height - ($toggle-border-width * 6);
52
+ width: $thumb-size;
53
+ height: $thumb-size;
32
54
  border-radius: 50%;
33
- transition: 0.1s transform ease;
55
+ transition:
56
+ $transition-duration transform ease,
57
+ $transition-duration background-color ease-out;
34
58
  @include reduce-motion("transition");
35
59
  background-color: $gray-900;
36
- border: 5px solid $gray-900; // Has explicit border to act as a fill in Windows High Contrast Mode.
60
+
61
+ // Transparent border acts as a fill in Windows High Contrast Mode.
62
+ border: $thumb-size / 2 solid transparent;
37
63
  }
38
64
 
39
65
  // Checked state.
40
66
  &.is-checked .components-form-toggle__track {
41
67
  background-color: $components-color-accent;
42
- border: $toggle-border-width solid $components-color-accent;
43
- border: #{ $toggle-height * 0.5 } solid transparent; // Expand the border to fake a solid in Windows High Contrast Mode.
68
+ border-color: $components-color-accent;
69
+
70
+ // Windows High Contrast Mode
71
+ &::after {
72
+ opacity: 1;
73
+ }
44
74
  }
45
75
 
46
76
  .components-form-toggle__input:focus + .components-form-toggle__track {
@@ -2,7 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  import classnames from 'classnames';
5
- import type { KeyboardEvent, MouseEvent, TouchEvent } from 'react';
5
+ import type { KeyboardEvent, MouseEvent, TouchEvent, FocusEvent } from 'react';
6
6
 
7
7
  /**
8
8
  * WordPress dependencies
@@ -162,7 +162,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
162
162
  }
163
163
  }
164
164
 
165
- function onBlur() {
165
+ function onBlur( event: FocusEvent ) {
166
166
  if (
167
167
  inputHasValidValue() &&
168
168
  __experimentalValidateInput( incompleteTokenValue )
@@ -176,7 +176,15 @@ export function FormTokenField( props: FormTokenFieldProps ) {
176
176
  setIncompleteTokenValue( '' );
177
177
  setInputOffsetFromEnd( 0 );
178
178
  setIsActive( false );
179
- setIsExpanded( false );
179
+
180
+ // If `__experimentalExpandOnFocus` is true, don't close the suggestions list when
181
+ // the user clicks on it (`tokensAndInput` will be the element that caused the blur).
182
+ const shouldKeepSuggestionsExpanded =
183
+ ! __experimentalExpandOnFocus ||
184
+ ( __experimentalExpandOnFocus &&
185
+ event.relatedTarget === tokensAndInput.current );
186
+ setIsExpanded( shouldKeepSuggestionsExpanded );
187
+
180
188
  setSelectedSuggestionIndex( -1 );
181
189
  setSelectedSuggestionScroll( false );
182
190
  }
@@ -48,9 +48,7 @@ export function UnForwardedTokenInput(
48
48
  onFocus?.( e );
49
49
  };
50
50
 
51
- const onBlurHandler: React.FocusEventHandler< HTMLInputElement > = (
52
- e
53
- ) => {
51
+ const onBlurHandler: FocusEventHandler< HTMLInputElement > = ( e ) => {
54
52
  setHasFocus( false );
55
53
  onBlur?.( e );
56
54
  };
@@ -5,6 +5,7 @@ import type {
5
5
  ComponentPropsWithRef,
6
6
  MouseEventHandler,
7
7
  ReactNode,
8
+ FocusEvent,
8
9
  } from 'react';
9
10
 
10
11
  type Messages = {
@@ -257,7 +257,7 @@ export function GradientPicker( {
257
257
  onChange={ onChange }
258
258
  />
259
259
  ) }
260
- { ( gradients.length || clearable ) && (
260
+ { ( gradients.length > 0 || clearable ) && (
261
261
  <Component
262
262
  { ...additionalProps }
263
263
  className={ className }
@@ -18,7 +18,12 @@ function Example() {
18
18
 
19
19
  ## Props
20
20
 
21
- `Heading` uses `Text` underneath, so we have access to all of `Text`'s props except for `size` which is replaced by `level`. For a complete list of those props, check out [`Text`](/packages/components/src/text/README.md#props).
21
+ `Heading` uses `Text` underneath, so we have access to all of `Text`'s props except for:
22
+
23
+ - `size` which is replaced by `level`;
24
+ - `isBlock`'s default value, which is `true` for the `Heading` component.
25
+
26
+ For a complete list of those props, check out [`Text`](/packages/components/src/text/README.md#props).
22
27
 
23
28
  ##### `level`: `1 | 2 | 3 | 4 | 5 | 6 | '1' | '2' | '3' | '4' | '5' | '6'`
24
29
 
@@ -14,6 +14,9 @@ export function useHeading(
14
14
  const {
15
15
  as: asProp,
16
16
  level = 2,
17
+ color = COLORS.gray[ 900 ],
18
+ isBlock = true,
19
+ weight = CONFIG.fontWeightHeading as import('react').CSSProperties[ 'fontWeight' ],
17
20
  ...otherProps
18
21
  } = useContextSystem( props, 'Heading' );
19
22
 
@@ -31,10 +34,10 @@ export function useHeading(
31
34
  }
32
35
 
33
36
  const textProps = useText( {
34
- color: COLORS.gray[ 900 ],
37
+ color,
38
+ isBlock,
39
+ weight,
35
40
  size: getHeadingFontSize( level ),
36
- isBlock: true,
37
- weight: CONFIG.fontWeightHeading as import('react').CSSProperties[ 'fontWeight' ],
38
41
  ...otherProps,
39
42
  } );
40
43