Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form Wizard Skeleton Block for React Aria

A four-step grant application where each Next loads the following step: a real steps strip over three bars that become that step's fields, with Back and Submit.

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

Show a multi-step form that loads one step at a time, with this form wizard skeleton for React with React Aria. A hairline frame with a plus mark on each corner holds a Steps strip (Organisation, Project, Budget, Review), the current step's three fields and a foot with Back and Next, from Mullein, a grant-management portal. The strip, the step's title and the labels are real from the first paint; the three values are Skeleton bars that become Input and Native Select controls in the same box when you press Load. Next is the one primary and a reload source: it moves to the next step and loads that step's fields, Back goes back the same way, and a press on a finished step in the strip does too. The last step is read-only, its primary reads Submit, and a polite line says nothing was submitted. The rules are drawn by Guides and the load control is an outline Button. On a phone the strip shows the current step and "Step 2 of 4". For applications, onboarding and any form split across steps.

FAQ

What stays local, and how do I wire it to a real query?

Nothing is fetched or saved. The four steps are typed in STAGES, Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real form when the data arrives. Save is a local line: replace the submit handler with your mutation. Submit says nothing was submitted; wire it to your mutation.

Why is every step three fields?

So the panel is the same height on every step. Steps that differ in height make a wizard jump when you move between them; here every step has three fields of one height, and the bars are drawn at that height. If your steps differ, give the panel the height of the tallest one.

Does the form keep its height while it loads?

Each bar and its control sit in one grid cell, so the larger of the two sets the cell's box and the swap changes nothing around it. The labels, the helper lines, the heading and the buttons are real in both phases, every bar has the height of the control it stands in for, and the polite line reserves two lines, so the panel is exactly as tall before, during and after loading at every width.

Is it accessible?

The region is marked busy while it loads and carries a screen-reader-only "Loading step…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so a field is neither read nor focusable until its data is in. Every control has a real label, and Save is aria-disabled rather than removed while it waits. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant. The steps strip is a labelled list; a step you haven't reached is disabled, and the current one is marked.

Are my edits kept between steps?

No: in this demo each step shows its typed sample values again when it loads, and the review step reads from the same data. In your app keep the answers in one state object, render them as the fields' values and send them all on Submit.