I'm using styled components and typescript and I want to get the value of the selected option of a custom dropdown but I don't understand why it doesn't work. If I remove the opacity from the native select element I can see that the value gets updated but that's not what I want. (I'm just starting out with typescript) Here's my dropdown:
label?: string;
value?: string;
iconId?: IconId;
}
const SelectGroup = styled.div`
position: relative;
width: max-content;
`;
const NativeSelect = styled.select`
position: absolute;
width: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
`;
const CustomSelect = styled.div`
border: 1px solid;
line-height: 2rem;
width: 25rem;
height: 5rem;
border-color: rgba(255, 255, 255, 0.4);
background: ${theme.color.darkGrey};
color: ${theme.color.white};
transition: border-color 0.15s ease-in;
${NativeSelect}:focus + & {
border-color: rgba(255, 255, 255, 0.8);
}
`;
const IconContainer = styled.div`
position: absolute;
top: 1.4rem;
right: 2rem;
pointer-events: none;
`;
const InputLabel = styled.label`
display: block;
padding-bottom: 1rem;
color: ${theme.color.white};
font-size: ${theme.font.size.small};
`;
export const SelectInput: FC<SelectProps> = ({
label,
value,
iconId,
children,
}) => {
return (
<>
<InputLabel>{label}</InputLabel>
<SelectGroup>
<NativeSelect value={value}>{children}</NativeSelect>
<CustomSelect>
<IconContainer>
<Icon iconId={iconId} />
</IconContainer>
</CustomSelect>
</SelectGroup>
</>
);
};
const [inputValue, setInputValue] = useState('');
const updateInputValue = (value: string): void => {
setInputValue(value);
};
<SelectInput
label="Select"
iconId="select"
defaultValue={inputValue}
onChange={e => updateInputValue(e.target.value)}
>
<option value="saab">Saab</option>
<option value="volvo">Volvo</option>
</SelectInput>
You have missed value
prop in the SelectInput. defaultValue
only sets the value on initial load, if we want to change that we update value property. As the component is a controlled, value of SelectInput changes, we need to update that.
<SelectInput
label="Select"
iconId="select"
defaultValue={inputValue}
value={inputValue}
onChange={e => updateInputValue(e.target.value)}
>
<option value="saab">Saab</option>
<option value="volvo">Volvo</option>
</SelectInput>