DialogDemo
import { Button } from '@/components/ui/button'
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
import { TextField } from '@/components/ui/text-field'
export function DialogDemo() {
return (
<div className='flex flex-wrap items-center gap-4'>
<Dialog>
<DialogTrigger asChild>
<Button square size='sm' variant='elevated'>
Open Dialog(centered)
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader center>
<i className='icon-[material-symbols--delete-outline-rounded]' />
<DialogTitle>Delete Settings?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your account and remove your data from
our servers.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant='text' size='sm'>
Action1
</Button>
</DialogClose>
<Button size='sm'>Action2</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<Dialog>
<DialogTrigger asChild>
<Button square size='sm' variant='elevated'>
Open Dialog
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your account and remove your data from
our servers.
</DialogDescription>
</DialogHeader>
<TextField className='w-full' label='Label Text' helperText='type "im sure" to continue' />
<DialogFooter>
<DialogClose asChild>
<Button variant='text' size='sm'>
Action1
</Button>
</DialogClose>
<Button size='sm'>Action2</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
)
}
Installation
- Install the following dependencies
pnpm add @radix-ui/react-dialog- Copy and paste the following code into your project
src/components/ui/dialog.tsx
'use client'
import * as React from 'react'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { cn } from '@/lib/utils'
function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot='dialog' {...props} />
}
function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot='dialog-trigger' {...props} />
}
function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot='dialog-portal' {...props} />
}
function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot='dialog-close' {...props} />
}
function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
data-slot='dialog-overlay'
className={cn(
'fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',
className,
)}
{...props}
/>
)
}
function DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>) {
return (
<DialogPortal data-slot='dialog-portal'>
<DialogOverlay />
<DialogPrimitive.Content
data-slot='dialog-content'
className={cn(
'fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-[28px] bg-surface-container-high p-6 duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg',
className,
)}
{...props}
>
{children}
</DialogPrimitive.Content>
</DialogPortal>
)
}
function DialogHeader({ center = false, className, ...props }: React.ComponentProps<'div'> & { center?: boolean }) {
return (
<div
data-slot='dialog-header'
className={cn(
'flex flex-col gap-4 text-center sm:text-left [&_i]:text-secondary [&_i:not([class*=size-])]:size-6',
center && 'items-center justify-baseline',
className,
)}
{...props}
/>
)
}
function DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='dialog-footer'
className={cn('mt-2 flex h-10 flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
{...props}
/>
)
}
function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
return <DialogPrimitive.Title data-slot='dialog-title' className={cn('text-2xl leading-8', className)} {...props} />
}
function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
return (
<DialogPrimitive.Description
data-slot='dialog-description'
className={cn('text-sm text-on-surface-variant', className)}
{...props}
/>
)
}
export {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
DialogClose,
}
Usage
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'<Dialog>
<DialogTrigger>Open</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone.
</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>API Reference
Dialog
| Prop | type | default |
|---|---|---|
| open | boolean | |
| defaultOpen | boolean | |
| onOpenChange | function | |
| modal | boolean | true |
DialogTrigger
| Prop | type | default |
|---|---|---|
| asChild | boolean | false |
DialogContent
| Prop | type | default |
|---|---|---|
| onOpenAutoFocus | function | |
| onCloseAutoFocus | function | |
| onEscapeKeyDown | function | |
| onPointerDownOutside | function | |
| onInteractOutside | function | |
| forceMount | boolean |
DialogHeader
| Prop | type | default |
|---|---|---|
| center | boolean | false |
DialogFooter
| Prop | type | default |
|---|---|---|
| - | - | - |
DialogTitle
| Prop | type | default |
|---|---|---|
| asChild | boolean | false |
DialogDescription
| Prop | type | default |
|---|---|---|
| asChild | boolean | false |
DialogClose
| Prop | type | default |
|---|---|---|
| asChild | boolean | false |
DialogOverlay
| Prop | type | default |
|---|---|---|
| forceMount | boolean |