@wordpress/components 35.0.1 → 35.1.1-next.v.202606191442.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 (264) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/build/alignment-matrix-control/cell.cjs +1 -1
  3. package/build/alignment-matrix-control/cell.cjs.map +2 -2
  4. package/build/alignment-matrix-control/index.cjs +1 -1
  5. package/build/alignment-matrix-control/index.cjs.map +2 -2
  6. package/build/angle-picker-control/angle-circle.cjs +1 -1
  7. package/build/angle-picker-control/angle-circle.cjs.map +2 -2
  8. package/build/angle-picker-control/index.cjs +2 -2
  9. package/build/autocomplete/get-autocomplete-match.cjs.map +1 -1
  10. package/build/autocomplete/index.cjs.map +1 -1
  11. package/build/base-control/styles/base-control-styles.cjs +6 -6
  12. package/build/base-control/styles/base-control-styles.cjs.map +2 -2
  13. package/build/border-control/styles.cjs +17 -14
  14. package/build/border-control/styles.cjs.map +2 -2
  15. package/build/button/index.cjs +3 -7
  16. package/build/button/index.cjs.map +2 -2
  17. package/build/card/card-divider/hook.cjs.map +2 -2
  18. package/build/color-palette/index.cjs.map +1 -1
  19. package/build/color-picker/component.cjs.map +1 -1
  20. package/build/date-time/utils.cjs.map +1 -1
  21. package/build/draggable/index.cjs.map +1 -1
  22. package/build/external-link/index.cjs +1 -1
  23. package/build/external-link/index.cjs.map +1 -1
  24. package/build/menu/popover.cjs.map +1 -1
  25. package/build/menu/styles.cjs +17 -17
  26. package/build/menu/styles.cjs.map +2 -2
  27. package/build/modal/index.cjs.map +1 -1
  28. package/build/modal/use-modal-exit-animation.cjs +37 -52
  29. package/build/modal/use-modal-exit-animation.cjs.map +2 -2
  30. package/build/palette-edit/index.cjs +1 -1
  31. package/build/progress-bar/index.cjs +1 -1
  32. package/build/progress-bar/index.cjs.map +2 -2
  33. package/build/query-controls/index.cjs +2 -2
  34. package/build/query-controls/index.cjs.map +2 -2
  35. package/build/range-control/index.cjs.map +1 -1
  36. package/build/sandbox/index.cjs +7 -1
  37. package/build/sandbox/index.cjs.map +2 -2
  38. package/build/snackbar/index.cjs +1 -1
  39. package/build/spinner/styles.cjs +4 -4
  40. package/build/spinner/styles.cjs.map +2 -2
  41. package/build/tabs/index.cjs +0 -18
  42. package/build/tabs/index.cjs.map +2 -2
  43. package/build/tabs/tablist.cjs +5 -15
  44. package/build/tabs/tablist.cjs.map +2 -2
  45. package/build/tools-panel/styles.cjs +13 -13
  46. package/build/tools-panel/styles.cjs.map +2 -2
  47. package/build/tools-panel/tools-panel/hook.cjs.map +1 -1
  48. package/build/tree-select/index.cjs +1 -1
  49. package/build/tree-select/index.cjs.map +1 -1
  50. package/build/truncate/utils.cjs +1 -1
  51. package/build/truncate/utils.cjs.map +1 -1
  52. package/build/utils/colors-values.cjs +12 -12
  53. package/build/utils/colors-values.cjs.map +2 -2
  54. package/build/utils/config-values.cjs +2 -2
  55. package/build/utils/config-values.cjs.map +2 -2
  56. package/build/utils/dropdown-motion.cjs.map +2 -2
  57. package/build/utils/strings.cjs.map +1 -1
  58. package/build-module/alignment-matrix-control/cell.mjs +1 -1
  59. package/build-module/alignment-matrix-control/cell.mjs.map +2 -2
  60. package/build-module/alignment-matrix-control/index.mjs +1 -1
  61. package/build-module/alignment-matrix-control/index.mjs.map +2 -2
  62. package/build-module/angle-picker-control/angle-circle.mjs +1 -1
  63. package/build-module/angle-picker-control/angle-circle.mjs.map +2 -2
  64. package/build-module/angle-picker-control/index.mjs +2 -2
  65. package/build-module/autocomplete/get-autocomplete-match.mjs.map +1 -1
  66. package/build-module/autocomplete/index.mjs.map +1 -1
  67. package/build-module/base-control/styles/base-control-styles.mjs +6 -6
  68. package/build-module/base-control/styles/base-control-styles.mjs.map +2 -2
  69. package/build-module/border-control/styles.mjs +17 -14
  70. package/build-module/border-control/styles.mjs.map +2 -2
  71. package/build-module/button/index.mjs +2 -5
  72. package/build-module/button/index.mjs.map +2 -2
  73. package/build-module/card/card-divider/hook.mjs.map +2 -2
  74. package/build-module/color-palette/index.mjs.map +1 -1
  75. package/build-module/color-picker/component.mjs.map +1 -1
  76. package/build-module/date-time/utils.mjs.map +1 -1
  77. package/build-module/draggable/index.mjs.map +1 -1
  78. package/build-module/external-link/index.mjs +1 -1
  79. package/build-module/external-link/index.mjs.map +1 -1
  80. package/build-module/menu/popover.mjs.map +1 -1
  81. package/build-module/menu/styles.mjs +17 -17
  82. package/build-module/menu/styles.mjs.map +2 -2
  83. package/build-module/modal/index.mjs.map +1 -1
  84. package/build-module/modal/use-modal-exit-animation.mjs +37 -52
  85. package/build-module/modal/use-modal-exit-animation.mjs.map +2 -2
  86. package/build-module/palette-edit/index.mjs +1 -1
  87. package/build-module/progress-bar/index.mjs +1 -1
  88. package/build-module/progress-bar/index.mjs.map +2 -2
  89. package/build-module/query-controls/index.mjs +2 -2
  90. package/build-module/query-controls/index.mjs.map +2 -2
  91. package/build-module/range-control/index.mjs.map +1 -1
  92. package/build-module/sandbox/index.mjs +3 -1
  93. package/build-module/sandbox/index.mjs.map +2 -2
  94. package/build-module/snackbar/index.mjs +1 -1
  95. package/build-module/spinner/styles.mjs +4 -4
  96. package/build-module/spinner/styles.mjs.map +2 -2
  97. package/build-module/tabs/index.mjs +1 -19
  98. package/build-module/tabs/index.mjs.map +2 -2
  99. package/build-module/tabs/tablist.mjs +5 -15
  100. package/build-module/tabs/tablist.mjs.map +2 -2
  101. package/build-module/tools-panel/styles.mjs +13 -13
  102. package/build-module/tools-panel/styles.mjs.map +2 -2
  103. package/build-module/tools-panel/tools-panel/hook.mjs.map +1 -1
  104. package/build-module/tree-select/index.mjs +1 -1
  105. package/build-module/tree-select/index.mjs.map +1 -1
  106. package/build-module/truncate/utils.mjs +1 -1
  107. package/build-module/truncate/utils.mjs.map +1 -1
  108. package/build-module/utils/colors-values.mjs +12 -12
  109. package/build-module/utils/colors-values.mjs.map +2 -2
  110. package/build-module/utils/config-values.mjs +2 -2
  111. package/build-module/utils/config-values.mjs.map +2 -2
  112. package/build-module/utils/dropdown-motion.mjs.map +2 -2
  113. package/build-module/utils/strings.mjs.map +1 -1
  114. package/build-style/style-rtl.css +82 -82
  115. package/build-style/style.css +82 -82
  116. package/build-types/base-control/styles/base-control-styles.d.ts.map +1 -1
  117. package/build-types/border-control/styles.d.ts.map +1 -1
  118. package/build-types/button/index.d.ts +0 -2
  119. package/build-types/button/index.d.ts.map +1 -1
  120. package/build-types/card/card-divider/hook.d.ts +1 -274
  121. package/build-types/card/card-divider/hook.d.ts.map +1 -1
  122. package/build-types/composite/stories/index.story.d.ts.map +1 -1
  123. package/build-types/confirm-dialog/stories/index.story.d.ts.map +1 -1
  124. package/build-types/dropdown/stories/index.story.d.ts.map +1 -1
  125. package/build-types/menu/styles.d.ts.map +1 -1
  126. package/build-types/menu/types.d.ts +2 -2
  127. package/build-types/sandbox/index.d.ts +15 -0
  128. package/build-types/sandbox/index.d.ts.map +1 -1
  129. package/build-types/spinner/styles.d.ts.map +1 -1
  130. package/build-types/tabs/index.d.ts.map +1 -1
  131. package/build-types/tabs/tablist.d.ts.map +1 -1
  132. package/build-types/tools-panel/styles.d.ts.map +1 -1
  133. package/build-types/utils/colors-values.d.ts.map +1 -1
  134. package/build-types/utils/dropdown-motion.d.ts.map +1 -1
  135. package/build-types/validated-form-controls/components/combobox-control.d.ts +1 -1
  136. package/package.json +34 -28
  137. package/src/angle-picker-control/angle-circle.tsx +3 -3
  138. package/src/base-control/README.md +2 -2
  139. package/src/base-control/styles/base-control-styles.ts +1 -0
  140. package/src/border-control/styles.ts +1 -0
  141. package/src/button/index.tsx +2 -4
  142. package/src/button/style.scss +3 -3
  143. package/src/card/card-divider/hook.ts +5 -1
  144. package/src/card/test/__snapshots__/index.tsx.snap +3 -3
  145. package/src/composite/stories/index.story.tsx +5 -0
  146. package/src/confirm-dialog/stories/index.story.tsx +1 -0
  147. package/src/dropdown/stories/index.story.tsx +5 -0
  148. package/src/dropdown-menu/style.scss +1 -1
  149. package/src/external-link/style.scss +4 -4
  150. package/src/form-toggle/style.scss +1 -1
  151. package/src/heading/test/__snapshots__/index.tsx.snap +4 -4
  152. package/src/menu/README.md +2 -2
  153. package/src/menu/styles.ts +2 -0
  154. package/src/menu/test/index.tsx +120 -87
  155. package/src/menu/types.ts +2 -2
  156. package/src/modal/style.scss +1 -1
  157. package/src/modal/use-modal-exit-animation.ts +2 -2
  158. package/src/notice/style.scss +11 -13
  159. package/src/panel/README.md +2 -0
  160. package/src/panel/stories/index.story.tsx +2 -2
  161. package/src/panel/style.scss +1 -1
  162. package/src/radio-control/style.scss +1 -1
  163. package/src/sandbox/index.tsx +18 -1
  164. package/src/sandbox/test/index.tsx +44 -1
  165. package/src/spinner/styles.ts +1 -0
  166. package/src/tab-panel/style.scss +6 -6
  167. package/src/tabs/index.tsx +1 -26
  168. package/src/tabs/tablist.tsx +5 -21
  169. package/src/tabs/test/index.tsx +16 -27
  170. package/src/text/test/__snapshots__/index.tsx.snap +3 -3
  171. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +34 -26
  172. package/src/toolbar/toolbar-group/style.scss +2 -2
  173. package/src/tools-panel/styles.ts +1 -1
  174. package/src/tooltip/stories/index.story.tsx +2 -2
  175. package/src/utils/colors-values.js +36 -16
  176. package/src/utils/config-values.js +2 -2
  177. package/src/utils/dropdown-motion.ts +6 -4
  178. package/src/utils/theme-variables.scss +18 -13
  179. package/build-types/card/context.d.ts +0 -3
  180. package/build-types/card/context.d.ts.map +0 -1
  181. package/build-types/date-time/date/index.d.ts +0 -23
  182. package/build-types/date-time/date/index.d.ts.map +0 -1
  183. package/build-types/date-time/date/styles.d.ts +0 -45
  184. package/build-types/date-time/date/styles.d.ts.map +0 -1
  185. package/build-types/date-time/date/test/index.d.ts +0 -2
  186. package/build-types/date-time/date/test/index.d.ts.map +0 -1
  187. package/build-types/date-time/date/test/use-lilius.d.ts +0 -2
  188. package/build-types/date-time/date/test/use-lilius.d.ts.map +0 -1
  189. package/build-types/date-time/date/use-lilius/index.d.ts +0 -169
  190. package/build-types/date-time/date/use-lilius/index.d.ts.map +0 -1
  191. package/build-types/date-time/time/index.d.ts +0 -27
  192. package/build-types/date-time/time/index.d.ts.map +0 -1
  193. package/build-types/date-time/time/styles.d.ts +0 -93
  194. package/build-types/date-time/time/styles.d.ts.map +0 -1
  195. package/build-types/date-time/time/test/index.d.ts +0 -2
  196. package/build-types/date-time/time/test/index.d.ts.map +0 -1
  197. package/build-types/date-time/time/time-input/index.d.ts +0 -4
  198. package/build-types/date-time/time/time-input/index.d.ts.map +0 -1
  199. package/build-types/date-time/time/time-input/test/index.d.ts +0 -2
  200. package/build-types/date-time/time/time-input/test/index.d.ts.map +0 -1
  201. package/build-types/date-time/time/timezone.d.ts +0 -7
  202. package/build-types/date-time/time/timezone.d.ts.map +0 -1
  203. package/build-types/mobile/image/constants.d.ts +0 -5
  204. package/build-types/mobile/image/constants.d.ts.map +0 -1
  205. package/build-types/navigation/back-button/index.d.ts +0 -7
  206. package/build-types/navigation/back-button/index.d.ts.map +0 -1
  207. package/build-types/navigation/constants.d.ts +0 -3
  208. package/build-types/navigation/constants.d.ts.map +0 -1
  209. package/build-types/navigation/context.d.ts +0 -4
  210. package/build-types/navigation/context.d.ts.map +0 -1
  211. package/build-types/navigation/group/context.d.ts +0 -7
  212. package/build-types/navigation/group/context.d.ts.map +0 -1
  213. package/build-types/navigation/group/index.d.ts +0 -7
  214. package/build-types/navigation/group/index.d.ts.map +0 -1
  215. package/build-types/navigation/index.d.ts +0 -46
  216. package/build-types/navigation/index.d.ts.map +0 -1
  217. package/build-types/navigation/item/base-content.d.ts +0 -3
  218. package/build-types/navigation/item/base-content.d.ts.map +0 -1
  219. package/build-types/navigation/item/base.d.ts +0 -3
  220. package/build-types/navigation/item/base.d.ts.map +0 -1
  221. package/build-types/navigation/item/index.d.ts +0 -7
  222. package/build-types/navigation/item/index.d.ts.map +0 -1
  223. package/build-types/navigation/item/use-navigation-tree-item.d.ts +0 -3
  224. package/build-types/navigation/item/use-navigation-tree-item.d.ts.map +0 -1
  225. package/build-types/navigation/menu/context.d.ts +0 -7
  226. package/build-types/navigation/menu/context.d.ts.map +0 -1
  227. package/build-types/navigation/menu/index.d.ts +0 -7
  228. package/build-types/navigation/menu/index.d.ts.map +0 -1
  229. package/build-types/navigation/menu/menu-title-search.d.ts +0 -3
  230. package/build-types/navigation/menu/menu-title-search.d.ts.map +0 -1
  231. package/build-types/navigation/menu/menu-title.d.ts +0 -3
  232. package/build-types/navigation/menu/menu-title.d.ts.map +0 -1
  233. package/build-types/navigation/menu/search-no-results-found.d.ts +0 -3
  234. package/build-types/navigation/menu/search-no-results-found.d.ts.map +0 -1
  235. package/build-types/navigation/menu/use-navigation-tree-menu.d.ts +0 -3
  236. package/build-types/navigation/menu/use-navigation-tree-menu.d.ts.map +0 -1
  237. package/build-types/navigation/stories/index.story.d.ts +0 -23
  238. package/build-types/navigation/stories/index.story.d.ts.map +0 -1
  239. package/build-types/navigation/stories/utils/controlled-state.d.ts +0 -7
  240. package/build-types/navigation/stories/utils/controlled-state.d.ts.map +0 -1
  241. package/build-types/navigation/stories/utils/default.d.ts +0 -10
  242. package/build-types/navigation/stories/utils/default.d.ts.map +0 -1
  243. package/build-types/navigation/stories/utils/group.d.ts +0 -10
  244. package/build-types/navigation/stories/utils/group.d.ts.map +0 -1
  245. package/build-types/navigation/stories/utils/hide-if-empty.d.ts +0 -10
  246. package/build-types/navigation/stories/utils/hide-if-empty.d.ts.map +0 -1
  247. package/build-types/navigation/stories/utils/more-examples.d.ts +0 -10
  248. package/build-types/navigation/stories/utils/more-examples.d.ts.map +0 -1
  249. package/build-types/navigation/stories/utils/search.d.ts +0 -10
  250. package/build-types/navigation/stories/utils/search.d.ts.map +0 -1
  251. package/build-types/navigation/styles/navigation-styles.d.ts +0 -55
  252. package/build-types/navigation/styles/navigation-styles.d.ts.map +0 -1
  253. package/build-types/navigation/test/index.d.ts +0 -2
  254. package/build-types/navigation/test/index.d.ts.map +0 -1
  255. package/build-types/navigation/types.d.ts +0 -266
  256. package/build-types/navigation/types.d.ts.map +0 -1
  257. package/build-types/navigation/use-create-navigation-tree.d.ts +0 -15
  258. package/build-types/navigation/use-create-navigation-tree.d.ts.map +0 -1
  259. package/build-types/navigation/use-navigation-tree-nodes.d.ts +0 -10
  260. package/build-types/navigation/use-navigation-tree-nodes.d.ts.map +0 -1
  261. package/build-types/navigation/utils.d.ts +0 -3
  262. package/build-types/navigation/utils.d.ts.map +0 -1
  263. package/build-types/visually-hidden/test/index.d.ts +0 -2
  264. package/build-types/visually-hidden/test/index.d.ts.map +0 -1
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { render, screen, waitFor } from '@testing-library/react';
5
- import { press, click, hover, type } from '@ariakit/test';
4
+ import { act, render, screen, waitFor } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
6
 
7
7
  /**
8
8
  * WordPress dependencies
@@ -14,10 +14,6 @@ import { useState } from '@wordpress/element';
14
14
  */
15
15
  import { Menu } from '..';
16
16
 
17
- const delay = ( delayInMs: number ) => {
18
- return new Promise( ( resolve ) => setTimeout( resolve, delayInMs ) );
19
- };
20
-
21
17
  const waitForFocusedMenu = () =>
22
18
  waitFor( () => expect( screen.getByRole( 'menu' ) ).toHaveFocus() );
23
19
 
@@ -26,10 +22,36 @@ const waitForFocusedMenuItem = ( name: string ) =>
26
22
  expect( screen.getByRole( 'menuitem', { name } ) ).toHaveFocus()
27
23
  );
28
24
 
25
+ const resetTypeahead = () => {
26
+ act( () => jest.advanceTimersByTime( 500 ) );
27
+ };
28
+
29
29
  // Open dropdown => open menu
30
30
  // Submenu trigger item => open submenu
31
31
 
32
32
  describe( 'Menu', () => {
33
+ let user: ReturnType< typeof userEvent.setup >;
34
+ let originalGetClientRects: () => DOMRectList;
35
+
36
+ beforeAll( () => {
37
+ // Code that considers focusability considers rects in whether the
38
+ // element is visible, but since jsdom does not simulate layout, we
39
+ // need to fake it. This should ideally be a global test mock to
40
+ // faithfully emulate a true browser environment.
41
+ originalGetClientRects = window.Element.prototype.getClientRects;
42
+ window.Element.prototype.getClientRects = jest.fn(
43
+ () => [ { width: 1, height: 1 } ] as unknown as DOMRectList
44
+ );
45
+ } );
46
+
47
+ afterAll( () => {
48
+ window.Element.prototype.getClientRects = originalGetClientRects;
49
+ } );
50
+
51
+ beforeEach( () => {
52
+ user = userEvent.setup();
53
+ } );
54
+
33
55
  // See https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/
34
56
  it( 'should follow the WAI-ARIA spec', async () => {
35
57
  render(
@@ -58,7 +80,7 @@ describe( 'Menu', () => {
58
80
  expect( toggleButton ).toHaveAttribute( 'aria-haspopup', 'menu' );
59
81
  expect( toggleButton ).toHaveAttribute( 'aria-expanded', 'false' );
60
82
 
61
- await click( toggleButton );
83
+ await user.click( toggleButton );
62
84
 
63
85
  expect( toggleButton ).toHaveAttribute( 'aria-expanded', 'true' );
64
86
 
@@ -82,7 +104,7 @@ describe( 'Menu', () => {
82
104
  expect( submenuTrigger ).toHaveAttribute( 'aria-haspopup', 'menu' );
83
105
  expect( submenuTrigger ).toHaveAttribute( 'aria-expanded', 'false' );
84
106
 
85
- await hover( submenuTrigger );
107
+ await user.hover( submenuTrigger );
86
108
 
87
109
  // Wait for the open animation after hovering
88
110
  await waitFor( () =>
@@ -119,7 +141,7 @@ describe( 'Menu', () => {
119
141
  expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
120
142
 
121
143
  // Click to open the menu
122
- await click( toggleButton );
144
+ await user.click( toggleButton );
123
145
 
124
146
  // Menu open, focus is on the menu wrapper
125
147
  await waitForFocusedMenu();
@@ -142,14 +164,14 @@ describe( 'Menu', () => {
142
164
  } );
143
165
 
144
166
  // Move focus on the toggle
145
- await press.Tab();
167
+ await user.tab();
146
168
 
147
169
  expect( toggleButton ).toHaveFocus();
148
170
 
149
171
  // Menu closed
150
172
  expect( screen.queryByRole( 'menuitem' ) ).not.toBeInTheDocument();
151
173
 
152
- await press.ArrowDown();
174
+ await user.keyboard( '{ArrowDown}' );
153
175
 
154
176
  // Menu open, focus is on the first focusable item
155
177
  // (disabled items are still focusable and accessible)
@@ -173,16 +195,16 @@ describe( 'Menu', () => {
173
195
  } );
174
196
 
175
197
  // Move focus on the toggle
176
- await press.Tab();
198
+ await user.tab();
177
199
 
178
200
  expect( toggleButton ).toHaveFocus();
179
201
 
180
202
  // Menu closed
181
203
  expect( screen.queryByRole( 'menuitem' ) ).not.toBeInTheDocument();
182
204
 
183
- // Keyboard-triggered clicks have `detail: 0`, which Ariakit uses to
184
- // distinguish keyboard activation from pointer activation.
185
- await press.Space( toggleButton, { detail: 0 } );
205
+ // Use keyboard activation so the synthetic click has `detail: 0`,
206
+ // which Ariakit uses to distinguish it from pointer activation.
207
+ await user.keyboard( ' ' );
186
208
 
187
209
  await waitFor( () =>
188
210
  expect( toggleButton ).toHaveAttribute(
@@ -207,16 +229,18 @@ describe( 'Menu', () => {
207
229
  name: 'Open dropdown',
208
230
  } );
209
231
 
210
- await click( trigger );
232
+ await user.click( trigger );
211
233
 
212
234
  // Focuses menu on mouse click, focuses first item on keyboard press
213
235
  // Can be changed with a custom useEffect
214
236
  await waitForFocusedMenu();
215
237
 
216
238
  // Pressing esc will close the menu and move focus to the toggle
217
- await press.Escape();
239
+ await user.keyboard( '{Escape}' );
218
240
 
219
- expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
241
+ await waitFor( () =>
242
+ expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument()
243
+ );
220
244
 
221
245
  await waitFor( () =>
222
246
  expect(
@@ -238,9 +262,11 @@ describe( 'Menu', () => {
238
262
  expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
239
263
 
240
264
  // Click on the body (ie. outside of the dropdown menu)
241
- await click( document.body );
265
+ await user.click( document.body );
242
266
 
243
- expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
267
+ await waitFor( () =>
268
+ expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument()
269
+ );
244
270
  } );
245
271
 
246
272
  it( 'should close when clicking on a menu item', async () => {
@@ -256,9 +282,11 @@ describe( 'Menu', () => {
256
282
  expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
257
283
 
258
284
  // Clicking a menu item will close the menu
259
- await click( screen.getByRole( 'menuitem' ) );
285
+ await user.click( screen.getByRole( 'menuitem' ) );
260
286
 
261
- expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
287
+ await waitFor( () =>
288
+ expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument()
289
+ );
262
290
  } );
263
291
 
264
292
  it( 'should not close when clicking on a menu item when the `hideOnClick` prop is set to `false`', async () => {
@@ -274,7 +302,7 @@ describe( 'Menu', () => {
274
302
  expect( screen.getByRole( 'menu' ) ).toBeVisible();
275
303
 
276
304
  // Clicking a menu item will close the menu
277
- await click( screen.getByRole( 'menuitem' ) );
305
+ await user.click( screen.getByRole( 'menuitem' ) );
278
306
 
279
307
  expect( screen.getByRole( 'menu' ) ).toBeVisible();
280
308
  } );
@@ -292,7 +320,7 @@ describe( 'Menu', () => {
292
320
  expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
293
321
 
294
322
  // Clicking a disabled menu item won't close the menu
295
- await click( screen.getByRole( 'menuitem' ) );
323
+ await user.click( screen.getByRole( 'menuitem' ) );
296
324
 
297
325
  expect( screen.getByRole( 'menu' ) ).toBeInTheDocument();
298
326
  } );
@@ -325,7 +353,7 @@ describe( 'Menu', () => {
325
353
  } )
326
354
  ).not.toBeInTheDocument();
327
355
 
328
- await hover(
356
+ await user.hover(
329
357
  screen.getByRole( 'menuitem', { name: 'Submenu trigger item' } )
330
358
  );
331
359
 
@@ -358,57 +386,53 @@ describe( 'Menu', () => {
358
386
  </Menu>
359
387
  );
360
388
 
361
- // The menu is focused automatically when `defaultOpen` is set.
362
- await waitForFocusedMenu();
389
+ // The first menu item is focused automatically when `defaultOpen` is
390
+ // set and jsdom reports visible elements as focusable.
391
+ await waitForFocusedMenuItem( 'Menu item 1' );
363
392
 
364
393
  // Arrow up/down selects menu items
365
394
  // The selection wraps around from last to first and viceversa
366
- await press.ArrowDown();
367
- expect(
368
- screen.getByRole( 'menuitem', { name: 'Menu item 1' } )
369
- ).toHaveFocus();
370
-
371
- await press.ArrowDown();
395
+ await user.keyboard( '{ArrowDown}' );
372
396
  expect(
373
397
  screen.getByRole( 'menuitem', { name: 'Menu item 2' } )
374
398
  ).toHaveFocus();
375
399
 
376
- await press.ArrowDown();
400
+ await user.keyboard( '{ArrowDown}' );
377
401
  expect(
378
402
  screen.getByRole( 'menuitem', { name: 'Submenu trigger item' } )
379
403
  ).toHaveFocus();
380
404
 
381
- await press.ArrowDown();
405
+ await user.keyboard( '{ArrowDown}' );
382
406
  expect(
383
407
  screen.getByRole( 'menuitem', { name: 'Menu item 3' } )
384
408
  ).toHaveFocus();
385
409
 
386
- await press.ArrowDown();
410
+ await user.keyboard( '{ArrowDown}' );
387
411
  expect(
388
412
  screen.getByRole( 'menuitem', { name: 'Menu item 1' } )
389
413
  ).toHaveFocus();
390
414
 
391
- await press.ArrowUp();
415
+ await user.keyboard( '{ArrowUp}' );
392
416
  expect(
393
417
  screen.getByRole( 'menuitem', { name: 'Menu item 3' } )
394
418
  ).toHaveFocus();
395
419
 
396
- await press.ArrowUp();
420
+ await user.keyboard( '{ArrowUp}' );
397
421
  expect(
398
422
  screen.getByRole( 'menuitem', { name: 'Submenu trigger item' } )
399
423
  ).toHaveFocus();
400
424
 
401
425
  // Arrow right/left can be used to enter/leave submenus
402
426
  // (focus crosses menu contexts, so wait for it to settle)
403
- await press.ArrowRight();
427
+ await user.keyboard( '{ArrowRight}' );
404
428
  await waitForFocusedMenuItem( 'Submenu item 1' );
405
429
 
406
- await press.ArrowDown();
430
+ await user.keyboard( '{ArrowDown}' );
407
431
  expect(
408
432
  screen.getByRole( 'menuitem', { name: 'Submenu item 2' } )
409
433
  ).toHaveFocus();
410
434
 
411
- await press.ArrowLeft();
435
+ await user.keyboard( '{ArrowLeft}' );
412
436
  expect(
413
437
  screen.getByRole( 'menuitem', {
414
438
  name: 'Submenu trigger item',
@@ -416,20 +440,20 @@ describe( 'Menu', () => {
416
440
  ).toHaveFocus();
417
441
 
418
442
  // Spacebar or enter key can also be used to enter a submenu
419
- await press.Enter();
443
+ await user.keyboard( '{Enter}' );
420
444
  await waitForFocusedMenuItem( 'Submenu item 1' );
421
445
 
422
- await press.ArrowLeft();
446
+ await user.keyboard( '{ArrowLeft}' );
423
447
  expect(
424
448
  screen.getByRole( 'menuitem', {
425
449
  name: 'Submenu trigger item',
426
450
  } )
427
451
  ).toHaveFocus();
428
452
 
429
- await press.Space();
453
+ await user.keyboard( ' ' );
430
454
  await waitForFocusedMenuItem( 'Submenu item 1' );
431
455
 
432
- await press.ArrowLeft();
456
+ await user.keyboard( '{ArrowLeft}' );
433
457
  expect(
434
458
  screen.getByRole( 'menuitem', {
435
459
  name: 'Submenu trigger item',
@@ -478,7 +502,7 @@ describe( 'Menu', () => {
478
502
  render( <ControlledRadioGroup /> );
479
503
 
480
504
  // Open dropdown
481
- await click(
505
+ await user.click(
482
506
  screen.getByRole( 'button', { name: 'Open dropdown' } )
483
507
  );
484
508
 
@@ -492,7 +516,7 @@ describe( 'Menu', () => {
492
516
  ).not.toBeChecked();
493
517
 
494
518
  // Click first radio item, make sure that the callback fires
495
- await click(
519
+ await user.click(
496
520
  screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
497
521
  );
498
522
  expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 1 );
@@ -509,7 +533,7 @@ describe( 'Menu', () => {
509
533
  ).not.toBeChecked();
510
534
 
511
535
  // Click second radio item, make sure that the callback fires
512
- await click(
536
+ await user.click(
513
537
  screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
514
538
  );
515
539
  expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 2 );
@@ -558,7 +582,7 @@ describe( 'Menu', () => {
558
582
  );
559
583
 
560
584
  // Open dropdown
561
- await click(
585
+ await user.click(
562
586
  screen.getByRole( 'button', { name: 'Open dropdown' } )
563
587
  );
564
588
 
@@ -572,7 +596,7 @@ describe( 'Menu', () => {
572
596
  ).toBeChecked();
573
597
 
574
598
  // Click first radio item, make sure that the callback fires
575
- await click(
599
+ await user.click(
576
600
  screen.getByRole( 'menuitemradio', { name: 'Radio item one' } )
577
601
  );
578
602
  expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 1 );
@@ -589,7 +613,7 @@ describe( 'Menu', () => {
589
613
  ).not.toBeChecked();
590
614
 
591
615
  // Click second radio item, make sure that the callback fires
592
- await click(
616
+ await user.click(
593
617
  screen.getByRole( 'menuitemradio', { name: 'Radio item two' } )
594
618
  );
595
619
  expect( onRadioValueChangeSpy ).toHaveBeenCalledTimes( 2 );
@@ -658,7 +682,7 @@ describe( 'Menu', () => {
658
682
  render( <ControlledRadioGroup /> );
659
683
 
660
684
  // Open dropdown
661
- await click(
685
+ await user.click(
662
686
  screen.getByRole( 'button', { name: 'Open dropdown' } )
663
687
  );
664
688
 
@@ -678,7 +702,7 @@ describe( 'Menu', () => {
678
702
  ).not.toBeChecked();
679
703
 
680
704
  // Click first checkbox item, make sure that the callback fires
681
- await click(
705
+ await user.click(
682
706
  screen.getByRole( 'menuitemcheckbox', {
683
707
  name: 'Checkbox item one',
684
708
  } )
@@ -698,7 +722,7 @@ describe( 'Menu', () => {
698
722
  ).toBeChecked();
699
723
 
700
724
  // Click second checkbox item, make sure that the callback fires
701
- await click(
725
+ await user.click(
702
726
  screen.getByRole( 'menuitemcheckbox', {
703
727
  name: 'Checkbox item two',
704
728
  } )
@@ -718,7 +742,7 @@ describe( 'Menu', () => {
718
742
  ).toBeChecked();
719
743
 
720
744
  // Click second checkbox item, make sure that the callback fires
721
- await click(
745
+ await user.click(
722
746
  screen.getByRole( 'menuitemcheckbox', {
723
747
  name: 'Checkbox item two',
724
748
  } )
@@ -778,7 +802,7 @@ describe( 'Menu', () => {
778
802
  );
779
803
 
780
804
  // Open dropdown
781
- await click(
805
+ await user.click(
782
806
  screen.getByRole( 'button', { name: 'Open dropdown' } )
783
807
  );
784
808
 
@@ -798,7 +822,7 @@ describe( 'Menu', () => {
798
822
  ).toBeChecked();
799
823
 
800
824
  // Click first checkbox item, make sure that the callback fires
801
- await click(
825
+ await user.click(
802
826
  screen.getByRole( 'menuitemcheckbox', {
803
827
  name: 'Checkbox item one',
804
828
  } )
@@ -818,7 +842,7 @@ describe( 'Menu', () => {
818
842
  ).toBeChecked();
819
843
 
820
844
  // Click second checkbox item, make sure that the callback fires
821
- await click(
845
+ await user.click(
822
846
  screen.getByRole( 'menuitemcheckbox', {
823
847
  name: 'Checkbox item two',
824
848
  } )
@@ -838,7 +862,7 @@ describe( 'Menu', () => {
838
862
  ).not.toBeChecked();
839
863
 
840
864
  // Click second checkbox item, make sure that the callback fires
841
- await click(
865
+ await user.click(
842
866
  screen.getByRole( 'menuitemcheckbox', {
843
867
  name: 'Checkbox item two',
844
868
  } )
@@ -874,7 +898,7 @@ describe( 'Menu', () => {
874
898
  );
875
899
 
876
900
  // Click to open the menu
877
- await click(
901
+ await user.click(
878
902
  screen.getByRole( 'button', {
879
903
  name: 'Open dropdown',
880
904
  } )
@@ -904,7 +928,7 @@ describe( 'Menu', () => {
904
928
  );
905
929
 
906
930
  // Click to open the menu
907
- await click(
931
+ await user.click(
908
932
  screen.getByRole( 'button', {
909
933
  name: 'Open dropdown',
910
934
  } )
@@ -922,9 +946,11 @@ describe( 'Menu', () => {
922
946
 
923
947
  // The outer button can be focused by pressing tab. Doing so will cause
924
948
  // the Menu to close.
925
- await press.Tab();
949
+ await user.tab();
926
950
  expect( outerButton ).toBeVisible();
927
- expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument();
951
+ await waitFor( () =>
952
+ expect( screen.queryByRole( 'menu' ) ).not.toBeInTheDocument()
953
+ );
928
954
  } );
929
955
  } );
930
956
 
@@ -942,7 +968,7 @@ describe( 'Menu', () => {
942
968
  );
943
969
 
944
970
  // Click to open the menu
945
- await click(
971
+ await user.click(
946
972
  screen.getByRole( 'button', {
947
973
  name: 'Open dropdown',
948
974
  } )
@@ -969,7 +995,7 @@ describe( 'Menu', () => {
969
995
  );
970
996
 
971
997
  // Click to open the menu
972
- await click(
998
+ await user.click(
973
999
  screen.getByRole( 'button', {
974
1000
  name: 'Open dropdown',
975
1001
  } )
@@ -1000,7 +1026,7 @@ describe( 'Menu', () => {
1000
1026
  );
1001
1027
 
1002
1028
  // Click to open the menu
1003
- await click(
1029
+ await user.click(
1004
1030
  screen.getByRole( 'button', {
1005
1031
  name: 'Open dropdown',
1006
1032
  } )
@@ -1031,7 +1057,7 @@ describe( 'Menu', () => {
1031
1057
  );
1032
1058
 
1033
1059
  // Click to open the menu
1034
- await click(
1060
+ await user.click(
1035
1061
  screen.getByRole( 'button', {
1036
1062
  name: 'Open dropdown',
1037
1063
  } )
@@ -1047,6 +1073,17 @@ describe( 'Menu', () => {
1047
1073
  } );
1048
1074
 
1049
1075
  describe( 'typeahead', () => {
1076
+ beforeEach( () => {
1077
+ jest.useFakeTimers();
1078
+ user = userEvent.setup( {
1079
+ advanceTimers: jest.advanceTimersByTime,
1080
+ } );
1081
+ } );
1082
+
1083
+ afterEach( () => {
1084
+ jest.useRealTimers();
1085
+ } );
1086
+
1050
1087
  it( 'should highlight matching item', async () => {
1051
1088
  render(
1052
1089
  <Menu>
@@ -1059,7 +1096,7 @@ describe( 'Menu', () => {
1059
1096
  );
1060
1097
 
1061
1098
  // Click to open the menu
1062
- await click(
1099
+ await user.click(
1063
1100
  screen.getByRole( 'button', {
1064
1101
  name: 'Open dropdown',
1065
1102
  } )
@@ -1067,17 +1104,16 @@ describe( 'Menu', () => {
1067
1104
  await waitForFocusedMenu();
1068
1105
 
1069
1106
  // Type "tw", it should match and focus the item with content "Two"
1070
- await type( 'tw' );
1107
+ await user.keyboard( 'tw' );
1071
1108
  expect(
1072
1109
  screen.getByRole( 'menuitem', { name: 'Two' } )
1073
1110
  ).toHaveFocus();
1074
1111
 
1075
- // Wait for the typeahead timer to reset and interpret
1076
- // the next keystrokes as a new search
1077
- await delay( 500 );
1112
+ // Reset the typeahead search so the next keystrokes start a new query.
1113
+ resetTypeahead();
1078
1114
 
1079
1115
  // Type "on", it should match and focus the item with content "One"
1080
- await type( 'on' );
1116
+ await user.keyboard( 'on' );
1081
1117
  expect(
1082
1118
  screen.getByRole( 'menuitem', { name: 'One' } )
1083
1119
  ).toHaveFocus();
@@ -1095,7 +1131,7 @@ describe( 'Menu', () => {
1095
1131
  );
1096
1132
 
1097
1133
  // Click to open the menu
1098
- await click(
1134
+ await user.click(
1099
1135
  screen.getByRole( 'button', {
1100
1136
  name: 'Open dropdown',
1101
1137
  } )
@@ -1103,35 +1139,32 @@ describe( 'Menu', () => {
1103
1139
  await waitForFocusedMenu();
1104
1140
 
1105
1141
  // Type a string that doesn't match any items. Focus shouldn't move.
1106
- await type( 'abc' );
1142
+ await user.keyboard( 'abc' );
1107
1143
  expect( screen.getByRole( 'menu' ) ).toHaveFocus();
1108
1144
 
1109
- // Wait for the typeahead timer to reset and interpret
1110
- // the next keystrokes as a new search
1111
- await delay( 500 );
1145
+ // Reset the typeahead search so the next keystrokes start a new query.
1146
+ resetTypeahead();
1112
1147
 
1113
1148
  // Type "on", it should match and focus the item with content "One"
1114
- await type( 'on' );
1149
+ await user.keyboard( 'on' );
1115
1150
  expect(
1116
1151
  screen.getByRole( 'menuitem', { name: 'One' } )
1117
1152
  ).toHaveFocus();
1118
1153
 
1119
- // Wait for the typeahead timer to reset and interpret
1120
- // the next keystrokes as a new search
1121
- await delay( 500 );
1154
+ // Reset the typeahead search so the next keystrokes start a new query.
1155
+ resetTypeahead();
1122
1156
 
1123
1157
  // Type a string that doesn't match any items. Focus shouldn't move.
1124
- await type( 'abc' );
1158
+ await user.keyboard( 'abc' );
1125
1159
  expect(
1126
1160
  screen.getByRole( 'menuitem', { name: 'One' } )
1127
1161
  ).toHaveFocus();
1128
1162
 
1129
- // Wait for the typeahead timer to reset and interpret
1130
- // the next keystrokes as a new search
1131
- await delay( 500 );
1163
+ // Reset the typeahead search so the next keystrokes start a new query.
1164
+ resetTypeahead();
1132
1165
 
1133
1166
  // Type "tw", it should match and focus the item with content "Two"
1134
- await type( 'tw' );
1167
+ await user.keyboard( 'tw' );
1135
1168
  expect(
1136
1169
  screen.getByRole( 'menuitem', { name: 'Two' } )
1137
1170
  ).toHaveFocus();
package/src/menu/types.ts CHANGED
@@ -258,7 +258,7 @@ export interface CheckboxItemProps {
258
258
  * The checked state of the checkbox menu item when it is initially rendered.
259
259
  * Use when not wanting to control its checked state.
260
260
  *
261
- * Note: this prop will be overriden by the `checked` prop, if it is defined.
261
+ * Note: this prop will be overridden by the `checked` prop, if it is defined.
262
262
  */
263
263
  defaultChecked?: Ariakit.MenuItemCheckboxProps[ 'defaultChecked' ];
264
264
  /**
@@ -321,7 +321,7 @@ export interface RadioItemProps {
321
321
  * The checked state of the radio menu item when it is initially rendered.
322
322
  * Use when not wanting to control its checked state.
323
323
  *
324
- * Note: this prop will be overriden by the `checked` prop, if it is defined.
324
+ * Note: this prop will be overridden by the `checked` prop, if it is defined.
325
325
  */
326
326
  defaultChecked?: Ariakit.MenuItemRadioProps[ 'defaultChecked' ];
327
327
  /**
@@ -217,7 +217,7 @@
217
217
  }
218
218
 
219
219
  .components-modal__content.has-scrolled-content:not(.hide-header) & {
220
- border-bottom-color: $gray-300;
220
+ border-bottom-color: var(--wpds-color-stroke-surface-neutral);
221
221
  }
222
222
 
223
223
  & + p {
@@ -14,8 +14,8 @@ import { CONFIG } from '../utils';
14
14
  * Milliseconds used as a fallback when racing `animationend` against a timeout.
15
15
  *
16
16
  * Sourced from `CONFIG.transitionDuration`. This value is implicitly coupled to
17
- * the modal frame’s CSS `animation-duration` in `style.scss`, which uses
18
- * `var(--wpds-motion-duration-md)`. If either the token, the SCSS, or
17
+ * the modal frame’s CSS `animation-duration` in `style.scss`, which uses the
18
+ * WPDS `motion-duration-md` token. If either the token, the SCSS, or
19
19
  * `CONFIG.transitionDuration` changes, keep them aligned so exit timing stays correct.
20
20
  */
21
21
  const FRAME_ANIMATION_DURATION_MS = Number.parseInt(
@@ -1,9 +1,9 @@
1
1
  @use "@wordpress/base-styles/variables" as *;
2
2
 
3
3
  .components-notice {
4
- --wp-components-notice-background-color: var(--wpds-color-bg-surface-info-weak);
4
+ --wp-components-notice-background-color: var(--wpds-color-background-surface-info-weak);
5
5
  --wp-components-notice-border-color: var(--wpds-color-stroke-surface-info);
6
- --wp-components-notice-text-color: var(--wpds-color-fg-content-info);
6
+ --wp-components-notice-text-color: var(--wpds-color-foreground-content-info);
7
7
 
8
8
  box-sizing: border-box;
9
9
  display: grid;
@@ -19,21 +19,21 @@
19
19
  line-height: var(--wpds-typography-line-height-sm);
20
20
 
21
21
  &.is-success {
22
- --wp-components-notice-background-color: var(--wpds-color-bg-surface-success-weak);
22
+ --wp-components-notice-background-color: var(--wpds-color-background-surface-success-weak);
23
23
  --wp-components-notice-border-color: var(--wpds-color-stroke-surface-success);
24
- --wp-components-notice-text-color: var(--wpds-color-fg-content-success);
24
+ --wp-components-notice-text-color: var(--wpds-color-foreground-content-success);
25
25
  }
26
26
 
27
27
  &.is-warning {
28
- --wp-components-notice-background-color: var(--wpds-color-bg-surface-warning-weak);
28
+ --wp-components-notice-background-color: var(--wpds-color-background-surface-warning-weak);
29
29
  --wp-components-notice-border-color: var(--wpds-color-stroke-surface-warning);
30
- --wp-components-notice-text-color: var(--wpds-color-fg-content-warning);
30
+ --wp-components-notice-text-color: var(--wpds-color-foreground-content-warning);
31
31
  }
32
32
 
33
33
  &.is-error {
34
- --wp-components-notice-background-color: var(--wpds-color-bg-surface-error-weak);
34
+ --wp-components-notice-background-color: var(--wpds-color-background-surface-error-weak);
35
35
  --wp-components-notice-border-color: var(--wpds-color-stroke-surface-error);
36
- --wp-components-notice-text-color: var(--wpds-color-fg-content-error);
36
+ --wp-components-notice-text-color: var(--wpds-color-foreground-content-error);
37
37
  }
38
38
  }
39
39
 
@@ -46,9 +46,7 @@
46
46
  // consistent across variants, matching `@wordpress/ui` Notice (`.title` /
47
47
  // `.description` always use `--text-vertical-padding` whether or not `CloseIcon`
48
48
  // is rendered).
49
- // TODO: Replace `$button-size-small` with a WPDS size token once size tokens
50
- // land in `@wordpress/theme`.
51
- padding-block: calc((#{$button-size-small} - 1lh) / 2);
49
+ padding-block: calc((var(--wpds-dimension-size-sm) - 1lh) / 2);
52
50
  }
53
51
 
54
52
  .components-notice__actions {
@@ -65,13 +63,13 @@
65
63
  .components-notice__dismiss {
66
64
  grid-column: 2;
67
65
  grid-row: 1;
68
- color: var(--wpds-color-fg-interactive-neutral);
66
+ color: var(--wpds-color-foreground-interactive-neutral);
69
67
  margin-inline-start: var(--wpds-dimension-gap-xs);
70
68
 
71
69
  &:not(:disabled):not([aria-disabled="true"]):not(.is-secondary):hover,
72
70
  &:not(:disabled):not([aria-disabled="true"]):not(.is-secondary):active,
73
71
  &:not(:disabled):not([aria-disabled="true"]):focus {
74
- color: var(--wpds-color-fg-interactive-neutral-active);
72
+ color: var(--wpds-color-foreground-interactive-neutral-active);
75
73
  background-color: transparent;
76
74
  }
77
75