'use client'
import { Button, Dialog } from '@saas-ui/react'
export const DialogBasic = () => {
  return (
    <Dialog.Root>
      <Dialog.Trigger asChild>
        <Button variant="outline" size="sm">
          Open Dialog
        </Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>Dialog Title</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua.
          </p>
        </Dialog.Body>
        <Dialog.Footer>
          <Dialog.ActionTrigger asChild>
            <Button variant="ghost">Cancel</Button>
          </Dialog.ActionTrigger>
          <Button variant="glass" colorPalette="accent">
            Save
          </Button>
        </Dialog.Footer>
      </Dialog.Content>
    </Dialog.Root>
  )
}
import { Dialog } from '@saas-ui/react/dialog'<Dialog.Root>
  <Dialog.Backdrop />
  <Dialog.Trigger />
  <Dialog.Content>
    <Dialog.Header>
      <Dialog.Title />
      <Dialog.CloseButton />
    </Dialog.Header>
    <Dialog.Body />
    <Dialog.Footer>
      <Dialog.CloseTrigger asChild>
        <Button>Close</Button>
      </Dialog.CloseTrigger>
    </Dialog.Footer>
  </Dialog.Content>
</Dialog.Root>Use the size prop to change the size of the dialog component.
'use client'
import { For, HStack } from '@chakra-ui/react'
import { Button, Dialog } from '@saas-ui/react'
export const DialogWithSizes = () => {
  return (
    <HStack>
      <For each={['xs', 'sm', 'md', 'lg']}>
        {(size) => (
          <Dialog.Root key={size} size={size}>
            <Dialog.Trigger asChild>
              <Button variant="outline" size={size}>
                Open ({size})
              </Button>
            </Dialog.Trigger>
            <Dialog.Content>
              <Dialog.Header>
                <Dialog.Title>Dialog Title</Dialog.Title>
                <Dialog.CloseButton />
              </Dialog.Header>
              <Dialog.Body>
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
                  do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                </p>
              </Dialog.Body>
              <Dialog.Footer>
                <Dialog.ActionTrigger asChild>
                  <Button variant="ghost">Cancel</Button>
                </Dialog.ActionTrigger>
                <Button variant="glass" colorPalette="accent">
                  Save
                </Button>
              </Dialog.Footer>
            </Dialog.Content>
          </Dialog.Root>
        )}
      </For>
    </HStack>
  )
}
Use the size="cover" prop to make the dialog component cover the entire screen
while revealing a small portion of the page behind.
'use client'
import { Button, Dialog } from '@saas-ui/react'
export const DialogWithCover = () => {
  return (
    <Dialog.Root size="cover" placement="center" motionPreset="slide-in-bottom">
      <Dialog.Trigger asChild>
        <Button variant="outline" size="sm">
          Open Dialog
        </Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>Dialog Title</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </Dialog.Body>
      </Dialog.Content>
    </Dialog.Root>
  )
}
Use the open and onOpenChange prop to control the visibility of the dialog
component.
'use client'
import { useState } from 'react'
import { Button, Dialog } from '@saas-ui/react'
import Lorem from 'react-lorem-ipsum'
export const DialogControlled = () => {
  const [open, setOpen] = useState(false)
  return (
    <Dialog.Root lazyMount open={open} onOpenChange={(e) => setOpen(e.open)}>
      <Dialog.Trigger asChild>
        <Button variant="outline">Open</Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>Dialog Title</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          <Lorem p={2} />
        </Dialog.Body>
        <Dialog.Footer>
          <Dialog.ActionTrigger asChild>
            <Button variant="ghost">Cancel</Button>
          </Dialog.ActionTrigger>
          <Button variant="glass" colorPalette="accent">
            Save
          </Button>
        </Dialog.Footer>
      </Dialog.Content>
    </Dialog.Root>
  )
}
Use the initialFocusEl prop to set the initial focus of the dialog component.
'use client'
import { useRef } from 'react'
import { Input, Stack } from '@chakra-ui/react'
import { Button, Dialog } from '@saas-ui/react'
export const DialogWithInitialFocus = () => {
  const ref = useRef<HTMLInputElement>(null)
  return (
    <Dialog.Root initialFocusEl={() => ref.current}>
      <Dialog.Trigger asChild>
        <Button variant="outline">Open</Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>Dialog Header</Dialog.Title>
        </Dialog.Header>
        <Dialog.Body pb="4">
          <Stack gap="4">
            <Input placeholder="First Name" />
            <Input placeholder="Last Name" />
            <Input ref={ref} placeholder="Focus First" />
          </Stack>
        </Dialog.Body>
        <Dialog.Footer>
          <Dialog.ActionTrigger asChild>
            <Button variant="ghost">Cancel</Button>
          </Dialog.ActionTrigger>
          <Button variant="glass" colorPalette="accent">
            Save
          </Button>
        </Dialog.Footer>
      </Dialog.Content>
    </Dialog.Root>
  )
}
Use the scrollBehavior=inside prop to change the scroll behavior of the dialog
when its content overflows.
'use client'
import { Button, Dialog } from '@saas-ui/react'
import Lorem from 'react-lorem-ipsum'
export const DialogWithInsideScroll = () => {
  return (
    <Dialog.Root scrollBehavior="inside" size="sm">
      <Dialog.Trigger asChild>
        <Button variant="outline">Inside Scroll</Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>With Inside Scroll</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          <Lorem p={8} />
        </Dialog.Body>
      </Dialog.Content>
    </Dialog.Root>
  )
}
Use the scrollBehavior=outside prop to change the scroll behavior of the
dialog when its content overflows.
'use client'
import { Button, Dialog } from '@saas-ui/react'
import Lorem from 'react-lorem-ipsum'
export const DialogWithOutsideScroll = () => {
  return (
    <Dialog.Root size="sm" scrollBehavior="outside">
      <Dialog.Trigger asChild>
        <Button variant="outline">Outside Scroll</Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>With Outside Scroll</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          <Lorem p={8} />
        </Dialog.Body>
      </Dialog.Content>
    </Dialog.Root>
  )
}
Use the motionPreset prop to change the animation of the dialog component.
'use client'
import { Button, Dialog } from '@saas-ui/react'
export const DialogWithMotionPreset = () => {
  return (
    <Dialog.Root motionPreset="slide-in-bottom">
      <Dialog.Trigger asChild>
        <Button variant="outline">Slide in Bottom</Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>Dialog Title</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua.
          </p>
        </Dialog.Body>
        <Dialog.Footer>
          <Dialog.ActionTrigger asChild>
            <Button variant="ghost">Cancel</Button>
          </Dialog.ActionTrigger>
          <Button variant="glass" colorPalette="accent">
            Save
          </Button>
        </Dialog.Footer>
      </Dialog.Content>
    </Dialog.Root>
  )
}
Set the role: "alertdialog" prop to change the dialog component to an alert
dialog.
'use client'
import { Button, Dialog } from '@saas-ui/react'
export const DialogWithRole = () => {
  return (
    <Dialog.Root role="alertdialog">
      <Dialog.Trigger asChild>
        <Button variant="outline" size="sm">
          Open Dialog
        </Button>
      </Dialog.Trigger>
      <Dialog.Content>
        <Dialog.Header>
          <Dialog.Title>Are you sure?</Dialog.Title>
          <Dialog.CloseButton />
        </Dialog.Header>
        <Dialog.Body>
          <p>
            This action cannot be undone. This will permanently delete your
            account and remove your data from our systems.
          </p>
        </Dialog.Body>
        <Dialog.Footer>
          <Dialog.ActionTrigger asChild>
            <Button variant="ghost">Cancel</Button>
          </Dialog.ActionTrigger>
          <Button variant="glass" colorPalette="red">
            Delete
          </Button>
        </Dialog.Footer>
        <Dialog.CloseTrigger />
      </Dialog.Content>
    </Dialog.Root>
  )
}
Here's an example of how to compose the dialog component with the DataList
component.
'use client'
import { HStack, Textarea, VStack } from '@chakra-ui/react'
import { Avatar, Badge, Button, DataList, Dialog } from '@saas-ui/react'
export const DialogWithDatalist = () => {
  return (
    <VStack alignItems="start">
      <Dialog.Root>
        <Dialog.Trigger asChild>
          <Button variant="outline">Open Dialog</Button>
        </Dialog.Trigger>
        <Dialog.Content>
          <Dialog.Header>
            <Dialog.Title>Prepare Chakra V3</Dialog.Title>
            <Dialog.CloseButton />
          </Dialog.Header>
          <Dialog.Body pb="8">
            <DataList.Root orientation="horizontal">
              <DataList.Item>
                <DataList.ItemLabel>Status</DataList.ItemLabel>
                <DataList.ItemValue>
                  <Badge colorPalette="green">Completed</Badge>
                </DataList.ItemValue>
              </DataList.Item>
              <DataList.Item>
                <DataList.ItemLabel>Assigned to</DataList.ItemLabel>
                <DataList.ItemValue>
                  <HStack>
                    <Avatar
                      size="xs"
                      name="Eelco Wiersma"
                      src="https://eelco.dev"
                    />
                    Eelco Wiersma
                  </HStack>
                </DataList.ItemValue>
              </DataList.Item>
              <DataList.Item>
                <DataList.ItemLabel>Due date</DataList.ItemLabel>
                <DataList.ItemValue>12th August 2024</DataList.ItemValue>
              </DataList.Item>
            </DataList.Root>
            <Textarea placeholder="Add a note" mt="8" />
          </Dialog.Body>
        </Dialog.Content>
      </Dialog.Root>
    </VStack>
  )
}
| Prop | Default | Type | 
|---|---|---|
| closeOnEscape  | true | booleanWhether to close the dialog when the escape key is pressed | 
| closeOnInteractOutside  | true | booleanWhether to close the dialog when the outside is clicked | 
| lazyMount  | false | booleanWhether to enable lazy mounting | 
| modal  | true | booleanWhether to prevent pointer interaction outside the element and hide all content below it | 
| preventScroll  | true | booleanWhether to prevent scrolling behind the dialog when it's opened | 
| role  | '\'dialog\'' | 'dialog' | 'alertdialog'The dialog's role | 
| trapFocus  | true | booleanWhether to trap focus inside the dialog when it's opened | 
| unmountOnExit  | false | booleanWhether to unmount on exit. | 
| colorPalette  | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' | 'accent'The color palette of the component | 
| scrollBehavior  | 'outside' | 'inside' | 'outside'The scrollBehavior of the component | 
| size  | 'md' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full'The size of the component | 
| motionPreset  | 'scale' | 'scale' | 'slide-in-bottom' | 'slide-in-top' | 'slide-in-left' | 'slide-in-right' | 'none'The motionPreset of the component | 
| aria-label  | stringHuman readable label for the dialog, in event the dialog title is not rendered | |
| defaultOpen  | booleanThe initial open state of the dialog when it is first rendered. Use when you do not need to control its open state. | |
| finalFocusEl  | () => HTMLElement | nullElement to receive focus when the dialog is closed | |
| id  | stringThe unique identifier of the machine. | |
| ids  | Partial<{
  trigger: string
  positioner: string
  backdrop: string
  content: string
  closeTrigger: string
  title: string
  description: string
}>The ids of the elements in the dialog. Useful for composition. | |
| immediate  | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
| initialFocusEl  | () => HTMLElement | nullElement to receive focus when the dialog is opened | |
| onEscapeKeyDown  | (event: KeyboardEvent) => voidFunction called when the escape key is pressed | |
| onExitComplete  | () => voidFunction called when the animation ends in the closed state | |
| onFocusOutside  | (event: FocusOutsideEvent) => voidFunction called when the focus is moved outside the component | |
| onInteractOutside  | (event: InteractOutsideEvent) => voidFunction called when an interaction happens outside the component | |
| onOpenChange  | (details: OpenChangeDetails) => voidCallback to be invoked when the dialog is opened or closed | |
| onPointerDownOutside  | (event: PointerDownOutsideEvent) => voidFunction called when the pointer is pressed down outside the component | |
| open  | booleanWhether the dialog is open | |
| persistentElements  | (() => Element | null)[]Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | |
| present  | booleanWhether the node is present (controlled by the user) | |
| restoreFocus  | booleanWhether to restore focus to the element that had focus before the dialog was opened | |
| centered  | 'true' | 'false'The centered of the component | |
| as  | React.ElementTypeThe underlying element to render. | |
| asChild  | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | |
| unstyled  | booleanWhether to remove the component's style. |