Skip to main content
xriptxr

Panel

Info:Layout
24

A titled content region: a header with a configurable heading and actions, a body, an optional footer, and an optional collapsible or scrollable form.

pane collapsible titled region section card

Live demo

live · @xtyle/astro

Panel

Project overview

A panel is a titled region with a header, body, and optional footer. The heading level is configurable so it slots cleanly into the document outline, and the actions slot parks controls on the right of the header.

Info:section level 3

Same disclosure, started expanded with open. Actions live in the header alongside the marker.

The marker leading the heading is an <xtyle-icon> the panel's fragment draws, so a mod can swap the caret without touching the panel.

Build log

Success:live

12:04:01 build resolving 92 component manifests

12:04:01 build coverage check — 92/92 green

12:04:02 emit wrote tokens.css (310 declarations)

12:04:02 emit wrote tokens.json

12:04:03 gauntlet 200 runs · 0 invariant breaks

12:04:03 gauntlet contrast floor held at 4.51:1

12:04:04 site 37 pages rendered

12:04:04 done build complete in 3.1s

fill — in a bounded column, one panel absorbs the slack and scrolls its body while the rest keep their natural height. The header and footer stay put.

Fixed

Natural height, whatever its content needs.

Layers

12

layer 12 · normal · 100%

layer 11 · normal · 100%

layer 10 · normal · 100%

layer 09 · normal · 100%

layer 08 · normal · 100%

layer 07 · normal · 100%

layer 06 · normal · 100%

layer 05 · normal · 100%

layer 04 · normal · 100%

layer 03 · normal · 100%

layer 02 · normal · 100%

layer 01 · normal · 100%

Also fixed

The column's slack went to the panel that asked for it.

Panel frames a labelled section of content. Its header carries a heading (rendered at a configurable heading level for a correct document outline), an actions slot pushed to the trailing edge by a spacer, and the body it labels via aria-labelledby.

The default variant is a static <section>; the collapsible variant is a native <details>/<summary> disclosure that needs no JavaScript in markup. The custom element drives it with aria-expanded. A footer slot adds a quiet trailing row, and the scroll flag turns the body into a focusable, keyboard-scrollable region capped at a fixed height.

When to use

How this component composes with the rest of the set.

Use as the building block of a Dock column; .xtyle-dock .xtyle-panel drops the border and radius so panels stack flush.
Put a Button cluster in the actions slot for per-panel controls; the spacer keeps them right-aligned.
Set level so nested panels keep a valid heading hierarchy: a top-level panel at 2, sub-panels at 3, and so on.

Props

8 props, straight from the manifest.

PropTypeDefaultBindingsDescription
label string
html svelte astro
Accessible name for a panel with no visible heading — names the region without rendering a heading.
heading string
html svelte astro
The panel heading text. When set (or an actions slot is filled) the header renders. Named heading rather than title because title is the HTML global attribute and paints a browser tooltip over the whole panel; a title still works and is migrated to heading.
level 1 | 2 | 3 | 4 | 5 | 6
1 2 3 4 5 6
2
html svelte astro
The heading level, so the panel slots into the document outline correctly.
variant PanelVariant
default collapsible
default
html svelte astro
default is a static section; collapsible is a disclosure with a clickable header.
open boolean false
html svelte astro
For the collapsible variant: whether the body starts expanded.
scroll boolean false
html svelte astro
Caps the body height and makes it a focusable, keyboard-scrollable region.
fill boolean false
html svelte astro
Takes the remaining height of a bounded parent and gives it to the body, which scrolls; the header and footer keep their natural height. This is the panel-in-a-column case — a stack of panels where one absorbs the slack — and it cannot be expressed from outside, because bounding the body means bounding the host and the section above it too. scroll caps the body at a fixed height; fill sizes it from what the column has left.
markerIcon html: marker-icon string "chevron-right"
html svelte astro
The roster glyph drawn as the collapsible header's marker. Any name the icon roster can draw, including one a mod contributed through the xtyle.icons slot.

Events

What the component emits, and what rides along on event.detail. The name in the first column is the one addEventListener takes.

EventDetailBindingsDescription
toggle svelte: onToggle { open }
html svelte astro
A collapsible panel opened or closed.

Appearance

Variants

default

.xtyle-panel

A static titled section.

collapsible

.xtyle-panel--collapsible

A native disclosure; the header toggles the body open and closed.

States

open

.xtyle-panel--collapsible[open] > summary .xtyle-panel__marker

The collapsible panel is expanded; the marker rotates to point down.

collapsed

.xtyle-panel__marker

The collapsible panel is closed; the body is hidden, the marker points right.

hover

.xtyle-panel--collapsible > summary:hover::after

Pointer over a collapsible header; the overlay paints the hover tint.

active

.xtyle-panel--collapsible > summary:active::after

Collapsible header pressed; the overlay paints the press tint.

focus-visible

.xtyle-panel__toggle:focus-visible

Keyboard focus on the toggle or the scroll body: an inset token-colored ring.

Anatomy

The named parts that make up the component. A ::part() handle is reachable from your own stylesheet; the class beside it is the component's internal selector, which a shadow boundary keeps to itself.

panel

Success:::part(panel) .xtyle-panel

The root section (or details) carrying the variant and modifier classes.

--bg-0 --line --border-thin --radius-lg

header

Success:::part(header) .xtyle-panel__header

The title row; for the collapsible variant it's the clickable summary/toggle.

--bg-1 --line --border-thin --space-3 --space-4 --space-2

title

Success:::part(title) .xtyle-panel__title

The heading, rendered at the configured level and referenced by the section's aria-labelledby.

--font-display --weight-semibold --text-sm --fg-1

spacer

Success:::part(spacer) .xtyle-panel__spacer

A flexible gap that pushes the actions slot to the trailing edge of the header.

marker

Success:::part(marker) .xtyle-panel__marker

The collapsible variant's disclosure caret, leading the toggle; rotates 90° to point down when the panel is open. It is an <xtyle-icon name="chevron-right"> inside the panel's fragment, so the glyph renders through the Icon component and a mod can swap it without touching the panel.

--fg-2 --duration-fast --ease-emphasized

body

Success:::part(body) .xtyle-panel__body

The content region the panel labels; becomes a scroll container under the scroll flag.

--space-4 --space-3

footer

Success:::part(footer) .xtyle-panel__footer

A quiet trailing row for metadata or secondary actions.

--bg-1 --line --border-thin --fg-2 --text-sm --space-3 --space-4 --space-2

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 24/24 consumed tokens produced default register: 310 tokens

Live coverage check against the xtyle-default register (derive(xtyleDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--bg-0 --bg-1 --border-normal --border-thick --border-thin --duration-fast --ease-emphasized --ease-standard --fg-1 --fg-2 --font-display --line --radius-lg --ring --scrollbar-thumb --scrollbar-track --space-2 --space-3 --space-4 --space-8 --state-hover --state-press --text-sm --weight-semibold

Slots

default
html svelte astro

The panel body content.

actions
html svelte astro

Controls aligned to the trailing edge of the header.

footer
html svelte astro

A quiet trailing row below the body.

Accessibility

The default variant is a native <section> labelled by its heading via aria-labelledby, so it is announced as a named region.
The heading renders at a configurable level so the panel participates correctly in the document outline; the binding warns when neither a heading nor an actions slot supplies one.
The collapsible variant uses native <details>/<summary> (or a <button> with aria-expanded in the custom element), giving keyboard toggling and screen-reader disclosure semantics for free.
The disclosure marker is decorative (aria-hidden); expanded state lives in [open] / aria-expanded, not the rotation.
Under scroll the body is a focusable region (tabindex="0", role="region") so keyboard users can scroll it, with the standard inset focus ring.

Code

Header, collapsible, and scroll

A titled panel with actions and a footer, a collapsible disclosure, and a scrollable body.

<xtyle-panel heading="Connections" level="2">
	<button slot="actions" class="xtyle-button xtyle-button--ghost xtyle-button--neutral xtyle-button--sm">Refresh</button>
	<p>Two services are connected.</p>
	<p slot="footer">Last synced a moment ago.</p>
</xtyle-panel>

<xtyle-panel heading="Advanced options" variant="collapsible">
	<label><input type="checkbox" /> Verbose logging</label>
	<label><input type="checkbox" /> Telemetry</label>
</xtyle-panel>

<xtyle-panel heading="Activity log" scroll>
	<p>A long stream of entries that scrolls inside the panel body…</p>
</xtyle-panel>

A different collapse marker

The collapsible header's marker drawn from any name the icon roster can draw, including one a mod contributed.

<xtyle-panel variant="collapsible" heading="A different marker" marker-icon="plus">
	<p>The disclosure marker is drawn from any name the icon roster can draw.</p>
</xtyle-panel>