Skip to main content
ClaudeWave
Skill1.7k estrellas del repoactualizado today

inline-widget

The inline-widget skill renders interactive HTML/SVG visualizations directly within chat conversations using the ShowWidget function, displaying charts, data tables, dashboards, and metric cards without requiring external sandboxes or preview URLs. Use this when users need quick, self-contained visualizations with embedded data and interactive elements like buttons or animated graphics, rather than complex multi-page applications that require server-side functionality.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/ginlix-ai/LangAlpha /tmp/inline-widget && cp -r /tmp/inline-widget/plugins/langalpha_deliverables/skills/inline-widget ~/.claude/skills/inline-widget
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Inline Widget

Render interactive HTML/SVG widgets directly inside the chat conversation using `ShowWidget`. Widgets appear inline between text — no sandbox, no preview URL, no side panel. They run JavaScript, so lean into making them **interactive and explorable** where it helps — something the user can sort, filter, toggle, and hover over, not just a static picture.

## When to Use

- User wants a **quick visualization** embedded in the conversation (chart, metric card, data table)
- The visualization is **self-contained** — all data is embedded in the HTML, no server needed
- User wants **interactivity** within the chat: buttons, toggles, hover effects, animated charts
- The output is a **single view** — not a multi-page app or dashboard that needs routing

**Use `interactive-dashboard` instead if:** User needs a multi-page web app, server-side data, live data refresh, or complex interactivity requiring React/FastAPI.

Read `.agents/skills/ui-design/SKILL.md` for design quality — its color discipline, chart restraint, and anti-slop principles apply here too. Its font pairings and type scale, though, are for full documents; a widget sits on the chat surface, so use the host-font typography rules below instead.

## ShowWidget API

```
ShowWidget(html: str, title: str | None = None, data_files: list[str] | None = None)
```

- `html`: Raw HTML fragment — no `<!DOCTYPE>`, `<html>`, `<head>`, or `<body>` tags
- `title`: Optional metadata (not displayed to user)
- `data_files`: Optional list of sandbox file paths to make available as `window.__WIDGET_DATA__`

The HTML is rendered in a sandboxed iframe with:
- **CDN libraries**: `cdnjs.cloudflare.com`, `cdn.jsdelivr.net`, `unpkg.com`, `esm.sh`
- **CSS theme variables**: automatically injected (see Theme section)
- **`sendPrompt('text')`**: global function to trigger follow-up chat messages
- **`window.__WIDGET_DATA__`**: dict of filename→content for files passed via `data_files`
- **No network to non-CDN origins**: `fetch()` / `XMLHttpRequest` to arbitrary URLs are blocked by CSP — only CDN domains (cdnjs, jsdelivr, unpkg, esm.sh) are allowed. Use `data_files` for sandbox files, or embed small data directly in HTML

## Layout Rules (CRITICAL)

The widget sits directly on the chat surface inside a transparent iframe. Follow these rules for seamless integration:

### Outer Element — Transparent Shell

The **outermost HTML element** must have:
- **NO background** (or `background: transparent`)
- **NO border**
- **NO border-radius**
- **NO box-shadow**
- **NO padding** — add padding on inner sections only

```html
<!-- CORRECT: transparent outer shell -->
<div>
  <div style="background: var(--color-bg-card, #ffffff); border-radius: 8px; padding: 16px; ...">
    ...inner card content...
  </div>
</div>

<!-- WRONG: styled outer wrapper — will be rejected -->
<div style="background: var(--color-bg-page); border: 1px solid ...; border-radius: 8px; padding: 20px;">
  ...content...
</div>
```

### Inner Elements — Use Theme Variables

Inner cards, sections, and components should use CSS variables for styling, always in the fallback form:

```css
/* Card */
background: var(--color-bg-card, #ffffff);
border: 0.5px solid var(--color-border-muted, #e4e1dc);
border-radius: 8px;
padding: 16px;

/* Metric card */
background: var(--color-bg-subtle, #f4f2ee);
border: 0.5px solid var(--color-border-muted, #e4e1dc);
border-radius: 8px;
```

In chat the variables are always injected, so the fallback never shows there — it is what renders when the widget is saved as a workspace `.html` file and previewed before theme injection or opened standalone. Use the light literals from the html-report skill's table.

### Positioning

- **NO `position: fixed`** — breaks iframe auto-sizing (elements collapse to 0 height)
- Use `position: relative` for chart containers
- No nested scrolling — the iframe auto-sizes to fit all content

## Theme Variables

These CSS variables are automatically injected and resolve correctly in both light and dark mode:

| Variable | Purpose |
|----------|---------|
| `--color-bg-page` | Page background |
| `--color-bg-card` | Card/panel background |
| `--color-bg-elevated` | Elevated surface |
| `--color-bg-subtle` | Subtle/muted background |
| `--color-bg-hover` | Hover state background |
| `--color-text-primary` | Primary text |
| `--color-text-secondary` | Secondary/muted text |
| `--color-text-tertiary` | Hint/label text |
| `--color-border-muted` | Default border (use with 0.5px) |
| `--color-accent-primary` | Brand/accent color |
| `--color-profit` | Positive/gain (green) |
| `--color-loss` | Negative/loss (red) |
| `--color-warning` | Warning (amber) |
| `--color-info` | Info (blue) |
| `--color-success` | Success (green) |

**Never hardcode colors** like `#333` or `rgb(...)` for text, backgrounds, or borders — they break in dark mode. Author every color as `var(--color-x, #lightLiteral)`: the injected variable always wins in chat, and the fallback keeps the widget legible on its secondary surfaces. The only exception is chart canvas colors — Chart.js canvas cannot read CSS variables; resolve them via `getComputedStyle` with a literal fallback.

## Charts (Chart.js)

Load Chart.js from CDN and follow these rules:

```html
<!-- Wrapper div with explicit height — REQUIRED -->
<div style="position: relative; height: 200px;">
  <canvas id="myChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
  // Read CSS variables for chart colors (canvas can't use var());
  // the literal fallback covers the widget opened outside the chat surface.
  var cs = getComputedStyle(document.documentElement);
  function pick(name, fallback) { return cs.getPropertyValue(name).trim() || fallback; }
  var accent = pick('--color-accent-primary', '#1f5fb4');
  var border = pick('--color-border-muted', '#e4e1dc');

  new Chart(document.getElementById('myChart'), {
    type: 'line',
    data: {
      labels: [...],
      data