Skip to content

DisclosureRow

The one-line [leading] title · summary chrome that expands to reveal a body. It is the row shared by <r-reasoning> and <r-tool-card>, so a transcript carrying both has one disclosure language instead of two.

Use when you have a compact line that stands for something larger — a tool call, a chain of thought, a log group — and the detail is worth hiding until asked for.

Quick Start

Basic Usage

The body appears when the row is open.
html
<r-disclosure-row heading="Read file" summary="packages/ranui/index.ts" expandable>
  <div>The body appears when the row is open.</div>
</r-disclosure-row>

The heading is the fixed-width left half and the summary is the truncating right half, so a column of rows lines up on the same spine no matter how long each summary is. An empty summary drops the separator with it.

While the work is running

busy draws a shimmer sweep across the row. A spinner says something somewhere is happening; a sweep over the row says this row is the one still working.

With a leading indicator

The leading slot and its hover chevron share one grid cell, so the swap on hover costs no layout.

Bundle exceeds the size limit.
html
<r-disclosure-row heading="Build" summary="failed in 4.2s" tone="error" expandable>
  <r-state-dot slot="leading" state="error"></r-state-dot>
  <div>Bundle exceeds the size limit.</div>
</r-disclosure-row>

API Reference

Properties

PropertyAttributeTypeDefaultDescription
headingheadingstring''The fixed-width left half of the line.
summarysummarystring''The truncating right half. Empty drops the separator with it.
openopenbooleanfalseWhether the body is shown. Reflected, so :has([open]) works.
expandableexpandablebooleanfalseWhether the row has a body worth opening.
busybusybooleanfalseWhether the work this row stands for is still running.
tonetonestring''error colours the summary; anything else is the ordinary tone.
sheetsheetstring''CSS injected into the shadow root.

The attribute is heading, not title

title is a native HTMLElement attribute the browser renders as a tooltip, so a component that used it for a heading would make every instance sprout a tooltip repeating the text already on screen — and nothing turns that off once it is set. <r-card> and <r-modal> carry the same rename for the same reason.

Events

EventDetailDispatchDescription
disclosuretogglebubbles, composedThe row was expanded or collapsed.

The event is disclosuretoggle, not toggle

toggle is what <details> fires, and its ToggleEvent carries oldState / newState rather than a detail — a listener typed against the platform name finds nothing in it. Read the state from the element: row.open.

js
row.addEventListener('disclosuretoggle', () => {
  console.log(row.open ? 'opened' : 'closed');
});

Slots

SlotContent
defaultThe body, revealed while open.
leadingAn indicator before the heading — typically <r-state-dot>.

Parts

row · leading · title · separator · summary · disclosure · body

Styling

<r-disclosure-row> exposes 15 CSS custom properties of its own, plus the semantic tokens it reads from the theme. Set one anywhere it inherits from — :root, a wrapper, or the element:

css
r-disclosure-row {
  --ran-disclosure-hover-background: var(--ran-color-bg-subtle);
}

Parts: body · disclosure · leading · row · separator · summary · title

The full list is in style tokens; which token to reach for is the design system.

Best Practices

  • Give a row a body, or don't make it expandable. A chevron that opens an empty area is a dead end; leave expandable off and the row stays a line.
  • Keep the heading a fixed vocabulary (Read file, Run tests, Search) and put the variable part in the summary. That is what makes a column of rows scannable.
  • Pair tone="error" with words, never colour alone — the summary should say what failed.

Released under the MIT License.