PyWry Component Reference - MANDATORY SYNTAX
SkillMediaThese are the ONLY events that work for updating widgets. Use sendevent tool with these event types:
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the PyWry Component Reference - MANDATORY SYNTAX skill
About this capability
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.
What this skill tells your AI
The instructions your AI receives, as published by deeleeramone/pywry in pywry/pywry/mcp/skills/component_reference/SKILL.md and read by ahel’s review.
STOP. THIS IS THE AUTHORITATIVE REFERENCE FOR ALL COMPONENTS. YOU MUST USE THE EXACT EVENT SIGNATURES DOCUMENTED HERE. THERE ARE NO EXCEPTIONS. NO WORKAROUNDS. NO DEVIATIONS.
CRITICAL: System Events for Widget Updates
These are the ONLY events that work for updating widgets. Use send_event tool with these event types:
AG Grid Data Updates
| Event Type | Payload | Description |
|---|---|---|
grid:update-data | {"data": [...rows...], "strategy": "set"} | Replace all rows |
grid:update-data | {"data": [...rows...], "strategy": "append"} | Append rows |
grid:update-data | {"data": [...rows...], "strategy": "update"} | Update existing rows |
grid:update-columns | {"columnDefs": [...]} | Update column definitions |
grid:update-cell | {"rowId": "row-1", "colId": "price", "value": 99.50} | Update single cell |
AG Grid State Persistence
| Event Type | Payload | Description |
|---|---|---|
grid:request-state | {} | Request current grid state |
grid:request-state | {"gridId": "my-grid"} | Request specific grid's state |
grid:restore-state | {"state": {...savedState...}} | Restore saved grid state |
grid:reset-state | {"hard": false} | Soft reset (keeps column order) |
grid:reset-state | {"hard": true} | Hard reset (full reset) |
Response Event: grid:state-response with {"gridId": "...", "state": {...}}
State Object Contents:
- Column state (width, order, visibility, pinned, sort)
- Filter state (active filters per column)
- Sort state (sorted columns and direction)
Plotly Chart Updates
| Event Type | Payload | Description |
|---|---|---|
plotly:update-figure | {"data": [...], "layout": {...}} | Full figure update |
plotly:update-layout | {"layout": {...}} | Layout only update |
plotly:reset-zoom | {} | Reset chart zoom to original |
Plotly State Persistence
| Event Type | Payload | Description |
|---|---|---|
plotly:request-state | {} | Request current chart state |
plotly:request-state | {"chartId": "my-chart"} | Request specific chart's state |
Response Event: plotly:state-response with {"chartId": "...", "data": [...], "layout": {...}}
Plotly Data Export
| Event Type | Payload | Description |
|---|---|---|
plotly:export-data | {} | Export chart data |
plotly:export-data | {"chartId": "my-chart"} | Export specific chart's data |
Response Event: plotly:export-response with {"data": [{"traceIndex": 0, "name": "...", "x": [...], "y": [...], "type": "..."}]}
DOM Content Updates
| Event Type | Payload | Description |
|---|---|---|
pywry:set-content | {"id": "elementId", "text": "..."} | Set text content |
pywry:set-content | {"id": "elementId", "html": "..."} | Set HTML content |
pywry:set-style | {"id": "elementId", "styles": {"color": "red"}} | Update CSS styles |
Theme Updates
| Event Type | Payload | Description |
|---|---|---|
pywry:update-theme | {"theme": "dark"} | Switch theme (dark/light/system) |
pywry:update-theme | {"theme": "ag-theme-alpine-dark"} | AG Grid theme |
pywry:update-theme | {"theme": "plotly_dark"} | Plotly template |
Toast Notifications
Use show_toast tool instead, or:
| Event Type | Payload | Description |
|---|---|---|
pywry:alert | {"message": "...", "type": "info"} | info, success, warning, error |
Toolbar Component State (Get/Set Values)
| Event Type | Payload | Description |
|---|---|---|
toolbar:set-value | {"componentId": "my-select", "value": "option2"} | Set single component value |
toolbar:set-values | {"values": {"select-1": "A", "toggle-1": true}} | Set multiple values at once |
toolbar:request-state | {"componentId": "my-input"} | Request single component value |
toolbar:request-state | {"toolbarId": "top-toolbar"} | Request all values in toolbar |
toolbar:request-state | {} | Request all toolbar values |
Response Event: toolbar:state-response with {"componentId": "...", "value": ...} or {"values": {...}}
Supported Components for set-value:
select:{"componentId": "id", "value": "option-value"}multiselect:{"componentId": "id", "value": ["a", "b"]}toggle:{"componentId": "id", "value": true}checkbox:{"componentId": "id", "value": true}text/textarea/search:{"componentId": "id", "value": "text"}number:{"componentId": "id", "value": 42}slider:{"componentId": "id", "value": 50}range:{"componentId": "id", "value": {"start": 10, "end": 90}}tabs/radio:{"componentId": "id", "value": "tab-value"}
Note: secret inputs cannot be set via toolbar:set-value for security.
Table of Contents
- Button
- Select
- MultiSelect
- Toggle
- Checkbox
- RadioGroup
- TabGroup
- TextInput
- TextArea
- SearchInput
- NumberInput
- DateInput
- SliderInput
- RangeInput
- SecretInput
- Div
- Marquee
- TickerItem
Button
A clickable button that emits an event.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "button" | ✅ YES | - | Component type identifier |
label | string | ✅ YES | - | Button text |
event | string | ✅ YES | - | Event name (format: namespace:action) |
variant | string | ❌ | "primary" | Style: primary, secondary, neutral, ghost, outline, danger, warning, icon |
size | string | ❌ | null | Size: xs, sm, lg, xl |
data | object | ❌ | {} | Extra data payload sent with event |
disabled | boolean | ❌ | false | Disable the button |
description | string | ❌ | "" | Tooltip on hover |
Event Emitted
{
componentId: "button-abc123", // Auto-generated component ID
...data // Your custom data object spread in
}
Auto-Wired Actions
When event follows elementId:action pattern, these actions work automatically:
| Event Pattern | Behavior |
|---|---|
myId:increment | Finds id="myId", parses as number, adds 1 |
myId:decrement | Finds id="myId", parses as number, subtracts 1 |
myId:reset | Finds id="myId", sets to 0 |
myId:toggle | Finds id="myId", toggles true/false |
Example
{
"type": "button",
"label": "Submit",
"event": "form:submit",
"variant": "primary",
"data": {"formId": "contact"}
}
Select
A single-select dropdown.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "select" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name (format: namespace:action) |
options | array | ✅ YES | - | Array of {label, value} objects |
selected | string | ❌ | "" | Initially selected value |
label | string | ❌ | "" | Label text |
searchable | boolean | ❌ | false | Enable search filtering |
disabled | boolean | ❌ | false | Disable the dropdown |
Event Emitted
{
value: "selected_value", // The selected option's value
componentId: "select-abc123"
}
Example
{
"type": "select",
"label": "Theme:",
"event": "theme:change",
"options": [
{"label": "Dark", "value": "dark"},
{"label": "Light", "value": "light"},
{"label": "System", "value": "system"}
],
"selected": "dark"
}
MultiSelect
A multi-select dropdown with checkboxes.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "multiselect" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
options | array | ✅ YES | - | Array of {label, value} objects |
selected | array | ❌ | [] | Initially selected values |
label | string | ❌ | "" | Label text |
disabled | boolean | ❌ | false | Disable the dropdown |
Event Emitted
{
values: ["value1", "value2"], // Array of selected values
componentId: "multiselect-abc123"
}
Example
{
"type": "multiselect",
"label": "Columns:",
"event": "columns:filter",
"options": [
{"label": "Name", "value": "name"},
{"label": "Age", "value": "age"},
{"label": "City", "value": "city"}
],
"selected": ["name", "age"]
}
Toggle
A toggle switch for boolean values.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "toggle" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | boolean | ❌ | false | Initial state |
label | string | ❌ | "" | Label text |
disabled | boolean | ❌ | false | Disable the toggle |
Event Emitted
{
value: true, // Boolean: true or false
componentId: "toggle-abc123"
}
Example
{
"type": "toggle",
"label": "Dark Mode:",
"event": "theme:toggle",
"value": true
}
Checkbox
A single checkbox for boolean values.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "checkbox" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | boolean | ❌ | false | Initial checked state |
label | string | ✅ YES | - | Label text (displayed next to checkbox) |
disabled | boolean | ❌ | false | Disable the checkbox |
Event Emitted
{
value: true, // Boolean: true or false
componentId: "checkbox-abc123"
}
Example
{
"type": "checkbox",
"label": "Enable notifications",
"event": "settings:notify",
"value": true
}
RadioGroup
A group of radio buttons for single selection.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "radio" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
options | array | ✅ YES | - | Array of {label, value} objects |
selected | string | ❌ | "" | Initially selected value |
label | string | ❌ | "" | Group label |
direction | string | ❌ | "horizontal" | Layout: horizontal or vertical |
disabled | boolean | ❌ | false | Disable all radios |
Event Emitted
{
value: "selected_value", // The selected option's value
componentId: "radio-abc123"
}
Example
{
"type": "radio",
"label": "View:",
"event": "view:change",
"options": [
{"label": "List", "value": "list"},
{"label": "Grid", "value": "grid"},
{"label": "Card", "value": "card"}
],
"selected": "list",
"direction": "horizontal"
}
TabGroup
Tab-style buttons for single selection (visually different from RadioGroup).
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "tabs" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
options | array | ✅ YES | - | Array of {label, value} objects |
selected | string | ❌ | "" | Initially selected value |
label | string | ❌ | "" | Group label |
size | string | ❌ | "md" | Size: sm, md, lg |
disabled | boolean | ❌ | false | Disable all tabs |
Event Emitted
{
value: "selected_value", // The selected tab's value
componentId: "tab-abc123"
}
Example
{
"type": "tabs",
"label": "Mode:",
"event": "mode:switch",
"options": [
{"label": "Edit", "value": "edit"},
{"label": "Preview", "value": "preview"},
{"label": "Split", "value": "split"}
],
"selected": "edit"
}
TextInput
A single-line text input with debounced events.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "text" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | string | ❌ | "" | Initial value |
placeholder | string | ❌ | "" | Placeholder text |
label | string | ❌ | "" | Label text |
debounce | integer | ❌ | 300 | Debounce milliseconds |
disabled | boolean | ❌ | false | Disable the input |
Event Emitted
{
value: "user typed text", // The current input value
componentId: "text-abc123"
}
Example
{
"type": "text",
"label": "Name:",
"event": "form:name",
"placeholder": "Enter your name",
"debounce": 300
}
TextArea
A multi-line text area with resizing.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "textarea" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | string | ❌ | "" | Initial value |
placeholder | string | ❌ | "" | Placeholder text |
label | string | ❌ | "" | Label text |
rows | integer | ❌ | 3 | Number of visible rows |
cols | integer | ❌ | 40 | Number of visible columns |
resize | string | ❌ | "both" | Resize: both, horizontal, vertical, none |
debounce | integer | ❌ | 300 | Debounce milliseconds |
disabled | boolean | ❌ | false | Disable the textarea |
Event Emitted
{
value: "multi-line\ntext content", // The textarea content
componentId: "textarea-abc123"
}
Example
{
"type": "textarea",
"label": "Notes:",
"event": "form:notes",
"placeholder": "Enter your notes...",
"rows": 5,
"resize": "vertical"
}
SearchInput
A search input with magnifying glass icon.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "search" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | string | ❌ | "" | Initial value |
placeholder | string | ❌ | "Search..." | Placeholder text |
label | string | ❌ | "" | Label text |
debounce | integer | ❌ | 300 | Debounce milliseconds |
disabled | boolean | ❌ | false | Disable the input |
Event Emitted
{
value: "search query", // The search text
componentId: "search-abc123"
}
Example
{
"type": "search",
"label": "Filter:",
"event": "table:filter",
"placeholder": "Type to filter...",
"debounce": 200
}
NumberInput
A numeric input with optional constraints.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "number" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | number | ❌ | null | Initial value |
min | number | ❌ | null | Minimum value |
max | number | ❌ | null | Maximum value |
step | number | ❌ | null | Step increment |
label | string | ❌ | "" | Label text |
disabled | boolean | ❌ | false | Disable the input |
Event Emitted
{
value: 42, // The numeric value
componentId: "number-abc123"
}
Example
{
"type": "number",
"label": "Quantity:",
"event": "cart:quantity",
"value": 1,
"min": 1,
"max": 100,
"step": 1
}
DateInput
A date picker input.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "date" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | string | ❌ | "" | Initial date (YYYY-MM-DD) |
min | string | ❌ | "" | Minimum date (YYYY-MM-DD) |
max | string | ❌ | "" | Maximum date (YYYY-MM-DD) |
label | string | ❌ | "" | Label text |
disabled | boolean | ❌ | false | Disable the input |
Event Emitted
{
value: "2025-01-29", // Date string in YYYY-MM-DD format
componentId: "date-abc123"
}
Example
{
"type": "date",
"label": "Start Date:",
"event": "filter:startDate",
"value": "2025-01-01",
"min": "2020-01-01",
"max": "2030-12-31"
}
SliderInput
A single-value slider.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "slider" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | number | ❌ | 50 | Initial value |
min | number | ❌ | 0 | Minimum value |
max | number | ❌ | 100 | Maximum value |
step | number | ❌ | 1 | Step increment |
show_value | boolean | ❌ | true | Show value display |
debounce | integer | ❌ | 50 | Debounce milliseconds |
label | string | ❌ | "" | Label text |
disabled | boolean | ❌ | false | Disable the slider |
Event Emitted
{
value: 75, // The slider value
componentId: "slider-abc123"
}
Example
{
"type": "slider",
"label": "Volume:",
"event": "audio:volume",
"value": 50,
"min": 0,
"max": 100,
"step": 5,
"show_value": true
}
RangeInput
A dual-handle range slider for min/max selection.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "range" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
start | number | ❌ | 0 | Initial start value |
end | number | ❌ | 100 | Initial end value |
min | number | ❌ | 0 | Minimum value |
max | number | ❌ | 100 | Maximum value |
step | number | ❌ | 1 | Step increment |
show_value | boolean | ❌ | true | Show value displays |
debounce | integer | ❌ | 50 | Debounce milliseconds |
label | string | ❌ | "" | Label text |
disabled | boolean | ❌ | false | Disable the slider |
Event Emitted
{
start: 25, // Start/min value
end: 75, // End/max value
componentId: "range-abc123"
}
Example
{
"type": "range",
"label": "Price Range:",
"event": "filter:price",
"start": 100,
"end": 500,
"min": 0,
"max": 1000,
"step": 10,
"show_value": true
}
SecretInput
A password/secret input with visibility toggle and copy button.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "secret" | ✅ YES | - | Component type identifier |
event | string | ✅ YES | - | Event name |
value | string | ❌ | "" | Initial secret value (stored securely) |
placeholder | string | ❌ | "" | Placeholder text |
label | string | ❌ | "" | Label text |
show_toggle | boolean | ❌ | true | Show visibility toggle button |
show_copy | boolean | ❌ | true | Show copy button |
debounce | integer | ❌ | 300 | Debounce milliseconds |
disabled | boolean | ❌ | false | Disable the input |
Events Emitted
On value change:
{
value: "base64_encoded_value", // Base64 encoded secret
encoded: true,
componentId: "secret-abc123"
}
On reveal request: (event: {event}:reveal)
{
componentId: "secret-abc123"
}
On copy request: (event: {event}:copy)
{
componentId: "secret-abc123"
}
Example
{
"type": "secret",
"label": "API Key:",
"event": "settings:apiKey",
"placeholder": "Enter your API key",
"show_toggle": true,
"show_copy": true
}
Div
A container for custom HTML content.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "div" | ✅ YES | - | Component type identifier |
content | string | ✅ YES | - | HTML content |
component_id | string | ❌ | auto | ID for updates via set_content |
class_name | string | ❌ | "" | CSS class name |
style | string | ❌ | "" | Inline CSS styles |
children | array | ❌ | null | Nested toolbar items |
Event Emitted
No automatic events. Use for layout/display only, or add interactive children.
Example
{
"type": "div",
"content": "<span style=\"color: green\">Online</span>",
"component_id": "status-display",
"style": "padding: 8px; font-weight: bold"
}
Marquee
A scrolling text ticker component.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | "marquee" | ✅ YES | - | Component type identifier |
text | string | ✅ YES | - | Scrolling text content |
event | string | ❌ | - | Event name (if clickable) |
speed | number | ❌ | 15 | Seconds per scroll cycle (1-300) |
direction | string | ❌ | "left" | Direction: left, right, up, down |
behavior | string | ❌ | "scroll" | Behavior: scroll, alternate, slide, static |
pause_on_hover | boolean | ❌ | true | Pause on mouse hover |
gap | integer | ❌ | 50 | Gap between content (pixels) |
clickable | boolean | ❌ | false | Emit event on click |
separator | string | ❌ | "" | Separator between repeats |
component_id | string | ❌ | auto | ID for updates |
Event Emitted (when clickable)
{
value: "the marquee text", // The text content
componentId: "marquee-abc123"
}
Update Events
Use set_content or update_marquee tools to update:
// Update text
{id: "marquee-abc123", text: "New content!"}
// Update speed
{id: "marquee-abc123", speed: 10}
// Pause/resume
{id: "marquee-abc123", paused: true}
Example
{
"type": "marquee",
"text": "Breaking News: Market is up 5% • Weather: Sunny • More updates...",
"speed": 20,
"direction": "left",
"pause_on_hover": true,
"clickable": true,
"event": "news:click"
}
TickerItem
A helper for creating updatable items within a Marquee.
Note: TickerItem is used with build_ticker_item tool, not as a direct toolbar item.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
ticker | string | ✅ YES | - | Unique identifier (e.g., "AAPL") |
text | string | ❌ | "" | Text content |
html | string | ❌ | "" | HTML content (overrides text) |
class_name | string | ❌ | "" | CSS classes |
style | string | ❌ | "" | Inline styles |
Update via update_ticker_item
{
ticker: "AAPL",
text: "AAPL $186.25 ▲",
styles: {color: "#22c55e"},
class_add: "stock-up",
class_remove: "stock-down"
}
Example
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 93
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
component-reference- Source
- github.com/deeleeramone/pywry