metis-desk/packages/rdx-ui/src/components/detail-panel.tsx

65 lines
2.0 KiB
TypeScript

import { Card, CardContent, CardHeader } from "@repo/shadcn-ui/components/card";
import type { ReactNode } from "react";
import { useId } from "react";
/** Panel de consulta con jerarquía común; datos, textos y acciones pertenecen al consumidor. */
export function DetailPanel({
title,
description,
icon,
count,
actions,
children,
density = "default",
}: {
title: string;
description?: string;
icon: ReactNode;
count?: number | undefined;
actions?: ReactNode;
children: ReactNode;
density?: "default" | "compact";
}) {
const id = useId();
return (
<section aria-labelledby={id} className="min-w-0">
<Card
className={`@container min-w-0 shadow-none ${density === "compact" ? "gap-3 rounded-lg py-4" : ""}`}
>
<CardHeader
className={`flex flex-wrap items-start justify-between gap-3 ${density === "compact" ? "px-4" : ""}`}
>
<div className="min-w-0 space-y-1">
<h2
className="flex min-w-0 flex-wrap items-center gap-2 text-base font-semibold"
id={id}
>
<span aria-hidden="true" className="text-primary [&_svg]:size-5">
{icon}
</span>
{title}
{count !== undefined && (
<span className="rounded-md bg-muted px-2 py-0.5 text-xs font-medium tabular-nums text-muted-foreground">
{count}
</span>
)}
</h2>
{description && (
<p className="max-w-prose text-sm leading-relaxed text-muted-foreground">
{description}
</p>
)}
</div>
{actions && <div className="flex shrink-0 flex-wrap gap-2">{actions}</div>}
</CardHeader>
<CardContent
className={density === "compact" ? "flex min-w-0 flex-col gap-3 px-4" : "space-y-5"}
>
{children}
</CardContent>
</Card>
</section>
);
}