@tmagic/stage 1.1.0-beta.7 → 1.1.0

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.1.0-beta.7",
2
+ "version": "1.1.0",
3
3
  "name": "@tmagic/stage",
4
4
  "sideEffects": [
5
5
  "dist/*"
@@ -29,9 +29,9 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@scena/guides": "^0.17.0",
32
- "@tmagic/core": "1.1.0-beta.7",
33
- "@tmagic/schema": "1.1.0-beta.7",
34
- "@tmagic/utils": "1.1.0-beta.7",
32
+ "@tmagic/core": "1.1.0",
33
+ "@tmagic/schema": "1.1.0",
34
+ "@tmagic/utils": "1.1.0",
35
35
  "events": "^3.3.0",
36
36
  "keycon": "^1.1.2",
37
37
  "lodash-es": "^4.17.21",
package/src/StageCore.ts CHANGED
@@ -21,7 +21,7 @@ import { EventEmitter } from 'events';
21
21
  import type { Id } from '@tmagic/schema';
22
22
  import { addClassName } from '@tmagic/utils';
23
23
 
24
- import { DEFAULT_ZOOM, GHOST_EL_ID_PREFIX, PAGE_CLASS } from './const';
24
+ import { CONTAINER_HIGHLIGHT_CLASS, DEFAULT_ZOOM, GHOST_EL_ID_PREFIX, PAGE_CLASS } from './const';
25
25
  import StageDragResize from './StageDragResize';
26
26
  import StageHighlight from './StageHighlight';
27
27
  import StageMask from './StageMask';
@@ -29,12 +29,14 @@ import StageMultiDragResize from './StageMultiDragResize';
29
29
  import StageRender from './StageRender';
30
30
  import {
31
31
  CanSelect,
32
+ ContainerHighlightType,
32
33
  GuidesEventData,
33
34
  IsContainer,
34
35
  RemoveData,
35
36
  Runtime,
36
37
  SortEventData,
37
38
  StageCoreConfig,
39
+ StageDragStatus,
38
40
  UpdateData,
39
41
  UpdateEventData,
40
42
  } from './types';
@@ -56,6 +58,7 @@ export default class StageCore extends EventEmitter {
56
58
  public zoom = DEFAULT_ZOOM;
57
59
  public containerHighlightClassName: string;
58
60
  public containerHighlightDuration: number;
61
+ public containerHighlightType?: ContainerHighlightType;
59
62
  public isContainer: IsContainer;
60
63
 
61
64
  private canSelect: CanSelect;
@@ -68,8 +71,9 @@ export default class StageCore extends EventEmitter {
68
71
  this.setZoom(config.zoom);
69
72
  this.canSelect = config.canSelect || ((el: HTMLElement) => !!el.id);
70
73
  this.isContainer = config.isContainer;
71
- this.containerHighlightClassName = config.containerHighlightClassName;
72
- this.containerHighlightDuration = config.containerHighlightDuration;
74
+ this.containerHighlightClassName = config.containerHighlightClassName || CONTAINER_HIGHLIGHT_CLASS;
75
+ this.containerHighlightDuration = config.containerHighlightDuration || 800;
76
+ this.containerHighlightType = config.containerHighlightType;
73
77
 
74
78
  this.renderer = new StageRender({ core: this });
75
79
  this.mask = new StageMask({ core: this });
@@ -101,6 +105,8 @@ export default class StageCore extends EventEmitter {
101
105
  .on('highlight', async (event: MouseEvent) => {
102
106
  const el = await this.getElementFromPoint(event);
103
107
  if (!el) return;
108
+ // 如果多选组件处于拖拽状态时不进行组件高亮
109
+ if (this.multiDr.dragStatus === StageDragStatus.ING) return;
104
110
  await this.highlight(el);
105
111
  if (this.highlightedDom === this.selectedDom) {
106
112
  this.highlightLayer.clearHighlight();
@@ -139,9 +145,15 @@ export default class StageCore extends EventEmitter {
139
145
  setTimeout(() => this.emit('sort', data));
140
146
  });
141
147
 
142
- this.multiDr.on('update', (data: UpdateEventData) => {
143
- setTimeout(() => this.emit('update', data));
144
- });
148
+ this.multiDr
149
+ .on('update', (data: UpdateEventData) => {
150
+ setTimeout(() => this.emit('update', data));
151
+ })
152
+ .on('select', async (id: Id) => {
153
+ const el = await this.getTargetElement(id);
154
+ this.select(el); // 选中
155
+ setTimeout(() => this.emit('select', el)); // set node
156
+ });
145
157
  }
146
158
 
147
159
  public getElementsFromPoint(event: MouseEvent) {
@@ -337,7 +349,7 @@ export default class StageCore extends EventEmitter {
337
349
  }
338
350
  }
339
351
 
340
- public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []) {
352
+ public getAddContainerHighlightClassNameTimeout(event: MouseEvent, exclude: Element[] = []): NodeJS.Timeout {
341
353
  return globalThis.setTimeout(() => {
342
354
  this.addContainerHighlightClassName(event, exclude);
343
355
  }, this.containerHighlightDuration);
@@ -19,6 +19,7 @@
19
19
  /* eslint-disable no-param-reassign */
20
20
  import { EventEmitter } from 'events';
21
21
 
22
+ import KeyController from 'keycon';
22
23
  import type { MoveableOptions } from 'moveable';
23
24
  import Moveable from 'moveable';
24
25
  import MoveableHelper from 'moveable-helper';
@@ -29,18 +30,9 @@ import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from
29
30
  import StageCore from './StageCore';
30
31
  import StageMask from './StageMask';
31
32
  import type { StageDragResizeConfig } from './types';
33
+ import { ContainerHighlightType, StageDragStatus } from './types';
32
34
  import { calcValueByFontsize, down, getAbsolutePosition, getMode, getOffset, getTargetElStyle, up } from './util';
33
35
 
34
- /** 拖动状态 */
35
- enum ActionStatus {
36
- /** 开始拖动 */
37
- START = 'start',
38
- /** 拖动中 */
39
- ING = 'ing',
40
- /** 拖动结束 */
41
- END = 'end',
42
- }
43
-
44
36
  /**
45
37
  * 选中框
46
38
  */
@@ -66,10 +58,11 @@ export default class StageDragResize extends EventEmitter {
66
58
 
67
59
  private moveableOptions: MoveableOptions = {};
68
60
  /** 拖动状态 */
69
- private dragStatus: ActionStatus = ActionStatus.END;
61
+ private dragStatus: StageDragStatus = StageDragStatus.END;
70
62
  /** 流式布局下,目标节点的镜像节点 */
71
63
  private ghostEl: HTMLElement | undefined;
72
64
  private moveableHelper?: MoveableHelper;
65
+ private isContainerHighlight: Boolean = false;
73
66
 
74
67
  constructor(config: StageDragResizeConfig) {
75
68
  super();
@@ -77,6 +70,20 @@ export default class StageDragResize extends EventEmitter {
77
70
  this.core = config.core;
78
71
  this.container = config.container;
79
72
  this.mask = config.mask;
73
+
74
+ KeyController.global.keydown('alt', (e) => {
75
+ e.inputEvent.preventDefault();
76
+ this.isContainerHighlight = true;
77
+ });
78
+ KeyController.global.keyup('alt', (e) => {
79
+ e.inputEvent.preventDefault();
80
+
81
+ const doc = this.core.renderer.contentWindow?.document;
82
+ if (doc && this.canContainerHighlight()) {
83
+ removeClassNameByClassName(doc, this.core.containerHighlightClassName);
84
+ }
85
+ this.isContainerHighlight = false;
86
+ });
80
87
  }
81
88
 
82
89
  /**
@@ -165,7 +172,7 @@ export default class StageDragResize extends EventEmitter {
165
172
  this.moveable?.destroy();
166
173
  this.destroyGhostEl();
167
174
  this.destroyDragEl();
168
- this.dragStatus = ActionStatus.END;
175
+ this.dragStatus = StageDragStatus.END;
169
176
  this.removeAllListeners();
170
177
  }
171
178
 
@@ -243,7 +250,7 @@ export default class StageDragResize extends EventEmitter {
243
250
  .on('resizeStart', (e) => {
244
251
  if (!this.target) return;
245
252
 
246
- this.dragStatus = ActionStatus.START;
253
+ this.dragStatus = StageDragStatus.START;
247
254
  this.moveableHelper?.onResizeStart(e);
248
255
 
249
256
  frame.top = this.target.offsetTop;
@@ -254,14 +261,15 @@ export default class StageDragResize extends EventEmitter {
254
261
  if (!this.moveable || !this.target || !this.dragEl) return;
255
262
 
256
263
  const { beforeTranslate } = drag;
257
- this.dragStatus = ActionStatus.ING;
258
-
259
- this.moveableHelper?.onResize(e);
264
+ this.dragStatus = StageDragStatus.ING;
260
265
 
261
266
  // 流式布局
262
267
  if (this.mode === Mode.SORTABLE) {
263
268
  this.target.style.top = '0px';
269
+ this.dragEl.style.width = `${width}px`;
270
+ this.dragEl.style.height = `${height}px`;
264
271
  } else {
272
+ this.moveableHelper?.onResize(e);
265
273
  this.target.style.left = `${frame.left + beforeTranslate[0]}px`;
266
274
  this.target.style.top = `${frame.top + beforeTranslate[1]}px`;
267
275
  }
@@ -270,7 +278,7 @@ export default class StageDragResize extends EventEmitter {
270
278
  this.target.style.height = `${height}px`;
271
279
  })
272
280
  .on('resizeEnd', () => {
273
- this.dragStatus = ActionStatus.END;
281
+ this.dragStatus = StageDragStatus.END;
274
282
  this.update(true);
275
283
  });
276
284
  }
@@ -292,7 +300,7 @@ export default class StageDragResize extends EventEmitter {
292
300
  .on('dragStart', (e) => {
293
301
  if (!this.target) throw new Error('未选中组件');
294
302
 
295
- this.dragStatus = ActionStatus.START;
303
+ this.dragStatus = StageDragStatus.START;
296
304
 
297
305
  this.moveableHelper?.onDragStart(e);
298
306
 
@@ -311,9 +319,11 @@ export default class StageDragResize extends EventEmitter {
311
319
  timeout = undefined;
312
320
  }
313
321
 
314
- timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
322
+ if (this.canContainerHighlight()) {
323
+ timeout = this.core.getAddContainerHighlightClassNameTimeout(e.inputEvent, [this.target]);
324
+ }
315
325
 
316
- this.dragStatus = ActionStatus.ING;
326
+ this.dragStatus = StageDragStatus.ING;
317
327
 
318
328
  // 流式布局
319
329
  if (this.ghostEl) {
@@ -334,12 +344,12 @@ export default class StageDragResize extends EventEmitter {
334
344
 
335
345
  let parentEl: HTMLElement | null = null;
336
346
 
337
- if (doc) {
347
+ if (doc && this.canContainerHighlight()) {
338
348
  parentEl = removeClassNameByClassName(doc, this.core.containerHighlightClassName);
339
349
  }
340
350
 
341
351
  // 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
342
- if (this.dragStatus === ActionStatus.ING) {
352
+ if (this.dragStatus === StageDragStatus.ING) {
343
353
  if (parentEl) {
344
354
  this.update(false, parentEl);
345
355
  } else {
@@ -353,7 +363,7 @@ export default class StageDragResize extends EventEmitter {
353
363
  }
354
364
  }
355
365
 
356
- this.dragStatus = ActionStatus.END;
366
+ this.dragStatus = StageDragStatus.END;
357
367
  this.destroyGhostEl();
358
368
  });
359
369
  }
@@ -363,18 +373,18 @@ export default class StageDragResize extends EventEmitter {
363
373
 
364
374
  this.moveable
365
375
  .on('rotateStart', (e) => {
366
- this.dragStatus = ActionStatus.START;
376
+ this.dragStatus = StageDragStatus.START;
367
377
  this.moveableHelper?.onRotateStart(e);
368
378
  })
369
379
  .on('rotate', (e) => {
370
380
  if (!this.target || !this.dragEl) return;
371
- this.dragStatus = ActionStatus.ING;
381
+ this.dragStatus = StageDragStatus.ING;
372
382
  this.moveableHelper?.onRotate(e);
373
383
  const frame = this.moveableHelper?.getFrame(e.target);
374
384
  this.target.style.transform = frame?.toCSSObject().transform || '';
375
385
  })
376
386
  .on('rotateEnd', (e) => {
377
- this.dragStatus = ActionStatus.END;
387
+ this.dragStatus = StageDragStatus.END;
378
388
  const frame = this.moveableHelper?.getFrame(e.target);
379
389
  this.emit('update', {
380
390
  el: this.target,
@@ -390,18 +400,18 @@ export default class StageDragResize extends EventEmitter {
390
400
 
391
401
  this.moveable
392
402
  .on('scaleStart', (e) => {
393
- this.dragStatus = ActionStatus.START;
403
+ this.dragStatus = StageDragStatus.START;
394
404
  this.moveableHelper?.onScaleStart(e);
395
405
  })
396
406
  .on('scale', (e) => {
397
407
  if (!this.target || !this.dragEl) return;
398
- this.dragStatus = ActionStatus.ING;
408
+ this.dragStatus = StageDragStatus.ING;
399
409
  this.moveableHelper?.onScale(e);
400
410
  const frame = this.moveableHelper?.getFrame(e.target);
401
411
  this.target.style.transform = frame?.toCSSObject().transform || '';
402
412
  })
403
413
  .on('scaleEnd', (e) => {
404
- this.dragStatus = ActionStatus.END;
414
+ this.dragStatus = StageDragStatus.END;
405
415
  const frame = this.moveableHelper?.getFrame(e.target);
406
416
  this.emit('update', {
407
417
  el: this.target,
@@ -459,9 +469,13 @@ export default class StageDragResize extends EventEmitter {
459
469
  }
460
470
 
461
471
  this.emit('update', {
462
- el: this.target,
472
+ data: [
473
+ {
474
+ el: this.target,
475
+ style: isResize ? { left, top, width, height } : { left, top },
476
+ },
477
+ ],
463
478
  parentEl,
464
- style: isResize ? { left, top, width, height } : { left, top },
465
479
  });
466
480
  }
467
481
 
@@ -505,6 +519,7 @@ export default class StageDragResize extends EventEmitter {
505
519
 
506
520
  const isAbsolute = this.mode === Mode.ABSOLUTE;
507
521
  const isFixed = this.mode === Mode.FIXED;
522
+ const isSortable = this.mode === Mode.SORTABLE;
508
523
 
509
524
  let { moveableOptions = {} } = this.core.config;
510
525
 
@@ -559,11 +574,18 @@ export default class StageDragResize extends EventEmitter {
559
574
  // 设置0的话无法移动到left为0,所以只能设置为-1
560
575
  left: -1,
561
576
  right: this.container.clientWidth - 1,
562
- bottom: this.container.clientHeight,
577
+ bottom: isSortable ? undefined : this.container.clientHeight,
563
578
  ...(moveableOptions.bounds || {}),
564
579
  },
565
580
  ...options,
566
581
  ...moveableOptions,
567
582
  };
568
583
  }
584
+
585
+ private canContainerHighlight() {
586
+ return (
587
+ this.core.containerHighlightType === ContainerHighlightType.DEFAULT ||
588
+ (this.core.containerHighlightType === ContainerHighlightType.ALT && this.isContainerHighlight)
589
+ );
590
+ }
569
591
  }
@@ -18,15 +18,16 @@
18
18
 
19
19
  import { EventEmitter } from 'events';
20
20
 
21
- import type { MoveableOptions } from 'moveable';
21
+ import type { MoveableOptions, OnDragStart, OnResizeStart } from 'moveable';
22
22
  import Moveable from 'moveable';
23
23
  import MoveableHelper from 'moveable-helper';
24
24
 
25
25
  import { DRAG_EL_ID_PREFIX, PAGE_CLASS } from './const';
26
26
  import StageCore from './StageCore';
27
27
  import StageMask from './StageMask';
28
- import { StageDragResizeConfig } from './types';
28
+ import { StageDragResizeConfig, StageDragStatus } from './types';
29
29
  import { calcValueByFontsize, getMode, getTargetElStyle } from './util';
30
+
30
31
  export default class StageMultiDragResize extends EventEmitter {
31
32
  public core: StageCore;
32
33
  public mask: StageMask;
@@ -38,6 +39,8 @@ export default class StageMultiDragResize extends EventEmitter {
38
39
  public dragElList: HTMLDivElement[] = [];
39
40
  /** Moveable多选拖拽类实例 */
40
41
  public moveableForMulti?: Moveable;
42
+ /** 拖动状态 */
43
+ public dragStatus: StageDragStatus = StageDragStatus.END;
41
44
  private multiMoveableHelper?: MoveableHelper;
42
45
 
43
46
  constructor(config: StageDragResizeConfig) {
@@ -82,23 +85,68 @@ export default class StageMultiDragResize extends EventEmitter {
82
85
  createAuto: true,
83
86
  });
84
87
  const frames: { left: number; top: number; id: string }[] = [];
88
+
89
+ const setFrames = (events: OnDragStart[] | OnResizeStart[]) => {
90
+ // 记录拖动前快照
91
+ events.forEach((ev) => {
92
+ // 实际目标元素
93
+ const matchEventTarget = this.targetList.find(
94
+ (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''),
95
+ );
96
+ if (!matchEventTarget) return;
97
+ frames.push({
98
+ left: matchEventTarget.offsetLeft,
99
+ top: matchEventTarget.offsetTop,
100
+ id: matchEventTarget.id,
101
+ });
102
+ });
103
+ };
104
+
85
105
  this.moveableForMulti
86
- .on('dragGroupStart', (params) => {
106
+ .on('resizeGroupStart', (params) => {
87
107
  const { events } = params;
88
- this.multiMoveableHelper?.onDragGroupStart(params);
89
- // 记录拖动前快照
108
+ this.multiMoveableHelper?.onResizeGroupStart(params);
109
+ setFrames(events);
110
+ this.dragStatus = StageDragStatus.START;
111
+ })
112
+ .on('resizeGroup', (params) => {
113
+ const { events } = params;
114
+ // 拖动过程更新
90
115
  events.forEach((ev) => {
91
- // 实际目标元素
92
- const matchEventTarget = this.targetList.find(
116
+ const { width, height, beforeTranslate } = ev.drag;
117
+ const frameSnapShot = frames.find(
118
+ (frameItem) => frameItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''),
119
+ );
120
+ if (!frameSnapShot) return;
121
+ const targeEl = this.targetList.find(
93
122
  (targetItem) => targetItem.id === ev.target.id.replace(DRAG_EL_ID_PREFIX, ''),
94
123
  );
95
- if (!matchEventTarget) return;
96
- frames.push({
97
- left: matchEventTarget.offsetLeft,
98
- top: matchEventTarget.offsetTop,
99
- id: matchEventTarget.id,
100
- });
124
+ if (!targeEl) return;
125
+ // 元素与其所属组同时加入多选列表时,只更新父元素
126
+ const isParentIncluded = this.targetList.find((targetItem) => targetItem.id === targeEl.parentElement?.id);
127
+ if (!isParentIncluded) {
128
+ // 更新页面元素位置
129
+ targeEl.style.left = `${frameSnapShot.left + beforeTranslate[0]}px`;
130
+ targeEl.style.top = `${frameSnapShot.top + beforeTranslate[1]}px`;
131
+ }
132
+
133
+ // 更新页面元素位置
134
+ targeEl.style.width = `${width}px`;
135
+ targeEl.style.height = `${height}px`;
101
136
  });
137
+ this.multiMoveableHelper?.onResizeGroup(params);
138
+ this.dragStatus = StageDragStatus.ING;
139
+ })
140
+ .on('resizeGroupEnd', () => {
141
+ this.update(true);
142
+ this.dragStatus = StageDragStatus.END;
143
+ })
144
+ .on('dragGroupStart', (params) => {
145
+ const { events } = params;
146
+ this.multiMoveableHelper?.onDragGroupStart(params);
147
+ // 记录拖动前快照
148
+ setFrames(events);
149
+ this.dragStatus = StageDragStatus.START;
102
150
  })
103
151
  .on('dragGroup', (params) => {
104
152
  const { events } = params;
@@ -121,9 +169,18 @@ export default class StageMultiDragResize extends EventEmitter {
121
169
  }
122
170
  });
123
171
  this.multiMoveableHelper?.onDragGroup(params);
172
+ this.dragStatus = StageDragStatus.ING;
124
173
  })
125
174
  .on('dragGroupEnd', () => {
126
175
  this.update();
176
+ this.dragStatus = StageDragStatus.END;
177
+ })
178
+ .on('clickGroup', (params) => {
179
+ const { inputTarget, targets } = params;
180
+ // 如果此时mask不处于多选状态下,且有多个元素被选中,同时点击的元素在选中元素中的其中一项,代表多选态切换为该元素的单选态
181
+ if (!this.mask.isMultiSelectStatus && targets.length > 1 && targets.includes(inputTarget)) {
182
+ this.emit('select', inputTarget.id.replace(DRAG_EL_ID_PREFIX, ''));
183
+ }
127
184
  });
128
185
  }
129
186
 
@@ -192,16 +249,19 @@ export default class StageMultiDragResize extends EventEmitter {
192
249
  const doc = contentWindow?.document;
193
250
  if (!doc) return;
194
251
 
195
- this.targetList.forEach((targetItem) => {
196
- const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
197
- const left = calcValueByFontsize(doc, offset.left);
198
- const top = calcValueByFontsize(doc, offset.top);
199
- const width = calcValueByFontsize(doc, targetItem.clientWidth);
200
- const height = calcValueByFontsize(doc, targetItem.clientHeight);
201
- this.emit('update', {
202
- el: targetItem,
203
- style: isResize ? { left, top, width, height } : { left, top },
204
- });
252
+ this.emit('update', {
253
+ data: this.targetList.map((targetItem) => {
254
+ const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
255
+ const left = calcValueByFontsize(doc, offset.left);
256
+ const top = calcValueByFontsize(doc, offset.top);
257
+ const width = calcValueByFontsize(doc, targetItem.clientWidth);
258
+ const height = calcValueByFontsize(doc, targetItem.clientHeight);
259
+ return {
260
+ el: targetItem,
261
+ style: isResize ? { left, top, width, height } : { left, top },
262
+ };
263
+ }),
264
+ parentEl: null,
205
265
  });
206
266
  }
207
267
 
@@ -228,6 +288,15 @@ export default class StageMultiDragResize extends EventEmitter {
228
288
  zoom: 1,
229
289
  origin: true,
230
290
  padding: { left: 0, top: 0, right: 0, bottom: 0 },
291
+ snappable: true,
292
+ bounds: {
293
+ top: 0,
294
+ // 设置0的话无法移动到left为0,所以只能设置为-1
295
+ left: -1,
296
+ right: this.container.clientWidth - 1,
297
+ bottom: this.container.clientHeight,
298
+ ...(multiMoveableOptions.bounds || {}),
299
+ },
231
300
  ...options,
232
301
  ...multiMoveableOptions,
233
302
  };
package/src/style.css CHANGED
@@ -9,3 +9,7 @@
9
9
  opacity: .1;
10
10
  pointer-events: none;
11
11
  }
12
+
13
+ .magic-ui-container.magic-layout-relative {
14
+ min-height: 50px;
15
+ }
package/src/types.ts CHANGED
@@ -29,6 +29,11 @@ import StageMask from './StageMask';
29
29
  export type CanSelect = (el: HTMLElement, event: MouseEvent, stop: () => boolean) => boolean | Promise<boolean>;
30
30
  export type IsContainer = (el: HTMLElement) => boolean | Promise<boolean>;
31
31
 
32
+ export enum ContainerHighlightType {
33
+ DEFAULT = 'default',
34
+ ALT = 'alt',
35
+ }
36
+
32
37
  export type StageCoreConfig = {
33
38
  /** 需要对齐的dom节点的CSS选择器字符串 */
34
39
  snapElementQuerySelector?: string;
@@ -36,8 +41,9 @@ export type StageCoreConfig = {
36
41
  zoom?: number;
37
42
  canSelect?: CanSelect;
38
43
  isContainer: IsContainer;
39
- containerHighlightClassName: string;
40
- containerHighlightDuration: number;
44
+ containerHighlightClassName?: string;
45
+ containerHighlightDuration?: number;
46
+ containerHighlightType?: ContainerHighlightType;
41
47
  moveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
42
48
  multiMoveableOptions?: ((core?: StageCore) => MoveableOptions) | MoveableOptions;
43
49
  /** runtime 的HTML地址,可以是一个HTTP地址,如果和编辑器不同域,需要设置跨域,也可以是一个相对或绝对路径 */
@@ -61,6 +67,16 @@ export interface StageDragResizeConfig {
61
67
  mask: StageMask;
62
68
  }
63
69
 
70
+ /** 拖动状态 */
71
+ export enum StageDragStatus {
72
+ /** 开始拖动 */
73
+ START = 'start',
74
+ /** 拖动中 */
75
+ ING = 'ing',
76
+ /** 拖动结束 */
77
+ END = 'end',
78
+ }
79
+
64
80
  export type Rect = {
65
81
  width: number;
66
82
  height: number;
@@ -77,19 +93,21 @@ export interface GuidesEventData {
77
93
  }
78
94
 
79
95
  export interface UpdateEventData {
80
- el: HTMLElement;
81
- parentEl: HTMLElement | null;
82
- ghostEl: HTMLElement;
83
- style: {
84
- width?: number;
85
- height?: number;
86
- left?: number;
87
- top?: number;
88
- transform?: {
89
- rotate?: string;
90
- scale?: string;
96
+ data: {
97
+ el: HTMLElement;
98
+ style: {
99
+ width?: number;
100
+ height?: number;
101
+ left?: number;
102
+ top?: number;
103
+ transform?: {
104
+ rotate?: string;
105
+ scale?: string;
106
+ };
91
107
  };
92
- };
108
+ ghostEl?: HTMLElement;
109
+ }[];
110
+ parentEl: HTMLElement | null;
93
111
  }
94
112
 
95
113
  export interface SortEventData {
@@ -101,11 +119,13 @@ export interface SortEventData {
101
119
  export interface UpdateData {
102
120
  config: MNode;
103
121
  parent?: MContainer;
122
+ parentId?: Id;
104
123
  root: MApp;
105
124
  }
106
125
 
107
126
  export interface RemoveData {
108
127
  id: Id;
128
+ parentId: Id;
109
129
  root: MApp;
110
130
  }
111
131
 
@@ -7,7 +7,7 @@ import StageHighlight from './StageHighlight';
7
7
  import StageMask from './StageMask';
8
8
  import StageMultiDragResize from './StageMultiDragResize';
9
9
  import StageRender from './StageRender';
10
- import { IsContainer, RemoveData, SortEventData, StageCoreConfig, UpdateData } from './types';
10
+ import { ContainerHighlightType, IsContainer, RemoveData, SortEventData, StageCoreConfig, UpdateData } from './types';
11
11
  export default class StageCore extends EventEmitter {
12
12
  container?: HTMLDivElement;
13
13
  selectedDom: HTMLElement | undefined;
@@ -22,6 +22,7 @@ export default class StageCore extends EventEmitter {
22
22
  zoom: number;
23
23
  containerHighlightClassName: string;
24
24
  containerHighlightDuration: number;
25
+ containerHighlightType?: ContainerHighlightType;
25
26
  isContainer: IsContainer;
26
27
  private canSelect;
27
28
  constructor(config: StageCoreConfig);
@@ -33,6 +33,7 @@ export default class StageDragResize extends EventEmitter {
33
33
  /** 流式布局下,目标节点的镜像节点 */
34
34
  private ghostEl;
35
35
  private moveableHelper?;
36
+ private isContainerHighlight;
36
37
  constructor(config: StageDragResizeConfig);
37
38
  /**
38
39
  * 将选中框渲染并覆盖到选中的组件Dom节点上方
@@ -67,4 +68,5 @@ export default class StageDragResize extends EventEmitter {
67
68
  private setGhostElChildrenId;
68
69
  private destroyGhostEl;
69
70
  private getOptions;
71
+ private canContainerHighlight;
70
72
  }
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
3
3
  import Moveable from 'moveable';
4
4
  import StageCore from './StageCore';
5
5
  import StageMask from './StageMask';
6
- import { StageDragResizeConfig } from './types';
6
+ import { StageDragResizeConfig, StageDragStatus } from './types';
7
7
  export default class StageMultiDragResize extends EventEmitter {
8
8
  core: StageCore;
9
9
  mask: StageMask;
@@ -15,6 +15,8 @@ export default class StageMultiDragResize extends EventEmitter {
15
15
  dragElList: HTMLDivElement[];
16
16
  /** Moveable多选拖拽类实例 */
17
17
  moveableForMulti?: Moveable;
18
+ /** 拖动状态 */
19
+ dragStatus: StageDragStatus;
18
20
  private multiMoveableHelper?;
19
21
  constructor(config: StageDragResizeConfig);
20
22
  /**