JM Family Design System

Panel

Panels group related controls or content inside operational interfaces. Use them when a boundary clarifies the task, not as decoration around every section.

Guidance for adoption

Start here before choosing examples or props. These notes explain where Panel helps, where another pattern is better, and what should stay true in product work.

When to use

  • Tool surfaces
  • Side panels
  • Repeated content groups
  • Focused workflow areas

When not to use

  • Wrapping entire page sections
  • Nested card layouts
  • Decorative framing

Accessibility expectations

  • Use headings to name important regions.
  • Keep reading order aligned to visual order.
  • Do not create focus traps outside modal contexts.

Content guidance

  • Use panel titles that name the region or task, such as "Vendor filters" or "Approval details".
  • Keep the content inside a panel tightly related so the boundary helps people understand the work.
  • Avoid wrapping every page section; panels should clarify function, not decorate the layout.
  • Use concise action labels inside panels so the next step remains clear in dense interfaces.

Implementation notes

  • Pass title and titleId together so aria-labelledby can give the section an accessible name.
  • Compose controls, actions, and footer content inside children; the component has no slot props.
  • Build collapsible behavior outside the component when a panel needs expand and collapse controls.
  • Do not nest framed panels or cards inside another panel unless the hierarchy is truly separate.

Import

import { Panel } from '@/components/ui/Panel';

Renders a labeled section container. Compose internal layout with normal HTML inside.

Usage patterns

Panels are functional containers. They should help users scan, compare, or complete work without turning the whole page into a stack of boxes.

Tool surface
Filters

Use panels to group controls that operate on the same object or view.

Side panel
Vendor details
Owner, status, and notes

Use a side panel for contextual details without leaving the current workflow.

Repeated group
Approvals

Use a panel when each group has a real boundary and a clear heading.

Workflow area

Use panels to contain a focused task with related fields and actions.

Status region
Ready18
Blocked3

Use a panel for operational state that users need to scan repeatedly.

Avoid decorative wrapping
Decorative wrapper

Do not wrap every page section just to make the page feel designed.

Anatomy

A panel should have a clear region name, a meaningful boundary, and content that belongs together. Internal structure should stay readable without nesting framed surfaces.

Vendor filters

  1. Region heading
  2. Functional boundary
  3. Related content
  4. Optional controls
  5. Clear actions
  6. Reading order

Props

The component accepts every native HTMLElement attribute on top of the design system props below.

PropTypeDefaultDescription
titleReactNodeRegion heading rendered inside the panel. Strings get wrapped in an h3.
titleIdstringSets id on the heading and auto-wires aria-labelledby on the section element.
titleIconReactNodeIcon rendered before the title. Mark decorative icons with aria-hidden.

Usage rules

Group functional content

Use a panel when the boundary helps users understand controls, content, or workflow state.

Do not wrap every section

Page-level sections should usually be unframed. A panel should earn its border through function.

Keep panel hierarchy flat

Use headings, spacing, dividers, or rows inside a panel before reaching for nested framed surfaces.

Do not place cards inside cards

Nested framed surfaces create visual noise and make generated layouts harder to reason about.

Known limitations

What Panel does not do yet, and what consumers need to compose themselves.

  • aria-labelledby wires up only when both title and titleId are passed. If consumers pass title without titleId, the heading renders without an id and the section has no accessible name despite appearing labelled.
  • No collapsible mode and no header or footer action slot. Common panel patterns (expand/collapse, inline actions, footer regions) must be assembled by consumers around children.

Related anti-patterns

Catalog entries to watch for when using Panel. Read these before shipping; they describe the failure modes the system has already documented.

Agent guidance

Agents should use panels only when grouping improves task clarity. Generated layouts should use spacing and headings for page structure before adding framed surfaces.

Generation rules

  • Use panels to group functional content, not to decorate layouts.
  • Do not place cards inside cards.
  • Prefer full-width sections for page-level structure.
  • Always pass titleId together with title. The aria-labelledby attribute only wires up when both are present, so passing one without the other leaves the section unlabeled to assistive tech.
  • For collapsible panels, manage the open state and aria-expanded on the trigger in product code. The component does not ship a collapsible mode.
  • Render inline actions or footer regions inside children rather than reaching for header or footer slot props that do not exist.
  • Use spacing tokens for the gap between Panel and surrounding content; never set magic-number margins. Off-scale spacing matches the off-scale-spacing anti-pattern.

Baseline example

import { Panel } from '@/components/ui/Panel';

<Panel title="Filters" titleId="filters-heading">
  <fieldset>
    <legend>Status</legend>
    {/* related controls */}
  </fieldset>
</Panel>
If a generated screen starts to look like boxed sections stacked inside more boxes, the agent should remove panel framing and rebuild the hierarchy with spacing, headings, and rows.

Decision standard

Use a panel when the boundary helps people do work. Do not use a panel when the boundary only makes a page section look more finished.