shadcn.io is not affiliated with official shadcn/ui
Order Tracking Timeline Block for React
A parcel's five milestones on a vertical rail with the expected delivery window worked out from today, and a switch that opens the eleven carrier scans between the milestones in place without changing the panel's height.
Installation
Overview
Tell a customer where a parcel is, and let them look closer only when they want to, with this order tracking timeline for React with Base UI. It is written for Parcelwise, a fictional delivery tracker. A hairline frame with a plus mark on each corner holds five milestones, Ordered, Packed, Handed to the carrier, Out for delivery and Delivered, as large circles on a vertical rail. The line is solid up to the milestone the parcel has reached and dashed after it, the circle that was reached last has a ring, and the two still to come say when they are expected, worked out from 14 Oct as Thu 15 Oct, 10:00 to 14:00. A "Show every scan" switch opens the eleven carrier scans, such as "Arrived at Depot 4" or "Sorted for the north line", between the milestones in place, each with its time, and the panel keeps its height whichever way the switch is set. It is built from Switch and Guides, with an entrance only. For shop order pages, delivery emails, field service visits and any record with a few milestones and many small events. The parcel is example data.
FAQ
How do I change the milestones and the scans?
Edit MILESTONES. Each has an id, a label, an ISO at once it has been reached and a list of scans, each with its own ISO time and a line of text. The ring, the solid and dashed lines and the "Expected" lines are worked out from which milestones have a time and from AS_OF.
Why does the panel not jump when I open the scans?
The rail is drawn twice in one grid cell: the live one, and the longest version, with every scan open, unseen and inert behind it. The cell takes the taller one's height, so the footer never moves.
How is the expected delivery worked out?
It is the day after the fixed "now" with the courier's window written beside it. In your own page, take the expected window from the carrier's tracking response and keep the times in UTC until you show them.
What stays in the page, and how do I wire a real parcel?
Only the switch is local. Nothing is fetched and nothing is saved. For a real parcel, load the milestones and scans from your carrier or your order system and map each carrier code to a milestone on the server.
Is it accessible, and does it work in a right-to-left page?
The milestones are an ordered list, the circles are decoration beside the words, and the switch has a visible name and is announced with its state. A polite status line says whether the five milestones or all the scans are showing. The rail sits at the start of the row, so it mirrors in Arabic and Hebrew, while the times stay left to right.