@logicflow/core 2.2.1 → 2.2.2

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 (126) hide show
  1. package/dist/docs/api/logicflow-constructor/index.en.md +106 -0
  2. package/dist/docs/api/logicflow-constructor/index.zh.md +106 -0
  3. package/dist/docs/api/logicflow-constructor/use.en.md +61 -0
  4. package/dist/docs/api/logicflow-constructor/use.zh.md +61 -0
  5. package/dist/docs/api/logicflow-instance/canvas.en.md +197 -0
  6. package/dist/docs/api/logicflow-instance/canvas.zh.md +199 -0
  7. package/dist/docs/api/logicflow-instance/edge.en.md +273 -0
  8. package/dist/docs/api/logicflow-instance/edge.zh.md +273 -0
  9. package/dist/docs/api/logicflow-instance/edit-config.en.md +59 -0
  10. package/dist/docs/api/logicflow-instance/edit-config.zh.md +59 -0
  11. package/dist/docs/api/logicflow-instance/element.en.md +375 -0
  12. package/dist/docs/api/logicflow-instance/element.zh.md +379 -0
  13. package/dist/docs/api/logicflow-instance/event.en.md +326 -0
  14. package/dist/docs/api/logicflow-instance/event.zh.md +406 -0
  15. package/dist/docs/api/logicflow-instance/history.en.md +38 -0
  16. package/dist/docs/api/logicflow-instance/history.zh.md +38 -0
  17. package/dist/docs/api/logicflow-instance/index.en.md +41 -0
  18. package/dist/docs/api/logicflow-instance/index.zh.md +41 -0
  19. package/dist/docs/api/logicflow-instance/node.en.md +308 -0
  20. package/dist/docs/api/logicflow-instance/node.zh.md +308 -0
  21. package/dist/docs/api/logicflow-instance/register.en.md +76 -0
  22. package/dist/docs/api/logicflow-instance/register.zh.md +76 -0
  23. package/dist/docs/api/logicflow-instance/render-and-data.en.md +179 -0
  24. package/dist/docs/api/logicflow-instance/render-and-data.zh.md +181 -0
  25. package/dist/docs/api/logicflow-instance/text.en.md +60 -0
  26. package/dist/docs/api/logicflow-instance/text.zh.md +60 -0
  27. package/dist/docs/api/logicflow-instance/theme.en.md +179 -0
  28. package/dist/docs/api/logicflow-instance/theme.zh.md +179 -0
  29. package/dist/docs/api/runtime-model/edgeModel.en.md +29 -0
  30. package/dist/docs/api/runtime-model/edgeModel.zh.md +325 -0
  31. package/dist/docs/api/runtime-model/graphModel.en.md +275 -0
  32. package/dist/docs/api/runtime-model/graphModel.zh.md +1153 -0
  33. package/dist/docs/api/runtime-model/nodeModel.en.md +37 -0
  34. package/dist/docs/api/runtime-model/nodeModel.zh.md +644 -0
  35. package/dist/docs/api/type/MainTypes.en.md +598 -0
  36. package/dist/docs/api/type/MainTypes.zh.md +867 -0
  37. package/dist/docs/api/type/Theme.en.md +187 -0
  38. package/dist/docs/api/type/Theme.zh.md +187 -0
  39. package/dist/docs/api/type/canvas-types.en.md +25 -0
  40. package/dist/docs/api/type/canvas-types.zh.md +25 -0
  41. package/dist/docs/api/type/index.en.md +96 -0
  42. package/dist/docs/api/type/index.zh.md +99 -0
  43. package/dist/docs/api/type/node-types.en.md +21 -0
  44. package/dist/docs/api/type/node-types.zh.md +21 -0
  45. package/dist/docs/api/type/plugin-types.en.md +24 -0
  46. package/dist/docs/api/type/plugin-types.zh.md +24 -0
  47. package/dist/docs/index.md +11 -0
  48. package/dist/docs/tutorial/about.en.md +38 -0
  49. package/dist/docs/tutorial/about.zh.md +65 -0
  50. package/dist/docs/tutorial/advanced/dnd.en.md +62 -0
  51. package/dist/docs/tutorial/advanced/dnd.zh.md +52 -0
  52. package/dist/docs/tutorial/advanced/edge.en.md +64 -0
  53. package/dist/docs/tutorial/advanced/edge.zh.md +66 -0
  54. package/dist/docs/tutorial/advanced/keyboard.en.md +70 -0
  55. package/dist/docs/tutorial/advanced/keyboard.zh.md +67 -0
  56. package/dist/docs/tutorial/advanced/node.en.md +338 -0
  57. package/dist/docs/tutorial/advanced/node.zh.md +338 -0
  58. package/dist/docs/tutorial/advanced/react.en.md +106 -0
  59. package/dist/docs/tutorial/advanced/react.zh.md +114 -0
  60. package/dist/docs/tutorial/advanced/silent-mode.en.md +75 -0
  61. package/dist/docs/tutorial/advanced/silent-mode.zh.md +71 -0
  62. package/dist/docs/tutorial/advanced/snapline.en.md +54 -0
  63. package/dist/docs/tutorial/advanced/vue.en.md +249 -0
  64. package/dist/docs/tutorial/advanced/vue.zh.md +248 -0
  65. package/dist/docs/tutorial/ai.en.md +64 -0
  66. package/dist/docs/tutorial/ai.zh.md +64 -0
  67. package/dist/docs/tutorial/basic/background.en.md +50 -0
  68. package/dist/docs/tutorial/basic/canvas.en.md +164 -0
  69. package/dist/docs/tutorial/basic/canvas.zh.md +183 -0
  70. package/dist/docs/tutorial/basic/class.en.md +106 -0
  71. package/dist/docs/tutorial/basic/class.zh.md +103 -0
  72. package/dist/docs/tutorial/basic/edge.en.md +151 -0
  73. package/dist/docs/tutorial/basic/edge.zh.md +152 -0
  74. package/dist/docs/tutorial/basic/event.en.md +70 -0
  75. package/dist/docs/tutorial/basic/event.zh.md +66 -0
  76. package/dist/docs/tutorial/basic/grid.en.md +77 -0
  77. package/dist/docs/tutorial/basic/node.en.md +358 -0
  78. package/dist/docs/tutorial/basic/node.zh.md +318 -0
  79. package/dist/docs/tutorial/basic/theme.en.md +154 -0
  80. package/dist/docs/tutorial/basic/theme.zh.md +157 -0
  81. package/dist/docs/tutorial/extension/adapter.en.md +446 -0
  82. package/dist/docs/tutorial/extension/adapter.zh.md +429 -0
  83. package/dist/docs/tutorial/extension/bpmn-element.en.md +1427 -0
  84. package/dist/docs/tutorial/extension/bpmn-element.zh.md +1472 -0
  85. package/dist/docs/tutorial/extension/control.en.md +117 -0
  86. package/dist/docs/tutorial/extension/control.zh.md +118 -0
  87. package/dist/docs/tutorial/extension/curved-edge.en.md +46 -0
  88. package/dist/docs/tutorial/extension/curved-edge.zh.md +46 -0
  89. package/dist/docs/tutorial/extension/custom.en.md +142 -0
  90. package/dist/docs/tutorial/extension/custom.zh.md +138 -0
  91. package/dist/docs/tutorial/extension/dnd-panel.en.md +109 -0
  92. package/dist/docs/tutorial/extension/dnd-panel.zh.md +109 -0
  93. package/dist/docs/tutorial/extension/dynamic-group.en.md +606 -0
  94. package/dist/docs/tutorial/extension/dynamic-group.zh.md +606 -0
  95. package/dist/docs/tutorial/extension/group.en.md +217 -0
  96. package/dist/docs/tutorial/extension/group.zh.md +209 -0
  97. package/dist/docs/tutorial/extension/highlight.en.md +50 -0
  98. package/dist/docs/tutorial/extension/highlight.zh.md +50 -0
  99. package/dist/docs/tutorial/extension/insert-node-in-polyline.en.md +52 -0
  100. package/dist/docs/tutorial/extension/insert-node-in-polyline.zh.md +47 -0
  101. package/dist/docs/tutorial/extension/intro.en.md +72 -0
  102. package/dist/docs/tutorial/extension/intro.zh.md +95 -0
  103. package/dist/docs/tutorial/extension/label.en.md +136 -0
  104. package/dist/docs/tutorial/extension/label.zh.md +135 -0
  105. package/dist/docs/tutorial/extension/layout.en.md +156 -0
  106. package/dist/docs/tutorial/extension/layout.zh.md +156 -0
  107. package/dist/docs/tutorial/extension/menu.en.md +319 -0
  108. package/dist/docs/tutorial/extension/menu.zh.md +377 -0
  109. package/dist/docs/tutorial/extension/minimap.en.md +164 -0
  110. package/dist/docs/tutorial/extension/minimap.zh.md +180 -0
  111. package/dist/docs/tutorial/extension/node-resize.en.md +199 -0
  112. package/dist/docs/tutorial/extension/node-resize.zh.md +221 -0
  113. package/dist/docs/tutorial/extension/pool.en.md +227 -0
  114. package/dist/docs/tutorial/extension/pool.zh.md +227 -0
  115. package/dist/docs/tutorial/extension/proximity-connect.en.md +104 -0
  116. package/dist/docs/tutorial/extension/proximity-connect.zh.md +107 -0
  117. package/dist/docs/tutorial/extension/selection.en.md +166 -0
  118. package/dist/docs/tutorial/extension/selection.zh.md +150 -0
  119. package/dist/docs/tutorial/extension/snapshot.en.md +276 -0
  120. package/dist/docs/tutorial/extension/snapshot.zh.md +276 -0
  121. package/dist/docs/tutorial/get-started.en.md +501 -0
  122. package/dist/docs/tutorial/get-started.zh.md +139 -0
  123. package/dist/docs/tutorial/update.en.md +213 -0
  124. package/dist/docs/tutorial/update.zh.md +212 -0
  125. package/package.json +5 -3
  126. package/scripts/postinstall-ai-prompt.js +67 -0
