Dialog
A modal dialog that displays content in a layer above the page. Supports ESC key, overlay click, focus trap, and scroll lock.
Dialog Title
This is a basic dialog example. Press ESC or click outside to close.
Dialog content goes here. You can add any content you need.
1<DialogContent open={open()} onClose={() => setOpen(false)}>...</DialogContent>#Installation
1bunx barefoot add dialog#Usage
1import { createSignal } from '@barefootjs/dom'2import {3 DialogTrigger,4 DialogOverlay,5 DialogContent,6 DialogHeader,7 DialogTitle,8 DialogDescription,9 DialogFooter,10 DialogClose,11} from '@/components/ui/dialog'1213export default function Page() {14 const [open, setOpen] = createSignal(false)1516 return (17 <div>18 <DialogTrigger onClick={() => setOpen(true)}>19 Open Dialog20 </DialogTrigger>21 <DialogOverlay open={open()} onClick={() => setOpen(false)} />22 <DialogContent23 open={open()}24 onClose={() => setOpen(false)}25 ariaLabelledby="dialog-title"26 ariaDescribedby="dialog-description"27 >28 <DialogHeader>29 <DialogTitle id="dialog-title">Dialog Title</DialogTitle>30 <DialogDescription id="dialog-description">31 Dialog description here.32 </DialogDescription>33 </DialogHeader>34 <p>Dialog content goes here.</p>35 <DialogFooter>36 <DialogClose onClick={() => setOpen(false)}>Close</DialogClose>37 </DialogFooter>38 </DialogContent>39 </div>40 )41}#Features
- ESC key to close - Press Escape to close the dialog
- Click outside to close - Click the overlay to close
- Scroll lock - Body scroll is disabled when dialog is open
- Focus trap - Tab/Shift+Tab cycles within the dialog
- Accessibility - role="dialog", aria-modal="true", aria-labelledby, aria-describedby
- Portal rendering - Dialog is mounted to document.body via createPortal
#Examples
#Basic Dialog
Dialog Title
This is a basic dialog example. Press ESC or click outside to close.
Dialog content goes here. You can add any content you need.
1const [open, setOpen] = createSignal(false)23<DialogTrigger onClick={() => setOpen(true)}>4 Open Dialog5</DialogTrigger>6<DialogOverlay open={open()} onClick={() => setOpen(false)} />7<DialogContent8 open={open()}9 onClose={() => setOpen(false)}10 ariaLabelledby="dialog-title"11 ariaDescribedby="dialog-description"12>13 <DialogHeader>14 <DialogTitle id="dialog-title">Dialog Title</DialogTitle>15 <DialogDescription id="dialog-description">16 This is a basic dialog example.17 </DialogDescription>18 </DialogHeader>19 <p>Dialog content goes here.</p>20 <DialogFooter>21 <DialogClose onClick={() => setOpen(false)}>Close</DialogClose>22 </DialogFooter>23</DialogContent>#Dialog with Form
Edit Profile
Make changes to your profile here. Click save when you're done.
1const [open, setOpen] = createSignal(false)23<DialogTrigger onClick={() => setOpen(true)}>4 Edit Profile5</DialogTrigger>6<DialogOverlay open={open()} onClick={() => setOpen(false)} />7<DialogContent8 open={open()}9 onClose={() => setOpen(false)}10 ariaLabelledby="form-dialog-title"11>12 <DialogHeader>13 <DialogTitle id="form-dialog-title">Edit Profile</DialogTitle>14 <DialogDescription>15 Make changes to your profile here.16 </DialogDescription>17 </DialogHeader>18 <div class="grid gap-4 py-4">19 <div class="grid grid-cols-4 items-center gap-4">20 <label for="name" class="text-right text-sm font-medium">21 Name22 </label>23 <input id="name" type="text" class="col-span-3 ..." />24 </div>25 </div>26 <DialogFooter>27 <DialogClose onClick={() => setOpen(false)}>Cancel</DialogClose>28 <button onClick={() => setOpen(false)}>Save changes</button>29 </DialogFooter>30</DialogContent>#Accessibility
- Focus Management - Focus moves to the first focusable element when dialog opens, and returns to the trigger when closed
- Tab Cycling - Tab/Shift+Tab cycles within the dialog content
- Keyboard - Press ESC to close the dialog
- ARIA - role="dialog", aria-modal="true", aria-labelledby, aria-describedby
- Screen Readers - Dialog title and description are announced when opened
#API Reference
DialogTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| onClick | () => void | - | Event handler called when the trigger is clicked. |
| disabled | boolean | false | Whether the trigger is disabled. |
DialogOverlay
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Whether the overlay is visible. |
| onClick | () => void | - | Event handler called when the overlay is clicked (typically to close the dialog). |
DialogContent
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Whether the dialog is open. |
| onClose | () => void | - | Event handler called when the dialog should close (ESC key). |
| ariaLabelledby | string | - | ID of the element that labels the dialog (typically DialogTitle). |
| ariaDescribedby | string | - | ID of the element that describes the dialog (typically DialogDescription). |
DialogTitle
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | - | ID for aria-labelledby reference. |
DialogDescription
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | - | ID for aria-describedby reference. |
DialogClose
| Prop | Type | Default | Description |
|---|---|---|---|
| onClick | () => void | - | Event handler called when the close button is clicked. |