Closed FezVrasta closed 5 years ago
Yes, I do. Just like you state, I think that fixed width columns are sufficient enough. I don't want to enter the spreadsheet territory :).
Regarding the grid layout: a thing which I consider mandatory is rendering using a single table
tag with thead
, tbody
, so on. Rendering tables as div elements is a major crime against a11y in my book.
Let me know what you think about that. Cheers!
My use case is to render a list of "cards", all with the same height and width, I don't think table
would make sense in my case, since it's not a "tabular data", it's just a list of elements that goes on a new line when there's no more room on the current row.
Also, table
would make the grid difficult to make responsive (so that the number of columns adapts to the page width)
I think I understand what you mean; something like a flexbox / CSS grid-ish layout - for example, https://codepen.io/underlog/pen/joveop. Would virtualizing the layout in this pen work for you?
Some thoughts - these layouts are responsive. Specifying the width/number of columns through JS is a road of pain and futile attempts to re-implement the browser layout engine. I would much rather have the sizing applied through CSS / media queries and have the JS engine infer the number of items necessary to fill in the viewport.
Yes that's the layout I'm talking about. Right now I use react-virtualized
but it's something like 600 lines of code just to render that grid 😓
Hey @FezVrasta - I just published v0.8.0 which includes VirtuosoGrid
- I believe that it should address the case you describe. Check the responsive columns demo. Would love to get some feedback on the approach. Cheers!
I will give it a shot on Monday! Thank you so much!
The itemClassName
and listClassName
properties aren't very CSS-in-JS friendly, with Emotion 10 I need to wrap the component into a ClassNames
render-prop to get access to the css
method.
Thanks, What would be the idiomatic way to handle that in the CSS-in-JS world (I am new to it, so pardon my ignorance)? I can expose *Container
props which accept custom components, like the ones in the initial Virtuoso
components.
That would probably work, the end result would be:
const ItemContainer = styled.div`
[...]
`;
const ListContainer = styled.div`
display: flex;
flex-wrap: wrap;
`;
const Grid = styled(VirtuosoGrid)`
width: 100%;
height: 500px;
`;
<Grid itemContainer={ItemContainer} listContainer={ListContainer} />
I tried to switch out my react-virtualized grid with VirtuosoGrid, but as soon I try to render my real elements and scroll a bit, the whole list starts flickering.
(The element contains text inside, I had to hide everything with > * { opacity: 0 }
because I'm under NDA)
If I render something simple such as <div>{index}</div>
everything works fine. I know it's a long shot, but do you have any idea?
Thanks for the suggestion, I will try the container approach.
Re: the flicker - a wild guess would be elements with margins in the content, that would mess up the calculations.
Another (less likely) is a rounding issue (I have discovered two cases that led me to this fix: https://github.com/petyosi/react-virtuoso/commit/6bbbca0b17a53da9cc2b0d7cc8787e97ff51a165).
A repro case would definitely help me address that. Feel free to reach out on the email from my profile if necessary.
Cheers,
I'm already on 0.8.2 which should include your recent fix.
My grid implementation is:
// @flow
import React, { type Node } from 'react';
import { ClassNames } from '@emotion/core';
import { VirtuosoGrid } from 'react-virtuoso';
const CARD_WIDTH = 364 + 15 * 2;
const CARD_HEIGHT = 247 + 15 * 2;
const Grid = <T>({
items,
item,
fetchMore,
}: {
items: Array<T>,
item: (T, number) => Node,
fetchMore: number => void,
}) => {
return (
<ClassNames>
{({ css }) => (
<VirtuosoGrid
totalCount={items.length}
style={{ height: '100%', width: '100%' }}
itemClassName={css`
width: ${CARD_WIDTH}px;
height: ${CARD_HEIGHT}px;
flex: none;
`}
listClassName={css`
display: flex;
flex-wrap: wrap;
justify-content: center;
&:not(:focus-visible) {
outline: none;
}
`}
endReached={index => fetchMore(index)}
item={index => item(items[index], index)}
/>
)}
</ClassNames>
);
};
export default Grid;
I think the CSS is fine, the margins are applied internally the item, not on its container. Unfortunately I can't share the render item function, I'll try to reduce the code until I find the issue.
Just published v0.9.0 with containers exposed and updated the demo.
Some debugging ideas:
Throw in an overflow: hidden
at the item CSS, just in case.
Maybe the flicker is caused by the component toggling between 3 and 4(?) items per row. The code is doing math trying to guess how many items will fit per row, and, on a few occasions, it turned out that the browser provides wrong numbers. I might have to increase the 0.02
tolerance.
Gonna close this issue since it seems solved for the general public, I'll open a specific one if I ever find out what's going on with my implementation :-)
I need to view the Loading circle with this, but why is there no Footer entry in VirtuosoGrid's components?
Hi, I was wondering if you do plan to support a grid layout? I think a simple fixed column width grid support would be more than enough to cover most of the use cases.