Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save janjakubnanista/27da6ff1876eef470f1cbb9954e7a020 to your computer and use it in GitHub Desktop.
Save janjakubnanista/27da6ff1876eef470f1cbb9954e7a020 to your computer and use it in GitHub Desktop.
// Approach 1: let's define a prop that turns a value into a ReactNode
export interface SelectProps<T> {
// ... Previous props
labelFromValue: (value: T) => React.ReactNode;
}
export function Select<T>({ items, value, idFromValue, labelFromValue, onChange }: SelectProps<T>) {
const selectedId = value === undefined ? undefined : idFromValue(value);
// We will define a little helper just to make things cleaner
const isSelected = (id: string | number) => id === selectedId;
// And a single toggle handler that we pass down to all items
const handleToggle = (value: T) => onChange?.(isSelected(idFromValue(value)) ? undefined : value);
return <div>
{items.map(item => {
const id = idFromValue(item);
const selected = isSelected(id);
const label = labelFromValue(item);
return <div key={id}>
<label>
{/* For brevity I decided to use a simple checkbox to show the selected state */}
<input type="checkbox" checked={selected} onChange={handleToggle}/>
{/* And here we render our label */}
<span>{label}</span>
</label>
</div>;
})}
</div>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment