@blueking/flow-canvas 0.0.1-beta.2 → 0.0.1-beta.4

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.
Files changed (46) hide show
  1. package/README.md +284 -94
  2. package/dist/index.cjs.js +1 -1
  3. package/dist/index.d.ts +808 -33
  4. package/dist/index.esm.js +3 -3
  5. package/dist/style.css +1 -1
  6. package/package.json +2 -2
  7. package/dist/core/apply-command.d.ts +0 -11
  8. package/dist/core/editor.d.ts +0 -50
  9. package/dist/core/errors.d.ts +0 -6
  10. package/dist/core/history.d.ts +0 -15
  11. package/dist/core/plugin-manager.d.ts +0 -58
  12. package/dist/index-BAAMFT_J.js +0 -236
  13. package/dist/index-CleU3x1v.cjs +0 -1
  14. package/dist/index-DD3pv5ZZ.cjs +0 -21
  15. package/dist/index-siYsjzl4.js +0 -181
  16. package/dist/plugins/clipboard.d.ts +0 -9
  17. package/dist/plugins/connection-validator.d.ts +0 -3
  18. package/dist/plugins/minimap.d.ts +0 -7
  19. package/dist/plugins/selection.d.ts +0 -7
  20. package/dist/plugins/snapline.d.ts +0 -6
  21. package/dist/runtime/canvas-api.d.ts +0 -25
  22. package/dist/runtime/canvas-runtime-core.vue.d.ts +0 -31
  23. package/dist/runtime/event-bridge.d.ts +0 -28
  24. package/dist/runtime/graph-bridge.d.ts +0 -127
  25. package/dist/runtime/overlay-manager.d.ts +0 -3
  26. package/dist/runtime/shape-registry.d.ts +0 -8
  27. package/dist/runtime/use-edge-delete-tool.d.ts +0 -11
  28. package/dist/runtime/use-node-hover.d.ts +0 -10
  29. package/dist/runtime/use-port-visibility.d.ts +0 -15
  30. package/dist/shell/canvas-layout.vue.d.ts +0 -35
  31. package/dist/shell/canvas-node-palette.vue.d.ts +0 -10
  32. package/dist/shell/canvas-toolbar.vue.d.ts +0 -11
  33. package/dist/shell/default-node.vue.d.ts +0 -4
  34. package/dist/shell/default-schema.d.ts +0 -39
  35. package/dist/shell/node-actions-toolbar.vue.d.ts +0 -22
  36. package/dist/shell/node-quick-add-popover.vue.d.ts +0 -36
  37. package/dist/shell/toolbar-items.d.ts +0 -15
  38. package/dist/types/api.d.ts +0 -104
  39. package/dist/types/command.d.ts +0 -160
  40. package/dist/types/flow-model.d.ts +0 -46
  41. package/dist/types/history.d.ts +0 -18
  42. package/dist/types/overlay.d.ts +0 -3
  43. package/dist/types/plugin.d.ts +0 -64
  44. package/dist/types/schema.d.ts +0 -80
  45. package/dist/utils/path.d.ts +0 -7
  46. package/dist/utils/uuid.d.ts +0 -1
package/README.md CHANGED
@@ -10,16 +10,10 @@
10
10
  npm install @blueking/flow-canvas
11
11
  ```
12
12
 
13
- ### 必需的对等依赖
13
+ 项目中另外还需要安装以下前置依赖
14
14
 
15
15
  ```bash
16
- npm install @antv/x6 @antv/x6-plugin-minimap @antv/x6-plugin-selection @antv/x6-plugin-snapline @antv/x6-vue-shape vue
17
- ```
18
-
19
- ### 可选依赖
20
-
21
- ```bash
22
- npm install @antv/x6-plugin-dnd # 拖拽建节点(DND)功能需要
16
+ npm install @antv/x6 @antv/x6-plugin-minimap @antv/x6-plugin-selection @antv/x6-plugin-snapline @antv/x6-plugin-dnd @antv/x6-vue-shape vue
23
17
  ```
24
18
 
25
19
  ## 快速开始
@@ -158,7 +152,7 @@ npm install @antv/x6-plugin-dnd # 拖拽建节点(DND)功能需要
158
152
  </script>
159
153
  ```
160
154
 
161
- ---
155
+ <br>
162
156
 
163
157
  ## 核心 API
164
158
 
@@ -193,7 +187,7 @@ npm install @antv/x6-plugin-dnd # 拖拽建节点(DND)功能需要
193
187
  | replaceFlowModel(model) | `(FlowModel) => void` | 整体替换流程模型 |
194
188
  | setMode(mode) | `(CanvasMode) => void` | 切换模式 |
195
189
 
196
- ---
190
+ <br>
197
191
 
198
192
  ## FlowModel 数据结构
199
193
 
@@ -227,7 +221,7 @@ interface FlowEdgeModel {
227
221
  }
228
222
  ```
229
223
 
230
- ---
224
+ <br>
231
225
 
232
226
  ## CanvasSchema 配置
233
227
 
@@ -264,7 +258,7 @@ interface CanvasEdgeDefinition {
264
258
 
265
259
  > **注意:** `labelRenderer` 字段在类型定义中存在但标记为 `@experimental`,当前版本尚未完整实现。如需自定义边标签样式,建议通过 `x6EdgeConfig.defaultLabel` 配置 X6 原生标签 markup。
266
260
 
267
- ---
261
+ <br>
268
262
 
269
263
  ## createDefaultSchema — 开箱即用的 Schema 工厂
270
264
 
@@ -278,11 +272,11 @@ const { schema, paletteItems } = createDefaultSchema(options?);
278
272
 
279
273
  ### DefaultSchemaOptions
280
274
 
281
- | 参数 | 类型 | 默认 | 说明 |
282
- | --------------- | ----------------------------------------- | ------------- | --------------------------------------------- |
283
- | nodeTypes | `Record<string, DefaultNodeTypeConfig>` | 7 种内置类型 | 自定义节点类型列表,传入后替换内置类型 |
284
- | defaultEdgeType | `string` | `'manhattan'` | 默认连线类型,内置 `'manhattan'` 和 `'bezier'` |
285
- | edgeTypes | `Record<string, CanvasEdgeDefinition>` | - | 额外/覆盖的边类型定义,会与内置类型合并 |
275
+ | 参数 | 类型 | 默认 | 说明 |
276
+ | --------------- | --------------------------------------- | ------------- | ---------------------------------------------- |
277
+ | nodeTypes | `Record<string, DefaultNodeTypeConfig>` | 7 种内置类型 | 自定义节点类型列表,传入后替换内置类型 |
278
+ | defaultEdgeType | `string` | `'manhattan'` | 默认连线类型,内置 `'manhattan'` 和 `'bezier'` |
279
+ | edgeTypes | `Record<string, CanvasEdgeDefinition>` | - | 额外/覆盖的边类型定义,会与内置类型合并 |
286
280
 
287
281
  ### 返回值
288
282
 
@@ -295,15 +289,15 @@ const { schema, paletteItems } = createDefaultSchema(options?);
295
289
 
296
290
  不传 `nodeTypes` 参数时,默认包含 7 种节点:
297
291
 
298
- | 类型 | 标签 | 尺寸 |
299
- | ---------------------------- | ------------ | --------- |
300
- | `start` | 开始 | 88 × 40 |
301
- | `end` | 结束 | 88 × 40 |
302
- | `empty` | 空节点 | 240 × 48 |
303
- | `parallel-gateway` | 并行网关 | 64 × 64 |
304
- | `branch-gateway` | 分支网关 | 64 × 64 |
305
- | `converge-gateway` | 汇聚网关 | 64 × 64 |
306
- | `conditional-parallel-gateway` | 条件并行网关 | 64 × 64 |
292
+ | 类型 | 标签 | 尺寸 |
293
+ | ------------------------------ | ------------ | -------- |
294
+ | `start` | 开始 | 88 × 40 |
295
+ | `end` | 结束 | 88 × 40 |
296
+ | `empty` | 空节点 | 240 × 48 |
297
+ | `parallel-gateway` | 并行网关 | 64 × 64 |
298
+ | `branch-gateway` | 分支网关 | 64 × 64 |
299
+ | `converge-gateway` | 汇聚网关 | 64 × 64 |
300
+ | `conditional-parallel-gateway` | 条件并行网关 | 64 × 64 |
307
301
 
308
302
  每种节点均使用内置 `DefaultNode` 组件渲染,自带上/右/下/左四个连接端口。
309
303
 
@@ -323,10 +317,10 @@ const { schema, paletteItems } = createDefaultSchema({
323
317
 
324
318
  `createDefaultSchema` 内置两种连线类型:
325
319
 
326
- | 类型 | 路由 | 连接器 | 说明 |
327
- | ----------------------- | ----------- | ---------------------- | -------------------- |
328
- | `manhattan`(默认) | `manhattan` | `rounded`(radius: 8)| 直角折线,圆角转弯 |
329
- | `bezier` | 无 | `smooth` | 贝塞尔曲线,平滑 S 形 |
320
+ | 类型 | 路由 | 连接器 | 说明 |
321
+ | ------------------- | ----------- | ---------------------- | --------------------- |
322
+ | `manhattan`(默认) | `manhattan` | `rounded`(radius: 8 | 直角折线,圆角转弯 |
323
+ | `bezier` | 无 | `smooth` | 贝塞尔曲线,平滑 S 形 |
330
324
 
331
325
  **切换为贝塞尔曲线连线:**
332
326
 
@@ -359,7 +353,9 @@ const { schema, paletteItems } = createDefaultSchema({
359
353
 
360
354
  ```typescript
