@patternfly/react-templates 1.1.0-prerelease.39 → 1.1.0-prerelease.40

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.
@@ -15,18 +15,20 @@ import {
15
15
  } from '@patternfly/react-core';
16
16
  import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
17
17
 
18
- export interface TypeaheadSelectOption extends Omit<SelectOptionProps, 'content'> {
18
+ export interface TypeaheadSelectOption extends Omit<SelectOptionProps, 'content' | 'isSelected'> {
19
19
  /** Content of the select option. */
20
20
  content: string | number;
21
21
  /** Value of the select option. */
22
22
  value: string | number;
23
+ /** Indicator for option being selected */
24
+ isSelected?: boolean;
23
25
  }
24
26
 
25
27
  export interface TypeaheadSelectProps extends Omit<SelectProps, 'toggle' | 'onSelect'> {
26
28
  /** @hide Forwarded ref */
27
29
  innerRef?: React.Ref<any>;
28
- /** Initial options of the select. */
29
- initialOptions: TypeaheadSelectOption[];
30
+ /** Options of the select */
31
+ selectOptions: TypeaheadSelectOption[];
30
32
  /** Callback triggered on selection. */
31
33
  onSelect?: (
32
34
  _event: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<HTMLInputElement> | undefined,
@@ -36,6 +38,8 @@ export interface TypeaheadSelectProps extends Omit<SelectProps, 'toggle' | 'onSe
36
38
  onToggle?: (nextIsOpen: boolean) => void;
37
39
  /** Callback triggered when the text in the input field changes. */
38
40
  onInputChange?: (newValue: string) => void;
41
+ /** Function to return items matching the current filter value */
42
+ filterFunction?: (filterValue: string, options: TypeaheadSelectOption[]) => TypeaheadSelectOption[];
39
43
  /** Callback triggered when the clear button is selected */
40
44
  onClearSelection?: () => void;
41
45
  /** Placeholder text for the select input. */
@@ -61,12 +65,16 @@ export interface TypeaheadSelectProps extends Omit<SelectProps, 'toggle' | 'onSe
61
65
  const defaultNoOptionsFoundMessage = (filter: string) => `No results found for "${filter}"`;
62
66
  const defaultCreateOptionMessage = (newValue: string) => `Create "${newValue}"`;
63
67
 
68
+ const defaultFilterFunction = (filterValue: string, options: TypeaheadSelectOption[]) =>
69
+ options.filter((o) => String(o.content).toLowerCase().includes(filterValue.toLowerCase()));
70
+
64
71
  export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps> = ({
65
72
  innerRef,
66
- initialOptions,
73
+ selectOptions,
67
74
  onSelect,
68
75
  onToggle,
69
76
  onInputChange,
77
+ filterFunction = defaultFilterFunction,
70
78
  onClearSelection,
71
79
  placeholder = 'Select an option',
72
80
  noOptionsAvailableMessage = 'No options are available',
@@ -80,31 +88,30 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
80
88
  ...props
81
89
  }: TypeaheadSelectProps) => {
82
90
  const [isOpen, setIsOpen] = React.useState(false);
83
- const [selected, setSelected] = React.useState<string>(String(initialOptions.find((o) => o.selected)?.content ?? ''));
84
- const [inputValue, setInputValue] = React.useState<string>(
85
- String(initialOptions.find((o) => o.selected)?.content ?? '')
86
- );
87
91
  const [filterValue, setFilterValue] = React.useState<string>('');
88
- const [selectOptions, setSelectOptions] = React.useState<TypeaheadSelectOption[]>(initialOptions);
92
+ const [isFiltering, setIsFiltering] = React.useState<boolean>(false);
89
93
  const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(null);
90
94
  const [activeItemId, setActiveItemId] = React.useState<string | null>(null);
91
95
  const textInputRef = React.useRef<HTMLInputElement>();
92
96
 
93
97
  const NO_RESULTS = 'no results';
94
98
 
95
- React.useEffect(() => {
96
- let newSelectOptions: TypeaheadSelectOption[] = initialOptions;
99
+ const selected = React.useMemo(
100
+ () => selectOptions?.find((option) => option.value === props.selected || option.isSelected),
101
+ [props.selected, selectOptions]
102
+ );
103
+
104
+ const filteredSelections = React.useMemo(() => {
105
+ let newSelectOptions: TypeaheadSelectOption[] = selectOptions;
97
106
 
98
107
  // Filter menu items based on the text input value when one exists
99
- if (filterValue) {
100
- newSelectOptions = initialOptions.filter((option) =>
101
- String(option.content).toLowerCase().includes(filterValue.toLowerCase())
102
- );
108
+ if (isFiltering && filterValue) {
109
+ newSelectOptions = filterFunction(filterValue, selectOptions);
103
110
 
104
111
  if (
105
112
  isCreatable &&
106
- filterValue &&
107
- !initialOptions.find((o) => String(o.content).toLowerCase() === filterValue.toLowerCase())
113
+ filterValue.trim() &&
114
+ !newSelectOptions.find((o) => String(o.content).toLowerCase() === filterValue.toLowerCase())
108
115
  ) {
109
116
  const createOption = {
110
117
  content: typeof createOptionMessage === 'string' ? createOptionMessage : createOptionMessage(filterValue),
@@ -126,9 +133,6 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
126
133
  }
127
134
  ];
128
135
  }
129
-
130
- // Open the menu when the input value changes and the new value is not empty
131
- openMenu();
132
136
  }
133
137
 
134
138
  // When no options are available, display 'No options available'
@@ -142,10 +146,12 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
142
146
  ];
143
147
  }
144
148
 
145
- setSelectOptions(newSelectOptions);
149
+ return newSelectOptions;
146
150
  }, [
151
+ isFiltering,
147
152
  filterValue,
148
- initialOptions,
153
+ filterFunction,
154
+ selectOptions,
149
155
  noOptionsFoundMessage,
150
156
  isCreatable,
151
157
  isCreateOptionOnTop,
@@ -154,14 +160,12 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
154
160
  ]);
155
161
 
156
162
  React.useEffect(() => {
157
- // If the selected option changed and the current input value is the previously selected item, update the displayed value.
158
- const selectedOption = initialOptions.find((o) => o.selected);
159
- if (inputValue === selected && selectedOption?.value !== selected) {
160
- setInputValue(String(selectedOption?.content ?? ''));
163
+ if (isFiltering) {
164
+ openMenu();
161
165
  }
162
- // Only update when options change
166
+ // Don't update on openMenu changes
163
167
  // eslint-disable-next-line react-hooks/exhaustive-deps
164
- }, [initialOptions]);
168
+ }, [isFiltering]);
165
169
 
166
170
  const setActiveAndFocusedItem = (itemIndex: number) => {
167
171
  setFocusedItemIndex(itemIndex);
@@ -178,6 +182,9 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
178
182
  if (!isOpen) {
179
183
  onToggle && onToggle(true);
180
184
  setIsOpen(true);
185
+ setTimeout(() => {
186
+ textInputRef.current?.focus();
187
+ }, 100);
181
188
  }
182
189
  };
183
190
 
@@ -185,16 +192,14 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
185
192
  onToggle && onToggle(false);
186
193
  setIsOpen(false);
187
194
  resetActiveAndFocusedItem();
188
- const option = initialOptions.find((o) => o.value === selected);
189
- if (option) {
190
- setInputValue(String(option.content));
191
- }
195
+ setIsFiltering(false);
196
+ setFilterValue(String(selected?.content ?? ''));
192
197
  };
193
198
 
194
199
  const onInputClick = () => {
195
200
  if (!isOpen) {
196
201
  openMenu();
197
- } else if (!inputValue) {
202
+ } else if (isFiltering) {
198
203
  closeMenu();
199
204
  }
200
205
  };
@@ -204,25 +209,24 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
204
209
  option: TypeaheadSelectOption
205
210
  ) => {
206
211
  onSelect && onSelect(_event, option.value);
207
-
208
- setInputValue(String(option.content));
209
- setFilterValue('');
210
- setSelected(String(option.value));
211
-
212
212
  closeMenu();
213
213
  };
214
214
 
215
215
  const _onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, value: string | number | undefined) => {
216
216
  if (value && value !== NO_RESULTS) {
217
217
  const optionToSelect = selectOptions.find((option) => option.value === value);
218
- selectOption(_event, optionToSelect);
218
+ if (optionToSelect) {
219
+ selectOption(_event, optionToSelect);
220
+ } else if (isCreatable) {
221
+ selectOption(_event, { value, content: value });
222
+ }
219
223
  }
220
224
  };