@@ -0,0 +1,319 @@
1
+ ---
2
+ nav: Guide
3
+ group:
4
+ title: Plug-in functionality
5
+ order: 3
6
+ title: Menu
7
+ order: 1
8
+ toc: content
9
+ ---
10
+
11
+ <style>
12
+ table td:first-of-type {
13
+ word-break: normal;
14
+ }
15
+ </style>
16
+
17
+ When using flowchart tools for editing, users' attention is often focused on the canvas area. Compared to frequently moving the mouse to click the top menu bar or using shortcut keys, right-clicking directly on nodes, edges, or blank areas is more efficient and intuitive. To better match users' operating habits, LogicFlow has built-in right-click menus, making common operations readily accessible and improving the overall editing experience.
18
+
19
+ ## Enable
20
+
21
+ Import and enable the default menu
22
+
23
+ ```tsx | pure
24
+ import LogicFlow from "@logicflow/core";
25
+ import { Menu } from "@logicflow/extension";
26
+ import "@logicflow/extension/lib/style/index.css";
27
+
28
+ LogicFlow.use(Menu); // Global import
29
+
30
+ const lf = new LogicFlow({
31
+ plugins: [Menu], // Local import
32
+ })
33
+ ```
34
+
35
+ By default, the menu plugin supports node menus, edge menus, and canvas menus, with the following built-in functions:
36
+
37
+ - Node right-click menu (nodeMenu): Delete, Copy, Edit text
38
+ - Edge right-click menu (edgeMenu): Delete, Edit text
39
+ - Canvas right-click menu (graphMenu): None
40
+
41
+ Of course, supporting only these configuration items is far from enough, so we also support users to customize menu configuration items.
42
+
43
+ ## Menu configuration items
44
+
45
+ Each function in the menu can be represented by a configuration entry. The specific fields are as follows:
46
+
47
+ | Fields | Type | Role | Required | Description |
48
+ | --------- | ---------------- | --------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
49
+ | text | string | Text content | | Text displayed by the menu item |
50
+ | className | string | Class name | | The default class for each item is lf-menu-item, set this field and class will add className to the original. |
51
+ | icon | boolean / string | Whether to create a span placeholder for icon | | If simple text cannot richly represent the menu, you can add an icon. Set to `true` to create an empty icon container with class `lf-menu-icon`. Set to a string for various icon formats: image file paths (e.g., `./icon.png`), base64 image data (e.g., `data:image/png;base64,...`), CSS class names, or HTML content. Usually used in conjunction with className. |
52
+ | disabled | boolean | Whether to disable menu item | | When set to true, the menu item will be displayed in gray and cannot be clicked. This state can be dynamically modified using the `changeMenuItemDisableStatus` method. |
53
+ | callback | Function | Callback executed after clicking | ✅ | You can get node data/edge data/event information in the three menu callbacks respectively. |
54
+
55
+ Here's an example of writing a node right-click menu delete function:
56
+
57
+ ```tsx | pure
58
+ // Define a menu item for node deletion
59
+ const menuItem = {
60
+ className: "lf-menu-delete",
61
+ icon: true,
62
+ callback: (node) => {
63
+ // Delete the node and emit a custom-node:deleted event with the deleted node data.
64
+ lf.graphModel.deleteNode(node.id);
65
+ lf.graphModel.eventCenter.emit("custom-node:deleted", node);
66
+ },
67
+ }
68
+ ```
69
+
70
+ ## Adding Menu Options
71
+
72
+ You can use the `lf.extension.menu.addMenuConfig` method to add new options to the existing menu. The specific configuration example is as follows:
73
+
74
+ ```tsx | pure
75
+ import LogicFlow from "@logicflow/core";
76
+ import { Menu } from "@logicflow/extension";
77
+
78
+ import NodeData = LogicFlow.NodeData;
79
+ import EdgeData = LogicFlow.EdgeData;
80
+ import Position = LogicFlow.Position;
81
+
82
+ // Instantiate LogicFlow
83
+ const lf = new LogicFlow({
84
+ container: document.getElementById("app"),
85
+ // Register plugins
86
+ plugins: [Menu],
87
+ });
88
+ // Add options to the menu
89
+ // You can also call lf.extension.menu.addMenuConfig to set the menu, both have the same effect
90
+ lf.addMenuConfig({
91
+ nodeMenu: [
92
+ {
93
+ text: 'Share',
94
+ callback() {
95
+ alert('Share Success!')
96
+ },
97
+ },
98
+ {
99
+ text: 'Properties',
100
+ callback(node: NodeData) {
101
+ alert(`
102
+ Node ID: ${node.id}
103
+ Node Type: ${node.type}
104
+ Node Position: (x: ${node.x}, y: ${node.y})
105
+ `)
106
+ },
107
+ },
108
+ ],
109
+ edgeMenu: [
110
+ {
111
+ text: 'Properties',
112
+ callback(edge: EdgeData) {
113
+ const {
114
+ id,
115
+ type,
116
+ startPoint,
117
+ endPoint,
118
+ sourceNodeId,
119
+ targetNodeId,
120
+ } = edge
121
+ alert(`
122
+ Edge ID: ${id}
123
+ Edge Type: ${type}
124
+ Start Point: (x: ${startPoint.x}, y: ${startPoint.y})
125
+ End Point: (x: ${endPoint.x}, y: ${endPoint.y})
126
+ Source Node ID: ${sourceNodeId}
127
+ Target Node ID: ${targetNodeId}
128
+ `)
129
+ },
130
+ },
131
+ ],
132
+ graphMenu: [
133
+ {
134
+ text: 'Share',
135
+ callback() {
136
+ alert('Share Success!')
137
+ },
138
+ },
139
+ {
140
+ text: 'Add Node',
141
+ callback(data: Position) {
142
+ lf.addNode({
143
+ type: 'rect',
144
+ x: data.x,
145
+ y: data.y,
146
+ })
147
+ },
148
+ },
149
+ ],
150
+ })
151
+ lf.render();
152
+ ```
153
+
154
+ ## Overwriting Menus
155
+
156
+ If there are unwanted options in the default menu, or it doesn't meet the requirements, you can use `lf.setMenuConfig` to override the default menu and achieve a custom menu effect.
157
+
158
+ ```tsx | pure
159
+ lf.setMenuConfig({
160
+ nodeMenu: [
161
+ {
162
+ text: "Delete",
163
+ callback(node) {
164
+ lf.deleteNode(node.id);
165
+ },
166
+ },
167
+ ], // Override the default node right-click menu
168
+ edgeMenu: false, // Remove the default edge right-click menu
169
+ graphMenu: [], // Override the default edge right-click menu, same behavior as false
170
+ });
171
+ ```
172
+
173
+ ## Configuring Menus for Specified Element Types
174
+
175
+ In addition to overwriting the entire menu above, you can also use `lf.setMenuByType` to set menus for elements of specified types.
176
+
177
+ ```tsx | pure
178
+ lf.setMenuByType({
179
+ type: "bpmn:startEvent",
180
+ menu: [
181
+ {
182
+ text: "Share111",
183
+ callback() {
184
+ console.log("Share Success222!");
185
+ },
186
+ },
187
+ ],
188
+ });
189
+ ```
190
+
191
+ ## Dynamic Enable/Disable Menu Items<Badge>New in 2.1.0</Badge>
192
+
193
+ To provide more flexible interaction, version 2.1.0 adds functionality to dynamically control the disabled state of menu items, allowing you to dynamically disable or enable specific menu items based on business logic.
194
+
195
+ ### API
196
+
197
+ ```tsx | pure
198
+ lf.changeMenuItemDisableStatus(menuKey, text, disabled)
199
+ ```
200
+
201
+ Parameter description:
202
+ - `menuKey`: Menu type, possible values are `'nodeMenu'` | `'edgeMenu'` | `'graphMenu'` | `'selectionMenu'`
203
+ - `text`: Text of the menu item to operate on
204
+ - `disabled`: Whether to disable, `true` to disable, `false` to enable
205
+
206
+ ### Usage Example
207
+
208
+ ```tsx | pure
209
+ // Disable the "Delete" option in node menu
210
+ lf.changeMenuItemDisableStatus('nodeMenu', 'Delete', true)
211
+
212
+ // Enable the "Properties" option in edge menu
213
+ lf.changeMenuItemDisableStatus('edgeMenu', 'Properties', false)
214
+
215
+ // Disable the "Share" option in graph menu
216
+ lf.changeMenuItemDisableStatus('graphMenu', 'Share', true)
217
+ ```
218
+
219
+ ### Setting Disabled State During Configuration
220
+
221
+ You can also directly set certain menu items to disabled state when configuring the menu:
222
+
223
+ ```tsx | pure
224
+ lf.addMenuConfig({
225
+ nodeMenu: [
226
+ {
227
+ text: 'Delete',
228
+ disabled: true, // Initially disabled
229
+ callback(node: NodeData) {
230
+ lf.deleteNode(node.id)
231
+ },
232
+ },
233
+ {
234
+ text: 'Copy',
235
+ disabled: false, // Initially enabled
236
+ callback(node: NodeData) {
237
+ lf.cloneNode(node.id)
238
+ },
239
+ },
240
+ ],
241
+ })
242
+ ```
243
+
244
+ ## Selection Menu
245
+
246
+ After using the selection plugin, the selection component will also display a menu. By default, the selection menu only has a delete operation.
247
+ Like other menu items, you can call the methods provided by the Menu plugin to modify the selection menu configuration.
248
+
249
+ ```tsx | pure
250
+ // Example: Set the selection menu to not display
251
+ lf.setMenuByType({
252
+ type: "lf:defaultSelectionMenu",
253
+ menu: [],
254
+ });
255
+ ```
256
+
257
+ ## Setting Menus for Custom Nodes
258
+
259
+ In addition to setting menus for general canvas elements above, LogicFlow also supports setting menus for custom nodes:
260
+
261
+ ```tsx | pure
262
+
263
+ // index.js
264
+ import { RectNode, CustomeModel } from "./custom.ts";
265
+ // Register custom node
266
+ lf.register({
267
+ type: "custome_node",
268
+ view: RectNode,
269
+ model: CustomeModel,
270
+ });
271
+ // Set custom node menu
272
+ lf.setMenuByType({
273
+ type: "custome_node",
274
+ menu: [
275
+ {
276
+ className: "lf-menu-delete",
277
+ icon: true,
278
+ callback: (node) => {
279
+ lf.graphModel.deleteNode(node.id);
280
+ lf.graphModel.eventCenter.emit("custom:event", node);
281
+ },
282
+ },
283
+ {
284
+ text: "edit",
285
+ className: "lf-menu-item",
286
+ callback: (node) => {
287
+ lf.graphModel.setElementStateById(node.id, 2);
288
+ },
289
+ },
290
+ {
291
+ text: "copy",
292
+ className: "lf-menu-item",
293
+ disabled: false, // Can set disabled state
294
+ callback: (node) => {
295
+ lf.graphModel.cloneNode(node.id);
296
+ },
297
+ }
298
+ ],
299
+ });
300
+
301
+ lf.on("custom:event", (node) => {
302
+ console.log(node);
303
+ });
304
+ ```
305
+
306
+ ### Custom Menu Styles
307
+
308
+ The Menu plugin sets a class for each DOM it displays. Users can override the original style based on the class in the menu structure and set styles that match the host's style.
309
+
310
+ - Menu: lf-menu
311
+ - Menu item: lf-menu-item, user-defined className
312
+ - Menu item text: lf-menu-item-text
313
+ - Menu item icon: lf-menu-item-icon, need to set the menu item configuration icon to true
314
+ - Disabled menu item: lf-menu-item__disabled, this class is automatically added when a menu item is disabled
315
+
316
+ By setting these classes, you can override the default style, beautify font color, set menu item icons, etc.
317
+
318
+ ## Effect
319
+ <a href="https://codesandbox.io/embed/dazzling-hypatia-en8s9?fontsize=14&hidenavigation=1&theme=dark&view=preview" target="_blank"> Go to CodeSandbox for examples </a>
@@ -0,0 +1,377 @@
1
+ ---
2
+ nav: 指南
3
+ group:
4
+ title: 插件功能
5
+ order: 3
6
+ title: 右键菜单 (Menu)
7
+ order: 1
8
+ toc: content
9
+ ---
10
+
11
+ 在使用流程图工具进行编辑时,用户的注意力往往集中在画布区域。相比频繁移动鼠标去点击顶部菜单栏或使用快捷键,直接在节点、边或空白区域右键操作会更高效、符合直觉。为了更好地贴合用户的操作习惯,LogicFlow内置了右键菜单,让常用操作触手可及,提升整体编辑体验。
12
+
13
+ ## 启用
14
+
15
+ 引入并启用默认菜单
16
+
17
+ ```tsx | pure
18
+ import LogicFlow from "@logicflow/core";
19
+ import { Menu } from "@logicflow/extension";
20
+ import "@logicflow/extension/lib/style/index.css";
21
+
22
+ LogicFlow.use(Menu); // 全局引入
23
+
24
+ const lf = new LogicFlow({
25
+ plugins: [Menu], // 局部引入
26
+ })
27
+ ```
28
+
29
+ 默认情况下,菜单插件支持节点菜单、边菜单、画布菜单,并内置了以下功能:
30
+
31
+ - 节点右键菜单(nodeMenu): 删除、复制、编辑文案
32
+ - 边右键菜单(edgeMenu):删除、编辑文案
33
+ - 画布右键菜单(graphMenu):无
34
+
35
+ 当然,只支持这些配置项是远远不够的,因此我们还支持用户定制菜单配置项。
36
+
37
+ ## 菜单配置项
38
+
39
+ 菜单中的每一项功能,可以用一条配置进行表示。具体字段如下:
40
+
41
+ | 字段 | 类型 | 作用 | 是否必须 | 描述 |
42
+ | --------- | ---------------- | -------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
43
+ | text | string | 文案 | | 菜单项展示的文案 |
44
+ | className | string | class 名称 | | 每一项默认 class 为 lf-menu-item,设置了此字段,class 会在原来的基础上添加 className。 |
45
+ | icon | boolean / string | 是否创建 icon 的 span 展位 | | 如果简单的文案不能丰富表示菜单,可以加个 icon。设置为 `true` 时会创建一个 class 为 `lf-menu-icon` 的空图标容器。<br/>`2.1.0`版本开始,支持多种图标格式:图片文件路径(如 `./icon.png`)、base64 图片数据(如 `data:image/png;base64,...`)、CSS 类名或 HTML 内容。一般与 className 配合使用。 |
46
+ | disabled | boolean | 是否禁用菜单项 | | 设置为 true 时,菜单项会显示为灰色且无法点击。可以通过 `changeMenuItemDisableStatus` 方法动态修改此状态。 |
47
+ | callback | Function | 点击后执行的回调 | ✅ | 三种菜单回调中分别可以拿到节点数据/边数据/事件信息。 |
48
+
49
+ 这里以节点右键菜单删除功能的写法为例:
50
+
51
+ ```tsx | pure
52
+ // 定义一个做节点删除动作的菜单项
53
+ const menuItem = {
54
+ className: "lf-menu-delete",
55
+ icon: true,
56
+ callback: (node) => {
57
+ // 删除节点,并触发一个自定义事件 custom-node:deleted,把当前删除的节点信息抛出去
58
+ lf.graphModel.deleteNode(node.id);
59
+ lf.graphModel.eventCenter.emit("custom-node:deleted", node);
60
+ },
61
+ }
62
+ ```
63
+
64
+ ## API
65
+
66
+ ### addMenuConfig
67
+
68
+ 通过`addMenuConfig`方法可以在原有菜单的基础上追加新的选项,具体配置示例如下:
69
+
70
+ ```tsx | pure
71
+ import LogicFlow from '@logicflow/core'
72
+ import { Menu } from '@logicflow/extension'
73
+
74
+ import NodeData = LogicFlow.NodeData
75
+ import EdgeData = LogicFlow.EdgeData
76
+ import Position = LogicFlow.Position
77
+
78
+ // 实例化 LogicFlow
79
+ const lf = new LogicFlow({
80
+ container: document.getElementById('app'),
81
+ // 注册插件
82
+ plugins: [Menu],
83
+ })
84
+ // 为菜单追加选项
85
+ // 也可以通过调用 lf.extension.menu.addMenuConfig 设置菜单,二者效果是相同的
86
+ lf.addMenuConfig({
87
+ nodeMenu: [
88
+ {
89
+ text: '分享',
90
+ callback() {
91
+ alert('分享成功!')
92
+ },
93
+ },
94
+ {
95
+ text: '属性',
96
+ callback(node: NodeData) {
97
+ alert(`
98
+ 节点id:${node.id}
99
+ 节点类型:${node.type}
100
+ 节点坐标:(x: ${node.x}, y: ${node.y})
101
+ `)
102
+ },
103
+ },
104
+ ],
105
+ edgeMenu: [
106
+ {
107
+ text: '属性',
108
+ callback(edge: EdgeData) {
109
+ const {
110
+ id,
111
+ type,
112
+ startPoint,
113
+ endPoint,
114
+ sourceNodeId,
115
+ targetNodeId,
116
+ } = edge
117
+ alert(`
118
+ 边id:${id}
119
+ 边类型:${type}
120
+ 边起点坐标:(startPoint: [${startPoint.x}, ${startPoint.y}])
121
+ 边终点坐标:(endPoint: [${endPoint.x}, ${endPoint.y}])
122
+ 源节点id:${sourceNodeId}
123
+ 目标节点id:${targetNodeId}
124
+ `)
125
+ },
126
+ },
127
+ ],
128
+ graphMenu: [
129
+ {
130
+ text: '分享',
131
+ callback() {
132
+ alert('分享成功!')
133
+ },
134
+ },
135
+ {
136
+ text: '添加节点',
137
+ callback(data: Position) {
138
+ lf.addNode({
139
+ type: 'rect',
140
+ x: data.x,
141
+ y: data.y,
142
+ })
143
+ },
144
+ },
145
+ ],
146
+ })
147
+ lf.render()
148
+ ```
149
+
150
+ ### setMenuConfig
151
+
152
+ 如果默认菜单中存在不需要的选项,或者无法满足需求,可以通过`lf.setMenuConfig`覆盖默认菜单,实现自定义菜单的效果。
153
+
154
+ ```tsx | pure
155
+ lf.setMenuConfig({
156
+ nodeMenu: [
157
+ {
158
+ text: "删除",
159
+ callback(node) {
160
+ lf.deleteNode(node.id);
161
+ },
162
+ },
163
+ ], // 覆盖默认的节点右键菜单
164
+ edgeMenu: false, // 删除默认的边右键菜单
165
+ graphMenu: [], // 覆盖默认的边右键菜单,与false表现一样
166
+ });
167
+ ```
168
+
169
+ ### setMenuByType
170
+
171
+ 除了上面的复写整个菜单外,还可以使用`lf.setMenuByType`为指定类型的元素设置菜单。
172
+
173
+ ```tsx | pure
174
+ lf.setMenuByType({
175
+ type: "bpmn:startEvent",
176
+ menu: [
177
+ {
178
+ text: "分享111",
179
+ callback() {
180
+ console.log("分享成功222!");
181
+ },
182
+ },
183
+ ],
184
+ });
185
+ ```
186
+
187
+ ### changeMenuItemDisableStatus<Badge>2.1.0新增</Badge>
188
+
189
+ 为了提供更灵活的交互,在2.1.0版本新增提供了动态控制菜单项禁用状态的功能,可以根据业务逻辑动态地禁用或启用特定的菜单项。
190
+
191
+ ```tsx | pure
192
+ lf.changeMenuItemDisableStatus(menuKey, text, disabled)
193
+ ```
194
+
195
+ 参数说明:
196
+ - `menuKey`: 菜单类型,可选值为 `'nodeMenu'` | `'edgeMenu'` | `'graphMenu'` | `'selectionMenu'`
197
+ - `text`: 要操作的菜单项文本
198
+ - `disabled`: 是否禁用,`true` 为禁用,`false` 为启用
199
+
200
+ #### 使用示例
201
+
202
+ ```tsx | pure
203
+ // 禁用节点菜单中的"删除"选项
204
+ lf.changeMenuItemDisableStatus('nodeMenu', '删除', true)
205
+
206
+ // 启用边菜单中的"属性"选项
207
+ lf.changeMenuItemDisableStatus('edgeMenu', '属性', false)
208
+
209
+ // 禁用画布菜单中的"分享"选项
210
+ lf.changeMenuItemDisableStatus('graphMenu', '分享', true)
211
+ ```
212
+
213
+ #### 配置时设置禁用状态
214
+
215
+ 也可以在配置菜单时直接设置某些菜单项为禁用状态:
216
+
217
+ ```tsx | pure
218
+ lf.addMenuConfig({
219
+ nodeMenu: [
220
+ {
221
+ text: '删除',
222
+ disabled: true, // 初始状态为禁用
223
+ callback(node: NodeData) {
224
+ lf.deleteNode(node.id)
225
+ },
226
+ },
227
+ {
228
+ text: '复制',
229
+ disabled: false, // 初始状态为启用
230
+ callback(node: NodeData) {
231
+ lf.cloneNode(node.id)
232
+ },
233
+ },
234
+ ],
235
+ })
236
+ ```
237
+
238
+ ## 选区菜单
239
+
240
+ 在使用了选区插件后,选区插件也会出现菜单,默认情况下选区菜单只有删除操作。
241
+ 和其他菜单项一样,可以调用Menu插件提供的方法对选区菜单配置进行修改。
242
+
243
+ ```tsx | pure
244
+ // 一个🌰:设置选区菜单不展示
245
+ lf.setMenuByType({
246
+ type: "lf:defaultSelectionMenu",
247
+ menu: [],
248
+ });
249
+ ```
250
+
251
+ ## 为自定义节点设置菜单
252
+
253
+ 除了上面的为画布通用元素设置菜单外,LogicFlow还支持为自定义节点设置菜单:
254
+
255
+ ```tsx | pure
256
+
257
+ // index.js
258
+ import { RectNode, CustomeModel } from "./custom.ts";
259
+ // 注册自定义节点
260
+ lf.register({
261
+ type: "custome_node",
262
+ view: RectNode,
263
+ model: CustomeModel,
264
+ });
265
+ // 设置自定义节点菜单
266
+ lf.setMenuByType({
267
+ type: "custome_node",
268
+ menu: [
269
+ {
270
+ className: "lf-menu-delete",
271
+ icon: true,
272
+ callback: (node) => {
273
+ lf.graphModel.deleteNode(node.id);
274
+ lf.graphModel.eventCenter.emit("custom:event", node);
275
+ },
276
+ },
277
+ {
278
+ text: "edit",
279
+ className: "lf-menu-item",
280
+ callback: (node) => {
281
+ this.lf.graphModel.setElementStateById(node.id, 2);
282
+ },
283
+ },
284
+ {
285
+ text: "copy",
286
+ className: "lf-menu-item",
287
+ disabled: false, // 可以设置禁用状态
288
+ callback: (node) => {
289
+ this.lf.graphModel.cloneNode(node.id);
290
+ },
291
+ }
292
+ ],
293
+ });
294
+
295
+ lf.on("custom:event", (node) => {
296
+ console.log(node);
297
+ });
298
+ ```
299
+
300
+ ## 自定义菜单样式
301
+
302
+ Menu插件为其展示的每个DOM都设置了 class ,用户可以根据菜单结构中的 class 覆盖原有样式,设置符合宿主风格的样式。
303
+
304
+ - 菜单:lf-menu
305
+ - 菜单项:lf-menu-item、用户自定义的 className
306
+ - 菜单项-文案:lf-menu-item-text
307
+ - 菜单项-图标:lf-menu-item-icon,需要将菜单项配置 icon 设置为 true
308
+ - 禁用菜单项:lf-menu-item__disabled,菜单项被禁用时会自动添加此 class
309
+
310
+ 通过设置这些 class,可以覆盖默认样式,美化字体颜色,设置菜单项 icon 等。
311
+
312
+ ## 自定义菜单Icon<Badge>2.1.0新增</Badge>
313
+ 菜单组件现在支持多种图标配置方式,可以通过 `MenuItem` 的 `icon` 字段来设置图标,目前支持以下几种Icon设置方式:
314
+
315
+ #### 1. 布尔值(兼容老逻辑)
316
+ ```typescript
317
+ {
318
+ text: '删除',
319
+ icon: true, // 创建空的图标容器
320
+ callback: (node) => { /* ... */ }
321
+ }
322
+ ```
323
+
324
+ #### 2. CSS类名(单个类名)
325
+ ```typescript
326
+ {
327
+ text: '删除',
328
+ icon: 'fa-trash', // 添加多个类名
329
+ callback: (node) => { /* ... */ }
330
+ }
331
+
332
+ // 或者使用点开头
333
+ {
334
+ text: '删除',
335
+ icon: '.fa .fa-trash', // 添加多个类名
336
+ callback: (node) => { /* ... */ }
337
+ }
338
+ ```
339
+
340
+ #### 3. 图片文件路径
341
+
342
+ :::warning{title=Tip}
343
+ 目前只支持 `png` `jpg` `jpeg` `gif` `svg` `webp` `ico` `bmp` 格式的图片
344
+ :::
345
+
346
+ ```typescript
347
+ {
348
+ text: '删除',
349
+ icon: './assets/icons/delete.png', // 本地图片文件
350
+ callback: (node) => { /* ... */ }
351
+ }
352
+
353
+ {
354
+ text: '复制',
355
+ icon: 'https://example.com/icons/copy.png', // 远程图片
356
+ callback: (node) => { /* ... */ }
357
+ }
358
+ ```
359
+
360
+ #### 5. HTML内容
361
+ ```typescript
362
+ {
363
+ text: '删除',
364
+ icon: '<i class="fa fa-trash"></i>', // 直接插入HTML
365
+ callback: (node) => { /* ... */ }
366
+ }
367
+
368
+ // SVG图标
369
+ {
370
+ text: '编辑',
371
+ icon: '<svg width="16" height="16"><path d="..."/></svg>',
372
+ callback: (node) => { /* ... */ }
373
+ }
374
+ ```
375
+
376
+ ## 功能演示
377
+ <code id="react-portal" src="@/src/tutorial/extension/menu"></code>