Dialog
Playground
TSX
'use client';
import { useState } from 'react';
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitleGroup,
DialogTitle,
DialogDescription,
DialogBody,
DialogActions,
Button,
type DialogSize,
} from '@mbsw/ui';
export default function Demo() {
const settings = {
"title": "Title",
"description": "description",
"content": "contents",
"actionLabel": "Save",
"cancelLabel": "Cancel",
"size": "sm",
"hasClose": true
};
const [open, setOpen] = useState(true);
return (
<Dialog open={open} onOpenChange={setOpen}>
<style>{`
.mbsw-dialog-overlay[data-state='closed'] {
animation-fill-mode: forwards;
}
`}</style>
<DialogTrigger asChild>
<Button variant="solid" tone="secondary">
open
</Button>
</DialogTrigger>
<DialogContent
style={{
animationFillMode: 'forwards',
maxWidth: 'calc(100% - 48px)',
}}
size={settings.size as DialogSize}
hasClose={settings.hasClose}
closeLabel={"Close dialog"}
>
<DialogHeader>
<DialogTitleGroup>
<DialogTitle>{settings.title}</DialogTitle>
<DialogDescription style={{ whiteSpace: 'pre-wrap' }}>
{settings.description}
</DialogDescription>
</DialogTitleGroup>
</DialogHeader>
<DialogBody style={{ whiteSpace: 'pre-wrap' }}>
{settings.content}
</DialogBody>
<DialogActions>
<Button
variant="outline"
tone="secondary"
onClick={() => setOpen(false)}
>
{settings.cancelLabel}
</Button>
<Button onClick={() => setOpen(false)}>{settings.actionLabel}</Button>
</DialogActions>
</DialogContent>
</Dialog>
);
}
Properties
Size
Close button
Content
Title
Description
Body
Confirm
Cancel
AlertDialog
Use AlertDialog for important decisions that need an explicit confirm or cancel action. It focuses the cancel button first and does not close with Escape.
TSX
'use client';
import {
Button,
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogHeader,
AlertDialogTitleGroup,
type DialogSize,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogActions,
AlertDialogAction,
AlertDialogCancel,
} from '@mbsw/ui';
export default function Demo() {
const settings = {
"title": "Title",
"description": "Description",
"actionLabel": "Confirm",
"cancelLabel": "Cancel",
"size": "sm"
};
return (
<>
<AlertDialog defaultOpen>
<style>{`
.mbsw-dialog-overlay[data-state='closed'] {
animation-fill-mode: forwards;
}
`}</style>
<AlertDialogTrigger asChild>
<Button tone="secondary">open</Button>
</AlertDialogTrigger>
<AlertDialogContent
size={settings.size as DialogSize}
style={{
animationFillMode: 'forwards',
maxWidth: 'calc(100vw - 32px)',
}}
>
<AlertDialogHeader>
<AlertDialogTitleGroup>
<AlertDialogTitle>{settings.title}</AlertDialogTitle>
<AlertDialogDescription style={{ whiteSpace: 'pre-wrap' }}>
{settings.description}
</AlertDialogDescription>
</AlertDialogTitleGroup>
</AlertDialogHeader>
<AlertDialogActions>
<AlertDialogCancel>{settings.cancelLabel}</AlertDialogCancel>
<AlertDialogAction asChild>
<Button variant="solid" tone="destructive">
{settings.actionLabel}
</Button>
</AlertDialogAction>
</AlertDialogActions>
</AlertDialogContent>
</AlertDialog>
</>
);
}
Properties
Size
Content
Title
Description
Confirm
Cancel
SplitDialog
TSX
'use client';
import { useState, useRef } from 'react';
import {
Button,
SplitDialog,
SplitDialogTrigger,
SplitDialogContent,
SplitDialogLayout,
SplitDialogActions,
DialogHeader,
DialogTitleGroup,
DialogTitle,
DialogDescription,
ScrollArea,
} from '@mbsw/ui';
export default function Demo() {
const settings = {
"secondaryContent": "Content B",
"title": "Title",
"description": "Description",
"content": "Content A",
"actionLabel": "Confirm",
"cancelLabel": "Cancel"
};
const [open, setOpen] = useState(true);
const contentRef = useRef<HTMLDivElement>(null);
return (
<SplitDialog open={open} onOpenChange={setOpen}>
<style>{`
.mbsw-dialog-overlay[data-state='closed'] { animation-fill-mode: forwards; }
.example-split-layout > [data-slot='split-dialog-left'] { width: auto; }
`}</style>
<SplitDialogTrigger asChild>
<Button tone="secondary" variant="solid">
open
</Button>
</SplitDialogTrigger>
<SplitDialogContent
ref={contentRef}
onOpenAutoFocus={(event) => {
event.preventDefault();
contentRef.current?.focus();
}}
style={{
animationFillMode: 'forwards',
width: 'min(960px, calc(100vw - 32px))',
height: 'calc(100dvh - 32px)',
maxHeight: 600,
gap: 16,
padding: 16,
}}
>
<DialogHeader>
<DialogTitleGroup>
<DialogTitle>{settings.title || 'Title'}</DialogTitle>
<DialogDescription style={{ whiteSpace: 'pre-wrap' }}>
{settings.description}
</DialogDescription>
</DialogTitleGroup>
</DialogHeader>
<SplitDialogLayout
className="example-split-layout"
style={{
display: 'grid',
gridTemplateColumns: 'minmax(0, 1fr) 1px minmax(0, 1fr)',
gap: 16,
}}
left={
<ScrollArea
style={{ width: '100%', height: '100%' }}
viewportProps={{ 'aria-label': 'Left content' }}
>
<div
style={{
padding: 12,
whiteSpace: 'pre-wrap',
overflowWrap: 'anywhere',
}}
>
{settings.content}
</div>
</ScrollArea>
}
right={
<ScrollArea
style={{ width: '100%', height: '100%' }}
viewportProps={{ 'aria-label': 'Right content' }}
>
<div
style={{
padding: 12,
whiteSpace: 'pre-wrap',
overflowWrap: 'anywhere',
}}
>
{settings.secondaryContent}
</div>
</ScrollArea>
}
/>
<SplitDialogActions>
<Button
variant="outline"
tone="secondary"
onClick={() => setOpen(false)}
>
{settings.cancelLabel}
</Button>
<Button onClick={() => setOpen(false)}>{settings.actionLabel}</Button>
</SplitDialogActions>
</SplitDialogContent>
</SplitDialog>
);
}
Content
Title
Description
Left content
Right content
Confirm
Cancel
Usage
DialogContent includes the backdrop, portal and close button. Use hasClose to show or hide the button and closeLabel to name it. Use AlertDialog for decisions that need an explicit confirm or cancel action. Use SplitDialog to divide content into two sections.
TSX
'use client';
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitleGroup,
DialogTitle,
DialogDescription,
DialogBody,
Button,
} from '@mbsw/ui';
export default function Example() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>open</Button>
</DialogTrigger>
<DialogContent size="sm" closeLabel={"Close dialog"}>
<DialogHeader>
<DialogTitleGroup>
<DialogTitle>Title</DialogTitle>
<DialogDescription>description</DialogDescription>
</DialogTitleGroup>
</DialogHeader>
<DialogBody>contents</DialogBody>
</DialogContent>
</Dialog>
);
}
The Playground Code tab includes the full example with your current settings. See Installation for the CSS imports.
Composition
AlertDialogAlertDialogActionAlertDialogActionsAlertDialogCancelAlertDialogContentAlertDialogDescriptionAlertDialogHeaderAlertDialogPortalAlertDialogTitleAlertDialogTitleGroupAlertDialogTriggerDialogDialogActionsDialogBodyDialogCloseDialogContentDialogDescriptionDialogHeaderDialogOverlayDialogPortalDialogTitleDialogTitleGroupDialogTriggerSplitDialogSplitDialogActionsSplitDialogCloseSplitDialogContentSplitDialogLayoutSplitDialogTrigger