shadcn.io is not affiliated with official shadcn/ui
Order Status History Table Block for Radix UI
A shop's orders with a five-stage cell of joined dots, a timestamp tooltip on each stage reached and an Advance button that moves an order one stage on, with Cancelled orders shown as a word.
Installation
Overview
Show where each order is and let staff move it on, with this status history table for React with Radix UI. A compact header names the table, and a native table lists seven orders from Parcelwink, a parcel shop: the order number, the customer, the item, the stages and the status. The stage cell is five dots joined by a rule, Placed, Confirmed, Packed, Shipped and Delivered. A stage reached is filled, the current one is filled and ringed, and a stage ahead is hollow with a faint rule, so progress reads by shape and weight and not by colour. Each reached dot is a button with a Tooltip giving the time it was reached. An Advance Button on each row moves the order one stage on, writes the next typed time into the cell and updates the status Badge; a delivered order keeps the button but it is inert, and a cancelled order shows the word "Cancelled" instead of dots. A polite line says what changed. On a phone the customer goes and Advance sits under the stages. It's built from Tooltip, Button, Badge, Guides and a native table, with a CSS entrance only. For order tracking, ticket progress, approvals and any list of things that move through fixed stages.
FAQ
How do I change the stages and the orders?
Edit STAGES, which is the list of stage names in order, and ORDERS: each order has the stage it is at and a times list with one ISO time per stage. Dots, rules, tooltips, the status word and the Advance label are all drawn from those two lists, so adding a stage to STAGES and a time to each order is enough. Times are in UTC and written by stampOf, so they read the same on the server and in the browser.
What stays local, and how do I make Advance real?
The progress lives in one useState and Advance only changes it; nothing is sent, so the status line says "in this demo". For real use, make the click handler call your API, update the order with what it returns (including the real timestamp) and keep the rest as it is. Keep the button available while the request runs and report a failure in the status line.
Is a row of dots accessible?
Yes. The dots are an ordered list named for the order, each reached dot is a button named "Packed, 9 Oct, 08:20 UTC" that shows its tooltip on focus as well as on hover, and each stage ahead has hidden text saying it hasn't been reached. The status word is real text, so nothing depends on colour. Advance is named by its order and the stage it goes to ("Advance PW-1051 to Shipped"); on a delivered order it stays focusable with aria-disabled so focus isn't lost when the last stage is reached.
What happens to a cancelled order?
It shows the word "Cancelled" where the dots would be and in the status badge, and its Advance button is inert and says why in its name. A cancelled order can't be moved on, which keeps a stage list that means one thing. To make cancellation a real action, add a row action that sets a cancelled flag and keep the history of the stages it reached.
How does it look on a phone?
Below the medium breakpoint the Customer and Status columns go: the status moves under the item name and the Advance button sits under the dots, so the table keeps Order, Item and Stages without scrolling sideways. Every row is the same height, so pressing Advance doesn't move the rows.