Dialog
A modal window that appears on top of the main content.
Dialog Title
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae maiores dolore ducimus illo animi, deserunt optio facere dignissimos.
import { Button, CloseButton, Dialog, Portal, Text } from '@fidely-ui/react'
export const DialogBasics = () => {
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<Button variant="outline" size="sm">
Open Dialog
</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<Text>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque,
ullam? Delectus, minus! Incidunt laudantium, cum quae maiores
dolore ducimus illo animi, deserunt optio facere dignissimos.
</Text>
</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseAction asChild>
<Button variant={'outline'}>Cancel</Button>
</Dialog.CloseAction>
<Button>Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
Usage
import { Dialog } from '@fidely-ui/react'<Dialog.Root>
<Dialog.Trigger />
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger />
<Dialog.Header>
<Dialog.Title />
</Dialog.Header>
<Dialog.Body />
<Dialog.Footer />
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>Examples
Sizes
Use the size prop to change the size of the dialog component.
Dialog Title
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae maiores dolore ducimus illo animi, deserunt optio facere dignissimos.
Dialog Title
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae maiores dolore ducimus illo animi, deserunt optio facere dignissimos.
Dialog Title
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae maiores dolore ducimus illo animi, deserunt optio facere dignissimos.
Dialog Title
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae maiores dolore ducimus illo animi, deserunt optio facere dignissimos.
import {
Button,
CloseButton,
Dialog,
HStack,
Portal,
Text,
} from '@fidely-ui/react'
export const DialogSizes = () => {
const sizes = ['xs', 'sm', 'md', 'lg'] as const
return (
<HStack gap={3}>
{sizes.map((size) => (
<Dialog.Root size={size} key={size}>
<Dialog.Trigger asChild>
<Button variant="outline" size={size}>
Open Dialog ({size})
</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<Text>
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae
maiores dolore ducimus illo animi, deserunt optio facere
dignissimos.
</Text>
</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseAction asChild>
<Button variant={'outline'}>Cancel</Button>
</Dialog.CloseAction>
<Button>Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
))}
</HStack>
)
}
Controlled
Use the open and onOpenChange prop to control the visibility of the dialog component.
'use client'
import { useState } from 'react'
import { Button, CloseButton, Dialog, Portal, Text } from '@fidely-ui/react'
export const DialogControlled = () => {
const [open, setOpen] = useState(false)
return (
<Dialog.Root open={open} onOpenChange={(e) => setOpen(e.open)} lazyMount>
<Dialog.Trigger asChild>
<Button variant="outline" size="sm">
Open Dialog
</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<Text>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque,
ullam? Delectus, minus! Incidunt laudantium, cum quae maiores
dolore ducimus illo animi, deserunt optio facere dignissimos.
</Text>
</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseAction asChild>
<Button variant={'outline'}>Cancel</Button>
</Dialog.CloseAction>
<Button>Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
Within Context
Use the Dialog.Context component to access the dialog state and methods from outside the dialog.
Dialog Title
Dialog is open: false
click the button below to close
'use client'
import { Button, CloseButton, Dialog, Portal } from '@fidely-ui/react'
export const DialogWithContext = () => {
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<Button variant="outline" size="sm">
Open Dialog
</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
</Dialog.Header>
<Dialog.Context>
{(dialog) => (
<Dialog.Body pt={6} spaceY={'3'}>
<p>Dialog is open: {dialog.open ? 'true' : 'false'}</p>
<p>click the button below to close</p>
<Button onClick={() => dialog.setOpen(false)}>Close</Button>
</Dialog.Body>
)}
</Dialog.Context>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
Store
An alternative way to control the dialog is to use the RootProvider component and the useDialog store hook.
This way you can access the dialog state and methods from outside the dialog.
Dialog Title
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae maiores dolore ducimus illo animi, deserunt optio facere dignissimos.
'use client'
import {
Button,
CloseButton,
Dialog,
HStack,
Portal,
Text,
useDialog,
} from '@fidely-ui/react'
export const DialogWithStore = () => {
const dialog = useDialog()
return (
<HStack gap={3}>
<Button onClick={() => dialog.setOpen(true)}>Open outside</Button>
<Dialog.RootProvider value={dialog}>
<Dialog.Trigger asChild>
<Button variant="outline">Open Dialog within</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<Text>
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
Atque, ullam? Delectus, minus! Incidunt laudantium, cum quae
maiores dolore ducimus illo animi, deserunt optio facere
dignissimos.
</Text>
</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseAction asChild>
<Button variant={'outline'}>Cancel</Button>
</Dialog.CloseAction>
<Button>Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.RootProvider>
</HStack>
)
}
AlertDialog
By default dialog renders as role: "dialog" to change the role below
Pass the role: "alertdialog" prop to change the dialog component to an alert dialog.
Are you sure?
This action cannot be undone.
import { Button, CloseButton, Dialog, Portal, Text } from '@fidely-ui/react'
export const DialogAlert = () => {
return (
<Dialog.Root role="alertdialog" size={'sm'}>
<Dialog.Trigger asChild>
<Button variant="outline" size="sm">
Open Dialog
</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Are you sure?</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<Text>This action cannot be undone.</Text>
</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseAction asChild>
<Button variant={'outline'}>Cancel</Button>
</Dialog.CloseAction>
<Button colorPalette={'red'}>Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
Initial Focus
Use the initialFocusEl prop to set the initial focus of the dialog component.
Login Form
'use client'
import { useRef } from 'react'
import {
Button,
CloseButton,
Dialog,
Field,
Input,
Portal,
Stack,
} from '@fidely-ui/react'
export const DialogFocus = () => {
const ref = useRef<HTMLInputElement | null>(null)
return (
<Dialog.Root initialFocusEl={() => ref.current}>
<Dialog.Trigger asChild>
<Button variant="outline" size="sm">
Open Dialog
</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton size={'sm'} />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Login Form</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<Stack gap="4">
<Field.Root>
<Field.Label>Email</Field.Label>
<Input placeholder="Enter email Address" />
</Field.Root>
<Field.Root>
<Field.Label>Password</Field.Label>
<Input
ref={ref}
placeholder="Enter password"
type="password"
/>
</Field.Root>
</Stack>
</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseAction asChild>
<Button variant={'outline'}>Cancel</Button>
</Dialog.CloseAction>
<Button>Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
Props
Root
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | false | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. |
closeOnEscape | boolean | true | Whether to close the dialog when the escape key is pressed |
closeOnInteractOutside | boolean | true | Whether to close the dialog when the outside is clicked |
lazyMount | boolean | false | Whether to enable lazy mounting |
modal | boolean | true | Whether to prevent pointer interaction outside the element and hide all content below it. |
preventScroll | boolean | true | Whether to prevent scrolling behind the dialog when it's opened |
role | "dialog" | "alertdialog" | "dialog" | The dialog's role. |
size | "xs" | "sm" | "md" | "lg" | "md" | Controls the size of the switch. |
skipAnimationOnMount | `boolean | "false" | Whether to allow the initial presence animation. |
unmountOnExit | boolean | false | Whether to unmount on exit. |
trapFocus | boolean | true | Whether to trap focus inside the dialog when it's opened. |
as | React.ElementType | — | The content of the switch, typically including control, thumb, and label. |
finalFocusEl | () => MaybeElement | — | Element to receive focus when the dialog is closed |
id | string | — | The 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 | boolean | — | Whether to synchronize the present change immediately or defer it to the next frame. |
open | boolean | — | The controlled open state of the dialog. |
present | boolean | — | Whether the node is present (controlled by the user). |
persistentElements | boolean | — | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event. |
restoreFocus | boolean | — | Whether to restore focus to the element that had focus before the dialog was opened |
CloseTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | false | boolean | Use the provided child element as the default rendered element, combining their props and behavior. |