import clsx from "clsx";
import { SURFACE } from "./surfaces";
// B8 (docs/DESIGN.md): a first load of a grid, list or table shows the SHAPE of what is coming, so
// nothing jumps when the data lands. One block primitive (a tonal fill, the Badge's 8% of the text
// colour, pulsing unless the user asked for less motion) and the page shapes built from it (plus a
// paragraph's, for prose that arrives after its page). The
// shapes are shown through `LoadingState shape=…`, which owns the 300 ms reveal and the status role.
function Skeleton({ className, inline = false }: { className?: string; inline?: boolean }) {
// Inline: a span, for a bone inside phrasing content (a chip is a button, which may not hold a div).
const Tag = inline ? "span" : "div";
return (
);
}
/** A chip whose name is still on its way: a name-sized bone, not the raw value (a channel's UC… id).
* A screen reader still gets the value, so two such chips stay told apart. */
export function ChipLabelPending({ value }: { value: string }) {
return (
<>
{value}
>
);
}
export type SkeletonShape = "grid" | "poster" | "list" | "table" | "text";
const COUNT: Record = { grid: 8, poster: 12, list: 6, table: 8, text: 5 };
/** The placeholder for a page's first load, by the shape of its content. */
export function SkeletonShapes({ shape }: { shape: SkeletonShape }) {
const n = Array.from({ length: COUNT[shape] }, (_, i) => i);
if (shape === "grid")
return (
{n.map((i) => (
// The video card's own surface, bones inside it, as the card will stand.
))}
);
if (shape === "poster")
return (
{n.map((i) => (
))}
);
if (shape === "text")
// A paragraph still on its way (a biography): lines at prose height, the last one short.
return (