Skip to content
zedkit
@zedtech/zedkit-ui

DetailPanel

Key-value details as boxed rows or `variant="grid"` stats, plus a live pulse. Idle copy is `inactiveLabel`; `label` only overrides Live.

Stable@zedtech/zedkit-ui

Wraps: none (theme tokens only)

Delivery D-2047

Tracking live
Carrier
Colissimo
Status
In transit
Destination
14 rue des Lilas, 69003 Lyon
Arrival
Thursday 29 October, before 6 pm
Weight
1.8 kg
Idle

Shown once tracking stops, for example after delivery.

View props table
Who is it for?
Developers rendering record details (drawers, side panels, headers).
When should I use it?
For read-only record summaries next to the list. Use `variant="grid"` for dashboard-style stats (large value, quiet label).
When should I pick something else?
For editable records — use Form instead.

Use it

Examples import from the package. With copied source, import from @/components/ui/detail-panel instead.

Simple
import { DetailPanel, LivePulse, PageHeader } from "@zedtech/zedkit-ui";
<PageHeader title="Server" actions={<LivePulse active={false} inactiveLabel="Paused" />} />
<DetailPanel items={[{ label: "Region", value: "eu" }]} />

Composed rows

Customer
Camille Rousseau
Plan
Pro
Last seen

2 minutes ago

Renews
1 December 2026
Customer ID
import { DetailPanelRow } from "@zedtech/zedkit-ui";
<dl>
  <DetailPanelRow label="Region" value="eu" />
</dl>

Stat grid

Requests
12,480
Uptime
99.9%
Latency
42 ms
Errors
0.12%
import { DetailPanel } from "@zedtech/zedkit-ui";
<DetailPanel
  variant="grid"
  items={[{ label: "Requests", value: "12,480" }, { label: "Uptime", value: "99.9%" }]}
/>

Kit not installed yet?

You get
Every component from one import, with the theme tokens included. Updates arrive with your package manager.
You need
  • React 19 and Tailwind CSS 4, for example a Next.js app created with the Tailwind option.
  1. Install

    Terminal
    pnpm add @zedtech/zedkit-ui @fontsource-variable/inter @fontsource-variable/space-grotesk
  2. Load the styles

    Tailwind does not scan node_modules, so the @source line points it at the kit's class names. The path is relative to this file.

    src/app/globals.cssReplace the contents
    @import "tailwindcss";
    @import "@zedtech/zedkit-ui/styles.css";
    @source "../../node_modules/@zedtech/zedkit-ui/src/**/*.{ts,tsx}";
    @source not "../../node_modules/@zedtech/zedkit-ui/src/**/*.test.*";
    
  3. Pick a look

    Set data-identity="glass" on <html> so the finished app matches the site. Fresh app: replace src/app/layout.tsx. Existing app: merge, and keep ThemeProvider and other providers.

    src/app/layout.tsxReplace the contents
    import "./globals.css";
    import "./fonts";
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en" data-identity="glass">
          <body>{children}</body>
        </html>
      );
    }
    
  4. Load the fonts

    The Glass look uses Inter and Space Grotesk; these imports self-host them.

    src/app/fonts.tsCreate the file
    import "@fontsource-variable/inter";
    import "@fontsource-variable/space-grotesk";
    
  5. Import and render

    src/app/page.tsxReplace the contents
    import { DetailPanelRow } from "@zedtech/zedkit-ui";
    
    export default function Page() {
      return (
        <main className="px-page-gutter py-section-sm">
          <dl>
            <DetailPanelRow label="Region" value="eu" />
          </dl>
        </main>
      );
    }
    

Package version 2.0.1.

Props

Prop

Type

Accessibility

Native dl/dt/dd semantics; rows read in order. Grid wraps each pair so a two-column layout does not interleave terms and definitions. LivePulse is role="status" (name from aria-label, not contents). aria-label is the shown word (label when live, inactiveLabel when idle, kit idle when the word is hidden) so the StatusDot is never unnamed. inactiveLabel is caller-localized (no lang).

Troubleshooting

Custom row content — compose `DetailPanelRow` inside your own `<dl>` (see Composed rows); `DetailPanel` only covers the plain `items[]` case. Grid is `items[]` only — there is no composed-cell export. Grid reading order — each item is one wrapped `dt`/`dd` pair, not flattened grid children. Boxed look on a grid — wrap in Card (`<Card><DetailPanel variant="grid" items={items} /></Card>`); `className` also works; grid drops list chrome. Grid loading — `DetailPanelSkeleton` is the boxed-list shape only. Cramped rows — inline padding is `px-detail-panel-inline`; block padding is `py-detail-panel-block`. Idle word stuck on Idle — pass `inactiveLabel`; `label` is ignored when `active={false}`. Dot-only idle still unnamed — empty `inactiveLabel` hides the visible word; `aria-label` stays the kit idle string. Mixed-language idle copy — localize `inactiveLabel` on the host; LivePulse does not translate it.

On this page