Skip to content
Blocks

Record Detail Panel

A working record detail panel with illustrative data and frontend interactions.

Open ↗

Make it yours.

Install the editable source and its dependencies into your React + Tailwind project.

Scroll horizontally for long lines
pnpm dlx shadcn@4.0.8 add http://localhost:3000/r/record-detail-panel.json

Use it

Scroll horizontally for long lines
"use client";
import {RecordDetailPanel} from '@/components/jez-ui/blocks/record-detail-panel';

export default function Example(){

return <><RecordDetailPanel/></>;
}

Props & types

Scroll horizontally for long lines
{
  name?: string;
  className?: string;
}

Source

View 3 source files

registry/blocks/record-detail-panel.tsx

Scroll horizontally for long lines
"use client";
import * as React from "react";
import { cn } from "../ui/utils";
import { Badge } from "../ui/badge";
export function RecordDetailPanel({
  name = "Alex Morgan",
  className,
}: {
  name?: string;
  className?: string;
}) {
  return (
    <section
      className={cn(
        "grid max-w-xl gap-6 rounded-xl border border-border p-6",
        className,
      )}
    >
      <div className="flex items-center justify-between gap-4">
        <div className="flex items-center gap-3">
          <span className="grid size-12 place-items-center rounded-full bg-primary/10 text-lg text-primary">
            {name
              .split(" ")
              .map((n) => n[0])
              .join("")}
          </span>
          <div>
            <h2 className="text-lg font-semibold">{name}</h2>
            <p className="mt-1 text-xs text-muted-foreground">
              Customer since August 2026
            </p>
          </div>
        </div>
        <Badge>Active</Badge>
      </div>
      <dl className="grid grid-cols-[minmax(0,1fr)_minmax(0,1.3fr)] gap-y-5 border-t border-border pt-6 text-sm">
        {[
          ["Email", "alex@example.com"],
          ["Plan", "Team"],
          ["Joined", "12 August 2026"],
          ["Projects", "4"],
          ["Last active", "Today"],
          ["Demo revenue", "£240"],
        ].map(([k, v]) => (
          <React.Fragment key={k}>
            <dt className="text-muted-foreground">{k}</dt>
            <dd className="break-words font-medium">{v}</dd>
          </React.Fragment>
        ))}
      </dl>
      <p className="text-xs text-muted-foreground">
        Illustrative customer record.
      </p>
    </section>
  );
}

registry/ui/utils.ts

Scroll horizontally for long lines
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...values: ClassValue[]) {
  return twMerge(clsx(values));
}

registry/ui/badge.tsx

Scroll horizontally for long lines
"use client";
import * as React from "react";
import { cn } from "./utils";
export function Badge({
  className,
  tone = "neutral",
  ...props
}: React.HTMLAttributes<HTMLSpanElement> & {
  tone?: "neutral" | "accent" | "positive" | "warning";
}) {
  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium",
        {
          "bg-muted text-foreground": tone === "neutral",
          "bg-primary/10 text-primary": tone === "accent",
          "bg-accent text-[#293620]": tone === "positive",
          "bg-[#f6e5c1] text-[#704517]": tone === "warning",
        },
        className,
      )}
      {...props}
    />
  );
}

Dependencies

clsx@2.1.1 · tailwind-merge@3.5.0

Accessibility & behaviour

Provide meaningful labels and preserve keyboard focus styles. Check contrast when customising theme colours.

Read the accessibility and performance guide →