Skip to content

Commit b7550aa

Browse files
jeff-phillips-18tlabaj
authored andcommitted
fix(SimpleSelect,CheckboxSelect): Handle initial selection(s) (patternfly#10734)
1 parent 12c4579 commit b7550aa

File tree

5 files changed

+60
-20
lines changed

5 files changed

+60
-20
lines changed

packages/react-templates/src/components/Select/CheckboxSelect.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ const CheckboxSelectBase: React.FunctionComponent<CheckboxSelectProps> = ({
5151
const [isOpen, setIsOpen] = React.useState(false);
5252
const [selected, setSelected] = React.useState<string[]>([]);
5353

54+
React.useEffect(() => {
55+
const selectedOptions = initialOptions?.filter((option) => option.selected);
56+
setSelected(selectedOptions?.map((selectedOption) => String(selectedOption.value)) ?? []);
57+
}, [initialOptions]);
58+
5459
const checkboxSelectOptions = initialOptions?.map((option) => {
5560
const { content, value, ...props } = option;
5661
const isSelected = selected.includes(`${value}`);

packages/react-templates/src/components/Select/SimpleSelect.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export interface SimpleSelectProps extends Omit<SelectProps, 'toggle'> {
2828
isDisabled?: boolean;
2929
/** Content of the toggle. Defaults to the selected option. */
3030
toggleContent?: React.ReactNode;
31+
/** Placeholder text for the select input. */
32+
placeholder?: string;
3133
/** Width of the toggle. */
3234
toggleWidth?: string;
3335
/** Additional props passed to the toggle. */
@@ -43,14 +45,20 @@ const SimpleSelectBase: React.FunctionComponent<SimpleSelectProps> = ({
4345
toggleContent,
4446
toggleWidth = '200px',
4547
toggleProps,
48+
placeholder = 'Select a value',
4649
...props
4750
}: SimpleSelectProps) => {
4851
const [isOpen, setIsOpen] = React.useState(false);
49-
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]);
5058

5159
const simpleSelectOptions = initialOptions?.map((option) => {
5260
const { content, value, ...props } = option;
53-
const isSelected = selected.includes(`${value}`);
61+
const isSelected = selected?.value === value;
5462
return (
5563
<SelectOption value={value} key={value} isSelected={isSelected} {...props}>
5664
{content}
@@ -65,8 +73,8 @@ const SimpleSelectBase: React.FunctionComponent<SimpleSelectProps> = ({
6573

6674
const _onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, value: string | number | undefined) => {
6775
onSelect && onSelect(_event, value);
68-
setSelected(value as string);
69-
onToggle && onToggle(!false);
76+
setSelected(initialOptions.find((o) => o.value === value));
77+
onToggle && onToggle(true);
7078
setIsOpen(false);
7179
};
7280

@@ -83,7 +91,7 @@ const SimpleSelectBase: React.FunctionComponent<SimpleSelectProps> = ({
8391
}
8492
{...toggleProps}
8593
>
86-
{toggleContent ? toggleContent : selected}
94+
{toggleContent ? toggleContent : selected?.content || placeholder}
8795
</MenuToggle>
8896
);
8997

packages/react-templates/src/components/Select/__tests__/__snapshots__/CheckboxSelectSnapshots.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ exports[`opened checkbox select snapshot 1`] = `
7575
</button>
7676
<div
7777
class="pf-v5-c-menu"
78-
data-ouia-component-id="OUIA-Generated-Select-3"
78+
data-ouia-component-id="OUIA-Generated-Select-5"
7979
data-ouia-component-type="PF5/Select"
8080
data-ouia-safe="true"
8181
data-popper-escaped="true"
Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
import React from 'react';
22
import { CheckboxSelect, CheckboxSelectOption } from '@patternfly/react-templates';
33

4+
const Options: { content: string; value: string; description?: string; isDisabled?: boolean }[] = [
5+
{ content: 'Option 1', value: 'option-1' },
6+
{ content: 'Option 2', value: 'option-2', description: 'Option with description' },
7+
{ content: 'Option 3', value: 'option-3', isDisabled: true },
8+
{ content: 'Option 4', value: 'option-4' }
9+
];
10+
411
export const SelectBasic: React.FunctionComponent = () => {
5-
const initialOptions: CheckboxSelectOption[] = [
6-
{ content: 'Option 1', value: 'option-1' },
7-
{ content: 'Option 2', value: 'option-2', description: 'Option with description' },
8-
{ content: 'Option 3', value: 'option-3', isDisabled: true },
9-
{ content: 'Option 4', value: 'option-4' }
10-
];
11-
12-
return <CheckboxSelect initialOptions={initialOptions} />;
12+
const [selected, setSelected] = React.useState<string[]>(['option-2']);
13+
14+
const initialOptions = React.useMemo<CheckboxSelectOption[]>(
15+
() => Options.map((o) => ({ ...o, selected: selected.includes(o.value) })),
16+
[selected]
17+
);
18+
19+
return (
20+
<CheckboxSelect
21+
initialOptions={initialOptions}
22+
onSelect={(_ev, value) => {
23+
const val = String(value);
24+
setSelected((prevSelected) =>
25+
prevSelected.includes(val) ? prevSelected.filter((item) => item !== val) : [...prevSelected, String(val)]
26+
);
27+
}}
28+
/>
29+
);
1330
};

packages/react-templates/src/components/Select/examples/SimpleSelectDemo.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ import React from 'react';
22
import { Checkbox } from '@patternfly/react-core';
33
import { SimpleSelect, SimpleSelectOption } from '@patternfly/react-templates';
44

5+
const Options: SimpleSelectOption[] = [
6+
{ content: 'Option 1', value: 'Option1' },
7+
{ content: 'Option 2', value: 'Option2', description: 'Option with description' },
8+
{ content: 'Option 3', value: 'Option3' }
9+
];
10+
511
export const SelectSimpleDemo: React.FunctionComponent = () => {
612
const [isDisabled, setIsDisabled] = React.useState<boolean>(false);
13+
const [selected, setSelected] = React.useState<string | undefined>('Option1');
714

8-
const initialOptions: SimpleSelectOption[] = [
9-
{ content: 'Option 1', value: 'Option 1' },
10-
{ content: 'Option 2', value: 'Option 2', description: 'Option with description' },
11-
{ content: 'Option 3', value: 'Option 3' }
12-
];
15+
const initialOptions = React.useMemo<SimpleSelectOption[]>(
16+
() => Options.map((o) => ({ ...o, selected: o.value === selected })),
17+
[selected]
18+
);
1319

1420
return (
1521
<React.Fragment>
@@ -20,7 +26,11 @@ export const SelectSimpleDemo: React.FunctionComponent = () => {
2026
onChange={(_event, checked) => setIsDisabled(checked)}
2127
style={{ marginBottom: 20 }}
2228
/>
23-
<SimpleSelect initialOptions={initialOptions} isDisabled={isDisabled} />
29+
<SimpleSelect
30+
initialOptions={initialOptions}
31+
isDisabled={isDisabled}
32+
onSelect={(_ev, selection) => setSelected(String(selection))}
33+
/>
2434
</React.Fragment>
2535
);
2636
};

0 commit comments

Comments
 (0)