pele-animate 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -56
- package/docs/accessibility.md +20 -0
- package/docs/agents.md +63 -0
- package/docs/api.md +49 -0
- package/docs/compatibility.md +33 -0
- package/docs/contributing.md +24 -0
- package/docs/custom-icons.md +39 -0
- package/docs/diagram-types.md +43 -0
- package/docs/faq.md +30 -0
- package/docs/getting-started.md +66 -0
- package/docs/how-it-works.md +44 -0
- package/docs/icons.md +82 -0
- package/docs/migrating.md +58 -0
- package/docs/recipes.md +80 -0
- package/docs/security.md +19 -0
- package/docs/step-order.md +75 -0
- package/docs/theming.md +48 -0
- package/package.json +10 -7
- package/skills/diagram-step-order/SKILL.md +43 -0
- package/skills/diagram-step-order/steps.js +15 -0
- package/skills/pele-animate/SKILL.md +131 -0
- package/skills/pele-animate/references/categories.md +42 -0
- package/skills/pele-animate/verify.js +14 -0
- package/types/glyphs.d.ts +13 -0
- package/types/index.d.ts +33 -0
- package/types/preset-doverunner.d.ts +1 -0
- package/types/tabler-pack.d.ts +2 -0
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# pele-animate
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[Pele](https://github.com/obsidianmd/pele) (MIT),
|
|
3
|
+
Mermaid diagrams that explain themselves one step at a time, with icons. You choose the order things appear in, readers
|
|
4
|
+
step through it, and nodes can carry icons. A small post-processor for [Pele](https://github.com/obsidianmd/pele) (MIT),
|
|
5
|
+
which renders the Mermaid; this adds the step order, the playback and the icons. It is not a theme package.
|
|
5
6
|
Unofficial add-on; not affiliated with or endorsed by the Pele or Obsidian teams.
|
|
6
7
|
The source stays valid Mermaid, so GitHub or Obsidian still show a normal diagram.
|
|
7
8
|
|
|
@@ -43,9 +44,9 @@ sequenceDiagram
|
|
|
43
44
|
| Pele | <img src="https://raw.githubusercontent.com/dkdev24/pele-animate/main/examples/p2.png" width="560" alt="Sequence diagram rendered by Pele"> |
|
|
44
45
|
| pele-animate | <img src="https://raw.githubusercontent.com/dkdev24/pele-animate/main/examples/a2.gif" width="560" alt="Animated sequence diagram: messages appear in order, tokens travel"> |
|
|
45
46
|
|
|
46
|
-
With
|
|
47
|
+
With icons (`@{ icon }` nodes from the Tabler `computers` pack, `%% pa: 1=C 2=L 3=S` pins the order):
|
|
47
48
|
|
|
48
|
-
<img src="https://raw.githubusercontent.com/dkdev24/pele-animate/main/examples/a3.gif" width="560" alt="Animated scene with
|
|
49
|
+
<img src="https://raw.githubusercontent.com/dkdev24/pele-animate/main/examples/a3.gif" width="560" alt="Animated scene with Tabler icons: a request, a load balancer and a cloud service">
|
|
49
50
|
|
|
50
51
|
## Install
|
|
51
52
|
|
|
@@ -59,7 +60,7 @@ npm i pele-animate pele
|
|
|
59
60
|
import { mount } from 'pele';
|
|
60
61
|
import { watch } from 'pele-animate';
|
|
61
62
|
import { icons } from 'pele-animate/glyphs';
|
|
62
|
-
import 'pele-animate/
|
|
63
|
+
import 'pele-animate/tabler/computers'; // one Tabler icon category; import as many as you need
|
|
63
64
|
import 'pele-animate/style.css';
|
|
64
65
|
|
|
65
66
|
for (const el of document.querySelectorAll('pre.mermaid')) {
|
|
@@ -73,62 +74,32 @@ Mermaid source:
|
|
|
73
74
|
|
|
74
75
|
```mermaid
|
|
75
76
|
flowchart LR
|
|
76
|
-
%% pa: 1=
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
%% pa: 1=C 2=L 3=S
|
|
78
|
+
C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
|
|
79
|
+
L@{ icon: "load-balancer", form: "square", h: 88, label: "Load balancer" }
|
|
80
|
+
S@{ icon: "cloud-computing", form: "square", h: 88, label: "Cloud service" }
|
|
81
|
+
C <-->|route| L
|
|
82
|
+
L <-->|forward| S
|
|
82
83
|
```
|
|
83
84
|
|
|
84
|
-
`form: "square", h: 88` makes a large frameless
|
|
85
|
-
`%% pa: 1=P 2=O 3=D` pins nodes to steps (optional). `X>Y` pins the edge from X to Y, so an edge between nodes that are
|
|
86
|
-
already visible can have its own step: `%% pa: 1=A,B 2=C,B>C 3=C>B`. Pin the nodes first; an edge pinned before its target appears lands early.
|
|
87
|
-
Sequence diagrams animate actors, then messages in order.
|
|
85
|
+
`%% pa: 1=C 2=L 3=S` pins the order (optional). `form: "square", h: 88` makes a large frameless icon.
|
|
88
86
|
|
|
89
|
-
##
|
|
87
|
+
## Documentation
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|---|---|
|
|
93
|
-
| `watch(container, source?)` | Animate the SVG inside `container` (and every re-render of it); adds the scene panel and step mode (click / Enter); pass `{ controls: false }` as a third argument for click-to-replay instead |
|
|
94
|
-
| `animate(svg, { hover, source })` | Animate one SVG; you handle re-renders |
|
|
95
|
-
| `replay(svg)` | Play the intro again |
|
|
96
|
-
| `parseOrder(source)` | Read the `%% pa:` pins: `Map(nodeId or 'X>Y' -> level)` |
|
|
97
|
-
| `svg.paSteps` | Set by `animate()`: one array per step, each item `[element, parts that animate in]`. Step mode uses it; read it to check the order |
|
|
98
|
-
| `registerGlyphs(pack, strokeWidth = 1.1)` (`/glyphs`) | Add glyphs: `{ name: '<inner markup of a 24x24 svg>' }`; colors via `--pa-solid` / `--pa-light` |
|
|
99
|
-
| `icons` (`/glyphs`) | Pele `icons` resolver; unknown names get a neutral rounded square, since Pele ships no icons of its own |
|
|
100
|
-
|
|
101
|
-
Illustrated glyphs (filled, two-tone, DoveRunner style) come from `pele-animate/preset-doverunner` and are all named `doverunner-<name>`: `player`, `server`, `key`, `document`, `shield`, `phone`, `cloud`, `package`, `token`, `lock`, `database`, `video`, `media`, `encoder`, `storage`, `plugin`, `variants`, `watermark`,
|
|
102
|
-
`bits-a`, `bits-b`. Plain names (`server`, `lock`, ...) are Tabler's.
|
|
103
|
-
|
|
104
|
-
### Tabler icon packs
|
|
105
|
-
|
|
106
|
-
About 4,300 line icons from [Tabler Icons](https://github.com/tabler/tabler-icons) (MIT), split by Tabler's own categories. Import only what you need:
|
|
107
|
-
|
|
108
|
-
```js
|
|
109
|
-
import 'pele-animate/tabler/devices'; // also: system, database, development, communication, charts, ...
|
|
110
|
-
```
|
|
89
|
+
Everything is in [`docs/`](docs/getting-started.md), and ships inside the npm package:
|
|
111
90
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
.pa-scene { --pa-stroke: 1; }
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Theme
|
|
122
|
-
|
|
123
|
-
`watch()` adds class `pa-scene` to the container. Override `--pa-bg`, `--pa-solid`, `--pa-light` or any `--pele-*`
|
|
124
|
-
variable on it; defaults are `:where()` rules, so your stylesheet wins.
|
|
125
|
-
|
|
126
|
-
## Limits
|
|
91
|
+
| | |
|
|
92
|
+
|---|---|
|
|
93
|
+
| [Getting started](docs/getting-started.md) · [How it works](docs/how-it-works.md) · [Diagram types](docs/diagram-types.md) | The basics |
|
|
94
|
+
| [Icons](docs/icons.md) · [Custom icons](docs/custom-icons.md) · [Step order](docs/step-order.md) · [Theming](docs/theming.md) · [Recipes](docs/recipes.md) | Guides (Vite, Astro, SvelteKit, Nuxt, React) |
|
|
95
|
+
| [API](docs/api.md) · [Compatibility](docs/compatibility.md) · [Accessibility](docs/accessibility.md) · [Security](docs/security.md) | Reference |
|
|
96
|
+
| [Migrating](docs/migrating.md) · [For coding agents](docs/agents.md) · [FAQ](docs/faq.md) · [Contributing](docs/contributing.md) | Everything else |
|
|
127
97
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
- Glyph art is square-boxed; wide art is drawn as a wide glyph inside the square.
|
|
98
|
+
**Coding agents:** the package includes a skill, `skills/pele-animate/`, that wires the library into a project and checks the
|
|
99
|
+
result in a browser. See [For coding agents](docs/agents.md).
|
|
131
100
|
|
|
132
|
-
##
|
|
101
|
+
## Credits and license
|
|
133
102
|
|
|
134
|
-
|
|
103
|
+
MIT. Built on [Pele](https://github.com/obsidianmd/pele) by kepano (MIT); this is an unofficial add-on, not affiliated with or
|
|
104
|
+
endorsed by the Pele or Obsidian teams. The Tabler icon packs come from [Tabler Icons](https://github.com/tabler/tabler-icons)
|
|
105
|
+
(MIT, Paweł Kuna); see [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md). See also [CHANGELOG.md](CHANGELOG.md).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Accessibility
|
|
3
|
+
description: What pele-animate does for keyboard users and reduced motion, and what has not been audited.
|
|
4
|
+
order: 11
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Accessibility
|
|
9
|
+
|
|
10
|
+
What is in place:
|
|
11
|
+
|
|
12
|
+
- **Reduced motion.** `prefers-reduced-motion: reduce` turns off the intro and the tokens. The finished diagram shows.
|
|
13
|
+
- **Keyboard.** The diagram container is focusable (`tabindex="0"`). Enter or Space starts step mode; then Space plays or pauses, ← and → step, and Esc leaves.
|
|
14
|
+
- **Step controls.** The bar has `role="toolbar"` with an accessible name, and its buttons have labels. Previous and next use
|
|
15
|
+
`aria-disabled` at the ends.
|
|
16
|
+
- **Focus outline.** A visible focus ring uses the `--pa-solid` color.
|
|
17
|
+
|
|
18
|
+
What has **not** been checked: a pass with a screen reader, and contrast ratios of custom palettes. Treat the diagram as an
|
|
19
|
+
illustration and keep the key information in the surrounding text as well, as with any diagram. The text of the Mermaid
|
|
20
|
+
source is not a substitute for a description.
|
package/docs/agents.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: For coding agents
|
|
3
|
+
description: How a coding agent should use pele-animate in a project, and how to verify the result.
|
|
4
|
+
order: 14
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# For coding agents
|
|
9
|
+
|
|
10
|
+
If you are an AI coding agent adding pele-animate to a project, use the skill that ships with the package. It carries the rules
|
|
11
|
+
below in an order that works.
|
|
12
|
+
|
|
13
|
+
## Install the skill
|
|
14
|
+
|
|
15
|
+
The skill is in the npm package, so after `npm i pele-animate` it is at `node_modules/pele-animate/skills/pele-animate/SKILL.md`.
|
|
16
|
+
For Claude Code, copy it where skills live:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
mkdir -p .claude/skills
|
|
20
|
+
cp -r node_modules/pele-animate/skills/pele-animate .claude/skills/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or clone just the skill folder from [GitHub](https://github.com/dkdev24/pele-animate/tree/main/skills/pele-animate) (it has `SKILL.md`, `verify.js` and `references/`).
|
|
24
|
+
|
|
25
|
+
A second skill, `diagram-step-order`, reviews a page's diagrams so the step order matches the text around them.
|
|
26
|
+
|
|
27
|
+
No skill support? Paste this into your instructions file:
|
|
28
|
+
|
|
29
|
+
```md
|
|
30
|
+
## Diagrams (pele-animate)
|
|
31
|
+
- Animated Mermaid diagrams use `pele` + `pele-animate`; mount on the client only (see node_modules/pele-animate/docs or the README).
|
|
32
|
+
- Icon names must exist: read node_modules/pele-animate/tabler/<category>.js. Never invent names. Unknown names render a plain square.
|
|
33
|
+
- Order with `%% pa: 1=A 2=B,C`; check svg.paSteps in a browser.
|
|
34
|
+
- Verify by rendering the page and confirming no unexpected rounded-square icons.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Rules
|
|
38
|
+
|
|
39
|
+
1. **Client only.** Never import `pele` or `pele-animate` in server code. Use the framework's mounted hook ([recipes](./recipes.md)).
|
|
40
|
+
2. **Never invent icon names.** Look them up in `node_modules/pele-animate/tabler/<category>.js` (object keys) and import that category.
|
|
41
|
+
An unknown name does not fail; it renders a rounded square, so a made-up name is a silent bug.
|
|
42
|
+
3. **Import three things:** `pele-animate/glyphs` (`icons`), the icon pack modules you use, and `pele-animate/style.css`.
|
|
43
|
+
4. **Pin the order** with `%% pa:` when the default is wrong ([step order](./step-order.md)). Do not rename node ids after pinning.
|
|
44
|
+
5. **Verify in a browser**, not by reading the code.
|
|
45
|
+
|
|
46
|
+
## Verify
|
|
47
|
+
|
|
48
|
+
Render the page in a headless browser (Playwright, or any CLI browser) and run this in the page:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
(() => {
|
|
52
|
+
const svgs = [...document.querySelectorAll('.pa-scene svg.pele')];
|
|
53
|
+
const icons = [...document.querySelectorAll('.pa-scene svg.pele-icon[data-icon]')];
|
|
54
|
+
return {
|
|
55
|
+
diagrams: svgs.length,
|
|
56
|
+
steps: svgs.map((s) => s.paSteps?.length ?? 0),
|
|
57
|
+
emptyIcons: icons.filter((i) => !i.innerHTML.trim()).map((i) => i.dataset.icon),
|
|
58
|
+
};
|
|
59
|
+
})()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Expect `diagrams` equal to the number you added, every `steps` entry above 0, and `emptyIcons` empty. A name that was not registered renders
|
|
63
|
+
a rounded square instead of nothing, so also compare the icon names in your Mermaid with the pack source.
|
package/docs/api.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API reference
|
|
3
|
+
description: Every export of pele-animate, with types.
|
|
4
|
+
order: 9
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# API reference
|
|
9
|
+
|
|
10
|
+
TypeScript types ship with the package (`types/`).
|
|
11
|
+
|
|
12
|
+
## `pele-animate`
|
|
13
|
+
|
|
14
|
+
| Export | Signature | Description |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `watch` | `watch(container: HTMLElement, source?: string, options?: { controls?: boolean }): void` | Marks the container as a scene (`pa-scene`), animates each SVG Pele renders into it and re-applies after Pele re-lays-out on resize. `controls: false` keeps click-to-replay instead of step mode. |
|
|
17
|
+
| `animate` | `animate(svg: SVGSVGElement, options?: { hover?: Element; source?: string }): void` | Animates one rendered svg. `source` is read for `%% pa:` pins. Sets `svg.paSteps`. |
|
|
18
|
+
| `replay` | `replay(svg: SVGSVGElement \| null \| undefined): void` | Plays the intro again. |
|
|
19
|
+
| `parseOrder` | `parseOrder(source?: string): Map<string, number>` | Parses the `%% pa:` comment: node id, or `'X>Y'` for an edge, to a 0-based step. |
|
|
20
|
+
|
|
21
|
+
`svg.paSteps` (type `PaStep[]`, where `PaStep = Array<[element: Element, parts: Element[]]>`) is set by `animate()`: one array per
|
|
22
|
+
step.
|
|
23
|
+
|
|
24
|
+
## `pele-animate/glyphs`
|
|
25
|
+
|
|
26
|
+
| Export | Signature | Description |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `icons` | `icons(name: string): string` | Pele's `icons` resolver. Unknown names return a neutral rounded square. |
|
|
29
|
+
| `registerGlyphs` | `registerGlyphs(pack: Record<string, string>, strokeWidth?: number): void` | Adds glyphs: `{ name: '<inner markup of a 24x24 svg>' }`. Default stroke width 1.1. |
|
|
30
|
+
| `registerTabler` | `registerTabler(pack: Record<string, string>, strokeWidth?: number): void` | Adds outline icons whose stroke width follows `--pa-stroke` (fallback `strokeWidth`, default 1.5). |
|
|
31
|
+
| `S`, `L`, `W` | `string` | Theme color expressions for glyph markup: solid, light, white. |
|
|
32
|
+
|
|
33
|
+
## `pele-animate/tabler/<category>`
|
|
34
|
+
|
|
35
|
+
Importing a module registers that category's icons. It also exports `pack: Record<string, string>` (name to inner markup).
|
|
36
|
+
Categories are listed in [icons](./icons.md).
|
|
37
|
+
|
|
38
|
+
## `pele-animate/preset-doverunner`
|
|
39
|
+
|
|
40
|
+
Importing it registers the 20 `doverunner-*` glyphs. No exports.
|
|
41
|
+
|
|
42
|
+
## `pele-animate/style.css`
|
|
43
|
+
|
|
44
|
+
The scene frame, motion and step controls. Import it once.
|
|
45
|
+
|
|
46
|
+
## Classes you may see
|
|
47
|
+
|
|
48
|
+
`pa-scene` (container), `pa-ready` (an animated svg), `pa-in` and `pa-done` (intro states), `pa-stepping` (step mode), `pa-controls`
|
|
49
|
+
(the button bar). These are internal and may change; prefer the CSS variables in [theming](./theming.md) over targeting them.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Compatibility
|
|
3
|
+
description: Versions of Pele, browsers, and the parts of Pele's markup pele-animate depends on.
|
|
4
|
+
order: 10
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Compatibility
|
|
9
|
+
|
|
10
|
+
| | Supported |
|
|
11
|
+
|---|---|
|
|
12
|
+
| Pele | `^1.7.0` (peer dependency). Tested with 1.7 (the docs site), 1.8 and 1.9. |
|
|
13
|
+
| Diagram types | Flowcharts and sequence diagrams ([diagram types](./diagram-types.md)) |
|
|
14
|
+
| Browsers | Current browsers with the Web Animations API, `IntersectionObserver` and `matchMedia` (Chrome, Edge, Firefox, Safari). Without `IntersectionObserver` the intro plays at once. |
|
|
15
|
+
| Module format | ESM only |
|
|
16
|
+
| Server rendering | Not applicable: mount on the client ([recipes](./recipes.md)) |
|
|
17
|
+
|
|
18
|
+
## What pele-animate depends on in Pele
|
|
19
|
+
|
|
20
|
+
pele-animate reads the SVG Pele produces. It selects on these class names and attributes:
|
|
21
|
+
|
|
22
|
+
`.pele-node`, `.pele-edge`, `.pele-edge-label`, `.pele-marker`, `.pele-cluster-label`, `.pele-icon`, `.pele-lifeline`,
|
|
23
|
+
`.pele-actor-participant`, and the `data-id` attribute.
|
|
24
|
+
|
|
25
|
+
Pele has not promised these are stable across releases (the question is open upstream). That is why Pele is a peer dependency:
|
|
26
|
+
upgrade it deliberately, and re-check your diagrams afterwards. The repository's tests render every documentation example,
|
|
27
|
+
which catches parse errors but not visual changes.
|
|
28
|
+
|
|
29
|
+
## Known limits
|
|
30
|
+
|
|
31
|
+
- Sequence-diagram participants ignore `@{ icon }`.
|
|
32
|
+
- Step mode is browser-tested on flowcharts only.
|
|
33
|
+
- Glyph art is square-boxed; wide art is drawn as a wide shape inside the square.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contributing
|
|
3
|
+
description: Set up the repository, run the checks, and regenerate the Tabler packs.
|
|
4
|
+
order: 15
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Contributing
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
git clone https://github.com/dkdev24/pele-animate
|
|
12
|
+
cd pele-animate
|
|
13
|
+
pnpm install
|
|
14
|
+
pnpm test # renders every Mermaid example in the docs and README with Pele, and checks icon names
|
|
15
|
+
pnpm build # builds the site (a placeholder until the site lands)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- The package is plain ESM at the repository root: no build step. The site lives in `site/`.
|
|
19
|
+
- Docs are the Markdown files in `docs/`. A fenced block marked `mermaid` must render, and every `@{ icon }` name in it must exist.
|
|
20
|
+
- Tabler packs are generated: `node scripts/build-tabler.mjs <path to a tabler-icons checkout>` rewrites `tabler/*.js`. Do not edit those
|
|
21
|
+
files by hand. The Tabler version is recorded in each file header and in `THIRD-PARTY-NOTICES.md`.
|
|
22
|
+
- Add an entry to `CHANGELOG.md` for any user-visible change. Breaking changes also get a section in `docs/migrating.md`.
|
|
23
|
+
- Versioning stays on `0.x`.
|
|
24
|
+
- Keep example diagrams generic (clients, APIs, databases).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Custom icons
|
|
3
|
+
description: Register your own glyphs with registerGlyphs.
|
|
4
|
+
order: 5
|
|
5
|
+
section: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Custom icons
|
|
9
|
+
|
|
10
|
+
Register your own icons with `registerGlyphs`:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import { registerGlyphs, S, L } from 'pele-animate/glyphs';
|
|
14
|
+
|
|
15
|
+
registerGlyphs({
|
|
16
|
+
'my-box': `<rect x="4" y="6" width="16" height="12" rx="2" fill="${L}" stroke="${S}"/>`,
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Then use `icon: "my-box"` in your Mermaid.
|
|
21
|
+
|
|
22
|
+
## The contract
|
|
23
|
+
|
|
24
|
+
- A glyph is the **inner markup** of a 24 by 24 SVG: shapes only, no `<svg>` wrapper. Draw inside the 24 by 24 box.
|
|
25
|
+
- Colors: use `S` (solid) and `L` (light), which are the CSS variables `--pa-solid` and `--pa-light` with fallbacks, plus
|
|
26
|
+
`W` for white. Then the glyph follows light and dark themes (see [theming](./theming.md)).
|
|
27
|
+
- `registerGlyphs(pack, strokeWidth = 1.1)` wraps each glyph in a group with that stroke width. Pele draws icons at stroke
|
|
28
|
+
width 2, which looks heavy on a large icon, so glyphs get a thinner one.
|
|
29
|
+
- Line icons that should respond to `--pa-stroke` (as the Tabler packs do) can use `registerTabler(pack, strokeWidth = 1.5)`
|
|
30
|
+
instead. It sets fill none, round caps and joins, and the stroke color for you.
|
|
31
|
+
|
|
32
|
+
## Names
|
|
33
|
+
|
|
34
|
+
Registering a name that already exists replaces it. Choose a prefix for your own pack (`acme-box`) so your names never clash
|
|
35
|
+
with Tabler's plain names.
|
|
36
|
+
|
|
37
|
+
## Safety
|
|
38
|
+
|
|
39
|
+
Glyph markup is inserted into the page as SVG. Only register markup you trust. See [security](./security.md).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Diagram types
|
|
3
|
+
description: Which Mermaid diagrams pele-animate animates, and what each one does.
|
|
4
|
+
order: 3
|
|
5
|
+
section: Start
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Diagram types
|
|
9
|
+
|
|
10
|
+
pele-animate supports **flowcharts** and **sequence diagrams**. Pele renders other diagram types too, but they are outside what
|
|
11
|
+
pele-animate is built for.
|
|
12
|
+
|
|
13
|
+
## Flowcharts
|
|
14
|
+
|
|
15
|
+
Nodes appear in step order, edges draw from their source node, and edge labels fade in. Groups (`subgraph`) and their titles
|
|
16
|
+
are kept. Icon nodes (`@{ icon }`) work here; see [icons](./icons.md).
|
|
17
|
+
|
|
18
|
+
```mermaid live
|
|
19
|
+
flowchart LR
|
|
20
|
+
A[Client] --> B{Cached?}
|
|
21
|
+
B -->|yes| C[Serve]
|
|
22
|
+
B -->|no| D[Fetch] --> C
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Sequence diagrams
|
|
26
|
+
|
|
27
|
+
Actors appear first, then the messages in order. Participant boxes in a row get the same height, and group titles are bold.
|
|
28
|
+
|
|
29
|
+
```mermaid live
|
|
30
|
+
sequenceDiagram
|
|
31
|
+
Client->>API: request
|
|
32
|
+
API->>Database: query
|
|
33
|
+
Database-->>API: rows
|
|
34
|
+
API-->>Client: response
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Limit:** Pele ignores `@{ icon }` on sequence participants (the box shows its id), so icons apply to flowcharts only.
|
|
38
|
+
|
|
39
|
+
## Everything else
|
|
40
|
+
|
|
41
|
+
Other Mermaid types (class, state, ER, gantt, pie and the rest) render through Pele as usual. pele-animate is not designed for
|
|
42
|
+
them and its behavior on them is untested, so use plain Pele for those. Step mode has been checked in a browser on
|
|
43
|
+
flowcharts only; sequence diagrams have not been checked the same way yet.
|
package/docs/faq.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: FAQ
|
|
3
|
+
description: Common questions about pele-animate, Pele, and licenses.
|
|
4
|
+
order: 16
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# FAQ
|
|
9
|
+
|
|
10
|
+
**Is this part of Pele?** No. It is an unofficial add-on, not affiliated with or endorsed by the Pele or Obsidian teams. Pele does the
|
|
11
|
+
layout and drawing; pele-animate adds step order, step-by-step playback and icons on top.
|
|
12
|
+
|
|
13
|
+
**Why not just use Pele?** Pele alone draws a static diagram. Use it directly if that is enough. pele-animate is for diagrams
|
|
14
|
+
you want to explain in order.
|
|
15
|
+
|
|
16
|
+
**Is it a theme?** No. It does not offer visual styles beyond a simple scene frame and light/dark colors you can override.
|
|
17
|
+
|
|
18
|
+
**Why not Mermaid.js?** Pele is much smaller and renders synchronously. pele-animate is built on Pele, so it follows that choice.
|
|
19
|
+
|
|
20
|
+
**Does it work with server rendering?** Mount it on the client ([recipes](./recipes.md)). Static site generators are fine.
|
|
21
|
+
|
|
22
|
+
**How big is it?** The core (`pele-animate.js` plus CSS) is about 20 KB unminified. Icon packs are separate modules, so you only
|
|
23
|
+
ship the categories you import (the largest, `system`, is about 199 KB unminified).
|
|
24
|
+
|
|
25
|
+
**Which diagrams does it support?** Flowcharts and sequence diagrams ([diagram types](./diagram-types.md)).
|
|
26
|
+
|
|
27
|
+
**Can I use my own icons?** Yes ([custom icons](./custom-icons.md)).
|
|
28
|
+
|
|
29
|
+
**Licenses.** pele-animate is MIT. Pele is MIT. The Tabler icon packs are from Tabler Icons (MIT, Paweł Kuna); see
|
|
30
|
+
`THIRD-PARTY-NOTICES.md`.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Getting started
|
|
3
|
+
description: Install pele-animate and render your first step-by-step Mermaid diagram.
|
|
4
|
+
order: 1
|
|
5
|
+
section: Start
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Getting started
|
|
9
|
+
|
|
10
|
+
pele-animate makes a [Pele](https://pele.run) diagram explain itself one step at a time. You choose the order things appear
|
|
11
|
+
in, readers step through it with buttons or the keyboard, and any node can carry an icon from a large set. It is an
|
|
12
|
+
unofficial add-on for Pele and does not change how Pele lays out or draws diagrams.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm i pele-animate pele
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`pele` is a peer dependency (`^1.7.0`). Both run in the browser: they need the DOM, so mount them on the client (see
|
|
21
|
+
[recipes](./recipes.md) for frameworks).
|
|
22
|
+
|
|
23
|
+
## First diagram
|
|
24
|
+
|
|
25
|
+
Put the Mermaid source in an element, then mount it with Pele and hand it to `watch()`:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { mount } from 'pele';
|
|
29
|
+
import { watch } from 'pele-animate';
|
|
30
|
+
import { icons } from 'pele-animate/glyphs';
|
|
31
|
+
import 'pele-animate/tabler/computers'; // icons: one Tabler category, import as many as you need
|
|
32
|
+
import 'pele-animate/style.css';
|
|
33
|
+
|
|
34
|
+
const el = document.querySelector('pre.mermaid');
|
|
35
|
+
const src = el.textContent;
|
|
36
|
+
mount(el, src, { icons }); // Pele draws the SVG
|
|
37
|
+
watch(el, src); // pele-animate animates it, and re-applies when Pele re-lays-out on resize
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The Mermaid source:
|
|
41
|
+
|
|
42
|
+
```mermaid live
|
|
43
|
+
flowchart LR
|
|
44
|
+
%% pa: 1=C 2=L 3=S
|
|
45
|
+
C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
|
|
46
|
+
L@{ icon: "load-balancer", form: "square", h: 88, label: "Load balancer" }
|
|
47
|
+
S@{ icon: "cloud-computing", form: "square", h: 88, label: "Cloud service" }
|
|
48
|
+
C <-->|route| L
|
|
49
|
+
L <-->|forward| S
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
What you get:
|
|
53
|
+
|
|
54
|
+
- The intro plays once when the diagram scrolls into view: nodes appear in order, edges draw in, labels fade in.
|
|
55
|
+
- Hover or focus: small tokens travel along the edges.
|
|
56
|
+
- Click, or focus and press Enter: **step mode**. Previous, play/pause and next buttons appear, and Space, ←, → and Esc work.
|
|
57
|
+
- With `prefers-reduced-motion`, the motion is off and the finished picture shows.
|
|
58
|
+
|
|
59
|
+
The `%% pa: 1=C 2=L 3=S` comment pins the order. Without it, the order follows the edges. See [step order](./step-order.md).
|
|
60
|
+
|
|
61
|
+
## Next
|
|
62
|
+
|
|
63
|
+
- Pick icons: [icons](./icons.md).
|
|
64
|
+
- Control the order: [step order](./step-order.md).
|
|
65
|
+
- Match your site's colors: [theming](./theming.md).
|
|
66
|
+
- Upgrading from 0.12: [migrating](./migrating.md).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: How it works
|
|
3
|
+
description: What Pele does, what pele-animate adds, and the three kinds of motion.
|
|
4
|
+
order: 2
|
|
5
|
+
section: Start
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# How it works
|
|
9
|
+
|
|
10
|
+
Two layers, one diagram:
|
|
11
|
+
|
|
12
|
+
1. **Pele** parses the Mermaid, lays the diagram out and returns an SVG. That is all Pele's job; pele-animate does not
|
|
13
|
+
touch layout, sizing or syntax.
|
|
14
|
+
2. **pele-animate** reads that SVG after Pele draws it, works out the order things should appear in, and adds the motion,
|
|
15
|
+
the step playback and the icons. The Mermaid source stays valid Mermaid, so GitHub or Obsidian still show a normal diagram.
|
|
16
|
+
|
|
17
|
+
## The calls
|
|
18
|
+
|
|
19
|
+
- `mount(el, src, { icons })` is Pele's. The `icons` option is how glyphs get in (see [icons](./icons.md)).
|
|
20
|
+
- `watch(el, src)` is pele-animate's. It marks the container as a scene (class `pa-scene`), animates each SVG Pele renders into
|
|
21
|
+
it, and re-applies after Pele re-draws on resize. The intro is skipped on those re-draws once it has played.
|
|
22
|
+
- `animate(svg, { source })` does one SVG. Use it if you render with Pele yourself and do not want `watch()`.
|
|
23
|
+
- `replay(svg)` plays the intro again.
|
|
24
|
+
|
|
25
|
+
## The three kinds of motion
|
|
26
|
+
|
|
27
|
+
| Motion | When | Notes |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| **Intro** | Once, when the diagram is 30% in view | Nodes appear by step, each edge draws from its source, labels fade in. A long diagram squeezes its steps so the intro stays near 3 seconds. |
|
|
30
|
+
| **Tokens** | While hovering or focusing the diagram | Small dots travel along the edges in sequence. |
|
|
31
|
+
| **Step mode** | Click, or Enter | You move through the same steps one at a time. See [step order](./step-order.md). |
|
|
32
|
+
|
|
33
|
+
The resting state is always the finished picture. Everything honors `prefers-reduced-motion`.
|
|
34
|
+
|
|
35
|
+
## Where the order comes from
|
|
36
|
+
|
|
37
|
+
Order is a list of **steps**. By default, a flowchart's steps are the breadth-first levels from the nodes that nothing points to;
|
|
38
|
+
a sequence diagram's steps are its actors, then its messages in order. A `%% pa:` comment overrides that. After
|
|
39
|
+
`animate()` runs, `svg.paSteps` holds one array per step, which is also what step mode uses.
|
|
40
|
+
|
|
41
|
+
## What it depends on in Pele
|
|
42
|
+
|
|
43
|
+
pele-animate selects on class names in Pele's SVG (`.pele-node`, `.pele-edge`, and a few others) and on the `data-id` attribute.
|
|
44
|
+
Pele is a peer dependency so you control its version. See [compatibility](./compatibility.md).
|
package/docs/icons.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Icons
|
|
3
|
+
description: Use icons on flowchart nodes, pick names from 4,000+ Tabler icons, and control stroke width.
|
|
4
|
+
order: 4
|
|
5
|
+
section: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Icons
|
|
9
|
+
|
|
10
|
+
A flowchart node becomes an illustrated node with Mermaid's own `@{ }` syntax:
|
|
11
|
+
|
|
12
|
+
```mermaid live
|
|
13
|
+
flowchart LR
|
|
14
|
+
A@{ icon: "device-desktop", form: "square", h: 88, label: "Laptop" }
|
|
15
|
+
B@{ icon: "server", form: "square", h: 88, label: "Server" }
|
|
16
|
+
A --> B
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Both names are in the Tabler `devices` category, so this needs `import 'pele-animate/tabler/devices'`.
|
|
20
|
+
|
|
21
|
+
- `icon` is the glyph name. `label` is the caption.
|
|
22
|
+
- `form: "square", h: 88` makes a large frameless icon. Leave both out for a small icon inside a frame.
|
|
23
|
+
- Unknown names get a neutral rounded square, never a blank slot. Pele ships no icons of its own, so every name must come
|
|
24
|
+
from a pack you import.
|
|
25
|
+
|
|
26
|
+
## Packs
|
|
27
|
+
|
|
28
|
+
Icons come from packs. Importing a pack module registers its icons.
|
|
29
|
+
|
|
30
|
+
| Pack | Import | Contents |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| **Tabler categories** | `pele-animate/tabler/<category>` | 4,368 outline icons in 36 categories, from [Tabler Icons](https://github.com/tabler/tabler-icons) 3.49.0 (MIT) |
|
|
33
|
+
| **doverunner-\*** (optional) | `pele-animate/preset-doverunner` | 20 filled, two-tone illustrations named `doverunner-<name>` (see below) |
|
|
34
|
+
| **Your own** | `registerGlyphs()` | See [custom icons](./custom-icons.md) |
|
|
35
|
+
|
|
36
|
+
Pass the resolver to Pele: `mount(el, src, { icons })` with `import { icons } from 'pele-animate/glyphs'`.
|
|
37
|
+
|
|
38
|
+
### Tabler categories
|
|
39
|
+
|
|
40
|
+
Import only the categories you use; each is its own module (the largest, `system`, is about 199 KB).
|
|
41
|
+
|
|
42
|
+
| Category | Icons | Category | Icons | Category | Icons |
|
|
43
|
+
|---|---|---|---|---|---|
|
|
44
|
+
| system | 784 | map | 263 | food | 96 |
|
|
45
|
+
| devices | 363 | document | 209 | buildings | 95 |
|
|
46
|
+
| design | 350 | text | 194 | vehicles | 90 |
|
|
47
|
+
| arrows | 333 | shapes | 187 | math | 88 |
|
|
48
|
+
| media | 160 | e-commerce | 155 | health | 87 |
|
|
49
|
+
| communication | 121 | sport | 76 | currencies | 76 |
|
|
50
|
+
| development | 63 | weather | 61 | photography | 52 |
|
|
51
|
+
| mood | 52 | nature | 50 | games | 48 |
|
|
52
|
+
| computers | 44 | database | 42 | laundry | 40 |
|
|
53
|
+
| charts | 39 | symbols | 37 | badges | 22 |
|
|
54
|
+
| electrical | 19 | animals | 18 | gestures | 17 |
|
|
55
|
+
| version-control | 16 | extensions | 13 | logic | 8 |
|
|
56
|
+
|
|
57
|
+
Brand, Letters, Numbers, Zodiac and Gender are not included. Counts are for Tabler 3.49.0.
|
|
58
|
+
|
|
59
|
+
### Finding a name
|
|
60
|
+
|
|
61
|
+
Do not guess names. Look them up:
|
|
62
|
+
|
|
63
|
+
- Tabler's own site, [tabler.io/icons](https://tabler.io/icons), lists names and categories (use the outline style).
|
|
64
|
+
- In your project: `node_modules/pele-animate/tabler/<category>.js` lists every name in that category as an object key.
|
|
65
|
+
- Names that exist in more than one place are not a problem: Tabler names are plain (`server`, `lock`), `doverunner-*` names are prefixed.
|
|
66
|
+
|
|
67
|
+
## Stroke width
|
|
68
|
+
|
|
69
|
+
Tabler icons are line icons drawn to work at any stroke width. Set the CSS variable `--pa-stroke` on the container:
|
|
70
|
+
|
|
71
|
+
```css
|
|
72
|
+
.pa-scene { --pa-stroke: 1; }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The default is `1.5`. Tabler draws at 2. The `doverunner-*` glyphs have a fixed stroke width.
|
|
76
|
+
|
|
77
|
+
## The optional doverunner-* pack
|
|
78
|
+
|
|
79
|
+
`pele-animate/preset-doverunner` ships 20 filled, two-tone glyphs in the style of the DoveRunner Lab product cards, named
|
|
80
|
+
`doverunner-<name>`: `player`, `server`, `key`, `document`, `shield`, `phone`, `cloud`, `package`, `token`, `lock`,
|
|
81
|
+
`database`, `video`, `media`, `encoder`, `storage`, `plugin`, `variants`, `watermark`, `bits-a`, `bits-b`. Import it only
|
|
82
|
+
if you want that look; nothing else needs it.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Migrating
|
|
3
|
+
description: Breaking changes between releases, with the renames to apply.
|
|
4
|
+
order: 13
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Migrating
|
|
9
|
+
|
|
10
|
+
pele-animate stays on `0.x`: a minor release may break things. Pin a range such as `^0.13.0` and bump it deliberately.
|
|
11
|
+
|
|
12
|
+
## 0.12 to 0.13
|
|
13
|
+
|
|
14
|
+
Two breaking changes.
|
|
15
|
+
|
|
16
|
+
### 1. Illustrated glyphs are renamed `doverunner-<name>`
|
|
17
|
+
|
|
18
|
+
The plain names now belong to the Tabler icon packs. Rename the `@{ icon }` values in your Mermaid sources:
|
|
19
|
+
|
|
20
|
+
| Before | After |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `player` | `doverunner-player` |
|
|
23
|
+
| `server` | `doverunner-server` |
|
|
24
|
+
| `key` | `doverunner-key` |
|
|
25
|
+
| `document` | `doverunner-document` |
|
|
26
|
+
| `shield` | `doverunner-shield` |
|
|
27
|
+
| `phone` | `doverunner-phone` |
|
|
28
|
+
| `cloud` | `doverunner-cloud` |
|
|
29
|
+
| `package` | `doverunner-package` |
|
|
30
|
+
| `token` | `doverunner-token` |
|
|
31
|
+
| `lock` | `doverunner-lock` |
|
|
32
|
+
| `database` | `doverunner-database` |
|
|
33
|
+
| `video` | `doverunner-video` |
|
|
34
|
+
| `media` | `doverunner-media` |
|
|
35
|
+
| `encoder` | `doverunner-encoder` |
|
|
36
|
+
| `storage` | `doverunner-storage` |
|
|
37
|
+
| `plugin` | `doverunner-plugin` |
|
|
38
|
+
| `variants` | `doverunner-variants` |
|
|
39
|
+
| `watermark` | `doverunner-watermark` |
|
|
40
|
+
| `bits-a`, `bits-b` | `doverunner-bits-a`, `doverunner-bits-b` |
|
|
41
|
+
|
|
42
|
+
A search and replace over `icon: "<name>"` does it. Or switch to Tabler icons and drop the renamed ones; see [icons](./icons.md).
|
|
43
|
+
|
|
44
|
+
### 2. The glyphs moved into the preset
|
|
45
|
+
|
|
46
|
+
The seven glyphs that lived in `pele-animate/glyphs` are now in `pele-animate/preset-doverunner`. `pele-animate/glyphs` is only the
|
|
47
|
+
registry (`icons`, `registerGlyphs`, `registerTabler`). If you use any `doverunner-*` glyph, import the preset:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import 'pele-animate/preset-doverunner';
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### New in 0.13
|
|
54
|
+
|
|
55
|
+
- Tabler icon packs: `pele-animate/tabler/<category>`, with the `--pa-stroke` variable.
|
|
56
|
+
- `icons()` returns a neutral rounded square for unknown names, instead of a blank slot.
|
|
57
|
+
|
|
58
|
+
A missed rename shows up as that rounded square, not as an error, so look for unexpected squares after upgrading.
|
package/docs/recipes.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Recipes
|
|
3
|
+
description: Using pele-animate in Vite, SvelteKit, Astro, Nuxt, React and plain HTML, with what has been tested.
|
|
4
|
+
order: 8
|
|
5
|
+
section: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Recipes
|
|
9
|
+
|
|
10
|
+
Pele and pele-animate need the DOM, so in every framework the rule is the same: **mount on the client, after the page has
|
|
11
|
+
rendered.** Load them with dynamic `import()` inside the framework's mounted hook so server rendering never touches them.
|
|
12
|
+
|
|
13
|
+
The shape is always:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
const [{ mount }, { watch }, { icons }] = await Promise.all([
|
|
17
|
+
import('pele'),
|
|
18
|
+
import('pele-animate'),
|
|
19
|
+
import('pele-animate/glyphs'),
|
|
20
|
+
import('pele-animate/tabler/computers'), // your icon categories
|
|
21
|
+
import('pele-animate/style.css'),
|
|
22
|
+
]);
|
|
23
|
+
mount(el, src, { icons });
|
|
24
|
+
watch(el, src);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Framework | Status | Where the code goes |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| Plain HTML / Vite | Tested | A module script, as in [getting started](./getting-started.md) |
|
|
30
|
+
| Astro | Tested in production (the DoveRunner docs site) | A client `<script>` that finds the diagram elements |
|
|
31
|
+
| SvelteKit 3 | Tested (build and browser, static adapter) | `onMount(async () => { ... })` in the page or component |
|
|
32
|
+
| Nuxt 4 | Tested (build and browser, static generate) | `onMounted` in a `.client.vue` component |
|
|
33
|
+
| React / Next.js | Not tested | A client component (`'use client'`) with `useEffect` |
|
|
34
|
+
| Vue (no Nuxt) | Not tested | `onMounted` |
|
|
35
|
+
|
|
36
|
+
Notes for all of them:
|
|
37
|
+
|
|
38
|
+
- Give each diagram its own element (`<pre>` or `<div>`) holding the Mermaid source, and call `mount` and `watch` once per
|
|
39
|
+
element.
|
|
40
|
+
- If the page changes without a reload (client-side routing), mount again for the new elements.
|
|
41
|
+
- Importing the CSS (`pele-animate/style.css`) once is enough. In TypeScript, a CSS side-effect import needs a `*.css` module
|
|
42
|
+
declaration (Vite projects get it from `vite/client`).
|
|
43
|
+
- Static site generators are fine: nothing here needs a server.
|
|
44
|
+
|
|
45
|
+
## Astro
|
|
46
|
+
|
|
47
|
+
```astro
|
|
48
|
+
<pre class="mermaid" set:text={src}></pre>
|
|
49
|
+
<script>
|
|
50
|
+
// runs in the browser only
|
|
51
|
+
import { mount } from 'pele';
|
|
52
|
+
import { watch } from 'pele-animate';
|
|
53
|
+
import { icons } from 'pele-animate/glyphs';
|
|
54
|
+
import 'pele-animate/tabler/computers';
|
|
55
|
+
import 'pele-animate/style.css';
|
|
56
|
+
document.querySelectorAll('pre.mermaid').forEach((el) => {
|
|
57
|
+
const src = el.textContent ?? '';
|
|
58
|
+
mount(el as HTMLElement, src, { icons });
|
|
59
|
+
watch(el as HTMLElement, src);
|
|
60
|
+
});
|
|
61
|
+
</script>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## SvelteKit
|
|
65
|
+
|
|
66
|
+
```svelte
|
|
67
|
+
<script>
|
|
68
|
+
import { onMount } from 'svelte';
|
|
69
|
+
let el;
|
|
70
|
+
const src = 'flowchart LR\n A --> B';
|
|
71
|
+
onMount(async () => {
|
|
72
|
+
const [{ mount }, { watch }, { icons }] = await Promise.all([
|
|
73
|
+
import('pele'), import('pele-animate'), import('pele-animate/glyphs'), import('pele-animate/style.css'),
|
|
74
|
+
]);
|
|
75
|
+
mount(el, src, { icons });
|
|
76
|
+
watch(el, src);
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
79
|
+
<div bind:this={el}></div>
|
|
80
|
+
```
|
package/docs/security.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Security
|
|
3
|
+
description: Untrusted diagram text, and what pele-animate adds.
|
|
4
|
+
order: 12
|
|
5
|
+
section: Reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Security
|
|
9
|
+
|
|
10
|
+
- **Diagram text.** Pele escapes diagram text, filters links and styles, and limits source and output size. Read Pele's
|
|
11
|
+
[security page](https://pele.run/security) before rendering diagrams you did not write. pele-animate does not weaken any of
|
|
12
|
+
that: it reads the SVG after Pele renders it.
|
|
13
|
+
- **Pins.** The `%% pa:` comment is parsed with a simple pattern (step numbers and ids). It cannot run code.
|
|
14
|
+
- **Glyph markup is trusted.** `registerGlyphs()` and `registerTabler()` insert your markup into the page as SVG. Register only
|
|
15
|
+
markup you wrote or reviewed. The bundled Tabler and `doverunner-*` packs are static files in the package.
|
|
16
|
+
- **No network.** pele-animate makes no requests and loads no remote assets.
|
|
17
|
+
- **No eval.** Nothing in the package uses `eval` or generates code, so a content security policy without `unsafe-eval` works.
|
|
18
|
+
|
|
19
|
+
Report a vulnerability by opening an issue on the [GitHub repository](https://github.com/dkdev24/pele-animate) that asks for a private contact. Leave the details out of the public issue.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Step order
|
|
3
|
+
description: Choose the order things appear in, and how step mode works.
|
|
4
|
+
order: 6
|
|
5
|
+
section: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Step order
|
|
9
|
+
|
|
10
|
+
Every diagram is a list of **steps**. The intro plays them one after another, and step mode lets the reader move through
|
|
11
|
+
them. By default, the order follows the edges. A `%% pa:` comment lets you set it yourself.
|
|
12
|
+
|
|
13
|
+
## Default order
|
|
14
|
+
|
|
15
|
+
- **Flowchart:** nodes appear by level, counting from the nodes nothing points to. Each edge draws from its source once the source
|
|
16
|
+
is on screen, and its target appears as the edge lands. Branches of a decision appear together.
|
|
17
|
+
- **Sequence diagram:** actors first, then the messages in order.
|
|
18
|
+
|
|
19
|
+
## Pins
|
|
20
|
+
|
|
21
|
+
Add one comment line anywhere in the source:
|
|
22
|
+
|
|
23
|
+
```mermaid live
|
|
24
|
+
flowchart LR
|
|
25
|
+
%% pa: 1=A 2=B 3=C
|
|
26
|
+
A[Request] --> B[Validate] --> C[Respond]
|
|
27
|
+
A --> C
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`%% pa: 1=A 2=B,C` means: step 1 shows A, step 2 shows B and C. Steps are numbered from 1. Anything you do not pin keeps its default
|
|
31
|
+
level.
|
|
32
|
+
|
|
33
|
+
### Edge pins
|
|
34
|
+
|
|
35
|
+
`X>Y` pins the edge from X to Y to its own step, so an edge between two nodes that are already visible can be a step:
|
|
36
|
+
|
|
37
|
+
```mermaid live
|
|
38
|
+
flowchart LR
|
|
39
|
+
%% pa: 1=A,B 2=C 3=A>B
|
|
40
|
+
A[Client] --> B[Server]
|
|
41
|
+
B --> C[Database]
|
|
42
|
+
B --> A
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Rules that avoid surprises:
|
|
46
|
+
|
|
47
|
+
- **Pin the nodes first.** An edge pinned before its target appears lands early.
|
|
48
|
+
- A two-way edge (`A <--> B`) is pinned in the direction you wrote it first (`A>B`).
|
|
49
|
+
- Do not rename node ids after pinning: pins match ids.
|
|
50
|
+
- Translated pages keep the same ids, so copy the `%% pa:` line across languages after checking the ids match.
|
|
51
|
+
|
|
52
|
+
## Step mode
|
|
53
|
+
|
|
54
|
+
Click the diagram, or focus it and press Enter or Space. A small bar appears with previous, play/pause and next.
|
|
55
|
+
|
|
56
|
+
| Key | Action |
|
|
57
|
+
|---|---|
|
|
58
|
+
| Space | Play or pause |
|
|
59
|
+
| → | Next step |
|
|
60
|
+
| ← | Previous step |
|
|
61
|
+
| Esc | Leave step mode |
|
|
62
|
+
|
|
63
|
+
Pass `{ controls: false }` as the third argument of `watch()` to turn step mode off; a click then just replays the intro.
|
|
64
|
+
|
|
65
|
+
## Checking your order
|
|
66
|
+
|
|
67
|
+
After `animate()` runs, `svg.paSteps` is one array per step. Print what each step shows:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const svg = document.querySelector('.pa-scene svg.pele');
|
|
71
|
+
svg.paSteps.map((items, n) => `${n + 1}: ` + items.map(([el]) => el.textContent.trim() || el.dataset.id).join(' ; '));
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`parseOrder(source)` returns the parsed pins as a `Map` (node id or `'X>Y'` to a 0-based step), if you want to check them
|
|
75
|
+
without a browser.
|
package/docs/theming.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Theming
|
|
3
|
+
description: Colors, dark mode, stroke width and reduced motion.
|
|
4
|
+
order: 7
|
|
5
|
+
section: Guides
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Theming
|
|
9
|
+
|
|
10
|
+
`watch()` adds the class `pa-scene` to the container. That class gives the diagram its tinted panel and its colors. The
|
|
11
|
+
defaults are written with `:where()`, so any rule in your stylesheet wins without a specificity fight.
|
|
12
|
+
|
|
13
|
+
## Variables
|
|
14
|
+
|
|
15
|
+
Set these on the container (or any ancestor):
|
|
16
|
+
|
|
17
|
+
| Variable | What it controls | Default (light) |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `--pa-bg` | Panel background | `#efeafa` |
|
|
20
|
+
| `--pa-solid` | Strong color: lines, icon strokes, accents | `#4F378B` |
|
|
21
|
+
| `--pa-light` | Light fill: icon fills, group surfaces | `#e4dcf6` |
|
|
22
|
+
| `--pa-stroke` | Stroke width of Tabler icons | `1.5` |
|
|
23
|
+
| `--pele-*` | Any of Pele's own variables (`--pele-fg`, `--pele-surface`, ...) | Set from the `--pa-*` values |
|
|
24
|
+
|
|
25
|
+
```css
|
|
26
|
+
.pa-scene {
|
|
27
|
+
--pa-bg: #f6f6f0;
|
|
28
|
+
--pa-solid: #0b5fff;
|
|
29
|
+
--pa-light: #dbe7ff;
|
|
30
|
+
--pa-stroke: 1.25;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
For the full list of `--pele-*` variables, see Pele's [theming docs](https://pele.run).
|
|
35
|
+
|
|
36
|
+
## Dark mode
|
|
37
|
+
|
|
38
|
+
Dark colors apply when the system prefers dark, unless the page sets `data-theme="light"` on the root element. To force dark,
|
|
39
|
+
set `data-theme="dark"` on the root element. Both follow the same variables, so overriding `--pa-solid` and friends works in
|
|
40
|
+
either mode.
|
|
41
|
+
|
|
42
|
+
## Reduced motion
|
|
43
|
+
|
|
44
|
+
With `prefers-reduced-motion: reduce`, the intro and the tokens do not play: the finished picture shows.
|
|
45
|
+
|
|
46
|
+
## Scene frame
|
|
47
|
+
|
|
48
|
+
The panel, its padding and rounded corners come from `.pa-scene`. Override `border-radius`, `padding` or `margin` on it directly.
|
package/package.json
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pele-animate",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"description": "Step-by-step animated Mermaid diagrams with icons: an unofficial add-on for the Pele renderer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/dkdev24/pele-animate#readme",
|
|
8
|
+
"packageManager": "pnpm@10.13.1",
|
|
9
|
+
"scripts": { "test": "node scripts/check-docs.mjs", "build": "pnpm -r --filter ./site build" },
|
|
8
10
|
"publishConfig": { "access": "public" },
|
|
9
11
|
"author": "Daniel Kim",
|
|
10
12
|
"repository": { "type": "git", "url": "git+https://github.com/dkdev24/pele-animate.git" },
|
|
11
13
|
"keywords": ["mermaid", "pele", "svg", "diagram", "animation"],
|
|
14
|
+
"types": "./types/index.d.ts",
|
|
12
15
|
"exports": {
|
|
13
|
-
".": "./pele-animate.js",
|
|
14
|
-
"./glyphs": "./glyphs.js",
|
|
15
|
-
"./preset-doverunner": "./preset-doverunner.js",
|
|
16
|
+
".": { "types": "./types/index.d.ts", "default": "./pele-animate.js" },
|
|
17
|
+
"./glyphs": { "types": "./types/glyphs.d.ts", "default": "./glyphs.js" },
|
|
18
|
+
"./preset-doverunner": { "types": "./types/preset-doverunner.d.ts", "default": "./preset-doverunner.js" },
|
|
16
19
|
"./style.css": "./pele-animate.css",
|
|
17
|
-
"./tabler/*": "./tabler/*.js"
|
|
20
|
+
"./tabler/*": { "types": "./types/tabler-pack.d.ts", "default": "./tabler/*.js" }
|
|
18
21
|
},
|
|
19
|
-
"files": ["pele-animate.js", "pele-animate.css", "glyphs.js", "preset-doverunner.js", "tabler", "THIRD-PARTY-NOTICES.md", "README.md", "LICENSE"],
|
|
22
|
+
"files": ["pele-animate.js", "pele-animate.css", "glyphs.js", "preset-doverunner.js", "tabler", "types", "docs", "skills", "THIRD-PARTY-NOTICES.md", "README.md", "LICENSE"],
|
|
20
23
|
"sideEffects": ["*.css", "./preset-doverunner.js", "./tabler/*.js"],
|
|
21
24
|
"peerDependencies": { "pele": "^1.7.0" },
|
|
22
25
|
"devDependencies": { "pele": "^1.7.0" }
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diagram-step-order
|
|
3
|
+
description: Review and fix the animation step order of pele-animate diagrams (Mermaid code blocks in document pages) against the page text, and tune groups, icons and labels so the flow reads clearly. Use when converting existing Mermaid diagrams to pele-animate, or when asked to check or adjust step order, `%% pa:` pins, or step-by-step playback of a diagram.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Diagram step order
|
|
7
|
+
|
|
8
|
+
Goal: when a viewer steps through a diagram (click, then ←/→), each step shows what the surrounding text says happens next.
|
|
9
|
+
|
|
10
|
+
## What controls the order
|
|
11
|
+
|
|
12
|
+
- **Flowcharts:** nodes appear by BFS level from the sources. An edge appears with its later end. `%% pa: 1=A,B 2=C` (first line inside the block, after the diagram type) pins nodes to steps. `%% pa: 3=A>B` pins the edge from A to B (needed for a reply or any edge between nodes that are already visible). Pin nodes first: an edge pinned before its target exists lands early. Unpinned nodes keep their BFS level; gaps in step numbers are skipped when stepping.
|
|
13
|
+
- **Sequence diagrams:** step 1 is the participants, then one step per message in source order. Pins do nothing. Reordering messages changes what the diagram says, so never do it silently: if the order disagrees with the text, report it.
|
|
14
|
+
- Ties: two edges into the same node share a step. Request and reply between the same two nodes land together unless the reply is edge-pinned.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
1. **Find the blocks** in the page and read the prose around each one (heading, the paragraph before and after, captions, numbered lists). Write down the order the text describes, one line per step.
|
|
19
|
+
2. **Probe the current order.** With the site running (restart a dev server after changing a locally copied library, then hard reload; a soft reload can show stale steps): open the page in a headless browser and evaluate `steps.js` in it (for example `agent-browser open <url>` then `agent-browser eval "$(cat steps.js)"`, or Playwright's `page.evaluate`). Each step prints its nodes, `[FROM_TO]` edges and quoted edge labels.
|
|
20
|
+
3. **Triage.**
|
|
21
|
+
- Sequence diagram: compare message order with the text, change nothing, flag mismatches.
|
|
22
|
+
- Linear chain or decision tree: BFS order is normally right (branches of a decision appear together). Say "no change" and why.
|
|
23
|
+
- Existing pins: a person tuned them. Keep their intent; refine only where the text clearly disagrees, and say so.
|
|
24
|
+
- Topology with lanes or groups: usually needs work.
|
|
25
|
+
4. **Fix** with pins and edge pins, then node declaration order and edge direction. Do not rename node ids (pins and CSS key on them) and do not change labels' meaning. Keep one idea per step: a request and its response are two steps; things that happen at the same moment share one.
|
|
26
|
+
5. **Appearance.** Follow the site's own diagram conventions file (group colour ids, icon set, label length). Within it: put nodes in groups by who owns them, use a glyph where one fits the meaning, keep edge labels to one short line, order nodes inside a lane so arrows run in the reading direction. Do not edit shared styles or the library; list any needed glyph or CSS as a follow-up.
|
|
27
|
+
6. **Mirror translations.** Translated pages have their own labels but the same node ids. Diff the ids between the two sources before copying a `%% pa:` line, then probe the translated page too.
|
|
28
|
+
7. **Re-probe** every changed diagram and confirm the printed steps match the order you wrote down in step 1.
|
|
29
|
+
|
|
30
|
+
## Lessons from the first run
|
|
31
|
+
|
|
32
|
+
- Probe every diagram you report on, linear chains included. "Read the source" is not a check; one run left some diagrams unprobed.
|
|
33
|
+
- A `<-->` edge is pinned in its first-written direction (`H>F` for `H <--> F`).
|
|
34
|
+
- When several agents work in parallel, give each its own browser session (`agent-browser --session <name>`) and tell them not to start, stop or restart the shared dev server.
|
|
35
|
+
- After changing a locally copied library, restart the dev server and clear its cache, or the page keeps the old module.
|
|
36
|
+
- Edge pins need a pele-animate release that supports them; until then they are ignored and the node order still applies.
|
|
37
|
+
- Tuned one language? Mirror the pins to the others in the same pass; a tuned EN page next to an untuned KO page is the usual miss.
|
|
38
|
+
|
|
39
|
+
## Report, one row per diagram
|
|
40
|
+
|
|
41
|
+
`page | n/total | before steps → after steps | one line tying the order to the text | changes (pins, groups, labels) | follow-ups`
|
|
42
|
+
|
|
43
|
+
Say "no change" with the reason when you leave one alone. The person reviewing reads this table, so keep each cell short and let the probe output carry the detail.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Paste into the browser (agent-browser eval "$(cat steps.js)"): lists, per animated diagram on the page, what each step reveals.
|
|
2
|
+
// Nodes by label, edges as [FROM_TO], edge labels in quotes. Relies on svg.paSteps, set by pele-animate animate().
|
|
3
|
+
(() => [...document.querySelectorAll('.pa-scene')].map((sc, i) => {
|
|
4
|
+
const svg = sc.querySelector('svg.pele');
|
|
5
|
+
if (!svg?.paSteps) return `#${i + 1} (no steps)`;
|
|
6
|
+
const kind = svg.classList.contains('pele-sequence') ? 'seq' : 'flow';
|
|
7
|
+
const txt = (el) => el.textContent.replace(/\s+/g, ' ').trim();
|
|
8
|
+
const lines = svg.paSteps.map((items, n) => ` ${n + 1}: ` + items.map(([el]) => {
|
|
9
|
+
if (el.classList.contains('pele-edge')) return `[${el.dataset.id.replace(/^L_/, '').replace(/_\d+$/, '')}]`;
|
|
10
|
+
if (el.classList.contains('pele-edge-label')) return `"${txt(el)}"`;
|
|
11
|
+
if (el.classList.contains('pele-lifeline')) return '|';
|
|
12
|
+
return txt(el) || el.dataset.id;
|
|
13
|
+
}).filter((x) => x !== '|').join(' ; ')).join('\n');
|
|
14
|
+
return `#${i + 1} ${kind}\n${lines}`;
|
|
15
|
+
}).join('\n'))()
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pele-animate
|
|
3
|
+
description: Add animated, step-by-step Mermaid diagrams to a project with pele-animate (an add-on for the Pele renderer): install, mount on the client, pick icons from the Tabler packs, set the step order with `%% pa:` pins, theme with CSS variables, and verify in a browser. Use whenever asked to animate Mermaid diagrams, add icons to a flowchart, or make a diagram step-through, or when the project already imports `pele-animate`. Do not use for plain static diagrams or other Mermaid renderers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pele-animate
|
|
7
|
+
|
|
8
|
+
pele-animate makes a [Pele](https://pele.run) diagram explain itself one step at a time: you choose the order things appear in,
|
|
9
|
+
readers step through it, and flowchart nodes can carry icons. It supports **flowcharts and sequence diagrams only**. Pele
|
|
10
|
+
does the layout; pele-animate is an unofficial add-on and not a theme package.
|
|
11
|
+
|
|
12
|
+
Your job when this skill is loaded: wire it into the project **and prove it renders**. Do not hand work back unverified.
|
|
13
|
+
|
|
14
|
+
## Hard rules
|
|
15
|
+
|
|
16
|
+
1. **Client only.** `pele` and `pele-animate` need the DOM. Load them with dynamic `import()` in the framework's mounted hook,
|
|
17
|
+
never in server code.
|
|
18
|
+
2. **Never invent icon names.** Unknown names do not fail: they render a plain rounded square. Look names up (see Icons) and
|
|
19
|
+
import the category that holds them.
|
|
20
|
+
3. **Import three things:** the resolver `icons` from `pele-animate/glyphs`, each icon category you use, and `pele-animate/style.css`.
|
|
21
|
+
4. **Do not rename node ids after pinning the order**: pins match ids.
|
|
22
|
+
5. **Verify in a browser** (last section). Reading the code is not a check.
|
|
23
|
+
|
|
24
|
+
## 1. Install
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm i pele-animate pele # or pnpm / yarn / bun; pele is a peer dependency (^1.7.0)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 2. Mount (client side)
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
const [{ mount }, { watch }, { icons }] = await Promise.all([
|
|
34
|
+
import('pele'), import('pele-animate'), import('pele-animate/glyphs'),
|
|
35
|
+
import('pele-animate/tabler/computers'), // one import per icon category you use
|
|
36
|
+
import('pele-animate/style.css'),
|
|
37
|
+
]);
|
|
38
|
+
mount(el, src, { icons }); // Pele draws the SVG from the Mermaid text in `src`
|
|
39
|
+
watch(el, src); // pele-animate animates it (also on resize)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`el` is an element that holds the Mermaid source: a `<pre>` whose text is the diagram, or any element you set first with
|
|
43
|
+
`el.textContent = src`. Mount once per element. `await` at the top level works in current Vite builds; elsewhere wrap the code
|
|
44
|
+
in an `async` function.
|
|
45
|
+
Framework placement (Vite, Astro, SvelteKit, Nuxt, React): `docs/recipes.md` in the package, or the table below.
|
|
46
|
+
|
|
47
|
+
| Framework | Put it in |
|
|
48
|
+
|---|---|
|
|
49
|
+
| Plain HTML / Vite | A module script |
|
|
50
|
+
| Astro | A client `<script>` that finds the diagram elements |
|
|
51
|
+
| SvelteKit | `onMount(async () => { ... })` |
|
|
52
|
+
| Nuxt | `onMounted` in a `.client.vue` component |
|
|
53
|
+
| React / Next.js (untested) | A client component, `useEffect` |
|
|
54
|
+
|
|
55
|
+
TypeScript: a CSS side-effect import needs a `*.css` module declaration unless the project uses Vite's client types.
|
|
56
|
+
|
|
57
|
+
## 3. Write the diagram
|
|
58
|
+
|
|
59
|
+
Icon nodes use Mermaid's own syntax:
|
|
60
|
+
|
|
61
|
+
```mermaid
|
|
62
|
+
flowchart LR
|
|
63
|
+
%% pa: 1=C 2=L 3=S
|
|
64
|
+
C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
|
|
65
|
+
L@{ icon: "load-balancer", form: "square", h: 88, label: "Load balancer" }
|
|
66
|
+
S@{ icon: "cloud-computing", form: "square", h: 88, label: "Cloud service" }
|
|
67
|
+
C <-->|route| L
|
|
68
|
+
L <-->|forward| S
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- `form: "square", h: 88` = large frameless icon. Leave both out for a small icon in a frame.
|
|
72
|
+
- **Sequence diagrams ignore icons** (the participant box shows its id).
|
|
73
|
+
- Keep node ids short and stable (`C`, `L`, `S`); labels are what people read.
|
|
74
|
+
|
|
75
|
+
### Icons: find the name, then import its category
|
|
76
|
+
|
|
77
|
+
4,368 Tabler outline icons in 36 categories, each its own module `pele-animate/tabler/<category>`. Category list with sample
|
|
78
|
+
names: `references/categories.md`. To find a name:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
# by keyword, across all categories (prints file:"name":)
|
|
82
|
+
grep -o '"[a-z0-9-]*server[a-z0-9-]*":' node_modules/pele-animate/tabler/*.js | head
|
|
83
|
+
# every name in one category
|
|
84
|
+
node -e "import('pele-animate/tabler/devices').then(m => console.log(Object.keys(m.pack).join(' ')))"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The file the keyword appears in tells you which category to import. A keyword grep also matches longer names (`user` matches
|
|
88
|
+
`user-bolt`), so confirm the exact name with an anchored check, e.g. `grep -l '"user":' node_modules/pele-animate/tabler/*.js`.
|
|
89
|
+
Abstract concepts often have no icon of their own (there is no `client`): pick a close synonym (`user`, `device-desktop`) and
|
|
90
|
+
label the node with the real word. Optional extras: `import 'pele-animate/preset-doverunner'`
|
|
91
|
+
adds 20 filled glyphs named `doverunner-<name>`; only use it if the project already does or the user asks for that look.
|
|
92
|
+
Custom glyphs: `registerGlyphs({ name: '<inner markup of a 24x24 svg>' })` from `pele-animate/glyphs`.
|
|
93
|
+
|
|
94
|
+
## 4. Step order
|
|
95
|
+
|
|
96
|
+
Default order follows the edges. Override with one comment line anywhere in the source:
|
|
97
|
+
|
|
98
|
+
- `%% pa: 1=A 2=B,C` : step 1 shows A, step 2 shows B and C (steps count from 1).
|
|
99
|
+
- `%% pa: 1=A,B 2=C 3=A>B` : `X>Y` pins the edge from X to Y to its own step. **Pin the nodes first.** A two-way edge
|
|
100
|
+
(`A <--> B`) is pinned in the direction you wrote first.
|
|
101
|
+
|
|
102
|
+
Click or Enter on a diagram starts step mode (prev / play / next; Space, ←, →, Esc). `watch(el, src, { controls: false })` turns that off.
|
|
103
|
+
To review the order of existing diagrams against the page text, use the `diagram-step-order` skill.
|
|
104
|
+
|
|
105
|
+
## 5. Theme
|
|
106
|
+
|
|
107
|
+
Set on the container (`.pa-scene`, added by `watch`): `--pa-bg` (panel), `--pa-solid` (strong color), `--pa-light` (light fill),
|
|
108
|
+
`--pa-stroke` (Tabler stroke width, default 1.5), plus any `--pele-*`. Dark mode follows `prefers-color-scheme`, or force it
|
|
109
|
+
with `data-theme="dark"` on the root element. `prefers-reduced-motion` turns the intro and tokens off.
|
|
110
|
+
|
|
111
|
+
## 6. Verify
|
|
112
|
+
|
|
113
|
+
Build or run the project, open the page in a headless browser, wait about 3 seconds (the intro starts when 30% of the diagram
|
|
114
|
+
is in view, so scroll it into view first), and evaluate `verify.js` (next to this file) in the page:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
agent-browser open http://localhost:PORT/page && agent-browser eval "$(cat verify.js)" # or Playwright page.evaluate
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Expect: `diagrams` equals the number you added; every `steps` entry above 0; `emptyIcons` empty; `fallbackIcons` empty unless a
|
|
121
|
+
plain square was intended. Fix by cause:
|
|
122
|
+
|
|
123
|
+
| Symptom | Cause |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `diagrams: 0` | `watch()` never ran: it was not client-side, or the element was not found |
|
|
126
|
+
| `fallbackIcons` lists a name | The name does not exist, or its category was not imported. Look it up again |
|
|
127
|
+
| Icons missing but names are right | The category import ran after `mount()`; import packs before mounting |
|
|
128
|
+
| `steps` is `[0]` or a single step | `%% pa:` pins mismatched ids, or the diagram type is unsupported |
|
|
129
|
+
| Looks unstyled | `pele-animate/style.css` not imported |
|
|
130
|
+
|
|
131
|
+
Print the order to compare with the text you meant: `svg.paSteps.map((items, n) => ...)`, or use `diagram-step-order/steps.js`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Tabler categories (generated by scripts/build-tabler.mjs; Tabler Icons 3.49.0, MIT)
|
|
2
|
+
|
|
3
|
+
Import `pele-animate/tabler/<category>`. Names below are a sample; the full list is the object keys in `node_modules/pele-animate/tabler/<category>.js`.
|
|
4
|
+
|
|
5
|
+
| Category | Icons | Sample names |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `system` | 784 | ad-circle-off, calendar-exclamation, dental-broken, filter-question, loader-2, pointer-cancel, shield-cog, tip-jar-euro |
|
|
8
|
+
| `devices` | 363 | access-point-off, browser-off, device-desktop-question, device-ipad-horizontal-cog, device-mobile-pin, device-usb, devices-star, power |
|
|
9
|
+
| `design` | 350 | ad-2, bounce-left, color-picker-off, droplet-star, inner-shadow-top-right, layout-grid, pencil-minus, sparkles-2-off |
|
|
10
|
+
| `arrows` | 333 | arrow-autofit-content, arrow-big-up, arrow-merge-alt-right, arrow-sharp-turn-right, arrows-move-vertical, chevrons-down, corner-up-left-double, square-chevrons-left |
|
|
11
|
+
| `map` | 263 | air-traffic-control, flag-pause, location-pin, map-pin-down, medical-cross, pennant-2, sign-left, world-heart |
|
|
12
|
+
| `document` | 209 | archive-off, clipboard-copy, file-cv, file-orientation, file-type-csv, file-zip, folder-stats, receipt-off |
|
|
13
|
+
| `text` | 194 | a-b-2, align-right-2, baseline-density-medium, copy-x, italic-off, overline, sort-ascending, text-regex-plus |
|
|
14
|
+
| `shapes` | 187 | border-corner-ios, circle-minus-2, cylinder-off, heart-plus, hexagonal-prism, pentagon-off, sphere-plus, square-rounded-minus |
|
|
15
|
+
| `media` | 160 | album-off, camera-plus, headset-off, music-cog, photo-cancel, photo-spark, playlist, rewind-forward-50 |
|
|
16
|
+
| `e-commerce` | 155 | backpack-off, basket-star, cash-plus, credit-card, package, shopping-bag-exclamation, shopping-cart-pause, tags-off |
|
|
17
|
+
| `communication` | 121 | address-book-off, mail-down, mail-up, message-2-off, message-check, message-circle-search, message-minus, messages-off |
|
|
18
|
+
| `food` | 96 | apple, bowl, carrot-off, cup, glass-off, lollipop-off, milkshake, salad |
|
|
19
|
+
| `buildings` | 95 | armchair-2-off, building-bridge, building-factory-2, building-stadium, home-2, home-hand, home-share, podium |
|
|
20
|
+
| `vehicles` | 90 | aerial-lift, camper, car-off, engine, motorbike, sailboat-off, steering-wheel, wheelchair |
|
|
21
|
+
| `math` | 88 | abacus-off, decimal, math-1-divide-3, math-integral, math-sin, math-xy, parentheses-off, sum |
|
|
22
|
+
| `health` | 87 | accessible-off, cane, dna-2, eye-table, flask-2, hospital-circle, pill-off, stethoscope |
|
|
23
|
+
| `sport` | 76 | acrobatic, barbell-off, cliff-jumping, hula-hoop, olympics, rugby, soccer-field, trekking |
|
|
24
|
+
| `currencies` | 76 | currency-afghani, currency-dollar-canadian, currency-euro, currency-krone-danish, currency-nano, currency-riyal, currency-tether, taiwan-dollar |
|
|
25
|
+
| `development` | 63 | a-b, api-book, auth-2fa, firewall-check, package-import, scan-traces, thinking-high, timeline-event |
|
|
26
|
+
| `weather` | 61 | cloud-bolt, cloud-fog, cloud-rain, cloud, moon-off, storm, sunset-2, tornado |
|
|
27
|
+
| `photography` | 52 | aperture-off, brightness-up, contrast, exposure, lens-convex, panorama-vertical-off, photo-sensor-3, shadow |
|
|
28
|
+
| `mood` | 52 | mood-angry, mood-confused, mood-heart, mood-nerd, mood-sad-2, mood-silence, mood-tongue-wink-2, mood-wrrr |
|
|
29
|
+
| `nature` | 50 | acorn, butterfly, clover-2, flame-off, leaf-maple, orbit-vertical, ripple-off, wind-electricity |
|
|
30
|
+
| `games` | 48 | archery-arrow, dice-5, ghost, pick, play-card-5, play-card-j, poker-chip, roulette |
|
|
31
|
+
| `computers` | 44 | binary-off, error-404-off, http-get-off, http-patch-off, http-que-off, network, topology-ring-3, topology-star-ring |
|
|
32
|
+
| `database` | 42 | column-insert-left, database-exclamation, database-off, database, row-remove, table-export, table-plus |
|
|
33
|
+
| `laundry` | 40 | bleach-chlorine, ironing-2, ironing, wash-dry-dip, wash-dry-p, wash-dryclean, wash-press, wash-temperature-5 |
|
|
34
|
+
| `charts` | 39 | chart-arcs-3, chart-arrows, chart-candle, chart-donut-2, chart-dots-3, chart-infographic, chart-pie-off, chart-scatter-3d |
|
|
35
|
+
| `symbols` | 37 | ankh, command-off, copyright-off, mars, peace, rating-16-plus, registered, venus |
|
|
36
|
+
| `badges` | 22 | award-off, badge-3d, badge-5k, badge-ad, badge-hd, badge-tm, badge-wc, badges |
|
|
37
|
+
| `electrical` | 19 | circuit-ammeter, circuit-capacitor-polarized, circuit-cell, circuit-diode, circuit-inductor, circuit-resistor, circuit-voltmeter |
|
|
38
|
+
| `animals` | 18 | bat, dog, fish-hook-off, fish, paw-off, pig-off |
|
|
39
|
+
| `gestures` | 17 | hand-click-off, hand-finger-left, hand-finger, hand-love-you, hand-off, hand-three-fingers |
|
|
40
|
+
| `version-control` | 16 | git-branch-check, git-branch-x, git-cherry-pick, git-compare, git-merge-queue, git-pull-request-closed, git-pull-request-draft, git-pull-request-unlisted |
|
|
41
|
+
| `extensions` | 13 | bmp, gif, jpg, pdf, sql, toml, zip |
|
|
42
|
+
| `logic` | 8 | logic-and, logic-buffer, logic-nand, logic-nor, logic-not, logic-or, logic-xnor, logic-xor |
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Evaluate in the page (e.g. `agent-browser eval "$(cat verify.js)"` or Playwright page.evaluate): did pele-animate render?
|
|
2
|
+
// Expect: diagrams = how many you added, every steps entry > 0, emptyIcons = [], and no name in `fallbackIcons` you meant to be real.
|
|
3
|
+
(() => {
|
|
4
|
+
const svgs = [...document.querySelectorAll('.pa-scene svg.pele')];
|
|
5
|
+
const icons = [...document.querySelectorAll('.pa-scene svg.pele-icon[data-icon]')];
|
|
6
|
+
// An unregistered name renders pele-animate's neutral rounded square: one <rect x="4" y="4" ...> and nothing else.
|
|
7
|
+
const fallback = (i) => /^<g[^>]*><rect x="4" y="4" width="16" height="16" rx="4"(\/>|><\/rect>)<\/g>$/.test(i.innerHTML.trim());
|
|
8
|
+
return JSON.stringify({
|
|
9
|
+
diagrams: svgs.length,
|
|
10
|
+
steps: svgs.map((s) => s.paSteps?.length ?? 0),
|
|
11
|
+
emptyIcons: icons.filter((i) => !i.innerHTML.trim()).map((i) => i.dataset.icon),
|
|
12
|
+
fallbackIcons: icons.filter(fallback).map((i) => i.dataset.icon),
|
|
13
|
+
});
|
|
14
|
+
})()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Theme colors the illustrated glyphs use: CSS variables with fallbacks. */
|
|
2
|
+
export const S: string;
|
|
3
|
+
export const L: string;
|
|
4
|
+
export const W: string;
|
|
5
|
+
|
|
6
|
+
/** Register glyphs: `{ name: '<inner markup of a 24x24 svg>' }`. Default stroke width 1.1. */
|
|
7
|
+
export function registerGlyphs(pack: Record<string, string>, strokeWidth?: number): void;
|
|
8
|
+
|
|
9
|
+
/** Register Tabler-style outline icons; stroke width follows the `--pa-stroke` CSS variable (fallback `strokeWidth`, default 1.5). */
|
|
10
|
+
export function registerTabler(pack: Record<string, string>, strokeWidth?: number): void;
|
|
11
|
+
|
|
12
|
+
/** Pele `icons` resolver. Unknown names return a neutral rounded square. */
|
|
13
|
+
export function icons(name: string): string;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface AnimateOptions {
|
|
2
|
+
/** Element that triggers the hover token animation. Default: the svg itself. */
|
|
3
|
+
hover?: Element;
|
|
4
|
+
/** The Mermaid source, read for `%% pa:` pins. */
|
|
5
|
+
source?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface WatchOptions {
|
|
9
|
+
/** `false` keeps the old click-to-replay instead of step mode. Default `true`. */
|
|
10
|
+
controls?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** One step: the elements that appear and, for each, the parts that pop in. */
|
|
14
|
+
export type PaStep = Array<[element: Element, parts: Element[]]>;
|
|
15
|
+
|
|
16
|
+
declare global {
|
|
17
|
+
interface SVGSVGElement {
|
|
18
|
+
/** Set by `animate()`: one array per step. */
|
|
19
|
+
paSteps?: PaStep[];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Read the `%% pa:` pins: node id, or `'X>Y'` for an edge, to a 0-based step. */
|
|
24
|
+
export function parseOrder(source?: string): Map<string, number>;
|
|
25
|
+
|
|
26
|
+
/** Animate one rendered Pele svg (flowchart or sequence diagram). */
|
|
27
|
+
export function animate(svg: SVGSVGElement, options?: AnimateOptions): void;
|
|
28
|
+
|
|
29
|
+
/** Animate every svg Pele renders into `container`, re-applying after Pele re-lays-out on resize. */
|
|
30
|
+
export function watch(container: HTMLElement, source?: string, options?: WatchOptions): void;
|
|
31
|
+
|
|
32
|
+
/** Play the intro again. */
|
|
33
|
+
export function replay(svg: SVGSVGElement | null | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|