Open petyosi opened 3 years ago
I think it would be better to revise the props of GroupedVirtuoso to something more intuitive like:
interface GroupedVirtuosoProps<T> extends Omit<VirtuosoProps<T>, 'totalCount' | 'itemContent'> {
groups: {
items: T[]
RenderItem: React.FC<{ item: T, index: number }>
RenderGroup: React.FC
}[]
}
If people want a wrapper you could use this:
export interface CustomGroupedVirtuosoProps<T> extends Omit<VirtuosoProps<T>, 'totalCount' | 'itemContent'> {
groups: {
items: T[]
RenderItem: React.FC<{ item: T, index: number }>
RenderGroup: React.FC
}[]
}
export const CustomGroupedVirtuoso = <T extends unknown>({ groups, ...props }: React.PropsWithChildren<CustomGroupedVirtuosoProps<T>>): React.ReactElement => {
const virtuosoProps = useMemo<Pick<GroupedVirtuosoProps<T>, 'data' | 'itemContent' | 'groupContent' | 'groupCounts'>>(() => {
const groupCounts: number[] = []
let data: T[] = []
const formattedGroups: (Pick<CustomGroupedVirtuosoProps<T>['groups'][0], 'RenderGroup' | 'RenderItem'> & { firstIndex: number })[] = []
let size = 0
groups.forEach(({ items, RenderGroup, RenderItem }) => {
const prevSize = size
size += items.length
groupCounts.push(items.length)
data = data.concat(items)
formattedGroups.push({
firstIndex: prevSize,
RenderGroup: React.memo(RenderGroup),
RenderItem: React.memo(RenderItem)
})
})
const itemContent: GroupedVirtuosoProps<T>['itemContent'] = (globalIndex, groupIndex, item) => {
const { RenderItem, firstIndex } = formattedGroups[groupIndex]
const index = globalIndex - firstIndex
return <RenderItem index={index} item={item} />
}
const groupContent: GroupedVirtuosoProps<T>['groupContent'] = groupIndex => {
const { RenderGroup } = formattedGroups[groupIndex]
return <RenderGroup />
}
return { data, itemContent, groupContent, groupCounts }
}, [groups])
return <GroupedVirtuoso {...props} {...virtuosoProps} />
}
Since the flat and the grouped component are the same, there should be a way to detect the grouped mode. Most intuitive would be an array of arrays. Partially reported in #232.