WebberUI

Queue Waitlist Section

A gamified waitlist section — submit an email and a 3D card flip reveals your queue number and the crowd ahead of you; copy the referral link and you move up the line with a queue-jump animation.

Loading preview…
npx shadcn@latest add https://webberui.com/r/queue-waitlist-section.json

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

1284
12480
128
1
<QueueWaitlistSection />

Installation

npx shadcn@latest add https://webberui.com/r/queue-waitlist-section.json

Or, once registries are configured in components.json, install it as @webberui/queue-waitlist-section.

Usage

import { QueueWaitlistSection } from "@/components/ui/queue-waitlist-section";

<QueueWaitlistSection
  title="Get early access — join the waitlist"
  initialPosition={1284}
  totalWaiting={12480}
  referralUrl="webber.ui/r/AH29X"
  referralBoost={128}
  onSubmit={(email) => console.log(email)}
  onReferral={(position) => console.log("new position", position)}
/>

Controlled mode

submitted and onSubmittedChange let you control from the outside whether the card has flipped to its back, which fits nicely with a real API response:

const [submitted, setSubmitted] = React.useState(false);

<QueueWaitlistSection
  submitted={submitted}
  onSubmittedChange={setSubmitted}
  onSubmit={async (email) => {
    await joinWaitlist(email);
    setSubmitted(true);
  }}
/>

Props

PropTypeDefaultDescription
titleReact.ReactNode"Get early access — join the waitlist"Section title
descriptionReact.ReactNodeSection description
eyebrowReact.ReactNode"Early access"Badge text above the title
placeholderstring"you@example.com"Placeholder for the email input
submitLabelstring"Join the waitlist"Text on the submit button
initialPositionnumber1284Your initial queue position after joining
totalWaitingnumber12480Total number of people waiting, shown below the form
referralUrlstring"webber.ui/r/AH29X"Contents of the referral link, copied to the clipboard
referralBoostnumber128How many places you move up each time the referral link is copied
minPositionnumber1Frontmost position reachable by jumping the queue (lower bound)
submittedbooleanControlled: whether it has been submitted (showing the back face)
onSubmittedChange(submitted: boolean) => voidCallback for submission state changes (fires in both controlled and uncontrolled modes)
onSubmit(email: string) => voidFires when a valid email is submitted
onReferral(position: number) => voidFires after a successful queue jump, returning the new position
classNamestringAppended to the outer section's className

How it works

  • 3D card flip: after submitting, the outer card rotates on rotateY and swaps the front and back content right at the 90° edge, so the card's height can change naturally with its content and you never see the content jump during the flip.
  • Count animation: the queue number counts from 0 up to your position through a MotionValue; on a queue jump it counts back down, updating frame by frame without triggering a React re-render.
  • Queue-jump animation: the crowd ahead is drawn as a row of avatars, with a gradient at the left edge hinting that many more people are still in front. After copying the link, your avatar reorders forward through Motion layout and the avatars you overtake naturally make way.
  • Both modes: submitted supports controlled and uncontrolled modes; when omitted, the component manages the flip state internally.
  • All timers (copy feedback, queue-jump badge) are cleared on unmount.

Accessibility

  • The form's email field carries a visually hidden <label>; on validation failure it warns through role="alert" and sets aria-invalid and aria-describedby.
  • The back face contains an aria-live="polite" screen reader region that always announces "you are currently at position N, with M people ahead", while the count animation itself is hidden from assistive technology.
  • The submit and copy buttons both have aria-labels and focus-visible outline styles.
  • When the user has "reduce motion" enabled at the system level, the 3D flip and the count / queue-jump animations do not run; the matching face is shown directly based on state and the numbers land instantly.

On this page