@logicflow/extension 2.0.10 → 2.0.12
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/.turbo/turbo-build.log +9 -17
- package/CHANGELOG.md +37 -0
- package/dist/index.css +278 -1
- package/es/bpmn-elements/presets/Pool/Pool.d.ts +2 -2
- package/es/dynamic-group/index.d.ts +2 -1
- package/es/dynamic-group/index.js +21 -19
- package/es/dynamic-group/model.js +1 -5
- package/es/dynamic-group/node.d.ts +8 -1
- package/es/dynamic-group/node.js +87 -22
- package/es/index.css +278 -1
- package/es/index.less +1 -0
- package/es/materials/group/GroupNode.d.ts +5 -5
- package/es/materials/group/GroupNode.js +3 -3
- package/es/materials/group/index.js +5 -5
- package/es/materials/node-selection/index.d.ts +6 -6
- package/es/materials/node-selection/index.js +90 -10
- package/es/style/index.css +278 -1
- package/es/style/index.less +327 -0
- package/lib/bpmn-elements/presets/Pool/Pool.d.ts +2 -2
- package/lib/dynamic-group/index.d.ts +2 -1
- package/lib/dynamic-group/index.js +21 -19
- package/lib/dynamic-group/model.js +1 -5
- package/lib/dynamic-group/node.d.ts +8 -1
- package/lib/dynamic-group/node.js +87 -22
- package/lib/index.css +278 -1
- package/lib/index.less +1 -0
- package/lib/materials/group/GroupNode.d.ts +5 -5
- package/lib/materials/group/GroupNode.js +3 -3
- package/lib/materials/group/index.js +5 -5
- package/lib/materials/node-selection/index.d.ts +6 -6
- package/lib/materials/node-selection/index.js +89 -9
- package/lib/style/index.css +278 -1
- package/lib/style/index.less +327 -0
- package/package.json +3 -3
- package/src/components/mini-map/index.ts +11 -0
- package/src/dynamic-group/index.ts +29 -8
- package/src/dynamic-group/model.ts +1 -6
- package/src/dynamic-group/node.ts +136 -85
- package/src/index.ts +1 -0
- package/src/materials/group/GroupNode.ts +3 -3
- package/src/materials/group/index.ts +5 -5
- package/src/materials/node-selection/index.ts +115 -14
- package/src/style/index.less +3 -5
- package/src/style/raw.ts +3 -7
- package/src/tools/label/Label.tsx +106 -55
- package/src/tools/label/LabelModel.ts +1 -0
- package/src/tools/label/index.ts +64 -3
- package/src/tools/proximity-connect/index.ts +399 -0
- package/stats.html +1 -1
- package/dist/index.min.js +0 -2
- package/dist/index.min.js.map +0 -1
|
@@ -25,6 +25,7 @@ export interface ILabelState {
|
|
|
25
25
|
isEditing: boolean
|
|
26
26
|
isHovered: boolean
|
|
27
27
|
isDragging: boolean
|
|
28
|
+
isSelected: boolean
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
@observer
|
|
@@ -52,6 +53,7 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
52
53
|
isEditing: false,
|
|
53
54
|
isHovered: false,
|
|
54
55
|
isDragging: false,
|
|
56
|
+
isSelected: false,
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -75,35 +77,34 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
75
77
|
const {
|
|
76
78
|
editConfigModel: { nodeTextDraggable },
|
|
77
79
|
} = graphModel
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.
|
|
80
|
+
// 当 label 允许拖拽 且不处于拖拽状态、不处于编辑状态时, StepDrag 开启拖拽
|
|
81
|
+
if (
|
|
82
|
+
(label.draggable ?? nodeTextDraggable) &&
|
|
83
|
+
!this.state.isDragging &&
|
|
84
|
+
!this.state.isEditing
|
|
85
|
+
) {
|
|
82
86
|
this.stepDrag.handleMouseDown(e)
|
|
83
87
|
}
|
|
84
88
|
}
|
|
89
|
+
handleMouseUp = (e: MouseEvent) => {
|
|
90
|
+
if (this.state.isDragging) {
|
|
91
|
+
this.stepDrag.handleMouseUp(e)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
85
94
|
handleDragging = ({ deltaX, deltaY }: IDragParams) => {
|
|
86
|
-
|
|
95
|
+
if (!this.state.isDragging) {
|
|
96
|
+
this.setState({ isDragging: true })
|
|
97
|
+
}
|
|
98
|
+
const { label, graphModel } = this.props
|
|
87
99
|
|
|
88
100
|
// DONE: 添加缩放时拖拽的逻辑,对 deltaX 和 deltaY 进行按比例缩放
|
|
89
101
|
const { transformModel } = graphModel
|
|
90
102
|
const [curDeltaX, curDeltaY] = transformModel.fixDeltaXY(deltaX, deltaY)
|
|
91
103
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
const elementLabel = _label as LabelConfig[]
|
|
97
|
-
const idx = findIndex(elementLabel, (cur) => cur.id === label.id)
|
|
98
|
-
|
|
99
|
-
const target = elementLabel[idx]
|
|
100
|
-
elementLabel[idx] = {
|
|
101
|
-
...target,
|
|
102
|
-
x: target.x + curDeltaX,
|
|
103
|
-
y: target.y + curDeltaY,
|
|
104
|
-
}
|
|
105
|
-
const targetElem = graphModel.getElement(element.id)
|
|
106
|
-
targetElem?.setProperty('_label', elementLabel)
|
|
104
|
+
this.setElementModelLabelInfo({
|
|
105
|
+
x: label.x + curDeltaX,
|
|
106
|
+
y: label.y + curDeltaY,
|
|
107
|
+
})
|
|
107
108
|
|
|
108
109
|
graphModel.eventCenter.emit('label:drag', {
|
|
109
110
|
data: label.getData(),
|
|
@@ -114,6 +115,21 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
114
115
|
this.setState({ isDragging: false })
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
handleClick = (e: MouseEvent) => {
|
|
119
|
+
const { label, element, graphModel } = this.props
|
|
120
|
+
// 更新当前Label选中状态
|
|
121
|
+
element.setSelected(!this.state.isSelected)
|
|
122
|
+
this.setState({ isSelected: !this.state.isSelected })
|
|
123
|
+
this.setElementModelLabelInfo({
|
|
124
|
+
isSelected: true,
|
|
125
|
+
})
|
|
126
|
+
graphModel.eventCenter.emit('label:click', {
|
|
127
|
+
data: label.getData(),
|
|
128
|
+
e,
|
|
129
|
+
model: element,
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
117
133
|
handleDbClick = (e: MouseEvent) => {
|
|
118
134
|
const { label, element, graphModel } = this.props
|
|
119
135
|
graphModel.eventCenter.emit('label:dblclick', {
|
|
@@ -162,9 +178,28 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
162
178
|
this.setState({
|
|
163
179
|
isDragging: false,
|
|
164
180
|
isHovered: false,
|
|
181
|
+
isSelected: false,
|
|
165
182
|
})
|
|
166
183
|
}
|
|
167
184
|
|
|
185
|
+
setElementModelLabelInfo(data) {
|
|
186
|
+
const { label, element, graphModel } = this.props
|
|
187
|
+
const {
|
|
188
|
+
properties: { _label },
|
|
189
|
+
} = element
|
|
190
|
+
const elementLabel = _label as LabelConfig[]
|
|
191
|
+
const idx = findIndex(elementLabel, (cur) => cur.id === label.id)
|
|
192
|
+
|
|
193
|
+
const target = elementLabel[idx]
|
|
194
|
+
elementLabel[idx] = {
|
|
195
|
+
...target,
|
|
196
|
+
...data,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const targetElem = graphModel.getElement(element.id)
|
|
200
|
+
targetElem?.setProperty('_label', elementLabel)
|
|
201
|
+
}
|
|
202
|
+
|
|
168
203
|
// 重新计算 Label 大小
|
|
169
204
|
reCalcLabelSize = () => {}
|
|
170
205
|
|
|
@@ -175,37 +210,49 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
175
210
|
const { label, element, graphModel } = this.props
|
|
176
211
|
|
|
177
212
|
// 在点击元素、边或者画布 时,结束 Label 的编辑态
|
|
178
|
-
graphModel.eventCenter.on(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const elementLabel = _label as LabelConfig[]
|
|
190
|
-
const idx = findIndex(elementLabel, (cur) => cur.id === label.id)
|
|
191
|
-
|
|
192
|
-
const target = elementLabel[idx]
|
|
193
|
-
elementLabel[idx] = {
|
|
194
|
-
...target,
|
|
195
|
-
value,
|
|
196
|
-
content,
|
|
213
|
+
graphModel.eventCenter.on(
|
|
214
|
+
'blank:click,node:click,edge:click,label:click',
|
|
215
|
+
({ data }) => {
|
|
216
|
+
// 点击的不是label 、点击的不是当前label、点击的是当前label,且当前 label 处于选中态
|
|
217
|
+
// 则取消选中态
|
|
218
|
+
if (
|
|
219
|
+
data?.type !== 'label' ||
|
|
220
|
+
(data.type === 'label' && data.id !== label.id) ||
|
|
221
|
+
this.state.isSelected
|
|
222
|
+
) {
|
|
223
|
+
this.setState({ isSelected: false })
|
|
197
224
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
225
|
+
// 点击的不是label 、点击的不是当前label、点击的是当前label,且当前 label 处于编辑态
|
|
226
|
+
// 则结束编辑态
|
|
227
|
+
if (
|
|
228
|
+
(data?.type !== 'label' ||
|
|
229
|
+
(data.type == 'label' && data.id !== label.id)) &&
|
|
230
|
+
this.state.isEditing
|
|
231
|
+
) {
|
|
232
|
+
this.setState({ isEditing: false })
|
|
233
|
+
|
|
234
|
+
const value = this.textRef.current?.innerText ?? ''
|
|
235
|
+
const content = this.textRef.current?.innerHTML ?? ''
|
|
236
|
+
|
|
237
|
+
this.setElementModelLabelInfo({
|
|
238
|
+
value,
|
|
239
|
+
content,
|
|
240
|
+
isSelected: false,
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
element.setElementState(ElementState.DEFAULT)
|
|
244
|
+
}
|
|
245
|
+
// 点击的不是label 、点击的不是当前label、点击的是当前label,且当前 label 的文本DOM存在
|
|
246
|
+
// 则结束文本DOM的编辑态
|
|
247
|
+
if (
|
|
248
|
+
(data?.type !== 'label' ||
|
|
249
|
+
(data.type == 'label' && data.id !== label.id)) &&
|
|
250
|
+
this.textRef.current
|
|
251
|
+
) {
|
|
252
|
+
this.textRef.current.contentEditable = 'false'
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
)
|
|
209
256
|
// TODO: 节点拖拽结束后,更新 Label 的位置
|
|
210
257
|
// eventCenter.on('node:drag', () => {})
|
|
211
258
|
// eventCenter.on('node:drop', () => {})
|
|
@@ -216,7 +263,7 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
216
263
|
|
|
217
264
|
componentDidUpdate() {
|
|
218
265
|
// snapshot: any, // previousState: Readonly<ILabelState>, // previousProps: Readonly<ILabelProps>,
|
|
219
|
-
console.log('Label componentDidUpdate')
|
|
266
|
+
// console.log('Label componentDidUpdate')
|
|
220
267
|
// console.log('previousProps', previousProps)
|
|
221
268
|
// console.log('previousState', previousState)
|
|
222
269
|
// console.log('snapshot', snapshot)
|
|
@@ -232,7 +279,7 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
232
279
|
|
|
233
280
|
render() {
|
|
234
281
|
const { label, element, graphModel } = this.props
|
|
235
|
-
const { isDragging, isHovered, isEditing } = this.state
|
|
282
|
+
const { isDragging, isHovered, isSelected, isEditing } = this.state
|
|
236
283
|
const { transformModel } = graphModel
|
|
237
284
|
const { transform } = transformModel.getTransformStyle()
|
|
238
285
|
const {
|
|
@@ -260,13 +307,14 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
260
307
|
? `${transform} rotate(${rotate}deg)`
|
|
261
308
|
: `${transform} rotate(${vertical ? -0.25 : 0}turn)`,
|
|
262
309
|
}
|
|
263
|
-
|
|
264
310
|
return (
|
|
265
311
|
<div
|
|
266
312
|
id={`element-container-${id}`}
|
|
267
313
|
className={classNames('lf-label-editor-container')}
|
|
268
314
|
style={containerStyle}
|
|
269
315
|
onMouseDown={this.handleMouseDown}
|
|
316
|
+
onMouseUp={this.handleMouseUp}
|
|
317
|
+
onClick={this.handleClick}
|
|
270
318
|
onDblClick={this.handleDbClick}
|
|
271
319
|
onBlur={this.handleBlur}
|
|
272
320
|
onMouseEnter={this.setHoverOn}
|
|
@@ -279,12 +327,15 @@ export class Label extends Component<ILabelProps, ILabelState> {
|
|
|
279
327
|
className={classNames('lf-label-editor', {
|
|
280
328
|
'lf-label-editor-dragging': isDragging,
|
|
281
329
|
'lf-label-editor-editing': isEditing,
|
|
282
|
-
'lf-label-editor-hover': !isEditing && isHovered,
|
|
330
|
+
'lf-label-editor-hover': !isEditing && (isHovered || isSelected),
|
|
283
331
|
[`lf-label-editor-${textOverflowMode}`]: !isEditing,
|
|
284
332
|
})}
|
|
285
333
|
style={{
|
|
286
334
|
maxWidth: `${maxLabelWidth}px`,
|
|
287
|
-
|
|
335
|
+
boxSizing: 'border-box',
|
|
336
|
+
display: 'inline-block',
|
|
337
|
+
background:
|
|
338
|
+
isEditing || element.BaseType === 'edge' ? '#fff' : 'transparent',
|
|
288
339
|
...style,
|
|
289
340
|
}}
|
|
290
341
|
dangerouslySetInnerHTML={{ __html: content }}
|
package/src/tools/label/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import LogicFlow, { createUuid, GraphModel, TextMode } from '@logicflow/core'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
cloneDeep,
|
|
4
|
+
forEach,
|
|
5
|
+
isArray,
|
|
6
|
+
isEmpty,
|
|
7
|
+
isEqual,
|
|
8
|
+
isObject,
|
|
9
|
+
map,
|
|
10
|
+
} from 'lodash-es'
|
|
3
11
|
import LabelOverlay, { LabelConfigType } from './LabelOverlay'
|
|
4
12
|
import {
|
|
5
13
|
BBoxInfo,
|
|
@@ -53,7 +61,7 @@ export class Label implements Extension {
|
|
|
53
61
|
this.addEventListeners()
|
|
54
62
|
|
|
55
63
|
// TODO: 3. 自定义快捷键,比如 delete,选中 label 时,移除 label
|
|
56
|
-
|
|
64
|
+
this.rewriteShortcut()
|
|
57
65
|
|
|
58
66
|
// 插件中注册 LabelOverlay 工具,用于 label 的编辑
|
|
59
67
|
lf.tool.registerTool(LabelOverlay.toolName, LabelOverlay)
|
|
@@ -377,7 +385,60 @@ export class Label implements Extension {
|
|
|
377
385
|
// TODO: others methods ???
|
|
378
386
|
}
|
|
379
387
|
|
|
380
|
-
|
|
388
|
+
private rewriteShortcut() {
|
|
389
|
+
const { keyboard, graphModel } = this.lf
|
|
390
|
+
const {
|
|
391
|
+
options: { keyboard: keyboardOptions },
|
|
392
|
+
} = keyboard
|
|
393
|
+
keyboard.off(['backspace'])
|
|
394
|
+
keyboard.on(['backspace'], () => {
|
|
395
|
+
if (!keyboardOptions?.enabled) return true
|
|
396
|
+
if (graphModel.textEditElement) return true
|
|
397
|
+
const elements = graphModel.getSelectElements(true)
|
|
398
|
+
this.lf.clearSelectElements()
|
|
399
|
+
const {
|
|
400
|
+
graphModel: { editConfigModel },
|
|
401
|
+
} = this.lf
|
|
402
|
+
elements.edges.forEach((edge) => {
|
|
403
|
+
const { properties } = edge
|
|
404
|
+
if (
|
|
405
|
+
properties &&
|
|
406
|
+
!isEmpty(properties._label) &&
|
|
407
|
+
editConfigModel.textMode === TextMode.LABEL
|
|
408
|
+
) {
|
|
409
|
+
const newLabelList = properties._label.filter(
|
|
410
|
+
(label) => !label.isSelected,
|
|
411
|
+
)
|
|
412
|
+
// 如果两个labelList长度不一致,说明有选中的元素,此时backspace做的动作是删除label
|
|
413
|
+
if (!isEqual(newLabelList.length, properties._label.length)) {
|
|
414
|
+
const edgeModel = graphModel.getEdgeModelById(edge.id)
|
|
415
|
+
edgeModel?.setProperty('_label', newLabelList)
|
|
416
|
+
return
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
edge.id && this.lf.deleteEdge(edge.id)
|
|
420
|
+
})
|
|
421
|
+
elements.nodes.forEach((node) => {
|
|
422
|
+
const { properties } = node
|
|
423
|
+
if (
|
|
424
|
+
properties &&
|
|
425
|
+
!isEmpty(properties._label) &&
|
|
426
|
+
editConfigModel.textMode === TextMode.LABEL
|
|
427
|
+
) {
|
|
428
|
+
const newLabelList = properties._label.filter(
|
|
429
|
+
(label) => !label.isSelected,
|
|
430
|
+
)
|
|
431
|
+
if (!isEqual(newLabelList.length, properties._label.length)) {
|
|
432
|
+
const nodeModel = graphModel.getNodeModelById(node.id)
|
|
433
|
+
nodeModel?.setProperty('_label', newLabelList)
|
|
434
|
+
return
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
node.id && this.lf.deleteNode(node.id)
|
|
438
|
+
})
|
|
439
|
+
return false
|
|
440
|
+
})
|
|
441
|
+
}
|
|
381
442
|
|
|
382
443
|
/**
|
|
383
444
|
* 更新当前渲染使用的 Text or Label 模式
|