Date PickerDrawer
Get Started
Introduction
Components
Accordion
Badge
Button
Card
Checkbox
Command
Dialog
Dropdown Menu
Input
Select
Switch
Table
Tabs
Toast
Tooltip
Forms
Controlled Input
Field Arrays
Submit
Validation

A modal dialog that displays content in a layer above the page. Supports ESC key, overlay click, focus trap, and scroll lock.

#Installation

bunx --bun barefoot add dialog

#Usage

1import {2  Dialog,3  DialogTrigger,4  DialogOverlay,5  DialogContent,6  DialogHeader,7  DialogTitle,8  DialogDescription,9  DialogFooter,10  DialogClose,11} from '@/components/ui/dialog'

#Examples

#Delete Confirmation

1"use client"23import { createSignal } from '@barefootjs/dom'4import {5  Dialog,6  DialogTrigger,7  DialogOverlay,8  DialogContent,9  DialogHeader,10  DialogTitle,11  DialogDescription,12  DialogFooter,13  DialogClose,14} from '@/components/ui/dialog'1516function DeleteConfirmDialog() {17  const [open, setOpen] = createSignal(false)18  const [confirmText, setConfirmText] = createSignal('')19  const projectName = 'my-project'2021  const isConfirmed = () => confirmText() === projectName2223  const handleOpenChange = (isOpen: boolean) => {24    setOpen(isOpen)25    if (!isOpen) setConfirmText('')26  }2728  return (29    <Dialog open={open()} onOpenChange={handleOpenChange}>30      <DialogTrigger asChild>31        <button class="bg-destructive ...">Delete Project</button>32      </DialogTrigger>33      <DialogOverlay />34      <DialogContent ariaLabelledby="delete-dialog-title" ...>35        <DialogHeader>36          <DialogTitle>Delete Project</DialogTitle>37          <DialogDescription>38            This will permanently delete <strong>{projectName}</strong>.39          </DialogDescription>40        </DialogHeader>41        <div className="py-4">42          <label className="text-sm text-muted-foreground">43            Please type <strong>{projectName}</strong> to confirm.44          </label>45          <input46            type="text"47            value={confirmText()}48            onInput={(e) => setConfirmText(e.target.value)}49            placeholder={projectName}50            className="mt-2 flex h-10 w-full rounded-md border ..."51          />52        </div>53        <DialogFooter>54          <DialogClose>Cancel</DialogClose>55          <button56            onClick={() => { setOpen(false); setConfirmText('') }}57            disabled={!isConfirmed()}58            class="bg-destructive ..."59          >60            Delete Project61          </button>62        </DialogFooter>63      </DialogContent>64    </Dialog>65  )66}

#Long Content

1"use client"23import { createSignal } from '@barefootjs/dom'4import {5  Dialog,6  DialogTrigger,7  DialogOverlay,8  DialogContent,9  DialogHeader,10  DialogTitle,11  DialogDescription,12  DialogFooter,13  DialogClose,14} from '@/components/ui/dialog'1516function DialogLongContent() {17  const [open, setOpen] = createSignal(false)1819  return (20    <Dialog open={open()} onOpenChange={setOpen}>21      <DialogTrigger>Open Long Content Dialog</DialogTrigger>22      <DialogOverlay />23      <DialogContent24        ariaLabelledby="long-dialog-title"25        ariaDescribedby="long-dialog-description"26        class="max-h-[66vh]"27      >28        <DialogHeader class="flex-shrink-0">29          <DialogTitle id="long-dialog-title">Terms of Service</DialogTitle>30          <DialogDescription id="long-dialog-description">31            Please read the following terms carefully.32          </DialogDescription>33        </DialogHeader>34        <div className="text-sm text-muted-foreground space-y-4 overflow-y-auto flex-1 min-h-0">35          <p>Lorem ipsum dolor sit amet...</p>36          {/* Multiple paragraphs - only this area scrolls */}37        </div>38        <DialogFooter class="flex-shrink-0">39          <DialogClose>Decline</DialogClose>40          <DialogClose>Accept</DialogClose>41        </DialogFooter>42      </DialogContent>43    </Dialog>44  )45}

#Accessibility

  • 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
  • ARIA attributes - role="dialog", aria-modal="true", aria-labelledby, aria-describedby
  • Portal rendering - Dialog is mounted to document.body via createPortal

#API Reference

Dialog

PropTypeDefaultDescription
openbooleanfalseWhether the dialog is open.
onOpenChange(open: boolean) => void-Event handler called when the open state should change.

DialogTrigger

PropTypeDefaultDescription
disabledbooleanfalseWhether the trigger is disabled.
asChildbooleanfalseRender child element as trigger instead of built-in button.

DialogOverlay

PropTypeDefaultDescription

DialogContent

PropTypeDefaultDescription
ariaLabelledbystring-ID of the element that labels the dialog (typically DialogTitle).
ariaDescribedbystring-ID of the element that describes the dialog (typically DialogDescription).

DialogTitle

PropTypeDefaultDescription
idstring-ID for aria-labelledby reference.

DialogDescription

PropTypeDefaultDescription
idstring-ID for aria-describedby reference.

DialogClose

PropTypeDefaultDescription