Skip to content

Instantly share code, notes, and snippets.

@janjakubnanista
Created June 2, 2020 09:35
Show Gist options
  • Save janjakubnanista/dd36cd02b4bdd3adb32727f4b7b56b30 to your computer and use it in GitHub Desktop.
Save janjakubnanista/dd36cd02b4bdd3adb32727f4b7b56b30 to your computer and use it in GitHub Desktop.
// Approach 1: let's define a prop that turns a value into a human readable label
//
// In this case Select will be rendering the "item container" and will put
// this label into the container
export interface SelectProps<T> {
// ... previous props
labelFromValue: (value: T) => React.ReactNode;
}
// 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
// BUT we will need to create such a component for every T
export interface SelectItemProps<T> {
selected: boolean;
value: T;
onToggle?: (value: T | undefined) => void;
}
export interface SelectProps<T> {
// ... previous props
itemComponent: React.ComponentType<SelectItemProps<T>>;
}
// Approach 3: Let's merge Approach 1 and Approach 2!
//
// We will adjust the SelectItemProps to accept children:
export interface SelectItemProps<T> {
children?: React.ReactNode;
selected: boolean;
value: T;
onToggle?: (value: T | undefined) => void;
}
// And will add both labelFromValue and itemComponent props to SelectProps:
export interface SelectProps<T> {
// ... previous props
itemComponent: React.ComponentType<SelectItemProps<T>>;
labelFromValue: (value: T) => React.ReactNode;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment