use the selected options in the render (#39535) (#39680)

fixes: #39496


(cherry picked from commit 9cb5b5926dea298c84cd13da93751ed67dabcc12)

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2025-05-14 19:41:18 +02:00 committed by GitHub
parent 63396368d9
commit e40c955333
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 26 deletions

View File

@ -41,7 +41,7 @@ export type SelectControlProps<
name: string;
label?: string;
options: OptionType;
selectedOptions?: SelectControlOption[];
selectedOptions?: OptionType;
labelIcon?: string;
controller: Omit<ControllerProps, "name" | "render">;
onFilter?: (value: string) => void;

View File

@ -30,6 +30,7 @@ export const SingleSelectControl = <
name,
label,
options,
selectedOptions = [],
controller,
labelIcon,
isDisabled,
@ -104,7 +105,7 @@ export const SingleSelectControl = <
isOpen={open}
>
<SelectList data-testid={`select-${name}`}>
{options.map((option) => (
{[...options, ...selectedOptions].map((option) => (
<SelectOption key={key(option)} value={key(option)}>
{isString(option) ? option : option.value}
</SelectOption>

View File

@ -24,6 +24,7 @@ import {
import { getRuleValue } from "../../utils/getRuleValue";
import { FormLabel } from "../FormLabel";
import {
OptionType,
SelectControlOption,
SelectControlProps,
SelectVariant,
@ -65,22 +66,19 @@ export const TypeaheadSelectControl = <
const required = getRuleValue(controller.rules?.required) === true;
const isTypeaheadMulti = variant === SelectVariant.typeaheadMulti;
const filteredOptions = options.filter((option) =>
getValue(option).toLowerCase().startsWith(filterValue.toLowerCase()),
const combinedOptions = useMemo(
() =>
[
...options.filter(
(o) => !selectedOptions.map((o) => getValue(o)).includes(getValue(o)),
),
...selectedOptions,
] as OptionType,
[selectedOptions, options],
);
const convert = useMemo(
() =>
filteredOptions.map((option, index) => (
<SelectOption
key={key(option)}
value={key(option)}
isFocused={focusedItemIndex === index}
>
{getValue(option)}
</SelectOption>
)),
[focusedItemIndex, filteredOptions],
const filteredOptions = combinedOptions.filter((option) =>
getValue(option).toLowerCase().startsWith(filterValue.toLowerCase()),
);
const updateValue = (
@ -96,10 +94,10 @@ export const TypeaheadSelectControl = <
}
} else {
field.onChange([...field.value, option]);
if (isSelectBasedOptions(options)) {
if (isSelectBasedOptions(combinedOptions)) {
setSelectedOptions([
...selectedOptionsState,
options.find((o) => o.key === option)!,
combinedOptions.find((o) => o.key === option)!,
]);
}
}
@ -186,8 +184,8 @@ export const TypeaheadSelectControl = <
{...rest}
onOpenChange={() => setOpen(false)}
selected={
isSelectBasedOptions(options)
? options
isSelectBasedOptions(combinedOptions)
? combinedOptions
.filter((o) =>
Array.isArray(field.value)
? field.value.includes(o.key)
@ -215,8 +213,8 @@ export const TypeaheadSelectControl = <
placeholder={placeholderText}
value={
variant === SelectVariant.typeahead && field.value
? isSelectBasedOptions(options)
? options.find(
? isSelectBasedOptions(combinedOptions)
? combinedOptions.find(
(o) =>
o.key ===
(Array.isArray(field.value)
@ -254,11 +252,10 @@ export const TypeaheadSelectControl = <
);
}}
>
{isSelectBasedOptions(options)
{isSelectBasedOptions(combinedOptions)
? [
...options,
...combinedOptions,
...selectedOptionsState,
...selectedOptions,
].find((o) => selection === o.key)?.value
: getValue(selection)}
</Chip>
@ -298,7 +295,18 @@ export const TypeaheadSelectControl = <
}}
isOpen={open}
>
<SelectList>{convert}</SelectList>
<SelectList>
{filteredOptions.map((option, index) => (
<SelectOption
key={key(option)}
value={key(option)}
isFocused={focusedItemIndex === index}
isActive={field.value.includes(getValue(option))}
>
{getValue(option)}
</SelectOption>
))}
</SelectList>
</Select>
)}
/>