Designer view

Disclosure

A single collapsible region with one toggle — a button that expands or collapses an associated content panel. The atomic unit of disclosure: Accordion is a list of disclosures grouped with shared keyboard navigation, but a standalone Disclosure has no peers and no group semantics. Used for "show more" patterns in prose, expandable details rows, optional advanced settings, inline help expansion, and any single named region whose content is disclosable on demand.

When to use

Use

For a single collapsible region — "show more" patterns in prose, expandable details rows, optional advanced settings, inline help expansion, expandable filter sections. The user toggles the disclosure to reveal or hide content that is not always needed.

Avoid

For a list of disclosures grouped with shared keyboard navigation — that is `Accordion`. For mutually-exclusive parallel views — that is `Tabs`. For navigation between independent pages — that is `SidebarNav`. For blocking content reveals — that is `Modal` or `Drawer`.

Versus related

  • accordion

    `Accordion` is a list of disclosures grouped as a unit with shared keyboard navigation (ArrowDown / Up between items, Home / End to first / last). `Disclosure` is a single collapsible region with no peers and no group semantics. Accordion-of-one-item is anti-pattern; use Disclosure when there's only one region.

  • tabs

    `Tabs` always shows one panel at a time, replaces on selection, and has visible peer labels for unselected panels. `Disclosure` shows zero or one panel and has no peers. Tabs are lateral; Disclosure is hierarchical (the trigger is a heading or sentence-fragment in the document outline).

  • modal

    `Modal` blocks the page and demands explicit response; `Disclosure` is non-blocking and reveals inline. Modal severs spatial relationship to the underlying content; Disclosure preserves it.

Highlight
Fig 1.1 · Disclosure · Designer view
Designer

Figma anatomy

Slot Figma type Hint
trigger instance Button instance; visual treatment varies by variant (inline link-style, standalone block)
icon instance Icon component instance; rotation or swap bound to expanded state
panel frame Auto-layout vertical frame; visibility bound to expanded state
Designer

Token usage per slot

trigger
spacing
  • paddingspacing.compact
  • gapspacing.compact
color
  • foregroundcolor.text.accent
  • ringcolor.border.focus
typography
  • sizetext.md
  • weightweight.medium
icon
color
  • foregroundcolor.text.muted
panel
spacing
  • paddingspacing.compact
color
  • foregroundcolor.text.primary
typography
  • sizetext.md
  • lineHeightleading.normal
Both

Figma ↔ Code property map

FigmaTypeCodeNotes
VariantVariantvariantMaps inline / standalone. Drives heading-wrapping (standalone wraps trigger in heading; inline does not).
Default ExpandedBooleandefaultExpandedInitial open state. False for "show more" patterns; true for content that should be visible by default but collapsible for users who want to reduce noise.
DensityVariantdensitycomfortable / compact. At and below `breakpoint.sm` density compact is the canonical default for inline variant.
Has IconBooleanhasIconToggles the chevron / plus-minus icon. Default true; rare to disable.
Trigger LabelTexttriggerLabelThe button's accessible name. "Show more" / "Read details" / heading text per use case.
Panel ContentInstance SwapchildrenSwap the panel content slot — prose, form, list, custom layout.
IconInstance SwapiconSwap the chevron glyph; defaults vary per design system.
Designer

Motion

TransitionDuration token
expandmotion.duration.base
collapsemotion.duration.base
chevronRotatemotion.duration.fast
Easing
motion.easing.standard
Reduced motion
Instant (jump cut)
Designer

Responsive behaviour

BreakpointChange
breakpoint.smAt and below, density compact becomes the canonical default for inline-variant disclosures (narrow viewports cannot accommodate comfortable density inline). Standalone-variant disclosures retain comfortable density unless explicitly authored as compact.
breakpoint.mdAbove this width, density and variant render as authored. No layout transformation.
Both

Internationalisation

RTL · mirroring

Trigger inline-content order reverses logically — the icon moves from inline-end (visual right in LTR) to inline-end (visual left in RTL) via logical positioning. Panel content inherits document direction. Chevron rotation is direction-neutral (down/up arrows are symmetric); plus-minus glyphs are also direction-neutral. Standalone-variant heading-wrapping is direction-neutral.

Text expansion

Trigger label wraps to additional lines under heavy expansion (DE / RU / FI). Panel content follows its own text-flow. Density compact risks crowding long-text trigger labels; density comfortable is the safer default in long-text locales. Multi-line trigger labels behave correctly with the icon — chevron aligns with the first line by canonical convention.

Both

Variants, properties, states

Variants

Structurally different versions of the component.

inlinestandalone

Properties

The same component, parameterised.

PropertyType
defaultExpandedboolean
densitycomfortable | compact
hasIconboolean

States

Browser/user-driven (interactive) vs. app-driven (data).

KindStates
interactive
hoverfocus-visibleactivedisabled
data
closedexpandingexpandedcollapsing
Both

State transitions

FromToTrigger
closedexpandingUser activates the trigger (Enter / Space / click). `aria-expanded` flips to true; the panel begins its enter animation.
expandingexpandedThe expand animation completes (or, under prefers-reduced-motion reduce, immediately). The panel is fully visible and reachable by keyboard via Tab.
expandedcollapsingUser activates the trigger again (toggle is symmetric on Disclosure — unlike single-mode Accordion which may have non-collapsible behaviour).
collapsingclosedThe collapse animation completes (or immediately under reduced motion). The panel is removed from the accessibility tree and from keyboard tab order via `hidden` or `display: none`.
Both

