shadcn.io is not affiliated with official shadcn/ui
Status Page Command Menu Block for React
A status page host's command menu shown open over a public status page: four components each with its own state select, a banner and 30 uptime squares that follow the worst state, and Post an incident from what you type.
Installation
Overview
Update a component and post an incident from the keyboard with this status page command menu for React with Base UI. It opens from a public status page in Openwell, a status page host, whose header holds an outline field with its ⌘ K cap, and the page is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The menu is the catalog Command: API, Dashboard, Webhooks and Search, each row with its own select for Operational, Degraded, Outage or Maintenance. Enter on a row moves focus to its select, and the page behind the menu follows: its banner derives the worst state, such as Partial outage, and the last of its 30 drawn uptime squares marks today. The last row, Post an incident, takes what you typed as the title and adds an incident card to the page. Phones put each select full width under its name. For the preview the menu is drawn open in place when the page loads; the field, or Ctrl or ⌘ K while focus is in the block, opens the real command dialog with the same states. For status pages, admin consoles and any list of things with a state.
FAQ
Why is the menu already open, and what do I keep?
So you can see it without a click. On load the menu is the Command drawn inline over a picture of a public status page, in a plain shell that is not modal, so nothing is trapped, hidden or focused and the page around the preview keeps working. The header's field opens the real command dialog, modal, with its focus trap, Escape and focus return, and the inline copy stays closed until a reload. Both show the same Palette and share the block's state, so a component's state in the copy is still there in the dialog. In your app keep the dialog and drop the copy: the "in-place" state, the scrim with its shell and the Escape and blur effects.
How is the banner worked out?
bannerOf reads the four states and returns the worst: all four in Outage is a Major outage, any Outage is a Partial outage, then Degraded performance, then Scheduled maintenance, and otherwise All systems operational. Today's square among the 30 follows the same order, drawn as a pale, outlined, mid or solid square, with a ring so it can be found without colour. The earlier 29 days are typed data.
How do the selects work inside the list?
Each row holds a native select that is out of the tab order, so the list keeps its one tab stop. Enter on a row focuses its select; the arrow keys then change the value and stay with the select, which stops its keys and presses from reaching the list, and Enter or a choice hands focus back to the field. A click on a select opens it without choosing the row. Escape still closes the menu.
How does Post an incident take its title?
The field is the title. With it empty the last row says to type one first; with text it reads Post an incident followed by your words, and Enter adds an Investigating card with a fixed time to the page, clears the field and says so on the status line. The components list also filters by what you type, so a long title may show none of them, and the incident row is always there.
What stays local, and how do I wire it?
All of it. The states and the incident cards are state in the block and nothing is published; the status line says so. In your app write the new state from setState and the incident from pick to your status API, and read START and the incidents from it.
Is it accessible from the keyboard?
Type to filter, the arrow keys move through the rows, Enter on a component moves focus to its select, the select's arrow keys change the state and Enter returns to the field, and Escape closes the menu with focus back on the header's field; Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. The rows are options of a cmdk listbox; the block turns off its own fuzzy filter and lists the rows itself.