Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Multi-Step Form Sheet for React

A Start Setup button opens Account Setup on step 1 of 3, with first name, last name, phone, Back, and Next.

The title is Account Setup. The description reads Step 1 of 3: Personal Information. First Name, Last Name, and Phone Number are empty. Back and Next fill the footer.

Use it for a setup that is too long for one view. These buttons do not change the step, so track it yourself, and show the sequence with Steps. In React, Base UI does not keep the answers.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Sheet anatomy: content, close, title, description, footer

Usage

<Sheet>
  <SheetTrigger render={<Button />}>Start Setup</SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Account Setup</SheetTitle>
      <SheetDescription>Step 1 of 3: Personal Information</SheetDescription>
    </SheetHeader>
    <FieldGroup className="gap-4 p-4">
      <Field>
        <FieldLabel htmlFor="setup-first-name">First Name</FieldLabel>
        <Input
          id="setup-first-name"
          placeholder="Enter first name"
          type="text"
        />
      </Field>
      <Field>
        <FieldLabel htmlFor="setup-last-name">Last Name</FieldLabel>
        <Input
          id="setup-last-name"
          placeholder="Enter last name"
          type="text"
        />
      </Field>
      <Field>
        <FieldLabel htmlFor="setup-phone">Phone Number</FieldLabel>
        <Input id="setup-phone" placeholder="Enter phone number" type="tel" />
      </Field>
    </FieldGroup>
    <SheetFooter>
      <Button className="w-full" variant="outline">
{/* The rest of the file is under Installation. */}

FAQ

How does the sheet show the current step?

In SheetDescription, which reads Step 1 of 3: Personal Information. Change that text with the step so screen readers hear it when the sheet opens.

What does step 1 collect?

First Name, Last Name and Phone Number. The phone input uses type="tel", so phones show the number pad.

Do Back and Next change the step?

Not in this demo: both are plain Buttons. Keep the step number in state, render that step's fields, and disable Back on the first step.

Where do the answers go between steps?

Keep them in one object in state, or in a form library, outside the step's fields. Otherwise unmounting a step loses what was typed.

How does Start Setup open the sheet?

The button labeled Start Setup is the trigger, and its text is the accessible name. The Button goes in the render prop of SheetTrigger, and the label stays its child.

What does the setup sheet announce?

SheetTitle names the dialog for assistive tech, so every sheet renders one; hide it with sr-only when the design has no visible heading. It reads Account Setup, and the description gives the step.

API Reference

Sheet

No extra props in this demo. The rest is on the Sheet page.

Button

Sets variant="outline". The rest is on the Button page.

Field

Sets htmlFor="setup-first-name", htmlFor="setup-last-name" and htmlFor="setup-phone". The rest is on the Field page.

Input

Sets id="setup-first-name", placeholder="Enter first name", type="text", id="setup-last-name", placeholder="Enter last name" and id="setup-phone". The rest is on the Input page.