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

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 +238 -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-D0LdS41Q.css +23489 -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,348 @@
1
+ import React from 'react';
2
+ import {
3
+ Select,
4
+ SelectOption,
5
+ SelectList,
6
+ SelectOptionProps,
7
+ MenuToggle,
8
+ MenuToggleElement,
9
+ TextInputGroup,
10
+ TextInputGroupMain,
11
+ TextInputGroupUtilities,
12
+ Button,
13
+ MenuToggleProps,
14
+ SelectProps,
15
+ Label,
16
+ LabelGroup
17
+ } from '@patternfly/react-core';
18
+ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
19
+
20
+ export interface MultiTypeaheadSelectOption extends Omit<SelectOptionProps, 'content'> {
21
+ /** Content of the select option. */
22
+ content: string | number;
23
+ /** Value of the select option. */
24
+ value: string | number;
25
+ }
26
+
27
+ export interface MultiTypeaheadSelectProps extends Omit<SelectProps, 'toggle' | 'onSelect'> {
28
+ /** @hide Forwarded ref */
29
+ innerRef?: React.Ref<any>;
30
+ /** Initial options of the select. */
31
+ initialOptions: MultiTypeaheadSelectOption[];
32
+ /** Callback triggered on selection. */
33
+ onSelectionChange?: (
34
+ _event: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<HTMLInputElement>,
35
+ selections: (string | number)[]
36
+ ) => void;
37
+ /** Callback triggered when the select opens or closes. */
38
+ onToggle?: (nextIsOpen: boolean) => void;
39
+ /** Callback triggered when the text in the input field changes. */
40
+ onInputChange?: (newValue: string) => void;
41
+ /** Placeholder text for the select input. */
42
+ placeholder?: string;
43
+ /** Message to display when no options match the filter. */
44
+ noOptionsFoundMessage?: string | ((filter: string) => string);
45
+ /** Flag indicating the select should be disabled. */
46
+ isDisabled?: boolean;
47
+ /** Width of the toggle. */
48
+ toggleWidth?: string;
49
+ /** Additional props passed to the toggle. */
50
+ toggleProps?: MenuToggleProps;
51
+ }
52
+
53
+ export const MultiTypeaheadSelectBase: React.FunctionComponent<MultiTypeaheadSelectProps> = ({
54
+ innerRef,
55
+ initialOptions,
56
+ onSelectionChange,
57
+ onToggle,
58
+ onInputChange,
59
+ placeholder = 'Select an option',
60
+ noOptionsFoundMessage = (filter) => `No results found for "${filter}"`,
61
+ isDisabled,
62
+ toggleWidth,
63
+ toggleProps,
64
+ ...props
65
+ }: MultiTypeaheadSelectProps) => {
66
+ const [isOpen, setIsOpen] = React.useState(false);
67
+ const [selected, setSelected] = React.useState<(string | number)[]>(
68
+ (initialOptions?.filter((o) => o.selected) ?? []).map((o) => o.value)
69
+ );
70
+ const [inputValue, setInputValue] = React.useState<string>();
71
+ const [selectOptions, setSelectOptions] = React.useState<MultiTypeaheadSelectOption[]>(initialOptions);
72
+ const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(null);
73
+ const [activeItemId, setActiveItemId] = React.useState<string | null>(null);
74
+ const textInputRef = React.useRef<HTMLInputElement>();
75
+
76
+ const NO_RESULTS = 'no results';
77
+
78
+ const openMenu = () => {
79
+ onToggle && onToggle(true);
80
+ setIsOpen(true);
81
+ };
82
+
83
+ React.useEffect(() => {
84
+ let newSelectOptions: MultiTypeaheadSelectOption[] = initialOptions;
85
+
86
+ // Filter menu items based on the text input value when one exists
87
+ if (inputValue) {
88
+ newSelectOptions = initialOptions.filter((option) =>
89
+ String(option.content).toLowerCase().includes(inputValue.toLowerCase())
90
+ );
91
+
92
+ // When no options are found after filtering, display 'No results found'
93
+ if (!newSelectOptions.length) {
94
+ newSelectOptions = [
95
+ {
96
+ isAriaDisabled: true,
97
+ content:
98
+ typeof noOptionsFoundMessage === 'string' ? noOptionsFoundMessage : noOptionsFoundMessage(inputValue),
99
+ value: NO_RESULTS
100
+ }
101
+ ];
102
+ }
103
+
104
+ // Open the menu when the input value changes and the new value is not empty
105
+ openMenu();
106
+ }
107
+
108
+ setSelectOptions(newSelectOptions);
109
+ // eslint-disable-next-line react-hooks/exhaustive-deps
110
+ }, [inputValue, initialOptions]);
111
+
112
+ React.useEffect(
113
+ () => setSelected((initialOptions?.filter((o) => o.selected) ?? []).map((o) => o.value)),
114
+ [initialOptions]
115
+ );
116
+
117
+ const setActiveAndFocusedItem = (itemIndex: number) => {
118
+ setFocusedItemIndex(itemIndex);
119
+ const focusedItem = selectOptions[itemIndex];
120
+ setActiveItemId(focusedItem.value as string);
121
+ };
122
+
123
+ const resetActiveAndFocusedItem = () => {
124
+ setFocusedItemIndex(null);
125
+ setActiveItemId(null);
126
+ };
127
+
128
+ const closeMenu = () => {
129
+ onToggle && onToggle(false);
130
+ setIsOpen(false);
131
+ resetActiveAndFocusedItem();
132
+ setInputValue('');
133
+ };
134
+
135
+ const onInputClick = () => {
136
+ if (!isOpen) {
137
+ openMenu();
138
+ } else if (!inputValue) {
139
+ closeMenu();
140
+ }
141
+ };
142
+
143
+ const selectOption = (
144
+ _event: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<HTMLInputElement> | undefined,
145
+ option: string | number
146
+ ) => {
147
+ const selections = selected.includes(option) ? selected.filter((o) => option !== o) : [...selected, option];
148
+
149
+ onSelectionChange && onSelectionChange(_event, selections);
150
+ setSelected(selections);
151
+ };
152
+
153
+ const clearOption = (
154
+ _event: React.MouseEvent<Element, MouseEvent> | React.KeyboardEvent<HTMLInputElement> | undefined,
155
+ option: string | number
156
+ ) => {
157
+ const selections = selected.filter((o) => option !== o);
158
+ onSelectionChange && onSelectionChange(_event, selections);
159
+ setSelected(selections);
160
+ };
161
+
162
+ const _onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, value: string | number | undefined) => {
163
+ if (value && value !== NO_RESULTS) {
164
+ selectOption(_event, value);
165
+ }
166
+ };
167
+
168
+ const onTextInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {
169
+ setInputValue(value);
170
+ onInputChange && onInputChange(value);
171
+
172
+ resetActiveAndFocusedItem();
173
+ };
174
+
175
+ const handleMenuArrowKeys = (key: string) => {
176
+ let indexToFocus = 0;
177
+
178
+ if (!isOpen) {
179
+ openMenu();
180
+ }
181
+
182
+ if (selectOptions.every((option) => option.isDisabled)) {
183
+ return;
184
+ }
185
+
186
+ if (key === 'ArrowUp') {
187
+ // When no index is set or at the first index, focus to the last, otherwise decrement focus index
188
+ if (focusedItemIndex === null || focusedItemIndex === 0) {
189
+ indexToFocus = selectOptions.length - 1;
190
+ } else {
191
+ indexToFocus = focusedItemIndex - 1;
192
+ }
193
+
194
+ // Skip disabled options
195
+ while (selectOptions[indexToFocus].isDisabled) {
196
+ indexToFocus--;
197
+ if (indexToFocus === -1) {
198
+ indexToFocus = selectOptions.length - 1;
199
+ }
200
+ }
201
+ }
202
+
203
+ if (key === 'ArrowDown') {
204
+ // When no index is set or at the last index, focus to the first, otherwise increment focus index
205
+ if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
206
+ indexToFocus = 0;
207
+ } else {
208
+ indexToFocus = focusedItemIndex + 1;
209
+ }
210
+
211
+ // Skip disabled options
212
+ while (selectOptions[indexToFocus].isDisabled) {
213
+ indexToFocus++;
214
+ if (indexToFocus === selectOptions.length) {
215
+ indexToFocus = 0;
216
+ }
217
+ }
218
+ }
219
+
220
+ setActiveAndFocusedItem(indexToFocus);
221
+ };
222
+
223
+ const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
224
+ const focusedItem = focusedItemIndex !== null ? selectOptions[focusedItemIndex] : null;
225
+
226
+ switch (event.key) {
227
+ case 'Enter':
228
+ if (isOpen && focusedItem && focusedItem.value !== NO_RESULTS && !focusedItem.isAriaDisabled) {
229
+ selectOption(event, focusedItem?.value);
230
+ }
231
+
232
+ if (!isOpen) {
233
+ onToggle && onToggle(true);
234
+ setIsOpen(true);
235
+ }
236
+
237
+ break;
238
+ case 'ArrowUp':
239
+ case 'ArrowDown':
240
+ event.preventDefault();
241
+ handleMenuArrowKeys(event.key);
242
+ break;
243
+ }
244
+ };
245
+
246
+ const onToggleClick = () => {
247
+ onToggle && onToggle(!isOpen);
248
+ setIsOpen(!isOpen);
249
+ textInputRef?.current?.focus();
250
+ };
251
+
252
+ const onClearButtonClick = (ev: React.MouseEvent) => {
253
+ setSelected([]);
254
+ onInputChange && onInputChange('');
255
+ resetActiveAndFocusedItem();
256
+ textInputRef?.current?.focus();
257
+ onSelectionChange && onSelectionChange(ev, []);
258
+ };
259
+
260
+ const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
261
+ <MenuToggle
262
+ ref={toggleRef}
263
+ variant="typeahead"
264
+ aria-label="Multi select Typeahead menu toggle"
265
+ onClick={onToggleClick}
266
+ isExpanded={isOpen}
267
+ isDisabled={isDisabled}
268
+ isFullWidth
269
+ style={
270
+ {
271
+ width: toggleWidth
272
+ } as React.CSSProperties
273
+ }
274
+ {...toggleProps}
275
+ >
276
+ <TextInputGroup isPlain>
277
+ <TextInputGroupMain
278
+ value={inputValue}
279
+ onClick={onInputClick}
280
+ onChange={onTextInputChange}
281
+ onKeyDown={onInputKeyDown}
282
+ autoComplete="off"
283
+ innerRef={textInputRef}
284
+ placeholder={placeholder}
285
+ {...(activeItemId && { 'aria-activedescendant': activeItemId })}
286
+ role="combobox"
287
+ isExpanded={isOpen}
288
+ aria-controls="select-typeahead-listbox"
289
+ >
290
+ <LabelGroup aria-label="Current selections">
291
+ {selected.map((selection, index) => (
292
+ <Label
293
+ key={index}
294
+ datatest-id={`${selection}-chip`}
295
+ onClick={(ev) => {
296
+ ev.stopPropagation();
297
+ clearOption(ev, selection);
298
+ }}
299
+ >
300
+ {initialOptions.find((o) => o.value === selection)?.content}
301
+ </Label>
302
+ ))}
303
+ </LabelGroup>
304
+ </TextInputGroupMain>
305
+ <TextInputGroupUtilities {...(selected.length === 0 ? { style: { display: 'none' } } : {})}>
306
+ <Button variant="plain" onClick={onClearButtonClick} aria-label="Clear input value">
307
+ <TimesIcon aria-hidden />
308
+ </Button>
309
+ </TextInputGroupUtilities>
310
+ </TextInputGroup>
311
+ </MenuToggle>
312
+ );
313
+
314
+ return (
315
+ <Select
316
+ isOpen={isOpen}
317
+ selected={selected}
318
+ onSelect={_onSelect}
319
+ onOpenChange={(isOpen) => {
320
+ !isOpen && closeMenu();
321
+ }}
322
+ toggle={toggle}
323
+ shouldFocusFirstItemOnOpen={false}
324
+ ref={innerRef}
325
+ {...props}
326
+ >
327
+ <SelectList>
328
+ {selectOptions.map((option, index) => {
329
+ const { content, value, ...props } = option;
330
+
331
+ return (
332
+ <SelectOption key={value} value={value} isFocused={focusedItemIndex === index} {...props}>
333
+ {content}
334
+ </SelectOption>
335
+ );
336
+ })}
337
+ </SelectList>
338
+ </Select>
339
+ );
340
+ };
341
+
342
+ MultiTypeaheadSelectBase.displayName = 'MultiTypeaheadSelectBase';
343
+
344
+ export const MultiTypeaheadSelect = React.forwardRef((props: MultiTypeaheadSelectProps, ref: React.Ref<any>) => (
345
+ <MultiTypeaheadSelectBase {...props} innerRef={ref} />
346
+ ));
347
+
348
+ MultiTypeaheadSelect.displayName = 'MultiTypeaheadSelect';
@@ -1,19 +1,25 @@
1
1
  import React from 'react';
2
- import { Select, SelectList, SelectOption, SelectOptionProps } from '@patternfly/react-core/dist/esm/components/Select';
3
- import { MenuToggle, MenuToggleElement } from '@patternfly/react-core/dist/esm/components/MenuToggle';
2
+ import {
3
+ Select,
4
+ SelectList,
5
+ SelectOption,
6
+ SelectOptionProps,
7
+ SelectProps
8
+ } from '@patternfly/react-core/dist/esm/components/Select';
9
+ import { MenuToggle, MenuToggleElement, MenuToggleProps } from '@patternfly/react-core/dist/esm/components/MenuToggle';
4
10
 
5
- export interface SelectSimpleOption extends Omit<SelectOptionProps, 'content'> {
11
+ export interface SimpleSelectOption extends Omit<SelectOptionProps, 'content'> {
6
12
  /** Content of the select option. */
7
13
  content: React.ReactNode;
8
14
  /** Value of the select option. */
9
15
  value: string | number;
10
16
  }
11
17
 
12
- export interface SelectSimpleProps {
18
+ export interface SimpleSelectProps extends Omit<SelectProps, 'toggle'> {
13
19
  /** @hide Forwarded ref */
14
20
  innerRef?: React.Ref<any>;
15
21
  /** Initial options of the select. */
16
- initialOptions?: SelectSimpleOption[];
22
+ initialOptions?: SimpleSelectOption[];
17
23
  /** Callback triggered on selection. */
18
24
  onSelect?: (_event: React.MouseEvent<Element, MouseEvent>, selection: string | number) => void;
19
25
  /** Callback triggered when the select opens or closes. */
@@ -22,11 +28,15 @@ export interface SelectSimpleProps {
22
28
  isDisabled?: boolean;
23
29
  /** Content of the toggle. Defaults to the selected option. */
24
30
  toggleContent?: React.ReactNode;
25
- /** Width of the toggle */
31
+ /** Placeholder text for the select input. */
32
+ placeholder?: string;
33
+ /** Width of the toggle. */
26
34
  toggleWidth?: string;
35
+ /** Additional props passed to the toggle. */
36
+ toggleProps?: MenuToggleProps;
27
37
  }
28
38
 
29
- const SelectSimpleBase: React.FunctionComponent<SelectSimpleProps> = ({
39
+ const SimpleSelectBase: React.FunctionComponent<SimpleSelectProps> = ({
30
40
  innerRef,
31
41
  initialOptions,
32
42
  isDisabled,
@@ -34,16 +44,23 @@ const SelectSimpleBase: React.FunctionComponent<SelectSimpleProps> = ({
34
44
  onToggle,
35
45
  toggleContent,
36
46
  toggleWidth = '200px',
47
+ toggleProps,
48
+ placeholder = 'Select a value',
37
49
  ...props
38
- }: SelectSimpleProps) => {
50
+ }: SimpleSelectProps) => {
39
51
  const [isOpen, setIsOpen] = React.useState(false);
40
- const [selected, setSelected] = React.useState<string>('Select a value');
52
+ const [selected, setSelected] = React.useState<SimpleSelectOption | undefined>();
53
+
54
+ React.useEffect(() => {
55
+ const selectedOption = initialOptions?.find((option) => option.selected);
56
+ setSelected(selectedOption);
57
+ }, [initialOptions]);
41
58
 
42
59
  const simpleSelectOptions = initialOptions?.map((option) => {
43
60
  const { content, value, ...props } = option;
44
- const isSelected = selected.includes(`${value}`);
61
+ const isSelected = selected?.value === value;
45
62
  return (
46
- <SelectOption {...props} value={value} key={value} isSelected={isSelected}>
63
+ <SelectOption value={value} key={value} isSelected={isSelected} {...props}>
47
64
  {content}
48
65
  </SelectOption>
49
66
  );
@@ -56,7 +73,8 @@ const SelectSimpleBase: React.FunctionComponent<SelectSimpleProps> = ({
56
73
 
57
74
  const _onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, value: string | number | undefined) => {
58
75
  onSelect && onSelect(_event, value);
59
- setSelected(value as string);
76
+ setSelected(initialOptions.find((o) => o.value === value));
77
+ onToggle && onToggle(true);
60
78
  setIsOpen(false);
61
79
  };
62
80
 
@@ -71,18 +89,21 @@ const SelectSimpleBase: React.FunctionComponent<SelectSimpleProps> = ({
71
89
  width: toggleWidth
72
90
  } as React.CSSProperties
73
91
  }
92
+ {...toggleProps}
74
93
  >
75
- {toggleContent ? toggleContent : selected}
94
+ {toggleContent ? toggleContent : selected?.content || placeholder}
76
95
  </MenuToggle>
77
96
  );
78
97
 
79
98
  return (
80
99
  <Select
81
- id="single-select"
82
100
  isOpen={isOpen}
83
101
  selected={selected}
84
102
  onSelect={_onSelect}
85
- onOpenChange={(isOpen) => setIsOpen(isOpen)}
103
+ onOpenChange={(isOpen) => {
104
+ onToggle && onToggle(isOpen);
105
+ setIsOpen(isOpen);
106
+ }}
86
107
  toggle={toggle}
87
108
  shouldFocusToggleOnSelect
88
109
  ref={innerRef}
@@ -93,8 +114,8 @@ const SelectSimpleBase: React.FunctionComponent<SelectSimpleProps> = ({
93
114
  );
94
115
  };
95
116
 
96
- export const SelectSimple = React.forwardRef((props: SelectSimpleProps, ref: React.Ref<any>) => (
97
- <SelectSimpleBase {...props} innerRef={ref} />
117
+ export const SimpleSelect = React.forwardRef((props: SimpleSelectProps, ref: React.Ref<any>) => (
118
+ <SimpleSelectBase {...props} innerRef={ref} />
98
119
  ));
99
120
 
100
- SelectSimple.displayName = 'SelectSimple';
121
+ SimpleSelect.displayName = 'SimpleSelect';