@wordpress/components 21.0.5 → 21.0.7
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.
- package/CHANGELOG.md +19 -0
- package/build/autocomplete/index.js +11 -9
- package/build/autocomplete/index.js.map +1 -1
- package/build/circular-option-picker/index.js +14 -14
- package/build/circular-option-picker/index.js.map +1 -1
- package/build/color-palette/index.js +83 -30
- package/build/color-palette/index.js.map +1 -1
- package/build/color-palette/styles.js +3 -3
- package/build/color-palette/styles.js.map +1 -1
- package/build/color-palette/types.js +6 -0
- package/build/color-palette/types.js.map +1 -0
- package/build/font-size-picker/index.js +1 -1
- package/build/font-size-picker/index.js.map +1 -1
- package/build/form-token-field/index.js +12 -10
- package/build/form-token-field/index.js.map +1 -1
- package/build/navigator/navigator-provider/component.js +5 -3
- package/build/navigator/navigator-provider/component.js.map +1 -1
- package/build/navigator/navigator-screen/component.js +5 -3
- package/build/navigator/navigator-screen/component.js.map +1 -1
- package/build/popover/index.js +1 -26
- package/build/popover/index.js.map +1 -1
- package/build-module/autocomplete/index.js +10 -9
- package/build-module/autocomplete/index.js.map +1 -1
- package/build-module/circular-option-picker/index.js +14 -14
- package/build-module/circular-option-picker/index.js.map +1 -1
- package/build-module/color-palette/index.js +81 -28
- package/build-module/color-palette/index.js.map +1 -1
- package/build-module/color-palette/styles.js +3 -3
- package/build-module/color-palette/styles.js.map +1 -1
- package/build-module/color-palette/types.js +2 -0
- package/build-module/color-palette/types.js.map +1 -0
- package/build-module/font-size-picker/index.js +1 -1
- package/build-module/font-size-picker/index.js.map +1 -1
- package/build-module/form-token-field/index.js +11 -10
- package/build-module/form-token-field/index.js.map +1 -1
- package/build-module/navigator/navigator-provider/component.js +5 -3
- package/build-module/navigator/navigator-provider/component.js.map +1 -1
- package/build-module/navigator/navigator-screen/component.js +5 -3
- package/build-module/navigator/navigator-screen/component.js.map +1 -1
- package/build-module/popover/index.js +1 -26
- package/build-module/popover/index.js.map +1 -1
- package/build-types/border-control/types.d.ts +1 -1
- package/build-types/border-control/types.d.ts.map +1 -1
- package/build-types/circular-option-picker/index.d.ts +4 -24
- package/build-types/circular-option-picker/index.d.ts.map +1 -1
- package/build-types/color-palette/index.d.ts +33 -18
- package/build-types/color-palette/index.d.ts.map +1 -1
- package/build-types/color-palette/stories/index.d.ts +21 -0
- package/build-types/color-palette/stories/index.d.ts.map +1 -0
- package/build-types/color-palette/styles.d.ts +2 -1
- package/build-types/color-palette/styles.d.ts.map +1 -1
- package/build-types/color-palette/test/index.d.ts +2 -0
- package/build-types/color-palette/test/index.d.ts.map +1 -0
- package/build-types/color-palette/types.d.ts +86 -0
- package/build-types/color-palette/types.d.ts.map +1 -0
- package/build-types/confirm-dialog/component.d.ts +4 -4
- package/build-types/form-token-field/index.d.ts.map +1 -1
- package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
- package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
- package/build-types/navigator/types.d.ts +1 -0
- package/build-types/navigator/types.d.ts.map +1 -1
- package/build-types/popover/index.d.ts.map +1 -1
- package/build-types/popover/types.d.ts +0 -14
- package/build-types/popover/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/autocomplete/index.js +18 -9
- package/src/border-control/types.ts +1 -1
- package/src/circular-option-picker/index.js +14 -20
- package/src/color-palette/README.md +51 -49
- package/src/color-palette/{index.js → index.tsx} +132 -51
- package/src/color-palette/stories/{index.js → index.tsx} +38 -27
- package/src/color-palette/{styles.js → styles.ts} +0 -0
- package/src/color-palette/test/__snapshots__/index.tsx.snap +270 -0
- package/src/color-palette/test/index.tsx +164 -0
- package/src/color-palette/types.ts +93 -0
- package/src/font-size-picker/index.js +1 -1
- package/src/form-token-field/index.tsx +21 -10
- package/src/form-token-field/test/index.tsx +167 -73
- package/src/navigator/navigator-provider/component.tsx +2 -0
- package/src/navigator/navigator-screen/component.tsx +9 -1
- package/src/navigator/types.ts +1 -0
- package/src/popover/README.md +3 -9
- package/src/popover/index.tsx +1 -25
- package/src/popover/types.ts +0 -14
- package/tsconfig.tsbuildinfo +1 -1
- package/src/color-palette/test/__snapshots__/index.js.snap +0 -1207
- package/src/color-palette/test/index.js +0 -118
|
@@ -2,12 +2,27 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
|
+
fireEvent,
|
|
5
6
|
render,
|
|
6
7
|
screen,
|
|
7
8
|
within,
|
|
8
9
|
getDefaultNormalizer,
|
|
9
10
|
waitFor,
|
|
10
11
|
} from '@testing-library/react';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* WordPress dependencies
|
|
15
|
+
*/
|
|
16
|
+
import {
|
|
17
|
+
BACKSPACE,
|
|
18
|
+
ENTER,
|
|
19
|
+
UP,
|
|
20
|
+
DOWN,
|
|
21
|
+
LEFT,
|
|
22
|
+
RIGHT,
|
|
23
|
+
DELETE,
|
|
24
|
+
ESCAPE,
|
|
25
|
+
} from '@wordpress/keycodes';
|
|
11
26
|
import userEvent from '@testing-library/user-event';
|
|
12
27
|
import type { ComponentProps } from 'react';
|
|
13
28
|
|
|
@@ -21,6 +36,54 @@ import { useState } from '@wordpress/element';
|
|
|
21
36
|
*/
|
|
22
37
|
import FormTokenField from '../';
|
|
23
38
|
|
|
39
|
+
function triggerEnter( element: Element ) {
|
|
40
|
+
fireEvent.keyDown( element, {
|
|
41
|
+
keyCode: ENTER,
|
|
42
|
+
} );
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function triggerBackspace( element: Element ) {
|
|
46
|
+
fireEvent.keyDown( element, {
|
|
47
|
+
keyCode: BACKSPACE,
|
|
48
|
+
} );
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function triggerArrowRight( element: Element ) {
|
|
52
|
+
fireEvent.keyDown( element, {
|
|
53
|
+
keyCode: RIGHT,
|
|
54
|
+
} );
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function triggerArrowLeft( element: Element ) {
|
|
58
|
+
fireEvent.keyDown( element, {
|
|
59
|
+
keyCode: LEFT,
|
|
60
|
+
} );
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function triggerArrowUp( element: Element ) {
|
|
64
|
+
fireEvent.keyDown( element, {
|
|
65
|
+
keyCode: UP,
|
|
66
|
+
} );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function triggerArrowDown( element: Element ) {
|
|
70
|
+
fireEvent.keyDown( element, {
|
|
71
|
+
keyCode: DOWN,
|
|
72
|
+
} );
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function triggerDelete( element: Element ) {
|
|
76
|
+
fireEvent.keyDown( element, {
|
|
77
|
+
keyCode: DELETE,
|
|
78
|
+
} );
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function triggerEscape( element: Element ) {
|
|
82
|
+
fireEvent.keyDown( element, {
|
|
83
|
+
keyCode: ESCAPE,
|
|
84
|
+
} );
|
|
85
|
+
}
|
|
86
|
+
|
|
24
87
|
const FormTokenFieldWithState = ( {
|
|
25
88
|
onChange,
|
|
26
89
|
value,
|
|
@@ -118,13 +181,15 @@ describe( 'FormTokenField', () => {
|
|
|
118
181
|
const input = screen.getByRole( 'combobox' );
|
|
119
182
|
|
|
120
183
|
// Add 'apple' token by typing it and pressing enter to tokenize it.
|
|
121
|
-
await user.type( input, 'apple
|
|
184
|
+
await user.type( input, 'apple' );
|
|
185
|
+
triggerEnter( input );
|
|
122
186
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
123
187
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'apple' ] );
|
|
124
188
|
expectTokensToBeInTheDocument( [ 'apple' ] );
|
|
125
189
|
|
|
126
190
|
// Add 'pear' token by typing it and pressing enter to tokenize it.
|
|
127
|
-
await user.type( input, 'pear
|
|
191
|
+
await user.type( input, 'pear' );
|
|
192
|
+
triggerEnter( input );
|
|
128
193
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
129
194
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [
|
|
130
195
|
'apple',
|
|
@@ -165,7 +230,8 @@ describe( 'FormTokenField', () => {
|
|
|
165
230
|
const input = screen.getByRole( 'combobox' );
|
|
166
231
|
|
|
167
232
|
// Add 'dragon fruit' token by typing it and pressing enter to tokenize it.
|
|
168
|
-
await user.type( input, 'dragon fruit
|
|
233
|
+
await user.type( input, 'dragon fruit' );
|
|
234
|
+
triggerEnter( input );
|
|
169
235
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
170
236
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'dragon fruit' ] );
|
|
171
237
|
expectTokensToBeInTheDocument( [ 'dragon fruit' ] );
|
|
@@ -179,7 +245,8 @@ describe( 'FormTokenField', () => {
|
|
|
179
245
|
|
|
180
246
|
// Add 'dragon fruit' token by typing it and pressing enter to tokenize it,
|
|
181
247
|
// this time two separate tokens should be added
|
|
182
|
-
await user.type( input, 'dragon fruit
|
|
248
|
+
await user.type( input, 'dragon fruit' );
|
|
249
|
+
triggerEnter( input );
|
|
183
250
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
|
|
184
251
|
expect( onChangeSpy ).toHaveBeenNthCalledWith( 2, [
|
|
185
252
|
'dragon fruit',
|
|
@@ -216,10 +283,6 @@ describe( 'FormTokenField', () => {
|
|
|
216
283
|
} );
|
|
217
284
|
|
|
218
285
|
it( 'should remove the last token when pressing the backspace key', async () => {
|
|
219
|
-
const user = userEvent.setup( {
|
|
220
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
221
|
-
} );
|
|
222
|
-
|
|
223
286
|
const onChangeSpy = jest.fn();
|
|
224
287
|
|
|
225
288
|
render(
|
|
@@ -232,14 +295,15 @@ describe( 'FormTokenField', () => {
|
|
|
232
295
|
const input = screen.getByRole( 'combobox' );
|
|
233
296
|
|
|
234
297
|
// Press backspace to remove the last token ("mango")
|
|
235
|
-
|
|
298
|
+
input.focus();
|
|
299
|
+
triggerBackspace( input );
|
|
236
300
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
237
301
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [ 'banana' ] );
|
|
238
302
|
expectTokensToBeInTheDocument( [ 'banana' ] );
|
|
239
303
|
expectTokensNotToBeInTheDocument( [ 'mango' ] );
|
|
240
304
|
|
|
241
305
|
// Press backspace to remove the last token ("banana")
|
|
242
|
-
|
|
306
|
+
triggerBackspace( input );
|
|
243
307
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
244
308
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [] );
|
|
245
309
|
expectTokensNotToBeInTheDocument( [ 'banana', 'mango' ] );
|
|
@@ -343,23 +407,21 @@ describe( 'FormTokenField', () => {
|
|
|
343
407
|
const input = screen.getByRole( 'combobox' );
|
|
344
408
|
|
|
345
409
|
// Add 'guava' token by typing it and pressing enter to tokenize it.
|
|
346
|
-
await user.type( input, 'guava
|
|
410
|
+
await user.type( input, 'guava' );
|
|
411
|
+
triggerEnter( input );
|
|
347
412
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
348
413
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'papaya', 'guava' ] );
|
|
349
414
|
expectTokensToBeInTheDocument( [ 'papaya', 'guava' ] );
|
|
350
415
|
|
|
351
416
|
// Try to add a 'papaya' token by typing it and pressing enter to tokenize it,
|
|
352
417
|
// but the token won't be added because it already exists.
|
|
353
|
-
await user.type( input, 'papaya
|
|
418
|
+
await user.type( input, 'papaya' );
|
|
419
|
+
triggerEnter( input );
|
|
354
420
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
355
421
|
expectTokensToBeInTheDocument( [ 'papaya', 'guava' ] );
|
|
356
422
|
} );
|
|
357
423
|
|
|
358
424
|
it( 'should not add a new token if the text input is blank', async () => {
|
|
359
|
-
const user = userEvent.setup( {
|
|
360
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
361
|
-
} );
|
|
362
|
-
|
|
363
425
|
const onChangeSpy = jest.fn();
|
|
364
426
|
|
|
365
427
|
render(
|
|
@@ -372,7 +434,9 @@ describe( 'FormTokenField', () => {
|
|
|
372
434
|
const input = screen.getByRole( 'combobox' );
|
|
373
435
|
|
|
374
436
|
// Press enter on an empty input, no token gets added
|
|
375
|
-
|
|
437
|
+
input.focus();
|
|
438
|
+
triggerEnter( input );
|
|
439
|
+
|
|
376
440
|
expect( onChangeSpy ).not.toHaveBeenCalled();
|
|
377
441
|
expectTokensToBeInTheDocument( [ 'melon' ] );
|
|
378
442
|
} );
|
|
@@ -381,7 +445,6 @@ describe( 'FormTokenField', () => {
|
|
|
381
445
|
const user = userEvent.setup( {
|
|
382
446
|
advanceTimers: jest.advanceTimersByTime,
|
|
383
447
|
} );
|
|
384
|
-
|
|
385
448
|
const onChangeSpy = jest.fn();
|
|
386
449
|
|
|
387
450
|
render(
|
|
@@ -402,12 +465,14 @@ describe( 'FormTokenField', () => {
|
|
|
402
465
|
|
|
403
466
|
// Press "delete" to delete the token in front of the cursor, but since
|
|
404
467
|
// there's no token in front of the cursor, nothing happens
|
|
405
|
-
|
|
468
|
+
input.focus();
|
|
469
|
+
triggerDelete( input );
|
|
406
470
|
|
|
407
471
|
// Pressing the right arrow doesn't move the cursor because there are no
|
|
408
472
|
// tokens in front of it, and therefore pressing "delete" yields the same
|
|
409
473
|
// result as before — no tokens are deleted.
|
|
410
|
-
|
|
474
|
+
triggerArrowRight( input );
|
|
475
|
+
triggerDelete( input );
|
|
411
476
|
|
|
412
477
|
// Proof that so far, all keyboard interactions didn't delete any tokens.
|
|
413
478
|
expect( onChangeSpy ).not.toHaveBeenCalled();
|
|
@@ -421,10 +486,12 @@ describe( 'FormTokenField', () => {
|
|
|
421
486
|
// Press the left arrow 4 times, moving cursor between the "kiwi" and
|
|
422
487
|
// "peach" tokens. Pressing the "delete" key will delete the "peach"
|
|
423
488
|
// token, since it's in front of the cursor.
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
);
|
|
489
|
+
triggerArrowLeft( input );
|
|
490
|
+
triggerArrowLeft( input );
|
|
491
|
+
triggerArrowLeft( input );
|
|
492
|
+
triggerArrowLeft( input );
|
|
493
|
+
triggerDelete( input );
|
|
494
|
+
|
|
428
495
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
429
496
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
430
497
|
'peach',
|
|
@@ -440,20 +507,21 @@ describe( 'FormTokenField', () => {
|
|
|
440
507
|
|
|
441
508
|
// Press backspace to delete the token before the cursor, but since
|
|
442
509
|
// there's no token before the cursor, nothing happens
|
|
443
|
-
|
|
510
|
+
triggerBackspace( input );
|
|
444
511
|
|
|
445
512
|
// Pressing the left arrow doesn't move the cursor because there are no
|
|
446
513
|
// tokens before it, and therefore pressing backspace yields the same
|
|
447
514
|
// result as before — no tokens are deleted.
|
|
448
|
-
|
|
449
|
-
|
|
515
|
+
triggerArrowLeft( input );
|
|
516
|
+
triggerBackspace( input );
|
|
450
517
|
// Proof that pressing backspace hasn't caused any further token deletion.
|
|
451
518
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
452
519
|
|
|
453
520
|
// Press the right arrow, moving cursor between the "kiwi" and
|
|
454
521
|
// "nectarine" tokens. Pressing the "delete" key will delete the "nectarine"
|
|
455
522
|
// token, since it's in front of the cursor.
|
|
456
|
-
|
|
523
|
+
triggerArrowRight( input );
|
|
524
|
+
triggerDelete( input );
|
|
457
525
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
458
526
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
459
527
|
'peach',
|
|
@@ -464,7 +532,8 @@ describe( 'FormTokenField', () => {
|
|
|
464
532
|
|
|
465
533
|
// Add 'starfruit' token while the cursor is in between the "peach" and
|
|
466
534
|
// "coconut" tokens.
|
|
467
|
-
await user.type( input, 'starfruit
|
|
535
|
+
await user.type( input, 'starfruit' );
|
|
536
|
+
triggerEnter( input );
|
|
468
537
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
|
|
469
538
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
470
539
|
'peach',
|
|
@@ -619,7 +688,8 @@ describe( 'FormTokenField', () => {
|
|
|
619
688
|
const input = screen.getByRole( 'combobox' );
|
|
620
689
|
|
|
621
690
|
// Add 'blueberry' token. The placeholder text should not be shown anymore
|
|
622
|
-
await user.type( input, 'blueberry
|
|
691
|
+
await user.type( input, 'blueberry' );
|
|
692
|
+
triggerEnter( input );
|
|
623
693
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
624
694
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'blueberry' ] );
|
|
625
695
|
expectTokensToBeInTheDocument( [ 'blueberry' ] );
|
|
@@ -646,7 +716,8 @@ describe( 'FormTokenField', () => {
|
|
|
646
716
|
const input = screen.getByRole( 'combobox' );
|
|
647
717
|
|
|
648
718
|
// Add 'عربى' token by typing it and pressing enter to tokenize it.
|
|
649
|
-
await user.type( input, 'عربى
|
|
719
|
+
await user.type( input, 'عربى' );
|
|
720
|
+
triggerEnter( input );
|
|
650
721
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
651
722
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
652
723
|
'français',
|
|
@@ -833,7 +904,7 @@ describe( 'FormTokenField', () => {
|
|
|
833
904
|
).toHaveLength( 0 );
|
|
834
905
|
|
|
835
906
|
// Pressing the down arrow will select "Salmon"
|
|
836
|
-
|
|
907
|
+
triggerArrowDown( input );
|
|
837
908
|
|
|
838
909
|
expect(
|
|
839
910
|
within( suggestionList ).getByRole( 'option', {
|
|
@@ -843,7 +914,7 @@ describe( 'FormTokenField', () => {
|
|
|
843
914
|
|
|
844
915
|
// Pressing the up arrow will select "Neon" (the selection wraps around
|
|
845
916
|
// the list)
|
|
846
|
-
|
|
917
|
+
triggerArrowUp( input );
|
|
847
918
|
|
|
848
919
|
expect(
|
|
849
920
|
within( suggestionList ).getByRole( 'option', {
|
|
@@ -853,7 +924,8 @@ describe( 'FormTokenField', () => {
|
|
|
853
924
|
|
|
854
925
|
// Pressing the down arrow twice will select "Carnation" (the selection
|
|
855
926
|
// wraps around the list)
|
|
856
|
-
|
|
927
|
+
triggerArrowDown( input );
|
|
928
|
+
triggerArrowDown( input );
|
|
857
929
|
|
|
858
930
|
expect(
|
|
859
931
|
within( suggestionList ).getByRole( 'option', {
|
|
@@ -862,7 +934,7 @@ describe( 'FormTokenField', () => {
|
|
|
862
934
|
).toHaveAccessibleName( 'Carnation' );
|
|
863
935
|
|
|
864
936
|
// Pressing enter will add "Carnation" as a token and close the suggestion list
|
|
865
|
-
|
|
937
|
+
triggerEnter( input );
|
|
866
938
|
|
|
867
939
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
868
940
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'Carnation' ] );
|
|
@@ -972,7 +1044,7 @@ describe( 'FormTokenField', () => {
|
|
|
972
1044
|
expect( screen.getByRole( 'listbox' ) ).toBeVisible();
|
|
973
1045
|
|
|
974
1046
|
// Pressing the ESC key will close the suggestion list
|
|
975
|
-
|
|
1047
|
+
triggerEscape( input );
|
|
976
1048
|
|
|
977
1049
|
expect( screen.queryByRole( 'listbox' ) ).not.toBeInTheDocument();
|
|
978
1050
|
expect( onChangeSpy ).not.toHaveBeenCalled();
|
|
@@ -1174,8 +1246,10 @@ describe( 'FormTokenField', () => {
|
|
|
1174
1246
|
/>
|
|
1175
1247
|
);
|
|
1176
1248
|
|
|
1249
|
+
const input = screen.getByRole( 'combobox' );
|
|
1250
|
+
|
|
1177
1251
|
// Type "woo". Matching suggestion will be "Wood"
|
|
1178
|
-
await user.type(
|
|
1252
|
+
await user.type( input, 'woo' );
|
|
1179
1253
|
|
|
1180
1254
|
// The `__experimentalRenderItem` only affects the rendered suggestion,
|
|
1181
1255
|
// but doesn't change the underlying data `value`, nor the value
|
|
@@ -1184,7 +1258,8 @@ describe( 'FormTokenField', () => {
|
|
|
1184
1258
|
'Suggestion: Wood',
|
|
1185
1259
|
] );
|
|
1186
1260
|
|
|
1187
|
-
|
|
1261
|
+
triggerArrowDown( input );
|
|
1262
|
+
triggerEnter( input );
|
|
1188
1263
|
|
|
1189
1264
|
expectTokensToBeInTheDocument( [ 'Wood' ] );
|
|
1190
1265
|
} );
|
|
@@ -1213,7 +1288,8 @@ describe( 'FormTokenField', () => {
|
|
|
1213
1288
|
|
|
1214
1289
|
const input = screen.getByRole( 'combobox' );
|
|
1215
1290
|
|
|
1216
|
-
await user.type( input, 'Italy
|
|
1291
|
+
await user.type( input, 'Italy' );
|
|
1292
|
+
triggerEnter( input );
|
|
1217
1293
|
|
|
1218
1294
|
expect( onChangeSpy ).not.toHaveBeenCalled();
|
|
1219
1295
|
|
|
@@ -1318,12 +1394,13 @@ describe( 'FormTokenField', () => {
|
|
|
1318
1394
|
const input = screen.getByRole( 'combobox' );
|
|
1319
1395
|
|
|
1320
1396
|
// Press enter on an empty input, no token gets added
|
|
1321
|
-
|
|
1397
|
+
triggerEnter( input );
|
|
1322
1398
|
expect( onChangeSpy ).not.toHaveBeenCalled();
|
|
1323
1399
|
expectTokensToBeInTheDocument( [ 'potato' ] );
|
|
1324
1400
|
|
|
1325
1401
|
// Add the "carrot" token - white space gets trimmed
|
|
1326
|
-
await user.type( input, ' carrot
|
|
1402
|
+
await user.type( input, ' carrot ' );
|
|
1403
|
+
triggerEnter( input );
|
|
1327
1404
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1328
1405
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
1329
1406
|
'potato',
|
|
@@ -1333,12 +1410,14 @@ describe( 'FormTokenField', () => {
|
|
|
1333
1410
|
|
|
1334
1411
|
// Press enter on an input containing a duplicate token but surrounded by
|
|
1335
1412
|
// white space, no token gets added
|
|
1336
|
-
await user.type( input, ' potato
|
|
1413
|
+
await user.type( input, ' potato ' );
|
|
1414
|
+
triggerEnter( input );
|
|
1337
1415
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1338
1416
|
expectTokensToBeInTheDocument( [ 'potato', 'carrot' ] );
|
|
1339
1417
|
|
|
1340
1418
|
// Press enter on an input containing only spaces, no token gets added
|
|
1341
|
-
await user.type( input, '
|
|
1419
|
+
await user.type( input, ' ' );
|
|
1420
|
+
triggerEnter( input );
|
|
1342
1421
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1343
1422
|
expectTokensToBeInTheDocument( [ 'potato', 'carrot' ] );
|
|
1344
1423
|
|
|
@@ -1353,7 +1432,8 @@ describe( 'FormTokenField', () => {
|
|
|
1353
1432
|
// If a custom `saveTransform` function is passed, it will be the new
|
|
1354
1433
|
// function's duty to trim the whitespace if necessary.
|
|
1355
1434
|
await user.clear( input );
|
|
1356
|
-
await user.type( input, ' parnsnip
|
|
1435
|
+
await user.type( input, ' parnsnip ' );
|
|
1436
|
+
triggerEnter( input );
|
|
1357
1437
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
1358
1438
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
1359
1439
|
'potato',
|
|
@@ -1413,7 +1493,8 @@ describe( 'FormTokenField', () => {
|
|
|
1413
1493
|
// The saveTransform function will change its value to "medium jacket"
|
|
1414
1494
|
// when tokenizing it, thus affecting both the onChange callback and
|
|
1415
1495
|
// the text rendered in the document.
|
|
1416
|
-
await user.type( input, 'small jacket
|
|
1496
|
+
await user.type( input, 'small jacket' );
|
|
1497
|
+
triggerEnter( input );
|
|
1417
1498
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1418
1499
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
1419
1500
|
'small trousers',
|
|
@@ -1464,7 +1545,8 @@ describe( 'FormTokenField', () => {
|
|
|
1464
1545
|
|
|
1465
1546
|
// Selecting the suggestion will add the transformed value as a token,
|
|
1466
1547
|
// since the `saveTransform` function will be applied before tokenizing.
|
|
1467
|
-
|
|
1548
|
+
triggerArrowDown( input );
|
|
1549
|
+
triggerEnter( input );
|
|
1468
1550
|
|
|
1469
1551
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1470
1552
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [ 'Free food' ] );
|
|
@@ -1511,7 +1593,8 @@ describe( 'FormTokenField', () => {
|
|
|
1511
1593
|
// The displayTransform function will change its displayed value to
|
|
1512
1594
|
// "light red", but the onChange callback will still receive "dark red" as
|
|
1513
1595
|
// part of the component's new value.
|
|
1514
|
-
await user.type( input, 'dark red
|
|
1596
|
+
await user.type( input, 'dark red' );
|
|
1597
|
+
triggerEnter( input );
|
|
1515
1598
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1516
1599
|
expect( onChangeSpy ).toHaveBeenCalledWith( [
|
|
1517
1600
|
'dark blue',
|
|
@@ -1560,7 +1643,8 @@ describe( 'FormTokenField', () => {
|
|
|
1560
1643
|
'cold tea',
|
|
1561
1644
|
] );
|
|
1562
1645
|
|
|
1563
|
-
|
|
1646
|
+
triggerArrowDown( input );
|
|
1647
|
+
triggerEnter( input );
|
|
1564
1648
|
|
|
1565
1649
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1566
1650
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [ 'Hot coffee' ] );
|
|
@@ -1642,7 +1726,8 @@ describe( 'FormTokenField', () => {
|
|
|
1642
1726
|
const input = screen.getByRole( 'combobox' );
|
|
1643
1727
|
|
|
1644
1728
|
// Add 'cherry' token by typing it and pressing enter to tokenize it.
|
|
1645
|
-
await user.type( input, 'cherry
|
|
1729
|
+
await user.type( input, 'cherry' );
|
|
1730
|
+
triggerEnter( input );
|
|
1646
1731
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1647
1732
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'cherry' ] );
|
|
1648
1733
|
expectTokensToBeInTheDocument( [ 'cherry' ] );
|
|
@@ -1659,14 +1744,16 @@ describe( 'FormTokenField', () => {
|
|
|
1659
1744
|
// Note that the any token added before is still around, even if it
|
|
1660
1745
|
// wouldn't pass the newly added validation — this is because the
|
|
1661
1746
|
// validation happens when the input\'s value gets tokenized.
|
|
1662
|
-
await user.type( input, 'cranberry
|
|
1747
|
+
await user.type( input, 'cranberry' );
|
|
1748
|
+
triggerEnter( input );
|
|
1663
1749
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1664
1750
|
expectTokensToBeInTheDocument( [ 'cherry' ] );
|
|
1665
1751
|
expectTokensNotToBeInTheDocument( [ 'cranberry' ] );
|
|
1666
1752
|
|
|
1667
1753
|
// Retry, this time with capital letter. The value should be added.
|
|
1668
1754
|
await user.clear( input );
|
|
1669
|
-
await user.type( input, 'Cranberry
|
|
1755
|
+
await user.type( input, 'Cranberry' );
|
|
1756
|
+
triggerEnter( input );
|
|
1670
1757
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
1671
1758
|
expectTokensToBeInTheDocument( [ 'cherry', 'Cranberry' ] );
|
|
1672
1759
|
} );
|
|
@@ -1694,7 +1781,8 @@ describe( 'FormTokenField', () => {
|
|
|
1694
1781
|
|
|
1695
1782
|
// Try to add the 'hexagon' token, but because the number of tokens already
|
|
1696
1783
|
// matches `maxLength`, the token won't be added.
|
|
1697
|
-
await user.type( input, 'hexagon
|
|
1784
|
+
await user.type( input, 'hexagon' );
|
|
1785
|
+
triggerEnter( input );
|
|
1698
1786
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 0 );
|
|
1699
1787
|
expectTokensToBeInTheDocument( [ 'square', 'triangle', 'circle' ] );
|
|
1700
1788
|
expectTokensNotToBeInTheDocument( [ 'hexagon' ] );
|
|
@@ -1702,7 +1790,7 @@ describe( 'FormTokenField', () => {
|
|
|
1702
1790
|
// Delete the last token ("circle"), in order to make space for the
|
|
1703
1791
|
// hexagon token
|
|
1704
1792
|
await user.clear( input );
|
|
1705
|
-
|
|
1793
|
+
triggerBackspace( input );
|
|
1706
1794
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1707
1795
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [
|
|
1708
1796
|
'square',
|
|
@@ -1714,7 +1802,8 @@ describe( 'FormTokenField', () => {
|
|
|
1714
1802
|
// Try to add the 'hexagon' token again. This time, the token will be
|
|
1715
1803
|
// added because the current number of tokens is below the `maxLength`
|
|
1716
1804
|
// threshold.
|
|
1717
|
-
await user.type( input, 'hexagon
|
|
1805
|
+
await user.type( input, 'hexagon' );
|
|
1806
|
+
triggerEnter( input );
|
|
1718
1807
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 2 );
|
|
1719
1808
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [
|
|
1720
1809
|
'square',
|
|
@@ -1756,7 +1845,12 @@ describe( 'FormTokenField', () => {
|
|
|
1756
1845
|
|
|
1757
1846
|
const input = screen.getByRole( 'combobox' );
|
|
1758
1847
|
|
|
1759
|
-
await user.type( input, 'cube
|
|
1848
|
+
await user.type( input, 'cube' );
|
|
1849
|
+
triggerEnter( input );
|
|
1850
|
+
await user.type( input, 'sphere' );
|
|
1851
|
+
triggerEnter( input );
|
|
1852
|
+
await user.type( input, 'cylinder' );
|
|
1853
|
+
triggerEnter( input );
|
|
1760
1854
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
|
|
1761
1855
|
expect( onChangeSpy ).toHaveBeenLastCalledWith( [
|
|
1762
1856
|
'cube',
|
|
@@ -1780,7 +1874,8 @@ describe( 'FormTokenField', () => {
|
|
|
1780
1874
|
|
|
1781
1875
|
// Try to add the 'pyramid' token, but because the number of tokens already
|
|
1782
1876
|
// exceeds `maxLength`, the token won't be added.
|
|
1783
|
-
await user.type( input, 'pyramid
|
|
1877
|
+
await user.type( input, 'pyramid' );
|
|
1878
|
+
triggerEnter( input );
|
|
1784
1879
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 3 );
|
|
1785
1880
|
expectTokensToBeInTheDocument( [ 'cube', 'sphere', 'cylinder' ] );
|
|
1786
1881
|
expectTokensNotToBeInTheDocument( [ 'pyramid' ] );
|
|
@@ -1802,7 +1897,8 @@ describe( 'FormTokenField', () => {
|
|
|
1802
1897
|
const input = screen.getByRole( 'combobox' );
|
|
1803
1898
|
|
|
1804
1899
|
// Add 'sun' token by typing it and pressing enter to tokenize it.
|
|
1805
|
-
await user.type( input, 'sun
|
|
1900
|
+
await user.type( input, 'sun' );
|
|
1901
|
+
triggerEnter( input );
|
|
1806
1902
|
expect( onChangeSpy ).toHaveBeenCalledTimes( 1 );
|
|
1807
1903
|
expect( onChangeSpy ).toHaveBeenCalledWith( [ 'sun' ] );
|
|
1808
1904
|
expectTokensToBeInTheDocument( [ 'sun' ] );
|
|
@@ -1876,7 +1972,8 @@ describe( 'FormTokenField', () => {
|
|
|
1876
1972
|
const input = screen.getByRole( 'combobox' );
|
|
1877
1973
|
|
|
1878
1974
|
// Add 'cat' token, check that the aria-live region has been updated.
|
|
1879
|
-
await user.type( input, 'cat
|
|
1975
|
+
await user.type( input, 'cat' );
|
|
1976
|
+
triggerEnter( input );
|
|
1880
1977
|
|
|
1881
1978
|
expect( screen.getByText( defaultMessages.added ) ).toHaveAttribute(
|
|
1882
1979
|
'aria-live',
|
|
@@ -1894,7 +1991,8 @@ describe( 'FormTokenField', () => {
|
|
|
1894
1991
|
const input = screen.getByRole( 'combobox' );
|
|
1895
1992
|
|
|
1896
1993
|
// Add 'dog' token, check that the aria-live region has been updated.
|
|
1897
|
-
await user.type( input, 'dog
|
|
1994
|
+
await user.type( input, 'dog' );
|
|
1995
|
+
triggerEnter( input );
|
|
1898
1996
|
|
|
1899
1997
|
expect( screen.getByText( customMessages.added ) ).toHaveAttribute(
|
|
1900
1998
|
'aria-live',
|
|
@@ -1903,16 +2001,13 @@ describe( 'FormTokenField', () => {
|
|
|
1903
2001
|
} );
|
|
1904
2002
|
|
|
1905
2003
|
it( 'should announce to assistive technology the removal of a token', async () => {
|
|
1906
|
-
const user = userEvent.setup( {
|
|
1907
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
1908
|
-
} );
|
|
1909
|
-
|
|
1910
2004
|
render( <FormTokenFieldWithState initialValue={ [ 'horse' ] } /> );
|
|
1911
2005
|
|
|
1912
2006
|
const input = screen.getByRole( 'combobox' );
|
|
1913
2007
|
|
|
1914
2008
|
// Delete "horse" token
|
|
1915
|
-
|
|
2009
|
+
input.focus();
|
|
2010
|
+
triggerBackspace( input );
|
|
1916
2011
|
|
|
1917
2012
|
expect(
|
|
1918
2013
|
screen.getByText( defaultMessages.removed )
|
|
@@ -1920,10 +2015,6 @@ describe( 'FormTokenField', () => {
|
|
|
1920
2015
|
} );
|
|
1921
2016
|
|
|
1922
2017
|
it( 'should announce to assistive technology the removal of a token with a custom message', async () => {
|
|
1923
|
-
const user = userEvent.setup( {
|
|
1924
|
-
advanceTimers: jest.advanceTimersByTime,
|
|
1925
|
-
} );
|
|
1926
|
-
|
|
1927
2018
|
render(
|
|
1928
2019
|
<FormTokenFieldWithState
|
|
1929
2020
|
initialValue={ [ 'donkey' ] }
|
|
@@ -1934,7 +2025,8 @@ describe( 'FormTokenField', () => {
|
|
|
1934
2025
|
const input = screen.getByRole( 'combobox' );
|
|
1935
2026
|
|
|
1936
2027
|
// Delete "donkey" token
|
|
1937
|
-
|
|
2028
|
+
input.focus();
|
|
2029
|
+
triggerBackspace( input );
|
|
1938
2030
|
|
|
1939
2031
|
expect(
|
|
1940
2032
|
screen.getByText( customMessages.removed )
|
|
@@ -1956,7 +2048,8 @@ describe( 'FormTokenField', () => {
|
|
|
1956
2048
|
|
|
1957
2049
|
// Try to add "eagle" token, which won't be added because of the
|
|
1958
2050
|
// __experimentalValidateInput prop.
|
|
1959
|
-
await user.type( input, 'eagle
|
|
2051
|
+
await user.type( input, 'eagle' );
|
|
2052
|
+
triggerEnter( input );
|
|
1960
2053
|
|
|
1961
2054
|
expect(
|
|
1962
2055
|
screen.getByText( defaultMessages.__experimentalInvalid )
|
|
@@ -1979,7 +2072,8 @@ describe( 'FormTokenField', () => {
|
|
|
1979
2072
|
|
|
1980
2073
|
// Try to add "crocodile" token, which won't be added because of the
|
|
1981
2074
|
// __experimentalValidateInput prop.
|
|
1982
|
-
await user.type( input, 'crocodile
|
|
2075
|
+
await user.type( input, 'crocodile' );
|
|
2076
|
+
triggerEnter( input );
|
|
1983
2077
|
|
|
1984
2078
|
expect(
|
|
1985
2079
|
screen.getByText( customMessages.__experimentalInvalid )
|
|
@@ -2085,7 +2179,7 @@ describe( 'FormTokenField', () => {
|
|
|
2085
2179
|
|
|
2086
2180
|
// Select the "Pine" suggestion
|
|
2087
2181
|
await user.click( input );
|
|
2088
|
-
|
|
2182
|
+
triggerArrowDown( input );
|
|
2089
2183
|
|
|
2090
2184
|
const pineSuggestion = within( suggestionList ).getByRole(
|
|
2091
2185
|
'option',
|
|
@@ -2115,7 +2209,7 @@ describe( 'FormTokenField', () => {
|
|
|
2115
2209
|
);
|
|
2116
2210
|
|
|
2117
2211
|
// Add the suggestion, which hides the list
|
|
2118
|
-
|
|
2212
|
+
triggerEnter( input );
|
|
2119
2213
|
|
|
2120
2214
|
expect( screen.queryByRole( 'listbox' ) ).not.toBeInTheDocument();
|
|
2121
2215
|
|
|
@@ -49,6 +49,7 @@ function NavigatorProvider(
|
|
|
49
49
|
...options,
|
|
50
50
|
path,
|
|
51
51
|
isBack: false,
|
|
52
|
+
hasRestoredFocus: false,
|
|
52
53
|
},
|
|
53
54
|
] );
|
|
54
55
|
},
|
|
@@ -62,6 +63,7 @@ function NavigatorProvider(
|
|
|
62
63
|
{
|
|
63
64
|
...locationHistory[ locationHistory.length - 2 ],
|
|
64
65
|
isBack: true,
|
|
66
|
+
hasRestoredFocus: false,
|
|
65
67
|
},
|
|
66
68
|
] );
|
|
67
69
|
}
|
|
@@ -79,7 +79,13 @@ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) {
|
|
|
79
79
|
// - if the current location is not the initial one (to avoid moving focus on page load)
|
|
80
80
|
// - when the screen becomes visible
|
|
81
81
|
// - if the wrapper ref has been assigned
|
|
82
|
-
if
|
|
82
|
+
// - if focus hasn't already been restored for the current location
|
|
83
|
+
if (
|
|
84
|
+
isInitialLocation ||
|
|
85
|
+
! isMatch ||
|
|
86
|
+
! wrapperRef.current ||
|
|
87
|
+
location.hasRestoredFocus
|
|
88
|
+
) {
|
|
83
89
|
return;
|
|
84
90
|
}
|
|
85
91
|
|
|
@@ -103,10 +109,12 @@ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) {
|
|
|
103
109
|
elementToFocus = firstTabbable ?? wrapperRef.current;
|
|
104
110
|
}
|
|
105
111
|
|
|
112
|
+
location.hasRestoredFocus = true;
|
|
106
113
|
elementToFocus.focus();
|
|
107
114
|
}, [
|
|
108
115
|
isInitialLocation,
|
|
109
116
|
isMatch,
|
|
117
|
+
location.hasRestoredFocus,
|
|
110
118
|
location.isBack,
|
|
111
119
|
previousLocation?.focusTargetSelector,
|
|
112
120
|
] );
|