Panel
A titled content region: a header with a configurable heading and actions, a body, an optional footer, and an optional collapsible or scrollable form.
Live demo
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.
Props
8 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
heading — names the region without rendering a heading. | ||||
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. | ||||
default is a static section; collapsible is a disclosure with a clickable header. | ||||
scroll caps the body at a fixed height; fill sizes it from what the column has left. | ||||
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.
| Event | Detail | Bindings | Description |
|---|---|---|---|
Appearance
Variants
default
A static titled section.
collapsible
A native disclosure; the header toggles the body open and closed.
States
open
The collapsible panel is expanded; the marker rotates to point down.
collapsed
The collapsible panel is closed; the body is hidden, the marker points right.
hover
Pointer over a collapsible header; the overlay paints the hover tint.
active
Collapsible header pressed; the overlay paints the press tint.
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
The root section (or details) carrying the variant and modifier classes.
header
The title row; for the collapsible variant it's the clickable summary/toggle.
title
The heading, rendered at the configured level and referenced by the section's aria-labelledby.
spacer
A flexible gap that pushes the actions slot to the trailing edge of the header.
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.
body
The content region the panel labels; becomes a scroll container under the scroll flag.
footer
A quiet trailing row for metadata or secondary actions.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
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-semiboldSlots
The panel body content.
Controls aligned to the trailing edge of the header.
A quiet trailing row below the body.
Accessibility
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><script lang="ts">
import { Panel } from "@xtyle/svelte";
</script>
<Panel heading="Connections" level={2}>
{#snippet actions()}
<button class="xtyle-button xtyle-button--ghost xtyle-button--neutral xtyle-button--sm">Refresh</button>
{/snippet}
<p>Two services are connected.</p>
{#snippet footer()}
<span>Last synced a moment ago.</span>
{/snippet}
</Panel>
<Panel heading="Advanced options" variant="collapsible">
<label><input type="checkbox" /> Verbose logging</label>
<label><input type="checkbox" /> Telemetry</label>
</Panel>
<Panel heading="Activity log" scroll>
<p>A long stream of entries that scrolls inside the panel body…</p>
</Panel>---
import { Panel } from "@xtyle/astro";
---
<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>
</Panel>
<Panel heading="Advanced options" variant="collapsible">
<label><input type="checkbox" /> Verbose logging</label>
<label><input type="checkbox" /> Telemetry</label>
</Panel>
<Panel heading="Activity log" scroll>
<p>A long stream of entries that scrolls inside the panel body…</p>
</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>---
import Panel from "@xtyle/astro/Panel.astro";
---
<Panel variant="collapsible" heading="A different marker" markerIcon="plus">
<p>The disclosure marker is drawn from any name the icon roster can draw.</p>
</Panel>