Overlay Components
Modal, Tooltip, Dropdown
Overlay Components
Components that appear above other content.
Modal
Dialog window for focused content or actions.
json
{
"type": "Modal",
"id": "confirm-modal",
"title": "Confirm Action",
"description": "Are you sure you want to continue?",
"content": {
"type": "Text",
"content": "This action cannot be undone."
},
"footer": {
"type": "Flex",
"justify": "end",
"gap": "0.5rem",
"children": [
{
"type": "Button",
"label": "Cancel",
"variant": "outline",
"events": {
"on_click": [{ "type": "close_dialog", "dialogId": "confirm-modal" }]
}
},
{
"type": "Button",
"label": "Confirm",
"events": {
"on_click": [
{ "type": "call_api", "api": "confirmAction" },
{ "type": "close_dialog", "dialogId": "confirm-modal" }
]
}
}
]
},
"events": {
"on_close": [{ "type": "update_state", "path": "modalData", "value": null }]
}
} Properties
| Property | Type | Default | Description |
|---|---|---|---|
id | string | - | Modal identifier (required) |
title | string | - | Modal title |
description | string | - | Subtitle/description |
content | object | - | Modal body content (required) |
footer | object | - | Modal footer content |
size | sm | md | lg | xl | full | md | Modal size |
closable | boolean | true | Show close button |
className | string | - | CSS classes |
events | object | - | Event handlers |
Events
| Event | Trigger |
|---|---|
on_close | Modal close requested |
on_open | Modal opened |
Sizes
| Size | Width |
|---|---|
sm | 400px |
md | 500px |
lg | 640px |
xl | 800px |
full | Full screen |
Opening Modals
Use the show_dialog action to open a modal:
json
{
"type": "Button",
"label": "Open Modal",
"events": {
"on_click": [
{ "type": "show_dialog", "dialogId": "my-modal" }
]
}
} Closing Modals
Use the close_dialog action:
json
{
"type": "Button",
"label": "Close",
"events": {
"on_click": [
{ "type": "close_dialog", "dialogId": "my-modal" }
]
}
} Examples
Confirmation dialog:
json
{
"type": "Button",
"label": "Delete Item",
"variant": "destructive",
"events": {
"on_click": [
{ "type": "show_dialog", "dialogId": "delete-modal" }
]
}
} json
{
"type": "Modal",
"id": "delete-modal",
"title": "Delete Item?",
"description": "This action cannot be undone.",
"content": {
"type": "Alert",
"variant": "destructive",
"message": "The item '{{state.itemToDelete.name}}' will be permanently deleted."
},
"footer": {
"type": "Flex",
"justify": "end",
"gap": "0.5rem",
"children": [
{
"type": "Button",
"label": "Cancel",
"variant": "outline",
"events": {
"on_click": [{ "type": "close_dialog", "dialogId": "delete-modal" }]
}
},
{
"type": "Button",
"label": "Delete",
"variant": "destructive",
"events": {
"on_click": [
{ "type": "call_api", "api": "deleteItem", "body": { "id": "{{state.itemToDelete.id}}" } },
{ "type": "close_dialog", "dialogId": "delete-modal" },
{ "type": "show_toast", "message": "Item deleted", "level": "success" }
]
}
}
]
}
} Form modal:
json
{
"type": "Modal",
"id": "edit-profile-modal",
"title": "Edit Profile",
"size": "lg",
"content": {
"type": "Form",
"id": "edit-profile",
"fields": [
{
"name": "name",
"fieldType": "text",
"label": "Display Name",
"bindTo": "editForm.name",
"validation": { "required": { "message": "Name is required" } }
},
{
"name": "bio",
"fieldType": "textarea",
"label": "Bio",
"bindTo": "editForm.bio"
}
],
"events": {
"on_submit": [
{ "type": "call_api", "api": "updateProfile", "body": "{{state.editForm}}" },
{ "type": "close_dialog", "dialogId": "edit-profile-modal" },
{ "type": "show_toast", "message": "Profile updated", "level": "success" }
]
}
}
} Full-screen modal:
json
{
"type": "Modal",
"id": "preview-modal",
"size": "full",
"title": "Document Preview",
"content": {
"type": "Container",
"className": "h-[80vh] overflow-auto",
"children": [
{ "type": "Image", "src": "{{state.previewUrl}}", "className": "w-full" }
]
}
} Tooltip
Informational popup on hover.
json
{
"type": "Tooltip",
"content": "This is helpful information",
"children": {
"type": "Button",
"icon": "HelpCircle",
"variant": "ghost",
"size": "icon"
}
} Properties
| Property | Type | Default | Description |
|---|---|---|---|
content | string | - | Tooltip content (required) |
children | object | - | Trigger component (required) |
side | top | bottom | left | right | top | Tooltip position |
delayMs | number | 200 | Show delay (ms) |
className | string | - | CSS classes |
Examples
Simple tooltip:
json
{
"type": "Tooltip",
"content": "Click to edit",
"children": {
"type": "Button",
"icon": "Edit",
"variant": "ghost",
"size": "icon"
}
} On icon:
json
{
"type": "Flex",
"align": "center",
"gap": "0.5rem",
"children": [
{ "type": "Text", "content": "API Rate Limit" },
{
"type": "Tooltip",
"content": "Maximum 100 requests per minute",
"side": "right",
"children": {
"type": "Icon",
"name": "Info",
"size": "sm"
}
}
]
} Different positions:
json
{
"type": "Flex",
"gap": "1rem",
"children": [
{
"type": "Tooltip",
"content": "Above",
"side": "top",
"children": { "type": "Button", "label": "Top" }
},
{
"type": "Tooltip",
"content": "Below",
"side": "bottom",
"children": { "type": "Button", "label": "Bottom" }
},
{
"type": "Tooltip",
"content": "Left side",
"side": "left",
"children": { "type": "Button", "label": "Left" }
},
{
"type": "Tooltip",
"content": "Right side",
"side": "right",
"children": { "type": "Button", "label": "Right" }
}
]
} On disabled button:
json
{
"type": "Tooltip",
"content": "You need admin permissions to perform this action",
"children": {
"type": "Container",
"children": [
{
"type": "Button",
"label": "Delete All",
"variant": "destructive",
"disabled": true
}
]
}
} Overlay Patterns
Modal with Loading State
json
{
"type": "Modal",
"id": "processing-modal",
"title": "Processing",
"closable": false,
"content": {
"type": "Flex",
"direction": "column",
"align": "center",
"gap": "1rem",
"className": "py-4",
"children": [
{ "type": "Progress", "value": "{{state.progress}}", "showLabel": true },
{ "type": "Text", "content": "Please wait while we process your request..." }
]
}
} Cascading Modals
json
{
"type": "Modal",
"id": "select-item-modal",
"title": "Select Item",
"content": {
"type": "Container",
"children": [
{ "type": "List", "dataSource": "state:items" },
{
"type": "Button",
"label": "Create New",
"events": {
"on_click": [
{ "type": "show_dialog", "dialogId": "create-item-modal" }
]
}
}
]
}
} json
{
"type": "Modal",
"id": "create-item-modal",
"title": "Create Item",
"content": {
"type": "Form",
"id": "create-form",
"fields": [
{
"name": "name",
"fieldType": "text",
"label": "Name",
"bindTo": "newItem.name"
}
],
"events": {
"on_submit": [
{ "type": "call_api", "api": "createItem", "body": "{{state.newItem}}" },
{ "type": "close_dialog", "dialogId": "create-item-modal" },
{ "type": "close_dialog", "dialogId": "select-item-modal" }
]
}
}
} Tooltip on Table Cell
json
{
"type": "Table",
"dataSource": "state:items",
"columns": [
{ "key": "name", "label": "Name" },
{
"key": "status",
"label": "Status",
"render": {
"type": "Tooltip",
"content": "{{$row.statusDetails}}",
"children": {
"type": "Badge",
"text": "{{$cell}}",
"variant": "{{$cell === 'active' ? 'success' : 'secondary'}}"
}
}
}
]
} Confirmation Pattern
json
{
"type": "Button",
"label": "Delete All",
"variant": "destructive",
"events": {
"on_click": [
{
"type": "conditional",
"condition": "{{state.items.length}} > 0",
"then": [
{ "type": "show_dialog", "dialogId": "confirm-delete-all" }
],
"elseActions": [
{ "type": "show_toast", "message": "No items to delete", "level": "info" }
]
}
]
}
}