Skip to content

Commit

Permalink
fix(react): select should respond to value changes (#1150)
Browse files Browse the repository at this point in the history
  • Loading branch information
rabelloo authored Nov 26, 2021
1 parent 0d4aa7a commit 60125af
Showing 1 changed file with 20 additions and 12 deletions.
32 changes: 20 additions & 12 deletions packages/react/src/components/select/custom/custom-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { c, classy, m, PopoverProps, SelectProps } from '@onfido/castor';
import React, {
ReactNode,
SyntheticEvent,
useEffect,
useMemo,
useRef,
useState,
Expand Down Expand Up @@ -31,39 +32,46 @@ export function CustomSelect({
onClick,
onKeyUp,
onOpenChange,
value,
...restProps
}: CustomSelectProps) {
const selectRef = useRef<HTMLSelectElement>(null);
const [selectedOption, setSelectedOption] = useState<ReactNode>();
const [value, setValue] = useState(restProps.value ?? defaultValue);
const options = useRef(new Map<typeof value, ReactNode>());
const [currentValue, setCurrentValue] = useState<typeof value>();

// default to first option on first render
useEffect(() => setCurrentValue(value ?? defaultValue), []);

useEffect(() => {
if (value != null) setCurrentValue(value);
}, [value]);

const name = useMemo(
() => initialName || `castor-select-${++id}`,
[initialName]
);

const open = () => onOpenChange?.(true);

const close = () => {
onOpenChange?.(false);
focus(selectRef.current);
};

const selectedOption = options.current.get(currentValue);

return (
<CustomSelectProvider
value={{
name,
selectedOption,
value,
value: currentValue,
initialize(option, optionValue) {
// initial value
if (value == optionValue) setSelectedOption(option);
// or default to first option
else setSelectedOption((current) => current ?? option);
options.current.set(optionValue, option);
},
select(option, value) {
setSelectedOption(option);
setValue(value);
select(option, optionValue) {
// if there are repeated keys, make the selected one take priority
options.current.set(optionValue, option);
setCurrentValue(optionValue);
close();
// propagate onChange manually because <select> won't naturally when
// its value is changed programatically by React, and on next tick
Expand Down Expand Up @@ -96,7 +104,7 @@ export function CustomSelect({
onKeyUp?.(event);
}}
>
{!value || <option hidden value={value} />}
{!currentValue || <option hidden value={currentValue} />}
</NativeSelect>

<output className={classy(c('select-output'))}>{selectedOption}</output>
Expand Down

1 comment on commit 60125af

@vercel
Copy link

@vercel vercel bot commented on 60125af Nov 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.