Skip to content

Commit

Permalink
fix: select multioption not rendering text when you use an options ob…
Browse files Browse the repository at this point in the history
…ject (#2323)

OKTA-795183 chore: added broken example
fix: select rendering values instead of text in multiselect

Signed-off-by: Zheng Chen <[email protected]>
  • Loading branch information
zhengchen-okta authored Aug 28, 2024
1 parent 0c03ec5 commit 4bafbb9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 23 deletions.
50 changes: 27 additions & 23 deletions packages/odyssey-react-mui/src/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,27 +292,31 @@ const Select = <
);
// Normalize the options array to accommodate the various
// data types that might be passed
const normalizedOptions = useMemo(
() =>
options.map((option) => {
if (typeof option === "object") {
/**
* If the value of `option?.value is an empty string, we need to make sure that we
* set an empty string to `value` in the normalized option so that the select component
* can potentially set it as the selected one in the text input
*/
const value =
option?.value === "" ? option.value : option.value || option.text;
return {
text: option.text,
value,
type: option.type === "heading" ? "heading" : "option",
};
}
return { text: option, value: option, type: "option" };
}),
[options],
);
const [normalizedOptions, normalizedOptionsMap] = useMemo(() => {
const normalizedOptions = options.map((option) => {
if (typeof option === "object") {
/**
* If the value of `option?.value is an empty string, we need to make sure that we
* set an empty string to `value` in the normalized option so that the select component
* can potentially set it as the selected one in the text input
*/
const value =
option?.value === "" ? option.value : option.value || option.text;
return {
text: option.text,
value,
type: option.type === "heading" ? "heading" : "option",
};
}

return { text: option, value: option, type: "option" };
});

const normalizedOptionsMap = new Map(
normalizedOptions.map((option) => [option.value, option]),
);
return [normalizedOptions, normalizedOptionsMap];
}, [options]);

const removeSelectedValue = useCallback(
(selectedValue: string) => {
Expand Down Expand Up @@ -346,7 +350,6 @@ const Select = <
!isInteractive &&
controlledStateRef.current === CONTROLLED &&
hasMultipleChoices;

return (
Array.isArray(internalSelectedValues) && (
<ChipsInnerContainer
Expand All @@ -361,7 +364,7 @@ const Select = <
key={item}
label={
<>
{item}
{normalizedOptionsMap.get(item)?.text}
{hasNonInteractiveIcon && (
<NonInteractiveIcon
odysseyDesignTokens={odysseyDesignTokens}
Expand Down Expand Up @@ -397,6 +400,7 @@ const Select = <
internalSelectedValues,
odysseyDesignTokens,
removeSelectedValue,
normalizedOptionsMap,
],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,23 @@ export const OptionsObject: StoryObj<typeof Select> = {
},
};

export const OptionsObjectAndMultiSelect: StoryObj<typeof Select> = {
args: {
options: optionsObject,
value: [],
hasMultipleChoices: true,
},
render: function C(props) {
const [localValue, setLocalValue] = useState<string[]>([]);
const onChange = useCallback(
(event: SelectChangeEvent<string | string[]>) =>
setLocalValue(event.target.value as string[]),
[],
);
return <Select {...props} value={localValue} onChange={onChange} />;
},
};

export const OptionsGrouped: StoryObj<typeof Select> = {
args: {
options: optionsGrouped,
Expand Down

0 comments on commit 4bafbb9

Please sign in to comment.