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