content-explorer/ui/components/RecordBrowser.tsx
tegwick d92eb25f92 Map records to generic browser rows.
CONTENT-WP-0002-T03 renders manifest columns through a pure row mapper and replaceable cell renderers.

Assistant: grok
Assistant-Session: 01a1346c-fdff-7741-b1af-b7283661554b
2026-10-13 23:01:09 +02:00

41 lines
1.3 KiB
TypeScript

"use client";
import { useState } from "react";
import { renderCell, type CellRenderer } from "@/components/cell-renderers";
import { ResultsTable } from "@/components/ResultsTable";
import { cellSortValue, type BrowserRow, type ColumnDef } from "@/lib/browser-row";
import { nextSort, sortRows } from "@/lib/sort-rows";
import type { SortState } from "@/lib/types";
export function RecordBrowser({
rows,
columns,
heading = "Records",
renderers,
}: {
rows: BrowserRow[];
columns: ColumnDef[];
heading?: string;
renderers?: Record<string, CellRenderer>;
}) {
const [sort, setSort] = useState<SortState | undefined>({ key: columns[0]?.key ?? "name", dir: 1 });
const ordered = sortRows(rows, sort, cellSortValue);
const tableColumns = columns.map((column) => ({
key: column.key,
label: column.label,
sortable: true,
render: (row: BrowserRow) => renderCell(column.key, row, renderers),
}));
return (
<section id="records" aria-labelledby="records-heading" className="mx-auto max-w-7xl px-4 py-14 sm:px-6">
<h2 id="records-heading" className="mb-6 text-2xl">{heading}</h2>
<ResultsTable
columns={tableColumns}
rows={ordered}
rowKey={(row) => row.id}
sort={sort}
onSort={(key) => setSort((current) => nextSort(current, key))}
/>
</section>
);
}