ChoiceDialog
A dialog that offers a few ways to go: each a row with an icon, a title, a line and an arrow, choosing one closes it.
import { ChoiceDialog } from "@butteryui/react";Demo
When to use it
Use it for
- Starting something that comes in a few kinds, such as a retail or a wholesale order
- Picking a report or a template before going to its page
Not for
- Two buttons: use a Dialog with Dialog.Actions
- Picking a value in a form: use Select or SegmentedControl
- More than six or so choices: use a page, such as SettingsIndex
Examples
New from header
Opened from a page header's action, with open and onOpenChange kept in useState.
Orders
No order started yet
New order
A New order button that asks which kind of order before going to its form.
Report picker
A reports page whose choices stay on it: picking a report runs it in its section rather than following a link.
Reports
This month
No report run yet
Variants and states
Three kinds of order
Open it and point at a row: its arrow draws its stem.
Props
ChoiceDialog
| Prop | Type | Default | Description |
|---|---|---|---|
ref | Ref<HTMLDivElement> | The dialog's content box. | |
trigger | ReactElement | The button that opens it. | |
open | boolean | Whether it's open, when you control it. | |
defaultOpen | boolean | false | Whether it starts open. Defaults to false. |
onOpenChange | ((open: boolean) => void) | Called when it opens or closes. | |
titlerequired | string | The question, which names the dialog. | |
description | ReactNode | A line under the title, which describes it. | |
choicesrequired | readonly DialogChoice[] | The ways to go, 8px apart. | |
closeLabel | string | "Close" | Names the close button. Defaults to "Close". |
className | string | Classes for the content inside the dialog, the element that carries data-bt="ChoiceDialog". | |
style | CSSProperties | Inline styles for the same element. |
DialogChoice
One way to go in a `ChoiceDialog`.
| Field | Type | Default | Description |
|---|---|---|---|
idrequired | string | Identifies the choice among the others. | |
iconrequired | ComponentType<IconComponentProps> | A 20px icon in its tile. | |
titlerequired | string | What it is, such as "Wholesale order". | |
description | string | A line on what it's for. | |
href | string | Makes it a link to this page. | |
onSelect | ((event: MouseEvent<HTMLElement>) => void) | Runs when it's chosen, before the dialog closes, or as its link is followed. |
Accessibility
A modal dialog named by its title and described by its line. Focus starts on the first choice; each is a link or a button named by its title and line, and choosing one closes the dialog. Escape, the close button or a press outside closes it too, and focus goes back to what opened it.
| Keys | What they do |
|---|---|
| Tab or Shift+Tab | Moves between the choices and the close button, staying inside the dialog |
| Enter | Follows or runs the focused choice and closes the dialog |
| Space | Runs the focused choice when it's a button, not a link, and closes the dialog |
| Escape | Closes it and puts focus back on what opened it |
Motion
It appears with a `Presence` preset and leaves faster than it came, in about 60% of the time.
With reduced motion: It and its scrim fade in and out in 100ms without growing or rising, and a row's arrow draws its stem at once, without the nudge.
Layout
It's 560px wide at most (--bt-w-dialog-md) and 16px inside the window, scrolling inside when it's taller. Each choice is a full-width row padded 16, 8 apart: a 36px icon tile, its title over a line that wraps, and an arrow at the end, the whole row its hit area.
Related
See it in the roastery demo.