Skip to content
LayoutGenerated from the public API

Panel

The dense surface for toolbars, sidebars and nested regions.

@luc/ui

Examples

Surface tones

Panel is the dense surface under everything else — a toolbar, a sidebar, a code block, a region inside a card. The tone says where it sits in the stack, not how important it is.

default

tone=default

sunken

tone=sunken

raised

tone=raised

Header, body and actions

`PanelHeader` is the region's title bar: a minimum height, a hairline under it and a right-hand slot, which is what keeps a toolbar's controls in the same place on every panel in a product.

Constituents

61

AAPL

4.1%

MSFT

3.8%

NVDA

3.2%

Panel or Card

The distinction, shown with the same content: a Card is the surface a reader acts on, a Panel is a region inside one. A Panel never carries elevation, so a page cannot end up with two competing shadows.

Card

A surface with elevation

Panel inside a Card

Panel

A region, no elevation of its own

Nested regions

A panel inside a panel separates two kinds of region with one hairline instead of a second border, a margin and a background — which is what keeps a dense tool screen legible.

Workspace

Nested region

Nested region

Bordered and borderless

`bordered={false}` is for a panel that already sits inside a framed surface: the frame is drawn once, by the outer region, and the inner one keeps only its background.

bordered

bordered=false

Usage

import { Panel, PanelBody, PanelHeader } from "@luc/ui";
<Panel>
  <PanelHeader>
    <Text variant="label">Constituents</Text>
  </PanelHeader>
  <PanelBody>…</PanelBody>
</Panel>

`tone` says where the panel sits in the stack, not how important it is; `bordered` drops the frame when the surface outside it already has one.

Package setup — peer requirements, the stylesheet and the provider — is on installation.

API

Read from the published TypeScript API, so a prop that is not listed here does not exist and a default that is listed is the one the compiler sees.

Exported symbols
ExportKindSignature
Panel2 documented props({ className, tone, bordered, ...props }: PanelProps) => import("@types/react").JSX.Element
PanelBodyexport({ className, ...props }: React.ComponentPropsWithRef<"div">) => import("@types/react").JSX.Element
PanelHeader1 documented props({ className, actions, children, ...props }: PanelHeaderProps) => import("@types/react").JSX.Element

Panel props

Type: PanelProps

Values the compiler reads from the declaration.

Panel props
PropTypeDefaultNotes
bordered?boolean | undefined—Hairline frame. Default `true`.
tone?"default" | "raised" | "sunken" | undefined—`sunken` sits inside cards; `default` sits on the canvas.

PanelHeader props

Type: PanelHeaderProps

Values the compiler reads from the declaration.

PanelHeader props
PropTypeDefaultNotes
actions?ReactNode—

Guidelines

Do

  • Use `Panel` for the regions *inside* a page or a card: a toolbar, a sidebar, a code block, a section of an inspector.
  • Pick `tone="sunken"` when the panel sits on a raised surface and `tone="raised"` when it has to read as a layer inside a dense tool screen.
  • Use the `PanelHeader` action slot rather than a row of buttons above the panel — a toolbar belongs on the region it acts on.

Don't

  • Do not stack two surfaces with the same tone: two identical panels side by side read as one broken surface.
  • Do not add elevation to a Panel by class; elevation belongs to `Card`, and a page with both has two shadows competing.
  • Do not nest a panel inside a panel without changing the tone — the hairline between them is what makes the nesting legible.

Accessibility

A panel is a `div`: a surface, not a landmark. When it is a page's toolbar it needs a name (`aria-label`) or an enclosing `Toolbar`, and when it groups controls it should be a `fieldset` or carry `role="group"` — the component adds neither, because only the caller knows which region it is.

Family

Layout

Space, rhythm and the surfaces a page is made of.

10 documented entries in this family. Open the family index

Luc UI v1.0Paneldark theme