<div align="center">
  <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="72" height="72" alt="BPMN Kit logo"></a>
  <h1>@bpmnkit/canvas</h1>
  <p>Zero-dependency SVG BPMN viewer with pan/zoom, theming, and a plugin API</p>

  [![npm](https://img.shields.io/npm/v/@bpmnkit/canvas?style=flat-square&color=6244d7)](https://www.npmjs.com/package/@bpmnkit/canvas)
  [![license](https://img.shields.io/npm/l/@bpmnkit/canvas?style=flat-square)](https://github.com/bpmnkit/monorepo/blob/main/LICENSE)
  [![typescript](https://img.shields.io/badge/TypeScript-strict-6244d7?style=flat-square&logo=typescript&logoColor=white)](https://github.com/bpmnkit/monorepo)
  [![ai-assisted](https://img.shields.io/badge/AI--assisted-claude-8b5cf6?style=flat-square)](https://github.com/bpmnkit/monorepo)
  [![stable](https://img.shields.io/badge/status-stable-16a34a?style=flat-square)](https://bpmnkit.com/docs/getting-started/stability)

  [Website](https://bpmnkit.com) · [Documentation](https://bpmnkit.com/docs) · [GitHub](https://github.com/bpmnkit/monorepo) · [Changelog](https://github.com/bpmnkit/monorepo/blob/main/packages/canvas/CHANGELOG.md)
</div>

---

## Overview

`@bpmnkit/canvas` renders BPMN 2.0 diagrams as interactive SVG. It has zero runtime dependencies, works in any framework (or none), and exposes a plugin API for extending its behaviour.

## Features

- **SVG rendering** — crisp diagrams at any zoom level, all element types
- **Pan & zoom** — mouse drag, scroll wheel, touch/pinch, keyboard shortcuts
- **Theming** — light / dark / system-auto, fully overridable via CSS custom properties
- **Plugin API** — install composable `CanvasPlugin` add-ons without touching core code
- **Event system** — subscribe to element clicks, selection changes, diagram load, viewport updates
- **Keyboard navigation** — arrow keys, fit-to-screen, zoom shortcuts
- **Zero dependencies** — runs in browsers, bundlers, and SSR

## Installation

```sh
npm install @bpmnkit/canvas
```

## Quick Start

```typescript
import { BpmnCanvas } from "@bpmnkit/canvas"

const canvas = new BpmnCanvas({
  container: document.getElementById("canvas")!,
  theme: "dark",          // "light" | "dark" | "auto"
  grid: true,             // dot-grid background
  plugins: [],            // CanvasPlugin[]
})

// Load a diagram
canvas.loadXML(bpmnXml)

// Respond to element clicks
canvas.on("element:click", (id, event) => {
  console.log("Clicked:", id)
})

// Fit diagram to container
canvas.fit()
```

## API Reference

### Constructor Options

```typescript
interface CanvasOptions {
  container: HTMLElement
  theme?: "light" | "dark" | "auto"   // default: "auto"
  grid?: boolean                       // default: false
  fit?: boolean                        // auto-fit on load, default: true
  plugins?: CanvasPlugin[]
}
```

### CanvasApi Methods

| Method | Description |
|--------|-------------|
| `loadXML(xml)` | Parse and render a BPMN XML string |
| `fit()` | Fit the diagram to the container |
| `zoom(factor)` | Set zoom level (1 = 100%) |
| `getShapes()` | All rendered `RenderedShape` objects |
| `getEdges()` | All rendered `RenderedEdge` objects |
| `setTheme(theme)` | Switch theme at runtime |
| `destroy()` | Remove canvas and clean up |
| `on(event, handler)` | Subscribe to a canvas event |
| `off(event, handler)` | Unsubscribe |

### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `diagram:load` | `BpmnDefinitions` | Fired when a new diagram loads |
| `element:click` | `(id, PointerEvent)` | An element was clicked |
| `editor:select` | `string[]` | Selection changed (element IDs) |
| `viewport:change` | `ViewportState` | Pan or zoom occurred |

### Plugin API

```typescript
import type { CanvasPlugin, CanvasApi } from "@bpmnkit/canvas"

const myPlugin: CanvasPlugin = {
  name: "my-plugin",
  install(api: CanvasApi) {
    api.on("element:click", (id) => console.log("clicked", id))
  },
  uninstall() {},
}
```

---

## Related Packages

| Package | Description |
|---------|-------------|
| [`@bpmnkit/core`](https://www.npmjs.com/package/@bpmnkit/core) | BPMN/DMN/Form parser, builder, layout engine |
| [`@bpmnkit/editor`](https://www.npmjs.com/package/@bpmnkit/editor) | Full-featured interactive BPMN editor |
| [`@bpmnkit/engine`](https://www.npmjs.com/package/@bpmnkit/engine) | Lightweight BPMN process execution engine |
| [`@bpmnkit/feel`](https://www.npmjs.com/package/@bpmnkit/feel) | FEEL expression language parser & evaluator |
| [`@bpmnkit/plugins`](https://www.npmjs.com/package/@bpmnkit/plugins) | 22 composable canvas plugins |
| [`@bpmnkit/api`](https://www.npmjs.com/package/@bpmnkit/api) | Camunda 8 REST API TypeScript client |
| [`@bpmnkit/ascii`](https://www.npmjs.com/package/@bpmnkit/ascii) | Render BPMN diagrams as Unicode ASCII art |
| [`@bpmnkit/docspack`](https://www.npmjs.com/package/@bpmnkit/docspack) | BPMN Kit docs as an offline docspack package for AI agents |
| [`@bpmnkit/camunda-docspack`](https://www.npmjs.com/package/@bpmnkit/camunda-docspack) | Camunda 8 docs as an offline docspack package for AI agents |
| [`@bpmnkit/ui`](https://www.npmjs.com/package/@bpmnkit/ui) | Shared design tokens and UI components |
| [`@bpmnkit/profiles`](https://www.npmjs.com/package/@bpmnkit/profiles) | Shared auth, profile storage, and client factories for CLI & proxy |
| [`@bpmnkit/operate`](https://www.npmjs.com/package/@bpmnkit/operate) | Monitoring & operations frontend for Camunda clusters |
| [`@bpmnkit/connector-gen`](https://www.npmjs.com/package/@bpmnkit/connector-gen) | Generate connector templates from OpenAPI specs |
| [`@bpmnkit/connectors`](https://www.npmjs.com/package/@bpmnkit/connectors) | Camunda 8 OOTB connector catalog and deterministic template application |
| [`@bpmnkit/cli`](https://www.npmjs.com/package/@bpmnkit/cli) | Camunda 8 command-line interface (casen) |
| [`@bpmnkit/proxy`](https://www.npmjs.com/package/@bpmnkit/proxy) | Local AI bridge and Camunda API proxy server |
| [`@bpmnkit/patterns`](https://www.npmjs.com/package/@bpmnkit/patterns) | Domain process patterns for BPMNKit AIKit |
| [`@bpmnkit/reebe-wasm`](https://www.npmjs.com/package/@bpmnkit/reebe-wasm) | WebAssembly BPMN engine for browser simulation |
| [`@bpmnkit/worker-client`](https://www.npmjs.com/package/@bpmnkit/worker-client) | Thin Zeebe REST client for standalone workers |
| [`@bpmnkit/user-tasks`](https://www.npmjs.com/package/@bpmnkit/user-tasks) | Embeddable user task widget for Camunda 8 |
| [`@bpmnkit/cli-sdk`](https://www.npmjs.com/package/@bpmnkit/cli-sdk) | Plugin authoring SDK for the casen CLI |
| [`@bpmnkit/create-casen-plugin`](https://www.npmjs.com/package/@bpmnkit/create-casen-plugin) | Scaffold a new casen CLI plugin in seconds |
| [`@bpmnkit/casen-report`](https://www.npmjs.com/package/@bpmnkit/casen-report) | HTML reports from Camunda 8 incident and SLA data |
| [`@bpmnkit/casen-worker-http`](https://www.npmjs.com/package/@bpmnkit/casen-worker-http) | Example HTTP worker plugin — completes jobs with live JSONPlaceholder API data |
| [`@bpmnkit/casen-worker-ai`](https://www.npmjs.com/package/@bpmnkit/casen-worker-ai) | AI task worker — classify, summarize, extract, and decide using Claude |

## License

[MIT](https://github.com/bpmnkit/monorepo/blob/main/LICENSE) © BPMN Kit — made by [u11g](https://u11g.com)

<div align="center">
  <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="32" height="32" alt="BPMN Kit"></a>
</div>
