@tmagic/stage 1.2.6 → 1.2.8

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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.6",
2
+ "version": "1.2.8",
3
3
  "name": "@tmagic/stage",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -29,14 +29,14 @@
29
29
  "url": "https://github.com/Tencent/tmagic-editor.git"
30
30
  },
31
31
  "dependencies": {
32
- "@scena/guides": "^0.17.0",
33
- "@tmagic/core": "1.2.6",
34
- "@tmagic/schema": "1.2.6",
35
- "@tmagic/utils": "1.2.6",
32
+ "@scena/guides": "^0.23.3",
33
+ "@tmagic/core": "1.2.8",
34
+ "@tmagic/schema": "1.2.8",
35
+ "@tmagic/utils": "1.2.8",
36
36
  "events": "^3.3.0",
37
37
  "keycon": "^1.1.2",
38
38
  "lodash-es": "^4.17.21",
39
- "moveable": "^0.30.0",
39
+ "moveable": "^0.43.1",
40
40
  "moveable-helper": "^0.4.0"
41
41
  },
42
42
  "devDependencies": {
@@ -25,6 +25,7 @@ import { Id } from '@tmagic/schema';
25
25
  import { addClassName, getDocument, removeClassNameByClassName } from '@tmagic/utils';
26
26
 
27
27
  import { CONTAINER_HIGHLIGHT_CLASS_NAME, GHOST_EL_ID_PREFIX, GuidesType, MouseButton, PAGE_CLASS } from './const';
28
+ import DragResizeHelper from './DragResizeHelper';
28
29
  import StageDragResize from './StageDragResize';
29
30
  import StageHighlight from './StageHighlight';
30
31
  import StageMultiDragResize from './StageMultiDragResize';
@@ -39,6 +40,7 @@ import {
39
40
  GetTargetElement,
40
41
  IsContainer,
41
42
  Point,
43
+ RemoveEventData,
42
44
  SelectStatus,
43
45
  StageDragStatus,
44
46
  UpdateEventData,
@@ -100,27 +102,30 @@ export default class ActionManager extends EventEmitter {
100
102
  this.getRenderDocument = config.getRenderDocument;
101
103
  this.isContainer = config.isContainer;
102
104
 
105
+ const createDrHelper = () =>
106
+ new DragResizeHelper({
107
+ container: config.container,
108
+ updateDragEl: config.updateDragEl,
109
+ });
110
+
103
111
  this.dr = new StageDragResize({
104
112
  container: config.container,
105
113
  disabledDragStart: config.disabledDragStart,
114
+ moveableOptions: this.changeCallback(config.moveableOptions),
115
+ dragResizeHelper: createDrHelper(),
106
116
  getRootContainer: config.getRootContainer,
107
117
  getRenderDocument: config.getRenderDocument,
108
- updateDragEl: config.updateDragEl,
109
- markContainerEnd: () => this.markContainerEnd(),
110
- delayedMarkContainer: (event: MouseEvent, exclude: Element[]) => {
111
- if (this.canAddToContainer()) {
112
- return this.delayedMarkContainer(event, exclude);
113
- }
114
- return undefined;
115
- },
116
- moveableOptions: this.changeCallback(config.moveableOptions),
118
+ markContainerEnd: this.markContainerEnd.bind(this),
119
+ delayedMarkContainer: this.delayedMarkContainer.bind(this),
117
120
  });
118
121
  this.multiDr = new StageMultiDragResize({
119
122
  container: config.container,
120
123
  multiMoveableOptions: config.multiMoveableOptions,
124
+ dragResizeHelper: createDrHelper(),
121
125
  getRootContainer: config.getRootContainer,
122
126
  getRenderDocument: config.getRenderDocument,
123
- updateDragEl: config.updateDragEl,
127
+ markContainerEnd: this.markContainerEnd.bind(this),
128
+ delayedMarkContainer: this.delayedMarkContainer.bind(this),
124
129
  });
125
130
  this.highlightLayer = new StageHighlight({
126
131
  container: config.container,
@@ -319,10 +324,13 @@ export default class ActionManager extends EventEmitter {
319
324
  * @param excludeElList 计算鼠标所在容器时要排除的元素列表
320
325
  * @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
321
326
  */
322
- public delayedMarkContainer(event: MouseEvent, excludeElList: Element[] = []): NodeJS.Timeout {
323
- return globalThis.setTimeout(() => {
324
- this.addContainerHighlightClassName(event, excludeElList);
325
- }, this.containerHighlightDuration);
327
+ public delayedMarkContainer(event: MouseEvent, excludeElList: Element[] = []): NodeJS.Timeout | undefined {
328
+ if (this.canAddToContainer()) {
329
+ return globalThis.setTimeout(() => {
330
+ this.addContainerHighlightClassName(event, excludeElList);
331
+ }, this.containerHighlightDuration);
332
+ }
333
+ return undefined;
326
334
  }
327
335
 
328
336
  public destroy(): void {
@@ -454,11 +462,19 @@ export default class ActionManager extends EventEmitter {
454
462
  })
455
463
  .on('select-parent', () => {
456
464
  this.emit('select-parent');
465
+ })
466
+ .on('remove', () => {
467
+ const drTarget = this.dr.getTarget();
468
+ if (!drTarget) return;
469
+ const data: RemoveEventData = {
470
+ data: [{ el: drTarget }],
471
+ };
472
+ this.emit('remove', data);
457
473
  });
458
474
 
459
475
  this.multiDr
460
- .on('update', (data: UpdateEventData, parentEl: HTMLElement | null) => {
461
- this.emit('multi-update', data, parentEl);
476
+ .on('update', (data: UpdateEventData) => {
477
+ this.emit('multi-update', data);
462
478
  })
463
479
  .on('change-to-select', async (id: Id) => {
464
480
  // 如果还在多选状态,不触发切换到单选
@@ -34,8 +34,8 @@ import MoveableHelper from 'moveable-helper';
34
34
 
35
35
  import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, Mode, ZIndex } from './const';
36
36
  import TargetShadow from './TargetShadow';
37
- import { DragResizeHelperConfig, TargetElement } from './types';
38
- import { getAbsolutePosition, getOffset } from './util';
37
+ import { DragResizeHelperConfig, Rect, TargetElement } from './types';
38
+ import { calcValueByFontsize, getAbsolutePosition, getOffset } from './util';
39
39
 
40
40
  /**
41
41
  * 拖拽/改变大小等操作发生时,moveable会抛出各种状态事件,DragResizeHelper负责响应这些事件,对目标节点target和拖拽节点targetShadow进行修改;
@@ -282,6 +282,44 @@ export default class DragResizeHelper {
282
282
  this.moveableHelper.onDragGroup(e);
283
283
  }
284
284
 
285
+ public getUpdatedElRect(el: HTMLElement, parentEl: HTMLElement | null, doc: Document): Rect {
286
+ const offset = this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: el.offsetLeft, top: el.offsetTop };
287
+
288
+ let left = calcValueByFontsize(doc, offset.left);
289
+ let top = calcValueByFontsize(doc, offset.top);
290
+ const width = calcValueByFontsize(doc, el.clientWidth);
291
+ const height = calcValueByFontsize(doc, el.clientHeight);
292
+
293
+ let shadowEl = this.getShadowEl();
294
+ const shadowEls = this.getShadowEls();
295
+
296
+ if (shadowEls.length) {
297
+ shadowEl = shadowEls.find((item) => item.id.endsWith(el.id));
298
+ }
299
+
300
+ if (parentEl && this.mode === Mode.ABSOLUTE && shadowEl) {
301
+ const targetShadowHtmlEl = shadowEl as HTMLElement;
302
+ const targetShadowElOffsetLeft = targetShadowHtmlEl.offsetLeft || 0;
303
+ const targetShadowElOffsetTop = targetShadowHtmlEl.offsetTop || 0;
304
+
305
+ const frame = this.getFrame(shadowEl);
306
+
307
+ const [translateX, translateY] = frame?.properties.transform.translate.value;
308
+ const { left: parentLeft, top: parentTop } = getOffset(parentEl);
309
+
310
+ left =
311
+ calcValueByFontsize(doc, targetShadowElOffsetLeft) +
312
+ parseFloat(translateX) -
313
+ calcValueByFontsize(doc, parentLeft);
314
+ top =
315
+ calcValueByFontsize(doc, targetShadowElOffsetTop) +
316
+ parseFloat(translateY) -
317
+ calcValueByFontsize(doc, parentTop);
318
+ }
319
+
320
+ return { width, height, left, top };
321
+ }
322
+
285
323
  /**
286
324
  * 多选状态设置多个节点的快照
287
325
  */
@@ -0,0 +1,109 @@
1
+ import { MoveableManagerInterface, Renderer } from 'moveable';
2
+
3
+ import { AbleActionEventType } from './types';
4
+
5
+ export default (handler: (type: AbleActionEventType) => void) => ({
6
+ name: 'actions',
7
+ props: {
8
+ selectParent: Boolean,
9
+ },
10
+ events: {},
11
+ render(moveable: MoveableManagerInterface<any, any>, React: Renderer) {
12
+ const rect = moveable.getRect();
13
+ const { pos2 } = moveable.state;
14
+
15
+ // use css for able
16
+ const editableViewer = moveable.useCSS(
17
+ 'div',
18
+ `
19
+ {
20
+ position: absolute;
21
+ left: 0px;
22
+ top: 0px;
23
+ will-change: transform;
24
+ transform-origin: 0px 0px;
25
+ display: flex;
26
+ }
27
+ .moveable-button {
28
+ width: 20px;
29
+ height: 20px;
30
+ background: #4af;
31
+ border-radius: 4px;
32
+ appearance: none;
33
+ border: 0;
34
+ color: white;
35
+ font-size: 12px;
36
+ font-weight: bold;
37
+ margin-left: 2px;
38
+ position: relative;
39
+ }
40
+ .moveable-remove-button:before, .moveable-remove-button:after {
41
+ content: "";
42
+ position: absolute;
43
+ left: 50%;
44
+ top: 50%;
45
+ transform: translate(-50%, -50%) rotate(45deg);
46
+ width: 14px;
47
+ height: 2px;
48
+ background: #fff;
49
+ border-radius: 1px;
50
+ cursor: pointer;
51
+ }
52
+ .moveable-remove-button:after {
53
+ transform: translate(-50%, -50%) rotate(-45deg);
54
+ }
55
+ `,
56
+ );
57
+ // Add key (required)
58
+ // Add class prefix moveable-(required)
59
+ return React.createElement(
60
+ editableViewer,
61
+ {
62
+ className: 'moveable-editable',
63
+ style: {
64
+ transform: `translate(${pos2[0] - 48}px, ${pos2[1] - 28}px) rotate(${rect.rotation}deg) translate(10px)`,
65
+ },
66
+ },
67
+ [
68
+ React.createElement(
69
+ 'button',
70
+ {
71
+ className: 'moveable-button',
72
+ title: '选中父组件',
73
+ onClick: () => {
74
+ handler(AbleActionEventType.SELECT_PARENT);
75
+ },
76
+ },
77
+ React.createElement(
78
+ 'svg',
79
+ {
80
+ width: '20px',
81
+ height: '20px',
82
+ viewBox: '0 0 16 16',
83
+ fill: 'none',
84
+ xmlns: 'http://www.w3.org/2000/svg',
85
+ style: {
86
+ transform: 'rotate(90deg)',
87
+ position: 'absolute',
88
+ left: 0,
89
+ top: 0,
90
+ },
91
+ },
92
+ React.createElement('path', {
93
+ d: 'M13.0001 4V10H4.20718L5.85363 8.35355L5.14652 7.64645L2.64652 10.1464C2.45126 10.3417 2.45126 10.6583 2.64652 10.8536L5.14652 13.3536L5.85363 12.6464L4.20718 11H13.0001C13.5524 11 14.0001 10.5523 14.0001 10V4H13.0001Z',
94
+ fill: 'currentColor',
95
+ fillOpacity: '0.9',
96
+ }),
97
+ ),
98
+ ),
99
+ React.createElement('button', {
100
+ className: 'moveable-button moveable-remove-button',
101
+ title: '删除',
102
+ onClick: () => {
103
+ handler(AbleActionEventType.REMOVE);
104
+ },
105
+ }),
106
+ ],
107
+ );
108
+ },
109
+ });
@@ -22,8 +22,8 @@ import { merge } from 'lodash-es';
22
22
  import { MoveableOptions } from 'moveable';
23
23
 
24
24
  import { GuidesType, Mode } from './const';
25
- import selectParentAbles from './MoveableSelectParentAble';
26
- import { GetRootContainer, MoveableOptionsManagerConfig } from './types';
25
+ import MoveableActionsAble from './MoveableActionsAble';
26
+ import { AbleActionEventType, GetRootContainer, MoveableOptionsManagerConfig } from './types';
27
27
  import { getOffset } from './util';
28
28
 
29
29
  /**
@@ -173,10 +173,10 @@ export default class MoveableOptionsManager extends EventEmitter {
173
173
  isDisplayInnerSnapDigit: true,
174
174
 
175
175
  props: {
176
- selectParent: true,
176
+ actions: true,
177
177
  },
178
178
 
179
- ables: [selectParentAbles(this.selectParentHandler.bind(this))],
179
+ ables: [MoveableActionsAble(this.actionHandler.bind(this))],
180
180
  };
181
181
  }
182
182
 
@@ -208,8 +208,8 @@ export default class MoveableOptionsManager extends EventEmitter {
208
208
  /**
209
209
  * 这是给selectParentAbles的回调函数,用于触发选中父元素事件
210
210
  */
211
- private selectParentHandler(): void {
212
- this.emit('select-parent');
211
+ private actionHandler(type: AbleActionEventType): void {
212
+ this.emit(type);
213
213
  }
214
214
 
215
215
  /**
package/src/StageCore.ts CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  GuidesEventData,
31
31
  Point,
32
32
  RemoveData,
33
+ RemoveEventData,
33
34
  Runtime,
34
35
  StageCoreConfig,
35
36
  UpdateData,
@@ -188,7 +189,10 @@ export default class StageCore extends EventEmitter {
188
189
  /**
189
190
  * @deprecated 废弃接口,建议用delayedMarkContainer代替
190
191
  */
191
- public getAddContainerHighlightClassNameTimeout(event: MouseEvent, excludeElList: Element[] = []): NodeJS.Timeout {
192
+ public getAddContainerHighlightClassNameTimeout(
193
+ event: MouseEvent,
194
+ excludeElList: Element[] = [],
195
+ ): NodeJS.Timeout | undefined {
192
196
  return this.delayedMarkContainer(event, excludeElList);
193
197
  }
194
198
 
@@ -199,7 +203,7 @@ export default class StageCore extends EventEmitter {
199
203
  * @param excludeElList 计算鼠标所在容器时要排除的元素列表
200
204
  * @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
201
205
  */
202
- public delayedMarkContainer(event: MouseEvent, excludeElList: Element[] = []): NodeJS.Timeout {
206
+ public delayedMarkContainer(event: MouseEvent, excludeElList: Element[] = []): NodeJS.Timeout | undefined {
203
207
  return this.actionManager.delayedMarkContainer(event, excludeElList);
204
208
  }
205
209
 
@@ -313,6 +317,9 @@ export default class StageCore extends EventEmitter {
313
317
  })
314
318
  .on('select-parent', () => {
315
319
  this.emit('select-parent');
320
+ })
321
+ .on('remove', (data: RemoveEventData) => {
322
+ this.emit('remove', data);
316
323
  });
317
324
  }
318
325
 
@@ -327,8 +334,8 @@ export default class StageCore extends EventEmitter {
327
334
  // 先保证画布内完成渲染,再通知外部更新
328
335
  setTimeout(() => this.emit('select', el));
329
336
  })
330
- .on('multi-update', (data: UpdateEventData, parentEl: HTMLElement | null) => {
331
- this.emit('update', { data, parentEl });
337
+ .on('multi-update', (data: UpdateEventData) => {
338
+ this.emit('update', data);
332
339
  });
333
340
  }
334
341
 
@@ -24,7 +24,7 @@ import DragResizeHelper from './DragResizeHelper';
24
24
  import MoveableOptionsManager from './MoveableOptionsManager';
25
25
  import type { DelayedMarkContainer, GetRenderDocument, MarkContainerEnd, StageDragResizeConfig } from './types';
26
26
  import { StageDragStatus } from './types';
27
- import { calcValueByFontsize, down, getMode, getOffset, up } from './util';
27
+ import { down, getMode, up } from './util';
28
28
 
29
29
  /**
30
30
  * 管理单选操作,响应选中操作,初始化moveableOption参数并初始化moveable,处理moveable回调事件对组件进行更新
@@ -51,10 +51,7 @@ export default class StageDragResize extends MoveableOptionsManager {
51
51
  this.delayedMarkContainer = config.delayedMarkContainer;
52
52
  this.disabledDragStart = config.disabledDragStart;
53
53
 
54
- this.dragResizeHelper = new DragResizeHelper({
55
- container: config.container,
56
- updateDragEl: config.updateDragEl,
57
- });
54
+ this.dragResizeHelper = config.dragResizeHelper;
58
55
 
59
56
  this.on('update-moveable', () => {
60
57
  if (this.moveable) {
@@ -63,6 +60,10 @@ export default class StageDragResize extends MoveableOptionsManager {
63
60
  });
64
61
  }
65
62
 
63
+ public getTarget() {
64
+ return this.target;
65
+ }
66
+
66
67
  /**
67
68
  * 将选中框渲染并覆盖到选中的组件Dom节点上方
68
69
  * 当选中的节点不是absolute时,会创建一个新的节点出来作为拖拽目标
@@ -311,40 +312,13 @@ export default class StageDragResize extends MoveableOptionsManager {
311
312
 
312
313
  if (!doc) return;
313
314
 
314
- const offset =
315
- this.mode === Mode.SORTABLE ? { left: 0, top: 0 } : { left: this.target.offsetLeft, top: this.target.offsetTop };
316
-
317
- let left = calcValueByFontsize(doc, offset.left);
318
- let top = calcValueByFontsize(doc, offset.top);
319
- const width = calcValueByFontsize(doc, this.target.clientWidth);
320
- const height = calcValueByFontsize(doc, this.target.clientHeight);
321
-
322
- const shadowEl = this.dragResizeHelper.getShadowEl();
323
- if (parentEl && this.mode === Mode.ABSOLUTE && shadowEl) {
324
- const targetShadowHtmlEl = shadowEl as HTMLElement;
325
- const targetShadowElOffsetLeft = targetShadowHtmlEl.offsetLeft || 0;
326
- const targetShadowElOffsetTop = targetShadowHtmlEl.offsetTop || 0;
327
-
328
- const frame = this.dragResizeHelper.getFrame(shadowEl);
329
-
330
- const [translateX, translateY] = frame?.properties.transform.translate.value;
331
- const { left: parentLeft, top: parentTop } = getOffset(parentEl);
332
-
333
- left =
334
- calcValueByFontsize(doc, targetShadowElOffsetLeft) +
335
- parseFloat(translateX) -
336
- calcValueByFontsize(doc, parentLeft);
337
- top =
338
- calcValueByFontsize(doc, targetShadowElOffsetTop) +
339
- parseFloat(translateY) -
340
- calcValueByFontsize(doc, parentTop);
341
- }
315
+ const rect = this.dragResizeHelper.getUpdatedElRect(this.target, parentEl, doc);
342
316
 
343
317
  this.emit('update', {
344
318
  data: [
345
319
  {
346
320
  el: this.target,
347
- style: isResize ? { left, top, width, height } : { left, top },
321
+ style: isResize ? rect : { left: rect.left, top: rect.top },
348
322
  },
349
323
  ],
350
324
  parentEl,
@@ -21,8 +21,15 @@ import Moveable from 'moveable';
21
21
  import { DRAG_EL_ID_PREFIX, Mode } from './const';
22
22
  import DragResizeHelper from './DragResizeHelper';
23
23
  import MoveableOptionsManager from './MoveableOptionsManager';
24
- import { GetRenderDocument, MoveableOptionsManagerConfig, StageDragStatus, StageMultiDragResizeConfig } from './types';
25
- import { calcValueByFontsize, getMode } from './util';
24
+ import {
25
+ DelayedMarkContainer,
26
+ GetRenderDocument,
27
+ MarkContainerEnd,
28
+ MoveableOptionsManagerConfig,
29
+ StageDragStatus,
30
+ StageMultiDragResizeConfig,
31
+ } from './types';
32
+ import { getMode } from './util';
26
33
 
27
34
  export default class StageMultiDragResize extends MoveableOptionsManager {
28
35
  /** 画布容器 */
@@ -34,6 +41,8 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
34
41
  public dragStatus: StageDragStatus = StageDragStatus.END;
35
42
  private dragResizeHelper: DragResizeHelper;
36
43
  private getRenderDocument: GetRenderDocument;
44
+ private delayedMarkContainer: DelayedMarkContainer;
45
+ private markContainerEnd: MarkContainerEnd;
37
46
 
38
47
  constructor(config: StageMultiDragResizeConfig) {
39
48
  const moveableOptionsManagerConfig: MoveableOptionsManagerConfig = {
@@ -43,13 +52,12 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
43
52
  };
44
53
  super(moveableOptionsManagerConfig);
45
54
 
55
+ this.delayedMarkContainer = config.delayedMarkContainer;
56
+ this.markContainerEnd = config.markContainerEnd;
46
57
  this.container = config.container;
47
58
  this.getRenderDocument = config.getRenderDocument;
48
59
 
49
- this.dragResizeHelper = new DragResizeHelper({
50
- container: config.container,
51
- updateDragEl: config.updateDragEl,
52
- });
60
+ this.dragResizeHelper = config.dragResizeHelper;
53
61
 
54
62
  this.on('update-moveable', () => {
55
63
  if (this.moveableForMulti) {
@@ -85,6 +93,8 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
85
93
  }),
86
94
  );
87
95
 
96
+ let timeout: NodeJS.Timeout | undefined;
97
+
88
98
  this.moveableForMulti
89
99
  .on('resizeGroupStart', (e) => {
90
100
  this.dragResizeHelper.onResizeGroupStart(e);
@@ -103,11 +113,18 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
103
113
  this.dragStatus = StageDragStatus.START;
104
114
  })
105
115
  .on('dragGroup', (e) => {
116
+ if (timeout) {
117
+ globalThis.clearTimeout(timeout);
118
+ timeout = undefined;
119
+ }
120
+ timeout = this.delayedMarkContainer(e.inputEvent, this.targetList);
121
+
106
122
  this.dragResizeHelper.onDragGroup(e);
107
123
  this.dragStatus = StageDragStatus.ING;
108
124
  })
109
125
  .on('dragGroupEnd', () => {
110
- this.update();
126
+ const parentEl = this.markContainerEnd();
127
+ this.update(false, parentEl);
111
128
  this.dragStatus = StageDragStatus.END;
112
129
  })
113
130
  .on('clickGroup', (e) => {
@@ -182,22 +199,19 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
182
199
  * 拖拽完成后将更新的位置信息暴露给上层业务方,业务方可以接收事件进行保存
183
200
  * @param isResize 是否进行大小缩放
184
201
  */
185
- private update(isResize = false): void {
202
+ private update(isResize = false, parentEl: HTMLElement | null = null): void {
186
203
  if (this.targetList.length === 0) return;
187
204
 
188
205
  const doc = this.getRenderDocument();
189
206
  if (!doc) return;
190
207
 
191
208
  const data = this.targetList.map((targetItem) => {
192
- const left = calcValueByFontsize(doc, targetItem.offsetLeft);
193
- const top = calcValueByFontsize(doc, targetItem.offsetTop);
194
- const width = calcValueByFontsize(doc, targetItem.clientWidth);
195
- const height = calcValueByFontsize(doc, targetItem.clientHeight);
209
+ const rect = this.dragResizeHelper.getUpdatedElRect(targetItem, parentEl, doc);
196
210
  return {
197
211
  el: targetItem,
198
- style: isResize ? { left, top, width, height } : { left, top },
212
+ style: isResize ? rect : { left: rect.left, top: rect.top },
199
213
  };
200
214
  });
201
- this.emit('update', data, null);
215
+ this.emit('update', { data, parentEl });
202
216
  }
203
217
  }
package/src/types.ts CHANGED
@@ -22,6 +22,7 @@ import Core from '@tmagic/core';
22
22
  import type { Id, MApp, MContainer, MNode } from '@tmagic/schema';
23
23
 
24
24
  import { GuidesType, ZIndex } from './const';
25
+ import DragResizeHelper from './DragResizeHelper';
25
26
  import StageCore from './StageCore';
26
27
 
27
28
  export type TargetElement = HTMLElement | SVGElement;
@@ -112,21 +113,23 @@ export interface StageMaskConfig {
112
113
 
113
114
  export interface StageDragResizeConfig {
114
115
  container: HTMLElement;
116
+ dragResizeHelper: DragResizeHelper;
115
117
  moveableOptions?: CustomizeMoveableOptions;
116
118
  disabledDragStart?: boolean;
117
119
  getRootContainer: GetRootContainer;
118
120
  getRenderDocument: GetRenderDocument;
119
121
  markContainerEnd: MarkContainerEnd;
120
122
  delayedMarkContainer: DelayedMarkContainer;
121
- updateDragEl?: UpdateDragEl;
122
123
  }
123
124
 
124
125
  export interface StageMultiDragResizeConfig {
125
126
  container: HTMLElement;
127
+ dragResizeHelper: DragResizeHelper;
126
128
  multiMoveableOptions?: CustomizeMoveableOptions;
127
129
  getRootContainer: GetRootContainer;
128
130
  getRenderDocument: GetRenderDocument;
129
- updateDragEl?: UpdateDragEl;
131
+ markContainerEnd: MarkContainerEnd;
132
+ delayedMarkContainer: DelayedMarkContainer;
130
133
  }
131
134
 
132
135
  export interface DragResizeHelperConfig {
@@ -190,6 +193,12 @@ export interface UpdateEventData {
190
193
  parentEl: HTMLElement | null;
191
194
  }
192
195
 
196
+ export interface RemoveEventData {
197
+ data: {
198
+ el: HTMLElement;
199
+ }[];
200
+ }
201
+
193
202
  export interface SortEventData {
194
203
  src: Id;
195
204
  dist: Id;
@@ -244,3 +253,8 @@ export interface TargetShadowConfig {
244
253
  updateDragEl?: UpdateDragEl;
245
254
  idPrefix?: string;
246
255
  }
256
+
257
+ export enum AbleActionEventType {
258
+ SELECT_PARENT = 'select-parent',
259
+ REMOVE = 'remove',
260
+ }
@@ -100,7 +100,7 @@ export default class ActionManager extends EventEmitter {
100
100
  * @param excludeElList 计算鼠标所在容器时要排除的元素列表
101
101
  * @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
102
102
  */
103
- delayedMarkContainer(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout;
103
+ delayedMarkContainer(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout | undefined;
104
104
  destroy(): void;
105
105
  private changeCallback;
106
106
  /**
@@ -1,7 +1,7 @@
1
1
  import { OnDrag, OnDragGroup, OnDragGroupStart, OnDragStart, OnResize, OnResizeGroup, OnResizeGroupStart, OnResizeStart, OnRotate, OnRotateStart, OnScale, OnScaleStart } from 'moveable';
2
2
  import MoveableHelper from 'moveable-helper';
3
3
  import { Mode } from './const';
4
- import { DragResizeHelperConfig, TargetElement } from './types';
4
+ import { DragResizeHelperConfig, Rect, TargetElement } from './types';
5
5
  /**
6
6
  * 拖拽/改变大小等操作发生时,moveable会抛出各种状态事件,DragResizeHelper负责响应这些事件,对目标节点target和拖拽节点targetShadow进行修改;
7
7
  * 其中目标节点是DragResizeHelper直接改的,targetShadow作为直接被操作的拖拽框,是调用moveableHelper改的;
@@ -58,6 +58,7 @@ export default class DragResizeHelper {
58
58
  onResizeGroup(e: OnResizeGroup): void;
59
59
  onDragGroupStart(e: OnDragGroupStart): void;
60
60
  onDragGroup(e: OnDragGroup): void;
61
+ getUpdatedElRect(el: HTMLElement, parentEl: HTMLElement | null, doc: Document): Rect;
61
62
  /**
62
63
  * 多选状态设置多个节点的快照
63
64
  */
@@ -1,7 +1,10 @@
1
1
  import { MoveableManagerInterface, Renderer } from 'moveable';
2
- declare const _default: (selectParentHandler: () => void) => {
2
+ import { AbleActionEventType } from './types';
3
+ declare const _default: (handler: (type: AbleActionEventType) => void) => {
3
4
  name: string;
4
- props: {};
5
+ props: {
6
+ selectParent: BooleanConstructor;
7
+ };
5
8
  events: {};
6
9
  render(moveable: MoveableManagerInterface<any, any>, React: Renderer): any;
7
10
  };
@@ -68,7 +68,7 @@ export default class MoveableOptionsManager extends EventEmitter {
68
68
  /**
69
69
  * 这是给selectParentAbles的回调函数,用于触发选中父元素事件
70
70
  */
71
- private selectParentHandler;
71
+ private actionHandler;
72
72
  /**
73
73
  * 为需要辅助对齐的元素创建div
74
74
  * @param selectedElList 选中的元素列表,需要排除在对齐元素之外
@@ -60,7 +60,7 @@ export default class StageCore extends EventEmitter {
60
60
  /**
61
61
  * @deprecated 废弃接口,建议用delayedMarkContainer代替
62
62
  */
63
- getAddContainerHighlightClassNameTimeout(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout;
63
+ getAddContainerHighlightClassNameTimeout(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout | undefined;
64
64
  /**
65
65
  * 鼠标拖拽着元素,在容器上方悬停,延迟一段时间后,对容器进行标记,如果悬停时间够长将标记成功,悬停时间短,调用方通过返回的timeoutId取消标记
66
66
  * 标记的作用:1、高亮容器,给用户一个加入容器的交互感知;2、释放鼠标后,通过标记的标志找到要加入的容器
@@ -68,7 +68,7 @@ export default class StageCore extends EventEmitter {
68
68
  * @param excludeElList 计算鼠标所在容器时要排除的元素列表
69
69
  * @returns timeoutId,调用方在鼠标移走时要取消该timeout,阻止标记
70
70
  */
71
- delayedMarkContainer(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout;
71
+ delayedMarkContainer(event: MouseEvent, excludeElList?: Element[]): NodeJS.Timeout | undefined;
72
72
  /**
73
73
  * 销毁实例
74
74
  */