docs / patterns / panel

Panel

the dashboard workhorse: it fills its grid cell, the header stays fixed, and the body scrolls its own overflow.

intensity · structuresrsc · server

provenance

shaped from sisu-plus

layer

core / patterns

intensity

structures · organizes a region, stays out of the content

composition

a cell of DashboardGrid or a bento layout. it needs a sized boxbadge takes a Badge, actions take icon-only Buttonsnever nested in a Card or another Panel. it is the regionnot a page section on a marketing page. that is Card territory

a11y

the loading spinner is role="status" with an sr label · badge and actions keep their own semanticsjest-axe

dependencies

Spinner · Card from the same package
live demo · try it out

overview

Deployments
live
  • feat/docs

    1ec3bbc · just now

    building
  • fix/hero-split

    0df772e · 14m ago

    live
  • chore/tokens

    c74cf7c · 1h ago

    live
  • feat/color-field

    fa17ccd · 3h ago

    live
  • fix/bento-grid

    9d2d01e · 5h ago

    failed
  • feat/segmented

    8b21f04 · yesterday

    live
  • chore/registry

    a90c7d1 · yesterday

    queued
customize
eyebrowmono label above the title
titlethe panel heading
surfacehow it sits on the page
badgea status Badge in the header
loadingswaps the body for a Spinner
usagecopy
import { Panel } from "@usva-ui/react/patterns/panel";
import { Badge } from "@usva-ui/react/primitives/badge";

<Panel
  eyebrow="overview"
  title="Deployments"
  badge={<Badge tone="accent-alt" live>live</Badge>}
>
  <DeploymentList />
</Panel>

props

proptypedefaultnotes
titleReactNodethe panel heading.
eyebrowReactNodemono uppercase label above the title.
iconReactNodeleading icon, shown in a tile.
badgeReactNoderight-aligned status slot. pass a Badge.
actionsReactNoderight-aligned controls slot. icon-only Buttons fit.
loadingbooleanfalseswaps the body for a centered Spinner. the header stays.
loadingSlotReactNodereplaces the default spinner while loading. a Skeleton stack goes here.
surfaceCardSurface"elevated"how the panel sits on the page. shares Card's surface scale.

get it

bun add @usva-ui/reactcopy
usagecopy
import { Panel } from "@usva-ui/react/patterns/panel";
import { Badge } from "@usva-ui/react/primitives/badge";

<Panel eyebrow="overview" title="Deployments" badge={<Badge live>live</Badge>}>
  <DeploymentList />
</Panel>