IconGrid: experiment with various list virtualization libraries

This commit is contained in:
Tobias Fried
2020-07-17 13:24:00 -04:00
parent 44ac4455b7
commit e1dfe6aed1
6 changed files with 238 additions and 17 deletions

View File

@@ -1,27 +1,101 @@
import React from "react";
import React, { useRef, useCallback, useMemo } from "react";
import { useRecoilValue } from "recoil";
import { useVirtual } from "react-virtual";
import { filteredQueryResultsSelector } from "../../state/selectors";
import { iconColorAtom, iconSizeAtom } from "../../state/atoms";
import "./IconGrid.css";
type IconGridProps = {};
const COLUMN_COUNT = 5;
const IconGrid: React.FC<IconGridProps> = () => {
const parentRef = useRef<HTMLDivElement>(null);
const color = useRecoilValue(iconColorAtom);
const size = useRecoilValue(iconSizeAtom);
const filteredQueryResults = useRecoilValue(filteredQueryResultsSelector);
// const categorizedQueryResults = useRecoilValue(categorizedQueryResultsSelector);
// console.log(categorizedQueryResults);
// const rowVirtualizer = useVirtual({
// size: useMemo(() => Math.ceil(filteredQueryResults.length / COLUMN_COUNT), [
// filteredQueryResults,
// ]),
// parentRef,
// estimateSize: useCallback(() => 220 * COLUMN_COUNT, []),
// });
const rowVirtualizer = useVirtual({
size: useMemo(() => Math.ceil(filteredQueryResults.length / COLUMN_COUNT), [
filteredQueryResults,
]),
parentRef,
estimateSize: useCallback(() => 240, []),
overscan: 5,
});
const columnVirtualizer = useVirtual({
horizontal: true,
size: COLUMN_COUNT,
parentRef,
estimateSize: useCallback(() => 160, []),
});
return (
<div className="grid">
{filteredQueryResults.map((icon) => (
<div key={`ph-${icon.name}-${icon.style}`} className="grid-item">
<img
src={icon.asset}
alt={`${icon.name} icon`}
width="100%"
/>
<div style={{ padding: 16 }}>{icon.name}</div>
<>
<div ref={parentRef} style={{ height: "90vh", width: "100%", overflowY: "auto" }}>
<div
style={{
height: `${rowVirtualizer.totalSize}px`,
// width: `${columnVirtualizer.totalSize}px`,
// height: `${rowVirtualizer.totalSize}px`,
width: "100%",
position: "relative",
}}
className="grid"
>
{rowVirtualizer.virtualItems.map((virtualRow) => (
<React.Fragment key={virtualRow.index}>
{columnVirtualizer.virtualItems.map((virtualColumn) => (
<div
key={virtualColumn.index}
style={{
position: "absolute",
top: 0,
left: 0,
width: `${virtualColumn.size}px`,
height: `${virtualRow.size}px`,
transform: `translateX(${virtualColumn.start}px) translateY(${virtualRow.start}px)`,
}}
className="grid-item"
>
{(function () {
const icon =
filteredQueryResults[
virtualRow.index * COLUMN_COUNT + virtualColumn.index
];
if (!icon) return null;
return (
<>
<img
color={color}
style={{ height: size, width: size }}
src={icon.asset}
alt={`${icon.name} icon`}
width="100%"
/>
<p style={{ padding: 16 }}>{icon.name}</p>
</>
);
})()}
</div>
))}
</React.Fragment>
))}
</div>
))}
</div>
</div>
</>
);
};