react-virtuoso
react-virtuoso copied to clipboard
How to get the current visible group in a GroupedVirtuoso?
Hey there, is there a way to efficiently get the current group in a GroupedVirtuoso? I currently do not see any Subscription for that.
I've tried to use rangeChanged but it seems it will misscount near the end of a list.
See this example that is using the GroupedVirtuoso example in combination with rangeChanged.
Do I really have to add some kind of counting logic myself or did I miss something?
rangeChanged={({startIndex}) => {
let countLeft = startIndex;
let group: string | undefined;
for (let i = 0; i < groupSizes.length; i++){
const groupSize = groupSizes[i] + 1/*groupHeader*/;
if (countLeft - groupSize <= 0) {
group = groups[i];
break;
}
countLeft -= groupSize;
}
if (group) {
console.log(group);
}
}}
Are you looking for all visible groups or the "sticky" group?
Well I think it's easier if I just somehow get the sticky group that is on top. But if possible finding out what is in the center of the screen would also be nice.
Can you show me what UI are you building? I need to give this a better thought.
It is literally like the the example that I've linked. But instead of Current visible range: I would like to see the current group.
https://stackblitz.com/edit/react-xfltju?file=example.js
Technically there should be a list of all groups and I want to highlight the current group: https://virtuoso.dev/scroll-to-group/
I need something similar. Is there a way to get the current index at the top of the scroll area? Not the range because seems the overscan affects it.
I've got the exact same requirement. My use case is exactly the same as the following:
I think what's probably better, is knowing the visible groups.
https://www.loom.com/share/825e54480da944679de7eae9c74d0cd9
So I finally got around thinking about this again and thanks to @carstenpatzke to providing the solution for me to work on.
useEffect(() => {
const categoryRanges = {}
categoryRanges[0] = { min: 0, max: 63 } // people
categoryRanges[1] = { min: 64, max: 81 } // nature
categoryRanges[2] = { min: 82, max: 98 } // food
categoryRanges[3] = { min: 99, max: 109 } // activities
categoryRanges[4] = { min: 110, max: 136 } // transport
categoryRanges[5] = { min: 137, max: 168 } // objects
categoryRanges[6] = { min: 169, max: 196 } // symbols
categoryRanges[7] = { min: 197, max: 230 } // flags
if (visibleRange[0]) {
Object.keys(categoryRanges).forEach((_, index) => {
const range = categoryRanges[index] as categoryRange
const rangeMin = visibleRange[0] as number
if (rangeMin >= range.min && rangeMin <= range.max) {
snapshot.setCategoryId(index)
}
})
}
}, [visibleRange, snapshot])