Last active
June 8, 2020 09:41
-
-
Save janjakubnanista/d4ea4249f76a48b93c8fc914d6c16833 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Approach 2: let's define a whole new component type and let it handle the item rendering completely | |
// | |
// This way we are free to handle the rendering and selecting/deselecting anyway we want | |
export interface SelectProps<T> { | |
// ... previous props | |
itemComponent: React.ComponentType<SelectItemProps<T>>; | |
} | |
// These will be the props of our new item component | |
export interface SelectItemProps<T> { | |
selected: boolean; | |
value: T; | |
onToggle: (value: T) => void; | |
} | |
export function Select<T>({ items, value, idFromValue, itemComponent: ItemComponent, onChange }: SelectProps<T>) { | |
const selectedId = value === undefined ? undefined : idFromValue(value); | |
const isSelected = (id: string | number) => id === selectedId; | |
const handleToggle = (value: T) => onChange?.(isSelected(idFromValue(value)) ? undefined : value); | |
return <div> | |
{items.map(item => { | |
const id = idFromValue(item); | |
const selected = isSelected(id); | |
// We need to rename the itemComponent prop to something that starts | |
// with an uppercase letter because if we write | |
// | |
// <itemComponent ... /> | |
// | |
// React is going to think we want to use a HTML tag called "itemComponent" | |
return <ItemComponent key={id} value={item} selected={selected} onToggle={handleToggle} />; | |
})} | |
</div>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment