@wordpress/components 25.4.0 → 25.5.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 (119) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/build/border-control/border-control-dropdown/component.js +8 -10
  3. package/build/border-control/border-control-dropdown/component.js.map +1 -1
  4. package/build/color-palette/index.js +2 -2
  5. package/build/color-palette/index.js.map +1 -1
  6. package/build/focal-point-picker/index.native.js +6 -4
  7. package/build/focal-point-picker/index.native.js.map +1 -1
  8. package/build/menu-items-choice/index.js +1 -0
  9. package/build/menu-items-choice/index.js.map +1 -1
  10. package/build/mobile/bottom-sheet/bottom-sheet-navigation/bottom-sheet-navigation-context.native.js +3 -1
  11. package/build/mobile/bottom-sheet/bottom-sheet-navigation/bottom-sheet-navigation-context.native.js.map +1 -1
  12. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js +50 -44
  13. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js.map +1 -1
  14. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +13 -20
  15. package/build/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
  16. package/build/mobile/bottom-sheet/index.native.js +3 -1
  17. package/build/mobile/bottom-sheet/index.native.js.map +1 -1
  18. package/build/mobile/link-picker/link-picker-results.native.js +2 -1
  19. package/build/mobile/link-picker/link-picker-results.native.js.map +1 -1
  20. package/build/mobile/segmented-control/index.native.js +7 -7
  21. package/build/mobile/segmented-control/index.native.js.map +1 -1
  22. package/build/modal/index.js +14 -1
  23. package/build/modal/index.js.map +1 -1
  24. package/build/private-apis.js +4 -1
  25. package/build/private-apis.js.map +1 -1
  26. package/build/progress-bar/index.js +54 -0
  27. package/build/progress-bar/index.js.map +1 -0
  28. package/build/progress-bar/styles.js +69 -0
  29. package/build/progress-bar/styles.js.map +1 -0
  30. package/build/progress-bar/types.js +6 -0
  31. package/build/progress-bar/types.js.map +1 -0
  32. package/build/tab-panel/index.js +91 -58
  33. package/build/tab-panel/index.js.map +1 -1
  34. package/build-module/border-control/border-control-dropdown/component.js +8 -10
  35. package/build-module/border-control/border-control-dropdown/component.js.map +1 -1
  36. package/build-module/color-palette/index.js +2 -2
  37. package/build-module/color-palette/index.js.map +1 -1
  38. package/build-module/focal-point-picker/index.native.js +6 -5
  39. package/build-module/focal-point-picker/index.native.js.map +1 -1
  40. package/build-module/menu-items-choice/index.js +1 -0
  41. package/build-module/menu-items-choice/index.js.map +1 -1
  42. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/bottom-sheet-navigation-context.native.js +3 -1
  43. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/bottom-sheet-navigation-context.native.js.map +1 -1
  44. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js +43 -41
  45. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js.map +1 -1
  46. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +14 -20
  47. package/build-module/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js.map +1 -1
  48. package/build-module/mobile/bottom-sheet/index.native.js +3 -1
  49. package/build-module/mobile/bottom-sheet/index.native.js.map +1 -1
  50. package/build-module/mobile/link-picker/link-picker-results.native.js +2 -1
  51. package/build-module/mobile/link-picker/link-picker-results.native.js.map +1 -1
  52. package/build-module/mobile/segmented-control/index.native.js +7 -7
  53. package/build-module/mobile/segmented-control/index.native.js.map +1 -1
  54. package/build-module/modal/index.js +14 -1
  55. package/build-module/modal/index.js.map +1 -1
  56. package/build-module/private-apis.js +3 -1
  57. package/build-module/private-apis.js.map +1 -1
  58. package/build-module/progress-bar/index.js +41 -0
  59. package/build-module/progress-bar/index.js.map +1 -0
  60. package/build-module/progress-bar/styles.js +61 -0
  61. package/build-module/progress-bar/styles.js.map +1 -0
  62. package/build-module/progress-bar/types.js +2 -0
  63. package/build-module/progress-bar/types.js.map +1 -0
  64. package/build-module/tab-panel/index.js +88 -59
  65. package/build-module/tab-panel/index.js.map +1 -1
  66. package/build-types/border-control/border-control-dropdown/component.d.ts.map +1 -1
  67. package/build-types/menu-items-choice/index.d.ts.map +1 -1
  68. package/build-types/menu-items-choice/types.d.ts +5 -0
  69. package/build-types/menu-items-choice/types.d.ts.map +1 -1
  70. package/build-types/modal/index.d.ts.map +1 -1
  71. package/build-types/private-apis.d.ts.map +1 -1
  72. package/build-types/progress-bar/index.d.ts +5 -0
  73. package/build-types/progress-bar/index.d.ts.map +1 -0
  74. package/build-types/progress-bar/stories/index.d.ts +12 -0
  75. package/build-types/progress-bar/stories/index.d.ts.map +1 -0
  76. package/build-types/progress-bar/styles.d.ts +18 -0
  77. package/build-types/progress-bar/styles.d.ts.map +1 -0
  78. package/build-types/progress-bar/test/index.d.ts +2 -0
  79. package/build-types/progress-bar/test/index.d.ts.map +1 -0
  80. package/build-types/progress-bar/types.d.ts +11 -0
  81. package/build-types/progress-bar/types.d.ts.map +1 -0
  82. package/build-types/tab-panel/index.d.ts.map +1 -1
  83. package/build-types/tab-panel/stories/index.d.ts +1 -0
  84. package/build-types/tab-panel/stories/index.d.ts.map +1 -1
  85. package/build-types/tab-panel/types.d.ts +1 -9
  86. package/build-types/tab-panel/types.d.ts.map +1 -1
  87. package/package.json +20 -20
  88. package/src/border-control/border-control-dropdown/component.tsx +7 -11
  89. package/src/border-control/test/index.js +6 -6
  90. package/src/color-palette/index.tsx +2 -2
  91. package/src/color-palette/test/__snapshots__/index.tsx.snap +1 -1
  92. package/src/color-palette/test/index.tsx +1 -5
  93. package/src/draggable/test/index.native.js +4 -0
  94. package/src/focal-point-picker/index.native.js +6 -5
  95. package/src/menu-item/README.md +7 -0
  96. package/src/menu-items-choice/index.tsx +1 -0
  97. package/src/menu-items-choice/types.ts +5 -0
  98. package/src/mobile/bottom-sheet/bottom-sheet-navigation/bottom-sheet-navigation-context.native.js +1 -1
  99. package/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js +72 -53
  100. package/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-screen.native.js +15 -21
  101. package/src/mobile/bottom-sheet/bottom-sheet-navigation/test/navigation-container.native.js +165 -119
  102. package/src/mobile/bottom-sheet/index.native.js +2 -0
  103. package/src/mobile/link-picker/link-picker-results.native.js +1 -1
  104. package/src/mobile/link-settings/test/edit.native.js +37 -23
  105. package/src/mobile/segmented-control/index.native.js +11 -11
  106. package/src/modal/index.tsx +16 -0
  107. package/src/modal/test/index.tsx +33 -0
  108. package/src/private-apis.ts +2 -0
  109. package/src/progress-bar/README.md +30 -0
  110. package/src/progress-bar/index.tsx +45 -0
  111. package/src/progress-bar/stories/index.tsx +33 -0
  112. package/src/progress-bar/styles.ts +67 -0
  113. package/src/progress-bar/test/index.tsx +79 -0
  114. package/src/progress-bar/types.ts +11 -0
  115. package/src/tab-panel/index.tsx +121 -84
  116. package/src/tab-panel/stories/index.tsx +6 -0
  117. package/src/tab-panel/test/index.tsx +128 -109
  118. package/src/tab-panel/types.ts +1 -10
  119. package/tsconfig.tsbuildinfo +1 -1
