Overlay Components

Modal, Tooltip, Dropdown

Overlay Components

Components that appear above other content.

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

PropertyTypeDefaultDescription
idstring-Modal identifier (required)
titlestring-Modal title
descriptionstring-Subtitle/description
contentobject-Modal body content (required)
footerobject-Modal footer content
sizesm | md | lg | xl | fullmdModal size
closablebooleantrueShow close button
classNamestring-CSS classes
eventsobject-Event handlers

Events

EventTrigger
on_closeModal close requested
on_openModal opened

Sizes

SizeWidth
sm400px
md500px
lg640px
xl800px
fullFull 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

PropertyTypeDefaultDescription
contentstring-Tooltip content (required)
childrenobject-Trigger component (required)
sidetop | bottom | left | righttopTooltip position
delayMsnumber200Show delay (ms)
classNamestring-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

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" }
        ]
      }
    ]
  }
}