bp-canvas

The library does not query. You read the user’s data, aggregate, and put results in attributes or JSON script children.

bpicori/skills1 installsMITSynced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI

Agent Skills format with YAML frontmatter. Claude Code reads it as-is.

---
name: "bp-canvas"
description: "The library does not query. You read the user’s data, aggregate, and put results in attributes or JSON script children."
license: "MIT"
---

# bp-canvas

The library does not query. You read the user’s data, aggregate, and put results in attributes or JSON script children.

Tag catalog: [references/catalog.md](references/catalog.md).

## Runtime

Load the published runtime from **canvas** (`github.com/bpicori/canvas`). Do not invent tags. Do not import React. Do not `fetch` from the page. Do not inline the bundle.

```html
<script src="https://cdn.jsdelivr.net/gh/bpicori/canvas@main/runtime/canvas.js"></script>
```

If that 404s, use `https://raw.githubusercontent.com/bpicori/canvas/main/runtime/canvas.js`.

Put that tag **after** `</cv-dashboard>`. Not in `<head>`, not above the dashboard. `cv-dashboard` reads only direct children (`:scope > cv-pane`) in `connectedCallback`. If the custom element upgrades before those panes exist — or if they sit inside a wrapper — it paints "No panes. Add cv-pane children to this dashboard." and does not look again.

## Workflow

1. Read the user’s data. Compute KPIs, series, tables, and other pane bodies.
2. Write **one** HTML file (template below). Point at the runtime URL. No extra JS files.
3. Hand the user that file.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>TITLE</title>
    <style>html, body, cv-dashboard { margin: 0; height: 100%; display: block; }</style>
  </head>
  <body>
    <cv-dashboard name="Sales">
      <cv-pane id="rev" title="Revenue" x="0" y="0" w="3" h="3">
        <cv-stat value="12450" label="8 orders" format="currency" currency="EUR"></cv-stat>
      </cv-pane>
      <cv-pane id="by-region" title="By region" x="3" y="0" w="5" h="5">
        <cv-bar>
          <script type="application/json">
            {
              "categories": ["EU", "US"],
              "series": [{ "name": "Revenue", "data": [8000, 4450] }]
            }
          </script>
        </cv-bar>
      </cv-pane>
    </cv-dashboard>
    <script src="https://cdn.jsdelivr.net/gh/bpicori/canvas@main/runtime/canvas.js"></script>
  </body>
</html>
```

Grid is 12 columns. Default pane `w: 4, h: 3`. Drag the header to move; resize from either bottom corner. Layout is stored in `localStorage`.

Prefer `<cv-dashboard>` + `<cv-pane>` for data work. A docs-only page may omit the dashboard and use `cv-stack` at the root.

Scalars go on attributes. Structured data goes in a child `<script type="application/json">`.

More General & Other skills

← All General & Other skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY