mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-03 19:17:16 -05:00 
			
		
		
		
	First pass to create a grid component
This commit is contained in:
		
							parent
							
								
									d1816e2d7b
								
							
						
					
					
						commit
						75bb24d6d8
					
				@ -32,6 +32,7 @@ import {
 | 
			
		||||
} from "react";
 | 
			
		||||
import { Stylable, nativeStyleToCss, useYoshiki, ysMap } from "yoshiki";
 | 
			
		||||
import { EmptyView, ErrorView, Layout, WithLoading, addHeader } from "./fetch";
 | 
			
		||||
import { Grid } from "./grid.web";
 | 
			
		||||
import type { ContentStyle } from "@shopify/flash-list";
 | 
			
		||||
import { useVirtualizer } from "@tanstack/react-virtual";
 | 
			
		||||
 | 
			
		||||
@ -60,6 +61,12 @@ const InfiniteScroll = <T extends { id: string }, Props>({
 | 
			
		||||
	contentContainerStyle?: ContentStyle;
 | 
			
		||||
	getItemSize: (x: T, idx: number) => number;
 | 
			
		||||
} & Stylable) => {
 | 
			
		||||
	return (
 | 
			
		||||
		<Grid getItemSize={() => layout.size as any} data={data} layout={layout}>
 | 
			
		||||
			{renderItem}
 | 
			
		||||
		</Grid>
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	const ref = useRef<HTMLDivElement>(null);
 | 
			
		||||
	const containerRef = useRef<HTMLDivElement>(null);
 | 
			
		||||
	const virtualizer = useVirtualizer({
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ import { useYoshiki } from "yoshiki/native";
 | 
			
		||||
 | 
			
		||||
export type Layout = {
 | 
			
		||||
	numColumns: Breakpoint<number>;
 | 
			
		||||
	size: number;
 | 
			
		||||
	padding: number;
 | 
			
		||||
	gap: Breakpoint<number>;
 | 
			
		||||
	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