import Link from "next/link"; import type { HTMLAttributes, ReactNode, TdHTMLAttributes, ThHTMLAttributes } from "react"; import { cn } from "./cn"; import { CollapsibleRows } from "./collapsible-rows"; /** * Dense data table. Sticky header (via .dci-table th), hairline rows, tabular numerics. * `responsive` turns rows into compact two-line rows under 640 px — the first line is the * cell with the optional figure on the right, the other cells wrap under it * as "LABEL value" pairs (every must carry `label`). Cells hidden with `hidden sm:table-cell` * stay hidden on phones. * `mobileCollapse` shows only the first 10 rows under 640 px with a "Show all N" toggle. */ export function Table({ className, responsive = true, children, dense, mobileCollapse, ...rest }: HTMLAttributes & { responsive?: boolean; dense?: boolean; mobileCollapse?: { total: number; label?: string } }) { const table = (
{children}
); if (mobileCollapse && responsive) { return ( {table} ); } return table; } export function THead({ children, className }: { children: ReactNode; className?: string }) { return {children}; } export function TBody({ children, className }: { children: ReactNode; className?: string }) { return {children}; } export function Tr({ children, className, href, ...rest }: HTMLAttributes & { href?: string }) { return ( {children} ); } export interface ThProps extends ThHTMLAttributes { numeric?: boolean; /** sort state */ sort?: "asc" | "desc" | null; sortHref?: string; } export function Th({ children, className, numeric, sort, sortHref, ...rest }: ThProps) { const inner = ( {children} {sort !== undefined && ( {sort === "asc" ? "▲" : sort === "desc" ? "▼" : "◆"} )} ); return ( {sortHref ? ( {inner} ) : ( inner )} ); } export interface TdProps extends TdHTMLAttributes { label?: string; numeric?: boolean; primary?: boolean; muted?: boolean; /** key figure of the row: sits right of the primary cell on the first line under 640 px */ lead?: boolean; } export function Td({ children, className, label, numeric, primary, muted, lead, ...rest }: TdProps) { return ( {children} ); } /** Row link (keeps the table semantic). Under 640 px, inside a , it stretches over the whole row (`.dci-rowlink`). */ export function RowLink({ href, children, className }: { href: string; children: ReactNode; className?: string }) { return ( {children} ); }