T
TanStack2y ago
passive-yellow

Is there a documented way to make a responsive grid list?

Can you share an example of a responsive grid list? I tried using lanes, dynamically substituting the number of lines there, but it didn't work
42 Replies
rising-crimson
rising-crimson2y ago
Hi, what do you understand under responsive grid list? Basic each row size should grow till max size from each column?
passive-yellow
passive-yellowOP2y ago
When changing the width of the window, the columns should adjust themselves, as if I had written
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
rising-crimson
rising-crimson2y ago
oo this can be tricky, you need to resolve how many columns can fit in viewport
flat-fuchsia
flat-fuchsia2y ago
I have also been looking for a way to do this. The only references I have found are all using the autosizer component from the react-virtualized lib which is very much unmaintained. this is the example in mind: https://codesandbox.io/p/sandbox/react-virtualized-responsive-card-grid-7ry39g @piecyk is there an example of something similar using react-virtual?
rising-crimson
rising-crimson2y ago
yeah you can implement something similar using react-virtual
flat-fuchsia
flat-fuchsia2y ago
would it be possible to have an example?
rising-crimson
rising-crimson2y ago
Will try to create one when got a moment
passive-yellow
passive-yellowOP2y ago
It would be very cool, I've been trying to do something like this for several months now
flat-fuchsia
flat-fuchsia2y ago
@piecyk I had to use this https://virtuoso.dev/grid-responsive-columns/ in the meantime - but would very much rather use react-virtual instead
Grid with Responsive Columns | React Virtuoso
The VirtuosoGrid component displays equally-sized items, while supporting multiple items per row.
passive-yellow
passive-yellowOP2y ago
@piecyk Hello! Any updates? Very necessary
rising-crimson
rising-crimson2y ago
pong, let me try to create a quick WIP
rising-crimson
rising-crimson2y ago
@desertir @bogdan.css something like this https://stackblitz.com/edit/tanstack-virtual-8egvwh
Damian Pieczynski
StackBlitz
Virtual Fixed Example (forked) - StackBlitz
Run official live example code for Virtual Fixed, created by Tanstack on StackBlitz
passive-yellow
passive-yellowOP2y ago
Oh, thank you!!
rising-crimson
rising-crimson2y ago
So is it working for you, any other issues?
passive-yellow
passive-yellowOP2y ago
I'm still testing, write about the results this week
rising-crimson
rising-crimson2y ago
Ok, ping me with the outcome 🙂
quickest-silver
quickest-silver2y ago
I have a similar (but more complicated) need for react-virtual paired with a fluid grid. I've cobbled together a minimal example here: https://stackblitz.com/edit/react-virtual-fluid-grid?file=src%2FApp.tsx&terminal=dev My requirements are: 1. While all items in the grid will have a uniform height... the item height scales based on the container width (and is therefor not static). I only made items square in the demo to make troubleshooting easier. 2. I require a resize observer (and cannot rely simply on the observeElementRect > observeWindowRect pattern) because outside elements could influence the width of the "virtual container" (not present in the StackBlitz example). 3. I require a gap between items. It would seem that I am most of the way there except that virtualizer.getTotalSize() does not always calculate the correct value, and therefor, the height + scroll "milestones" are off. Most likely this is due to a gap between "resize observer" and applying the updated "item styles". With enough window resizing, I can usually end up with the whole thing working correctly... but of course, I'd need this to work correctly without doing that 😆 If anyone has any advice, it would be greatly appreciated 🙏 Okay, I believe I've actually got this mostly fixed. I forked the original StackBlitz - this "mostly working" version only made minor changes - mostly using measureElement as the way to capture item height: https://stackblitz.com/edit/react-virtual-fluid-grid-fixed?file=src%2FApp.tsx&terminal=dev Feels wrong to call that on every single item though when you know all items will be the same height as the first item measured. My last remaining problem - that I can find at least - is resizing the window can put the measurements out of sync. Scrolling to the top can usually fix it.
rising-crimson
rising-crimson2y ago
@beefchimi something similar using javascript https://stackblitz.com/edit/tanstack-virtual-chmknb
Damian Pieczynski
StackBlitz
Virtual Fixed Example (forked) - StackBlitz
Run official live example code for Virtual Fixed, created by Tanstack on StackBlitz
quickest-silver
quickest-silver2y ago
Hey @piecyk thanks for the reply 😄 Still looking over your solution, but I see that you hard code the aspect ratio within main.tsx. What isn't adequately expressed in my StackBlitz is that the use of aspect-ratio is just for demo purposes. The real-life scenario would be for a set of cards that do not actually have that style applied. In other words, the design would be such that the cards compute to equal heights, but that height is derived from the content within - not a specific style applied via CSS (and therefor, not known ahead of time). So, I think your solution gets around the "item measurement" problem by having a predicatable item height. Unfortunately I can't do that in my solution.
rising-crimson
rising-crimson2y ago
Yep, most cases item height is not know and that is most problematic part when talking about virtualization 🙂 then measureElement should do the trick, if the height is equal maybe measure row not a cell, but didn't dig into your example
quickest-silver
quickest-silver2y ago
Yea it is proving to be a hard problem to solve. Manually calling virtualizer.measure() seems to fix it:
quickest-silver
quickest-silver2y ago
I was hoping that I could call virtualizer.measure() within a useEffect when the columns value changes... but that appears to be too early. Struggling to find the right moment to programatically call this, but I feel like that could be the solution.
passive-yellow
passive-yellowOP2y ago
Hello! Can you show the code of how you reduce the number of elements when opening the sidebar?
quickest-silver
quickest-silver2y ago
@desertir all the code for that Wakurtual prototype can be found here: https://github.com/beefchimi/wakurtual But, all of the relevant react-virtual code should be identical to my most recent StackBlitz test: https://stackblitz.com/edit/react-virtual-fluid-grid-fixed?file=src%2Fdemo%2FuseVirtualWindowGrid%2FuseVirtualWindowGrid.ts&terminal=dev Within the useVirtualWindowGrid.ts file, you will see that I have a useResizeObserver() watching the width changes to the listRef. That width measurement is used to help determine all of the layout measurements for the grid. In @piecyk examples, he listens for the window size. That unfortunately doesn't work for me, since I have this expanding Sidebar component, which is why I require the useResizeObserver.
passive-yellow
passive-yellowOP2y ago
Hello @piecyk ! How can I rewrite this part of the code so that it tracks the width of the container in which the elements are located, and not the width of the window? and at the same time use useWindowVirtualizer I have an element filter open and it narrows the grid
No description
quickest-silver
quickest-silver2y ago
You would need to use a resize observer on the container like Ive done. Im not aware of any way to get this from useWindowVirtualizer.
passive-yellow
passive-yellowOP2y ago
You and I have a very similar problem))
rising-crimson
rising-crimson2y ago
Yep @beefchimi is right, basic you want to track height of viewport and width of some div, this is not build, nevertheless virtual expose observeElementRect, so you can hack something like
const [columnCount, setColumnCount] = React.useState(1);
const columns = Array.from(Array(columnCount).keys());
const count = Math.ceil(itemsCount / columnCount);

