@patternfly/react-templates 6.0.0-alpha.9 → 6.0.0-prerelease.2

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 (109) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/README.md +4 -17
  3. package/components/package.json +1 -1
  4. package/dist/dynamic/components/Dropdown/package.json +1 -0
  5. package/dist/dynamic/components/Select/package.json +1 -1
  6. package/dist/dynamic-modules.json +19 -0
  7. package/dist/esm/components/Dropdown/SimpleDropdown.d.ts +48 -0
  8. package/dist/esm/components/Dropdown/SimpleDropdown.d.ts.map +1 -0
  9. package/dist/esm/components/Dropdown/SimpleDropdown.js +33 -0
  10. package/dist/esm/components/Dropdown/SimpleDropdown.js.map +1 -0
  11. package/dist/esm/components/Dropdown/index.d.ts +2 -0
  12. package/dist/esm/components/Dropdown/index.d.ts.map +1 -0
  13. package/dist/esm/components/Dropdown/index.js +2 -0
  14. package/dist/esm/components/Dropdown/index.js.map +1 -0
  15. package/dist/esm/components/Select/CheckboxSelect.d.ts +7 -3
  16. package/dist/esm/components/Select/CheckboxSelect.d.ts.map +1 -1
  17. package/dist/esm/components/Select/CheckboxSelect.js +14 -6
  18. package/dist/esm/components/Select/CheckboxSelect.js.map +1 -1
  19. package/dist/esm/components/Select/MultiTypeaheadSelect.d.ts +33 -0
  20. package/dist/esm/components/Select/MultiTypeaheadSelect.d.ts.map +1 -0
  21. package/dist/esm/components/Select/MultiTypeaheadSelect.js +186 -0
  22. package/dist/esm/components/Select/MultiTypeaheadSelect.js.map +1 -0
  23. package/dist/esm/components/Select/{SelectSimple.d.ts → SimpleSelect.d.ts} +12 -7
  24. package/dist/esm/components/Select/SimpleSelect.d.ts.map +1 -0
  25. package/dist/esm/components/Select/SimpleSelect.js +39 -0
  26. package/dist/esm/components/Select/SimpleSelect.js.map +1 -0
  27. package/dist/esm/components/Select/TypeaheadSelect.d.ts +43 -0
  28. package/dist/esm/components/Select/TypeaheadSelect.d.ts.map +1 -0
  29. package/dist/esm/components/Select/TypeaheadSelect.js +219 -0
  30. package/dist/esm/components/Select/TypeaheadSelect.js.map +1 -0
  31. package/dist/esm/components/Select/index.d.ts +3 -1
  32. package/dist/esm/components/Select/index.d.ts.map +1 -1
  33. package/dist/esm/components/Select/index.js +3 -1
  34. package/dist/esm/components/Select/index.js.map +1 -1
  35. package/dist/esm/components/index.d.ts +1 -0
  36. package/dist/esm/components/index.d.ts.map +1 -1
  37. package/dist/esm/components/index.js +1 -0
  38. package/dist/esm/components/index.js.map +1 -1
  39. package/dist/js/components/Dropdown/SimpleDropdown.d.ts +48 -0
  40. package/dist/js/components/Dropdown/SimpleDropdown.d.ts.map +1 -0
  41. package/dist/js/components/Dropdown/SimpleDropdown.js +36 -0
  42. package/dist/js/components/Dropdown/SimpleDropdown.js.map +1 -0
  43. package/dist/js/components/Dropdown/index.d.ts +2 -0
  44. package/dist/js/components/Dropdown/index.d.ts.map +1 -0
  45. package/dist/js/components/Dropdown/index.js +5 -0
  46. package/dist/js/components/Dropdown/index.js.map +1 -0
  47. package/dist/js/components/Select/CheckboxSelect.d.ts +7 -3
  48. package/dist/js/components/Select/CheckboxSelect.d.ts.map +1 -1
  49. package/dist/js/components/Select/CheckboxSelect.js +14 -6
  50. package/dist/js/components/Select/CheckboxSelect.js.map +1 -1
  51. package/dist/js/components/Select/MultiTypeaheadSelect.d.ts +33 -0
  52. package/dist/js/components/Select/MultiTypeaheadSelect.d.ts.map +1 -0
  53. package/dist/js/components/Select/MultiTypeaheadSelect.js +190 -0
  54. package/dist/js/components/Select/MultiTypeaheadSelect.js.map +1 -0
  55. package/dist/js/components/Select/{SelectSimple.d.ts → SimpleSelect.d.ts} +12 -7
  56. package/dist/js/components/Select/SimpleSelect.d.ts.map +1 -0
  57. package/dist/js/components/Select/SimpleSelect.js +42 -0
  58. package/dist/js/components/Select/SimpleSelect.js.map +1 -0
  59. package/dist/js/components/Select/TypeaheadSelect.d.ts +43 -0
  60. package/dist/js/components/Select/TypeaheadSelect.d.ts.map +1 -0
  61. package/dist/js/components/Select/TypeaheadSelect.js +223 -0
  62. package/dist/js/components/Select/TypeaheadSelect.js.map +1 -0
  63. package/dist/js/components/Select/index.d.ts +3 -1
  64. package/dist/js/components/Select/index.d.ts.map +1 -1
  65. package/dist/js/components/Select/index.js +3 -1
  66. package/dist/js/components/Select/index.js.map +1 -1
  67. package/dist/js/components/index.d.ts +1 -0
  68. package/dist/js/components/index.d.ts.map +1 -1
  69. package/dist/js/components/index.js +1 -0
  70. package/dist/js/components/index.js.map +1 -1
  71. package/dist/umd/assets/output-Drxynxu2.css +23380 -0
  72. package/dist/umd/react-templates.min.js +1 -1
  73. package/package.json +10 -14
  74. package/rollup.config.mjs +8 -0
  75. package/src/components/Dropdown/SimpleDropdown.tsx +139 -0
  76. package/src/components/Dropdown/__tests__/SimpleDropdown.test.tsx +266 -0
  77. package/src/components/Dropdown/__tests__/__snapshots__/SimpleDropdown.test.tsx.snap +81 -0
  78. package/src/components/Dropdown/examples/DropdownTemplates.md +24 -0
  79. package/src/components/Dropdown/examples/SimpleDropdownExample.tsx +53 -0
  80. package/src/components/Dropdown/index.ts +1 -0
  81. package/src/components/Select/CheckboxSelect.tsx +23 -7
  82. package/src/components/Select/MultiTypeaheadSelect.tsx +348 -0
  83. package/src/components/Select/{SelectSimple.tsx → SimpleSelect.tsx} +39 -18
  84. package/src/components/Select/TypeaheadSelect.tsx +388 -0
  85. package/src/components/Select/{CheckboxSelect.test.tsx → __tests__/CheckboxSelect.test.tsx} +29 -1
  86. package/src/components/Select/{CheckboxSelectSnapshots.test.tsx → __tests__/CheckboxSelectSnapshots.test.tsx} +1 -1
  87. package/src/components/Select/__tests__/MultiTypeaheadSelect.test.tsx +414 -0
  88. package/src/components/Select/__tests__/SimpleSelect.test.tsx +241 -0
  89. package/src/components/Select/__tests__/TypeaheadSelect.test.tsx +408 -0
  90. package/src/components/Select/__tests__/__snapshots__/CheckboxSelectSnapshots.test.tsx.snap +83 -0
  91. package/src/components/Select/__tests__/__snapshots__/MultiTypeaheadSelect.test.tsx.snap +97 -0
  92. package/src/components/Select/__tests__/__snapshots__/SimpleSelect.test.tsx.snap +83 -0
  93. package/src/components/Select/__tests__/__snapshots__/TypeaheadSelect.test.tsx.snap +97 -0
  94. package/src/components/Select/examples/CheckboxSelectDemo.tsx +25 -8
  95. package/src/components/Select/examples/MultiTypeaheadSelectDemo.tsx +35 -0
  96. package/src/components/Select/examples/SelectTemplates.md +17 -4
  97. package/src/components/Select/examples/SimpleSelectDemo.tsx +36 -0
  98. package/src/components/Select/examples/TypeaheadSelectDemo.tsx +65 -0
  99. package/src/components/Select/index.ts +3 -1
  100. package/src/components/index.ts +1 -0
  101. package/dist/esm/components/Select/SelectSimple.d.ts.map +0 -1
  102. package/dist/esm/components/Select/SelectSimple.js +0 -31
  103. package/dist/esm/components/Select/SelectSimple.js.map +0 -1
  104. package/dist/js/components/Select/SelectSimple.d.ts.map +0 -1
  105. package/dist/js/components/Select/SelectSimple.js +0 -34
  106. package/dist/js/components/Select/SelectSimple.js.map +0 -1
  107. package/rollup.config.js +0 -7
  108. package/src/components/Select/__snapshots__/CheckboxSelectSnapshots.test.tsx.snap +0 -212
  109. package/src/components/Select/examples/SelectSimpleDemo.tsx +0 -26
