Skip to main content
xriptxr

Reveal

Info:Layout
79

A lid that slides aside to expose a belly of detail or actions underneath.

swipe slide belly backdrop disclosure swipe actions drawer peek

Live demo

live · @xtyle/astro

Reveal

An incoming call

The whole point of the component in one box. Slide the lid right to answer, left to decline. The belly under each edge is already the color of its answer, so the box says what will happen before you commit to it. Both are behavior="commit", so a full pull acts and springs back rather than staying open.

Answer
Decline

A mail row, the way you would actually ship it

Grouped by name, so opening one closes the last. Sliding right latches a detail belly open to read; sliding left is endBehavior="both", so a short pull shows the action and a full pull just takes it.

Received 09:12 · 2 attachments
Archive
Received 08:40 · 2 attachments
Archive
Received Yesterday · 2 attachments
Archive

Box shapes

A shaped box is a sliding-top box: belly and lid are the same silhouette, and the lid moves as one whole shape rather than being cut as it goes. A shaped box drops its corner radius, and a toned belly drops its frame, since a straight edge cannot survive a cut one. Add contained to hold the lid inside the box's bounds instead of letting it travel clear; the last one here shows it.

underneath
underneath
underneath
underneath
underneath

Any silhouette, not just the named ones

shape takes a registered name or a clip-path value outright, so a box can be built from a shape the library has never heard of. Register more names with registerRevealShapes(), last-wins, the way the effect library takes verbs.

underneath
underneath

A lid carrying artwork

bleed lets the lid's content run to the edges with the grips floating over it, which is what a picture wants and text does not. These take gripStyle="dots", since a glyph reads as clutter over a picture; bar and none are the other two. The art is inline <svg> whose gradients read the named hue tokens, so these scenes recolor with the theme rather than being pinned to dead hex. Each option carries its own art, belly tones, and grip glyphs; sliding right latches the detail open, sliding left commits.

Restores 12 HP · costs 3 hours
Travel to the abbey
Trade goods · prices shift daily
Travel to the market
Catch supper · costs 2 hours
Travel to the river

Every direction, each saying what it does

All four bellies filled, each with its own tone and its own grip glyph, so every edge announces itself. Travel still locks to one axis, so it only ever goes one way at a time.

Add to basket
Remove
1.0L · variable temperature
Save for later

Disabled

The lid is locked in place and the bellies are hidden entirely.

You should not see this

Reveal layers a lid over as many as four bellies, one per direction, and slides the lid to expose whichever the gesture asks for. Which directions are live is inferred from the bellies you fill: a [slot="end"] makes the end direction live and nothing else does, so there is no second list of directions to keep in sync.

Travel is locked to one axis per gesture, so a component offering start and bottom still only ever moves one way at a time. Every knob is a host attribute, so the same markup configures identically from HTML, Svelte, and Astro; behavior sets the default and endBehavior and friends override one direction. Each direction decides what its own slide means: latch opens and stays, commit fires an action and springs back, and both gives the short pull a latch and the full pull the action. Give several reveals a shared name and they behave like radios, where opening one closes the last; leave the name off and they behave like checkboxes, each independent. A concealed belly is inert, so its buttons never sit in the tab order waiting to be tabbed into by accident.

When to use

How this component composes with the rest of the set.

Give a list row an end belly of actions and a start belly of detail, so one row answers both "what is this" and "what can I do with it".
Reach for behavior="both" when a belly's first action is the obvious one: the short pull shows the choices, the full pull takes the first without waiting.
Group a stack with a shared name when only one detail panel should be open at a time, and leave the name off when they are independent.
Wrap a group in <xtyle-reveal-group> to scope its names and give the set an accessible label; two lists on one page can then both use name="items".
Override the component.reveal fill to reshape the grips or the belly containers without touching the content either side of them.

Props

45 props, straight from the manifest.

PropTypeDefaultBindingsDescription
name string
html svelte astro
Groups this reveal with others sharing the name, so opening one closes the last, the way radios share a choice. Omit it and the reveal is independent. The name is scoped to the nearest `<xtyle-reveal-group>`, falling back to the document, so two unrelated lists can reuse a name without cross-talk.
open "start" | "end" | "top" | "bottom"
start end top bottom
html svelte astro
Which direction's belly is currently exposed. Set it to open one outright; absent means closed.
behavior "latch" | "commit" | "both"
latch commit both
latch
html svelte astro
What letting go of a slide means, for every direction unless one overrides it. `latch` opens and stays open, `commit` fires the belly's action and springs back, and `both` gives a short pull the latch and a full pull the action.
shape string
html svelte astro
A silhouette to build the box from. Takes a registered name (`parallelogram`, `chevron`, `ticket`, `heart`) or any `clip-path` value outright, so a caller can hand over a shape the library has never heard of: `shape="polygon(0 0, 100% 20%, 100% 100%, 0 80%)"`. Register more names with `registerRevealShapes()`, last-wins on the name, the way the effect library takes verbs. Percentages scale with the box; absolute units do not. Set `contained` to hold the sliding lid inside the box's bounds instead of letting it travel clear.
bleed boolean false
html svelte astro
Lets the lid's content reach the lid's edges instead of stepping aside for the grips, so a grip glyph floats over the content rather than pushing it inward. For a lid carrying artwork (an illustration, an inline `<svg>`, a photo) the picture should run to the edge; for a lid carrying text it should not, which is why the inset is the default. It drops the inset and nothing else: sizing the artwork stays the author's, since forcing a height onto content with its own aspect ratio blows the box open.
contained boolean false
html svelte astro
Holds a shaped box's lid inside the box's bounds as it slides, cutting it off at the edge rather than letting it travel clear. Off by default, so a shaped box behaves like a sliding-top box: belly and lid are the same silhouette and the lid moves as one whole shape. Only meaningful alongside `shape`; an unshaped box always contains its lid.
tone FullTone
accent neutral danger success warn info
html svelte astro
Paints every belly from one tone's token family (its fill from `--{tone}-bg`, its text from `--{tone}-text`, and a frame from `--{tone}`), so a belly reads as accept or decline at a glance. Any tone in the roster works: the semantic roles, the accent-ramp variants, and the named hues.
flickVelocity number 0.4
html svelte astro
Pixels per millisecond above which a short fast flick latches regardless of how far it travelled, so a quick decisive swipe counts as intent the way a slow deliberate drag does.
travel number | string 0.7
html svelte astro
How far the lid slides when it opens, as a fraction of the box along that axis. The default leaves the lid holding onto the box rather than sliding off it entirely; `1` lets it come clear, and a smaller value suits a row that only needs to show an action. Overridable per direction.
gripStyle "glyph" | "bar" | "dots" | "none"
glyph bar dots none
glyph
html svelte astro
What each grip draws. `glyph` is the roster icon, which says what the edge does; `bar` and `dots` are quiet marks for a lid carrying artwork, where an icon reads as clutter; `none` draws no grip at all, leaving the drag and the arrow keys as the way in. Overridable per direction.
gripSize string var(--space-5)
html svelte astro
The size of the glyph in each grip. A bare bar can be tiny; an icon you must read before answering a call cannot.
gripPad string var(--space-3)
html svelte astro
The breathing room around each grip glyph, which together with `gripSize` sets the grip's hit area.
latchAt number | string 0.4
html svelte astro
How far the lid must travel, as a fraction of the belly's own measured size, before letting go latches it open. Accepts a fraction (`0.4`) or a percentage (`40%`). A belly can override it for its own direction.
commitAt number | string 0.85
html svelte astro
How far the lid must travel before letting go fires the belly's action instead of latching. Only consulted for a `commit` or `both` belly. Same fraction-or-percentage shape as `latchAt`, and overridable per belly.
lockThreshold number 8
html svelte astro
Pixels of travel before the gesture commits to an axis. Until then nothing moves, so a near-vertical drag on a horizontal reveal scrolls the page instead of fighting it.
disabled boolean false
html svelte astro
Locks the lid in place and hides the bellies.
label string
html svelte astro
Accessible name for the lid, which is announced as a group carrying its expanded state.
startTone FullTone
accent neutral danger success warn info
html svelte astro
Overrides `tone` for the start belly alone, which is how one box declines in red and accepts in green.
startGrip string
html svelte astro
The roster glyph drawn in the start grip, so each edge says what it does. Any name the icon roster can draw, including one a mod contributed through the `xtyle.icons` slot.
endTone FullTone
accent neutral danger success warn info
html svelte astro
Overrides `tone` for the end belly alone, which is how one box declines in red and accepts in green.
endGrip string
html svelte astro
The roster glyph drawn in the end grip, so each edge says what it does. Any name the icon roster can draw, including one a mod contributed through the `xtyle.icons` slot.
topTone FullTone
accent neutral danger success warn info
html svelte astro
Overrides `tone` for the top belly alone, which is how one box declines in red and accepts in green.
topGrip string
html svelte astro
The roster glyph drawn in the top grip, so each edge says what it does. Any name the icon roster can draw, including one a mod contributed through the `xtyle.icons` slot.
bottomTone FullTone
accent neutral danger success warn info
html svelte astro
Overrides `tone` for the bottom belly alone, which is how one box declines in red and accepts in green.
bottomGrip string
html svelte astro
The roster glyph drawn in the bottom grip, so each edge says what it does. Any name the icon roster can draw, including one a mod contributed through the `xtyle.icons` slot.
startTravel number | string
html svelte astro
Overrides `travel` for the start direction alone.
endTravel number | string
html svelte astro
Overrides `travel` for the end direction alone.
topTravel number | string
html svelte astro
Overrides `travel` for the top direction alone.
bottomTravel number | string
html svelte astro
Overrides `travel` for the bottom direction alone.
startGripStyle "glyph" | "bar" | "dots" | "none"
glyph bar dots none
html svelte astro
Overrides `gripStyle` for the start direction alone.
endGripStyle "glyph" | "bar" | "dots" | "none"
glyph bar dots none
html svelte astro
Overrides `gripStyle` for the end direction alone.
topGripStyle "glyph" | "bar" | "dots" | "none"
glyph bar dots none
html svelte astro
Overrides `gripStyle` for the top direction alone.
bottomGripStyle "glyph" | "bar" | "dots" | "none"
glyph bar dots none
html svelte astro
Overrides `gripStyle` for the bottom direction alone.
startBehavior "latch" | "commit" | "both"
latch commit both
html svelte astro
Overrides `behavior` for the start direction alone.
startLatchAt number | string
html svelte astro
Overrides `latchAt` for the start direction alone.
startCommitAt number | string
html svelte astro
Overrides `commitAt` for the start direction alone.
endBehavior "latch" | "commit" | "both"
latch commit both
html svelte astro
Overrides `behavior` for the end direction alone.
endLatchAt number | string
html svelte astro
Overrides `latchAt` for the end direction alone.
endCommitAt number | string
html svelte astro
Overrides `commitAt` for the end direction alone.
topBehavior "latch" | "commit" | "both"
latch commit both
html svelte astro
Overrides `behavior` for the top direction alone.
topLatchAt number | string
html svelte astro
Overrides `latchAt` for the top direction alone.
topCommitAt number | string
html svelte astro
Overrides `commitAt` for the top direction alone.
bottomBehavior "latch" | "commit" | "both"
latch commit both
html svelte astro
Overrides `behavior` for the bottom direction alone.
bottomLatchAt number | string
html svelte astro
Overrides `latchAt` for the bottom direction alone.
bottomCommitAt number | string
html svelte astro
Overrides `commitAt` for the bottom direction alone.

Appearance

States

open

.xtyle-reveal--open

A belly is exposed; the modifier names which direction.

grouped

.xtyle-reveal--grouped

The reveal carries a name, so opening it closes its peers.

disabled

.xtyle-reveal--disabled

The lid is locked and the bellies are hidden.

Anatomy

The named parts that make up the component, with their selectors.

lid

.xtyle-reveal__lid

The lid: the sliding surface holding the default slot's content. Focusable, and the target of the drag.

belly

.xtyle-reveal__belly

What sits under the lid in one direction, revealed as the lid slides off it.

grip

.xtyle-reveal__grip

The edge affordance for a direction, giving a pointer-free way to open that belly.

Tokens & coverage

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

Success:fully covered 79/79 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.

--accent --accent-2 --accent-2-bg --accent-2-text --accent-3 --accent-3-bg --accent-3-text --accent-4 --accent-4-bg --accent-4-text --accent-bg --accent-text --bg-1 --bg-2 --black --black-bg --black-text --blue --blue-bg --blue-text --border-normal --border-thick --brown --brown-bg --brown-text --cyan --cyan-bg --cyan-text --danger --danger-bg --danger-text --duration-base --ease-standard --fg-0 --fg-1 --fg-2 --gray --gray-bg --gray-text --green --green-bg --green-text --info --info-bg --info-text --neutral --neutral-bg --neutral-text --orange --orange-bg --orange-text --pink --pink-bg --pink-text --purple --purple-bg --purple-text --radius-full --radius-md --red --red-bg --red-text --ring --space-1 --space-2 --space-3 --space-5 --success --success-bg --success-text --warn --warn-bg --warn-text --white --white-bg --white-text --yellow --yellow-bg --yellow-text

