PathLogs UI
Русский

Components

Dialog

A modal window with a focus trap and scroll lock.

A modal window: portalled into body, with a scrim, a focus trap, Escape and a scroll lock on the page beneath it.

Example

The state lives outside. That way one and the same window serves both creating and editing without growing an internal mode of its own.

Props

open*boolean

Whether the window is shown.

onClose*() => void

Called on Escape, a click on the scrim, and the close button.

titlestring

The visible heading of the window.

headerReactNode

A custom heading instead of the title string — with an icon and a counter, say.

labelstring

The accessible name when there is no visible heading: the window draws its own, but a screen reader still needs a name.

footerReactNode

The action bar at the bottom.

size"sm" | "md" | "lg" | "xl"

defaults to: "md"

Maximum width: 24 / 32 / 42 / 56 rem.

align"center" | "top"

defaults to: "center"

Pin the window to the top — this is how the command palette sits.

busyboolean

defaults to: false

Saving in progress: closing is blocked so the result is not lost.

dismissOnBackdropboolean

defaults to: true

Close on a click on the scrim.

dismissOnEscapeboolean

defaults to: true

Close on Escape.

Focus and keyboard

  • On opening, focus moves to the first interactive element, or to the panel itself if there is none. Without this the keyboard would be left on the page beneath the scrim.
  • Tab from the last element wraps back to the first: focus never leaves the window.
  • On closing, focus returns to wherever the window was opened from — otherwise after Escape the keyboard would end up at the top of the page.
  • Page scrolling beneath the window is locked: otherwise the wheel over the scrim scrolls the content away, and on closing the user is no longer where they were.

A window without a heading

If the window draws its own heading (a confirmation, a palette), pass label instead of title: no header bar appears, but the accessible name remains.

tsx
<Dialog open={open} onClose={close} label="Delete project?" size="sm">
  {/* your own markup with an icon and a heading */}
</Dialog>