Dialog
A modal window that appears on top of the main content.
Usage
Dialog Title
Dialog Description
import { XIcon } from 'lucide-react'
import { Stack } from 'styled-system/jsx'
import { Button, Dialog, IconButton } from '~/components/ui'
export const Demo = (props: Dialog.RootProps) => {
return (
<Dialog.Root {...props}>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Stack gap="8" p="6">
<Stack gap="1">
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
</Stack>
<Stack gap="3" direction="row" width="full">
<Dialog.CloseTrigger asChild>
<Button variant="outline" width="full">
Cancel
</Button>
</Dialog.CloseTrigger>
<Button width="full">Confirm</Button>
</Stack>
</Stack>
<Dialog.CloseTrigger asChild position="absolute" top="2" right="2">
<IconButton aria-label="Close Dialog" variant="ghost" size="sm">
<XIcon />
</IconButton>
</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
)
}
Installation
npx @park-ui/cli components add dialog
1
Styled Primitive
Copy the code snippet below into ~/components/ui/primitives/dialog.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { Dialog } from '@ark-ui/react/dialog'
import { type DialogVariantProps, dialog } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withRootProvider, withContext } = createStyleContext(dialog)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withRootProvider<Assign<Dialog.RootProviderProps, DialogVariantProps>>(
Dialog.RootProvider,
)
export type RootProps = ComponentProps<typeof Root>
export const Root = withRootProvider<Assign<Dialog.RootProps, DialogVariantProps>>(Dialog.Root)
export const Backdrop = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Dialog.BackdropBaseProps>
>(Dialog.Backdrop, 'backdrop')
export const CloseTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Dialog.CloseTriggerBaseProps>
>(Dialog.CloseTrigger, 'closeTrigger')
export const Content = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Dialog.ContentBaseProps>
>(Dialog.Content, 'content')
export const Description = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Dialog.DescriptionBaseProps>
>(Dialog.Description, 'description')
export const Positioner = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Dialog.PositionerBaseProps>
>(Dialog.Positioner, 'positioner')
export const Title = withContext<
HTMLHeadingElement,
Assign<HTMLStyledProps<'h2'>, Dialog.TitleBaseProps>
>(Dialog.Title, 'title')
export const Trigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Dialog.TriggerBaseProps>
>(Dialog.Trigger, 'trigger')
export { DialogContext as Context } from '@ark-ui/react/dialog'
import { type Assign, Dialog } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { type DialogVariantProps, dialog } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withRootProvider, withContext } = createStyleContext(dialog)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withRootProvider<Assign<Dialog.RootProviderProps, DialogVariantProps>>(
Dialog.RootProvider,
)
export type RootProps = ComponentProps<typeof Root>
export const Root = withRootProvider<Assign<Dialog.RootProps, DialogVariantProps>>(Dialog.Root)
export const Backdrop = withContext<Assign<HTMLStyledProps<'div'>, Dialog.BackdropBaseProps>>(
Dialog.Backdrop,
'backdrop',
)
export const CloseTrigger = withContext<
Assign<HTMLStyledProps<'button'>, Dialog.CloseTriggerBaseProps>
>(Dialog.CloseTrigger, 'closeTrigger')
export const Content = withContext<Assign<HTMLStyledProps<'div'>, Dialog.ContentBaseProps>>(
Dialog.Content,
'content',
)
export const Description = withContext<Assign<HTMLStyledProps<'div'>, Dialog.DescriptionBaseProps>>(
Dialog.Description,
'description',
)
export const Positioner = withContext<Assign<HTMLStyledProps<'div'>, Dialog.PositionerBaseProps>>(
Dialog.Positioner,
'positioner',
)
export const Title = withContext<Assign<HTMLStyledProps<'h2'>, Dialog.TitleBaseProps>>(
Dialog.Title,
'title',
)
export const Trigger = withContext<Assign<HTMLStyledProps<'button'>, Dialog.TriggerBaseProps>>(
Dialog.Trigger,
'trigger',
)
export { DialogContext as Context } from '@ark-ui/solid'
No snippet found
Extend ~/components/ui/primitives/index.ts
with the following line:
export * as Dialog from './dialog'
2
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { dialogAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const dialog = defineSlotRecipe({
className: 'dialog',
slots: dialogAnatomy.keys(),
base: {
backdrop: {
backdropFilter: 'blur(4px)',
background: {
base: 'white.a10',
_dark: 'black.a10',
},
height: '100vh',
left: '0',
position: 'fixed',
top: '0',
width: '100vw',
zIndex: 'overlay',
_open: {
animation: 'backdrop-in',
},
_closed: {
animation: 'backdrop-out',
},
},
positioner: {
alignItems: 'center',
display: 'flex',
justifyContent: 'center',
left: '0',
overflow: 'auto',
position: 'fixed',
top: '0',
width: '100vw',
height: '100dvh',
zIndex: 'modal',
},
content: {
background: 'bg.default',
borderRadius: 'l3',
boxShadow: 'lg',
minW: 'sm',
position: 'relative',
_open: {
animation: 'dialog-in',
},
_closed: {
animation: 'dialog-out',
},
},
title: {
fontWeight: 'semibold',
textStyle: 'lg',
},
description: {
color: 'fg.muted',
textStyle: 'sm',
},
},
})