mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
First pass to create a grid component
This commit is contained in:
parent
d1816e2d7b
commit
75bb24d6d8
@ -32,6 +32,7 @@ import {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import { Stylable, nativeStyleToCss, useYoshiki, ysMap } from "yoshiki";
|
import { Stylable, nativeStyleToCss, useYoshiki, ysMap } from "yoshiki";
|
||||||
import { EmptyView, ErrorView, Layout, WithLoading, addHeader } from "./fetch";
|
import { EmptyView, ErrorView, Layout, WithLoading, addHeader } from "./fetch";
|
||||||
|
import { Grid } from "./grid.web";
|
||||||
import type { ContentStyle } from "@shopify/flash-list";
|
import type { ContentStyle } from "@shopify/flash-list";
|
||||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||||
|
|
||||||
@ -60,6 +61,12 @@ const InfiniteScroll = <T extends { id: string }, Props>({
|
|||||||
contentContainerStyle?: ContentStyle;
|
contentContainerStyle?: ContentStyle;
|
||||||
getItemSize: (x: T, idx: number) => number;
|
getItemSize: (x: T, idx: number) => number;
|
||||||
} & Stylable) => {
|
} & Stylable) => {
|
||||||
|
return (
|
||||||
|
<Grid getItemSize={() => layout.size as any} data={data} layout={layout}>
|
||||||
|
{renderItem}
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const virtualizer = useVirtualizer({
|
const virtualizer = useVirtualizer({
|
||||||
|
@ -27,7 +27,7 @@ import { useYoshiki } from "yoshiki/native";
|
|||||||
|
|
||||||
export type Layout = {
|
export type Layout = {
|
||||||
numColumns: Breakpoint<number>;
|
numColumns: Breakpoint<number>;
|
||||||
size: number;
|
padding: number;
|
||||||
gap: Breakpoint<number>;
|
gap: Breakpoint<number>;
|
||||||
layout: "grid" | "horizontal" | "vertical";
|
layout: "grid" | "horizontal" | "vertical";
|
||||||
};
|
};
|
||||||
|
78
front/packages/ui/src/grid.web.tsx
Normal file
78
front/packages/ui/src/grid.web.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Kyoo - A portable and vast media library solution.
|
||||||
|
* Copyright (c) Kyoo.
|
||||||
|
*
|
||||||
|
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
*
|
||||||
|
* Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* Kyoo is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ReactNode, useRef } from "react";
|
||||||
|
import { Layout } from "./fetch";
|
||||||
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||||
|
|
||||||
|
export const Grid = <T extends { id: string }>({
|
||||||
|
data,
|
||||||
|
children,
|
||||||
|
layout,
|
||||||
|
getItemSize,
|
||||||
|
...props
|
||||||
|
}: {
|
||||||
|
data: T[];
|
||||||
|
children: (item: T, index: number) => ReactNode;
|
||||||
|
layout: Layout;
|
||||||
|
getItemSize: (item: T, index: number) => number;
|
||||||
|
}) => {
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const virtualizer = useVirtualizer({
|
||||||
|
// horizontal: layout.layout === "horizontal",
|
||||||
|
count: data.length,
|
||||||
|
getScrollElement: () => ref.current,
|
||||||
|
estimateSize: (i) => 350, //getItemSize(data[i], i),
|
||||||
|
overscan: 5,
|
||||||
|
});
|
||||||
|
console.log(virtualizer);
|
||||||
|
console.log(virtualizer.getTotalSize());
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} style={{ width: 400, height: 600, overflow: "auto" }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: virtualizer.getTotalSize(),
|
||||||
|
width: "100%",
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
// {...props}
|
||||||
|
>
|
||||||
|
{virtualizer.getVirtualItems().map((x) => (
|
||||||
|
<div
|
||||||
|
key={x.key}
|
||||||
|
data-index={x.index}
|
||||||
|
ref={virtualizer.measureElement}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: "100%",
|
||||||
|
// height: `${x.size}px`,
|
||||||
|
transform: `translateY(${x.start}px)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children(data[x.index], x.index)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user