@logicflow/core 2.2.0 → 2.2.1

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 (236) hide show
  1. package/dist/index.css +3 -2
  2. package/dist/index.min.js +1 -1
  3. package/dist/index.min.js.map +1 -1
  4. package/es/LogicFlow.d.ts +9 -0
  5. package/es/LogicFlow.js +0 -1
  6. package/es/constant/index.d.ts +1 -1
  7. package/es/constant/index.js +1 -1
  8. package/es/constant/theme.d.ts +136 -0
  9. package/es/constant/theme.js +680 -0
  10. package/es/index.css +3 -2
  11. package/es/model/GraphModel.d.ts +10 -2
  12. package/es/model/GraphModel.js +48 -14
  13. package/es/model/TransformModel.js +9 -9
  14. package/es/model/edge/BaseEdgeModel.js +7 -2
  15. package/es/model/edge/PolylineEdgeModel.d.ts +7 -0
  16. package/es/model/edge/PolylineEdgeModel.js +136 -7
  17. package/es/model/node/BaseNodeModel.d.ts +12 -1
  18. package/es/model/node/BaseNodeModel.js +9 -2
  19. package/es/model/node/HtmlNodeModel.d.ts +12 -0
  20. package/es/model/node/HtmlNodeModel.js +19 -0
  21. package/es/model/node/PolygonNodeModel.js +3 -3
  22. package/es/options.d.ts +4 -2
  23. package/es/style/index.css +3 -2
  24. package/es/style/index.less +3 -2
  25. package/es/style/raw.d.ts +1 -1
  26. package/es/style/raw.js +1 -1
  27. package/es/tool/MultipleSelectTool.js +10 -5
  28. package/es/util/drag.js +0 -1
  29. package/es/util/edge.d.ts +40 -1
  30. package/es/util/edge.js +43 -9
  31. package/es/util/geometry.d.ts +8 -0
  32. package/es/util/geometry.js +79 -0
  33. package/es/util/theme.d.ts +2 -65
  34. package/es/util/theme.js +4 -281
  35. package/es/view/Anchor.d.ts +1 -0
  36. package/es/view/Anchor.js +24 -21
  37. package/es/view/Control.d.ts +5 -0
  38. package/es/view/Control.js +44 -57
  39. package/es/view/edge/BaseEdge.js +9 -0
  40. package/es/view/edge/PolylineEdge.js +13 -2
  41. package/es/view/node/BaseNode.d.ts +1 -0
  42. package/es/view/node/BaseNode.js +23 -11
  43. package/es/view/node/HtmlNode.js +2 -4
  44. package/es/view/overlay/CanvasOverlay.js +5 -2
  45. package/es/view/overlay/Grid.d.ts +12 -1
  46. package/es/view/overlay/Grid.js +85 -23
  47. package/es/view/overlay/OutlineOverlay.d.ts +1 -0
  48. package/es/view/overlay/OutlineOverlay.js +18 -17
  49. package/es/view/overlay/gridConfig.d.ts +46 -0
  50. package/es/view/overlay/gridConfig.js +99 -0
  51. package/es/view/shape/Polygon.d.ts +0 -7
  52. package/es/view/shape/Polygon.js +12 -43
  53. package/lib/LogicFlow.d.ts +9 -0
  54. package/lib/LogicFlow.js +0 -1
  55. package/lib/constant/index.d.ts +1 -1
  56. package/lib/constant/index.js +16 -2
  57. package/lib/constant/theme.d.ts +136 -0
  58. package/lib/constant/theme.js +683 -0
  59. package/lib/index.css +3 -2
  60. package/lib/model/GraphModel.d.ts +10 -2
  61. package/lib/model/GraphModel.js +49 -15
  62. package/lib/model/TransformModel.js +9 -9
  63. package/lib/model/edge/BaseEdgeModel.js +7 -2
  64. package/lib/model/edge/PolylineEdgeModel.d.ts +7 -0
  65. package/lib/model/edge/PolylineEdgeModel.js +136 -7
  66. package/lib/model/node/BaseNodeModel.d.ts +12 -1
  67. package/lib/model/node/BaseNodeModel.js +9 -2
  68. package/lib/model/node/HtmlNodeModel.d.ts +12 -0
  69. package/lib/model/node/HtmlNodeModel.js +19 -0
  70. package/lib/model/node/PolygonNodeModel.js +3 -3
  71. package/lib/options.d.ts +4 -2
  72. package/lib/style/index.css +3 -2
  73. package/lib/style/index.less +3 -2
  74. package/lib/style/raw.d.ts +1 -1
  75. package/lib/style/raw.js +1 -1
  76. package/lib/tool/MultipleSelectTool.js +10 -5
  77. package/lib/util/drag.js +0 -1
  78. package/lib/util/edge.d.ts +40 -1
  79. package/lib/util/edge.js +43 -9
  80. package/lib/util/geometry.d.ts +8 -0
  81. package/lib/util/geometry.js +81 -1
  82. package/lib/util/theme.d.ts +2 -65
  83. package/lib/util/theme.js +15 -292
  84. package/lib/view/Anchor.d.ts +1 -0
  85. package/lib/view/Anchor.js +24 -21
  86. package/lib/view/Control.d.ts +5 -0
  87. package/lib/view/Control.js +44 -57
  88. package/lib/view/edge/BaseEdge.js +9 -0
  89. package/lib/view/edge/PolylineEdge.js +13 -2
  90. package/lib/view/node/BaseNode.d.ts +1 -0
  91. package/lib/view/node/BaseNode.js +22 -10
  92. package/lib/view/node/HtmlNode.js +1 -3
  93. package/lib/view/overlay/CanvasOverlay.js +5 -2
  94. package/lib/view/overlay/Grid.d.ts +12 -1
  95. package/lib/view/overlay/Grid.js +83 -21
  96. package/lib/view/overlay/OutlineOverlay.d.ts +1 -0
  97. package/lib/view/overlay/OutlineOverlay.js +18 -17
  98. package/lib/view/overlay/gridConfig.d.ts +46 -0
  99. package/lib/view/overlay/gridConfig.js +104 -0
  100. package/lib/view/shape/Polygon.d.ts +0 -7
  101. package/lib/view/shape/Polygon.js +13 -45
  102. package/package.json +6 -1
  103. package/.turbo/turbo-build$colon$dev.log +0 -10
  104. package/.turbo/turbo-build.log +0 -33
  105. package/CHANGELOG.md +0 -1849
  106. package/__tests__/algorithm/egde.test.ts +0 -131
  107. package/__tests__/algorithm/index.test.ts +0 -74
  108. package/__tests__/algorithm/outline.test.ts +0 -43
  109. package/__tests__/bugs/1545-spec.test.ts +0 -42
  110. package/__tests__/event/event.test.ts +0 -22
  111. package/__tests__/history/history.test.ts +0 -28
  112. package/__tests__/logicflow.test.ts +0 -575
  113. package/__tests__/model/graphmodel.test.ts +0 -87
  114. package/__tests__/util/compatible.test.ts +0 -48
  115. package/__tests__/util/edge.test.ts +0 -224
  116. package/__tests__/util/geometry.test.ts +0 -14
  117. package/__tests__/util/graph.test.ts +0 -16
  118. package/__tests__/util/matrix.test.ts +0 -41
  119. package/__tests__/util/node.test.ts +0 -68
  120. package/__tests__/util/sampling.test.ts +0 -12
  121. package/__tests__/util/vector.test.ts +0 -50
  122. package/__tests__/util/zIndex.test.ts +0 -10
  123. package/src/LogicFlow.tsx +0 -2008
  124. package/src/algorithm/edge.ts +0 -67
  125. package/src/algorithm/index.ts +0 -70
  126. package/src/algorithm/outline.ts +0 -77
  127. package/src/algorithm/rotate.ts +0 -55
  128. package/src/common/drag.ts +0 -219
  129. package/src/common/history.ts +0 -108
  130. package/src/common/index.ts +0 -6
  131. package/src/common/keyboard.ts +0 -108
  132. package/src/common/matrix.ts +0 -122
  133. package/src/common/vector.ts +0 -93
  134. package/src/constant/index.ts +0 -179
  135. package/src/event/event.md +0 -66
  136. package/src/event/eventArgs.ts +0 -643
  137. package/src/event/eventEmitter.ts +0 -156
  138. package/src/history/index.ts +0 -119
  139. package/src/index.less +0 -1
  140. package/src/index.ts +0 -26
  141. package/src/keyboard/index.ts +0 -112
  142. package/src/keyboard/shortcut.ts +0 -200
  143. package/src/model/BaseModel.ts +0 -250
  144. package/src/model/EditConfigModel.ts +0 -334
  145. package/src/model/GraphModel.ts +0 -1788
  146. package/src/model/NestedTransformModel.ts +0 -121
  147. package/src/model/SnaplineModel.ts +0 -256
  148. package/src/model/TransformModel.ts +0 -258
  149. package/src/model/edge/BaseEdgeModel.ts +0 -777
  150. package/src/model/edge/BezierEdgeModel.ts +0 -197
  151. package/src/model/edge/LineEdgeModel.ts +0 -36
  152. package/src/model/edge/PolylineEdgeModel.ts +0 -672
  153. package/src/model/edge/index.ts +0 -4
  154. package/src/model/index.ts +0 -9
  155. package/src/model/node/BaseNodeModel.ts +0 -949
  156. package/src/model/node/CircleNodeModel.ts +0 -91
  157. package/src/model/node/DiamondNodeModel.ts +0 -132
  158. package/src/model/node/EllipseNodeModel.ts +0 -98
  159. package/src/model/node/HtmlNodeModel.ts +0 -50
  160. package/src/model/node/PolygonNodeModel.ts +0 -150
  161. package/src/model/node/RectNodeModel.ts +0 -69
  162. package/src/model/node/TextNodeModel.ts +0 -54
  163. package/src/model/node/index.ts +0 -8
  164. package/src/options.ts +0 -145
  165. package/src/style/index.less +0 -261
  166. package/src/style/raw.ts +0 -220
  167. package/src/tool/MultipleSelectTool.tsx +0 -132
  168. package/src/tool/TextEditTool.tsx +0 -193
  169. package/src/tool/index.ts +0 -101
  170. package/src/typings.d.ts +0 -5
  171. package/src/util/animation.ts +0 -29
  172. package/src/util/browser.ts +0 -4
  173. package/src/util/compatible.ts +0 -15
  174. package/src/util/drag.ts +0 -220
  175. package/src/util/edge.ts +0 -1060
  176. package/src/util/geometry.ts +0 -55
  177. package/src/util/graph.ts +0 -46
  178. package/src/util/index.ts +0 -17
  179. package/src/util/matrix.ts +0 -129
  180. package/src/util/mobx.ts +0 -23
  181. package/src/util/node.ts +0 -543
  182. package/src/util/raf.ts +0 -28
  183. package/src/util/resize.ts +0 -606
  184. package/src/util/sampling.ts +0 -85
  185. package/src/util/theme.ts +0 -375
  186. package/src/util/uuid.ts +0 -26
  187. package/src/util/vector.ts +0 -93
  188. package/src/util/zIndex.ts +0 -6
  189. package/src/view/Anchor.tsx +0 -445
  190. package/src/view/Control.tsx +0 -512
  191. package/src/view/Graph.tsx +0 -141
  192. package/src/view/Rotate.tsx +0 -113
  193. package/src/view/behavior/dnd.ts +0 -162
  194. package/src/view/behavior/index.ts +0 -2
  195. package/src/view/behavior/snapline.ts +0 -16
  196. package/src/view/edge/AdjustPoint.tsx +0 -425
  197. package/src/view/edge/Arrow.tsx +0 -54
  198. package/src/view/edge/BaseEdge.tsx +0 -650
  199. package/src/view/edge/BezierEdge.tsx +0 -101
  200. package/src/view/edge/LineEdge.tsx +0 -81
  201. package/src/view/edge/PolylineEdge.tsx +0 -299
  202. package/src/view/edge/index.ts +0 -6
  203. package/src/view/index.ts +0 -8
  204. package/src/view/node/BaseNode.tsx +0 -571
  205. package/src/view/node/CircleNode.tsx +0 -21
  206. package/src/view/node/DiamondNode.tsx +0 -24
  207. package/src/view/node/EllipseNode.tsx +0 -22
  208. package/src/view/node/HtmlNode.tsx +0 -95
  209. package/src/view/node/PolygonNode.tsx +0 -28
  210. package/src/view/node/RectNode.tsx +0 -30
  211. package/src/view/node/TextNode.tsx +0 -39
  212. package/src/view/node/index.ts +0 -8
  213. package/src/view/overlay/BackgroundOverlay.tsx +0 -34
  214. package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
  215. package/src/view/overlay/CanvasOverlay.tsx +0 -288
  216. package/src/view/overlay/Grid.tsx +0 -162
  217. package/src/view/overlay/ModificationOverlay.tsx +0 -31
  218. package/src/view/overlay/OutlineOverlay.tsx +0 -170
  219. package/src/view/overlay/SnaplineOverlay.tsx +0 -44
  220. package/src/view/overlay/ToolOverlay.tsx +0 -65
  221. package/src/view/overlay/getTransformHoc.tsx +0 -50
  222. package/src/view/overlay/index.ts +0 -8
  223. package/src/view/shape/Circle.tsx +0 -41
  224. package/src/view/shape/Ellipse.tsx +0 -42
  225. package/src/view/shape/Line.tsx +0 -39
  226. package/src/view/shape/Path.tsx +0 -22
  227. package/src/view/shape/Polygon.tsx +0 -91
  228. package/src/view/shape/Polyline.tsx +0 -31
  229. package/src/view/shape/Rect.tsx +0 -44
  230. package/src/view/shape/Text.tsx +0 -169
  231. package/src/view/shape/index.ts +0 -8
  232. package/src/view/text/BaseText.tsx +0 -134
  233. package/src/view/text/LineText.tsx +0 -168
  234. package/src/view/text/index.ts +0 -2
  235. package/stats.html +0 -4842
  236. package/tsconfig.json +0 -18
