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.
git clone --depth 1 https://github.com/ginlix-ai/LangAlpha /tmp/inline-widget && cp -r /tmp/inline-widget/skills/inline-widget ~/.claude/skills/inline-widgetSKILL.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.
## 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.
## 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); 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:
```css
/* Card */
background: var(--color-bg-card);
border: 0.5px solid var(--color-border-muted);
border-radius: 8px;
padding: 16px;
/* Metric card */
background: var(--color-bg-subtle);
border: 0.5px solid var(--color-border-muted);
border-radius: 8px;
```
### 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. Use CSS variables for everything except chart canvas colors (Chart.js canvas cannot read CSS variables — use computed hex values via `getComputedStyle`).
## 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())
var cs = getComputedStyle(document.documentElement);
var accent = cs.getPropertyValue('--color-accent-primary').trim();
var border = cs.getPropertyValue('--color-border-muted').trim();
new Chart(document.getElementById('myChart'), {
type: 'line',
data: {
labels: [...],
datasets: [{
data: [...],
borderColor: accent,
backgroundColor: accent + '20',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false, // REQUIRED
plugins: { legend: { display: true } },
scales: {
y: { grid: { color: border } },
x: { grid: { display: false } }
}
}
});
</script>
```
**Key rules:**
- Set height on the **wrapper div**, never on the canvas
- Always use `responsive: true, maintainAspectRatio: false`
- Use UMD build from CDN (sets `window.Chart` global)
- Read CSS variables via `getComputedStyle` for chart colors
## Typography
- Font: inherited from host (`-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif`)
- Weight: **400** (regular) and **500** (medium) only — never 600 or 700
- Heading sizes: h1 = 22px, h2 = 18px, h3 = 16px (all weight 500)
- Body: 14-16px, weight 400
- Use **sentence case** — no Title Case or ALL CAPS (except short metric labels)
## Interactivity
### sendPrompt()
Call `sendPrompt('text')` from buttons to trigger a follow-up chat messaIntegrated 3-statement financial model: linked income statement, balance sheet, and cash flow
Create and manage scheduled and price-triggered automations.
Event tracker: earnings dates, economic releases, conferences, regulatory events
Investment deck QC: number consistency, data-narrative alignment, IB language, formatting audit
Financial model audit: structural checks, formula validation, integrity testing
Competitive landscape analysis: positioning, scorecards, moat assessment, market share trends
Comparable company analysis: operating metrics, valuation multiples, peer benchmarking
DCF valuation: free cash flow projections, WACC, terminal value, sensitivity analysis