Dialog
A modal window on top of the page that asks for a decision or collects input. DialogTrigger opens it and DialogClose closes it.
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
TextField
} from 'alinea/components'
export function DialogExample() {
return (
<Dialog>
<DialogTrigger variant="outline">Rename entry</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Rename entry</DialogTitle>
<DialogDescription>
The URL of the entry stays the same.
</DialogDescription>
</DialogHeader>
<TextField label="Title" defaultValue="Summer collection" autoFocus />
<DialogFooter>
<DialogClose variant="ghost">Cancel</DialogClose>
<DialogClose color="primary">Save</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
)
}Confirm a destructive action
Use role="alertdialog" for a decision editors have to make. With dismissable={false} a click outside the dialog doesn't close it.
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger
} from 'alinea/components'
import {IcRoundDelete} from 'alinea/dashboard/icons'
export function DialogAlertExample() {
return (
<Dialog>
<DialogTrigger color="destructive" variant="outline" icon={IcRoundDelete}>
Delete
</DialogTrigger>
<DialogContent
role="alertdialog"
dismissable={false}
showCloseButton={false}
>
<DialogHeader>
<DialogTitle>Delete “Linen shirt”?</DialogTitle>
<DialogDescription>
The entry and its translations are removed. This can’t be undone.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose variant="ghost">Keep it</DialogClose>
<DialogClose color="destructive">Delete entry</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
)
}Controlled
Pass open and onOpenChange to open a dialog from anywhere, and close it once a change is saved. useDialog gives the content of a dialog its open state and a close function.
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
TextField
} from 'alinea/components'
import {useState} from 'react'
export function DialogFormExample() {
const [open, setOpen] = useState(false)
const [name, setName] = useState('Oak & Loom')
const [draft, setDraft] = useState(name)
return (
<>
<Button onClick={() => setOpen(true)}>Site name: {name}</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Site settings</DialogTitle>
</DialogHeader>
<TextField label="Site name" value={draft} onValueChange={setDraft} />
<DialogFooter>
<Button variant="ghost" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button
color="primary"
onClick={() => {
setName(draft)
setOpen(false)
}}
>
Save
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</>
)
}Props
<Dialog>
<DialogTrigger>
Accepts every prop of Button.
<DialogContent>
default fits its content up to a narrow width, lg is a fixed wide dialog and full fills the viewport (minus a margin), defaults to defaultAlso accepts className and style, id and aria-* labelling attributes and data-* attributes.
<DialogHeader>
Accepts every prop of a <div> element.
<DialogTitle>
Also accepts className and style.
<DialogDescription>
Accepts every prop of a <p> element.
<DialogFooter>
Accepts every prop of a <div> element.
<DialogClose>
Closes the surrounding Dialog or Popover when pressed
Accepts every prop of Button.
useDialog()
The open state of the surrounding Dialog or Popover, to close it from within its content
Accessibility
Focus moves into the dialog when it opens and returns to the trigger when it closes. Focus stays inside while it is open, Escape closes it and the page behind it is hidden from screen readers.