@wordpress/components 27.0.0 → 27.1.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.
- package/CHANGELOG.md +22 -0
- package/build/base-control/index.native.js.map +1 -1
- package/build/border-box-control/border-box-control/component.js.map +1 -1
- package/build/border-box-control/border-box-control-split-controls/component.js.map +1 -1
- package/build/border-control/border-control-dropdown/component.js.map +1 -1
- package/build/button/index.js +2 -2
- package/build/button/index.js.map +1 -1
- package/build/button/index.native.js.map +1 -1
- package/build/confirm-dialog/component.js.map +1 -1
- package/build/custom-select-control-v2/default-component/index.js.map +1 -1
- package/build/custom-select-control-v2/index.js +2 -2
- package/build/custom-select-control-v2/index.js.map +1 -1
- package/build/custom-select-control-v2/types.js.map +1 -1
- package/build/draggable/index.native.js +2 -2
- package/build/draggable/index.native.js.map +1 -1
- package/build/dropdown-menu/index.native.js.map +1 -1
- package/build/flex/flex/hook.js +1 -1
- package/build/flex/flex/hook.js.map +1 -1
- package/build/font-size-picker/index.native.js.map +1 -1
- package/build/form-token-field/index.js.map +1 -1
- package/build/h-stack/hook.js +6 -1
- package/build/h-stack/hook.js.map +1 -1
- package/build/mobile/bottom-sheet/button.native.js.map +1 -1
- package/build/mobile/bottom-sheet/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet/range-cell.native.js.map +1 -1
- package/build/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
- package/build/mobile/gradient/index.native.js.map +1 -1
- package/build/mobile/image/index.native.js +4 -13
- package/build/mobile/image/index.native.js.map +1 -1
- package/build/mobile/media-edit/index.native.js.map +1 -1
- package/build/palette-edit/index.js.map +1 -1
- package/build/query-controls/index.native.js.map +1 -1
- package/build/range-control/index.js.map +1 -1
- package/build/search-control/index.native.js.map +1 -1
- package/build/snackbar/index.js +3 -2
- package/build/snackbar/index.js.map +1 -1
- package/build/snackbar/list.js +2 -1
- package/build/snackbar/list.js.map +1 -1
- package/build/snackbar/types.js.map +1 -1
- package/build/tabs/index.js +7 -7
- package/build/tabs/index.js.map +1 -1
- package/build/tabs/types.js.map +1 -1
- package/build/utils/hooks/index.js +0 -7
- package/build/utils/hooks/index.js.map +1 -1
- package/build-module/base-control/index.native.js.map +1 -1
- package/build-module/border-box-control/border-box-control/component.js.map +1 -1
- package/build-module/border-box-control/border-box-control-split-controls/component.js.map +1 -1
- package/build-module/border-control/border-control-dropdown/component.js.map +1 -1
- package/build-module/button/index.js +2 -2
- package/build-module/button/index.js.map +1 -1
- package/build-module/button/index.native.js.map +1 -1
- package/build-module/confirm-dialog/component.js.map +1 -1
- package/build-module/custom-select-control-v2/default-component/index.js.map +1 -1
- package/build-module/custom-select-control-v2/index.js +1 -1
- package/build-module/custom-select-control-v2/index.js.map +1 -1
- package/build-module/custom-select-control-v2/types.js.map +1 -1
- package/build-module/draggable/index.native.js +2 -2
- package/build-module/draggable/index.native.js.map +1 -1
- package/build-module/dropdown-menu/index.native.js.map +1 -1
- package/build-module/flex/flex/hook.js +1 -1
- package/build-module/flex/flex/hook.js.map +1 -1
- package/build-module/font-size-picker/index.native.js.map +1 -1
- package/build-module/form-token-field/index.js.map +1 -1
- package/build-module/h-stack/hook.js +6 -1
- package/build-module/h-stack/hook.js.map +1 -1
- package/build-module/mobile/bottom-sheet/button.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/range-cell.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
- package/build-module/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
- package/build-module/mobile/gradient/index.native.js.map +1 -1
- package/build-module/mobile/image/index.native.js +6 -15
- package/build-module/mobile/image/index.native.js.map +1 -1
- package/build-module/mobile/media-edit/index.native.js.map +1 -1
- package/build-module/palette-edit/index.js.map +1 -1
- package/build-module/query-controls/index.native.js.map +1 -1
- package/build-module/range-control/index.js.map +1 -1
- package/build-module/search-control/index.native.js.map +1 -1
- package/build-module/snackbar/index.js +3 -2
- package/build-module/snackbar/index.js.map +1 -1
- package/build-module/snackbar/list.js +2 -1
- package/build-module/snackbar/list.js.map +1 -1
- package/build-module/snackbar/types.js.map +1 -1
- package/build-module/tabs/index.js +7 -7
- package/build-module/tabs/index.js.map +1 -1
- package/build-module/tabs/types.js.map +1 -1
- package/build-module/utils/hooks/index.js +0 -1
- package/build-module/utils/hooks/index.js.map +1 -1
- package/build-style/style-rtl.css +8 -1
- package/build-style/style.css +8 -1
- package/build-types/custom-select-control-v2/default-component/index.d.ts +2 -1
- package/build-types/custom-select-control-v2/default-component/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/index.d.ts +1 -1
- package/build-types/custom-select-control-v2/index.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/legacy-component/test/index.d.ts +2 -0
- package/build-types/custom-select-control-v2/legacy-component/test/index.d.ts.map +1 -0
- package/build-types/custom-select-control-v2/stories/default.story.d.ts +4 -3
- package/build-types/custom-select-control-v2/stories/default.story.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/stories/legacy.story.d.ts +2 -2
- package/build-types/custom-select-control-v2/stories/legacy.story.d.ts.map +1 -1
- package/build-types/custom-select-control-v2/types.d.ts +0 -1
- package/build-types/custom-select-control-v2/types.d.ts.map +1 -1
- package/build-types/flex/flex/hook.d.ts +2 -3
- package/build-types/flex/flex/hook.d.ts.map +1 -1
- package/build-types/h-stack/hook.d.ts +2 -4
- package/build-types/h-stack/hook.d.ts.map +1 -1
- package/build-types/navigation/stories/utils/hide-if-empty.d.ts.map +1 -1
- package/build-types/radio-group/stories/index.story.d.ts.map +1 -1
- package/build-types/snackbar/index.d.ts +5 -2
- package/build-types/snackbar/index.d.ts.map +1 -1
- package/build-types/snackbar/list.d.ts.map +1 -1
- package/build-types/snackbar/test/index.d.ts +2 -0
- package/build-types/snackbar/test/index.d.ts.map +1 -0
- package/build-types/snackbar/test/list.d.ts +2 -0
- package/build-types/snackbar/test/list.d.ts.map +1 -0
- package/build-types/snackbar/types.d.ts +18 -2
- package/build-types/snackbar/types.d.ts.map +1 -1
- package/build-types/tabs/index.d.ts +1 -1
- package/build-types/tabs/types.d.ts +1 -1
- package/build-types/utils/hooks/index.d.ts +0 -1
- package/build-types/v-stack/hook.d.ts +2 -4
- package/build-types/v-stack/hook.d.ts.map +1 -1
- package/package.json +19 -19
- package/src/base-control/index.native.js +1 -1
- package/src/base-control/test/index.tsx +1 -1
- package/src/border-box-control/border-box-control/component.tsx +1 -1
- package/src/border-box-control/border-box-control-split-controls/component.tsx +4 -4
- package/src/border-control/border-control-dropdown/component.tsx +1 -1
- package/src/button/index.native.js +1 -1
- package/src/button/index.tsx +1 -1
- package/src/button/style.scss +1 -3
- package/src/circular-option-picker/test/index.tsx +2 -4
- package/src/combobox-control/test/index.tsx +1 -1
- package/src/confirm-dialog/component.tsx +1 -1
- package/src/confirm-dialog/test/index.tsx +5 -21
- package/src/custom-select-control-v2/default-component/index.tsx +4 -1
- package/src/custom-select-control-v2/index.tsx +1 -1
- package/src/custom-select-control-v2/legacy-component/test/index.tsx +457 -0
- package/src/custom-select-control-v2/stories/legacy.story.tsx +5 -6
- package/src/custom-select-control-v2/test/index.tsx +279 -749
- package/src/custom-select-control-v2/types.ts +0 -1
- package/src/disabled/test/index.tsx +1 -1
- package/src/draggable/index.native.js +2 -2
- package/src/draggable/test/index.native.js +6 -2
- package/src/dropdown-menu/index.native.js +2 -2
- package/src/flex/flex/hook.ts +1 -1
- package/src/font-size-picker/index.native.js +2 -2
- package/src/form-token-field/index.tsx +1 -1
- package/src/h-stack/hook.tsx +2 -1
- package/src/h-stack/test/index.tsx +10 -0
- package/src/item-group/test/index.js +2 -2
- package/src/mobile/bottom-sheet/bottom-sheet-navigation/test/navigation-container.native.js +10 -15
- package/src/mobile/bottom-sheet/button.native.js +1 -5
- package/src/mobile/bottom-sheet/index.native.js +2 -2
- package/src/mobile/bottom-sheet/range-cell.native.js +1 -1
- package/src/mobile/bottom-sheet/stepper-cell/index.native.js +2 -2
- package/src/mobile/bottom-sheet-select-control/index.native.js +1 -1
- package/src/mobile/bottom-sheet-text-control/index.native.js +1 -1
- package/src/mobile/gradient/index.native.js +1 -1
- package/src/mobile/image/index.native.js +8 -23
- package/src/mobile/media-edit/index.native.js +1 -1
- package/src/modal/test/index.tsx +1 -1
- package/src/navigation/stories/utils/hide-if-empty.tsx +2 -6
- package/src/palette-edit/index.tsx +2 -2
- package/src/popover/test/index.tsx +1 -4
- package/src/query-controls/index.native.js +2 -2
- package/src/radio-group/stories/index.story.tsx +1 -0
- package/src/range-control/index.tsx +3 -3
- package/src/range-control/test/index.tsx +2 -2
- package/src/search-control/index.native.js +1 -1
- package/src/snackbar/index.tsx +5 -2
- package/src/snackbar/list.tsx +6 -1
- package/src/snackbar/stories/list.story.tsx +0 -3
- package/src/snackbar/test/index.tsx +267 -0
- package/src/snackbar/test/list.tsx +46 -0
- package/src/snackbar/types.ts +31 -3
- package/src/tabs/README.md +18 -18
- package/src/tabs/index.tsx +7 -7
- package/src/tabs/stories/index.story.tsx +1 -1
- package/src/tabs/test/index.tsx +30 -30
- package/src/tabs/types.ts +1 -1
- package/src/toggle-group-control/test/index.tsx +1 -1
- package/src/tools-panel/stories/index.story.tsx +8 -8
- package/src/tools-panel/test/index.tsx +10 -28
- package/src/tooltip/style.scss +2 -1
- package/src/tooltip/test/index.native.js +3 -3
- package/src/tree-grid/test/index.tsx +1 -1
- package/src/utils/hooks/index.js +0 -1
- package/src/v-stack/test/index.tsx +10 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/build/custom-select-control-v2/legacy-adapter.js +0 -29
- package/build/custom-select-control-v2/legacy-adapter.js.map +0 -1
- package/build/utils/hooks/use-latest-ref.js +0 -33
- package/build/utils/hooks/use-latest-ref.js.map +0 -1
- package/build-module/custom-select-control-v2/legacy-adapter.js +0 -21
- package/build-module/custom-select-control-v2/legacy-adapter.js.map +0 -1
- package/build-module/utils/hooks/use-latest-ref.js +0 -27
- package/build-module/utils/hooks/use-latest-ref.js.map +0 -1
- package/build-types/custom-select-control-v2/legacy-adapter.d.ts +0 -6
- package/build-types/custom-select-control-v2/legacy-adapter.d.ts.map +0 -1
- package/build-types/utils/hooks/use-latest-ref.d.ts +0 -15
- package/build-types/utils/hooks/use-latest-ref.d.ts.map +0 -1
- package/src/custom-select-control-v2/legacy-adapter.tsx +0 -25
- package/src/utils/hooks/test/use-latest-ref.js +0 -119
- package/src/utils/hooks/use-latest-ref.ts +0 -29
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { click, press, sleep, type, waitFor } from '@ariakit/test';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WordPress dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { useState } from '@wordpress/element';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
import UncontrolledCustomSelect from '..';
|
|
16
|
+
|
|
17
|
+
const customClass = 'amber-skies';
|
|
18
|
+
|
|
19
|
+
const legacyProps = {
|
|
20
|
+
label: 'label!',
|
|
21
|
+
options: [
|
|
22
|
+
{
|
|
23
|
+
key: 'flower1',
|
|
24
|
+
name: 'violets',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
key: 'flower2',
|
|
28
|
+
name: 'crimson clover',
|
|
29
|
+
className: customClass,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'flower3',
|
|
33
|
+
name: 'poppy',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: 'color1',
|
|
37
|
+
name: 'amber',
|
|
38
|
+
className: customClass,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: 'color2',
|
|
42
|
+
name: 'aquamarine',
|
|
43
|
+
style: {
|
|
44
|
+
backgroundColor: 'rgb(127, 255, 212)',
|
|
45
|
+
rotate: '13deg',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const LegacyControlledCustomSelect = ( {
|
|
52
|
+
options,
|
|
53
|
+
onChange,
|
|
54
|
+
...restProps
|
|
55
|
+
}: React.ComponentProps< typeof UncontrolledCustomSelect > ) => {
|
|
56
|
+
const [ value, setValue ] = useState( options[ 0 ] );
|
|
57
|
+
return (
|
|
58
|
+
<UncontrolledCustomSelect
|
|
59
|
+
{ ...restProps }
|
|
60
|
+
options={ options }
|
|
61
|
+
onChange={ ( args: any ) => {
|
|
62
|
+
onChange?.( args );
|
|
63
|
+
setValue( args.selectedItem );
|
|
64
|
+
} }
|
|
65
|
+
value={ options.find(
|
|
66
|
+
( option: any ) => option.key === value.key
|
|
67
|
+
) }
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
describe.each( [
|
|
73
|
+
[ 'Uncontrolled', UncontrolledCustomSelect ],
|
|
74
|
+
[ 'Controlled', LegacyControlledCustomSelect ],
|
|
75
|
+
] )( 'CustomSelectControl (%s)', ( ...modeAndComponent ) => {
|
|
76
|
+
const [ , Component ] = modeAndComponent;
|
|
77
|
+
|
|
78
|
+
it( 'Should replace the initial selection when a new item is selected', async () => {
|
|
79
|
+
render( <Component { ...legacyProps } /> );
|
|
80
|
+
|
|
81
|
+
const currentSelectedItem = screen.getByRole( 'combobox', {
|
|
82
|
+
expanded: false,
|
|
83
|
+
} );
|
|
84
|
+
|
|
85
|
+
await click( currentSelectedItem );
|
|
86
|
+
|
|
87
|
+
await click(
|
|
88
|
+
screen.getByRole( 'option', {
|
|
89
|
+
name: 'crimson clover',
|
|
90
|
+
} )
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
expect( currentSelectedItem ).toHaveTextContent( 'crimson clover' );
|
|
94
|
+
|
|
95
|
+
await click( currentSelectedItem );
|
|
96
|
+
|
|
97
|
+
await click(
|
|
98
|
+
screen.getByRole( 'option', {
|
|
99
|
+
name: 'poppy',
|
|
100
|
+
} )
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect( currentSelectedItem ).toHaveTextContent( 'poppy' );
|
|
104
|
+
} );
|
|
105
|
+
|
|
106
|
+
it( 'Should keep current selection if dropdown is closed without changing selection', async () => {
|
|
107
|
+
render( <Component { ...legacyProps } /> );
|
|
108
|
+
|
|
109
|
+
const currentSelectedItem = screen.getByRole( 'combobox', {
|
|
110
|
+
expanded: false,
|
|
111
|
+
} );
|
|
112
|
+
|
|
113
|
+
await sleep();
|
|
114
|
+
await press.Tab();
|
|
115
|
+
await press.Enter();
|
|
116
|
+
expect(
|
|
117
|
+
screen.getByRole( 'listbox', {
|
|
118
|
+
name: 'label!',
|
|
119
|
+
} )
|
|
120
|
+
).toBeVisible();
|
|
121
|
+
|
|
122
|
+
await press.Escape();
|
|
123
|
+
expect(
|
|
124
|
+
screen.queryByRole( 'listbox', {
|
|
125
|
+
name: 'label!',
|
|
126
|
+
} )
|
|
127
|
+
).not.toBeInTheDocument();
|
|
128
|
+
|
|
129
|
+
expect( currentSelectedItem ).toHaveTextContent(
|
|
130
|
+
legacyProps.options[ 0 ].name
|
|
131
|
+
);
|
|
132
|
+
} );
|
|
133
|
+
|
|
134
|
+
it( 'Should apply class only to options that have a className defined', async () => {
|
|
135
|
+
render( <Component { ...legacyProps } /> );
|
|
136
|
+
|
|
137
|
+
await click(
|
|
138
|
+
screen.getByRole( 'combobox', {
|
|
139
|
+
expanded: false,
|
|
140
|
+
} )
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
// return an array of items _with_ a className added
|
|
144
|
+
const itemsWithClass = legacyProps.options.filter(
|
|
145
|
+
( option ) => option.className !== undefined
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// assert against filtered array
|
|
149
|
+
itemsWithClass.map( ( { name } ) =>
|
|
150
|
+
expect( screen.getByRole( 'option', { name } ) ).toHaveClass(
|
|
151
|
+
customClass
|
|
152
|
+
)
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// return an array of items _without_ a className added
|
|
156
|
+
const itemsWithoutClass = legacyProps.options.filter(
|
|
157
|
+
( option ) => option.className === undefined
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
// assert against filtered array
|
|
161
|
+
itemsWithoutClass.map( ( { name } ) =>
|
|
162
|
+
expect( screen.getByRole( 'option', { name } ) ).not.toHaveClass(
|
|
163
|
+
customClass
|
|
164
|
+
)
|
|
165
|
+
);
|
|
166
|
+
} );
|
|
167
|
+
|
|
168
|
+
it( 'Should apply styles only to options that have styles defined', async () => {
|
|
169
|
+
const customStyles =
|
|
170
|
+
'background-color: rgb(127, 255, 212); rotate: 13deg;';
|
|
171
|
+
|
|
172
|
+
render( <Component { ...legacyProps } /> );
|
|
173
|
+
|
|
174
|
+
await click(
|
|
175
|
+
screen.getByRole( 'combobox', {
|
|
176
|
+
expanded: false,
|
|
177
|
+
} )
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// return an array of items _with_ styles added
|
|
181
|
+
const styledItems = legacyProps.options.filter(
|
|
182
|
+
( option ) => option.style !== undefined
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// assert against filtered array
|
|
186
|
+
styledItems.map( ( { name } ) =>
|
|
187
|
+
expect( screen.getByRole( 'option', { name } ) ).toHaveStyle(
|
|
188
|
+
customStyles
|
|
189
|
+
)
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
// return an array of items _without_ styles added
|
|
193
|
+
const unstyledItems = legacyProps.options.filter(
|
|
194
|
+
( option ) => option.style === undefined
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// assert against filtered array
|
|
198
|
+
unstyledItems.map( ( { name } ) =>
|
|
199
|
+
expect( screen.getByRole( 'option', { name } ) ).not.toHaveStyle(
|
|
200
|
+
customStyles
|
|
201
|
+
)
|
|
202
|
+
);
|
|
203
|
+
} );
|
|
204
|
+
|
|
205
|
+
it( 'does not show selected hint by default', async () => {
|
|
206
|
+
render(
|
|
207
|
+
<Component
|
|
208
|
+
{ ...legacyProps }
|
|
209
|
+
label="Custom select"
|
|
210
|
+
options={ [
|
|
211
|
+
{
|
|
212
|
+
key: 'one',
|
|
213
|
+
name: 'One',
|
|
214
|
+
__experimentalHint: 'Hint',
|
|
215
|
+
},
|
|
216
|
+
] }
|
|
217
|
+
/>
|
|
218
|
+
);
|
|
219
|
+
await waitFor( () =>
|
|
220
|
+
expect(
|
|
221
|
+
screen.getByRole( 'combobox', { name: 'Custom select' } )
|
|
222
|
+
).not.toHaveTextContent( 'Hint' )
|
|
223
|
+
);
|
|
224
|
+
} );
|
|
225
|
+
|
|
226
|
+
it( 'shows selected hint when __experimentalShowSelectedHint is set', async () => {
|
|
227
|
+
render(
|
|
228
|
+
<Component
|
|
229
|
+
{ ...legacyProps }
|
|
230
|
+
label="Custom select"
|
|
231
|
+
options={ [
|
|
232
|
+
{
|
|
233
|
+
key: 'one',
|
|
234
|
+
name: 'One',
|
|
235
|
+
__experimentalHint: 'Hint',
|
|
236
|
+
},
|
|
237
|
+
] }
|
|
238
|
+
__experimentalShowSelectedHint
|
|
239
|
+
/>
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
await waitFor( () =>
|
|
243
|
+
expect(
|
|
244
|
+
screen.getByRole( 'combobox', {
|
|
245
|
+
expanded: false,
|
|
246
|
+
} )
|
|
247
|
+
).toHaveTextContent( /hint/i )
|
|
248
|
+
);
|
|
249
|
+
} );
|
|
250
|
+
|
|
251
|
+
it( 'shows selected hint in list of options when added', async () => {
|
|
252
|
+
render(
|
|
253
|
+
<Component
|
|
254
|
+
{ ...legacyProps }
|
|
255
|
+
label="Custom select"
|
|
256
|
+
options={ [
|
|
257
|
+
{
|
|
258
|
+
key: 'one',
|
|
259
|
+
name: 'One',
|
|
260
|
+
__experimentalHint: 'Hint',
|
|
261
|
+
},
|
|
262
|
+
] }
|
|
263
|
+
__experimentalShowSelectedHint
|
|
264
|
+
/>
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
await click(
|
|
268
|
+
screen.getByRole( 'combobox', { name: 'Custom select' } )
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
expect( screen.getByRole( 'option', { name: /hint/i } ) ).toBeVisible();
|
|
272
|
+
} );
|
|
273
|
+
|
|
274
|
+
it( 'Should return object onChange', async () => {
|
|
275
|
+
const mockOnChange = jest.fn();
|
|
276
|
+
|
|
277
|
+
render( <Component { ...legacyProps } onChange={ mockOnChange } /> );
|
|
278
|
+
|
|
279
|
+
await click(
|
|
280
|
+
screen.getByRole( 'combobox', {
|
|
281
|
+
expanded: false,
|
|
282
|
+
} )
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
expect( mockOnChange ).toHaveBeenNthCalledWith(
|
|
286
|
+
1,
|
|
287
|
+
expect.objectContaining( {
|
|
288
|
+
inputValue: '',
|
|
289
|
+
isOpen: false,
|
|
290
|
+
selectedItem: { key: 'violets', name: 'violets' },
|
|
291
|
+
type: '',
|
|
292
|
+
} )
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
await click(
|
|
296
|
+
screen.getByRole( 'option', {
|
|
297
|
+
name: 'aquamarine',
|
|
298
|
+
} )
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
expect( mockOnChange ).toHaveBeenNthCalledWith(
|
|
302
|
+
2,
|
|
303
|
+
expect.objectContaining( {
|
|
304
|
+
inputValue: '',
|
|
305
|
+
isOpen: false,
|
|
306
|
+
selectedItem: expect.objectContaining( {
|
|
307
|
+
name: 'aquamarine',
|
|
308
|
+
} ),
|
|
309
|
+
type: '',
|
|
310
|
+
} )
|
|
311
|
+
);
|
|
312
|
+
} );
|
|
313
|
+
|
|
314
|
+
it( 'Should return selectedItem object when specified onChange', async () => {
|
|
315
|
+
const mockOnChange = jest.fn(
|
|
316
|
+
( { selectedItem } ) => selectedItem.key
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
render( <Component { ...legacyProps } onChange={ mockOnChange } /> );
|
|
320
|
+
|
|
321
|
+
await sleep();
|
|
322
|
+
await press.Tab();
|
|
323
|
+
expect(
|
|
324
|
+
screen.getByRole( 'combobox', {
|
|
325
|
+
expanded: false,
|
|
326
|
+
} )
|
|
327
|
+
).toHaveFocus();
|
|
328
|
+
|
|
329
|
+
await type( 'p' );
|
|
330
|
+
await press.Enter();
|
|
331
|
+
|
|
332
|
+
expect( mockOnChange ).toHaveReturnedWith( 'poppy' );
|
|
333
|
+
} );
|
|
334
|
+
|
|
335
|
+
describe( 'Keyboard behavior and accessibility', () => {
|
|
336
|
+
it( 'Should be able to change selection using keyboard', async () => {
|
|
337
|
+
render( <Component { ...legacyProps } /> );
|
|
338
|
+
|
|
339
|
+
const currentSelectedItem = screen.getByRole( 'combobox', {
|
|
340
|
+
expanded: false,
|
|
341
|
+
} );
|
|
342
|
+
|
|
343
|
+
await sleep();
|
|
344
|
+
await press.Tab();
|
|
345
|
+
expect( currentSelectedItem ).toHaveFocus();
|
|
346
|
+
|
|
347
|
+
await press.Enter();
|
|
348
|
+
expect(
|
|
349
|
+
screen.getByRole( 'listbox', {
|
|
350
|
+
name: 'label!',
|
|
351
|
+
} )
|
|
352
|
+
).toHaveFocus();
|
|
353
|
+
|
|
354
|
+
await press.ArrowDown();
|
|
355
|
+
await press.Enter();
|
|
356
|
+
|
|
357
|
+
expect( currentSelectedItem ).toHaveTextContent( 'crimson clover' );
|
|
358
|
+
} );
|
|
359
|
+
|
|
360
|
+
it( 'Should be able to type characters to select matching options', async () => {
|
|
361
|
+
render( <Component { ...legacyProps } /> );
|
|
362
|
+
|
|
363
|
+
const currentSelectedItem = screen.getByRole( 'combobox', {
|
|
364
|
+
expanded: false,
|
|
365
|
+
} );
|
|
366
|
+
|
|
367
|
+
await sleep();
|
|
368
|
+
await press.Tab();
|
|
369
|
+
await press.Enter();
|
|
370
|
+
expect(
|
|
371
|
+
screen.getByRole( 'listbox', {
|
|
372
|
+
name: 'label!',
|
|
373
|
+
} )
|
|
374
|
+
).toHaveFocus();
|
|
375
|
+
|
|
376
|
+
await type( 'a' );
|
|
377
|
+
await press.Enter();
|
|
378
|
+
expect( currentSelectedItem ).toHaveTextContent( 'amber' );
|
|
379
|
+
} );
|
|
380
|
+
|
|
381
|
+
it( 'Can change selection with a focused input and closed dropdown if typed characters match an option', async () => {
|
|
382
|
+
render( <Component { ...legacyProps } /> );
|
|
383
|
+
|
|
384
|
+
const currentSelectedItem = screen.getByRole( 'combobox', {
|
|
385
|
+
expanded: false,
|
|
386
|
+
} );
|
|
387
|
+
|
|
388
|
+
await sleep();
|
|
389
|
+
await press.Tab();
|
|
390
|
+
expect( currentSelectedItem ).toHaveFocus();
|
|
391
|
+
|
|
392
|
+
await type( 'aq' );
|
|
393
|
+
|
|
394
|
+
expect(
|
|
395
|
+
screen.queryByRole( 'listbox', {
|
|
396
|
+
name: 'label!',
|
|
397
|
+
hidden: true,
|
|
398
|
+
} )
|
|
399
|
+
).not.toBeInTheDocument();
|
|
400
|
+
|
|
401
|
+
await press.Enter();
|
|
402
|
+
expect( currentSelectedItem ).toHaveTextContent( 'aquamarine' );
|
|
403
|
+
} );
|
|
404
|
+
|
|
405
|
+
it( 'Should have correct aria-selected value for selections', async () => {
|
|
406
|
+
render( <Component { ...legacyProps } /> );
|
|
407
|
+
|
|
408
|
+
const currentSelectedItem = screen.getByRole( 'combobox', {
|
|
409
|
+
expanded: false,
|
|
410
|
+
} );
|
|
411
|
+
|
|
412
|
+
await click( currentSelectedItem );
|
|
413
|
+
|
|
414
|
+
// get all items except for first option
|
|
415
|
+
const unselectedItems = legacyProps.options.filter(
|
|
416
|
+
( { name } ) => name !== legacyProps.options[ 0 ].name
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
// assert that all other items have aria-selected="false"
|
|
420
|
+
unselectedItems.map( ( { name } ) =>
|
|
421
|
+
expect(
|
|
422
|
+
screen.getByRole( 'option', { name, selected: false } )
|
|
423
|
+
).toBeVisible()
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
// assert that first item has aria-selected="true"
|
|
427
|
+
expect(
|
|
428
|
+
screen.getByRole( 'option', {
|
|
429
|
+
name: legacyProps.options[ 0 ].name,
|
|
430
|
+
selected: true,
|
|
431
|
+
} )
|
|
432
|
+
).toBeVisible();
|
|
433
|
+
|
|
434
|
+
// change the current selection
|
|
435
|
+
await click( screen.getByRole( 'option', { name: 'poppy' } ) );
|
|
436
|
+
|
|
437
|
+
// click combobox to mount listbox with options again
|
|
438
|
+
await click( currentSelectedItem );
|
|
439
|
+
|
|
440
|
+
// check that first item is has aria-selected="false" after new selection
|
|
441
|
+
expect(
|
|
442
|
+
screen.getByRole( 'option', {
|
|
443
|
+
name: legacyProps.options[ 0 ].name,
|
|
444
|
+
selected: false,
|
|
445
|
+
} )
|
|
446
|
+
).toBeVisible();
|
|
447
|
+
|
|
448
|
+
// check that new selected item now has aria-selected="true"
|
|
449
|
+
expect(
|
|
450
|
+
screen.getByRole( 'option', {
|
|
451
|
+
name: 'poppy',
|
|
452
|
+
selected: true,
|
|
453
|
+
} )
|
|
454
|
+
).toBeVisible();
|
|
455
|
+
} );
|
|
456
|
+
} );
|
|
457
|
+
} );
|
|
@@ -11,12 +11,11 @@ import { useState } from '@wordpress/element';
|
|
|
11
11
|
/**
|
|
12
12
|
* Internal dependencies
|
|
13
13
|
*/
|
|
14
|
-
import
|
|
15
|
-
import { CustomSelect } from '..';
|
|
14
|
+
import CustomSelect from '../legacy-component';
|
|
16
15
|
|
|
17
|
-
const meta: Meta< typeof
|
|
16
|
+
const meta: Meta< typeof CustomSelect > = {
|
|
18
17
|
title: 'Components (Experimental)/CustomSelectControl v2/Legacy',
|
|
19
|
-
component:
|
|
18
|
+
component: CustomSelect,
|
|
20
19
|
argTypes: {
|
|
21
20
|
onChange: { control: { type: null } },
|
|
22
21
|
value: { control: { type: null } },
|
|
@@ -43,11 +42,11 @@ const meta: Meta< typeof _LegacyCustomSelect > = {
|
|
|
43
42
|
};
|
|
44
43
|
export default meta;
|
|
45
44
|
|
|
46
|
-
const Template: StoryFn< typeof
|
|
45
|
+
const Template: StoryFn< typeof CustomSelect > = ( props ) => {
|
|
47
46
|
const [ fontSize, setFontSize ] = useState( props.options[ 0 ] );
|
|
48
47
|
|
|
49
48
|
const onChange: React.ComponentProps<
|
|
50
|
-
typeof
|
|
49
|
+
typeof CustomSelect
|
|
51
50
|
>[ 'onChange' ] = ( changeObject ) => {
|
|
52
51
|
setFontSize( changeObject.selectedItem );
|
|
53
52
|
props.onChange?.( changeObject );
|