shadcn.io is not affiliated with official shadcn/ui
Dialog Wizard Stepper Block for Radix UI
A shared-drives page with a four-step dialog wizard shown open: a drive name checked against the existing ones, teammates to tick, an access level and a read-back, ending on a new row in the list behind it.
Installation
Overview
Put a short wizard inside a dialog, with this stepper for React with Radix UI. It opens from the Shared drives page of Cubbyfile, a team file tool: the header holds an outline New shared drive Button and the page itself, a search bar over a row for each drive, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The dialog holds a Steps line of four numbered circles (Name, Members, Access, Review) and one panel at a time: a name Input that refuses an empty name or one that already exists, five teammates to tick with Checkbox rows, a Radio Group of view, comment or edit, and a Data List read-back. Reached steps stay pressable and Back is free; the foot has Back and the block's one Shine Button, which reads Continue, then Create drive, then Done. Creating adds the drive to the list behind the dialog. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog with the same step and the same answers. For file tools, workspaces and any create flow that takes a few answers.
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 page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused. The header 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 WizardBody component and share the block's state, so a wizard begun in the copy carries on in the real one at the same step. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
How do I change the steps?
STAGES lists the four steps by id and title, and each one is a StepsContent with the next index inside WizardBody. The people to tick are in TEAM, the access levels in LEVELS, and the existing drives in DRIVES. A step's title is a line of text rather than a heading, because a dialog already has its own title; it takes focus after you move, so a screen reader hears where you are. To add a step, add it to STAGES, add its panel, and check it in submit before go moves on.
What stays local, and how do I make it real?
Everything. The drive, its members and its access level live in component state, and Create drive adds a row to the drawn list and says "Created in this demo": nothing is shared and no one is told. In your app send name, picked and access to your server from create, add the row from its response, and show its error in the name field if it refuses the name; the check against existing names is only a first line of defence.
How is the name checked?
When you leave the field and when you press Continue: an empty name asks for one, a name over 40 characters says so, and a name that matches an existing drive in any letter case says it already exists. The message sits under the field in a slot two lines high, so the dialog never grows, and focus goes back to the field when Continue is refused. Once a message shows, it follows your typing and clears as soon as the name is fine.
Is it accessible from the keyboard?
Yes. The step line is one tab stop on the current step: arrow keys move between the steps you can reach, and Enter or Space opens one. Enter in the name field presses Continue. The real dialog is named by its title and described by its sentence, and Escape, the close button and Done all return focus to New shared drive. The trigger is the button wrapped in DialogTrigger with asChild, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the header button.
How does it look on a phone?
The copy shown on load docks to the foot of the page as a bottom sheet, with the step line, the panel scrolling above and the actions pinned below, Continue on top. Only the numbers show on the step line, and each step's name is still read by screen readers. The real dialog keeps the Dialog's own phone layout, a sheet stuck to the bottom of the screen.