Panel
A widget or an overlay: a grey outer with a quiet frame line, the header on the grey, the content in a white bordered body, the footer back on the grey.
Examples
Needs a look
3Conversations
Last 24 hoursPrompt release v14
Paused at 25%States
- Needs a look3
rest
Usage
When to use it
- Use
- An overview widget shows a few numbers or a short list, about 8 rows at most: what needs a look, the last releases, API keys.
- Use
- A chart widget: one chart with a title and a range, such as conversations over the last day (Chart frame="panel" is this anatomy).
- Use
- A card that asks the person for a decision, such as a prompt release waiting on Resume or Roll back, with the buttons in the footer.
- Use
- A short read-only fact set, such as an environment and its workspace ID.
- Not for
- A working surface: a big table or stream, a trace, a log, code, a form or the detail of one object; anything that scrolls, filters, streams or has fields the person edits, such as a settings group. Use Card.
- Not for
- A task or a question that must finish first. Use Dialog.
Rules
6 rules
- Must
- Use a Panel for a summary or a decision: a short list, one chart, a read-only fact set or a card that asks for a choice, with a title, a meta and at most one action. Fields the person edits belong in a Card. Because the grey outer gives a widget a ground of its own and puts its buttons on the grey, but a long list or a working surface needs the white Card's edge and header rule to read as one place.
- Never
- Scroll inside a Panel; link to a full page for more. Because a white body that scrolls in a grey outer hides its edge, so no one can tell the list goes on.
- Never
- A widget is a Panel and a working surface is a Card; never a Card inside a Panel or a Panel inside a Card. Because a white card in a grey panel is a box in a box; side by side, the grey widget and the white table tell the person which one to glance at and which one to work in.
- Must
- Split rows in a PanelBody with rule-row and pad them px-3; an Item does both itself. Because the body sits 4px inside the panel, so px-3 lands the text on the same 16px as the header.
- Should
- Give the header at most one action, in PanelAction, and put "View all" there or in the footer. Because a header with several controls turns a glanceable widget into a toolbar and crowds the title off a narrow panel.
- Must
- Put a quiet line or buttons that belong to the whole panel in PanelFooter, never inside PanelBody. Because the body is the one white group of rows, and a footer line inside it reads as one more row.
Accessibility
2 checks
- Panel renders a section; give it aria-label, or name it with aria-labelledby on its PanelTitle.
- A list inside takes role="list" with listitem rows, named like the panel.
Edge cases
5 edge cases
- Very long title
- Truncates to one line and keeps the meta and the action.
- More than about 8 rows
- Show the first rows and a View all button in the header or footer.
- Empty body
- Put an empty state in the body; the panel keeps its header.
- Right to left
- The title and meta move to the right and the action to the left.
- Forced colors
- The panel keeps an outline and the body its frame border.
API
5 props
PanelsectionPanelHeaderdivPanelActiondivPanelBodydivPanelFooterdiv
Tokens
7 tokens
--surface-frame- color-mix(in oklch, var(--surface-card) 55%, var(--paper))
--surface-page- var(--paper)
--line-frame- oklch(var(--ink-c) / var(--line-frame-alpha))
--line-row- oklch(var(--ink-c) / 0.08)
--radius-frame- 10px
--text-3- oklch(var(--ink-c) / 0.66)
--type-label- 400 14px/16px var(--font-sans)