11 KiB
11 KiB
Modal
Modal dialog component for displaying content in an overlay with customizable actions and backdrop. Uses the native HTML <dialog> element for better accessibility and performance.
Tag
Modal
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open |
boolean | Signal<boolean> |
false |
Modal visibility state |
title |
string | VNode | Signal |
- |
Modal title text |
buttons |
Array<VNode> | VNode |
- |
Action buttons to display (auto-closes on click) |
class |
string |
'' |
Additional CSS classes (DaisyUI + Tailwind) |
children |
string | VNode |
- |
Modal content |
Styling
Modal supports all daisyUI Modal classes:
| Category | Keywords | Description |
|---|---|---|
| Size | modal-sm, modal-md, modal-lg, modal-xl |
Modal scale |
| Position | modal-top, modal-middle, modal-bottom |
Modal vertical alignment |
For further details, check the daisyUI Modal Documentation – Full reference for CSS classes.
Live Examples
Basic Modal
Live Demo
const BasicDemo = () => {
const isOpen = $(false);
return Div({ class: 'flex justify-center' }, [
Button({
class: 'btn btn-primary',
onclick: () => {
isOpen(true);
}
}, 'Open Modal'),
Modal({
open: isOpen,
title: 'Basic Modal',
buttons: Button({
class: 'btn-primary',
onclick: () => {
isOpen(false);
}
}, 'Custom Action')
}, [
Div({ class: 'py-4' }, 'This is a basic modal dialog. Press ESC or click Close.')
])
]);
};
$mount(BasicDemo, '#demo-basic');
Modal with Actions
Live Demo
const ActionsDemo = () => {
const isOpen = $(false);
const confirmed = $(false);
const handleConfirm = () => {
confirmed(true);
isOpen(false);
Toast('Action confirmed!', 'alert-success', 2000);
};
return Div({ class: 'flex flex-col gap-4 items-center' }, [
Button({
class: 'btn btn-primary',
onclick: () => isOpen(true)
}, 'Confirm Action'),
() => confirmed() ? Alert({
type: 'success',
message: 'You confirmed the action!'
}) : null,
Modal({
open: isOpen,
title: 'Confirm Action',
buttons: [
Button({
class: 'btn btn-ghost',
onclick: () => isOpen(false)
}, 'Cancel'),
Button({
class: 'btn btn-primary',
onclick: handleConfirm
}, 'Confirm')
]
}, [
Div({ class: 'py-4' }, 'Are you sure you want to perform this action? This cannot be undone.')
])
]);
};
$mount(ActionsDemo, '#demo-actions');
Form Modal
Live Demo
const FormModal = () => {
const isOpen = $(false);
const name = $('');
const email = $('');
const submitted = $(false);
const handleSubmit = () => {
if (name() && email()) {
submitted(true);
isOpen(false);
Toast(`Welcome ${name()}!`, 'alert-success', 2000);
setTimeout(() => submitted(false), 3000);
}
};
return Div({ class: 'flex flex-col gap-4 items-center' }, [
Button({
class: 'btn btn-primary',
onclick: () => isOpen(true)
}, 'Sign Up'),
() => submitted() ? Alert({
type: 'success',
message: 'Account created successfully!'
}) : null,
Modal({
open: isOpen,
title: 'Create Account',
buttons: [
Button({
class: 'btn btn-ghost',
onclick: () => isOpen(false)
}, 'Cancel'),
Button({
class: 'btn btn-primary',
onclick: handleSubmit
}, 'Sign Up')
]
}, [
Div({ class: 'flex flex-col gap-4 py-2' }, [
Input({
label: 'Full Name',
value: name,
placeholder: 'Enter your name',
oninput: (e) => name(e.target.value)
}),
Input({
label: 'Email',
type: 'email',
value: email,
placeholder: 'Enter your email',
oninput: (e) => email(e.target.value)
})
])
])
]);
};
$mount(FormModal, '#demo-form');
Confirmation Modal
Live Demo
const ConfirmDemo = () => {
const isOpen = $(false);
const items = $([
{ id: 1, name: 'Document A' },
{ id: 2, name: 'Document B' },
{ id: 3, name: 'Document C' }
]);
const pendingDelete = $(null);
const confirmDelete = (item) => {
pendingDelete(item);
isOpen(true);
};
const handleDelete = () => {
items(items().filter(i => i.id !== pendingDelete().id));
isOpen(false);
Toast(`Deleted: ${pendingDelete().name}`, 'alert-info', 2000);
};
return Div({ class: 'flex flex-col gap-4' }, [
Div({ class: 'flex flex-col gap-2' }, items().map(item =>
Div({ class: 'flex justify-between items-center p-3 bg-base-200 rounded-lg' }, [
Span({}, item.name),
Button({
class: 'btn btn-xs btn-error',
onclick: () => confirmDelete(item)
}, 'Delete')
])
)),
Modal({
open: isOpen,
title: 'Delete Confirmation',
buttons: [
Button({
class: 'btn btn-ghost',
onclick: () => isOpen(false)
}, 'Cancel'),
Button({
class: 'btn btn-error',
onclick: handleDelete
}, 'Delete')
]
}, [
Div({ class: 'py-4' }, () => `Are you sure you want to delete "${pendingDelete()?.name}"? This action cannot be undone.`)
])
]);
};
$mount(ConfirmDemo, '#demo-confirm');
Large Content Modal
Live Demo
const LargeDemo = () => {
const isOpen = $(false);
return Div({ class: 'flex justify-center' }, [
Button({
class: 'btn btn-primary',
onclick: () => isOpen(true)
}, 'Open Large Modal'),
Modal({
open: isOpen,
title: 'Terms and Conditions',
buttons: Button({
class: 'btn btn-primary',
onclick: () => isOpen(false)
}, 'I Agree')
}, [
Div({ class: 'py-4 max-h-96 overflow-y-auto' }, [
Div({ class: 'space-y-4' }, [
Div({ class: 'text-sm' }, [
Div({ class: 'font-bold mb-2' }, '1. Introduction'),
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.'
]),
Div({ class: 'text-sm' }, [
Div({ class: 'font-bold mb-2' }, '2. User Obligations'),
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.'
]),
Div({ class: 'text-sm' }, [
Div({ class: 'font-bold mb-2' }, '3. Privacy Policy'),
'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.'
]),
Div({ class: 'text-sm' }, [
Div({ class: 'font-bold mb-2' }, '4. Termination'),
'At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores.'
])
])
])
])
]);
};
$mount(LargeDemo, '#demo-large');
Multiple Modals
Live Demo
const MultipleDemo = () => {
const modal1 = $(false);
const modal2 = $(false);
const modal3 = $(false);
return Div({ class: 'flex flex-wrap gap-4 justify-center' }, [
Button({ class: 'btn', onclick: () => modal1(true) }, 'Info Modal'),
Button({ class: 'btn', onclick: () => modal2(true) }, 'Success Modal'),
Button({ class: 'btn', onclick: () => modal3(true) }, 'Warning Modal'),
Modal({
open: modal1,
title: 'Information',
buttons: Button({ onclick: () => modal1(false) }, 'OK')
}, 'This is an informational message.'),
Modal({
open: modal2,
title: 'Success!',
buttons: Button({ onclick: () => modal2(false) }, 'Great!')
}, 'Your operation was completed successfully.'),
Modal({
open: modal3,
title: 'Warning',
buttons: Button({ onclick: () => modal3(false) }, 'Understood')
}, 'Please review your input before proceeding.')
]);
};
$mount(MultipleDemo, '#demo-multiple');
Custom Styled Modal
Live Demo
const CustomDemo = () => {
const isOpen = $(false);
return Div({ class: 'flex justify-center' }, [
Button({
class: 'btn btn-primary',
onclick: () => isOpen(true)
}, 'Open Custom Modal'),
Modal({
open: isOpen,
class: 'bg-gradient-to-r from-primary to-secondary text-primary-content'
}, [
Div({ class: 'text-center py-8' }, [
Div({ class: 'text-6xl mb-4' }, '🎉'),
Div({ class: 'text-2xl font-bold mb-2' }, 'Congratulations!'),
Div({ class: 'mb-6' }, 'You\'ve successfully completed the tutorial.'),
Button({
class: 'btn btn-ghost bg-white/20 hover:bg-white/30',
onclick: () => isOpen(false)
}, 'Get Started')
])
])
]);
};
$mount(CustomDemo, '#demo-custom');