Skip to main content

Dialog

The Dialog (Modal) component is used to create focused interactions that require user attention or input. It displays content that temporarily blocks interactions with the main view.

Import

import { Dialog } from '@lazy-panda-ui/lazy-panda-ui';

Usage

import React from 'react';
import { Dialog, Button, Typography, Stack } from '@lazy-panda-ui/lazy-panda-ui';

function MyComponent() {
const [open, setOpen] = React.useState(false);
return (
<>
<Button onPress={() => setOpen(true)}>Open Dialog</Button>
<Dialog open={open} onClose={() => setOpen(false)} title="Dialog Title">
<Stack gap="sm">
<Typography>Dialog body content goes here.</Typography>
<Button onPress={() => setOpen(false)}>Close</Button>
</Stack>
</Dialog>
</>
);
}

Props

Dialog Props

  • open: boolean
  • onClose: () => void
  • title?: string
  • size?: 'small' | 'medium' | 'large' (default 'medium')
  • style?: ViewStyle

Dialog.Header Props

NameTypeDefaultDescription
showCloseButtonbooleantrueShow close button
closeButtonPropsButtonProps-Close button props

Examples

Basic Dialog

<Dialog open={open} onClose={onClose}>
<Dialog.Header>Confirmation</Dialog.Header>
<Dialog.Content>
Are you sure you want to continue?
</Dialog.Content>
<Dialog.Footer>
<Button variant="outlined" onClick={onClose}>
Cancel
</Button>
<Button onClick={onConfirm}>
Confirm
</Button>
</Dialog.Footer>
</Dialog>

Different Sizes

<Stack direction="row" gap="sm">
<Dialog open size="small" onClose={() => {}} title="Small" />
<Dialog open size="medium" onClose={() => {}} title="Medium" />
<Dialog open size="large" onClose={() => {}} title="Large" />
</Stack>

Theming

import { ThemeProvider, createTheme, defaultTheme } from '@lazy-panda-ui/lazy-panda-ui/theme';

const theme = createTheme(defaultTheme, {
dialog: {
sizes: { medium: 600 },
overlay: { color: '#000', opacity: 0.5 },
container: {
backgroundColor: defaultTheme.colors.surface,
borderRadius: 12,
padding: 20,
shadow: { ...defaultTheme.dialog.container.shadow, elevation: 6 },
},
title: { color: defaultTheme.colors.onSurface, fontSize: 20, fontWeight: defaultTheme.fontWeight.semibold, marginBottom: 12 },
animation: { type: 'fade' },
},
});

function App() {
return (
<ThemeProvider theme={theme}>
<Dialog open onClose={() => {}} title="Custom Dialog" />
</ThemeProvider>
);
}

Nested Dialogs

<Dialog open={open} onClose={onClose}>
<Dialog.Header>Parent Dialog</Dialog.Header>
<Dialog.Content>
<Button onClick={() => setNestedOpen(true)}>
Open nested dialog
</Button>
</Dialog.Content>

<Dialog open={nestedOpen} onClose={onNestedClose}>
<Dialog.Header>Nested Dialog</Dialog.Header>
<Dialog.Content>
This is a nested dialog.
</Dialog.Content>
</Dialog>
</Dialog>

Form Dialog

<Dialog open={open} onClose={onClose}>
<Dialog.Header>Create Account</Dialog.Header>
<Dialog.Content>
<Stack spacing="md">
<TextField
label="Username"
value={username}
onChange={setUsername}
/>
<TextField
label="Email"
type="email"
value={email}
onChange={setEmail}
/>
<TextField
label="Password"
type="password"
value={password}
onChange={setPassword}
/>
</Stack>
</Dialog.Content>
<Dialog.Footer>
<Button variant="outlined" onClick={onClose}>
Cancel
</Button>
<Button onClick={handleSubmit}>
Create
</Button>
</Dialog.Footer>
</Dialog>

Scroll Behavior

Inside Dialog

<Dialog
open={open}
onClose={onClose}
scrollBehavior="inside"
>
<Dialog.Header>Scrollable Content</Dialog.Header>
<Dialog.Content>
{/* Long content that scrolls inside dialog */}
</Dialog.Content>
</Dialog>

Outside Dialog

<Dialog
open={open}
onClose={onClose}
scrollBehavior="outside"
>
<Dialog.Header>Fixed Header</Dialog.Header>
<Dialog.Content>
{/* Content that causes page to scroll */}
</Dialog.Content>
<Dialog.Footer>Fixed Footer</Dialog.Footer>
</Dialog>

Customization

Custom Styles

<Dialog
open={open}
onClose={onClose}
containerStyle={{
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: '16px',
}}
overlayStyle={{
backgroundColor: 'rgba(0, 0, 0, 0.8)',
}}
>
<Dialog.Header
style={{ color: 'white' }}
>
Styled Dialog
</Dialog.Header>
<Dialog.Content
style={{ color: 'white' }}
>
This dialog has custom styling.
</Dialog.Content>
</Dialog>

Custom Transitions

<Dialog
open={open}
onClose={onClose}
transitions={{
overlay: {
enter: 'fade-in',
exit: 'fade-out',
},
dialog: {
enter: 'slide-up',
exit: 'slide-down',
},
}}
>
{/* Dialog content */}
</Dialog>

Best Practices

  1. Keep content focused and concise
  2. Provide clear actions
  3. Handle keyboard interactions
  4. Consider mobile viewports
  5. Maintain proper focus management
  6. Use appropriate sizes
  7. Implement proper error handling

API Reference

Token Overview

  • dialog.sizes: width by size key
  • dialog.minWidth: minimum width
  • dialog.overlay: color and opacity
  • dialog.container: background, radius, padding, shadow
  • dialog.title: typography and spacing
  • dialog.animation: modal animation type

Theme Customization

const theme = {
dialog: {
overlay: {
background: 'rgba(0, 0, 0, 0.5)',
zIndex: 1000,
},
container: {
background: 'white',
borderRadius: '8px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
},
header: {
padding: '16px 24px',
borderBottom: '1px solid #eee',
},
content: {
padding: '24px',
},
footer: {
padding: '16px 24px',
borderTop: '1px solid #eee',
},
},
};
  • Modal - Alternative name for Dialog
  • Drawer - Side-sliding panel
  • Popover - For smaller overlays
  • Alert - For simple messages