shadcn.io is not affiliated with official shadcn/ui
Horizontal Stepper Timeline Block for React Aria
A signing record of five stages joined by connectors that carry the time between stages, with a ring and a derived wait on the stage that is waiting, a button per stage that opens its audit lines, and a Send a reminder button that adds a dated line and sends nothing.
Installation
Overview
Show where an agreement is stuck, and for how long, with this horizontal stepper timeline for React with React Aria. It is written for Signtrail, a fictional agreement signing service. A hairline frame with a plus mark on each corner holds five circles, Sent, Viewed, Signed by Jorunn, Signed by Haakon and Completed, joined by connectors. Each connector carries the time between the two stages, such as +2 h 10 min and +2 d 22 h, worked out from the typed times. Done stages are filled with a check, the stage that is waiting has a ring and says "Waiting on Haakon for 2 days", counted from 14 Oct, and the last one is dashed. Each stage is a button that opens its audit lines under the rail: what happened, the time in UTC, a masked address and the device. "Send a reminder" adds one dated line to the waiting stage and says that nothing was sent. On a phone the rail is vertical, at the start. It is built from Button and Guides, with an entrance only. For signing, approvals, order tracking and any record of stages with waiting between them. The agreement is example data.
FAQ
How do I change the stages and the audit lines?
Edit STAGES. Each has an id, a label, a phase of done, waiting or pending, an ISO at once reached and a list of audit lines. The times on the connectors, the wait on the waiting stage and the count in the footer are derived from those times and from AS_OF.
What does Send a reminder do?
It appends one line, "Reminder noted in this demo", to the waiting stage, opens that stage and says in the polite status line that nothing was sent. A second press says it is already noted. Real reminders belong on your back end, behind an action that checks who may send one.
Why are addresses masked?
An audit view should not expose a full address to everyone who can see the record. The example uses reserved documentation addresses with the last part hidden; mask yours on the server, never in the page.
What stays in the page, and how do I wire a real record?
The chosen stage and the reminder line are local state; nothing is signed, sent or saved. For a real record, load the stages and audit events from your signing provider and keep the times in UTC.
Is it accessible, and does it work in a right-to-left page?
Each stage is a native button named with its label and state and marked with aria-pressed, the circles are decoration beside the words, and a polite status line says what was chosen or noted. The horizontal rail does not mirror in Arabic or Hebrew, while the vertical rail on a phone follows the page direction.