@vanduo-oss/vd3-flowchart 1.2.0 → 1.4.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/dist/meta.json CHANGED
@@ -5,14 +5,24 @@
5
5
  "imports": [],
6
6
  "format": "esm"
7
7
  },
8
+ "src/mindmap.js": {
9
+ "bytes": 6603,
10
+ "imports": [],
11
+ "format": "esm"
12
+ },
8
13
  "src/core.js": {
9
- "bytes": 127688,
14
+ "bytes": 196396,
10
15
  "imports": [
11
16
  {
12
17
  "path": "src/layout.js",
13
18
  "kind": "import-statement",
14
19
  "original": "./layout.js"
15
20
  },
21
+ {
22
+ "path": "src/mindmap.js",
23
+ "kind": "import-statement",
24
+ "original": "./mindmap.js"
25
+ },
16
26
  {
17
27
  "path": "src/layout.js",
18
28
  "kind": "import-statement",
@@ -22,7 +32,7 @@
22
32
  "format": "esm"
23
33
  },
24
34
  "src/vue.js": {
25
- "bytes": 3278,
35
+ "bytes": 3981,
26
36
  "imports": [
27
37
  {
28
38
  "path": "vue",
@@ -38,7 +48,7 @@
38
48
  "format": "esm"
39
49
  },
40
50
  "src/index.js": {
41
- "bytes": 479,
51
+ "bytes": 541,
42
52
  "imports": [
43
53
  {
44
54
  "path": "src/vue.js",
@@ -59,7 +69,7 @@
59
69
  "imports": [],
60
70
  "exports": [],
61
71
  "inputs": {},
62
- "bytes": 233948
72
+ "bytes": 360394
63
73
  },
64
74
  "dist/index.js": {
65
75
  "imports": [
@@ -70,8 +80,10 @@
70
80
  }
71
81
  ],
72
82
  "exports": [
83
+ "FLOWCHART_DOCUMENT_VERSION",
73
84
  "FLOWCHART_EDGE_MARKERS",
74
85
  "FLOWCHART_EDGE_ROUTES",
86
+ "FLOWCHART_KEYBOARD_SHORTCUTS",
75
87
  "FLOWCHART_NODE_TYPES",
76
88
  "FLOWCHART_PORTS",
77
89
  "LAYOUT_MODES",
@@ -83,25 +95,28 @@
83
95
  "entryPoint": "src/index.js",
84
96
  "inputs": {
85
97
  "src/vue.js": {
86
- "bytesInOutput": 2621
98
+ "bytesInOutput": 3238
87
99
  },
88
100
  "src/layout.js": {
89
101
  "bytesInOutput": 6422
90
102
  },
103
+ "src/mindmap.js": {
104
+ "bytesInOutput": 4886
105
+ },
91
106
  "src/core.js": {
92
- "bytesInOutput": 121438
107
+ "bytesInOutput": 186928
93
108
  },
94
109
  "src/index.js": {
95
110
  "bytesInOutput": 0
96
111
  }
97
112
  },
98
- "bytes": 130805
113
+ "bytes": 201879
99
114
  },
100
115
  "dist/index.cjs.map": {
101
116
  "imports": [],
102
117
  "exports": [],
103
118
  "inputs": {},
104
- "bytes": 234554
119
+ "bytes": 361074
105
120
  },
106
121
  "dist/index.cjs": {
107
122
  "imports": [
@@ -115,19 +130,22 @@
115
130
  "entryPoint": "src/index.js",
116
131
  "inputs": {
117
132
  "src/index.js": {
118
- "bytesInOutput": 502
133
+ "bytesInOutput": 634
119
134
  },
120
135
  "src/vue.js": {
121
- "bytesInOutput": 2684
136
+ "bytesInOutput": 3301
122
137
  },
123
138
  "src/layout.js": {
124
139
  "bytesInOutput": 6422
125
140
  },
141
+ "src/mindmap.js": {
142
+ "bytesInOutput": 4886
143
+ },
126
144
  "src/core.js": {
127
- "bytesInOutput": 121438
145
+ "bytesInOutput": 186928
128
146
  }
129
147
  },
130
- "bytes": 131961
148
+ "bytes": 203105
131
149
  }
132
150
  }
133
151
  }
@@ -44,7 +44,7 @@
44
44
  .vd-flowchart-shell {
45
45
  box-sizing: border-box;
46
46
  display: grid;
47
- grid-template-rows: auto minmax(0, 1fr);
47
+ grid-template-rows: auto minmax(0, 1fr) auto;
48
48
  height: 100%;
49
49
  /* Fill the host only — a fixed min-height here overflowed short containers
50
50
  and clipped the bottom outline off-screen. */
@@ -114,6 +114,15 @@
114
114
  color: var(--vd-flowchart-muted);
115
115
  }
116
116
 
117
+ /* The palette column is 88px wide; keep its title on one line. */
118
+ .vd-flowchart-panel--palette .vd-flowchart-panel-title {
119
+ font-size: 0.72rem;
120
+ letter-spacing: 0.02em;
121
+ white-space: nowrap;
122
+ overflow-wrap: normal;
123
+ word-break: normal;
124
+ }
125
+
117
126
  .vd-flowchart-palette {
118
127
  display: grid;
119
128
  grid-template-columns: 1fr;
@@ -352,8 +361,7 @@
352
361
  .vd-flowchart-field input:focus-visible,
353
362
  .vd-flowchart-field select:focus-visible,
354
363
  .vd-flowchart-field textarea:focus-visible,
355
- .vd-flowchart-json textarea:focus-visible,
356
- .vd-flowchart-canvas:focus-visible {
364
+ .vd-flowchart-json textarea:focus-visible {
357
365
  outline: 2px solid color-mix(in srgb, var(--vd-flowchart-accent) 72%, transparent);
358
366
  outline-offset: 2px;
359
367
  }
@@ -372,6 +380,101 @@
372
380
  background: var(--vd-flowchart-canvas-bg);
373
381
  }
374
382
 
383
+ .vd-flowchart-minimap {
384
+ position: absolute;
385
+ right: 0.75rem;
386
+ bottom: 0.75rem;
387
+ z-index: 4;
388
+ width: 180px;
389
+ height: 120px;
390
+ border: 1px solid var(--vd-flowchart-border);
391
+ border-radius: 8px;
392
+ background: color-mix(in srgb, var(--vd-flowchart-panel) 92%, transparent);
393
+ box-shadow: 0 8px 20px color-mix(in srgb, var(--vd-flowchart-text) 10%, transparent);
394
+ overflow: hidden;
395
+ cursor: pointer;
396
+ touch-action: none;
397
+ }
398
+
399
+ .vd-flowchart-minimap[hidden] {
400
+ display: none;
401
+ }
402
+
403
+ .vd-flowchart-minimap-svg {
404
+ display: block;
405
+ }
406
+
407
+ .vd-flowchart-minimap-node {
408
+ fill: color-mix(in srgb, var(--vd-flowchart-muted) 45%, transparent);
409
+ }
410
+
411
+ .vd-flowchart-minimap-node.is-selected {
412
+ fill: var(--vd-flowchart-accent);
413
+ }
414
+
415
+ .vd-flowchart-minimap-viewport {
416
+ fill: color-mix(in srgb, var(--vd-flowchart-accent) 12%, transparent);
417
+ stroke: var(--vd-flowchart-accent);
418
+ stroke-width: 1.25;
419
+ }
420
+
421
+ .vd-flowchart-shortcuts-btn {
422
+ font-size: 0.95rem;
423
+ font-weight: 700;
424
+ }
425
+
426
+ .vd-flowchart-shortcuts {
427
+ position: absolute;
428
+ top: 0.75rem;
429
+ right: 0.75rem;
430
+ z-index: 6;
431
+ box-sizing: border-box;
432
+ width: min(24rem, calc(100% - 1.5rem));
433
+ max-height: calc(100% - 1.5rem);
434
+ overflow-y: auto;
435
+ padding: 0.75rem 0.9rem;
436
+ border: 1px solid var(--vd-flowchart-border);
437
+ border-radius: 8px;
438
+ background: color-mix(in srgb, var(--vd-flowchart-panel) 96%, transparent);
439
+ box-shadow: 0 12px 26px color-mix(in srgb, var(--vd-flowchart-text) 14%, transparent);
440
+ color: var(--vd-flowchart-text);
441
+ font-size: 0.8rem;
442
+ }
443
+
444
+ .vd-flowchart-shortcuts[hidden] {
445
+ display: none;
446
+ }
447
+
448
+ .vd-flowchart-shortcuts-header {
449
+ display: flex;
450
+ align-items: center;
451
+ justify-content: space-between;
452
+ gap: 0.5rem;
453
+ margin-bottom: 0.4rem;
454
+ }
455
+
456
+ .vd-flowchart-shortcuts-list {
457
+ display: grid;
458
+ grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
459
+ gap: 0.4rem 0.75rem;
460
+ margin: 0;
461
+ }
462
+
463
+ .vd-flowchart-shortcuts-list dt,
464
+ .vd-flowchart-shortcuts-list dd {
465
+ margin: 0;
466
+ padding: 0;
467
+ line-height: 1.35;
468
+ }
469
+
470
+ .vd-flowchart-shortcuts-list dt {
471
+ font-weight: 700;
472
+ }
473
+
474
+ .vd-flowchart-shortcuts-list dd {
475
+ color: var(--vd-flowchart-muted);
476
+ }
477
+
375
478
  .vd-flowchart-svg {
376
479
  display: block;
377
480
  width: 100%;
@@ -508,21 +611,42 @@
508
611
  stroke: var(--vd-flowchart-accent);
509
612
  stroke-width: 2;
510
613
  vector-effect: non-scaling-stroke;
511
- transition: opacity 120ms ease, transform 120ms ease, fill 120ms ease;
614
+ pointer-events: none;
615
+ transition: opacity 120ms ease, fill 120ms ease;
512
616
  }
513
617
 
514
- .vd-flowchart-port-group.is-visible {
618
+ .vd-flowchart-port-plus {
619
+ fill: none;
620
+ stroke: var(--vd-flowchart-accent);
621
+ stroke-width: 1.75;
622
+ stroke-linecap: round;
623
+ vector-effect: non-scaling-stroke;
624
+ pointer-events: none;
625
+ opacity: 0;
626
+ transition: opacity 120ms ease;
627
+ }
628
+
629
+ /* Handles appear on node hover as well as on selection. Hidden during a node
630
+ drag or resize so they do not flicker under the pointer. */
631
+ .vd-flowchart-port-group.is-visible,
632
+ .vd-flowchart-node:hover:not(.is-dragging, .is-resizing) .vd-flowchart-port-group {
515
633
  pointer-events: auto;
516
634
  cursor: crosshair;
517
635
  }
518
636
 
519
- .vd-flowchart-port-group.is-visible .vd-flowchart-port {
637
+ .vd-flowchart-port-group.is-visible .vd-flowchart-port,
638
+ .vd-flowchart-node:hover:not(.is-dragging, .is-resizing) .vd-flowchart-port {
520
639
  opacity: 1;
521
640
  }
522
641
 
523
- .vd-flowchart-port-group.is-visible:hover .vd-flowchart-port {
524
- transform: scale(1.08);
525
- fill: color-mix(in srgb, var(--vd-flowchart-accent) 12%, var(--vd-bg-primary, #fcfbf7));
642
+ /* Color only: a transform here would scale around the node origin and shift
643
+ the handle away from the pointer. */
644
+ .vd-flowchart-port-group:hover .vd-flowchart-port {
645
+ fill: color-mix(in srgb, var(--vd-flowchart-accent) 22%, var(--vd-bg-primary, #fcfbf7));
646
+ }
647
+
648
+ .vd-flowchart-port-group:hover .vd-flowchart-port-plus {
649
+ opacity: 1;
526
650
  }
527
651
 
528
652
  .vd-flowchart-canvas.is-connecting .vd-flowchart-node:hover .vd-flowchart-node-shape {
@@ -530,14 +654,62 @@
530
654
  filter: none;
531
655
  }
532
656
 
533
- .vd-flowchart-canvas.is-connecting .vd-flowchart-port-group.is-visible .vd-flowchart-port,
534
- .vd-flowchart-canvas.is-arrow-tool .vd-flowchart-port-group.is-visible .vd-flowchart-port {
535
- opacity: 1;
657
+ .vd-flowchart-canvas.is-connecting .vd-flowchart-port-group:hover .vd-flowchart-port-plus,
658
+ .vd-flowchart-canvas.is-arrow-tool .vd-flowchart-port-group:hover .vd-flowchart-port-plus {
659
+ opacity: 0;
536
660
  }
537
661
 
538
- .vd-flowchart-canvas.is-connecting .vd-flowchart-port-group.is-visible:hover .vd-flowchart-port,
539
- .vd-flowchart-canvas.is-arrow-tool .vd-flowchart-port-group.is-visible:hover .vd-flowchart-port {
540
- transform: none;
662
+ .vd-flowchart-collapse-toggle {
663
+ cursor: pointer;
664
+ }
665
+
666
+ .vd-flowchart-collapse-toggle circle {
667
+ fill: color-mix(in srgb, var(--vd-flowchart-panel) 92%, var(--vd-bg-primary, #fcfbf7));
668
+ stroke: var(--vd-flowchart-accent);
669
+ stroke-width: 1.5;
670
+ vector-effect: non-scaling-stroke;
671
+ }
672
+
673
+ .vd-flowchart-collapse-toggle.is-collapsed circle {
674
+ fill: var(--vd-flowchart-accent);
675
+ }
676
+
677
+ .vd-flowchart-collapse-toggle text {
678
+ fill: var(--vd-flowchart-accent);
679
+ font-family: var(--vd-flowchart-font);
680
+ font-weight: 700;
681
+ pointer-events: none;
682
+ }
683
+
684
+ .vd-flowchart-collapse-toggle.is-collapsed text {
685
+ fill: var(--vd-bg-primary, #fcfbf7);
686
+ }
687
+
688
+ .vd-flowchart-marquee {
689
+ fill: color-mix(in srgb, var(--vd-flowchart-accent) 10%, transparent);
690
+ stroke: var(--vd-flowchart-accent);
691
+ stroke-width: 1;
692
+ stroke-dasharray: 4 3;
693
+ vector-effect: non-scaling-stroke;
694
+ pointer-events: none;
695
+ }
696
+
697
+ .vd-flowchart-guide {
698
+ stroke: var(--vd-flowchart-accent);
699
+ stroke-width: 1;
700
+ stroke-dasharray: 3 3;
701
+ vector-effect: non-scaling-stroke;
702
+ pointer-events: none;
703
+ }
704
+
705
+ .vd-flowchart-selection-box {
706
+ fill: none;
707
+ stroke: var(--vd-flowchart-accent);
708
+ stroke-width: 1;
709
+ stroke-dasharray: 4 3;
710
+ vector-effect: non-scaling-stroke;
711
+ pointer-events: none;
712
+ opacity: 0.7;
541
713
  }
542
714
 
543
715
  .vd-flowchart-edge-endpoint-hit {
@@ -600,6 +772,11 @@
600
772
  text-align: left;
601
773
  }
602
774
 
775
+ .vd-flowchart-text-editor--edge {
776
+ font-weight: 500;
777
+ white-space: nowrap;
778
+ }
779
+
603
780
  .vd-flowchart-text-editor--label {
604
781
  border-color: transparent;
605
782
  background: color-mix(in srgb, var(--vd-flowchart-panel) 82%, transparent);
@@ -727,3 +904,45 @@
727
904
  grid-template-columns: repeat(4, minmax(0, 1fr));
728
905
  }
729
906
  }
907
+
908
+ .vd-flowchart-outline {
909
+ max-height: 220px;
910
+ overflow: auto;
911
+ padding: 0.5rem 0.9rem;
912
+ border-top: 1px solid var(--vd-flowchart-border);
913
+ background: var(--vd-flowchart-panel);
914
+ font-size: 0.875rem;
915
+ }
916
+
917
+ .vd-flowchart-outline summary {
918
+ cursor: pointer;
919
+ }
920
+
921
+ .vd-flowchart-outline-controls {
922
+ display: flex;
923
+ flex-wrap: wrap;
924
+ gap: 0.5rem;
925
+ }
926
+
927
+ .vd-flowchart-host .vd-flowchart-outline select,
928
+ .vd-flowchart-shell .vd-flowchart-outline select {
929
+ max-width: 16rem;
930
+ color: var(--vd-flowchart-text);
931
+ background: var(--vd-flowchart-surface);
932
+ }
933
+
934
+ .vd-flowchart-outline :focus-visible,
935
+ .vd-flowchart-canvas:focus-visible {
936
+ outline: 2px solid var(--vd-flowchart-accent);
937
+ outline-offset: -2px;
938
+ }
939
+
940
+ .vd-flowchart-sr-only {
941
+ position: absolute;
942
+ width: 1px;
943
+ height: 1px;
944
+ padding: 0;
945
+ overflow: hidden;
946
+ clip-path: inset(50%);
947
+ white-space: nowrap;
948
+ }
package/dist/vue.d.ts CHANGED
@@ -8,6 +8,7 @@ import type {
8
8
  VdFlowchart as VdFlowchartCore,
9
9
  LayoutMode,
10
10
  LayoutOptions,
11
+ FlowchartKeyboardShortcuts,
11
12
  } from './core';
12
13
 
13
14
  /** Loosely-typed document accepted by the `data` prop. */
@@ -32,6 +33,14 @@ export interface VdFlowchartProps {
32
33
  history?: boolean;
33
34
  /** Maximum number of history entries to retain. */
34
35
  historyLimit?: number;
36
+ /** Keyboard model on the focused canvas (default `'mindmap'`). */
37
+ keyboardShortcuts?: FlowchartKeyboardShortcuts;
38
+ /** Snap dragged nodes to alignment guides; Alt bypasses (default true). */
39
+ snapGuides?: boolean;
40
+ /** Show the overview minimap (default true). */
41
+ minimap?: boolean;
42
+ /** Re-run the current layout after keyboard or handle insertions (default false). */
43
+ autoLayout?: boolean;
35
44
  }
36
45
 
37
46
  export interface VdFlowchartEmits {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanduo-oss/vd3-flowchart",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Vanduo Vue 3 flowchart editor — nodes, edges, layout, undo/redo, and a framework-agnostic core",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,7 +28,10 @@
28
28
  "import": "./dist/index.js",
29
29
  "require": "./dist/index.cjs"
30
30
  },
31
- "./css": "./dist/vd3-flowchart.css",
31
+ "./css": {
32
+ "types": "./styles.d.ts",
33
+ "default": "./dist/vd3-flowchart.css"
34
+ },
32
35
  "./package.json": "./package.json"
33
36
  },
34
37
  "files": [
@@ -36,7 +39,9 @@
36
39
  "README.md",
37
40
  "SKILL.md",
38
41
  "CHANGELOG.md",
39
- "LICENSE"
42
+ "LICENSE",
43
+ "recipes",
44
+ "styles.d.ts"
40
45
  ],
41
46
  "keywords": [
42
47
  "vanduo",
@@ -73,12 +78,13 @@
73
78
  "build": "node scripts/build.js",
74
79
  "clean": "rm -rf dist",
75
80
  "lint": "eslint .",
76
- "format": "prettier --write \"src/**/*.{js,ts}\" \"scripts/**/*.js\" \"tests/**/*.{js,ts}\"",
77
- "format:check": "prettier --check \"src/**/*.{js,ts}\" \"scripts/**/*.js\" \"tests/**/*.{js,ts}\"",
81
+ "format": "prettier --write \"src/**/*.{js,ts}\" \"scripts/**/*.{js,mjs}\" \"tests/**/*.{js,ts}\"",
82
+ "format:check": "prettier --check \"src/**/*.{js,ts}\" \"scripts/**/*.{js,mjs}\" \"tests/**/*.{js,ts}\"",
78
83
  "stylelint": "stylelint \"src/**/*.css\"",
79
84
  "test": "vitest run",
80
85
  "test:types": "tsc --noEmit -p tests/types/tsconfig.json",
81
86
  "test:e2e": "playwright test",
82
- "release": "pnpm run build && pnpm publish"
87
+ "release": "pnpm run build && pnpm publish",
88
+ "test:skills": "node scripts/check-skills.mjs"
83
89
  }
84
90
  }
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+ import { VdFlowchart, type VdFlowchartDocument, type VdFlowchartExposed } from '@vanduo-oss/vd3-flowchart';
4
+ import '@vanduo-oss/vd3-flowchart/css';
5
+ const editor = ref<VdFlowchartExposed | null>(null);
6
+ const readonly = ref(false);
7
+ const document = ref<VdFlowchartDocument>({
8
+ nodes: [{ id: 'start', text: 'Start', x: 40, y: 100 }, { id: 'end', text: 'End', x: 300, y: 100 }],
9
+ edges: [{ id: 'next', from: { nodeId: 'start', port: 'right' }, to: { nodeId: 'end', port: 'left' } }],
10
+ });
11
+ </script>
12
+ <template>
13
+ <button type="button" @click="readonly = !readonly">Toggle read-only</button>
14
+ <button type="button" :disabled="readonly" @click="editor?.undo()">Undo</button>
15
+ <VdFlowchart ref="editor" :data="document" :readonly="readonly" auto-fit
16
+ style="height: 560px" @change="document = $event.document" />
17
+ </template>
package/styles.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ // TypeScript declaration for the side-effect stylesheet exports.
2
+ export {};