import clsx from "clsx";
import type { HTMLAttributes, TdHTMLAttributes, ThHTMLAttributes } from "react";
/*
* One table treatment for the whole console.
*
* There were four: billing, licences, accounts and catalogue each wrote their
* own thead, and they disagreed about the head's type size, its tracking,
* whether it sat on --panel-2, and whether numbers were tabular. Catalogue's
* heads were sentence-case body text. A registry whose columns are set four
* ways does not read as one product.
*
* The head is the keyed idiom — mono, small, uppercase, widely tracked — which
* is what a column head is: a key above a value, exactly as the record line is
* a key beside one.
*
* MOBILE. `stack` collapses the table into one card per row below sm, each cell
* becoming a label/value pair drawn from TD's `label`. The variants below hang
* off a `stacked` class on the
, so a table that does not opt in is
* untouched at every width.
*
* It is opt-in rather than automatic because a stacked row whose cells have no
* labels is worse than a scrolling one — the values lose the only thing naming
* them. Customer screens stack; the staff console's wide registry tables scroll
* sideways instead, which is the right trade for eight columns read at a desk.
*/
const STACK = "max-sm:[.stacked_&]:block";
export function Table({ stack, className, children, ...props }: HTMLAttributes & { stack?: boolean }) {
return (
);
}
export function THead({ className, children, ...props }: HTMLAttributes) {
return (
{children}
);
}
export function TBody({ className, children, ...props }: HTMLAttributes) {
return (
{children}
);
}
export function TR({ className, children, ...props }: HTMLAttributes) {
return (
{children}
);
}
interface CellProps {
/** Right-aligns the cell. For quantities and money, which read down the column. */
numeric?: boolean;
}
export function TH({ className, numeric, children, ...props }: ThHTMLAttributes & CellProps) {
return (
{children}
|
);
}
export function TD({ className, numeric, label, children, ...props }: TdHTMLAttributes & CellProps & { label?: string }) {
return (
{label && (
{label}
)}
{children}
|
);
}
/** The secondary line under a cell's main value — an ID, a deployment, a date. */
export function Sub({ children }: { children: React.ReactNode }) {
return {children}
;
}