shadcn.io is not affiliated with official shadcn/ui
Flight Status Board Table Block for Radix UI
An airport arrivals and departures board in a fixed window: Departures and Arrivals tabs, scheduled times struck through when the estimate moves, status words, and a star that pins a flight to a Tracked group.
Installation
Overview
Show what is leaving and landing, with this flight status board for React with Radix UI. A fixed-height window holds a slim top bar with the airport and the date, Tabs for Departures and Arrivals, and a native table of eight flights per board: the flight with its gate under it, the city, the scheduled time over the estimate, and a status word in an outline Badge whose dot is filled, half filled, hollow or struck through. When the estimate differs the scheduled time is crossed out and the delay is said in words ("25 min late"); a cancelled flight has no estimate. The star on each row is a Toggle: pressing it pins the flight to a Tracked group at the top and the table regroups, with the star keeping its focus and a status line naming what changed. The board scrolls inside the window, the heads stay put, and the window never changes height. It's built from Tabs, Toggle, Badge and Guides, with a CSS entrance only. For airports, stations, ferry terminals and any live board people want to follow one line of.
FAQ
How do I load my own flights?
Replace FLIGHTS. Each flight is a small typed record: the airline and its two-letter code with the number, the board it belongs to, the city, the scheduled and estimated time as HH:MM, the gate and a status. The delay is never typed: gapOf takes the difference between the two times and gapWords says it ("25 min late", "2 min early"), so the struck-through time, the words and the row can never disagree. A cancelled flight has an empty estimate and gate. The day is the DAY constant, so every time prints the same wherever the page is opened.
What does tracking do, and where is it kept?
Pressing a star adds the flight's id to one list in the component's state, and the table splits each board into a Tracked group and the rest. Tracked flights keep the board's time order, a reserved line says so when a board has none, and the star keeps keyboard focus after the row moves to its new group. Nothing is saved: a reload starts with the sample flight tracked again. To keep it, write the list to your own store in the track handler, or to a cookie or local storage, and read it back into the initial state.
What stays local in the demo, and how do I make it live?
Everything: the flights are typed, the day is fixed and no airline, airport or tracking service is called. To go live, fetch the board for the selected tab, map each record onto the Flight shape and set it as the rows; keep gapOf as it is and the delays will follow the new estimates. A board that refreshes should update the same rows rather than rebuild the table, so a pinned flight does not jump.
How is status shown without colour?
Every status is a word first (On time, Boarding, Delayed, Cancelled, Landed) and then a dot that differs in shape: filled, half filled, hollow, or struck through. The delay is written out beside it, and the changed time is the only one in full strength. Nothing uses green, amber or red, so the board reads in a grey theme, in dark mode and for people who cannot tell those colours apart. The same dot recipe is used by the other tables blocks, so a status looks the same across a stack.
Is the board accessible?
Yes. It is a native table with a caption, th scope="col" heads, a row header for each flight and a colgroup heading for each group. Each star is a real button named "Track flight NV 204" that exposes its pressed state, so it is announced as pressed or not. Struck-through times are read as "Scheduled 09:55" and "Estimated 10:20", the tabs follow the usual arrow-key pattern, and the polite status line, present from the start, reports every tab change and every pin. Tab visits the stars and the tab list; nothing else on the board is a tab stop.
How does it look on a phone?
All four columns stay. The airline name drops out of the flight's second line and leaves the gate, the time is two short lines, and the status keeps its badge and its delay words. The window is a little taller than on a desktop, and the table scrolls inside it with the heads fixed, so the page never grows as a flight is tracked or a tab is changed.