@@ -34,7 +34,8 @@ const TABS = [
34
34
  },
35
35
  ];
36
36
 
37
- const getSelectedTab = () => screen.getByRole( 'tab', { selected: true } );
37
+ const getSelectedTab = async () =>
38
+ await screen.findByRole( 'tab', { selected: true } );
38
39
 
39
40
  let originalGetClientRects: () => DOMRectList;
40
41
 
@@ -62,7 +63,7 @@ describe.each( [
62
63
  } );
63
64
 
64
65
  describe( 'Accessibility and semantics', () => {
65
- test( 'should use the correct aria attributes', () => {
66
+ it( 'should use the correct aria attributes', async () => {
66
67
  const panelRenderFunction = jest.fn();
67
68
 
68
69
  render(
@@ -71,7 +72,7 @@ describe.each( [
71
72
 
72
73
  const tabList = screen.getByRole( 'tablist' );
73
74
  const allTabs = screen.getAllByRole( 'tab' );
74
- const selectedTabPanel = screen.getByRole( 'tabpanel' );
75
+ const selectedTabPanel = await screen.findByRole( 'tabpanel' );
75
76
 
76
77
  expect( tabList ).toBeVisible();
77
78
  expect( tabList ).toHaveAttribute(
@@ -94,7 +95,7 @@ describe.each( [
94
95
  );
95
96
  } );
96
97
 
97
- test( 'should display a tooltip when hovering tabs provided with an icon', async () => {
98
+ it( 'should display a tooltip when hovering tabs provided with an icon', async () => {
98
99
  const user = userEvent.setup();
99
100
 
100
101
  const panelRenderFunction = jest.fn();
@@ -138,7 +139,7 @@ describe.each( [
138
139
  }
139
140
  } );
140
141
 
141
- test( 'should display a tooltip when moving the selection via the keyboard on tabs provided with an icon', async () => {
142
+ it( 'should display a tooltip when moving the selection via the keyboard on tabs provided with an icon', async () => {
142
143
  const user = userEvent.setup();
143
144
 
144
145
  const mockOnSelect = jest.fn();
@@ -165,10 +166,10 @@ describe.each( [
165
166
  </SlotFillProvider>
166
167
  );
167
168
 
168
- expect( getSelectedTab() ).not.toHaveTextContent( 'Alpha' );
169
+ expect( await getSelectedTab() ).not.toHaveTextContent( 'Alpha' );
169
170
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
170
171
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
171
- await expect( getSelectedTab() ).not.toHaveFocus();
172
+ expect( await getSelectedTab() ).not.toHaveFocus();
172
173
 
173
174
  // Tab to focus the tablist. Make sure alpha is focused, and that the
174
175
  // corresponding tooltip is shown.
@@ -176,7 +177,7 @@ describe.each( [
176
177
  await user.keyboard( '[Tab]' );
177
178
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
178
179
  expect( screen.getByText( 'Alpha' ) ).toBeInTheDocument();
179
- await expect( getSelectedTab() ).toHaveFocus();
180
+ expect( await getSelectedTab() ).toHaveFocus();
180
181
 
181
182
  // Move selection with arrow keys. Make sure beta is focused, and that
182
183
  // the corresponding tooltip is shown.
@@ -185,7 +186,7 @@ describe.each( [
185
186
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
186
187
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
187
188
  expect( screen.getByText( 'Beta' ) ).toBeInTheDocument();
188
- await expect( getSelectedTab() ).toHaveFocus();
189
+ expect( await getSelectedTab() ).toHaveFocus();
189
190
 
190
191
  // Move selection with arrow keys. Make sure gamma is focused, and that
191
192
  // the corresponding tooltip is shown.
@@ -194,7 +195,7 @@ describe.each( [
194
195
  expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
195
196
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
196
197
  expect( screen.getByText( 'Gamma' ) ).toBeInTheDocument();
197
- await expect( getSelectedTab() ).toHaveFocus();
198
+ expect( await getSelectedTab() ).toHaveFocus();
198
199
 
199
200
  // Move selection with arrow keys. Make sure beta is focused, and that
200
201
  // the corresponding tooltip is shown.
@@ -203,7 +204,7 @@ describe.each( [
203
204
  expect( mockOnSelect ).toHaveBeenCalledTimes( 4 );
204
205
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
205
206
  expect( screen.getByText( 'Beta' ) ).toBeInTheDocument();
206
- await expect( getSelectedTab() ).toHaveFocus();
207
+ expect( await getSelectedTab() ).toHaveFocus();
207
208
  } );
208
209
  } );
209
210
 
@@ -215,11 +216,10 @@ describe.each( [
215
216
  <Component tabs={ TABS } children={ panelRenderFunction } />
216
217
  );
217
218
 
218
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
219
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
219
220
  expect(
220
- screen.getByRole( 'tabpanel', { name: 'Alpha' } )
221
+ await screen.findByRole( 'tabpanel', { name: 'Alpha' } )
221
222
  ).toBeInTheDocument();
222
- expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 0 ] );
223
223
  } );
224
224
 
225
225
  it( 'should fall back to first enabled tab if the active tab is removed', async () => {
@@ -239,12 +239,12 @@ describe.each( [
239
239
  onSelect={ mockOnSelect }
240
240
  />
241
241
  );
242
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
242
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
243
243
  } );
244
244
  } );
245
245
 
246
246
  describe( 'With `initialTabName`', () => {
247
- it( 'should render the tab set by initialTabName prop', () => {
247
+ it( 'should render the tab set by initialTabName prop', async () => {
248
248
  render(
249
249
  <Component
250
250
  initialTabName="beta"
@@ -253,7 +253,7 @@ describe.each( [
253
253
  />
254
254
  );
255
255
 
256
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
256
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
257
257
  } );
258
258
 
259
259
  it( 'should not select a tab when `initialTabName` does not match any known tab', () => {
@@ -273,8 +273,7 @@ describe.each( [
273
273
  // No tabpanel should be rendered either
274
274
  expect( screen.queryByRole( 'tabpanel' ) ).not.toBeInTheDocument();
275
275
  } );
276
-
277
- it( 'should not change tabs when initialTabName is changed', () => {
276
+ it( 'should not change tabs when initialTabName is changed', async () => {
278
277
  const { rerender } = render(
279
278
  <Component
280
279
  initialTabName="beta"
@@ -291,7 +290,7 @@ describe.each( [
291
290
  />
292
291
  );
293
292
 
294
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
293
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
295
294
  } );
296
295
 
297
296
  it( 'should fall back to the tab associated to `initialTabName` if the currently active tab is removed', async () => {
@@ -307,13 +306,11 @@ describe.each( [
307
306
  />
308
307
  );
309
308
 
310
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
311
- expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
309
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
312
310
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
313
311
 
314
312
  await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) );
315
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
316
- expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
313
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
317
314
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
318
315
 
319
316
  rerender(
@@ -325,12 +322,11 @@ describe.each( [
325
322
  />
326
323
  );
327
324
 
328
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
329
- expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
325
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
330
326
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
331
327
  } );
332
328
 
333
- it( 'should have no active tabs when the tab associated to `initialTabName` is removed while being the active tab', () => {
329
+ it( 'should have no active tabs when the tab associated to `initialTabName` is removed while being the active tab', async () => {
334
330
  const mockOnSelect = jest.fn();
335
331
 
336
332
  const { rerender } = render(
@@ -342,7 +338,7 @@ describe.each( [
342
338
  />
343
339
  );
344
340
 
345
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
341
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
346
342
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
347
343
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
348
344
 
@@ -362,7 +358,7 @@ describe.each( [
362
358
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
363
359
  } );
364
360
 
365
- it( 'waits for the tab with the `initialTabName` to be present in the `tabs` array before selecting it', () => {
361
+ it( 'waits for the tab with the `initialTabName` to be present in the `tabs` array before selecting it', async () => {
366
362
  const mockOnSelect = jest.fn();
367
363
  const { rerender } = render(
368
364
  <Component
@@ -394,7 +390,7 @@ describe.each( [
394
390
  />
395
391
  );
396
392
 
397
- expect( getSelectedTab() ).toHaveTextContent( 'Delta' );
393
+ expect( await getSelectedTab() ).toHaveTextContent( 'Delta' );
398
394
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'delta' );
399
395
  } );
400
396
  } );
@@ -433,7 +429,7 @@ describe.each( [
433
429
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
434
430
  } );
435
431
 
436
- it( 'should select first enabled tab when the initial tab is disabled', () => {
432
+ it( 'should select first enabled tab when the initial tab is disabled', async () => {
437
433
  const mockOnSelect = jest.fn();
438
434
 
439
435
  const { rerender } = render(
@@ -452,7 +448,7 @@ describe.each( [
452
448
 
453
449
  // As alpha (first tab) is disabled,
454
450
  // the first enabled tab should be gamma.
455
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
451
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
456
452
 
457
453
  // Re-enable all tabs
458
454
  rerender(
@@ -465,10 +461,10 @@ describe.each( [
465
461
 
466
462
  // Even if the initial tab becomes enabled again, the selected tab doesn't
467
463
  // change.
468
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
464
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
469
465
  } );
470
466
 
471
- it( 'should select first enabled tab when the tab associated to `initialTabName` is disabled', () => {
467
+ it( 'should select first enabled tab when the tab associated to `initialTabName` is disabled', async () => {
472
468
  const mockOnSelect = jest.fn();
473
469
 
474
470
  const { rerender } = render(
@@ -487,7 +483,7 @@ describe.each( [
487
483
 
488
484
  // As alpha (first tab), and beta (the initial tab), are both
489
485
  // disabled the first enabled tab should be gamma.
490
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
486
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
491
487
 
492
488
  // Re-enable all tabs
493
489
  rerender(
@@ -501,10 +497,10 @@ describe.each( [
501
497
 
502
498
  // Even if the initial tab becomes enabled again, the selected tab doesn't
503
499
  // change.
504
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
500
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
505
501
  } );
506
502
 
507
- it( 'should select the first enabled tab when the selected tab becomes disabled', () => {
503
+ it( 'should select the first enabled tab when the selected tab becomes disabled', async () => {
508
504
  const mockOnSelect = jest.fn();
509
505
  const { rerender } = render(
510
506
  <Component
@@ -514,7 +510,7 @@ describe.each( [
514
510
  />
515
511
  );
516
512
 
517
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
513
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
518
514
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
519
515
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
520
516
 
@@ -531,7 +527,7 @@ describe.each( [
531
527
  />
532
528
  );
533
529
 
534
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
530
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
535
531
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
536
532
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
537
533
 
@@ -543,12 +539,12 @@ describe.each( [
543
539
  />
544
540
  );
545
541
 
546
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
542
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
547
543
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
548
544
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
549
545
  } );
550
546
 
551
- it( 'should select the first enabled tab when the tab associated to `initialTabName` becomes disabled while being the active tab', () => {
547
+ it( 'should select the first enabled tab when the tab associated to `initialTabName` becomes disabled while being the active tab', async () => {
552
548
  const mockOnSelect = jest.fn();
553
549
 
554
550
  const { rerender } = render(
@@ -560,7 +556,7 @@ describe.each( [
560
556
  />
561
557
  );
562
558
 
563
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
559
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
564
560
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
565
561
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
566
562
 
@@ -577,7 +573,7 @@ describe.each( [
577
573
  />
578
574
  );
579
575
 
580
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
576
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
581
577
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
582
578
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
583
579
 
@@ -590,7 +586,7 @@ describe.each( [
590
586
  />
591
587
  );
592
588
 
593
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
589
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
594
590
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
595
591
  } );
596
592
  } );
@@ -610,31 +606,28 @@ describe.each( [
610
606
  );
611
607
 
612
608
  // Alpha is the initially selected tab
613
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
609
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
614
610
  expect(
615
- screen.getByRole( 'tabpanel', { name: 'Alpha' } )
611
+ await screen.findByRole( 'tabpanel', { name: 'Alpha' } )
616
612
  ).toBeInTheDocument();
617
- expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 0 ] );
618
613
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
619
614
 
620
615
  // Click on Beta, make sure beta is the selected tab
621
616
  await user.click( screen.getByRole( 'tab', { name: 'Beta' } ) );
622
617
 
623
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
618
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
624
619
  expect(
625
620
  screen.getByRole( 'tabpanel', { name: 'Beta' } )
626
621
  ).toBeInTheDocument();
627
- expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 1 ] );
628
622
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
629
623
 
630
624
  // Click on Alpha, make sure beta is the selected tab
631
625
  await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) );
632
626
 
633
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
627
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
634
628
  expect(
635
629
  screen.getByRole( 'tabpanel', { name: 'Alpha' } )
636
630
  ).toBeInTheDocument();
637
- expect( panelRenderFunction ).toHaveBeenLastCalledWith( TABS[ 0 ] );
638
631
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
639
632
  } );
640
633
 
@@ -654,24 +647,24 @@ describe.each( [
654
647
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
655
648
 
656
649
  // Tab to focus the tablist. Make sure alpha is focused.
657
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
658
- await expect( getSelectedTab() ).not.toHaveFocus();
650
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
651
+ expect( await getSelectedTab() ).not.toHaveFocus();
659
652
  await user.keyboard( '[Tab]' );
660
- await expect( getSelectedTab() ).toHaveFocus();
653
+ expect( await getSelectedTab() ).toHaveFocus();
661
654
 
662
655
  // Navigate forward with arrow keys and make sure the Beta tab is
663
656
  // selected automatically.
664
657
  await user.keyboard( '[ArrowRight]' );
665
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
666
- await expect( getSelectedTab() ).toHaveFocus();
658
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
659
+ expect( await getSelectedTab() ).toHaveFocus();
667
660
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
668
661
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
669
662
 
670
663
  // Navigate backwards with arrow keys. Make sure alpha is
671
664
  // selected automatically.
672
665
  await user.keyboard( '[ArrowLeft]' );
673
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
674
- await expect( getSelectedTab() ).toHaveFocus();
666
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
667
+ expect( await getSelectedTab() ).toHaveFocus();
675
668
  expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
676
669
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
677
670
  } );
@@ -692,24 +685,24 @@ describe.each( [
692
685
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
693
686
 
694
687
  // Tab to focus the tablist. Make sure Alpha is focused.
695
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
696
- await expect( getSelectedTab() ).not.toHaveFocus();
688
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
689
+ expect( await getSelectedTab() ).not.toHaveFocus();
697
690
  await user.keyboard( '[Tab]' );
698
- await expect( getSelectedTab() ).toHaveFocus();
691
+ expect( await getSelectedTab() ).toHaveFocus();
699
692
 
700
693
  // Navigate backwards with arrow keys and make sure that the Gamma tab
701
694
  // (the last tab) is selected automatically.
702
695
  await user.keyboard( '[ArrowLeft]' );
703
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
704
- await expect( getSelectedTab() ).toHaveFocus();
696
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
697
+ expect( await getSelectedTab() ).toHaveFocus();
705
698
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
706
699
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
707
700
 
708
701
  // Navigate forward with arrow keys. Make sure alpha (the first tab) is
709
702
  // selected automatically.
710
703
  await user.keyboard( '[ArrowRight]' );
711
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
712
- await expect( getSelectedTab() ).toHaveFocus();
704
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
705
+ expect( await getSelectedTab() ).toHaveFocus();
713
706
  expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
714
707
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
715
708
  } );
@@ -730,22 +723,22 @@ describe.each( [
730
723
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
731
724
 
732
725
  // Tab to focus the tablist. Make sure alpha is focused.
733
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
734
- await expect( getSelectedTab() ).not.toHaveFocus();
726
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
727
+ expect( await getSelectedTab() ).not.toHaveFocus();
735
728
  await user.keyboard( '[Tab]' );
736
- await expect( getSelectedTab() ).toHaveFocus();
729
+ expect( await getSelectedTab() ).toHaveFocus();
737
730
 
738
731
  // Press the arrow up key, nothing happens.
739
732
  await user.keyboard( '[ArrowUp]' );
740
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
741
- await expect( getSelectedTab() ).toHaveFocus();
733
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
734
+ expect( await getSelectedTab() ).toHaveFocus();
742
735
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
743
736
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
744
737
 
745
738
  // Press the arrow down key, nothing happens
746
739
  await user.keyboard( '[ArrowDown]' );
747
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
748
- await expect( getSelectedTab() ).toHaveFocus();
740
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
741
+ expect( await getSelectedTab() ).toHaveFocus();
749
742
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
750
743
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
751
744
 
@@ -766,38 +759,38 @@ describe.each( [
766
759
  );
767
760
 
768
761
  // Make sure alpha is still focused.
769
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
770
- await expect( getSelectedTab() ).toHaveFocus();
762
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
763
+ expect( await getSelectedTab() ).toHaveFocus();
771
764
 
772
765
  // Navigate forward with arrow keys and make sure the Beta tab is
773
766
  // selected automatically.
774
767
  await user.keyboard( '[ArrowDown]' );
775
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
776
- await expect( getSelectedTab() ).toHaveFocus();
768
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
769
+ expect( await getSelectedTab() ).toHaveFocus();
777
770
  expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
778
771
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
779
772
 
780
773
  // Navigate backwards with arrow keys. Make sure alpha is
781
774
  // selected automatically.
782
775
  await user.keyboard( '[ArrowUp]' );
783
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
784
- await expect( getSelectedTab() ).toHaveFocus();
776
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
777
+ expect( await getSelectedTab() ).toHaveFocus();
785
778
  expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
786
779
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
787
780
 
788
781
  // Navigate backwards with arrow keys. Make sure alpha is
789
782
  // selected automatically.
790
783
  await user.keyboard( '[ArrowUp]' );
791
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
792
- await expect( getSelectedTab() ).toHaveFocus();
784
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
785
+ expect( await getSelectedTab() ).toHaveFocus();
793
786
  expect( mockOnSelect ).toHaveBeenCalledTimes( 4 );
794
787
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
795
788
 
796
789
  // Navigate backwards with arrow keys. Make sure alpha is
797
790
  // selected automatically.
798
791
  await user.keyboard( '[ArrowDown]' );
799
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
800
- await expect( getSelectedTab() ).toHaveFocus();
792
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
793
+ expect( await getSelectedTab() ).toHaveFocus();
801
794
  expect( mockOnSelect ).toHaveBeenCalledTimes( 5 );
802
795
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
803
796
  } );
@@ -826,10 +819,10 @@ describe.each( [
826
819
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
827
820
 
828
821
  // Tab to focus the tablist. Make sure Alpha is focused.
829
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
830
- await expect( getSelectedTab() ).not.toHaveFocus();
822
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
823
+ expect( await getSelectedTab() ).not.toHaveFocus();
831
824
  await user.keyboard( '[Tab]' );
832
- await expect( getSelectedTab() ).toHaveFocus();
825
+ expect( await getSelectedTab() ).toHaveFocus();
833
826
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
834
827
 
835
828
  // Press the right arrow key three times. Since the delta tab is disabled:
@@ -838,26 +831,48 @@ describe.each( [
838
831
  // `mockOnSelect` function gets called only twice (and not three times)
839
832
  // - it will receive focus, when using arrow keys
840
833
  await user.keyboard( '[ArrowRight][ArrowRight][ArrowRight]' );
841
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
842
- await expect(
834
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
835
+ expect(
843
836
  screen.getByRole( 'tab', { name: 'Delta' } )
844
837
  ).toHaveFocus();
845
838
  expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
846
839
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
847
840
 
848
841
  // Navigate backwards with arrow keys. The gamma tab receives focus.
842
+ // The `mockOnSelect` callback doesn't fire, since the gamma tab was
843
+ // already selected.
849
844
  await user.keyboard( '[ArrowLeft]' );
850
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
851
- await expect( getSelectedTab() ).toHaveFocus();
852
- expect( mockOnSelect ).toHaveBeenCalledTimes( 4 );
845
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
846
+ expect( await getSelectedTab() ).toHaveFocus();
847
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
853
848
 
854
- // Click on on the disabled tab. Compared to using arrow keys to move the
849
+ // Click on the disabled tab. Compared to using arrow keys to move the
855
850
  // focus, disabled tabs ignore pointer clicks — and therefore, they don't
856
851
  // receive focus, nor they cause the `mockOnSelect` function to fire.
857
852
  await user.click( screen.getByRole( 'tab', { name: 'Delta' } ) );
858
- expect( getSelectedTab() ).toHaveTextContent( 'Gamma' );
859
- await expect( getSelectedTab() ).toHaveFocus();
860
- expect( mockOnSelect ).toHaveBeenCalledTimes( 4 );
853
+ expect( await getSelectedTab() ).toHaveTextContent( 'Gamma' );
854
+ expect( await getSelectedTab() ).toHaveFocus();
855
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
856
+ } );
857
+
858
+ it( 'should not focus the next tab when the Tab key is pressed', async () => {
859
+ const user = userEvent.setup();
860
+
861
+ render( <Component tabs={ TABS } children={ () => undefined } /> );
862
+
863
+ // Tab should initially focus the first tab in the tablist, which
864
+ // is Alpha.
865
+ await user.keyboard( '[Tab]' );
866
+ expect(
867
+ await screen.findByRole( 'tab', { name: 'Alpha' } )
868
+ ).toHaveFocus();
869
+
870
+ // Because all other tabs should have `tabindex=-1`, pressing Tab
871
+ // should NOT move the focus to the next tab, which is Beta.
872
+ await user.keyboard( '[Tab]' );
873
+ expect(
874
+ await screen.findByRole( 'tab', { name: 'Beta' } )
875
+ ).not.toHaveFocus();
861
876
  } );
862
877
 
863
878
  it( 'switches to manual tab activation when the `selectOnMove` prop is set to `false`', async () => {
@@ -873,47 +888,51 @@ describe.each( [
873
888
  />
874
889
  );
875
890
 
876
- // onSelect gets called on the initial render.
891
+ // onSelect gets called on the initial render with the default
892
+ // selected tab.
877
893
  expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
878
894
 
879
895
  // Click on Alpha and make sure it is selected.
896
+ // onSelect shouldn't fire since the selected tab didn't change.
880
897
  await user.click( screen.getByRole( 'tab', { name: 'Alpha' } ) );
881
- expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
898
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
882
899
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'alpha' );
883
900
 
884
901
  // Navigate forward with arrow keys. Make sure Beta is focused, but
885
902
  // that the tab selection happens only when pressing the spacebar
886
903
  // or enter key.
887
904
  await user.keyboard( '[ArrowRight]' );
888
- expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
889
- expect( screen.getByRole( 'tab', { name: 'Beta' } ) ).toHaveFocus();
905
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 1 );
906
+ expect(
907
+ await screen.findByRole( 'tab', { name: 'Beta' } )
908
+ ).toHaveFocus();
890
909
 
891
910
  await user.keyboard( '[Enter]' );
892
- expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
911
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
893
912
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'beta' );
894
913
 
895
914
  // Navigate forward with arrow keys. Make sure Gamma (last tab) is
896
915
  // focused, but that tab selection happens only when pressing the
897
916
  // spacebar or enter key.
898
917
  await user.keyboard( '[ArrowRight]' );
899
- expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
918
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 2 );
900
919
  expect(
901
920
  screen.getByRole( 'tab', { name: 'Gamma' } )
902
921
  ).toHaveFocus();
903
922
 
904
923
  await user.keyboard( '[Space]' );
905
- expect( mockOnSelect ).toHaveBeenCalledTimes( 4 );
924
+ expect( mockOnSelect ).toHaveBeenCalledTimes( 3 );
906
925
  expect( mockOnSelect ).toHaveBeenLastCalledWith( 'gamma' );
907
926
  } );
908
927
  } );
909
928
 
910
929
  describe( 'Tab Attributes', () => {
911
- it( "should apply the tab's `className` to the tab button", () => {
930
+ it( "should apply the tab's `className` to the tab button", async () => {
912
931
  render( <Component tabs={ TABS } children={ () => undefined } /> );
913
932
 
914
- expect( screen.getByRole( 'tab', { name: 'Alpha' } ) ).toHaveClass(
915
- 'alpha-class'
916
- );
933
+ expect(
934
+ await screen.findByRole( 'tab', { name: 'Alpha' } )
935
+ ).toHaveClass( 'alpha-class' );
917
936
  expect( screen.getByRole( 'tab', { name: 'Beta' } ) ).toHaveClass(
918
937
  'beta-class'
919
938
  );
@@ -935,8 +954,8 @@ describe.each( [
935
954
  );
936
955
 
937
956
  // Make sure that only the selected tab has the active class
938
- expect( getSelectedTab() ).toHaveTextContent( 'Alpha' );
939
- expect( getSelectedTab() ).toHaveClass( activeClass );
957
+ expect( await getSelectedTab() ).toHaveTextContent( 'Alpha' );
958
+ expect( await getSelectedTab() ).toHaveClass( activeClass );
940
959
  screen
941
960
  .getAllByRole( 'tab', { selected: false } )
942
961
  .forEach( ( unselectedTab ) => {
@@ -947,8 +966,8 @@ describe.each( [
947
966
  await user.click( screen.getByRole( 'tab', { name: 'Beta' } ) );
948
967
 
949
968
  // Make sure that only the selected tab has the active class
950
- expect( getSelectedTab() ).toHaveTextContent( 'Beta' );
951
- expect( getSelectedTab() ).toHaveClass( activeClass );
969
+ expect( await getSelectedTab() ).toHaveTextContent( 'Beta' );
970
+ expect( await getSelectedTab() ).toHaveClass( activeClass );
952
971
  screen
953
972
  .getAllByRole( 'tab', { selected: false } )
954
973
  .forEach( ( unselectedTab ) => {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import type { MouseEvent, ReactNode } from 'react';
4
+ import type { ReactNode } from 'react';
5
5
 
6
6
  /**
7
7
  * Internal dependencies
@@ -31,15 +31,6 @@ type Tab = {
31
31
  disabled?: boolean;
32
32
  } & Record< any, any >;
33
33
 
34
- export type TabButtonProps = {
35
- children: ReactNode;
36
- label?: string;
37
- onClick: ( event: MouseEvent ) => void;
38
- selected: boolean;
39
- showTooltip?: boolean;
40
- tabId: string;
41
- } & Pick< Tab, 'className' | 'icon' | 'disabled' >;
42
-
43
34
  export type TabPanelProps = {
44
35
  /**
45
36
  * The class name to add to the active tab.