pele-animate 0.16.2 → 0.17.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 CHANGED
@@ -9,7 +9,7 @@ step through it, and nodes can carry icons. A small post-processor for [Pele](ht
9
9
  which renders the Mermaid; this adds the step order, the playback and the icons. It is not a theme package.
10
10
  Unofficial add-on; not affiliated with or endorsed by the Pele or Obsidian teams.
11
11
 
12
- **[Website](https://pele-animate.pages.dev/) · [Docs](docs/getting-started.md) · [npm](https://www.npmjs.com/package/pele-animate) · [Changelog](CHANGELOG.md)**
12
+ **[Website](https://pele-animate.danielkimdev.com/) · [Docs](docs/getting-started.md) · [npm](https://www.npmjs.com/package/pele-animate) · [Changelog](CHANGELOG.md)**
13
13
 
14
14
  <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">
15
15
 
@@ -51,15 +51,17 @@ Mermaid source:
51
51
 
52
52
  ```mermaid-icons
53
53
  flowchart LR
54
- %% pa: 1=C 2=L 3=S
54
+ %% pa: 1=C 2=C>L 3=L>S 4=S>L 5=L>C
55
55
  C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
56
56
  L@{ icon: "load-balancer", form: "square", h: 88, label: "Load balancer" }
57
57
  S@{ icon: "cloud-computing", form: "square", h: 88, label: "Cloud service" }
58
- C <-->|route| L
59
- L <-->|forward| S
58
+ C -->|request| L
59
+ L -->|forward| S
60
+ S -->|response| L
61
+ L -->|reply| C
60
62
  ```
61
63
 
62
- `%% pa: 1=C 2=L 3=S` pins the order (optional). `form: "square", h: 88` makes a large frameless icon.
64
+ `%% pa: 1=C 2=C>L 3=L>S 4=S>L 5=L>C` pins the order: the request first, then each leg of the round trip (optional). `form: "square", h: 88` makes a large frameless icon.
63
65
 
64
66
  ## Documentation
65
67
 
package/docs/api.md CHANGED
@@ -13,10 +13,9 @@ TypeScript types ship with the package (`types/`).
13
13
 
14
14
  | Export | Signature | Description |
15
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. |
16
+ | `watch` | `watch(container: HTMLElement, source?: string): 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. |
17
17
  | `prepare` | `prepare(source?: string): string` | Returns the Mermaid source with icon-node labels padded so Pele lays out a box at least as wide as the icon (`h`). Pass its result to `mount()` and the original source to `watch()`. Without it, a label shorter than the icon puts edge ends and arrowheads under the icon. |
18
18
  | `animate` | `animate(svg: SVGSVGElement, options?: { hover?: Element; source?: string }): void` | Animates one rendered svg. `source` is read for `%% pa:` pins. Sets `svg.paSteps`. |
19
- | `replay` | `replay(svg: SVGSVGElement \| null \| undefined): void` | Plays the intro again. |
20
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. |
21
20
 
22
21
  `svg.paSteps` (type `PaStep[]`, where `PaStep = Array<[element: Element, parts: Element[]]>`) is set by `animate()`: one array per
@@ -64,11 +64,11 @@ sequenceDiagram
64
64
 
65
65
  `architecture-beta`: services in groups, joined by edges. Services appear in step order like flowchart nodes, groups stay visible,
66
66
  and `%% pa:` pins work the same way. The icon in parentheses is looked up in your icon packs, so Tabler names and `doverunner-*`
67
- names work (import the packs as for [icons](./icons.md)). The pins here follow a request: the user, the CDN, the API, the cache and database together, then the queue and worker.
67
+ names work (import the packs as for [icons](./icons.md)). The pins show the services first (the request path, then what sits behind the API), then trace the request one edge at a time with edge pins (`3=user>cdn`).
68
68
 
69
69
  ```mermaid-icons live title="Architecture: request path through CDN, API, cache, database and worker"
70
70
  architecture-beta
71
- %% pa: 1=user 2=cdn 3=api 4=cache,db 5=queue 6=worker
71
+ %% pa: 1=user,cdn,api 2=cache,db,queue,worker 3=user>cdn 4=cdn>api 5=api>cache 6=api>db 7=api>queue 8=queue>worker
72
72
  group edge(cloud)[Edge]
73
73
  group core(cloud)[Core]
74
74
  service user(device-desktop)[User]
@@ -96,7 +96,7 @@ start and end markers are nodes too, with the ids `root_start` and `root_end`, s
96
96
 
97
97
  ```mermaid live title="State: media player with loading, error and retry"
98
98
  stateDiagram-v2
99
- %% pa: 1=root_start 2=Idle 3=Loading 4=Playing 5=Paused 6=Error 7=root_end
99
+ %% pa: 1=root_start 2=Idle 3=Loading 4=Playing 5=Paused 6=Error 7=Error>Idle 8=root_end
100
100
  [*] --> Idle
101
101
  Idle --> Loading: play
102
102
  Loading --> Playing: ready
@@ -107,18 +107,18 @@ stateDiagram-v2
107
107
  Playing --> [*]: stop
108
108
  ```
109
109
 
110
- The pins give each state its own step, in the order a viewer meets them. Without pins the order is breadth-first from the start marker, which shows states at the same distance together (here `Playing` and `Error`). Pele gives
110
+ The pins give each state its own step, in the order a viewer meets them, and the `retry` transition (`Error>Idle`) its own step after `Error` is on screen. Without pins the order is breadth-first from the start marker, which shows states at the same distance together (here `Playing` and `Error`). Pele gives
111
111
  state edges no readable ids, so pele-animate finds each transition's ends from where its path starts and stops. Composite
112
112
  states and forks are untested. State diagrams take no icons.
113
113
 
114
114
  ## C4 context diagrams
115
115
 
116
116
  `C4Context`: people and systems appear in step order and each `Rel` draws from its source, with its label. Pins use the ids you
117
- give `Person(...)` and `System(...)`; an edge pin is `3=app>drm`. The example adds the DRM service, CDN and analytics one at a time, then the operator who reads the analytics.
117
+ give `Person(...)` and `System(...)`; an edge pin is `3=app>drm`. The example puts the landscape on screen first, then draws the relationships one at a time, then adds analytics and the operator who reads it.
118
118
 
119
119
  ```mermaid live title="C4 context: player app and the systems around it"
120
120
  C4Context
121
- %% pa: 1=viewer 2=app 3=drm 4=cdn 5=analytics 6=admin
121
+ %% pa: 1=viewer,app,drm,cdn 2=viewer>app 3=app>drm 4=app>cdn 5=analytics,admin 6=app>analytics 7=admin>analytics
122
122
  Person(viewer, "Viewer", "Watches video")
123
123
  System(app, "Player app", "Plays protected video")
124
124
  System_Ext(drm, "DRM service", "Issues licenses")
@@ -158,11 +158,11 @@ neighbour can give a bent arrow that runs along another one. Block diagrams take
158
158
  ## Class diagrams
159
159
 
160
160
  `classDiagram`: classes appear in step order, relationships draw from the class written first. `Media <|-- Video` reveals `Media`
161
- and then `Video`, whichever way the arrowhead points. Pins use the class names; the example shows the base class, its subtypes, then the classes that use them.
161
+ and then `Video`, whichever way the arrowhead points. Pins use the class names; the example shows the base class, its subtypes, the inheritance arrows as their own step, then the classes that use them. An edge pin may name the ends in either order, so `Video>Media` follows the arrow while the source says `Media <|-- Video`.
162
162
 
163
163
  ```mermaid live title="Class: media types, player and license"
164
164
  classDiagram
165
- %% pa: 1=Media 2=Video,Audio 3=Player 4=License 5=Session
165
+ %% pa: 1=Media 2=Video,Audio 3=Video>Media,Audio>Media 4=Player 5=License 6=Session
166
166
  Media <|-- Video
167
167
  Media <|-- Audio
168
168
  Player --> Media : plays
@@ -45,12 +45,14 @@ The Mermaid source:
45
45
 
46
46
  ```mermaid-icons live title="Icons: request, load balancer and cloud service"
47
47
  flowchart LR
48
- %% pa: 1=C 2=L 3=S
48
+ %% pa: 1=C 2=C>L 3=L>S 4=S>L 5=L>C
49
49
  C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
50
50
  L@{ icon: "load-balancer", form: "square", h: 88, label: "Load balancer" }
51
51
  S@{ icon: "cloud-computing", form: "square", h: 88, label: "Cloud service" }
52
- C <-->|route| L
53
- L <-->|forward| S
52
+ C -->|request| L
53
+ L -->|forward| S
54
+ S -->|response| L
55
+ L -->|reply| C
54
56
  ```
55
57
 
56
58
  What you get:
@@ -60,7 +62,7 @@ What you get:
60
62
  - Click, or focus and press Enter: **step mode**. Previous, play/pause and next buttons appear, and Space, ←, → and Esc work.
61
63
  - With `prefers-reduced-motion`, the motion is off and the finished picture shows.
62
64
 
63
- 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).
65
+ The `%% pa: 1=C 2=C>L 3=L>S 4=S>L 5=L>C` comment pins the order: the request first, then each leg of the round trip. Without it, the order follows the edges. See [step order](./step-order.md).
64
66
 
65
67
  ## Next
66
68
 
@@ -20,7 +20,6 @@ Two layers, one diagram:
20
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
21
  it, and re-applies after Pele re-draws on resize. The intro is skipped on those re-draws once it has played.
22
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
23
 
25
24
  ## The three kinds of motion
26
25
 
package/docs/icons.md CHANGED
@@ -61,7 +61,7 @@ Brand, Letters, Numbers, Zodiac and Gender are not included. Counts are for Tabl
61
61
 
62
62
  Do not guess names. Look them up:
63
63
 
64
- - The [icon browser](https://pele-animate.pages.dev/icons/) searches names and tags and copies a ready snippet; the same list is [icons.json](https://pele-animate.pages.dev/icons.json).
64
+ - The [icon browser](https://pele-animate.danielkimdev.com/icons/) searches names and tags and copies a ready snippet; the same list is [icons.json](https://pele-animate.danielkimdev.com/icons.json).
65
65
  - Tabler's own site, [tabler.io/icons](https://tabler.io/icons), lists names and categories (use the outline style).
66
66
  - In your project: `node_modules/pele-animate/tabler/<category>.js` lists every name in that category as an object key.
67
67
  - Names that exist in more than one place are not a problem: Tabler names are plain (`server`, `lock`), `doverunner-*` names are prefixed.
package/docs/migrating.md CHANGED
@@ -9,6 +9,10 @@ section: Reference
9
9
 
10
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
11
 
12
+ ## 0.16 to 0.17
13
+
14
+ `replay(svg)` and `watch(el, src, { controls: false })` are removed. A click or Enter on a diagram always enters step mode. To restart the intro yourself, remove the `pa-in` and `pa-done` classes from the svg, force a reflow, and add `pa-in` again.
15
+
12
16
  ## 0.12 to 0.13
13
17
 
14
18
  Two breaking changes.
@@ -51,6 +51,7 @@ flowchart LR
51
51
  Rules that avoid surprises:
52
52
 
53
53
  - **Pin the nodes first.** An edge pinned before its target appears lands early.
54
+ - Edge pins work in every diagram type that has edges, not only flowcharts.
54
55
  - A two-way edge (`A <--> B`) is pinned in the direction you wrote it first (`A>B`).
55
56
  - The ends may be named in either order (`Video>Media` or `Media>Video`), unless the diagram also has the opposite edge: then the order picks which of the two is meant.
56
57
  - Do not rename node ids after pinning: pins match ids.
@@ -67,8 +68,6 @@ Click the diagram, or focus it and press Enter or Space. A small bar appears wit
67
68
  | ← | Previous step |
68
69
  | Esc | Leave step mode |
69
70
 
70
- Pass `{ controls: false }` as the third argument of `watch()` to turn step mode off; a click then just replays the intro.
71
-
72
71
  ## Checking your order
73
72
 
74
73
  After `animate()` runs, `svg.paSteps` is one array per step. Print what each step shows:
package/package.json CHANGED
@@ -1,26 +1,68 @@
1
1
  {
2
2
  "name": "pele-animate",
3
- "version": "0.16.2",
3
+ "version": "0.17.0",
4
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" },
10
- "publishConfig": { "access": "public" },
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
11
  "author": "Daniel Kim",
12
- "repository": { "type": "git", "url": "git+https://github.com/dkdev24/pele-animate.git" },
13
- "keywords": ["mermaid", "pele", "svg", "diagram", "animation"],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/dkdev24/pele-animate.git"
15
+ },
16
+ "keywords": [
17
+ "mermaid",
18
+ "pele",
19
+ "svg",
20
+ "diagram",
21
+ "animation"
22
+ ],
14
23
  "types": "./types/index.d.ts",
15
24
  "exports": {
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" },
25
+ ".": {
26
+ "types": "./types/index.d.ts",
27
+ "default": "./pele-animate.js"
28
+ },
29
+ "./glyphs": {
30
+ "types": "./types/glyphs.d.ts",
31
+ "default": "./glyphs.js"
32
+ },
33
+ "./preset-doverunner": "./preset-doverunner.js",
19
34
  "./style.css": "./pele-animate.css",
20
- "./tabler/*": { "types": "./types/tabler-pack.d.ts", "default": "./tabler/*.js" }
35
+ "./tabler/*": {
36
+ "types": "./types/tabler-pack.d.ts",
37
+ "default": "./tabler/*.js"
38
+ }
39
+ },
40
+ "files": [
41
+ "pele-animate.js",
42
+ "pele-animate.css",
43
+ "glyphs.js",
44
+ "preset-doverunner.js",
45
+ "tabler",
46
+ "types",
47
+ "docs",
48
+ "skills",
49
+ "THIRD-PARTY-NOTICES.md",
50
+ "README.md",
51
+ "LICENSE"
52
+ ],
53
+ "sideEffects": [
54
+ "*.css",
55
+ "./preset-doverunner.js",
56
+ "./tabler/*.js"
57
+ ],
58
+ "peerDependencies": {
59
+ "pele": "^1.7.0"
60
+ },
61
+ "devDependencies": {
62
+ "pele": "^1.7.0"
21
63
  },
22
- "files": ["pele-animate.js", "pele-animate.css", "glyphs.js", "preset-doverunner.js", "tabler", "types", "docs", "skills", "THIRD-PARTY-NOTICES.md", "README.md", "LICENSE"],
23
- "sideEffects": ["*.css", "./preset-doverunner.js", "./tabler/*.js"],
24
- "peerDependencies": { "pele": "^1.7.0" },
25
- "devDependencies": { "pele": "^1.7.0" }
26
- }
64
+ "scripts": {
65
+ "test": "node scripts/check-docs.mjs",
66
+ "build": "pnpm -r --filter ./site build"
67
+ }
68
+ }
package/pele-animate.js CHANGED
@@ -319,8 +319,8 @@ function leaveStep(svg) {
319
319
  }
320
320
 
321
321
  // mount() re-renders on container resize; re-animate each new <svg>, skipping the intro once it has played.
322
- // Click (or Enter/Space) enters step mode: previous | play/pause | next, Space, ←/→, Esc to leave. `controls: false` keeps click-to-replay.
323
- export function watch(container, source = '', { controls = true } = {}) {
322
+ // Click (or Enter/Space) enters step mode: previous | play/pause | next, Space, ←/→, Esc to leave.
323
+ export function watch(container, source = '') {
324
324
  let played = false;
325
325
  let k = -1; // current step; -1 = not in step mode
326
326
  let timer = 0;
@@ -401,27 +401,14 @@ export function watch(container, source = '', { controls = true } = {}) {
401
401
  new MutationObserver(run).observe(container, { childList: true });
402
402
  container.classList.add('pa-scene');
403
403
  container.tabIndex = 0;
404
- container.title ||= controls ? 'Click to step through' : 'Click to replay';
405
- if (!controls) {
406
- container.addEventListener('click', () => replay(cur()));
407
- container.addEventListener('keydown', (e) => (e.key === 'Enter' || e.key === ' ') && (e.preventDefault(), replay(cur())));
408
- } else {
409
- container.addEventListener('click', () => k < 0 && enter());
410
- container.addEventListener('keydown', (e) => {
411
- const key = e.key;
412
- if (e.target.closest('button') && (key === 'Enter' || key === ' ')) return; // native button activation
413
- if (k < 0) return (key === 'Enter' || key === ' ') && (e.preventDefault(), enter());
414
- const act = { ' ': toggle, ArrowRight: () => manual(k + 1), ArrowLeft: () => manual(k - 1), Escape: exit }[key];
415
- if (act) { e.preventDefault(); act(); }
416
- });
417
- }
404
+ container.title ||= 'Click to step through';
405
+ container.addEventListener('click', () => k < 0 && enter());
406
+ container.addEventListener('keydown', (e) => {
407
+ const key = e.key;
408
+ if (e.target.closest('button') && (key === 'Enter' || key === ' ')) return; // native button activation
409
+ if (k < 0) return (key === 'Enter' || key === ' ') && (e.preventDefault(), enter());
410
+ const act = { ' ': toggle, ArrowRight: () => manual(k + 1), ArrowLeft: () => manual(k - 1), Escape: exit }[key];
411
+ if (act) { e.preventDefault(); act(); }
412
+ });
418
413
  run();
419
414
  }
420
-
421
- // Play the intro again (removing pa-in/pa-done restarts the CSS animations).
422
- export function replay(svg) {
423
- if (!svg || reduced()) return;
424
- svg.classList.remove('pa-in', 'pa-done');
425
- void svg.getBoundingClientRect();
426
- svg.classList.add('pa-in');
427
- }
@@ -60,12 +60,14 @@ Icon nodes use Mermaid's own syntax:
60
60
 
61
61
  ```mermaid-icons
62
62
  flowchart LR
63
- %% pa: 1=C 2=L 3=S
63
+ %% pa: 1=C 2=C>L 3=L>S 4=S>L 5=L>C
64
64
  C@{ icon: "http-get", form: "square", h: 88, label: "Request" }
65
65
  L@{ icon: "load-balancer", form: "square", h: 88, label: "Load balancer" }
66
66
  S@{ icon: "cloud-computing", form: "square", h: 88, label: "Cloud service" }
67
- C <-->|route| L
68
- L <-->|forward| S
67
+ C -->|request| L
68
+ L -->|forward| S
69
+ S -->|response| L
70
+ L -->|reply| C
69
71
  ```
70
72
 
71
73
  - `form: "square", h: 88` = large frameless icon. Leave both out for a small icon in a frame.
@@ -99,7 +101,7 @@ Default order follows the edges. Override with one comment line anywhere in the
99
101
  - `%% 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
102
  (`A <--> B`) is pinned in the direction you wrote first.
101
103
 
102
- Click or Enter on a diagram starts step mode (prev / play / next; Space, ←, →, Esc). `watch(el, src, { controls: false })` turns that off.
104
+ Click or Enter on a diagram starts step mode (prev / play / next; Space, ←, →, Esc).
103
105
  To review the order of existing diagrams against the page text, use the `diagram-step-order` skill.
104
106
 
105
107
  ## 5. Theme
package/types/index.d.ts CHANGED
@@ -5,11 +5,6 @@ export interface AnimateOptions {
5
5
  source?: string;
6
6
  }
7
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
8
  /** One step: the elements that appear and, for each, the parts that pop in. */
14
9
  export type PaStep = Array<[element: Element, parts: Element[]]>;
15
10
 
@@ -29,7 +24,4 @@ export function animate(svg: SVGSVGElement, options?: AnimateOptions): void;
29
24
  /** Animate every svg Pele renders into `container`, re-applying after Pele re-lays-out on resize. */
30
25
  /** Pad icon-node labels narrower than `h` so Pele's layout box is at least as wide as the drawn icon. Use as `mount(el, prepare(src), { icons })`; pass the original `src` to `watch()`. */
31
26
  export function prepare(source?: string): string;
32
- export function watch(container: HTMLElement, source?: string, options?: WatchOptions): void;
33
-
34
- /** Play the intro again. */
35
- export function replay(svg: SVGSVGElement | null | undefined): void;
27
+ export function watch(container: HTMLElement, source?: string): void;
@@ -1 +0,0 @@
1
- export {};