import { ArrowIcon } from "../ui/icons.tsx"; import type { ReactNode, HTMLAttributes } from "react"; export function DescriptionList({ items, className = "", ...props }: HTMLAttributes & { items: readonly { label: string; value: ReactNode }[]; }) { return (
{items.map((item, i) => (
{item.label}
{item.value}
))}
); } export function Stat({ label, value, change, detail, className = "", }: { label: string; value: ReactNode; change?: { value: string; direction: "up" | "down" | "flat"; favorable?: boolean; }; detail?: string; className?: string; }) { return (

{label}

{value}

{change && (

{" "} {change.value}

)} {detail &&

{detail}

}
); } export type TimelineEvent = { id: string; title: string; time: string; dateTime?: string; body?: ReactNode; state?: "complete" | "current" | "upcoming"; }; export function Timeline({ items, label = "Timeline", className = "", }: { items: readonly TimelineEvent[]; label?: string; className?: string; }) { return (
    {items.map((item) => (
  1. {item.title}

    {item.body &&
    {item.body}
    }
  2. ))}
); } export function ComparisonTable({ label, columns, rows, className = "", }: { label: string; columns: readonly string[]; rows: readonly { label: string; values: readonly (string | boolean)[] }[]; className?: string; }) { return (
{columns.map((c) => ( ))} {rows.map((row) => ( {columns.map((c, i) => ( ))} ))}
{label}
Feature {c}
{row.label} {typeof row.values[i] === "boolean" ? ( {row.values[i] ? "Included" : "Not included"} ) : ( (row.values[i] ?? "—") )}
); }