flowchart-sequence-designer 1.0.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/CHANGELOG.md +159 -0
- package/LICENSE +21 -0
- package/README.md +469 -0
- package/dist/.metafile-core.json +251 -0
- package/dist/.metafile-ui.json +797 -0
- package/dist/index.cjs +855 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +398 -0
- package/dist/index.d.ts +398 -0
- package/dist/index.js +817 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/index.cjs +4596 -0
- package/dist/ui/index.cjs.map +1 -0
- package/dist/ui/index.d.cts +356 -0
- package/dist/ui/index.d.ts +356 -0
- package/dist/ui/index.js +4563 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +77 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `flowchart-sequence-designer` are documented here.
|
|
4
|
+
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
Versioning: [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- `themeOverrides` prop on `DiagramEditor` and `SequenceEditor` — a
|
|
11
|
+
`Partial<ThemeColors>` (or `Partial<SequenceThemeColors>`) shallow-merged on
|
|
12
|
+
top of the resolved light/dark palette so consumers can match the editor to
|
|
13
|
+
their brand without forking. `ThemeColors` and `SequenceThemeColors` are now
|
|
14
|
+
exported from `flowchart-sequence-designer/ui`.
|
|
15
|
+
- Multi-selection on the canvas. `Shift+click` a node to toggle it in/out of
|
|
16
|
+
the selection. `Shift+drag` on the empty canvas runs a box-select (adds
|
|
17
|
+
every intersected node to the current selection). `Delete`, `Ctrl+D`, and
|
|
18
|
+
arrow-key nudging now apply to every selected node. Dragging any selected
|
|
19
|
+
node moves the whole group. The Delete button in the controls bar shows the
|
|
20
|
+
current count when more than one node is selected.
|
|
21
|
+
- `Ctrl+C` / `Ctrl+V` copy and paste. Copy snapshots the selected nodes plus
|
|
22
|
+
the edges that connect them, paste materializes fresh IDs offset by 24px
|
|
23
|
+
and re-selects the new nodes.
|
|
24
|
+
- Alignment guides and snap-to-sibling. When dragging a single node, dashed
|
|
25
|
+
indigo guide lines appear whenever its left/center/right or top/middle/
|
|
26
|
+
bottom edge lines up with another node, and the position snaps within a
|
|
27
|
+
4-pixel threshold. Group drags preserve relative offsets and skip the snap.
|
|
28
|
+
- Edge waypoint rerouting. Hover an edge to reveal a handle at its midpoint;
|
|
29
|
+
drag it to set a manual routing waypoint and the edge re-renders as two
|
|
30
|
+
smooth bezier segments through that point. `DiagramEdge.waypoint` is
|
|
31
|
+
persisted in JSON exports and ignored by the Mermaid / PlantUML serializers
|
|
32
|
+
(those formats don't encode routing). Right-click an edge → "Reset routing"
|
|
33
|
+
to clear the waypoint.
|
|
34
|
+
- Touch long-press opens the canvas context menu (Add node here, Re-center,
|
|
35
|
+
Undo, Redo). Significant finger movement cancels the gesture.
|
|
36
|
+
- Port circles grow from 6 to 9 px on `(pointer: coarse)` devices and stay
|
|
37
|
+
permanently visible (instead of fading in on hover) so they're tappable on
|
|
38
|
+
touch.
|
|
39
|
+
- `Alt+Arrow` traverses the graph from the currently selected node — picks the
|
|
40
|
+
nearest sibling in the chosen direction (45° cone, Euclidean nearest). Plain
|
|
41
|
+
arrow keys still nudge as before; the `Alt` modifier disambiguates.
|
|
42
|
+
- Focus-visible outlines on every focusable control inside the editor (buttons,
|
|
43
|
+
inputs, role="button" nodes, the canvas itself) using the active accent
|
|
44
|
+
color, so keyboard users always see where focus lives.
|
|
45
|
+
- `bun run analyze` — esbuild-metafile bundle analyzer that prints minified
|
|
46
|
+
bundle size + top input contributors per entry point, and writes
|
|
47
|
+
`dist/.metafile-{core,ui}.json` for a visual treemap on
|
|
48
|
+
esbuild.github.io/analyze. Useful before shipping any bundle-shape change.
|
|
49
|
+
- Built-in sample diagrams. `DiagramEditor` and `SequenceEditor` now fall
|
|
50
|
+
back to a small working preset when mounted without `initialModel` — a
|
|
51
|
+
6-node order-flow for the flowchart variant, a 3-answer role picker for
|
|
52
|
+
question, a 5-step onboarding for journey, and a 3-actor login handshake
|
|
53
|
+
for sequence. New exports `presetFlowchartModel(variant?)`,
|
|
54
|
+
`presetSequenceModel()`, and `emptyModel(type, variant?)` (the latter is
|
|
55
|
+
the opt-out for consumers who explicitly want a blank canvas).
|
|
56
|
+
- Demo (live site) gains a Sequence tab so all four variants are
|
|
57
|
+
reachable from the same nav, each booting with its preset diagram.
|
|
58
|
+
- Import dialog. Clicking **↑ Import** in the toolbar now opens a proper
|
|
59
|
+
modal with a paste-area, a file picker (`.json` / `.mmd` / `.mermaid` /
|
|
60
|
+
`.txt`), live format detection (`{` → JSON, otherwise Mermaid), error
|
|
61
|
+
feedback, focus trap, and Esc/backdrop dismissal. Replaces the previous
|
|
62
|
+
`window.prompt()` one-liner that couldn't fit a multi-line Mermaid graph
|
|
63
|
+
or accept file uploads at all.
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
- Internal refactor: the 1500-line `DiagramEditor.tsx` monolith is split into
|
|
67
|
+
focused modules (`layout.ts`, `theme.ts`, `render.tsx`, `NodeNavigator.tsx`,
|
|
68
|
+
`ContextMenu.tsx`, `hooks/useHistory.ts`, `hooks/useSystemTheme.ts`). No
|
|
69
|
+
public API or visual change — the file is now ~770 lines and the render
|
|
70
|
+
layer can be imported in isolation.
|
|
71
|
+
- Further refactor: extracted three more canvas hooks —
|
|
72
|
+
`hooks/useCanvasWheel.ts` (cursor-anchored zoom), `hooks/useCanvasTouch.ts`
|
|
73
|
+
(pan/pinch/long-press), and `hooks/useElementSize.ts` (ResizeObserver
|
|
74
|
+
viewport tracking) — and added a `nodeDims(node, variant)` helper to
|
|
75
|
+
`layout.ts` that collapses the repeated `variant === 'question' ? ... : ...`
|
|
76
|
+
width/height ternary. `DiagramEditor.tsx` is now ~990 lines.
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
- Sequence diagram new-message ID collision. `addMessage()` minted IDs from
|
|
80
|
+
a module-level counter starting at zero, so the first added message got
|
|
81
|
+
`m1` — the same ID as the preset's first message. Selection state holds
|
|
82
|
+
one ID, so clicking the new row highlighted both rows that shared the
|
|
83
|
+
collided ID. Replaced with `nextMsgId(messages)` which scans existing
|
|
84
|
+
IDs matching `/^m(\d+)$/` and returns `m{max+1}`, eliminating any chance
|
|
85
|
+
of collision with the preset or with imported diagrams.
|
|
86
|
+
- Sequence diagram message reorder. The previous drag handler ran
|
|
87
|
+
`reorderMessage` (which mutates the model + pushes history) on every
|
|
88
|
+
mouse-move tick, so a single drag could cascade through neighboring rows,
|
|
89
|
+
swap labels onto the wrong lifeline, and clog the undo stack with hundreds
|
|
90
|
+
of intermediate states. The new implementation seeds drag state on
|
|
91
|
+
mousedown, waits for a 5-pixel threshold before activating, renders the
|
|
92
|
+
dragged row in a virtual "preview" position via `useMemo` without touching
|
|
93
|
+
`messages`, and commits the reorder exactly once on mouseup. Window-level
|
|
94
|
+
`mousemove`/`mouseup` listeners replace the SVG-scoped handlers, so
|
|
95
|
+
releasing outside the canvas still ends the drag cleanly.
|
|
96
|
+
- Node drag operations now push to the undo history. Previously the drag
|
|
97
|
+
mutated state directly and was lost on `Ctrl+Z`.
|
|
98
|
+
- Edge `style: 'dashed'` and `style: 'dotted'` now render with the correct
|
|
99
|
+
dash pattern on the canvas. The previous render path computed the pattern
|
|
100
|
+
but discarded it — the animated `edge-flow` class overrode the value with
|
|
101
|
+
its own dasharray, so every edge looked solid regardless of style. The
|
|
102
|
+
animation now only runs on edges whose style is `'solid'` (the default);
|
|
103
|
+
explicitly dashed/dotted edges render statically with the user's chosen
|
|
104
|
+
pattern. Mermaid / PlantUML / JSON / SVG export already serialized the
|
|
105
|
+
style correctly — this was a canvas-only regression.
|
|
106
|
+
|
|
107
|
+
## [1.0.0] - 2026-05-16
|
|
108
|
+
|
|
109
|
+
First stable release. The package is now published on npm and considered
|
|
110
|
+
production-ready for the documented surface area.
|
|
111
|
+
|
|
112
|
+
### Added
|
|
113
|
+
- `LICENSE` (MIT).
|
|
114
|
+
- `CHANGELOG.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`.
|
|
115
|
+
- GitHub issue templates and pull request template.
|
|
116
|
+
- CI workflow that runs `bun test`, typecheck, and build on every push and PR.
|
|
117
|
+
- `repository`, `bugs`, `homepage` metadata in `package.json`.
|
|
118
|
+
- `sideEffects: false` for better tree-shaking.
|
|
119
|
+
- `Model.validate()` returns structural problems (dangling edge refs, duplicate IDs)
|
|
120
|
+
without throwing — used by tooling and surfaced in the editor UI.
|
|
121
|
+
- `Model.setVariant()` and persistent `variant` field on `DiagramModel` so the UI
|
|
122
|
+
variant (flowchart / question / journey) survives JSON round-trips.
|
|
123
|
+
- Mermaid importer now strips `%% comments`, `mermaid.initialize(...)` blocks,
|
|
124
|
+
`classDef` / `class` / `style` / `linkStyle` / `click` directives, and parses
|
|
125
|
+
`subgraph` blocks by tagging contained nodes with `metadata.group`.
|
|
126
|
+
- Redesigned SVG canvas: smooth cubic-bezier edges, dot grid, drop shadows,
|
|
127
|
+
glowing selection ring, indigo/slate palette. `StepEditor` matches with
|
|
128
|
+
indigo accent and softer card styling.
|
|
129
|
+
|
|
130
|
+
### Changed
|
|
131
|
+
- `Model.addEdge()` now throws on edges that reference unknown source/target
|
|
132
|
+
node IDs (previously accepted silently). Use `Model.validate()` to inspect
|
|
133
|
+
imported data without throwing.
|
|
134
|
+
- SVG / PNG exporter rewritten to mirror the canvas visuals — question nodes,
|
|
135
|
+
dynamic widths, bezier edges, dot grid, and drop shadows. Previously exports
|
|
136
|
+
used a primitive BFS grid layout with straight lines and no question-node
|
|
137
|
+
support.
|
|
138
|
+
|
|
139
|
+
### Fixed
|
|
140
|
+
- Mermaid exporter now emits `-.->` for dashed/dotted edges (previously
|
|
141
|
+
collapsed all styles to `-->`). PlantUML exporter emits `-[dashed]->` and
|
|
142
|
+
`-[dotted]->` for non-solid styles.
|
|
143
|
+
- Mermaid importer edge regex anchors correctly so node IDs containing `{[(`
|
|
144
|
+
characters no longer bleed into the connector.
|
|
145
|
+
|
|
146
|
+
## [0.1.0] - 2026-05
|
|
147
|
+
|
|
148
|
+
### Added
|
|
149
|
+
- Initial release.
|
|
150
|
+
- Programmatic API: `flowchart()`, `sequence()`, `Model` class.
|
|
151
|
+
- Exporters: Mermaid, PlantUML, JSON, SVG, PNG.
|
|
152
|
+
- Importers: Mermaid, JSON.
|
|
153
|
+
- React UI: `DiagramEditor` component with pan/zoom canvas, drag-to-connect, undo/redo, context menu, node navigator, light/dark/auto theme.
|
|
154
|
+
- Diagram variants: `flowchart`, `question`, `journey`.
|
|
155
|
+
- GitHub Pages live demo with developer docs.
|
|
156
|
+
|
|
157
|
+
[Unreleased]: https://github.com/ag-gr-hub/flowchart-sequence-designer/compare/v1.0.0...HEAD
|
|
158
|
+
[1.0.0]: https://github.com/ag-gr-hub/flowchart-sequence-designer/compare/v0.1.0...v1.0.0
|
|
159
|
+
[0.1.0]: https://github.com/ag-gr-hub/flowchart-sequence-designer/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ag-gr-hub
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
# flowchart-sequence-designer
|
|
2
|
+
|
|
3
|
+
A TypeScript-first Bun/npm package for building and editing flowchart and sequence diagrams — both programmatically via a fluent API and visually via a React drag-and-drop canvas editor.
|
|
4
|
+
|
|
5
|
+
**🔗 [Live demo & developer docs →](https://ag-gr-hub.github.io/flowchart-sequence-designer/)**
|
|
6
|
+
Open it to drive the editor, switch variants (Flowchart / Question / Journey / Sequence), and copy the same API snippets shown below straight from the docs tab. Every variant boots with a working sample diagram so you can poke without any setup.
|
|
7
|
+
|
|
8
|
+
## Quick start
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { DiagramEditor } from 'flowchart-sequence-designer/ui';
|
|
12
|
+
|
|
13
|
+
export default function App() {
|
|
14
|
+
return <DiagramEditor height={520} onChange={(m) => console.log(m)} />;
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
That's it — no provider, no theme setup, no required props. The editor
|
|
19
|
+
mounts with a sample diagram, a working toolbar, undo/redo, drag-to-pan,
|
|
20
|
+
scroll-to-zoom, and export buttons for Mermaid / PlantUML / JSON / SVG /
|
|
21
|
+
PNG. Pass `theme="dark"` or `themeOverrides={…}` to brand-match, or
|
|
22
|
+
`initialModel={emptyModel('flowchart')}` to start blank.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bun add flowchart-sequence-designer
|
|
28
|
+
# or
|
|
29
|
+
npm install flowchart-sequence-designer
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
React 18+ is a peer dependency for the UI components. The core API has zero runtime dependencies.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Programmatic API
|
|
37
|
+
|
|
38
|
+
### Flowchart
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { flowchart } from 'flowchart-sequence-designer';
|
|
42
|
+
|
|
43
|
+
const diagram = flowchart('Order Flow')
|
|
44
|
+
.node('start', 'Start', { shape: 'circle' })
|
|
45
|
+
.node('check', 'Payment valid?', { shape: 'diamond' })
|
|
46
|
+
.node('success', 'Confirm order', { shape: 'rectangle' })
|
|
47
|
+
.node('fail', 'Reject', { shape: 'rectangle' })
|
|
48
|
+
.edge('start', 'check')
|
|
49
|
+
.edge('check', 'success', { label: 'Yes' })
|
|
50
|
+
.edge('check', 'fail', { label: 'No' });
|
|
51
|
+
|
|
52
|
+
console.log(diagram.toMermaid());
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Node shapes
|
|
56
|
+
|
|
57
|
+
| Shape | Description |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `rectangle` | Standard process box (default) |
|
|
60
|
+
| `diamond` | Decision / branch |
|
|
61
|
+
| `circle` | Start or end terminal |
|
|
62
|
+
| `parallelogram` | Input / output |
|
|
63
|
+
|
|
64
|
+
#### Edge options
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
.edge(from, to, {
|
|
68
|
+
label?: string,
|
|
69
|
+
style?: 'solid' | 'dashed' | 'dotted',
|
|
70
|
+
arrowhead?: 'arrow' | 'open' | 'none',
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Sequence diagram
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { sequence } from 'flowchart-sequence-designer';
|
|
80
|
+
|
|
81
|
+
const diagram = sequence('Auth Flow')
|
|
82
|
+
.actor('User')
|
|
83
|
+
.actor('Server')
|
|
84
|
+
.message('User', 'Server', 'POST /login')
|
|
85
|
+
.message('Server', 'User', '200 OK + token', { style: 'dashed' });
|
|
86
|
+
|
|
87
|
+
console.log(diagram.toMermaid());
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Actors auto-register from `message()` calls, so you can skip `.actor()` if you prefer.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Export formats
|
|
95
|
+
|
|
96
|
+
Every builder exposes the same export methods:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
diagram.toMermaid() // string
|
|
100
|
+
diagram.toPlantUML() // string
|
|
101
|
+
diagram.toJSON() // string (serialised DiagramModel)
|
|
102
|
+
diagram.toSVG() // string (SVG markup)
|
|
103
|
+
diagram.toPNG() // Promise<Blob> (browser only)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### Import
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { fromMermaid, fromJSON } from 'flowchart-sequence-designer';
|
|
112
|
+
|
|
113
|
+
const model = fromMermaid('graph TD; A-->B; B-->C');
|
|
114
|
+
const model2 = fromJSON(jsonString);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Round-trip fidelity: `fromMermaid(diagram.toMermaid())` produces an equivalent model.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### Exporter / importer round-trip rules
|
|
122
|
+
|
|
123
|
+
The five export formats trade fidelity for portability. Use this table to
|
|
124
|
+
pick the one that matches what you need:
|
|
125
|
+
|
|
126
|
+
| Format | Round-trip | Preserved | Dropped or lossy |
|
|
127
|
+
|---|---|---|---|
|
|
128
|
+
| **JSON** | ✅ full | every field — `variant`, `metadata`, `waypoint`, x/y positions, edge arrowheads, message order | nothing |
|
|
129
|
+
| **Mermaid (flowchart)** | partial | node shapes (`[]` `{}` `(())` `[/]`), labels, edge connectors (`-->`, `-.->`, `---`, `-.-`), edge labels, `subgraph` → `metadata.group` | positions, `waypoint`, `metadata.answers`, `variant`. Dotted edges collapse to dashed. |
|
|
130
|
+
| **Mermaid (sequence)** | partial | actor order, message arrows (`->>`, `-->>`), labels | message metadata, styling overrides |
|
|
131
|
+
| **PlantUML (flowchart)** | export-only | edge styles (`-->` / `-[dashed]->` / `-[dotted]->`), labels, node id | shape distinctions (PlantUML state-diagram syntax is coarser), positions, `metadata`, `variant` |
|
|
132
|
+
| **PlantUML (sequence)** | export-only | actor order, message style (`->`, `-->`), labels | – |
|
|
133
|
+
| **SVG** | export-only (rendered) | full visual parity with the canvas — same dot grid, same edge curves, same node styling | – |
|
|
134
|
+
| **PNG** | export-only (rendered, **browser-only**) | same as SVG, rasterized at `devicePixelRatio` | – |
|
|
135
|
+
|
|
136
|
+
If you need 100% round-trip fidelity, use JSON. If you need a format that
|
|
137
|
+
GitHub renders inline in markdown, use Mermaid. If you need a polished
|
|
138
|
+
image for documentation, use SVG or PNG.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### Presets
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import {
|
|
146
|
+
presetFlowchartModel,
|
|
147
|
+
presetSequenceModel,
|
|
148
|
+
emptyModel,
|
|
149
|
+
} from 'flowchart-sequence-designer/ui';
|
|
150
|
+
|
|
151
|
+
presetFlowchartModel('flowchart') // 6-node order flow with one decision
|
|
152
|
+
presetFlowchartModel('question') // 1-question / 3-answer router
|
|
153
|
+
presetFlowchartModel('journey') // 5-step onboarding sequence
|
|
154
|
+
presetSequenceModel() // 3-actor login handshake
|
|
155
|
+
|
|
156
|
+
emptyModel('flowchart') // { type:'flowchart', variant:'flowchart', nodes:[], edges:[] }
|
|
157
|
+
emptyModel('flowchart', 'journey') // same with variant: 'journey'
|
|
158
|
+
emptyModel('sequence') // { type:'sequence', nodes:[], edges:[], actors:[], messages:[] }
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
All presets return a deep clone — mutate the result freely.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Working with the model directly
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { Model } from 'flowchart-sequence-designer';
|
|
169
|
+
import type { DiagramModel } from 'flowchart-sequence-designer';
|
|
170
|
+
|
|
171
|
+
const m = new Model({ type: 'flowchart', nodes: [], edges: [] });
|
|
172
|
+
m.addNode({ id: 'a', label: 'Step A', shape: 'rectangle' });
|
|
173
|
+
m.addNode({ id: 'b', label: 'Step B', shape: 'rectangle' });
|
|
174
|
+
m.addEdge({ id: 'e1', from: 'a', to: 'b', label: 'next' });
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## React UI component
|
|
180
|
+
|
|
181
|
+
Import from the `/ui` sub-entry to keep React out of the bundle for non-UI consumers:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { DiagramEditor } from 'flowchart-sequence-designer/ui';
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Basic usage
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
<DiagramEditor />
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Mounted without an `initialModel` the editor boots with a small working
|
|
194
|
+
sample diagram for the chosen `variant` — a 6-node order-flow for
|
|
195
|
+
`flowchart`, a role-picker for `question`, a 5-step onboarding for
|
|
196
|
+
`journey`, and a 3-actor login handshake for the `SequenceEditor`. This
|
|
197
|
+
gives anyone evaluating the package something to interact with from the
|
|
198
|
+
first render. To start blank instead:
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import { DiagramEditor, emptyModel } from 'flowchart-sequence-designer/ui';
|
|
202
|
+
|
|
203
|
+
<DiagramEditor initialModel={emptyModel('flowchart')} />
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The presets are also exported in case you want to hydrate them from your
|
|
207
|
+
own code: `presetFlowchartModel(variant?)` and `presetSequenceModel()`.
|
|
208
|
+
|
|
209
|
+
### All props
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
<DiagramEditor
|
|
213
|
+
initialModel={model} // pre-load a DiagramModel
|
|
214
|
+
onChange={(m) => save(m)} // fires on every node/edge change
|
|
215
|
+
onExport={(fmt, content) => …} // intercept exports instead of auto-downloading
|
|
216
|
+
height="100%" // any CSS height (default: 600)
|
|
217
|
+
variant="flowchart" // 'flowchart' | 'question' | 'journey'
|
|
218
|
+
theme="auto" // 'light' | 'dark' | 'auto'
|
|
219
|
+
allowedExports={['json','svg']} // restrict visible export buttons
|
|
220
|
+
allowImport={true} // show/hide the Import button
|
|
221
|
+
themeOverrides={{ // optional per-color overrides
|
|
222
|
+
canvas: '#0b0f1a',
|
|
223
|
+
nodeSelectedFill: '#1f2a44',
|
|
224
|
+
}}
|
|
225
|
+
/>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### Diagram variants
|
|
231
|
+
|
|
232
|
+
| Variant | Description |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `flowchart` | General purpose — any shapes, freeform connections |
|
|
235
|
+
| `question` | Each node is a question with lettered answer options (A, B, C…). Each answer has its own connection port. |
|
|
236
|
+
| `journey` | Numbered milestone steps — user path or process walkthrough |
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### Editor features
|
|
241
|
+
|
|
242
|
+
**Canvas**
|
|
243
|
+
- Drag nodes to reposition (snaps to 24px grid)
|
|
244
|
+
- Scroll to zoom in/out (pinch to zoom on touch)
|
|
245
|
+
- Drag the canvas background to pan (one-finger pan on touch)
|
|
246
|
+
- Double-click a node to rename it inline
|
|
247
|
+
- Dashed alignment guides appear when a dragged node lines up with a sibling's edge or center, and it snaps within 4 px
|
|
248
|
+
- Bottom-right minimap — click or drag to pan the viewport
|
|
249
|
+
- Accessibility: every node, port, and control is keyboard-reachable with a visible focus ring; selection / add / delete actions announce via an `aria-live` status region; the edge-flow animation honours `prefers-reduced-motion`
|
|
250
|
+
|
|
251
|
+
**Connecting nodes**
|
|
252
|
+
- Hover a node to reveal the bottom port dot, then drag it to another node
|
|
253
|
+
- Question variant: each answer row has its own port dot — drag it to route that answer to a specific node
|
|
254
|
+
|
|
255
|
+
**Node Navigator (left panel)**
|
|
256
|
+
- Lists all nodes with shape badge, label, and connection counts
|
|
257
|
+
- Search/filter by name
|
|
258
|
+
- Click any row to jump to that node and center the canvas on it
|
|
259
|
+
- Collapses to a slim icon strip
|
|
260
|
+
|
|
261
|
+
**Step Editor (right panel)**
|
|
262
|
+
- Appears when a node is selected
|
|
263
|
+
- Edit the node name, change its shape
|
|
264
|
+
- Manage branches / answer options (add, remove, reorder)
|
|
265
|
+
- Question variant shows connection status per answer
|
|
266
|
+
|
|
267
|
+
**Context menu** (right-click)
|
|
268
|
+
- On canvas: Add node at cursor, Re-center, Undo, Redo
|
|
269
|
+
- On node: Rename, Duplicate, Disconnect all edges, Delete
|
|
270
|
+
- On edge: Style (solid/dashed/dotted), Arrowhead, Reset routing, Delete
|
|
271
|
+
- On touch devices: long-press the canvas (~550ms) opens the canvas menu
|
|
272
|
+
|
|
273
|
+
**Keyboard shortcuts**
|
|
274
|
+
|
|
275
|
+
| Shortcut | Action |
|
|
276
|
+
|---|---|
|
|
277
|
+
| `Ctrl+Z` | Undo |
|
|
278
|
+
| `Ctrl+Y` / `Ctrl+Shift+Z` | Redo |
|
|
279
|
+
| `Ctrl+0` | Fit all nodes in view |
|
|
280
|
+
| `Ctrl+C` / `Ctrl+V` | Copy and paste the current selection (internal edges preserved, +24 px offset on paste) |
|
|
281
|
+
| `Ctrl+D` | Duplicate the current selection |
|
|
282
|
+
| `Delete` / `Backspace` | Remove the current selection |
|
|
283
|
+
| `Escape` | Deselect, cancel in-flight edge drag, close context menu |
|
|
284
|
+
| `Arrow` keys | Nudge selection by 1 grid unit (Shift = 4 units) |
|
|
285
|
+
| `Alt+Arrow` | Traverse to the nearest node in that direction from the current selection |
|
|
286
|
+
| `Shift+click` | Toggle a node in/out of the current selection |
|
|
287
|
+
| `Shift+drag` (empty canvas) | Box-select — add every intersected node to the selection |
|
|
288
|
+
| Double-click edge label | Rename the edge label inline |
|
|
289
|
+
| Drag edge midpoint | Route the edge through a waypoint (right-click → Reset routing to clear) |
|
|
290
|
+
|
|
291
|
+
**Export / Import**
|
|
292
|
+
- Toolbar exports to Mermaid, PlantUML, JSON, SVG, PNG
|
|
293
|
+
- Import accepts Mermaid syntax or JSON
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
### Theming
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
<DiagramEditor theme="dark" /> // force dark
|
|
301
|
+
<DiagramEditor theme="light" /> // force light
|
|
302
|
+
<DiagramEditor theme="auto" /> // follows system prefers-color-scheme (default)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
To match the editor to a host application's brand, pass `themeOverrides` —
|
|
306
|
+
a `Partial<ThemeColors>` that is shallow-merged on top of the resolved
|
|
307
|
+
light/dark palette:
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
import { DiagramEditor, type ThemeColors } from 'flowchart-sequence-designer/ui';
|
|
311
|
+
|
|
312
|
+
const brand: Partial<ThemeColors> = {
|
|
313
|
+
canvas: '#0b1020',
|
|
314
|
+
nodeFill: '#111a2e',
|
|
315
|
+
nodeStroke: '#2b3a5a',
|
|
316
|
+
nodeSelectedFill: '#1a2447',
|
|
317
|
+
edgeColor: '#7b8aa6',
|
|
318
|
+
textPrimary: '#e6edf7',
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
<DiagramEditor theme="dark" themeOverrides={brand} />;
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Every field on `ThemeColors` (canvas, nodeFill, nodeStroke, edgeColor, panelBg,
|
|
325
|
+
inputBg, …) is overridable. Sequence diagrams accept the same prop with a
|
|
326
|
+
slightly different shape — `Partial<SequenceThemeColors>` — also exported from
|
|
327
|
+
`flowchart-sequence-designer/ui`.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
### SequenceEditor
|
|
332
|
+
|
|
333
|
+
`<DiagramEditor>` auto-delegates to `<SequenceEditor>` when handed a
|
|
334
|
+
sequence model, but you can also mount it directly to avoid the
|
|
335
|
+
type-check redirect:
|
|
336
|
+
|
|
337
|
+
```tsx
|
|
338
|
+
import { SequenceEditor, presetSequenceModel } from 'flowchart-sequence-designer/ui';
|
|
339
|
+
|
|
340
|
+
<SequenceEditor
|
|
341
|
+
initialModel={presetSequenceModel()}
|
|
342
|
+
height={520}
|
|
343
|
+
theme="dark"
|
|
344
|
+
onChange={(m) => save(m)}
|
|
345
|
+
/>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**SequenceEditor props** (mirrors `DiagramEditorProps` minus `variant`):
|
|
349
|
+
|
|
350
|
+
| Prop | Type | Default | Notes |
|
|
351
|
+
|---|---|---|---|
|
|
352
|
+
| `initialModel` | `DiagramModel` | preset | Must have `type: 'sequence'`. Falls back to the preset if a non-sequence model is passed. |
|
|
353
|
+
| `onChange` | `(m: DiagramModel) => void` | – | Fires on every committed mutation. |
|
|
354
|
+
| `onExport` | `(format, content) => void` | download | Receives string for text formats, `Blob` for PNG. |
|
|
355
|
+
| `height` | `number \| string` | `600` | Any CSS height. |
|
|
356
|
+
| `allowedExports` | `ExportFormat[]` | all | Whitelist of toolbar export buttons. |
|
|
357
|
+
| `allowImport` | `boolean` | `true` | Show the Import button. |
|
|
358
|
+
| `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | `auto` follows OS `prefers-color-scheme`. |
|
|
359
|
+
| `themeOverrides` | `Partial<SequenceThemeColors>` | – | Per-property palette overrides. |
|
|
360
|
+
|
|
361
|
+
**Sequence-specific interactions:**
|
|
362
|
+
- Drag a message row by its handle to reorder messages.
|
|
363
|
+
- Double-click a message label to rename inline.
|
|
364
|
+
- Drag the column header of an actor to reorder lifelines.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
### Restricting exports and import
|
|
369
|
+
|
|
370
|
+
```tsx
|
|
371
|
+
// Only allow JSON and SVG download
|
|
372
|
+
<DiagramEditor allowedExports={['json', 'svg']} />
|
|
373
|
+
|
|
374
|
+
// Hide the import button entirely
|
|
375
|
+
<DiagramEditor allowImport={false} />
|
|
376
|
+
|
|
377
|
+
// Handle exports yourself (e.g. send to an API)
|
|
378
|
+
<DiagramEditor
|
|
379
|
+
onExport={(format, content) => {
|
|
380
|
+
if (format === 'json') myApi.save(content as string);
|
|
381
|
+
}}
|
|
382
|
+
/>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Types
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
import type {
|
|
391
|
+
DiagramModel,
|
|
392
|
+
DiagramNode,
|
|
393
|
+
DiagramEdge,
|
|
394
|
+
DiagramVariant,
|
|
395
|
+
DiagramType,
|
|
396
|
+
NodeShape,
|
|
397
|
+
ExportFormat,
|
|
398
|
+
SequenceMessage,
|
|
399
|
+
} from 'flowchart-sequence-designer';
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### `DiagramModel`
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
interface DiagramModel {
|
|
406
|
+
type: 'flowchart' | 'sequence';
|
|
407
|
+
title?: string;
|
|
408
|
+
nodes: DiagramNode[];
|
|
409
|
+
edges: DiagramEdge[];
|
|
410
|
+
actors?: string[]; // sequence diagrams
|
|
411
|
+
messages?: SequenceMessage[]; // sequence diagrams
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### `DiagramNode`
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
interface DiagramNode {
|
|
419
|
+
id: string;
|
|
420
|
+
label: string;
|
|
421
|
+
shape?: 'rectangle' | 'diamond' | 'circle' | 'parallelogram';
|
|
422
|
+
x?: number;
|
|
423
|
+
y?: number;
|
|
424
|
+
metadata?: Record<string, unknown>;
|
|
425
|
+
// question variant: metadata.answers = string[]
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### `DiagramEdge`
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
interface DiagramEdge {
|
|
433
|
+
id: string;
|
|
434
|
+
from: string;
|
|
435
|
+
to: string;
|
|
436
|
+
label?: string;
|
|
437
|
+
style?: 'solid' | 'dashed' | 'dotted';
|
|
438
|
+
arrowhead?: 'arrow' | 'none' | 'open';
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Package structure
|
|
445
|
+
|
|
446
|
+
```
|
|
447
|
+
flowchart-sequence-designer/
|
|
448
|
+
├── dist/
|
|
449
|
+
│ ├── index.js / index.cjs / index.d.ts ← core (no React)
|
|
450
|
+
│ └── ui/
|
|
451
|
+
│ └── index.js / index.cjs / index.d.ts ← React UI
|
|
452
|
+
└── src/
|
|
453
|
+
├── core/ # types, Model, FlowchartBuilder, SequenceBuilder
|
|
454
|
+
├── exporters/ # mermaid, plantuml, json, svg
|
|
455
|
+
├── importers/ # mermaid, json
|
|
456
|
+
└── ui/ # DiagramEditor, StepEditor, Toolbar, NodeNavigator
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
The `"."` export gives you the core API; `"./ui"` gives you the React components. Consumers that only use the programmatic API never pull in React.
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## Building from source
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
bun install
|
|
467
|
+
bun run build # outputs to dist/
|
|
468
|
+
bun test # runs the test suite
|
|
469
|
+
```
|