import { cn } from "~/utils/cn";
const PADDING = { none: "", sm: "p-3", md: "p-4", lg: "p-5", xl: "p-8" } as const;
/** Card surface shared by `Panel` and ad-hoc containers (popovers, link cards). */
export function panelClass(className?: string): string {
return cn("rounded-lg border border-gray-800 bg-gray-950/60", className);
}
type Props = {
/** `danger` frames destructive settings (danger zone, transfers, renames). */
tone?: "neutral" | "danger";
title?: React.ReactNode;
actions?: React.ReactNode;
/** Inner padding. With a header, it pads the body below the header rather than the whole panel. */
padding?: keyof typeof PADDING;
children: React.ReactNode;
className?: string;
};
export function Panel({ tone = "neutral", title, actions, padding = "none", children, className }: Props) {
const hasHeader = Boolean(title || actions);
return (
<section
className={panelClass(
cn("overflow-hidden", tone === "danger" && "border-danger-900/60", !hasHeader && PADDING[padding], className),
)}
>
{hasHeader && (
<header className="flex items-center justify-between gap-3 border-b border-gray-800 bg-gray-900/60 px-4 py-2.5">
<div className={cn("min-w-0 text-sm font-medium", tone === "danger" ? "text-danger-300" : "text-gray-200")}>
{title}
</div>
{actions && <div className="flex shrink-0 items-center gap-2">{actions}</div>}
</header>
)}
{hasHeader && padding !== "none" ? <div className={PADDING[padding]}>{children}</div> : children}
</section>
);
}