@@ -0,0 +1,414 @@
1
+ import * as React from 'react';
2
+ import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { MultiTypeaheadSelect } from '../MultiTypeaheadSelect';
5
+ import styles from '@patternfly/react-styles/css/components/Menu/menu';
6
+
7
+ const getToggle = () => screen.getByRole('button', { name: 'Multi select Typeahead menu toggle' });
8
+
9
+ describe('MultiTypeaheadSelect', () => {
10
+ it('renders MultiTypeaheadSelect with options', async () => {
11
+ const initialOptions = [
12
+ { content: 'Option 1', value: 'option1' },
13
+ { content: 'Option 2', value: 'option2' },
14
+ { content: 'Option 3', value: 'option3' }
15
+ ];
16
+
17
+ const user = userEvent.setup();
18
+
19
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
20
+
21
+ const toggle = getToggle();
22
+
23
+ await user.click(toggle);
24
+
25
+ const option1 = screen.getByText('Option 1');
26
+ const option2 = screen.getByText('Option 2');
27
+ const option3 = screen.getByText('Option 3');
28
+
29
+ expect(option1).toBeInTheDocument();
30
+ expect(option2).toBeInTheDocument();
31
+ expect(option3).toBeInTheDocument();
32
+ });
33
+
34
+ it('selects options when clicked', async () => {
35
+ const initialOptions = [
36
+ { content: 'Option 1', value: 'option1' },
37
+ { content: 'Option 2', value: 'option2' },
38
+ { content: 'Option 3', value: 'option3' }
39
+ ];
40
+
41
+ const user = userEvent.setup();
42
+
43
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
44
+
45
+ const toggle = getToggle();
46
+
47
+ await user.click(toggle);
48
+
49
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
50
+
51
+ expect(option1).not.toHaveClass(styles.modifiers.selected);
52
+
53
+ await user.click(option1);
54
+
55
+ expect(option1).toHaveClass(styles.modifiers.selected);
56
+ });
57
+
58
+ it('calls the onSelectionChange callback with the selected value when an option is selected', async () => {
59
+ const initialOptions = [
60
+ { content: 'Option 1', value: 'option1' },
61
+ { content: 'Option 2', value: 'option2' },
62
+ { content: 'Option 3', value: 'option3' }
63
+ ];
64
+
65
+ const user = userEvent.setup();
66
+ const onSelectionChangeMock = jest.fn();
67
+
68
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} onSelect={onSelectionChangeMock} />);
69
+
70
+ const toggle = getToggle();
71
+
72
+ await user.click(toggle);
73
+
74
+ expect(onSelectionChangeMock).not.toHaveBeenCalled();
75
+
76
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
77
+
78
+ await user.click(option1);
79
+
80
+ expect(onSelectionChangeMock).toHaveBeenCalledTimes(1);
81
+ expect(onSelectionChangeMock).toHaveBeenCalledWith(expect.anything(), 'option1');
82
+ });
83
+
84
+ it('deselects options when clear button is clicked', async () => {
85
+ const initialOptions = [
86
+ { content: 'Option 1', value: 'option1' },
87
+ { content: 'Option 2', value: 'option2' },
88
+ { content: 'Option 3', value: 'option3' }
89
+ ];
90
+
91
+ const user = userEvent.setup();
92
+
93
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
94
+
95
+ const toggle = getToggle();
96
+
97
+ await user.click(toggle);
98
+
99
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
100
+ await user.click(option1);
101
+ expect(option1).toHaveClass(styles.modifiers.selected);
102
+
103
+ const input = screen.getByRole('combobox');
104
+
105
+ const clearButton = screen.getByRole('button', { name: 'Clear input value' });
106
+ await user.click(clearButton);
107
+
108
+ expect(input).toHaveValue('');
109
+
110
+ await user.click(toggle);
111
+ expect(screen.getByRole('option', { name: 'Option 1' })).not.toHaveClass(styles.modifiers.selected);
112
+ });
113
+
114
+ it('toggles the select menu when the toggle button is clicked', async () => {
115
+ const initialOptions = [
116
+ { content: 'Option 1', value: 'option1' },
117
+ { content: 'Option 2', value: 'option2' },
118
+ { content: 'Option 3', value: 'option3' }
119
+ ];
120
+
121
+ const user = userEvent.setup();
122
+
123
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
124
+
125
+ const toggle = getToggle();
126
+
127
+ await user.click(toggle);
128
+
129
+ const menu = screen.getByRole('listbox');
130
+ expect(menu).toBeInTheDocument();
131
+
132
+ await user.click(toggle);
133
+
134
+ await waitForElementToBeRemoved(menu);
135
+
136
+ expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
137
+ });
138
+
139
+ it('calls the onToggle callback when the toggle is clicked', async () => {
140
+ const initialOptions = [
141
+ { content: 'Option 1', value: 'option1' },
142
+ { content: 'Option 2', value: 'option2' },
143
+ { content: 'Option 3', value: 'option3' }
144
+ ];
145
+
146
+ const user = userEvent.setup();
147
+ const onToggleMock = jest.fn();
148
+
149
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} onToggle={onToggleMock} />);
150
+
151
+ const toggle = getToggle();
152
+
153
+ expect(onToggleMock).not.toHaveBeenCalled();
154
+
155
+ await user.click(toggle);
156
+
157
+ expect(onToggleMock).toHaveBeenCalledTimes(1);
158
+ expect(onToggleMock).toHaveBeenCalledWith(true);
159
+
160
+ await user.click(toggle);
161
+
162
+ expect(onToggleMock).toHaveBeenCalledTimes(2);
163
+ expect(onToggleMock).toHaveBeenCalledWith(false);
164
+ });
165
+
166
+ it('Passes toggleWidth', () => {
167
+ const initialOptions = [
168
+ { content: 'Option 1', value: 'option1' },
169
+ { content: 'Option 2', value: 'option2' },
170
+ { content: 'Option 3', value: 'option3' }
171
+ ];
172
+
173
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} toggleWidth="500px" />);
174
+
175
+ const toggle = getToggle();
176
+ expect(toggle.parentElement).toHaveAttribute('style', 'width: 500px;');
177
+ });
178
+
179
+ it('Passes additional toggleProps', () => {
180
+ const initialOptions = [
181
+ { content: 'Option 1', value: 'option1' },
182
+ { content: 'Option 2', value: 'option2' },
183
+ { content: 'Option 3', value: 'option3' }
184
+ ];
185
+
186
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} toggleProps={{ id: 'toggle' }} />);
187
+
188
+ const toggle = getToggle();
189
+ expect(toggle.parentElement).toHaveAttribute('id', 'toggle');
190
+ });
191
+
192
+ it('passes custom placeholder text', async () => {
193
+ const initialOptions = [
194
+ { content: 'Option 1', value: 'option1' },
195
+ { content: 'Option 2', value: 'option2' },
196
+ { content: 'Option 3', value: 'option3' }
197
+ ];
198
+
199
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} placeholder="custom" />);
200
+
201
+ const input = screen.getByRole('combobox');
202
+
203
+ expect(input).toHaveAttribute('placeholder', 'custom');
204
+ });
205
+
206
+ it('displays noOptionsFoundMessage when filter returns no results', async () => {
207
+ const initialOptions = [
208
+ { content: 'Option 1', value: 'option1' },
209
+ { content: 'Option 2', value: 'option2' },
210
+ { content: 'Option 3', value: 'option3' }
211
+ ];
212
+ const user = userEvent.setup();
213
+
214
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
215
+
216
+ const toggle = getToggle();
217
+ const input = screen.getByRole('combobox');
218
+
219
+ expect(input).toHaveAttribute('placeholder', 'Select an option');
220
+
221
+ await user.click(toggle);
222
+
223
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
224
+ const option2 = screen.getByRole('option', { name: 'Option 2' });
225
+ const option3 = screen.getByRole('option', { name: 'Option 3' });
226
+
227
+ expect(option1).toBeInTheDocument();
228
+ expect(option2).toBeInTheDocument();
229
+ expect(option3).toBeInTheDocument();
230
+
231
+ await user.type(input, '9');
232
+ expect(input).toHaveValue('9');
233
+
234
+ expect(option1).not.toBeInTheDocument();
235
+ expect(option2).not.toBeInTheDocument();
236
+ expect(option3).not.toBeInTheDocument();
237
+ expect(screen.getByRole('option', { name: 'No results found for "9"' })).toBeInTheDocument();
238
+ });
239
+
240
+ it('displays custom noOptionsFoundMessage', async () => {
241
+ const initialOptions = [
242
+ { content: 'Option 1', value: 'option1' },
243
+ { content: 'Option 2', value: 'option2' },
244
+ { content: 'Option 3', value: 'option3' }
245
+ ];
246
+ const user = userEvent.setup();
247
+
248
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} noOptionsFoundMessage="custom" />);
249
+
250
+ const toggle = getToggle();
251
+ const input = screen.getByRole('combobox');
252
+
253
+ expect(input).toHaveAttribute('placeholder', 'Select an option');
254
+
255
+ await user.click(toggle);
256
+
257
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
258
+ const option2 = screen.getByRole('option', { name: 'Option 2' });
259
+ const option3 = screen.getByRole('option', { name: 'Option 3' });
260
+
261
+ expect(option1).toBeInTheDocument();
262
+ expect(option2).toBeInTheDocument();
263
+ expect(option3).toBeInTheDocument();
264
+
265
+ await user.type(input, '9');
266
+ expect(input).toHaveValue('9');
267
+
268
+ expect(option1).not.toBeInTheDocument();
269
+ expect(option2).not.toBeInTheDocument();
270
+ expect(option3).not.toBeInTheDocument();
271
+ expect(screen.getByRole('option', { name: 'custom' })).toBeInTheDocument();
272
+ });
273
+
274
+ it('disables the select when isDisabled prop is true', async () => {
275
+ const initialOptions = [
276
+ { content: 'Option 1', value: 'option1' },
277
+ { content: 'Option 2', value: 'option2' },
278
+ { content: 'Option 3', value: 'option3' }
279
+ ];
280
+
281
+ const user = userEvent.setup();
282
+
283
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} isDisabled={true} />);
284
+
285
+ const toggle = getToggle();
286
+
287
+ expect(toggle.parentElement).toHaveClass(styles.modifiers.disabled);
288
+
289
+ await user.click(toggle);
290
+
291
+ expect(screen.queryByRole('menu')).not.toBeInTheDocument();
292
+ });
293
+
294
+ it('passes other SelectOption props to the SelectOption component', async () => {
295
+ const initialOptions = [{ content: 'Option 1', value: 'option1', isDisabled: true }];
296
+
297
+ const user = userEvent.setup();
298
+
299
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
300
+
301
+ const toggle = getToggle();
302
+
303
+ await user.click(toggle);
304
+
305
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
306
+ expect(option1).toBeDisabled();
307
+ });
308
+
309
+ it('displays the option in chip when option is selected', async () => {
310
+ const initialOptions = [
311
+ { content: 'Option 1', value: 'option1' },
312
+ { content: 'Option 2', value: 'option2' },
313
+ { content: 'Option 3', value: 'option3' }
314
+ ];
315
+
316
+ const user = userEvent.setup();
317
+
318
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
319
+
320
+ const toggle = getToggle();
321
+ const input = screen.getByRole('combobox');
322
+
323
+ expect(input).toHaveAttribute('placeholder', 'Select an option');
324
+
325
+ await user.click(toggle);
326
+
327
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
328
+
329
+ await user.click(option1);
330
+
331
+ await user.click(toggle);
332
+
333
+ // TODO: How to find the chips?
334
+
335
+ const clearButton = screen.getByRole('button', { name: 'Clear input value' });
336
+ await user.click(clearButton);
337
+
338
+ // TODO: How to find the chips?
339
+ });
340
+
341
+ it('typing in input filters options', async () => {
342
+ const initialOptions = [
343
+ { content: 'Option 1', value: 'option1' },
344
+ { content: 'Option 2', value: 'option2' },
345
+ { content: 'Option 3', value: 'option3' }
346
+ ];
347
+
348
+ const user = userEvent.setup();
349
+
350
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
351
+
352
+ const toggle = getToggle();
353
+ const input = screen.getByRole('combobox');
354
+
355
+ expect(input).toHaveAttribute('placeholder', 'Select an option');
356
+
357
+ await user.click(toggle);
358
+
359
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
360
+ const option2 = screen.getByRole('option', { name: 'Option 2' });
361
+ const option3 = screen.getByRole('option', { name: 'Option 3' });
362
+
363
+ expect(option1).toBeInTheDocument();
364
+ expect(option2).toBeInTheDocument();
365
+ expect(option3).toBeInTheDocument();
366
+
367
+ await user.type(input, '1');
368
+ expect(input).toHaveValue('1');
369
+
370
+ expect(option1).toBeInTheDocument();
371
+ expect(option2).not.toBeInTheDocument();
372
+ expect(option3).not.toBeInTheDocument();
373
+ });
374
+
375
+ it('typing in input triggers onInputChange callback', async () => {
376
+ const initialOptions = [
377
+ { content: 'Option 1', value: 'option1' },
378
+ { content: 'Option 2', value: 'option2' },
379
+ { content: 'Option 3', value: 'option3' }
380
+ ];
381
+
382
+ const user = userEvent.setup();
383
+ const onInputChangeMock = jest.fn();
384
+
385
+ render(<MultiTypeaheadSelect initialOptions={initialOptions} onInputChange={onInputChangeMock} />);
386
+
387
+ const input = screen.getByRole('combobox');
388
+
389
+ expect(input).toHaveAttribute('placeholder', 'Select an option');
390
+
391
+ await user.type(input, '1');
392
+
393
+ expect(input).toHaveValue('1');
394
+ expect(onInputChangeMock).toHaveBeenCalledTimes(1);
395
+ expect(onInputChangeMock).toHaveBeenCalledWith('1');
396
+ });
397
+
398
+ it('Matches snapshot', async () => {
399
+ const initialOptions = [
400
+ { content: 'Option 1', value: 'option1' },
401
+ { content: 'Option 2', value: 'option2' },
402
+ { content: 'Option 3', value: 'option3' }
403
+ ];
404
+
405
+ const user = userEvent.setup();
406
+
407
+ const { asFragment } = render(<MultiTypeaheadSelect initialOptions={initialOptions} />);
408
+
409
+ const toggle = getToggle();
410
+ await user.click(toggle);
411
+
412
+ expect(asFragment()).toMatchSnapshot();
413
+ });
414
+ });
@@ -0,0 +1,241 @@
1
+ import * as React from 'react';
2
+ import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { SimpleSelect } from '../SimpleSelect';
5
+
6
+ test('renders simple select with options', async () => {
7
+ const initialOptions = [
8
+ { content: 'Option 1', value: 'option1' },
9
+ { content: 'Option 2', value: 'option2' },
10
+ { content: 'Option 3', value: 'option3' }
11
+ ];
12
+
13
+ const user = userEvent.setup();
14
+
15
+ render(<SimpleSelect initialOptions={initialOptions} />);
16
+
17
+ const toggle = screen.getByRole('button', { name: 'Select a value' });
18
+
19
+ await user.click(toggle);
20
+
21
+ const option1 = screen.getByText('Option 1');
22
+ const option2 = screen.getByText('Option 2');
23
+ const option3 = screen.getByText('Option 3');
24
+
25
+ expect(option1).toBeInTheDocument();
26
+ expect(option2).toBeInTheDocument();
27
+ expect(option3).toBeInTheDocument();
28
+ });
29
+
30
+ test('selects options when clicked', async () => {
31
+ const initialOptions = [
32
+ { content: 'Option 1', value: 'option1' },
33
+ { content: 'Option 2', value: 'option2' },
34
+ { content: 'Option 3', value: 'option3' }
35
+ ];
36
+
37
+ const user = userEvent.setup();
38
+
39
+ render(<SimpleSelect initialOptions={initialOptions} />);
40
+
41
+ const toggle = screen.getByRole('button', { name: 'Select a value' });
42
+
43
+ await user.click(toggle);
44
+
45
+ const option1 = screen.getByText('Option 1');
46
+ await user.click(option1);
47
+
48
+ expect(option1).toBeInTheDocument();
49
+ });
50
+
51
+ test('calls the onSelect callback with the selected value when an option is selected', async () => {
52
+ const initialOptions = [
53
+ { content: 'Option 1', value: 'option1' },
54
+ { content: 'Option 2', value: 'option2' },
55
+ { content: 'Option 3', value: 'option3' }
56
+ ];
57
+
58
+ const user = userEvent.setup();
59
+ const onSelectMock = jest.fn();
60
+
61
+ render(<SimpleSelect initialOptions={initialOptions} onSelect={onSelectMock} />);
62
+
63
+ const toggle = screen.getByRole('button', { name: 'Select a value' });
64
+
65
+ await user.click(toggle);
66
+
67
+ expect(onSelectMock).not.toHaveBeenCalled();
68
+
69
+ const option1 = screen.getByText('Option 1');
70
+
71
+ await user.click(option1);
72
+
73
+ expect(onSelectMock).toHaveBeenCalledTimes(1);
74
+ expect(onSelectMock).toHaveBeenCalledWith(expect.anything(), 'option1');
75
+ });
76
+
77
+ test('toggles the select menu when the toggle button is clicked', async () => {
78
+ const initialOptions = [
79
+ { content: 'Option 1', value: 'option1' },
80
+ { content: 'Option 2', value: 'option2' },
81
+ { content: 'Option 3', value: 'option3' }
82
+ ];
83
+
84
+ const user = userEvent.setup();
85
+
86
+ render(<SimpleSelect initialOptions={initialOptions} />);
87
+
88
+ const toggleButton = screen.getByRole('button', { name: 'Select a value' });
89
+
90
+ await user.click(toggleButton);
91
+
92
+ expect(screen.getByRole('listbox')).toBeInTheDocument();
93
+
94
+ await user.click(toggleButton);
95
+
96
+ await waitForElementToBeRemoved(() => screen.queryByRole('listbox'));
97
+
98
+ expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
99
+ });
100
+
101
+ test('displays custom toggle content', async () => {
102
+ const initialOptions = [
103
+ { content: 'Option 1', value: 'option1' },
104
+ { content: 'Option 2', value: 'option2' },
105
+ { content: 'Option 3', value: 'option3' }
106
+ ];
107
+
108
+ render(<SimpleSelect initialOptions={initialOptions} toggleContent="Custom Toggle" />);
109
+
110
+ const toggleButton = screen.getByRole('button', { name: 'Custom Toggle' });
111
+
112
+ expect(toggleButton).toBeInTheDocument();
113
+ });
114
+
115
+ test('Passes toggleWidth', () => {
116
+ const initialOptions = [
117
+ { content: 'Option 1', value: 'option1' },
118
+ { content: 'Option 2', value: 'option2' },
119
+ { content: 'Option 3', value: 'option3' }
120
+ ];
121
+
122
+ render(<SimpleSelect initialOptions={initialOptions} toggleContent="Custom Toggle" toggleWidth="500px" />);
123
+
124
+ const toggleButton = screen.getByRole('button', { name: 'Custom Toggle' });
125
+ expect(toggleButton).toHaveAttribute('style', 'width: 500px;');
126
+ });
127
+
128
+ test('Passes additional toggleProps', () => {
129
+ const initialOptions = [
130
+ { content: 'Option 1', value: 'option1' },
131
+ { content: 'Option 2', value: 'option2' },
132
+ { content: 'Option 3', value: 'option3' }
133
+ ];
134
+
135
+ render(<SimpleSelect initialOptions={initialOptions} toggleContent="Custom Toggle" toggleProps={{ id: 'toggle' }} />);
136
+
137
+ const toggleButton = screen.getByRole('button', { name: 'Custom Toggle' });
138
+ expect(toggleButton).toHaveAttribute('id', 'toggle');
139
+ });
140
+
141
+ test('calls the onToggle callback when the select opens or closes', async () => {
142
+ const initialOptions = [
143
+ { content: 'Option 1', value: 'option1' },
144
+ { content: 'Option 2', value: 'option2' },
145
+ { content: 'Option 3', value: 'option3' }
146
+ ];
147
+
148
+ const user = userEvent.setup();
149
+ const onToggleMock = jest.fn();
150
+
151
+ render(<SimpleSelect initialOptions={initialOptions} onToggle={onToggleMock} />);
152
+
153
+ const toggle = screen.getByRole('button', { name: 'Select a value' });
154
+
155
+ await user.click(toggle);
156
+
157
+ expect(onToggleMock).toHaveBeenCalledTimes(1);
158
+ expect(onToggleMock).toHaveBeenCalledWith(true);
159
+
160
+ await user.click(toggle);
161
+
162
+ expect(onToggleMock).toHaveBeenCalledTimes(2);
163
+ expect(onToggleMock).toHaveBeenCalledWith(false);
164
+ });
165
+
166
+ test('does not call the onToggle callback when the toggle is not clicked', async () => {
167
+ const initialOptions = [
168
+ { content: 'Option 1', value: 'option1' },
169
+ { content: 'Option 2', value: 'option2' },
170
+ { content: 'Option 3', value: 'option3' }
171
+ ];
172
+
173
+ const onToggleMock = jest.fn();
174
+
175
+ render(<SimpleSelect initialOptions={initialOptions} onToggle={onToggleMock} />);
176
+
177
+ expect(onToggleMock).not.toHaveBeenCalled();
178
+ });
179
+
180
+ test('disables the select when isDisabled prop is true', async () => {
181
+ const initialOptions = [
182
+ { content: 'Option 1', value: 'option1' },
183
+ { content: 'Option 2', value: 'option2' },
184
+ { content: 'Option 3', value: 'option3' }
185
+ ];
186
+
187
+ const user = userEvent.setup();
188
+
189
+ render(<SimpleSelect initialOptions={initialOptions} isDisabled={true} />);
190
+
191
+ const toggleButton = screen.getByRole('button', { name: 'Select a value' });
192
+
193
+ expect(toggleButton).toBeDisabled();
194
+
195
+ await user.click(toggleButton);
196
+
197
+ expect(screen.queryByRole('menu')).not.toBeInTheDocument();
198
+ });
199
+
200
+ test('passes other SelectOption props to the SelectOption component', async () => {
201
+ const initialOptions = [{ content: 'Option 1', value: 'option1', isDisabled: true }];
202
+
203
+ const user = userEvent.setup();
204
+
205
+ render(<SimpleSelect initialOptions={initialOptions} />);
206
+
207
+ const toggle = screen.getByRole('button', { name: 'Select a value' });
208
+
209
+ await user.click(toggle);
210
+
211
+ const option1 = screen.getByRole('option', { name: 'Option 1' });
212
+
213
+ expect(option1).toBeDisabled();
214
+ });
215
+
216
+ jest.mock('@patternfly/react-core/dist/js/helpers/GenerateId/GenerateId', () => ({
217
+ GenerateId: ({ children }) => children('generated-id')
218
+ }));
219
+
220
+ test('checkbox select with no props snapshot', () => {
221
+ const { asFragment } = render(<SimpleSelect />);
222
+
223
+ expect(asFragment()).toMatchSnapshot();
224
+ });
225
+
226
+ test('Matches snapshot', async () => {
227
+ const initialOptions = [
228
+ { content: 'Option 1', value: 'option1' },
229
+ { content: 'Option 2', value: 'option2' },
230
+ { content: 'Option 3', value: 'option3' }
231
+ ];
232
+
233
+ const user = userEvent.setup();
234
+
235
+ const { asFragment } = render(<SimpleSelect initialOptions={initialOptions} toggleContent="Select" />);
236
+
237
+ const toggle = screen.getByRole('button', { name: 'Select' });
238
+ await user.click(toggle);
239
+
240
+ expect(asFragment()).toMatchSnapshot();
241
+ });