361
355
  const schema: CanvasSchema = {
362
- nodeTypes: { /* ... */ },
356
+ nodeTypes: {
357
+ /* ... */
358
+ },
363
359
  edgeTypes: {
364
360
  bezier: {
365
361
  connector: { name: 'smooth' },
@@ -396,27 +392,188 @@ const schema: CanvasSchema = {
396
392
  - **连线**:宽度 2px,颜色 `#abb5cc`,hover 变 `#3a84ff`,平角箭头(`block` marker)。`zIndex: -1` 确保在节点下方,不阻挡端口交互。
397
393
  - **连接点**:`connectionPoint: 'anchor'` + `anchor: 'center'`,连线直达端口中心,紧贴节点。
398
394
 
399
- ---
395
+ <br>
400
396
 
401
397
  ## 命令系统
402
398
 
403
- 所有 FlowModel 变更必须通过命令执行:
399
+ 所有 FlowModel 变更必须通过命令执行。每条命令通过 `CommandEnvelope` 包装,一个信封可包含多条原子命令,作为一次事务整体执行(撤销时整体回退)。
404
400
 
405
401
  ```typescript
406
402
  import { generateId } from '@blueking/flow-canvas';
403
+ ```
407
404
 
405
+ **添加节点和连线:**
406
+
407
+ ```typescript
408
408
  editor.executeCommand({
409
409
  id: generateId(),
410
410
  source: 'user:panel',
411
411
  label: '添加节点',
412
412
  timestamp: Date.now(),
413
413
  commands: [
414
- { type: 'node.add', node: { id: 'n1', type: 'task', position: { x: 100, y: 100 } } },
415
- { type: 'edge.add', edge: { id: 'e1', source: { nodeId: 'n0' }, target: { nodeId: 'n1' } } },
414
+ { type: 'node.add', node: { id: 'n1', type: 'task', position: { x: 100, y: 100 }, label: '审批' } },
415
+ {
416
+ type: 'edge.add',
417
+ edge: { id: 'e1', source: { nodeId: 'n0', portId: 'right' }, target: { nodeId: 'n1', portId: 'left' } },
418
+ },
416
419
  ],
417
420
  });
418
421
  ```
419
422
 
423
+ **删除节点(自动级联删除关联边):**
424
+
425
+ ```typescript
426
+ editor.executeCommand({
427
+ id: generateId(),
428
+ source: 'user:panel',
429
+ label: '删除节点',
430
+ timestamp: Date.now(),
431
+ commands: [{ type: 'node.remove', nodeId: 'n1' }],
432
+ });
433
+ ```
434
+
435
+ **删除连线:**
436
+
437
+ ```typescript
438
+ editor.executeCommand({
439
+ id: generateId(),
440
+ source: 'user:panel',
441
+ label: '删除连线',
442
+ timestamp: Date.now(),
443
+ commands: [{ type: 'edge.remove', edgeId: 'e1' }],
444
+ });
445
+ ```
446
+
447
+ **移动节点:**
448
+
449
+ ```typescript
450
+ editor.executeCommand({
451
+ id: generateId(),
452
+ source: 'user:panel',
453
+ label: '移动节点',
454
+ timestamp: Date.now(),
455
+ commands: [{ type: 'node.move', nodeId: 'n1', position: { x: 300, y: 200 } }],
456
+ });
457
+ ```
458
+
459
+ **更新节点结构字段(label、type、ports 等,不含 payload/extensions):**
460
+
461
+ ```typescript
462
+ editor.executeCommand({
463
+ id: generateId(),
464
+ source: 'user:panel',
465
+ label: '重命名节点',
466
+ timestamp: Date.now(),
467
+ commands: [{ type: 'node.update', nodeId: 'n1', patch: { label: '新名称' } }],
468
+ });
469
+ ```
470
+
471
+ **按路径更新节点 payload(业务数据):**
472
+
473
+ ```typescript
474
+ // 设置 payload.config.timeout = 30
475
+ editor.executeCommand({
476
+ id: generateId(),
477
+ source: 'user:panel',
478
+ label: '更新超时配置',
479
+ timestamp: Date.now(),
480
+ commands: [{ type: 'node.set-payload', nodeId: 'n1', path: ['config', 'timeout'], value: 30 }],
481
+ });
482
+
483
+ // 设置整个 payload.config 对象
484
+ editor.executeCommand({
485
+ id: generateId(),
486
+ source: 'user:panel',
487
+ label: '更新节点配置',
488
+ timestamp: Date.now(),
489
+ commands: [{ type: 'node.set-payload', nodeId: 'n1', path: ['config'], value: { timeout: 30, retryable: true } }],
490
+ });
491
+
492
+ // 删除 payload 中的某个字段(value 传 undefined)
493
+ editor.executeCommand({
494
+ id: generateId(),
495
+ source: 'user:panel',
496
+ label: '清除超时配置',
497
+ timestamp: Date.now(),
498
+ commands: [{ type: 'node.set-payload', nodeId: 'n1', path: ['config', 'timeout'], value: undefined }],
499
+ });
500
+ ```
501
+
502
+ **重连边端点:**
503
+
504
+ ```typescript
505
+ editor.executeCommand({
506
+ id: generateId(),
507
+ source: 'user:panel',
508
+ label: '重连边',
509
+ timestamp: Date.now(),
510
+ commands: [
511
+ {
512
+ type: 'edge.reconnect',
513
+ edgeId: 'e1',
514
+ target: { nodeId: 'n2', portId: 'left' }, // 只改 target,source 不变
515
+ },
516
+ ],
517
+ });
518
+ ```
519
+
520
+ **更新边标签:**
521
+
522
+ ```typescript
523
+ editor.executeCommand({
524
+ id: generateId(),
525
+ source: 'user:panel',
526
+ label: '更新边标签',
527
+ timestamp: Date.now(),
528
+ commands: [{ type: 'edge.label.update', edgeId: 'e1', labelId: 'label1', patch: { text: '条件成立' } }],
529
+ });
530
+ ```
531
+
532
+ **更新全局 meta:**
533
+
534
+ ```typescript
535
+ editor.executeCommand({
536
+ id: generateId(),
537
+ source: 'user:panel',
538
+ label: '更新全局变量',
539
+ timestamp: Date.now(),
540
+ commands: [{ type: 'model.set-meta', path: ['variables', 'env'], value: 'production' }],
541
+ });
542
+ ```
543
+
544
+ **批量操作(一个信封包含多条命令,一次性执行):**
545
+
546
+ ```typescript
547
+ editor.executeCommand({
548
+ id: generateId(),
549
+ source: 'user:panel',
550
+ label: '批量删除选中',
551
+ timestamp: Date.now(),
552
+ commands: [
553
+ { type: 'edge.remove', edgeId: 'e1' },
554
+ { type: 'edge.remove', edgeId: 'e2' },
555
+ { type: 'node.remove', nodeId: 'n1' },
556
+ { type: 'node.remove', nodeId: 'n2' },
557
+ ],
558
+ });
559
+ ```
560
+
561
+ **处理命令执行结果:**
562
+
563
+ ```typescript
564
+ const result = editor.executeCommand({
565
+ /* ... */
566
+ });
567
+
568
+ if (result.status === 'applied') {
569
+ console.log('执行成功,新模型:', result.flowModel);
570
+ } else if (result.status === 'rejected') {
571
+ console.warn('被插件拒绝:', result.error?.reason);
572
+ } else if (result.status === 'invalid') {
573
+ console.error('违反约束:', result.error?.reason);
574
+ }
575
+ ```
576
+
420
577
  ### 命令类型一览
421
578
 
422
579
  | 命令 | 说明 |
@@ -441,7 +598,7 @@ editor.executeCommand({
441
598
 
442
599
  `'user:drag'` | `'user:keyboard'` | `'user:toolbar'` | `'user:quick-add'` | `'user:panel'` | `'plugin'` | `'system'` | `'system:replace'`
443
600
 
444
- ---
601
+ <br>
445
602
 
446
603
  ## 组件
447
604
 
@@ -487,18 +644,18 @@ editor.executeCommand({
487
644
 
488
645
  通过 schema `getBehavior` 返回值控制每个节点类型的工具栏行为:
489
646
 
490
- | 属性 | 说明 |
491
- | -------------------- | -------------------------------------------------------- |
492
- | `showActions` | `false` → 该节点类型不显示整个工具栏 |
493
- | `deletable` | `false` → 隐藏删除按钮 |
494
- | `copyable` | `false` → 隐藏复制和复制并插入按钮 |
495
- | `disconnectable` | `false` → 隐藏断开连线按钮 |
496
- | `debuggable` | `false` → 隐藏调试按钮(需全局 `showDebug` 也为 `true`) |
497
- | `deleteDisabled` | `true` → 删除按钮可见但置灰不可点击 |
498
- | `copyDisabled` | `true` → 复制按钮置灰 |
499
- | `copyInsertDisabled` | `true` → 复制并插入按钮置灰 |
500
- | `disconnectDisabled` | `true` → 断开连线按钮置灰 |
501
- | `debugDisabled` | `true` → 调试按钮置灰 |
647
+ | 属性 | 说明 |
648
+ | -------------------- | --------------------------------------------------------------------------------- |
649
+ | `showActions` | `false` → 该节点类型不显示整个工具栏 |
650
+ | `deletable` | `false` → 隐藏删除按钮 |
651
+ | `copyable` | `false` → 隐藏复制和复制并插入按钮 |
652
+ | `disconnectable` | `false` → 隐藏断开连线按钮 |
653
+ | `debuggable` | `false` → 隐藏调试按钮(需全局 `showDebug` 也为 `true`) |
654
+ | `deleteDisabled` | `true` → 删除按钮可见但置灰不可点击 |
655
+ | `copyDisabled` | `true` → 复制按钮置灰 |
656
+ | `copyInsertDisabled` | `true` → 复制并插入按钮置灰 |
657
+ | `disconnectDisabled` | `true` → 断开连线按钮置灰 |
658
+ | `debugDisabled` | `true` → 调试按钮置灰 |
502
659
  | `actionsOffset` | `{ x?: number; y?: number }` — 工具栏位置偏移(px),相对于默认位置(节点右下角) |
503
660
 
504
661
  按钮有效可见性 = 全局 `show*` AND 逐节点 `*able !== false`;
@@ -621,8 +778,7 @@ const schema: CanvasSchema = {
621
778
  component: TaskNode,
622
779
  getSize: () => ({ width: 180, height: 60 }),
623
780
  getBehavior: (node, ctx) => {
624
- const hasOutEdge = Object.values(ctx.flowModel.edges)
625
- .some(e => e.source.nodeId === node.id);
781
+ const hasOutEdge = Object.values(ctx.flowModel.edges).some((e) => e.source.nodeId === node.id);
626
782
  return {
627
783
  quickAddEnabled: !hasOutEdge, // 已有出边时隐藏"+"按钮
628
784
  };
@@ -642,18 +798,18 @@ const schema: CanvasSchema = {
642
798
  | sidebarWidth | `number` | `260` | 侧边栏宽度(px) |
643
799
  | hideSidebar | `boolean` | `false` | 是否隐藏侧边栏 |
644
800
  | hideFooter | `boolean` | `false` | 是否隐藏底部栏 |
645
- | editor | `CanvasEditorContext` | `undefined` | 编辑器实例,传入后自动渲染内置 `CanvasNodePalette` |
646
- | paletteItems | `NodePaletteItem[]` | `undefined` | 节点面板项列表,配合 `editor` 使用自定义面板节点列表 |
801
+ | editor | `CanvasEditorContext` | `undefined` | 编辑器实例,传入后自动渲染内置 `CanvasNodePalette` |
802
+ | paletteItems | `NodePaletteItem[]` | `undefined` | 节点面板项列表,配合 `editor` 使用自定义面板节点列表 |
647
803
 
648
- | Emit | 参数 | 说明 |
649
- | ----------------------- | --------- | ---------------- |
804
+ | Emit | 参数 | 说明 |
805
+ | ----------------------- | --------- | ------------------ |
650
806
  | update:sidebarCollapsed | `boolean` | 侧边栏收起状态变更 |
651
807
 
652
- | Slot | 说明 |
653
- | ------- | ------------------------------------------------------------- |
654
- | sidebar | 侧边栏内容(传入后覆盖内置 `CanvasNodePalette` 默认面板) |
655
- | default | 主画布区域(放置 `CanvasRuntime` + `CanvasToolbar`) |
656
- | footer | 底部栏 |
808
+ | Slot | 说明 |
809
+ | ------- | --------------------------------------------------------- |
810
+ | sidebar | 侧边栏内容(传入后覆盖内置 `CanvasNodePalette` 默认面板) |
811
+ | default | 主画布区域(放置 `CanvasRuntime` + `CanvasToolbar`) |
812
+ | footer | 底部栏 |
657
813
 
658
814
  #### 侧边栏的三种使用方式
659
815
 
@@ -699,12 +855,7 @@ const schema: CanvasSchema = {
699
855
  <template #sidebar>
700
856
  <div class="my-sidebar">
701
857
  <h3>节点库</h3>
702
- <div
703
- v-for="item in nodeItems"
704
- :key="item.type"
705
- ref="dndRefs"
706
- class="my-sidebar__item"
707
- :data-type="item.type">
858
+ <div v-for="item in nodeItems" :key="item.type" ref="dndRefs" class="my-sidebar__item" :data-type="item.type">
708
859
  {{ item.label }}
709
860
  </div>
710
861
  </div>
@@ -723,20 +874,23 @@ const schema: CanvasSchema = {
723
874
  ];
724
875
 
725
876
  // 通过 api.registerDndSource 注册拖拽源
726
- watch(() => editor.api.value, (api) => {
727
- if (!api) return;
728
- for (const item of nodeItems) {
729
- const el = document.querySelector(`[data-type="${item.type}"]`);
730
- if (el) {
731
- api.registerDndSource(el as HTMLElement, () => ({
732
- id: generateId(),
733
- type: item.type,
734
- label: item.label,
735
- position: { x: 0, y: 0 },
736
- }));
877
+ watch(
878
+ () => editor.api.value,
879
+ (api) => {
880
+ if (!api) return;
881
+ for (const item of nodeItems) {
882
+ const el = document.querySelector(`[data-type="${item.type}"]`);
883
+ if (el) {
884
+ api.registerDndSource(el as HTMLElement, () => ({
885
+ id: generateId(),
886
+ type: item.type,
887
+ label: item.label,
888
+ position: { x: 0, y: 0 },
889
+ }));
890
+ }
737
891
  }
738
- }
739
- });
892
+ },
893
+ );
740
894
  </script>
741
895
  ```
742
896
 
@@ -759,9 +913,9 @@ const schema: CanvasSchema = {
759
913
 
760
914
  ```typescript
761
915
  interface NodePaletteItem {
762
- type: string; // 节点类型,对应 schema.nodeTypes 的 key
763
- label: string; // 显示名称
764
- icon?: string; // CSS 图标类名
916
+ type: string; // 节点类型,对应 schema.nodeTypes 的 key
917
+ label: string; // 显示名称
918
+ icon?: string; // CSS 图标类名
765
919
  }
766
920
  ```
767
921
 
@@ -809,7 +963,43 @@ const customItems = [
809
963
  | description | `string` | 操作说明,有值时 hover 显示 tooltip 气泡 |
810
964
  | onClick | `(ctx: CanvasCallbackContext) => void` | 点击回调 |
811
965
 
812
- ---
966
+ #### 通过 CSS 变量定制工具栏样式与位置
967
+
968
+ `CanvasToolbar` 通过 CSS 自定义属性暴露了位置和外观的定制接口,使用方在父元素上设置对应变量即可覆盖默认值:
969
+
970
+ | CSS 变量 | 默认值 | 说明 |
971
+ | --------------------------------- | --------------------------- | -------------------- |
972
+ | `--flow-canvas-toolbar-top` | `16px` | 工具栏距画布顶部距离 |
973
+ | `--flow-canvas-toolbar-left` | `16px` | 工具栏距画布左侧距离 |
974
+ | `--flow-canvas-toolbar-right` | `auto` | 工具栏距画布右侧距离 |
975
+ | `--flow-canvas-toolbar-bottom` | `auto` | 工具栏距画布底部距离 |
976
+ | `--flow-canvas-toolbar-bg` | `#565e7a` | 工具栏背景色 |
977
+ | `--flow-canvas-toolbar-color` | `#f5f7fa` | 工具栏文字/图标颜色 |
978
+ | `--flow-canvas-toolbar-hover-bg` | `rgba(255, 255, 255, 0.15)` | 按钮 hover 背景色 |
979
+ | `--flow-canvas-toolbar-active-bg` | `rgba(255, 255, 255, 0.25)` | 按钮激活态背景色 |
980
+
981
+ **示例 — 将工具栏移至画布底部居中,并更换背景色:**
982
+
983
+ ```vue
984
+ <template>
985
+ <CanvasLayout :editor="editor" :palette-items="paletteItems" class="my-canvas-wrapper">
986
+ <CanvasRuntime :editor="editor" />
987
+ <CanvasToolbar :editor="editor" />
988
+ </CanvasLayout>
989
+ </template>
990
+
991
+ <style scoped>
992
+ .my-canvas-wrapper {
993
+ --flow-canvas-toolbar-top: auto;
994
+ --flow-canvas-toolbar-bottom: 16px;
995
+ --flow-canvas-toolbar-left: 50%;
996
+ --flow-canvas-toolbar-right: auto;
997
+ --flow-canvas-toolbar-bg: #1a1a2e;
998
+ }
999
+ </style>
1000
+ ```
1001
+
1002
+ <br>
813
1003
 
814
1004
  ## 自定义节点组件
815
1005
 
@@ -917,7 +1107,7 @@ const schema: CanvasSchema = {
917
1107
  };
918
1108
  ```
919
1109
 
920
- ---
1110
+ <br>
921
1111
 
922
1112
  ## CanvasApi
923
1113
 
@@ -947,7 +1137,7 @@ const schema: CanvasSchema = {
947
1137
  | onGraphEvent(event, handler) | 监听 X6 底层事件,返回取消函数 |
948
1138
  | unsafeGetGraph() | 获取 X6 Graph 实例(谨慎使用) |
949
1139
 
950
- ---
1140
+ <br>
951
1141
 
952
1142
  ## 内置插件
953
1143
 
@@ -1003,7 +1193,7 @@ minimapPlugin({
1003
1193
 
1004
1194
  Cmd/Ctrl+C 复制选中节点/边,Cmd/Ctrl+V 粘贴(生成新 ID、偏移位置)。
1005
1195
 
1006
- ---
1196
+ <br>
1007
1197
 
1008
1198
  ## 自定义插件
1009
1199
 
@@ -1065,7 +1255,7 @@ const myPlugin: CanvasPlugin = {
1065
1255
  };
1066
1256
  ```
1067
1257
 
1068
- ---
1258
+ <br>
1069
1259
 
1070
1260
  ## 工具函数与底层 API
1071
1261
 
@@ -1085,7 +1275,7 @@ const emptyModel = createEmptyFlowModel();
1085
1275
  // { version: '1.0', nodes: {}, edges: {} }
1086
1276
  ```
1087
1277
 
1088
- ---
1278
+ <br>
1089
1279
 
1090
1280
  ## 撤销/重做
1091
1281
 
@@ -1097,7 +1287,7 @@ editor.history.canRedo.value; // boolean
1097
1287
  editor.history.clear();
1098
1288
  ```
1099
1289
 
1100
- ---
1290
+ <br>
1101
1291
 
1102
1292
  ## 事件类型 (CanvasUiEvent)
1103
1293
 
@@ -1119,7 +1309,7 @@ editor.history.clear();
1119
1309
  | node.quick-add | nodeId, position | 快捷添加弹层打开 |
1120
1310
  | node.action.quick-insert | sourceNodeId, newNodeId | 快捷插入节点 |
1121
1311
 
1122
- ---
1312
+ <br>
1123
1313
 
1124
1314
  ## 公开类型参考
1125
1315
 
@@ -1193,11 +1383,11 @@ editor.history.clear();
1193
1383
 
1194
1384
  ### 默认 Schema
1195
1385
 
1196
- | 类型 | 说明 |
1197
- | ------------------------- | ------------------------------------- |
1198
- | `DefaultNodeTypeConfig` | `createDefaultSchema` 的节点配置项 |
1199
- | `DefaultSchemaOptions` | `createDefaultSchema` 的选项 |
1200
- | `DefaultSchemaResult` | `createDefaultSchema` 的返回值 |
1386
+ | 类型 | 说明 |
1387
+ | ---------------------------- | ---------------------------------- |
1388
+ | `DefaultNodeTypeConfig` | `createDefaultSchema` 的节点配置项 |
1389
+ | `DefaultSchemaOptions` | `createDefaultSchema` 的选项 |
1390
+ | `DefaultSchemaResult` | `createDefaultSchema` 的返回值 |
1201
1391
  | `DefaultToolbarItemsOptions` | `createDefaultToolbarItems` 的选项 |
1202
1392
 
1203
1393
  ### 历史与 Overlay