Figma↔Code mismatches

  1. 01
    Figma

    A "Show more" link drawn for inline disclosure in body prose

    Code

    A `<button>` toggling visibility of inline content

    Consequence

    Designers may use link-styling for "Show more" affordances (looks like other inline links in prose). Implementations following the Figma file ship `<a>` with click handlers — semantically wrong (anchors navigate, disclosures toggle), breaks middle-click expectations, and SR users hear "link" with no toggle-state cue.

    Correct

    Use `<button>` with disclosure semantics (`aria-expanded`, `aria-controls`). Visual styling may converge with link styling (underlined, accent colour) but the underlying element is a button. Document the visual-vs-semantic distinction in mismatches.

  2. 02
    Figma

    Disclosure drawn with chevron rotation but no panel-height transition

    Code

    Both chevron rotation AND panel height-transition animate together

    Consequence

    Designers animate the chevron in mocks but the panel appears instantly (Figma cannot easily mock smooth height-transitions). Developers shipping faithful-to-mock get jumpy panel transitions; SR users get no announcement while the visible content shifts.

    Correct

    Both the chevron rotation and the panel height-transition share the same duration token. Implementations using `[hidden]` toggle without animation are valid for `prefers-reduced-motion: reduce` (the canonical reducedMotionFallback is `instant`).

  3. 03
    Figma

    Standalone disclosure drawn without heading semantics

    Code

    Standalone disclosure with the trigger wrapped in a heading element

    Consequence

    Designers draw a "section" with a click-to-expand affordance but treat it as plain UI rather than as a document structural element. Implementations skip the heading wrapper; SR users navigating by heading miss the collapsible region's existence.

    Correct

    For standalone disclosures representing document content regions (an FAQ entry, a settings section, a CSV import step), wrap the trigger in a heading element of the appropriate level. For inline disclosures in prose ("Show more" inside a paragraph), the trigger is not heading- wrapped. Document the variant-driven structural choice.

  4. 04
    Figma

    Disclosure used for a single Accordion-of-one-item

    Code

    A standalone Disclosure component, not Accordion

    Consequence

    Designers compose an Accordion with a single item for visual consistency with multi-item accordions elsewhere on the page. Developers ship an Accordion with one item; the user sees a collapsible region but the surrounding ARIA structure is wrong (no list semantics for a single item, no shared keyboard navigation that Accordion provides for multiple items).

    Correct

    A single collapsible region is a Disclosure, not an Accordion-of-one. Use Disclosure when there's only one collapsible region; use Accordion when there are multiple disclosures grouped with shared keyboard navigation (ArrowDown / Up between triggers).

Designer

Common mistakes

#disclosure-no-aria-expanded

Trigger missing `aria-expanded` toggle

Problem

The button has no `aria-expanded` attribute. Visually content reveals; SR users hear "button" with no state cue. Icon rotation alone is invisible to non-sighted users.

Fix

`aria-expanded="true"` on the button when the panel is open, `false` when closed. Always pair with `aria-controls` referencing the panel's id. Style the icon from `[aria-expanded="true"]` rather than introducing a parallel `data-expanded` attribute.

#disclosure-no-aria-controls

`aria-controls` not wired to the panel

Problem

Trigger has `aria-expanded` but no `aria-controls`. SR users know the trigger is expanded/collapsed but cannot navigate to the disclosed content directly. The relationship between trigger and panel is implicit (visual proximity) rather than explicit.

Fix

`aria-controls` references the panel's id. Pair with the panel's `aria-labelledby` referencing the trigger's id for the bidirectional relationship. Mature primitives (Radix, React Aria) wire this automatically.

#disclosure-icon-only-state-cue

Expansion state shown only via icon rotation

Problem

The chevron rotates on expand, but `aria-expanded` is missing or stuck. Sighted users see the state; SR users do not. The icon is decorative; without `aria-expanded` it carries the entire state-meaning load.

Fix

`aria-expanded` is the source of truth. The icon visualises the state. Style icon rotation from `[aria-expanded="true"]`. The icon is `aria-hidden`.

Accessibility hints
Slot Accessibility hint
trigger Real `<button>` — never a `<div>` with click handler nor an `<a>` (anchors navigate; disclosures toggle in-page state). Carries `aria-expanded="true|false"` and `aria-controls` referencing the panel's id. Standalone disclosures may be wrapped in a heading element when the disclosure represents a content region; inline disclosures (within prose) are not heading-wrapped.
icon Decorative — `aria-hidden="true"`. State is communicated through `aria-expanded` on the trigger; the icon is visual reinforcement only.
panel Apply `aria-labelledby` referencing the trigger's id (or `aria-label` if the trigger has no useful text content for labelling). For standalone disclosures with regional content, `role="region"` is appropriate; for inline disclosures in prose, no role needed (the content retains its native semantics). Hide via `hidden` attribute or `display: none` when collapsed (not just zero-height) so SR users do not encounter ghost content.