Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Waitlist Signup Dialog Block for React

A launch page with its waitlist dialog shown open: one email field, then in the same dialog your place in the queue as a large number over a strip of 40 dots with yours ringed, how long the wait is at the invite rate, and a link to share that really copies.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let someone join a waitlist and see where they stand, with this waitlist signup dialog for React with Base UI. It opens from the launch page of Haulbird, a pre-launch electric cargo bike: the page's header holds an outline Join the waitlist Button, and the page itself, a bike drawn from circles and lines, a headline bar and a Join button, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog starts with an email Field and one line of fine print, over a strip of 40 empty dots. Pressing the only Shine Button replaces the form, in the same space, with your place as a large number (number 1,284 of 4,000), the strip with the dots ahead of you filled and yours ringed, what the invite rate means for your turn, and your link in a read-only Input with a Copy button. The header button then reads You're on the list. For preview the dialog is drawn open in place when the page loads; the header button opens the real dialog, with the same state. For product launches, beta lists, drops and any app that queues people.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the launch page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Join the waitlist button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same WaitFields component and share the block's state, so an address typed in the copy is there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

Where does the queue position come from?

It is typed in the file: number 1,284 of 4,000, the same for every address, and nothing in it is worked out from your clock or from what you type. The strip is drawn from those numbers: 40 dots of about a hundred people, so the first 12 are filled, the 13th, which holds places 1,201 to 1,300, is ringed, and the rest are empty. The turn line divides the position by the invite rate (about 250 a week) and rounds up, so it reads about 6 weeks. In your app return the real position and the real rate from your API when the address is added.

Why does the dialog not change height when it swaps?

The form and the result sit in one grid cell, and the one you are not looking at is inert and invisible, so the dialog is always as tall as the taller of the two. The form keeps its strip of empty dots at the foot so the space is used, and when you join, focus moves to your place so a screen reader reads it at once.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus starts on the email field, and Escape, Cancel, Done and the close button return focus to the header button. A wrong address is checked when you leave the field and again on Join, named in words under the field and focused. The queue strip is a single image with a sentence, not 40 stops, the polite status line says your place and your turn once, and the header button keeps its place in the tab order after you join: pressing it says where you stand. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange.

Does Copy really copy?

Yes. The browser's clipboard is real, so pressing Copy puts your link on it, the button reads Copied for three seconds and the status line says so. If the browser refuses, an alert in the same place asks you to select the link and copy it by hand. The link is typed in the file and points nowhere.

What stays local, and how do I wire it for real?

Everything but the clipboard. Nobody is added to anything and no email is sent: joining only changes this block's state and the drawn page. In your app send the address to your server on submit, answer with the position and a personal link, send a confirmation email, and make the link credit the friend who shared it.

  • Pro

    A meal-kit box page with its referral sheet shown open from the end edge: a code and a link that really copy, a friend's email and the message that would go with it, a reward ladder marked Reached or how many friends to go, and three figures.

  • Pro

    A waitlist for full classes: three session cells with the queue drawn as dots, your place shown when you tick one, and a form that confirms your place in place.

  • Pro

    Share Link Dialog

    Share and invite

    A prototype file with a share dialog shown open: a switch for anyone with the link, a read-only link whose role and expiry show in its suffix, a Copy link button that really copies, and a viewer preview that turns the file behind the dialog read-only.

  • Pro

    Invite Members Dialog

    Share and invite

    A household calendar's Members page with its invite dialog shown open: one email field that knows the household's domain, so an outside address joins as a guest, the people who already have access, and a Send invite button that adds a pending row.

  • Pro

    Referral Rewards Pricing

    Discounts and offers

    Referral pricing as a copyable invite link over a three-step reward track: friends invited and joined (2 of 3), the free months each step pays (1 month, 3 months, a year) and what's already earned.

  • Pro

    Two-Step Setup Dialog

    Account and security

    A cloud editor's security page with a three-step dialog shown open: a QR code and its key, eight backup codes to copy or download, and a six-digit check, ending in a note that two-step sign-in is on.