# Component Reference

> A Claude skill from deeleeramone/PyWry.

- **Type:** Skill
- **Install:** `agentstack add skill-deeleeramone-pywry-component-reference`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [deeleeramone](https://agentstack.voostack.com/s/deeleeramone)
- **Installs:** 0
- **Category:** [Data & Analytics](https://agentstack.voostack.com/c/data-and-analytics)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [deeleeramone](https://github.com/deeleeramone)
- **Source:** https://github.com/deeleeramone/PyWry/tree/develop/pywry/pywry/mcp/skills/component_reference
- **Website:** https://deeleeramone.github.io/PyWry/

## Install

```sh
agentstack add skill-deeleeramone-pywry-component-reference
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# PyWry Component Reference - MANDATORY SYNTAX

> **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

1. [Button](#button)
2. [Select](#select)
3. [MultiSelect](#multiselect)
4. [Toggle](#toggle)
5. [Checkbox](#checkbox)
6. [RadioGroup](#radiogroup)
7. [TabGroup](#tabgroup)
8. [TextInput](#textinput)
9. [TextArea](#textarea)
10. [SearchInput](#searchinput)
11. [NumberInput](#numberinput)
12. [DateInput](#dateinput)
13. [SliderInput](#sliderinput)
14. [RangeInput](#rangeinput)
15. [SecretInput](#secretinput)
16. [Div](#div)
17. [Marquee](#marquee)
18. [TickerItem](#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

```javascript
{
  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

```json
{
  "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

```javascript
{
  value: "selected_value",        // The selected option's value
  componentId: "select-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  values: ["value1", "value2"],   // Array of selected values
  componentId: "multiselect-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: true,                    // Boolean: true or false
  componentId: "toggle-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: true,                    // Boolean: true or false
  componentId: "checkbox-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: "selected_value",        // The selected option's value
  componentId: "radio-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: "selected_value",        // The selected tab's value
  componentId: "tab-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: "user typed text",       // The current input value
  componentId: "text-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: "multi-line\ntext content",  // The textarea content
  componentId: "textarea-abc123"
}
```

### Example

```json
{
  "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

```javascript
{
  value: "search query",          // The search text
  componentId: "search-abc123"
}
```

### Example

```json
{
  "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 |
| `disabl

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [deeleeramone](https://github.com/deeleeramone)
- **Source:** [deeleeramone/PyWry](https://github.com/deeleeramone/PyWry)
- **License:** Apache-2.0
- **Homepage:** https://deeleeramone.github.io/PyWry/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-deeleeramone-pywry-component-reference
- Seller: https://agentstack.voostack.com/s/deeleeramone
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
