Skip to content

Instantly share code, notes, and snippets.

@louis-young
Created December 7, 2023 12:14
Show Gist options
  • Save louis-young/d880fda7dcffff963cbe463db9802b2b to your computer and use it in GitHub Desktop.
Save louis-young/d880fda7dcffff963cbe463db9802b2b to your computer and use it in GitHub Desktop.
Generic select input React component
import { type ChangeEvent, useState } from "react";
type SelectInputOption<TOptionValue> = {
label: string;
value: TOptionValue;
};
interface SelectInputProps<TOptionValue> {
options: Array<SelectInputOption<TOptionValue>>;
selectedValue: TOptionValue;
onSelectedValueChange: (newSelectedValue: TOptionValue) => void;
}
export const SelectInput = <TOptionValue extends string | number>({
options,
selectedValue,
onSelectedValueChange,
}: SelectInputProps<TOptionValue>) => {
const handleSelectedValueChange = (event: ChangeEvent<HTMLSelectElement>) => {
const newSelectedOptionIndex = Number(event.target.value);
const newSelectedValueOption = options[newSelectedOptionIndex];
onSelectedValueChange(newSelectedValueOption.value);
};
return (
<select
value={options.findIndex(({ value }) => value === selectedValue)}
onChange={handleSelectedValueChange}
>
{options.map(({ label, value }, index) => (
<option value={index} key={value}>
{label}
</option>
))}
</select>
);
};
export const Application = () => {
const [selectedValue, setSelectedValue] = useState<"apple" | "orange">("apple");
return (
<SelectInput
options={[
{ label: "Apple", value: "apple" },
{ label: "Orange", value: "orange" },
]}
selectedValue={selectedValue}
onSelectedValueChange={setSelectedValue}
/>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment