Reveal
A lid that slides aside to expose a belly of detail or actions underneath.
Live demo
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.
Props
45 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
States
open
A belly is exposed; the modifier names which direction.
grouped
The reveal carries a name, so opening it closes its peers.
disabled
The lid is locked and the bellies are hidden.
Anatomy
The named parts that make up the component, with their selectors.
lid
The lid: the sliding surface holding the default slot's content. Focusable, and the target of the drag.
belly
What sits under the lid in one direction, revealed as the lid slides off it.
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.
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
The lid: whatever sits on top and slides.
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.
The belly on the inline-end edge, exposed by dragging toward the start. Configure it with the host's endBehavior / endLatchAt / endCommitAt.
The belly on the block-start edge, exposed by dragging the lid down. Configure it with the host's topBehavior / topLatchAt / topCommitAt.
The belly on the block-end edge, exposed by dragging the lid up. Configure it with the host's bottomBehavior / bottomLatchAt / bottomCommitAt.
Accessibility
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 · 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 · 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 · in stock</div>
</xtyle-reveal>
<xtyle-reveal name="products">
<article>Cafetière</article>
<div slot="bottom">£22 · in stock</div>
</xtyle-reveal>
</xtyle-reveal-group>
<script lang="ts">
import { Reveal, RevealGroup } from "@xtyle/svelte";
const products = [
{ name: "Kettle", price: "£49" },
{ name: "Cafetière", price: "£22" },
];
</script>
<Reveal latchAt="40%" endBehavior="commit" endCommitAt="0.7" onreveal={(d) => console.log(d.direction)}>
<article>Weekly digest</article>
<div slot="start">12 unread · 3 flagged</div>
<div slot="end"><button type="button">Archive</button></div>
</Reveal>
<!-- grouped: sliding one closes whichever was open -->
<RevealGroup label="Products">
{#each products as product}
<Reveal name="products">
<article>{product.name}</article>
<div slot="bottom">{product.price} · in stock</div>
</Reveal>
{/each}
</RevealGroup>
---
import Reveal from "@xtyle/astro/Reveal.astro";
import RevealGroup from "@xtyle/astro/RevealGroup.astro";
const products = [
{ name: "Kettle", price: "£49" },
{ name: "Cafetière", price: "£22" },
];
---
<Reveal latchAt="40%" endBehavior="commit" endCommitAt="0.7">
<article>Weekly digest</article>
<div slot="start">12 unread · 3 flagged</div>
<div slot="end"><button type="button">Archive</button></div>
</Reveal>
<!-- grouped: sliding one closes whichever was open -->
<RevealGroup label="Products">
{products.map((product) => (
<Reveal name="products">
<article>{product.name}</article>
<div slot="bottom">{product.price} · in stock</div>
</Reveal>
))}
</RevealGroup>