Suspense Reveal Queue
A reveal conductor wrapping several loading sections — whichever finishes first joins the queue, reveals follow the author's order with a minimum interval, and late sections catch up automatically.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
npx shadcn@latest add "https://webberui.com/r/suspense-reveal-queue.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<SuspenseRevealQueue />
Installation
npx shadcn@latest add "https://webberui.com/r/suspense-reveal-queue.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/suspense-reveal-queue.
Usage
SuspenseRevealQueue is the conductor, and you put several RevealSlot elements inside it. A slot does not pop in the moment it is ready — it joins the queue, and the conductor schedules every reveal centrally according to order and interval.
Controlled readiness (with your own loading state)
import {
RevealSlot,
SuspenseRevealQueue,
} from "@/components/ui/suspense-reveal-queue";
<SuspenseRevealQueue interval={200}>
<RevealSlot order={0} ready={!profile.loading} fallback={<ProfileSkeleton />}>
<Profile data={profile.data} />
</RevealSlot>
<RevealSlot order={1} ready={!chart.loading} fallback={<ChartSkeleton />}>
<Chart data={chart.data} />
</RevealSlot>
<RevealSlot order={2} ready={!feed.loading} fallback={<FeedSkeleton />}>
<Feed data={feed.data} />
</RevealSlot>
</SuspenseRevealQueue>Automatic mode (wrapping a Suspense boundary)
When ready is omitted, RevealSlot wraps its children in React.Suspense on its own and counts them as ready once they resolve and mount — you just drop the suspending component straight in:
<SuspenseRevealQueue interval={200}>
<RevealSlot order={0} fallback={<ProfileSkeleton />}>
<AsyncProfile />
</RevealSlot>
<RevealSlot order={1} fallback={<ChartSkeleton />}>
<AsyncChart />
</RevealSlot>
</SuspenseRevealQueue>Props
SuspenseRevealQueue
| Prop | Type | Default | Description |
|---|---|---|---|
interval | number | 200 | Minimum interval between two consecutive reveals (milliseconds) |
onRevealComplete | () => void | — | Fires once when every slot has been revealed |
aria-label | string | — | Accessible label applied to the queue container |
children | ReactNode | — | Several RevealSlot elements |
className | string | — | Appended to the container's class |
RevealSlot
| Prop | Type | Default | Description |
|---|---|---|---|
order | number | registration order | Reveal order (from 0; lower comes earlier); when omitted, numbering follows the DOM from top to bottom |
fallback | ReactNode | — | The loading skeleton, shown before the content is revealed and faded out during the reveal |
ready | boolean | — | Controlled readiness flag; when omitted it switches to automatic mode (with a built-in Suspense) |
children | ReactNode | — | The real content, shown once ready |
className | string | — | Appended to the slot container's class |
How it works
- Joining the queue: any section joins the queue as soon as it is ready (
readyflips totrue, or in automatic modeSuspenseresolves). - Revealing in order: the conductor reveals only one section at a time, with at least
intervalmilliseconds between two reveals; the candidate is whichever has the lowestorderamong the "not yet revealed and already ready" sections. - No idle waiting: if a section earlier in the order is not ready yet, the conductor does not stall — it reveals the later sections that are ready first.
- Automatic catch-up: an overtaken late section is added the moment it is ready, using a spring animation to signal "catching up", which distinguishes it from the smooth fade of a normal reveal.
Accessibility
- The container carries
role="group"and is markedaria-busyuntil everything has been revealed; you can add anaria-labelexplaining the purpose of the region. - Skeletons are marked
aria-hiddenso assistive technology never reads them. - Unrevealed content is isolated with
aria-hiddenandinert, so a section that is not yet shown cannot be read out or reached by keyboard focus. - When the user has "reduce motion" enabled at the system level, the paced choreography along with the displacement/blur are dropped and every ready section simply fades in.
Optimistic Mutation Frame
An optimistic update container that inserts a translucent ghost item immediately, solidifies it into a real one when the server confirms, and shakes it back out on failure while handing the error off to a toast.
Skeleton Orchestra
A skeleton-screen orchestration system: when loading finishes, the skeletons solidify into real content one by one in directional waves following the layout.