I use react virtualized to show some items. My problem is now how can I add margin for each box to have space between every box ?
here is a sandbox you see all boxes are bordered and have no space. How can I add space ?
and here is my list code
export function VirtualizedGrid<ItemType>({
items,
renderItem,
itemHeight,
itemMinWidth,
numColumns,
registerChild,
onRowsRendered
}: VirtualizedGridProps<ItemType>): JSX.Element {
const gridRef = useRef<any>(null);
const containerRef = useRef<any>(null);
const containerWidth = containerRef?.current?.clientWidth ?? 0;
const windowSize = useWindowSize();
useEffect(() => {
gridRef.current?.recomputeGridSize();
}, [windowSize]);
function calculateColumnCount(width: number) {
return Math.floor(width / itemMinWidth);
}
function calculateItemWidth(width: number, columnCount: number) {
return width / columnCount;
}
const columnCount = numColumns ?? calculateColumnCount(containerWidth);
const rowCount = Math.ceil(items.length / columnCount);
const itemWidth = calculateItemWidth(containerWidth, columnCount);
return (
<Container ref={containerRef}>
<WindowScroller>
{({ height, isScrolling, onChildScroll, scrollTop }) => (
<AutoSizer disableHeight>
{() => {
return (
<Grid
// ref={gridRef}
ref={(el) => {
registerChild(el);
gridRef.current = el;
}}
autoHeight
columnCount={columnCount}
columnWidth={itemWidth}
width={containerWidth}
height={height}
rowCount={rowCount}
rowHeight={itemHeight}
isScrolling={isScrolling}
scrollTop={scrollTop}
onScroll={onChildScroll}
cellRenderer={(props: GridCellProps) => {
const fullProps: VirtualizedGridItemProps<ItemType> = {
...props,
items,
columnCount: columnCount
};
return renderItem(fullProps);
}}
/>
);
}}
</AutoSizer>
)}
</WindowScroller>
</Container>
);
}
Just add conditional padding based on items indexes to the Container element of your TestGridItem.tsx.
Here is Sandbox example based on your code
import { motion } from "framer-motion";
import React from "react";
import styled from "styled-components";
import { VirtualizedGridItemProps } from "./interfaces";
/**
* Interfaces
*/
interface TestObject {
id: number;
name: string;
}
export interface TestGridItemProps
extends VirtualizedGridItemProps<TestObject> {}
/**
* Styles
*/
const GAP_BETWEEN_ITEMS = "10px";
const Container = styled.div<{
isFirstCol: boolean;
isLastCol: boolean;
isFirstRow: boolean;
}>`
display: flex;
padding-left: ${(props) => (props.isFirstCol ? "0px" : GAP_BETWEEN_ITEMS)};
padding-top: ${(props) => (props.isFirstRow ? "0px" : GAP_BETWEEN_ITEMS)};
`;
const Card = styled(motion.div)`
background: #111111;
border: 1px solid rgba(255, 255, 255, 0.1);
color: white;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
height: 100%;
font-family: sans-serif;
font-weight: 600;
text-align: center;
padding: 12px;
`;
/**
* Component
*/
export function TestGridItem({
items,
columnCount,
rowIndex,
columnIndex,
style,
}: TestGridItemProps): JSX.Element {
const index = rowIndex * columnCount + columnIndex;
if (index > items.length - 1) {
return <></>;
}
const isFirstCol = columnIndex === 0;
const isLastCol = columnIndex === columnCount - 1;
const isFirstRow = rowIndex === 0;
return (
<Container
style={style}
isFirstCol={isFirstCol}
isLastCol={isLastCol}
isFirstRow={isFirstRow}
>
<Card
variants={{
hidden: {
opacity: 0,
},
visible: {
opacity: 1,
},
}}
initial="hidden"
animate="visible"
>
{`${items[index].name} (ID: ${items[index].id})`}
</Card>
</Container>
);
}