I'd like to know how to nicely add types to a Select using react-select.
The component so far looks like this:
const Select: React.FC<Select> = (
{defaultValue, onChange, options}: Select) => (
<ReactSelect
styles={selectStyles}
…
</ReactSelect>
and the definition of selectStyles:
interface HoverProps {
bowShadow: string
border: string
}
interface ControlComponentCSSProperties extends CSSProperties {
'&:hover': HoverProps
}
const selectStyles = {
control: (
provided: CSSProperties,
state: Props<{label: string; value: string}> | Props<Record<string, unknown>>
): ControlComponentCSSProperties => ({
...provided,
'&:hover': {
bowShadow: 'none',
border: 'none',
},
border: 'none',
borderRadius: input.border.radius,
borderBottomLeftRadius: state.menuIsOpen ? 0 : input.border.radius,
borderBottomRightRadius: state.menuIsOpen ? 0 : input.border.radius,
…
This passes tsc but surely there are simpler ways to type this selectStyles object.
Would appreciate your help pointing me in a better direction. Cheers!
If you have a single-select you can type onChange like this: const onChange = (option: Option | null, actionMeta: ActionMeta<Option>) => { ... } If you have a multi-select you can type onChange like this: const onChange = (option: readonly Option[], actionMeta: ActionMeta<Option>) => { ... }
Setting value for the select React provides us with a shared API between <input type="text"> , <textarea> and <select> where we can use value or defaultValue (depending if the input is controlled or not) to set the field's value.
You can type the whole style object by using StyleConfig which removes the need to type every params manually. But before that you'll need to install @types/react-select package.
StyleConfig requires you to pass at least 2 generic type variables according to this declaration here.
OptionType: The option type of react-select. According to this, the default OptionType is { label: string; value: string }
IsMulti: a boolean value to determine if you can select multiple values.Putting it all together, we'll have something like this:
import Select, { StylesConfig } from 'react-select';
type MyOptionType = {
label: string;
value: string;
};
const options: MyOptionType[] = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
];
const customControlStyles: CSSProperties = {
color: "white",
borderColor: "pink"
};
type IsMulti = false;
const selectStyle: StylesConfig<MyOptionType, IsMulti> = {
control: (provided, state) => {
// provided has CSSObject type
// state has ControlProps type
// return type is CSSObject which means this line will throw error if uncommented
// return false;
return {
...provided,
...customControlStyles
};
}
};
export function App() {
return (
<Select options={options} styles={selectStyle} />
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With