221
225
 
222
226
  const onTextInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {
223
- setInputValue(value);
227
+ setIsFiltering(true);
228
+ setFilterValue(value || '');
224
229
  onInputChange && onInputChange(value);
225
- setFilterValue(value);
226
230
 
227
231
  resetActiveAndFocusedItem();
228
232
  };
@@ -232,39 +236,39 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
232
236
 
233
237
  openMenu();
234
238
 
235
- if (selectOptions.every((option) => option.isDisabled)) {
239
+ if (filteredSelections.every((option) => option.isDisabled)) {
236
240
  return;
237
241
  }
238
242
 
239
243
  if (key === 'ArrowUp') {
240
244
  // When no index is set or at the first index, focus to the last, otherwise decrement focus index
241
245
  if (focusedItemIndex === null || focusedItemIndex === 0) {
242
- indexToFocus = selectOptions.length - 1;
246
+ indexToFocus = filteredSelections.length - 1;
243
247
  } else {
244
248
  indexToFocus = focusedItemIndex - 1;
245
249
  }
246
250
 
247
251
  // Skip disabled options
248
- while (selectOptions[indexToFocus].isDisabled) {
252
+ while (filteredSelections[indexToFocus].isDisabled) {
249
253
  indexToFocus--;
250
254
  if (indexToFocus === -1) {
251
- indexToFocus = selectOptions.length - 1;
255
+ indexToFocus = filteredSelections.length - 1;
252
256
  }
253
257
  }
254
258
  }
255
259
 
256
260
  if (key === 'ArrowDown') {
257
261
  // When no index is set or at the last index, focus to the first, otherwise increment focus index
258
- if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
262
+ if (focusedItemIndex === null || focusedItemIndex === filteredSelections.length - 1) {
259
263
  indexToFocus = 0;
260
264
  } else {
261
265
  indexToFocus = focusedItemIndex + 1;
262
266
  }
263
267
 
264
268
  // Skip disabled options
265
- while (selectOptions[indexToFocus].isDisabled) {
269
+ while (filteredSelections[indexToFocus].isDisabled) {
266
270
  indexToFocus++;
267
- if (indexToFocus === selectOptions.length) {
271
+ if (indexToFocus === filteredSelections.length) {
268
272
  indexToFocus = 0;
269
273
  }
270
274
  }
@@ -274,7 +278,7 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
274
278
  };
275
279
 
276
280
  const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
277
- const focusedItem = focusedItemIndex !== null ? selectOptions[focusedItemIndex] : null;
281
+ const focusedItem = focusedItemIndex !== null ? filteredSelections[focusedItemIndex] : null;
278
282
 
279
283
  switch (event.key) {
280
284
  case 'Enter':
@@ -294,16 +298,21 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
294
298
  };
295
299
 
296
300
  const onToggleClick = () => {
297
- onToggle && onToggle(!isOpen);
298
- setIsOpen(!isOpen);
301
+ if (!isOpen) {
302
+ openMenu();
303
+ } else {
304
+ closeMenu();
305
+ }
299
306
  textInputRef.current?.focus();
300
307
  };
301
308
 
302
309
  const onClearButtonClick = () => {
303
- setSelected('');
304
- setInputValue('');
305
- onInputChange && onInputChange('');
310
+ if (selected && onSelect) {
311
+ onSelect(undefined, selected.value);
312
+ }
306
313
  setFilterValue('');
314
+ onInputChange && onInputChange('');
315
+ setIsFiltering(false);
307
316
  resetActiveAndFocusedItem();
308
317
  textInputRef.current?.focus();
309
318
  onClearSelection && onClearSelection();
@@ -327,7 +336,7 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
327
336
  >
328
337
  <TextInputGroup isPlain>
329
338
  <TextInputGroupMain
330
- value={inputValue}
339
+ value={isFiltering ? filterValue : (selected?.content ?? '')}
331
340
  onClick={onInputClick}
332
341
  onChange={onTextInputChange}
333
342
  onKeyDown={onInputKeyDown}
@@ -339,8 +348,9 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
339
348
  isExpanded={isOpen}
340
349
  aria-controls="select-typeahead-listbox"
341
350
  />
342
-
343
- <TextInputGroupUtilities {...(!inputValue ? { style: { display: 'none' } } : {})}>
351
+ <TextInputGroupUtilities
352
+ {...(!(isFiltering && filterValue) && !selected ? { style: { display: 'none' } } : {})}
353
+ >
344
354
  <Button variant="plain" onClick={onClearButtonClick} aria-label="Clear input value">
345
355
  <TimesIcon aria-hidden />
346
356
  </Button>
@@ -354,16 +364,14 @@ export const TypeaheadSelectBase: React.FunctionComponent<TypeaheadSelectProps>
354
364
  isOpen={isOpen}
355
365
  selected={selected}
356
366
  onSelect={_onSelect}
357
- onOpenChange={(isOpen) => {
358
- !isOpen && closeMenu();
359
- }}
367
+ onOpenChange={(isOpen) => !isOpen && closeMenu()}
360
368
  toggle={toggle}
361
369
  shouldFocusFirstItemOnOpen={false}
362
370
  ref={innerRef}
363
371
  {...props}
364
372
  >
365
373
  <SelectList>
366
- {selectOptions.map((option, index) => {
374
+ {filteredSelections.map((option, index) => {
367
375
  const { content, value, ...props } = option;
368
376
 
369
377
  return (
@@ -5,7 +5,7 @@ import { TypeaheadSelect } from '../TypeaheadSelect';
5
5
  import styles from '@patternfly/react-styles/css/components/Menu/menu';
6
6
 
7
7
  test('renders typeahead select with options', async () => {
8
- const initialOptions = [
8
+ const selectOptions = [
9
9
  { content: 'Option 1', value: 'option1' },
10
10
  { content: 'Option 2', value: 'option2' },
11
11
  { content: 'Option 3', value: 'option3' }
@@ -13,7 +13,7 @@ test('renders typeahead select with options', async () => {
13
13
 
14
14
  const user = userEvent.setup();
15
15
 
16
- render(<TypeaheadSelect initialOptions={initialOptions} />);
16
+ render(<TypeaheadSelect selectOptions={selectOptions} />);
17
17
 
18
18
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
19
19
 
@@ -28,8 +28,8 @@ test('renders typeahead select with options', async () => {
28
28
  expect(option3).toBeInTheDocument();
29
29
  });
30
30
 
31
- test('selects options when clicked', async () => {
32
- const initialOptions = [
31
+ test('shows the selected item as selected', async () => {
32
+ const selectOptions = [
33
33
  { content: 'Option 1', value: 'option1' },
34
34
  { content: 'Option 2', value: 'option2' },
35
35
  { content: 'Option 3', value: 'option3' }
@@ -37,7 +37,7 @@ test('selects options when clicked', async () => {
37
37
 
38
38
  const user = userEvent.setup();
39
39
 
40
- render(<TypeaheadSelect initialOptions={initialOptions} />);
40
+ render(<TypeaheadSelect selectOptions={selectOptions} selected="option1" />);
41
41
 
42
42
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
43
43
 
@@ -45,15 +45,11 @@ test('selects options when clicked', async () => {
45
45
 
46
46
  const option1 = screen.getByRole('option', { name: 'Option 1' });
47
47
 
48
- expect(option1).not.toHaveClass(styles.modifiers.selected);
49
-
50
- await user.click(option1);
51
-
52
48
  expect(option1).toHaveClass(styles.modifiers.selected);
53
49
  });
54
50
 
55
51
  test('calls the onSelect callback with the selected value when an option is selected', async () => {
56
- const initialOptions = [
52
+ const selectOptions = [
57
53
  { content: 'Option 1', value: 'option1' },
58
54
  { content: 'Option 2', value: 'option2' },
59
55
  { content: 'Option 3', value: 'option3' }
@@ -62,7 +58,7 @@ test('calls the onSelect callback with the selected value when an option is sele
62
58
  const user = userEvent.setup();
63
59
  const onSelectMock = jest.fn();
64
60
 
65
- render(<TypeaheadSelect initialOptions={initialOptions} onSelect={onSelectMock} />);
61
+ render(<TypeaheadSelect selectOptions={selectOptions} onSelect={onSelectMock} />);
66
62
 
67
63
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
68
64
 
@@ -78,23 +74,23 @@ test('calls the onSelect callback with the selected value when an option is sele
78
74
  expect(onSelectMock).toHaveBeenCalledWith(expect.anything(), 'option1');
79
75
  });
80
76
 
81
- test('deselects options when clear button is clicked', async () => {
82
- const initialOptions = [
77
+ test('calls the onClearSelection callback when clear button is clicked', async () => {
78
+ const selectOptions = [
83
79
  { content: 'Option 1', value: 'option1' },
84
80
  { content: 'Option 2', value: 'option2' },
85
81
  { content: 'Option 3', value: 'option3' }
86
82
  ];
83
+ const onClearSelectionMock = jest.fn();
87
84
 
88
85
  const user = userEvent.setup();
89
86
 
90
- render(<TypeaheadSelect initialOptions={initialOptions} />);
87
+ render(<TypeaheadSelect selectOptions={selectOptions} selected="option1" onClearSelection={onClearSelectionMock} />);
91
88
 
92
89
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
93
90
 
94
91
  await user.click(toggle);
95
92
 
96
93
  const option1 = screen.getByRole('option', { name: 'Option 1' });
97
- await user.click(option1);
98
94
  expect(option1).toHaveClass(styles.modifiers.selected);
99
95
 
100
96
  const input = screen.getByRole('combobox');
@@ -102,14 +98,12 @@ test('deselects options when clear button is clicked', async () => {
102
98
 
103
99
  const clearButton = screen.getByRole('button', { name: 'Clear input value' });
104
100
  await user.click(clearButton);
105
- expect(input).toHaveValue('');
106
101
 
107
- await user.click(toggle);
108
- expect(screen.getByRole('option', { name: 'Option 1' })).not.toHaveClass(styles.modifiers.selected);
102
+ expect(onClearSelectionMock).toHaveBeenCalledTimes(1);
109
103
  });
110
104
 
111
105
  test('toggles the select menu when the toggle button is clicked', async () => {
112
- const initialOptions = [
106
+ const selectOptions = [
113
107
  { content: 'Option 1', value: 'option1' },
114
108
  { content: 'Option 2', value: 'option2' },
115
109
  { content: 'Option 3', value: 'option3' }
@@ -117,7 +111,7 @@ test('toggles the select menu when the toggle button is clicked', async () => {
117
111
 
118
112
  const user = userEvent.setup();
119
113
 
120
- render(<TypeaheadSelect initialOptions={initialOptions} />);
114
+ render(<TypeaheadSelect selectOptions={selectOptions} />);
121
115
 
122
116
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
123
117
 
@@ -134,7 +128,7 @@ test('toggles the select menu when the toggle button is clicked', async () => {
134
128
  });
135
129
 
136
130
  test('calls the onToggle callback when the toggle is clicked', async () => {
137
- const initialOptions = [
131
+ const selectOptions = [
138
132
  { content: 'Option 1', value: 'option1' },
139
133
  { content: 'Option 2', value: 'option2' },
140
134
  { content: 'Option 3', value: 'option3' }
@@ -143,7 +137,7 @@ test('calls the onToggle callback when the toggle is clicked', async () => {
143
137
  const user = userEvent.setup();
144
138
  const onToggleMock = jest.fn();
145
139
 
146
- render(<TypeaheadSelect initialOptions={initialOptions} onToggle={onToggleMock} />);
140
+ render(<TypeaheadSelect selectOptions={selectOptions} onToggle={onToggleMock} />);
147
141
 
148
142
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
149
143
 
@@ -161,39 +155,39 @@ test('calls the onToggle callback when the toggle is clicked', async () => {
161
155
  });
162
156
 
163
157
  test('Passes toggleWidth', () => {
164
- const initialOptions = [
158
+ const selectOptions = [
165
159
  { content: 'Option 1', value: 'option1' },
166
160
  { content: 'Option 2', value: 'option2' },
167
161
  { content: 'Option 3', value: 'option3' }
168
162
  ];
169
163
 
170
- render(<TypeaheadSelect initialOptions={initialOptions} toggleWidth="500px" />);
164
+ render(<TypeaheadSelect selectOptions={selectOptions} toggleWidth="500px" />);
171
165
 
172
166
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
173
167
  expect(toggle.parentElement).toHaveAttribute('style', 'width: 500px;');
174
168
  });
175
169
 
176
170
  test('Passes additional toggleProps', () => {
177
- const initialOptions = [
171
+ const selectOptions = [
178
172
  { content: 'Option 1', value: 'option1' },
179
173
  { content: 'Option 2', value: 'option2' },
180
174
  { content: 'Option 3', value: 'option3' }
181
175
  ];
182
176
 
183
- render(<TypeaheadSelect initialOptions={initialOptions} toggleProps={{ id: 'toggle' }} />);
177
+ render(<TypeaheadSelect selectOptions={selectOptions} toggleProps={{ id: 'toggle' }} />);
184
178
 
185
179
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
186
180
  expect(toggle.parentElement).toHaveAttribute('id', 'toggle');
187
181
  });
188
182
 
189
183
  test('passes custom placeholder text', async () => {
190
- const initialOptions = [
184
+ const selectOptions = [
191
185
  { content: 'Option 1', value: 'option1' },
192
186
  { content: 'Option 2', value: 'option2' },
193
187
  { content: 'Option 3', value: 'option3' }
194
188
  ];
195
189
 
196
- render(<TypeaheadSelect initialOptions={initialOptions} placeholder="custom" />);
190
+ render(<TypeaheadSelect selectOptions={selectOptions} placeholder="custom" />);
197
191
 
198
192
  const input = screen.getByRole('combobox');
199
193
 
@@ -201,14 +195,14 @@ test('passes custom placeholder text', async () => {
201
195
  });
202
196
 
203
197
  test('displays noOptionsFoundMessage when filter returns no results', async () => {
204
- const initialOptions = [
198
+ const selectOptions = [
205
199
  { content: 'Option 1', value: 'option1' },
206
200
  { content: 'Option 2', value: 'option2' },
207
201
  { content: 'Option 3', value: 'option3' }
208
202
  ];
209
203
  const user = userEvent.setup();
210
204
 
211
- render(<TypeaheadSelect initialOptions={initialOptions} />);
205
+ render(<TypeaheadSelect selectOptions={selectOptions} />);
212
206
 
213
207
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
214
208
  const input = screen.getByRole('combobox');
@@ -235,14 +229,14 @@ test('displays noOptionsFoundMessage when filter returns no results', async () =
235
229
  });
236
230
 
237
231
  test('displays custom noOptionsFoundMessage', async () => {
238
- const initialOptions = [
232
+ const selectOptions = [
239
233
  { content: 'Option 1', value: 'option1' },
240
234
  { content: 'Option 2', value: 'option2' },
241
235
  { content: 'Option 3', value: 'option3' }
242
236
  ];
243
237
  const user = userEvent.setup();
244
238
 
245
- render(<TypeaheadSelect initialOptions={initialOptions} noOptionsFoundMessage="custom" />);
239
+ render(<TypeaheadSelect selectOptions={selectOptions} noOptionsFoundMessage="custom" />);
246
240
 
247
241
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
248
242
  const input = screen.getByRole('combobox');
@@ -269,7 +263,7 @@ test('displays custom noOptionsFoundMessage', async () => {
269
263
  });
270
264
 
271
265
  test('disables the select when isDisabled prop is true', async () => {
272
- const initialOptions = [
266
+ const selectOptions = [
273
267
  { content: 'Option 1', value: 'option1' },
274
268
  { content: 'Option 2', value: 'option2' },
275
269
  { content: 'Option 3', value: 'option3' }
@@ -277,7 +271,7 @@ test('disables the select when isDisabled prop is true', async () => {
277
271
 
278
272
  const user = userEvent.setup();
279
273
 
280
- render(<TypeaheadSelect initialOptions={initialOptions} isDisabled={true} />);
274
+ render(<TypeaheadSelect selectOptions={selectOptions} isDisabled={true} />);
281
275
 
282
276
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
283
277
 
@@ -289,11 +283,11 @@ test('disables the select when isDisabled prop is true', async () => {
289
283
  });
290
284
 
291
285
  test('passes other SelectOption props to the SelectOption component', async () => {
292
- const initialOptions = [{ content: 'Option 1', value: 'option1', isDisabled: true }];
286
+ const selectOptions = [{ content: 'Option 1', value: 'option1', isDisabled: true }];
293
287
 
294
288
  const user = userEvent.setup();
295
289
 
296
- render(<TypeaheadSelect initialOptions={initialOptions} />);
290
+ render(<TypeaheadSelect selectOptions={selectOptions} />);
297
291
 
298
292
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
299
293
 
@@ -303,38 +297,8 @@ test('passes other SelectOption props to the SelectOption component', async () =
303
297
  expect(option1).toBeDisabled();
304
298
  });
305
299
 
306
- test('displays the option in input when option is selected', async () => {
307
- const initialOptions = [
308
- { content: 'Option 1', value: 'option1' },
309
- { content: 'Option 2', value: 'option2' },
310
- { content: 'Option 3', value: 'option3' }
311
- ];
312
-
313
- const user = userEvent.setup();
314
-
315
- render(<TypeaheadSelect initialOptions={initialOptions} />);
316
-
317
- const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
318
- const input = screen.getByRole('combobox');
319
-
320
- expect(input).toHaveAttribute('placeholder', 'Select an option');
321
-
322
- await user.click(toggle);
323
-
324
- const option1 = screen.getByRole('option', { name: 'Option 1' });
325
-
326
- await user.click(option1);
327
-
328
- expect(input).toHaveValue('Option 1');
329
-
330
- const clearButton = screen.getByRole('button', { name: 'Clear input value' });
331
- await user.click(clearButton);
332
-
333
- expect(input).toHaveValue('');
334
- });
335
-
336
300
  test('typing in input filters options', async () => {
337
- const initialOptions = [
301
+ const selectOptions = [
338
302
  { content: 'Option 1', value: 'option1' },
339
303
  { content: 'Option 2', value: 'option2' },
340
304
  { content: 'Option 3', value: 'option3' }
@@ -342,7 +306,7 @@ test('typing in input filters options', async () => {
342
306
 
343
307
  const user = userEvent.setup();
344
308
 
345
- render(<TypeaheadSelect initialOptions={initialOptions} />);
309
+ render(<TypeaheadSelect selectOptions={selectOptions} />);
346
310
 
347
311
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
348
312
  const input = screen.getByRole('combobox');
@@ -368,7 +332,7 @@ test('typing in input filters options', async () => {
368
332
  });
369
333
 
370
334
  test('typing in input triggers onInputChange callback', async () => {
371
- const initialOptions = [
335
+ const selectOptions = [
372
336
  { content: 'Option 1', value: 'option1' },
373
337
  { content: 'Option 2', value: 'option2' },
374
338
  { content: 'Option 3', value: 'option3' }
@@ -377,7 +341,7 @@ test('typing in input triggers onInputChange callback', async () => {
377
341
  const user = userEvent.setup();
378
342
  const onInputChangeMock = jest.fn();
379
343
 
380
- render(<TypeaheadSelect initialOptions={initialOptions} onInputChange={onInputChangeMock} />);
344
+ render(<TypeaheadSelect selectOptions={selectOptions} onInputChange={onInputChangeMock} />);
381
345
 
382
346
  const input = screen.getByRole('combobox');
383
347
 
@@ -391,7 +355,7 @@ test('typing in input triggers onInputChange callback', async () => {
391
355
  });
392
356
 
393
357
  test('Matches snapshot', async () => {
394
- const initialOptions = [
358
+ const selectOptions = [
395
359
  { content: 'Option 1', value: 'option1' },
396
360
  { content: 'Option 2', value: 'option2' },
397
361
  { content: 'Option 3', value: 'option3' }
@@ -399,7 +363,7 @@ test('Matches snapshot', async () => {
399
363
 
400
364
  const user = userEvent.setup();
401
365
 
402
- const { asFragment } = render(<TypeaheadSelect initialOptions={initialOptions} />);
366
+ const { asFragment } = render(<TypeaheadSelect selectOptions={selectOptions} />);
403
367
 
404
368
  const toggle = screen.getByRole('button', { name: 'Typeahead menu toggle' });
405
369
  await user.click(toggle);
@@ -35,7 +35,7 @@ exports[`Matches snapshot 1`] = `
35
35
  aria-disabled="false"
36
36
  aria-label="Clear input value"
37
37
  class="pf-v5-c-button pf-m-plain"
38
- data-ouia-component-id="OUIA-Generated-Button-plain-17"
38
+ data-ouia-component-id="OUIA-Generated-Button-plain-16"
39
39
  data-ouia-component-type="PF5/Button"
40
40
  data-ouia-safe="true"
41
41
  type="button"
@@ -60,7 +60,7 @@ exports[`Matches snapshot 1`] = `
60
60
  aria-expanded="true"
61
61
  aria-label="Typeahead menu toggle"
62
62
  class="pf-v5-c-menu-toggle__button"
63
- data-ouia-component-id="OUIA-Generated-MenuToggle-typeahead-17"
63
+ data-ouia-component-id="OUIA-Generated-MenuToggle-typeahead-16"
64
64
  data-ouia-component-type="PF5/MenuToggle"
65
65
  data-ouia-safe="true"
66
66
  tabindex="-1"
@@ -91,7 +91,7 @@ exports[`Matches snapshot 1`] = `
91
91
  </div>
92
92
  <div
93
93
  class="pf-v5-c-menu"
94
- data-ouia-component-id="OUIA-Generated-Select-51"
94
+ data-ouia-component-id="OUIA-Generated-Select-36"
95
95
  data-ouia-component-type="PF5/Select"
96
96
  data-ouia-safe="true"
97
97
  data-popper-escaped="true"