const rectRef = React.useRef({ width: 0, height: 0 });
const virtualizer = useWindowVirtualizer({
count,
estimateSize: () => 50,
overscan: 5,
scrollMargin: listRef.current?.offsetTop ?? 0,
observeElementRect: (instance, cb) => {
const r1 = observeElementRect(
{ ...instance, scrollElement: listRef.current } as any,
(r) => {
rectRef.current.width = r.width;
setColumnCount(Math.floor(r.width / itemMinWidth));
cb(rectRef.current);
}
);
const r2 = observeWindowRect(instance, (r) => {
rectRef.current.height = r.height;
cb(rectRef.current);
});

return () => {
r1();
r2();
};
},
});
const [columnCount, setColumnCount] = React.useState(1);
const columns = Array.from(Array(columnCount).keys());
const count = Math.ceil(itemsCount / columnCount);

const rectRef = React.useRef({ width: 0, height: 0 });
const virtualizer = useWindowVirtualizer({
count,
estimateSize: () => 50,
overscan: 5,
scrollMargin: listRef.current?.offsetTop ?? 0,
observeElementRect: (instance, cb) => {
const r1 = observeElementRect(
{ ...instance, scrollElement: listRef.current } as any,
(r) => {
rectRef.current.width = r.width;
setColumnCount(Math.floor(r.width / itemMinWidth));
cb(rectRef.current);
}
);
const r2 = observeWindowRect(instance, (r) => {
rectRef.current.height = r.height;
cb(rectRef.current);
});

return () => {
r1();
r2();
};
},
});
https://stackblitz.com/edit/tanstack-virtual-czepgn
Damian Pieczynski
StackBlitz
Virtual Fixed Example (forked) - StackBlitz
Run official live example code for Virtual Fixed, created by Tanstack on StackBlitz
quickest-silver
quickest-silver2y ago
Just coming back to this to mention that I had to roll my own solution in order to solve the problem I was facing. In case it is useful to any future readers: https://github.com/beefchimi/vurtis There is a StackBlitz demo included in the README. So far, this has been working well for me, but I would likely switch back to react-virtual if I ever figure out how to solve my use-case.
GitHub
GitHub - beefchimi/vurtis: Fluid grid virtualization for React
Fluid grid virtualization for React. Contribute to beefchimi/vurtis development by creating an account on GitHub.
magic-amber
magic-amber2y ago
Use react-virtuoso hands down best virtualized solution for react works very well for responsive grids it's way better than tanstack virtual in every aspects
rising-crimson
rising-crimson2y ago
Great that it works for you 👍
multiple-amethyst
multiple-amethyst17mo ago
Has anyone been able to find a virtualized grid solution that support all of these features? - SSR - Responsive with a dynamic number of columns - Window scrolling I keep finding solutions and libraries that miss support for one of those. I believe the solution would need to work with CSS grid to properly render on the server without producing a client hydration issue - @tanstack/virtual: doesn't work well with SSR since it doesn't use CSS grid - react-cool-virtual: doesn't support window scrolling - vurtis: doesn't support SSR (@beefchimi right?) @Bhunter do you know if react-virtuoso support all of those features?
quickest-silver
quickest-silver17mo ago
Hello 👋 I do have a little Waku demo app for Vurtis, as I would love to explore what is needed to fully support SSR / RSC, but at the moment I cannot say what that work would be. I also haven’t had any more time to devote to this problem so there is no guarantee that Id ever get around to it.
rising-crimson
rising-crimson17mo ago
@tanstack/virtual: doesn't work well with SSR since it doesn't use CSS grid
@Igor Gassmann css grid will not be rednered on server as there is no layout, i think every solution will use some kind of pre estimated sizes
conscious-sapphire
conscious-sapphire17mo ago
Does anyone here know how to integrate flex gird column resizing with virtual table rows? I'm using a grid layout on my table to achieve column flexing. But I'm having trouble virtualizing the table rows and applying the appropriate CSS to maintain the column flexing. Here's a Stackbiz that demonstrates the column resizing solution I've got going on: https://stackblitz.com/edit/tanstack-table-kvo5cj?file=src%2Fmain.tsx
Jake Godin
StackBlitz
Table Column Resizing Performant Example (forked) - StackBlitz
Run official live example code for Table Column Resizing Performant, created by Tanstack on StackBlitz
rising-crimson
rising-crimson17mo ago
@yase grid layout will not work here, the issue is that virtualization is only rendering subset of the elements and because of that browser can't really calculate stuff for layout.
I'm using a grid layout on my table to achieve column flexing
What is your use case, column flexing? basic resizing?
ratty-blush
ratty-blush17mo ago
Im also struggling with what’s been discussed here. Tried applying piecyk’s example and adjust it to have horizontally scrollable div with grid but it’s not rendering the rows that are virtual… I shared the code here https://discord.com/channels/719702312431386674/1233325498776420362 if anyone could guide my what that’s happening I’d be grateful 🙂
conscious-sapphire
conscious-sapphire17mo ago
What is your use case, column flexing? basic resizing?
Yes, column flexing paired with resizing, and of course virtualization. Material React Table by @KevinVandy (uses both Tanstack Table and Virtual) has an example of what I'm looking for: https://stackblitz.com/edit/github-5cysa5?file=src%2FTS.tsx (note layoutMode set to grid). Seems like it takes a slightly different approach than what I have in my example. I can take dig through MRT's code but maybe you or @KevinVandy have some pointers to get me started?
wise-white
wise-white17mo ago
MRT uses pretty much the same virtualization techniques that I put in the TanStack Table docs examples with virtualization.
passive-yellow
passive-yellowOP16mo ago
Hey @piecyk , do you plan to implement grid virtualization like react virtuoso?
rising-crimson
rising-crimson16mo ago
@desertir hmm something like this https://virtuoso.dev/grid-responsive-columns/ didn't we had and example of this alredy 🤔
Grid with Responsive Columns | React Virtuoso
The VirtuosoGrid component displays equally-sized items, while supporting multiple items per row.
rising-crimson
rising-crimson7mo ago
GitHub
How to add horizontal gap? · TanStack virtual · Discussion #710
Hey guys, I recently discovered the new gap option. We use a Masonry list and tried to add space between the elements. It seems that the gap gets only added vertically, but not horizontally. Is the...

Did you find this page helpful?