Axon 911 Frontend DocsAxon 911 Frontend Docs
Axon 911 Frontend Docs
    Loading navigation…
U
User
Switch to light mode
  1. Blocks
  2. Detail Drawer
  3. Usage

Detail Drawer

Usage

Import @prepared911/ui/blocks/detail-drawer and its styles.css, plus the styles.css of each component the block composes (Drawer, AlertDialog, LoadingBoundary, ErrorBoundary, Skeleton, Box, Text, and the Button, Menu, and Checkbox you put in its slots). DetailDrawer is the record detail drawer: Drawer's header, scrolling body, and footer for one record at a time. There is one drawer. The page owns which record it shows, and changing the record swaps the content in place.
State is the page's
open and recordId are controlled. onOpenChange(open, details) reports a request to open or close: the trigger, the close control, Escape, or a press outside. details.cancel() vetoes a cancelable one. onRecordChange(id, details) reports the record the person chose in the record strip. Apply them to your state; the drawer shows what you ask for.
Header, body, footer
  • Header. title is the record's title and subtitle the line under it. Both may be data (DisplayValue). label names the drawer itself, such as "Incident details". actions takes Buttons, a ButtonGroup, or a Menu trigger; they sit between the title and the close control.
  • Body. children scroll under the header. Compose DetailDrawerSection for a titled section, with a hairline between sections. The body brings its own content padding: a section pads itself, a bare child does not.
  • Footer. footer takes Buttons at the inline end, primary last, and footerText adds a hint at the inline start. The footer stays in view while the body scrolls.
Related records
Pass records ({ id, label }) and recordsLabel to show a segmented strip under the header. The selected segment is the record on screen. Pressing a segment, or an arrow key on it, reports onRecordChange. Keep the set small, a handful of related records: every record is a segment. A long list of records belongs in the page's table.
Loading and errors
loading shows skeletons for the title and the body, named by loadingLabel. The drawer is not disabled while it loads: the person can still close it or move to another record. Give title a placeholder while loading so the heading keeps its name. The body sits in a LoadingBoundary, so a body that suspends shows its skeleton. A body that throws shows the ErrorBoundary recovery you describe in error (title, description, retryLabel, or a custom fallback), and another record id resets it. Omit error and the error reaches your own boundary.
Unsaved changes
Pass guard to ask before the drawer drops edits. While guard.dirty is true:
  • A dismiss (close control, Escape, outside press) or a swap to another record opens a confirm dialog and leaves the record on screen. A swap you make by changing recordId, such as a row press, is guarded the same way.
  • Discard shows what was asked for and calls guard.onDiscard. Reset your form there so dirty turns false.
  • Keep editing, or Escape on the dialog, leaves the record on screen and asks you to restore your request: onOpenChange(true, details) when you asked to close, onRecordChange(shownId, details) when you asked for another record. Both carry reason: "imperative-action" and are not cancelable. Apply them like any other change.
Opening and focus
The drawer is non-modal: the page stays interactive, Escape closes it through onOpenChange, and an outside press closes it with light-dismiss unless you cancel it. Focus moves into the drawer when it opens. When it closes, focus returns to its trigger if there is one, and otherwise to the element that was focused before it opened, such as the table row. The trigger slot takes one Button; use it when a single control opens the drawer. A drawer opened from a row needs none. A drawer mounted in a detached window's React tree opens its dialog and its confirm dialog in that window.
What it does not do
  • It does not fetch. The page supplies the record, its form state, and every handler.
  • It has no edge, size, modal, or resizable props. It renders Drawer's defaults. See the contract.
  • It does not stack. To show a second record, change recordId.
Previous
Dashboard Layout / Accessibility
Next
Detail Drawer / API and Development
On this page
State is the page's
Header, body, footer
Related records
Loading and errors
Unsaved changes
Opening and focus
What it does not do