Skip to content

Instantly share code, notes, and snippets.

@davidgilbertson
Last active April 18, 2021 07:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidgilbertson/f727558abae08b407b8a92a6d2600a2e to your computer and use it in GitHub Desktop.
Save davidgilbertson/f727558abae08b407b8a92a6d2600a2e to your computer and use it in GitHub Desktop.
type BaseProps<IdType> = {
options: Array<{id: IdType; name: string}>;
};
type PropsWhenOptional<IdType> = BaseProps<IdType> & {
required?: false;
selectedItemId?: IdType | null;
onSelect: (id: IdType | null) => void;
};
type PropsWhenRequired<IdType> = BaseProps<IdType> & {
required: true;
selectedItemId?: IdType;
onSelect: (id: IdType) => void;
};
const Select = <IdType extends string>(
props: PropsWhenOptional<IdType> | PropsWhenRequired<IdType>,
) => (
<select
value={props.selectedItemId ?? 'NULL_SELECTION'}
required={props.required}
onChange={e => {
const value = e.target.value as IdType;
if (!props.required) {
const selectedId = !props.required && e.target.value === 'NULL_SELECTION' ? null : value;
props.onSelect(selectedId);
} else {
props.onSelect(value);
}
}}
>
{!props.required && <option value="NULL_SELECTION">None selected</option>}
{props.options.map(option => (
<option key={option.id} value={option.id}>
{option.name}
</option>
))}
</select>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment