forked from nihonium/nyanimedb
52 lines
No EOL
1.3 KiB
TypeScript
52 lines
No EOL
1.3 KiB
TypeScript
import React from "react";
|
|
|
|
interface ListViewProps<TItem> {
|
|
hook: ReturnType<typeof import("./useListView.tsx").useListView<TItem>>;
|
|
renderHorizontal: (item: TItem) => React.ReactNode;
|
|
renderSquare: (item: TItem) => React.ReactNode;
|
|
}
|
|
|
|
export function ListView<TItem>({
|
|
hook,
|
|
renderHorizontal,
|
|
renderSquare
|
|
}: ListViewProps<TItem>) {
|
|
const { items, search, setSearch, viewMode, setViewMode, loadMore, hasMore } = hook;
|
|
|
|
return (
|
|
<div>
|
|
{/* Search + Layout Switcher */}
|
|
<div style={{ display: "flex", gap: 8, marginBottom: 16 }}>
|
|
<input
|
|
placeholder="Search..."
|
|
value={search}
|
|
onChange={e => setSearch(e.target.value)}
|
|
/>
|
|
|
|
<button onClick={() => setViewMode("horizontal")}>Horizontal</button>
|
|
<button onClick={() => setViewMode("square")}>Square</button>
|
|
</div>
|
|
|
|
{/* Items */}
|
|
<div
|
|
style={{
|
|
display: "grid",
|
|
gridTemplateColumns: viewMode === "square" ? "repeat(auto-fill, 160px)" : "1fr",
|
|
gap: 12
|
|
}}
|
|
>
|
|
{items.map(item =>
|
|
viewMode === "horizontal"
|
|
? renderHorizontal(item)
|
|
: renderSquare(item)
|
|
)}
|
|
</div>
|
|
|
|
{hasMore && (
|
|
<button onClick={loadMore} style={{ marginTop: 16 }}>
|
|
Load More
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
} |