@@ -1,132 +0,0 @@
1
- import { Component } from 'preact/compat'
2
- import { IToolProps } from '.'
3
- import { Model, observer } from '..'
4
- import LogicFlow from '../LogicFlow'
5
- import { StepDrag, IDragParams } from '../util'
6
- import { ElementType, EventType } from '../constant'
7
- import { getNodeOutline, getEdgeOutline } from '../algorithm/outline'
8
-
9
- import GraphData = LogicFlow.GraphData
10
-
11
- @observer
12
- export default class MultipleSelect extends Component<IToolProps> {
13
- static toolName = 'multiple-select-tool'
14
- stepDrag: StepDrag
15
-
16
- constructor(props: IToolProps) {
17
- super(props)
18
- const {
19
- graphModel: { gridSize, eventCenter },
20
- } = props
21
- this.stepDrag = new StepDrag({
22
- onDragging: this.onDragging,
23
- step: gridSize,
24
- eventType: 'SELECTION',
25
- eventCenter,
26
- })
27
- }
28
-
29
- handleMouseDown = (ev: PointerEvent) => {
30
- this.stepDrag.handleMouseDown(ev)
31
- }
32
- // 使多选区域的滚轮事件可以触发画布的滚轮事件
33
- handleWheelEvent = (ev: WheelEvent) => {
34
- ev.preventDefault()
35
- const { deltaX, deltaY, clientX, clientY, ctrlKey } = ev
36
- const newEvent = new WheelEvent('wheel', {
37
- deltaX,
38
- deltaY,
39
- clientX,
40
- clientY,
41
- ctrlKey,
42
- })
43
- this.props.lf.container
44
- ?.querySelector('.lf-canvas-overlay[name="canvas-overlay"]')
45
- ?.dispatchEvent(newEvent)
46
- }
47
- onDragging = ({ deltaX, deltaY }: IDragParams) => {
48
- const { graphModel, lf } = this.props
49
- const { SCALE_X, SCALE_Y } = lf.getTransform()
50
- const selectElements = graphModel.getSelectElements(true)
51
- graphModel.moveNodes(
52
- selectElements.nodes.map((node) => node.id),
53
- deltaX / SCALE_X,
54
- deltaY / SCALE_Y,
55
- )
56
- }
57
- handleContextMenu = (ev: MouseEvent) => {
58
- ev.preventDefault()
59
- const {
60
- graphModel,
61
- graphModel: { eventCenter, selectElements },
62
- } = this.props
63
- const position = graphModel.getPointByClient({
64
- x: ev.clientX,
65
- y: ev.clientY,
66
- })
67
- const selectGraphData: GraphData = {
68
- nodes: [],
69
- edges: [],
70
- }
71
- const models = [...selectElements.values()]
72
- models.forEach((model) => {
73
- if (model.BaseType === ElementType.NODE) {
74
- selectGraphData.nodes.push(model.getData())
75
- }
76
- if (model.BaseType === ElementType.EDGE) {
77
- selectGraphData.edges.push(model.getData())
78
- }
79
- })
80
- eventCenter.emit(EventType.SELECTION_CONTEXTMENU, {
81
- data: selectGraphData,
82
- e: ev,
83
- position,
84
- })
85
- }
86
-
87
- render() {
88
- const {
89
- graphModel: { selectElements, transformModel },
90
- } = this.props
91
- const { SCALE_X, SCALE_Y } = this.props.lf.getTransform()
92
- if (selectElements.size <= 1) return
93
- let x = Number.MAX_SAFE_INTEGER
94
- let y = Number.MAX_SAFE_INTEGER
95
- let x1 = Number.MIN_SAFE_INTEGER
96
- let y1 = Number.MIN_SAFE_INTEGER
97
- selectElements.forEach((element) => {
98
- let outline: Model.OutlineInfo | undefined
99
- if (element.BaseType === ElementType.NODE) {
100
- outline = getNodeOutline(element)
101
- }
102
- if (element.BaseType === ElementType.EDGE) {
103
- outline = getEdgeOutline(element)
104
- }
105
-
106
- if (outline !== undefined) {
107
- x = Math.min(x, outline.x)
108
- y = Math.min(y, outline.y)
109
- x1 = Math.max(x1, outline.x1)
110
- y1 = Math.max(y1, outline.y1)
111
- }
112
- })
113
- ;[x, y] = transformModel.CanvasPointToHtmlPoint([x, y])
114
- ;[x1, y1] = transformModel.CanvasPointToHtmlPoint([x1, y1])
115
- const style = {
116
- left: `${x - (20 * SCALE_X) / 2}px`,
117
- top: `${y - (20 * SCALE_Y) / 2}px`,
118
- width: `${x1 - x + 20 * SCALE_X}px`,
119
- height: `${y1 - y + 20 * SCALE_Y}px`,
120
- 'border-width': `${2 * SCALE_X}px`,
121
- }
122
- return (
123
- <div
124
- className="lf-multiple-select"
125
- style={style}
126
- onPointerDown={this.handleMouseDown}
127
- onContextMenu={this.handleContextMenu}
128
- onWheel={this.handleWheelEvent}
129
- />
130
- )
131
- }
132
- }
@@ -1,193 +0,0 @@
1
- import { createRef, Component } from 'preact/compat'
2
- import { IToolProps } from '.'
3
- import { ElementState, observer } from '..'
4
- import { ElementType, EventType, ModelType } from '../constant'
5
-
6
- type IState = {
7
- style: {
8
- left: number
9
- top: number
10
- }
11
- }
12
-
13
- @observer
14
- export class TextEditTool extends Component<IToolProps, IState> {
15
- static toolName = 'text-edit-tool'
16
- ref = createRef()
17
- __prevText = {
18
- type: '',
19
- text: '',
20
- id: '',
21
- }
22
-
23
- constructor(props: IToolProps) {
24
- super(props)
25
- this.state = {
26
- style: {
27
- left: 0,
28
- top: 0,
29
- },
30
- }
31
- }
32
-
33
- static getDerivedStateFromProps(props: IToolProps): IState | null {
34
- const { textEditElement, graphModel } = props
35
- const { transformModel, theme } = graphModel
36
- const { inputText } = theme
37
-
38
- let autoStyle
39
- if (textEditElement) {
40
- // 由于边上的文本是依据显示的时候动态计算出来的
41
- // 所以不能在边创建的时候就初始化文本位置。
42
- // 而是在边上新建文本的时候创建。
43
- if (!textEditElement.text?.value) {
44
- if (textEditElement.BaseType === ElementType.EDGE) {
45
- // textEditElement = textEditElement as BaseEdgeModel
46
- const textConfig = textEditElement.text
47
- const { x, y } = textEditElement.textPosition
48
- textConfig.x = x
49
- textConfig.y = y
50
- textEditElement.setText(textConfig)
51
- }
52
- }
53
- // 自动换行节点边通用样式
54
- const commonAutoStyle = {
55
- resize: 'auto',
56
- whiteSpace: 'normal',
57
- wordBreak: 'break-all',
58
- }
59
- if (textEditElement.BaseType === ElementType.EDGE) {
60
- // 如果边文案自动换行, 设置编辑框宽度
61
- const {
62
- edgeText: { overflowMode, lineHeight, wrapPadding, textWidth },
63
- } = theme
64
- if (textWidth && overflowMode === 'autoWrap') {
65
- autoStyle = {
66
- ...commonAutoStyle,
67
- width: textWidth,
68
- minWidth: textWidth,
69
- lineHeight,
70
- padding: wrapPadding,
71
- }
72
- }
73
- } else if (textEditElement.BaseType === ElementType.NODE) {
74
- // 如果节点文案自动换行, 设置编辑框宽度
75
- const {
76
- nodeText: { overflowMode, lineHeight, wrapPadding, textWidth },
77
- } = theme
78
- const { width, modelType, textWidth: nodeTextWidth } = textEditElement
79
-
80
- const finalTextWidth = nodeTextWidth || textWidth || width
81
- // 文本节点没有默认宽高,只有在设置了textWidth之后才能进行自动换行
82
- if (
83
- (modelType !== ModelType.TEXT_NODE && overflowMode === 'autoWrap') ||
84
- (modelType === ModelType.TEXT_NODE && textWidth)
85
- ) {
86
- autoStyle = {
87
- ...commonAutoStyle,
88
- width: finalTextWidth,
89
- minWidth: finalTextWidth,
90
- lineHeight,
91
- padding: wrapPadding,
92
- }
93
- }
94
- }
95
-
96
- const { x, y } = textEditElement.text
97
- const [left, top] = transformModel.CanvasPointToHtmlPoint([x, y])
98
- return {
99
- style: {
100
- left,
101
- top,
102
- ...autoStyle,
103
- ...inputText,
104
- },
105
- }
106
- }
107
-
108
- return null
109
- }
110
-
111
- componentDidUpdate() {
112
- const { graphModel } = this.props
113
- if (this.ref.current) {
114
- this.ref.current.focus()
115
- this.placeCaretAtEnd(this.ref.current)
116
- }
117
- if (this.__prevText.id !== '') {
118
- const { text, id } = this.__prevText
119
- graphModel.updateText(id, text)
120
- graphModel.eventCenter.emit(EventType.TEXT_UPDATE, {
121
- data: { ...this.__prevText },
122
- })
123
- this.__prevText.id = ''
124
- this.__prevText.text = ''
125
- this.__prevText.type = ''
126
- }
127
- }
128
-
129
- keyupHandler = (ev: KeyboardEvent) => {
130
- const {
131
- graphModel: { textEditElement },
132
- } = this.props
133
- // 按下alt+enter表示输入完成
134
- if (ev.key === 'Enter' && ev.altKey) {
135
- textEditElement?.setElementState(ElementState.DEFAULT)
136
- }
137
- }
138
- inputHandler = (ev: any) => {
139
- const { innerText: value } = ev.target as HTMLElement
140
- const {
141
- graphModel: { textEditElement },
142
- } = this.props
143
- if (textEditElement) {
144
- this.__prevText = {
145
- type: textEditElement.type,
146
- text: value.replace(/(\r\n)+$|(\n)+$/, ''), // fix #488: 文本后面的换行符不保留
147
- id: textEditElement.id,
148
- }
149
- }
150
- }
151
- // fix: #587 #760
152
- keydownHandler = (ev: any) => {
153
- ev.stopPropagation()
154
- }
155
-
156
- placeCaretAtEnd(el: any) {
157
- if (
158
- window.getSelection !== undefined &&
159
- document.createRange !== undefined
160
- ) {
161
- const range = document.createRange()
162
- range.selectNodeContents(el)
163
- range.collapse(false)
164
- const sel = window.getSelection()
165
- sel?.removeAllRanges()
166
- sel?.addRange(range)
167
- }
168
- }
169
-
170
- render() {
171
- const {
172
- graphModel: { textEditElement },
173
- } = this.props
174
- const { style } = this.state
175
- return textEditElement ? (
176
- <div
177
- contentEditable
178
- className="lf-text-input"
179
- style={style}
180
- ref={this.ref}
181
- key={textEditElement.id}
182
- onKeyUp={this.keyupHandler}
183
- onKeyDown={this.keydownHandler}
184
- onKeyPress={this.keydownHandler}
185
- onInput={this.inputHandler}
186
- >
187
- {textEditElement.text?.value}
188
- </div>
189
- ) : null
190
- }
191
- }
192
-
193
- export default TextEditTool
package/src/tool/index.ts DELETED
@@ -1,101 +0,0 @@
1
- import { Component, ReactElement } from 'preact/compat'
2
- import { action, observable } from 'mobx'
3
- import { forEach } from 'lodash-es'
4
- import TextEdit from './TextEditTool'
5
- import MultipleSelect from './MultipleSelectTool'
6
- import LogicFlow from '../LogicFlow'
7
- import { ElementState, EventType } from '../constant'
8
- import { GraphModel, BaseEdgeModel, BaseNodeModel } from '../model'
9
-
10
- export type IToolProps = {
11
- lf: LogicFlow
12
- graphModel: GraphModel
13
- textEditElement?: BaseNodeModel | BaseEdgeModel
14
- }
15
-
16
- type ToolConstructor = new (props: IToolProps) => Component<IToolProps>
17
-
18
- // 默认内置的工具
19
- const defaultTools = [TextEdit, MultipleSelect]
20
-
21
- export class Tool {
22
- tools?: Component[]
23
- components?: ReactElement<IToolProps>[]
24
- @observable toolMap = new Map<string, ToolConstructor>()
25
-
26
- disabledToolMap = new Map<string, ToolConstructor>()
27
- instance: LogicFlow
28
-
29
- constructor(instance: LogicFlow) {
30
- this.instance = instance
31
- forEach(defaultTools, (tool) => {
32
- if (!this.isDisabled(tool.toolName)) {
33
- this.registerTool(tool.toolName, tool)
34
- }
35
- })
36
-
37
- // @see https://github.com/didi/LogicFlow/issues/152
38
- const { graphModel } = instance
39
- const { eventCenter } = graphModel
40
- eventCenter.on(
41
- `${EventType.GRAPH_TRANSFORM},${EventType.NODE_CLICK},${EventType.BLANK_CLICK} `,
42
- () => {
43
- const {
44
- textEditElement,
45
- editConfigModel: { edgeTextEdit, nodeTextEdit },
46
- } = graphModel
47
- // fix #826, 保留之前的文本可以编辑点击空白才设置为不可编辑。如果以后有其他需求再改。
48
- if ((edgeTextEdit || nodeTextEdit) && textEditElement) {
49
- graphModel.textEditElement?.setElementState(ElementState.DEFAULT)
50
- }
51
- },
52
- )
53
- }
54
-
55
- private isDisabled(toolName) {
56
- return this.instance.options.disabledTools?.indexOf(toolName) !== -1
57
- }
58
-
59
- // 注册工具
60
- registerTool(name: string, component: ToolConstructor) {
61
- this.toolMap.set(name, component)
62
- }
63
-
64
- // 禁用工具
65
- @action
66
- disableTool(name: string): boolean | Error {
67
- const tool = this.toolMap.get(name)
68
- if (tool) {
69
- this.disabledToolMap.set(name, tool)
70
- this.toolMap.delete(name)
71
- return true
72
- }
73
- throw new Error(`禁用失败,不存在名为 ${tool} 的工具`)
74
- }
75
-
76
- @action
77
- enableTool(name: string): boolean | Error {
78
- const tool = this.disabledToolMap.get(name)
79
- if (tool) {
80
- this.toolMap.set(name, tool)
81
- this.disabledToolMap.delete(name)
82
- return true
83
- }
84
- throw new Error(`不存在名为 ${tool} 的工具`)
85
- }
86
-
87
- getTools() {
88
- return Array.from(this.toolMap.values())
89
- }
90
-
91
- getInstance() {
92
- return this.instance
93
- }
94
-
95
- destroy() {
96
- this.toolMap.clear()
97
- this.disabledToolMap.clear()
98
- }
99
- }
100
-
101
- export default Tool
package/src/typings.d.ts DELETED
@@ -1,5 +0,0 @@
1
- declare module 'mobx-preact' {
2
- import { ComponentConstructor } from 'preact/compat'
3
- type Component<P = any> = ComponentConstructor<P>
4
- export function observer<T extends Component>(target: T): T
5
- }
@@ -1,29 +0,0 @@
1
- import { cloneDeep, merge } from 'lodash-es'
2
- import { Options } from '../options'
3
-
4
- import AnimationConfig = Options.AnimationConfig
5
-
6
- export const defaultAnimationOffConfig = {
7
- node: false,
8
- edge: false,
9
- }
10
-
11
- export const defaultAnimationOnConfig = {
12
- node: true,
13
- edge: true,
14
- }
15
-
16
- export const setupAnimation = (
17
- config?: boolean | Partial<AnimationConfig>,
18
- ): AnimationConfig => {
19
- if (!config || typeof config === 'boolean') {
20
- return config === true
21
- ? cloneDeep(defaultAnimationOnConfig)
22
- : cloneDeep(defaultAnimationOffConfig)
23
- }
24
-
25
- // 当传入的是对象时,将其与默认关合并
26
- return merge(cloneDeep(defaultAnimationOffConfig), config)
27
- }
28
-
29
- export const updateAnimation = setupAnimation
@@ -1,4 +0,0 @@
1
- import { get } from 'lodash-es'
2
-
3
- export const isIe = () =>
4
- get(window, 'navigator.userAgent', '').match(/MSIE|Trident/) !== null
@@ -1,15 +0,0 @@
1
- // import { cloneDeep } from 'lodash-es'
2
- /**
3
- * 对数据实现兼容处理。
4
- *
5
- * Vue 中的 data 会进行 Observe,深拷贝的原始数据对象
6
- */
7
- export function formatData<T>(data: T): T {
8
- try {
9
- // WARNING: cloneDeep虽然也会将Observe对象转换为plain对象,但是不会像JSON.parse那样,会将undefined去掉。
10
- // 会导致后面的pick因为存在pick覆盖默认值的情况。
11
- return JSON.parse(JSON.stringify(data))
12
- } catch {
13
- return data
14
- }
15
- }
package/src/util/drag.ts DELETED
@@ -1,220 +0,0 @@
1
- import { noop } from 'lodash-es'
2
- import { Model } from '../model'
3
- import { EventType } from '../constant'
4
- import EventEmitter from '../event/eventEmitter'
5
-
6
- // TODO:这种方式在同构项目中,会报错,该如何解决(是否要求用户控制在浏览器环境时才初始化)
7
- // const DOC: any = window?.document
8
- const LEFT_MOUSE_BUTTON_CODE = 0
9
-
10
- export type IDragParams = {
11
- deltaX: number
12
- deltaY: number
13
- event?: PointerEvent
14
- [key: string]: unknown
15
- }
16
-
17
- export type ICreateDragParams = {
18
- onDragStart?: (params: Partial<IDragParams>) => void
19
- onDragging?: (param: IDragParams) => void
20
- onDragEnd?: (param: Partial<IDragParams>) => void
21
- step?: number
22
- isStopPropagation?: boolean
23
- }
24
-
25
- export type IStepperDragProps = {
26
- eventType?:
27
- | 'NODE'
28
- | 'BLANK'
29
- | 'SELECTION'
30
- | 'ADJUST_POINT'
31
- | 'TEXT'
32
- | 'LABEL'
33
- | ''
34
- eventCenter?: EventEmitter
35
- model?: Model.BaseModel | unknown
36
- data?: Record<string, unknown>
37
- [key: string]: unknown
38
- } & Partial<ICreateDragParams>
39
-
40
- // 支持拖拽的时候,按照指定step进行。
41
- // 因为在绘制的过程中因为放大缩小,移动的真实的step则是变化的。
42
- export class StepDrag {
43
- onDragStart: (params: Partial<IDragParams>) => void
44
- onDragging: (params: IDragParams) => void
45
- onDragEnd: (params: Partial<IDragParams>) => void
46
-
47
- step: number
48
- isStopPropagation: boolean
49
- eventType:
50
- | 'NODE'
51
- | 'BLANK'
52
- | 'SELECTION'
53
- | 'ADJUST_POINT'
54
- | 'TEXT'
55
- | 'LABEL'
56
- | ''
57
- eventCenter?: EventEmitter
58
- model?: Model.BaseModel | any // TODO: 如何兼容 LabelModel 类型。 LabelModel 能否是 BaseModel 的实现呢?
59
- data?: Record<string, unknown>
60
-
61
- // 运行时
62
- isDragging = false
63
- isStartDragging = false
64
-
65
- startX = 0
66
- startY = 0
67
- sumDeltaX = 0
68
- sumDeltaY = 0
69
-
70
- startTime?: number
71
-
72
- constructor({
73
- onDragStart = noop,
74
- onDragging = noop,
75
- onDragEnd = noop,
76
- eventType = '',
77
- eventCenter,
78
- step = 1,
79
- isStopPropagation = true,
80
- model,
81
- data,
82
- }: IStepperDragProps) {
83
- this.onDragStart = onDragStart
84
- this.onDragging = onDragging
85
- this.onDragEnd = onDragEnd
86
- this.step = step
87
- this.isStopPropagation = isStopPropagation
88
- this.eventType = eventType
89
- this.eventCenter = eventCenter
90
- this.model = model
91
- this.data = data
92
- }
93
-
94
- setStep(step: number) {
95
- this.step = step
96
- }
97
-
98
- setModel(model: Model.BaseModel) {
99
- this.model = model
100
- }
101
-
102
- handleMouseDown = (e: PointerEvent) => {
103
- const DOC: any = window?.document
104
- if (e.button !== LEFT_MOUSE_BUTTON_CODE) return
105
- if (this.isStopPropagation) e.stopPropagation()
106
- e.preventDefault()
107
- this.isStartDragging = true
108
- this.startX = e.clientX
109
- this.startY = e.clientY
110
- DOC.addEventListener('pointermove', this.handleMouseMove, false)
111
- DOC.addEventListener('pointerup', this.handleMouseUp, false)
112
- const elementData = this.model?.getData()
113
- this.eventCenter?.emit(EventType[`${this.eventType}_MOUSEDOWN`], {
114
- e,
115
- data: this.data || elementData,
116
- })
117
- this.startTime = new Date().getTime()
118
- }
119
-
120
- handleMouseMove = (e: PointerEvent) => {
121
- if (this.isStopPropagation) e.stopPropagation()
122
- e.preventDefault()
123
- if (!this.isStartDragging) return
124
- this.sumDeltaX += e.clientX - this.startX
125
- this.sumDeltaY += e.clientY - this.startY
126
- this.startX = e.clientX
127
- this.startY = e.clientY
128
- if (
129
- this.step <= 1 ||
130
- Math.abs(this.sumDeltaX) > this.step ||
131
- Math.abs(this.sumDeltaY) > this.step
132
- ) {
133
- const remainderX = this.sumDeltaX % this.step
134
- const remainderY = this.sumDeltaY % this.step
135
- const deltaX = this.sumDeltaX - remainderX
136
- const deltaY = this.sumDeltaY - remainderY
137
- this.sumDeltaX = remainderX
138
- this.sumDeltaY = remainderY
139
- const elementData = this.model?.getData()
140
- /**
141
- * 为了区分点击和拖动,在鼠标没有拖动时,不触发dragstart。
142
- */
143
- if (!this.isDragging) {
144
- this.eventCenter?.emit(EventType[`${this.eventType}_DRAGSTART`], {
145
- e,
146
- data: this.data || elementData,
147
- })
148
- this.onDragStart({ event: e })
149
- }
150
- this.isDragging = true
151
- // 为了让dragstart和drag不在同一个事件循环中,使drag事件放到下一个消息队列中。
152
- // TODO: 放到下一个消息队列中是否会有延迟,比如
153
- // 限制某个元素的拖拽范围,如果在dragstart中设置了拖拽范围,那么在drag中就会有延迟。
154
- Promise.resolve().then(() => {
155
- this.onDragging({
156
- deltaX,
157
- deltaY,
158
- event: e,
159
- })
160
- this.eventCenter?.emit(EventType[`${this.eventType}_MOUSEMOVE`], {
161
- deltaX,
162
- deltaY,
163
- e,
164
- data: this.data || elementData,
165
- })
166
- this.eventCenter?.emit(EventType[`${this.eventType}_DRAG`], {
167
- e,
168
- data: this.data || elementData,
169
- })
170
- })
171
- }
172
- }
173
-
174
- handleMouseUp = (e: PointerEvent) => {
175
- const DOC = window.document
176
-
177
- this.isStartDragging = false
178
- if (this.isStopPropagation) e.stopPropagation()
179
- const target = e.target as any
180
- if (target && typeof target.releasePointerCapture === 'function') {
181
- target.releasePointerCapture(e.pointerId)
182
- }
183
- // fix #568: 如果onDragging在下一个事件循环中触发,而drop在当前事件循环,会出现问题。
184
- Promise.resolve().then(() => {
185
- DOC.removeEventListener('pointermove', this.handleMouseMove, false)
186
- DOC.removeEventListener('pointerup', this.handleMouseUp, false)
187
- const elementData = this.model?.getData()
188
- this.eventCenter?.emit(EventType[`${this.eventType}_MOUSEUP`], {
189
- e,
190
- data: this.data || elementData,
191
- })
192
- if (!this.isDragging) return
193
- this.isDragging = false
194
- this.onDragEnd({ event: e })
195
- this.eventCenter?.emit(EventType[`${this.eventType}_DROP`], {
196
- e,
197
- data: this.data || elementData,
198
- })
199
- })
200
- }
201
- cancelDrag = () => {
202
- const DOC: any = window?.document
203
- DOC.removeEventListener('pointermove', this.handleMouseMove, false)
204
- DOC.removeEventListener('pointerup', this.handleMouseUp, false)
205
- this.onDragEnd({ event: undefined })
206
- this.isDragging = false
207
- }
208
-
209
- destroy = () => {
210
- if (this.isStartDragging) {
211
- // https://github.com/didi/LogicFlow/issues/1934
212
- // https://github.com/didi/LogicFlow/issues/1926
213
- // cancelDrag()->onDragEnd()->updateEdgePointByAnchors()触发线的重新计算
214
- // 我们的本意是为了防止mousemove和mouseup没有及时被移除
215
- // 因此这里增加if(this.isStartDragging)的判断,isStartDragging=true代表没有触发handleMouseUp(),此时监听还没被移除
216
- // 在拖拽情况下(isStartDragging=true),此时注册了监听,在组件突然销毁时,强制触发cancelDrag进行监听事件的移除
217
- this.cancelDrag()
218
- }
219
- }
220
- }