Skip to content
Development
Skill

/modals

**STOP. READ THIS ENTIRE FILE BEFORE CREATING MODALS.**

From plugin
pywry
9318 skills1 agent2 commands1 MCP
Install
$ npx -y skills add deeleeramone/PyWry --skill modals --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/modals

Context preview

The summary Claude sees to decide when to auto-load this skill.

**STOP. READ THIS ENTIRE FILE BEFORE CREATING MODALS.**

SKILL.md

modals.SKILL.md

Modals - MANDATORY PATTERN

> **STOP. READ THIS ENTIRE FILE BEFORE CREATING MODALS.**

Overview

Modals are reusable overlay dialogs that can contain any content - forms, confirmations, information panels, or custom HTML. They follow the same pattern as toolbars, passed to `.show-*` functions.

The ONLY Correct Way to Create Modals

Copy this EXACTLY. Do not deviate.

from pywry import Modal, show_plotly

fig = go.Figure(...)

widget = show_plotly(
    fig,
    modals=[
        Modal(
            component_id="settings-modal",
            title="Settings",
            items=["<p>Configure your preferences here.</p>"],
            size="medium",
        )
    ],
    toolbars=[{
        "position": "top",
        "items": [
            {"type": "button", "label": "Open Settings", "event": "modal:open:settings-modal"}
        ]
    }]
)

**THAT'S IT.** Button click opens the modal automatically.

---

Modal Schema

| Property | Type | Required | Default | Description | |----------|------|----------|---------|-------------| | `component_id` | `str` | **YES** | - | Unique identifier for the modal | | `title` | `str` | no | `""` | Modal header title | | `items` | `list[str]` | no | `[]` | HTML content strings | | `size` | `str` | no | `"medium"` | `"small"`, `"medium"`, `"large"`, `"fullscreen"` | | `width` | `str` | no | `None` | Custom width (e.g., `"600px"`, `"80%"`) | | `max_height` | `str` | no | `None` | Custom max-height (e.g., `"400px"`) | | `overlay_opacity` | `float` | no | `0.5` | Backdrop opacity (0.0-1.0) | | `close_on_escape` | `bool` | no | `True` | Close when Escape key pressed | | `close_on_overlay_click` | `bool` | no | `True` | Close when clicking outside modal | | `reset_on_close` | `bool` | no | `True` | Reset form inputs when closed | | `on_close_event` | `str` | no | `None` | Event to emit when modal closes | | `open_on_load` | `bool` | no | `False` | Open modal immediately on page load | | `style` | `str` | no | `""` | Additional CSS for this modal | | `script` | `str` | no | `""` | Additional JavaScript for this modal | | `class_name` | `str` | no | `""` | Additional CSS classes |

---

Size Presets

| Size | Width | Use Case | |------|-------|----------| | `small` | 320px | Confirmations, alerts | | `medium` | 500px | Forms, settings (default) | | `large` | 720px | Complex forms, tables | | `fullscreen` | 95vw / 95vh | Data grids, large content |

---

Modal Events

These are the ONLY events that work with modals:

Opening and Closing

| Event Type | Description | |------------|-------------| | `modal:open:<component_id>` | Opens the modal | | `modal:close:<component_id>` | Closes the modal | | `modal:toggle:<component_id>` | Toggles open/closed state |

Example: Button to Open Modal

toolbars=[{
    "position": "top",
    "items": [
        {"type": "button", "label": "Settings", "event": "modal:open:settings-modal"}
    ]
}]

Example: Button Inside Modal to Close

Modal(
    component_id="confirm-modal",
    title="Confirm Action",
    items=[
        "<p>Are you sure?</p>",
        '<button onclick="window.pywry.modal.close(\'confirm-modal\')">Cancel</button>',
        '<button onclick="doAction()">Confirm</button>',
    ]
)

---

Built-in Close Behaviors

1. **X Button**: Every modal has a close button in the top-right corner 2. **Escape Key**: Press Escape to close (unless `close_on_escape=False`) 3. **Overlay Click**: Click outside modal to close (unless `close_on_overlay_click=False`)

---

reset_on_close Behavior

When `reset_on_close=True` (default):

  • All `<input>`, `<textarea>`, `<select>` elements are reset to their initial values
  • Form state is cleared when modal closes
  • Next open shows fresh form

When `reset_on_close=False`:

  • Form values persist between opens
  • User can resume where they left off

---

JavaScript API

Access modal functions via `window.pywry.modal`:

// Open a modal
window.pywry.modal.open('my-modal');

// Close a modal  
window.pywry.modal.close('my-modal');

// Toggle a modal
window.pywry.modal.toggle('my-modal');

// Check if modal is open
const isOpen = window.pywry.modal.isOpen('my-modal');

---

Complete Examples

1. Settings Modal with Form

from pywry import Modal, show_plotly

widget = show_plotly(
    fig,
    modals=[
        Modal(
            component_id="settings",
            title="Chart Settings",
            items=[
                '<form id="settings-form">',
                '  <label>Title: <input type="text" name="title" value="My Chart"></label>',
                '  <label>Theme: <select name="theme">',
                '    <option value="dark">Dark</option>',
                '    <option value="light">Light</option>',
                '  </select></label>',
                '  <button type="button" onclick="applySettings()">Apply</button>',
                '</form>',
            ],
            size="medium",
            reset_on_close=False,  # Keep form values
        )
    ],
    toolbars=[{
        "position": "top",
        "items": [
            {"type": "button", "label": "⚙️ Settings", "event": "modal:open:settings"}
        ]
    }]
)

2. Confirmation Dialog

Modal(
    component_id="delete-confirm",
    title="Delete Item",
    items=[
        '<p>Are you sure you want to delete this item?</p>',
        '<p style="color: var(--pywry-text-danger);">This action cannot be undone.</p>',
        '<div class="pywry-modal-footer">',
        '  <button onclick="window.pywry.modal.close(\'delete-confirm\')">Cancel</button>',
        '  <button onclick="confirmDelete()" class="danger">Delete</button>',
        '</div>',
    ],
    size="small",
    close_on_overlay_click=False,  # Force user to click a button
)

3. Modal with Custom Styling

Modal(
    component_id="custom-modal",
    title="Styled Modal",
    items=["<p>Custom styled content</p>"],
    style="""
Read more
Ships withpywry

PyWry is a cross-platform app factory, rendering engine and UI toolkit for Python that produces native desktop, web, and notebook experiences from a single API.

Get the whole plugin

Other skills on pywry.