Slots

default
html svelte astro

The lid: whatever sits on top and slides.

start
html svelte astro

The belly on the inline-start edge, filling the whole box and uncovered as the lid slides toward the end. Mirrors under RTL. Configure it with the host's startBehavior / startLatchAt / startCommitAt.

end
html svelte astro

The belly on the inline-end edge, exposed by dragging toward the start. Configure it with the host's endBehavior / endLatchAt / endCommitAt.

top
html svelte astro

The belly on the block-start edge, exposed by dragging the lid down. Configure it with the host's topBehavior / topLatchAt / topCommitAt.

bottom
html svelte astro

The belly on the block-end edge, exposed by dragging the lid up. Configure it with the host's bottomBehavior / bottomLatchAt / bottomCommitAt.

Accessibility

The lid is focusable and announced as a group carrying aria-expanded, so the disclosure is legible without a pointer.
Arrow keys open the belly on the matching edge and Escape closes whichever is open, so every direction has a keyboard route.
A concealed belly is inert, keeping its controls out of the tab order until it is actually on screen.
When a grouped reveal is closed by a sibling opening, focus lands on its own lid rather than being dropped to the document.
Travel locks to one axis after lockThreshold pixels, so a vertical scroll gesture on a horizontal reveal still scrolls the page.
The slide honors prefers-reduced-motion, landing in the same place with the travel skipped.

Code

Directions, behaviors, and grouping

A single-direction reveal, a two-direction one pairing detail with a committing action, and a grouped stack where opening one closes the last.

<!-- One direction: slide the lid aside to read what's under it -->
<xtyle-reveal>
	<article>Ada Lovelace &middot; Analytical Engine notes</article>
	<div slot="end">First published 1843</div>
</xtyle-reveal>

<!-- Two directions with different bellies, and a swipe that acts rather than opens -->
<xtyle-reveal latch-at="40%" end-behavior="commit" end-commit-at="0.7">
	<article>Weekly digest</article>
	<div slot="start">12 unread &middot; 3 flagged</div>
	<div slot="end"><button type="button">Archive</button></div>
</xtyle-reveal>

<!-- A grouped stack: sliding one closes whichever was open -->
<xtyle-reveal-group label="Products">
	<xtyle-reveal name="products">
		<article>Kettle</article>
		<div slot="bottom">£49 &middot; in stock</div>
	</xtyle-reveal>
	<xtyle-reveal name="products">
		<article>Cafetière</article>
		<div slot="bottom">£22 &middot; in stock</div>
	</xtyle-reveal>
</xtyle-reveal-group>