@tmagic/stage 1.7.13 → 1.7.14-beta.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/dist/es/ActionManager.js +40 -6
- package/dist/es/StageCore.js +9 -0
- package/dist/tmagic-stage.umd.cjs +49 -6
- package/package.json +2 -2
- package/src/ActionManager.ts +47 -8
- package/src/StageCore.ts +10 -0
- package/src/types.ts +29 -0
- package/types/index.d.ts +44 -1
package/dist/es/ActionManager.js
CHANGED
|
@@ -40,8 +40,12 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
40
40
|
getElementsFromPoint;
|
|
41
41
|
canSelect;
|
|
42
42
|
isContainer;
|
|
43
|
+
/** 见 ActionManagerConfig.canDropIn */
|
|
44
|
+
canDropIn;
|
|
43
45
|
getRenderDocument;
|
|
44
46
|
disabledMultiSelect = false;
|
|
47
|
+
/** 始终启用多选模式(无需按住 Ctrl/Meta),优先级低于 disabledMultiSelect */
|
|
48
|
+
alwaysMultiSelect = false;
|
|
45
49
|
config;
|
|
46
50
|
mouseMoveHandler = throttle((event) => {
|
|
47
51
|
const handler = async () => {
|
|
@@ -65,13 +69,18 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
65
69
|
this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
|
|
66
70
|
this.containerHighlightType = config.containerHighlightType;
|
|
67
71
|
this.disabledMultiSelect = config.disabledMultiSelect ?? false;
|
|
72
|
+
this.alwaysMultiSelect = config.alwaysMultiSelect ?? false;
|
|
68
73
|
this.getTargetElement = config.getTargetElement;
|
|
69
74
|
this.getElementsFromPoint = config.getElementsFromPoint;
|
|
70
75
|
this.canSelect = config.canSelect || ((el) => Boolean(getIdFromEl()(el)));
|
|
71
76
|
this.getRenderDocument = config.getRenderDocument;
|
|
72
77
|
this.isContainer = config.isContainer;
|
|
78
|
+
this.canDropIn = config.canDropIn;
|
|
73
79
|
this.dr = this.createDr(config);
|
|
74
|
-
if (!this.disabledMultiSelect)
|
|
80
|
+
if (!this.disabledMultiSelect) {
|
|
81
|
+
this.multiDr = this.createMultiDr(config);
|
|
82
|
+
if (this.alwaysMultiSelect) this.isMultiSelectStatus = true;
|
|
83
|
+
}
|
|
75
84
|
this.highlightLayer = new StageHighlight({
|
|
76
85
|
container: config.container,
|
|
77
86
|
updateDragEl: config.updateDragEl,
|
|
@@ -82,6 +91,7 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
82
91
|
}
|
|
83
92
|
disableMultiSelect() {
|
|
84
93
|
this.disabledMultiSelect = true;
|
|
94
|
+
this.isMultiSelectStatus = false;
|
|
85
95
|
if (this.multiDr) {
|
|
86
96
|
this.multiDr.destroy();
|
|
87
97
|
this.multiDr = null;
|
|
@@ -90,6 +100,16 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
90
100
|
enableMultiSelect() {
|
|
91
101
|
this.disabledMultiSelect = false;
|
|
92
102
|
if (!this.multiDr) this.multiDr = this.createMultiDr(this.config);
|
|
103
|
+
if (this.alwaysMultiSelect) this.isMultiSelectStatus = true;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta),
|
|
107
|
+
* 当 `disabledMultiSelect` 为 true 时本方法不会启用多选。
|
|
108
|
+
*/
|
|
109
|
+
setAlwaysMultiSelect(value) {
|
|
110
|
+
this.alwaysMultiSelect = value;
|
|
111
|
+
if (this.disabledMultiSelect) return;
|
|
112
|
+
this.isMultiSelectStatus = value;
|
|
93
113
|
}
|
|
94
114
|
/**
|
|
95
115
|
* 设置水平/垂直参考线
|
|
@@ -255,9 +275,23 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
255
275
|
const doc = this.getRenderDocument();
|
|
256
276
|
if (!doc) return;
|
|
257
277
|
const els = this.getElementsFromPoint(event);
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
278
|
+
const sourceIds = excludeElList.map((el) => el instanceof HTMLElement ? getIdFromEl()(el) : void 0).filter((id) => Boolean(id));
|
|
279
|
+
for (const el of els) {
|
|
280
|
+
const targetId = getIdFromEl()(el);
|
|
281
|
+
if (!targetId?.startsWith("ghost_el_") && await this.isContainer?.(el) && !excludeElList.includes(el)) {
|
|
282
|
+
let highlightEl = el;
|
|
283
|
+
if (targetId && this.canDropIn) {
|
|
284
|
+
const result = this.canDropIn(sourceIds, targetId);
|
|
285
|
+
if (result === false) continue;
|
|
286
|
+
if (typeof result === "string" || typeof result === "number") {
|
|
287
|
+
const redirectedEl = this.getTargetElement(result);
|
|
288
|
+
if (!redirectedEl) continue;
|
|
289
|
+
highlightEl = redirectedEl;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
addClassName(highlightEl, doc, this.containerHighlightClassName);
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
261
295
|
}
|
|
262
296
|
}
|
|
263
297
|
/**
|
|
@@ -419,12 +453,12 @@ var ActionManager = class extends EventEmitter$1 {
|
|
|
419
453
|
if (!this.disabledMultiSelect) this.isMultiSelectStatus = true;
|
|
420
454
|
});
|
|
421
455
|
KeyController.global.on("blur", () => {
|
|
422
|
-
if (!this.disabledMultiSelect) this.isMultiSelectStatus = false;
|
|
456
|
+
if (!this.disabledMultiSelect && !this.alwaysMultiSelect) this.isMultiSelectStatus = false;
|
|
423
457
|
this.isAltKeydown = false;
|
|
424
458
|
});
|
|
425
459
|
KeyController.global.keyup(ctrl, (e) => {
|
|
426
460
|
e.inputEvent.preventDefault();
|
|
427
|
-
if (!this.disabledMultiSelect) this.isMultiSelectStatus = false;
|
|
461
|
+
if (!this.disabledMultiSelect && !this.alwaysMultiSelect) this.isMultiSelectStatus = false;
|
|
428
462
|
});
|
|
429
463
|
KeyController.global.keydown("alt", (e) => {
|
|
430
464
|
e.inputEvent.preventDefault();
|
package/dist/es/StageCore.js
CHANGED
|
@@ -177,6 +177,13 @@ var StageCore = class extends EventEmitter {
|
|
|
177
177
|
enableMultiSelect() {
|
|
178
178
|
this.actionManager?.enableMultiSelect();
|
|
179
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta)。
|
|
182
|
+
* 当多选被 `disabledMultiSelect` 禁用时,本方法不会启用多选。
|
|
183
|
+
*/
|
|
184
|
+
setAlwaysMultiSelect(value) {
|
|
185
|
+
this.actionManager?.setAlwaysMultiSelect(value);
|
|
186
|
+
}
|
|
180
187
|
reloadIframe(url) {
|
|
181
188
|
this.renderer?.reloadIframe(url);
|
|
182
189
|
}
|
|
@@ -231,8 +238,10 @@ var StageCore = class extends EventEmitter {
|
|
|
231
238
|
container: this.mask.content,
|
|
232
239
|
disabledDragStart: config.disabledDragStart,
|
|
233
240
|
disabledMultiSelect: config.disabledMultiSelect,
|
|
241
|
+
alwaysMultiSelect: config.alwaysMultiSelect,
|
|
234
242
|
canSelect: config.canSelect,
|
|
235
243
|
isContainer: config.isContainer,
|
|
244
|
+
canDropIn: config.canDropIn,
|
|
236
245
|
updateDragEl: config.updateDragEl,
|
|
237
246
|
getRootContainer: () => this.container,
|
|
238
247
|
getRenderDocument: () => this.renderer.getDocument(),
|
|
@@ -3512,8 +3512,12 @@
|
|
|
3512
3512
|
getElementsFromPoint;
|
|
3513
3513
|
canSelect;
|
|
3514
3514
|
isContainer;
|
|
3515
|
+
/** 见 ActionManagerConfig.canDropIn */
|
|
3516
|
+
canDropIn;
|
|
3515
3517
|
getRenderDocument;
|
|
3516
3518
|
disabledMultiSelect = false;
|
|
3519
|
+
/** 始终启用多选模式(无需按住 Ctrl/Meta),优先级低于 disabledMultiSelect */
|
|
3520
|
+
alwaysMultiSelect = false;
|
|
3517
3521
|
config;
|
|
3518
3522
|
mouseMoveHandler = throttle((event) => {
|
|
3519
3523
|
const handler = async () => {
|
|
@@ -3537,13 +3541,18 @@
|
|
|
3537
3541
|
this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
|
|
3538
3542
|
this.containerHighlightType = config.containerHighlightType;
|
|
3539
3543
|
this.disabledMultiSelect = config.disabledMultiSelect ?? false;
|
|
3544
|
+
this.alwaysMultiSelect = config.alwaysMultiSelect ?? false;
|
|
3540
3545
|
this.getTargetElement = config.getTargetElement;
|
|
3541
3546
|
this.getElementsFromPoint = config.getElementsFromPoint;
|
|
3542
3547
|
this.canSelect = config.canSelect || ((el) => Boolean((0, _tmagic_core.getIdFromEl)()(el)));
|
|
3543
3548
|
this.getRenderDocument = config.getRenderDocument;
|
|
3544
3549
|
this.isContainer = config.isContainer;
|
|
3550
|
+
this.canDropIn = config.canDropIn;
|
|
3545
3551
|
this.dr = this.createDr(config);
|
|
3546
|
-
if (!this.disabledMultiSelect)
|
|
3552
|
+
if (!this.disabledMultiSelect) {
|
|
3553
|
+
this.multiDr = this.createMultiDr(config);
|
|
3554
|
+
if (this.alwaysMultiSelect) this.isMultiSelectStatus = true;
|
|
3555
|
+
}
|
|
3547
3556
|
this.highlightLayer = new StageHighlight({
|
|
3548
3557
|
container: config.container,
|
|
3549
3558
|
updateDragEl: config.updateDragEl,
|
|
@@ -3554,6 +3563,7 @@
|
|
|
3554
3563
|
}
|
|
3555
3564
|
disableMultiSelect() {
|
|
3556
3565
|
this.disabledMultiSelect = true;
|
|
3566
|
+
this.isMultiSelectStatus = false;
|
|
3557
3567
|
if (this.multiDr) {
|
|
3558
3568
|
this.multiDr.destroy();
|
|
3559
3569
|
this.multiDr = null;
|
|
@@ -3562,6 +3572,16 @@
|
|
|
3562
3572
|
enableMultiSelect() {
|
|
3563
3573
|
this.disabledMultiSelect = false;
|
|
3564
3574
|
if (!this.multiDr) this.multiDr = this.createMultiDr(this.config);
|
|
3575
|
+
if (this.alwaysMultiSelect) this.isMultiSelectStatus = true;
|
|
3576
|
+
}
|
|
3577
|
+
/**
|
|
3578
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta),
|
|
3579
|
+
* 当 `disabledMultiSelect` 为 true 时本方法不会启用多选。
|
|
3580
|
+
*/
|
|
3581
|
+
setAlwaysMultiSelect(value) {
|
|
3582
|
+
this.alwaysMultiSelect = value;
|
|
3583
|
+
if (this.disabledMultiSelect) return;
|
|
3584
|
+
this.isMultiSelectStatus = value;
|
|
3565
3585
|
}
|
|
3566
3586
|
/**
|
|
3567
3587
|
* 设置水平/垂直参考线
|
|
@@ -3727,9 +3747,23 @@
|
|
|
3727
3747
|
const doc = this.getRenderDocument();
|
|
3728
3748
|
if (!doc) return;
|
|
3729
3749
|
const els = this.getElementsFromPoint(event);
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3750
|
+
const sourceIds = excludeElList.map((el) => el instanceof HTMLElement ? (0, _tmagic_core.getIdFromEl)()(el) : void 0).filter((id) => Boolean(id));
|
|
3751
|
+
for (const el of els) {
|
|
3752
|
+
const targetId = (0, _tmagic_core.getIdFromEl)()(el);
|
|
3753
|
+
if (!targetId?.startsWith("ghost_el_") && await this.isContainer?.(el) && !excludeElList.includes(el)) {
|
|
3754
|
+
let highlightEl = el;
|
|
3755
|
+
if (targetId && this.canDropIn) {
|
|
3756
|
+
const result = this.canDropIn(sourceIds, targetId);
|
|
3757
|
+
if (result === false) continue;
|
|
3758
|
+
if (typeof result === "string" || typeof result === "number") {
|
|
3759
|
+
const redirectedEl = this.getTargetElement(result);
|
|
3760
|
+
if (!redirectedEl) continue;
|
|
3761
|
+
highlightEl = redirectedEl;
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
(0, _tmagic_core.addClassName)(highlightEl, doc, this.containerHighlightClassName);
|
|
3765
|
+
break;
|
|
3766
|
+
}
|
|
3733
3767
|
}
|
|
3734
3768
|
}
|
|
3735
3769
|
/**
|
|
@@ -3891,12 +3925,12 @@
|
|
|
3891
3925
|
if (!this.disabledMultiSelect) this.isMultiSelectStatus = true;
|
|
3892
3926
|
});
|
|
3893
3927
|
keycon.default.global.on("blur", () => {
|
|
3894
|
-
if (!this.disabledMultiSelect) this.isMultiSelectStatus = false;
|
|
3928
|
+
if (!this.disabledMultiSelect && !this.alwaysMultiSelect) this.isMultiSelectStatus = false;
|
|
3895
3929
|
this.isAltKeydown = false;
|
|
3896
3930
|
});
|
|
3897
3931
|
keycon.default.global.keyup(ctrl, (e) => {
|
|
3898
3932
|
e.inputEvent.preventDefault();
|
|
3899
|
-
if (!this.disabledMultiSelect) this.isMultiSelectStatus = false;
|
|
3933
|
+
if (!this.disabledMultiSelect && !this.alwaysMultiSelect) this.isMultiSelectStatus = false;
|
|
3900
3934
|
});
|
|
3901
3935
|
keycon.default.global.keydown("alt", (e) => {
|
|
3902
3936
|
e.inputEvent.preventDefault();
|
|
@@ -4716,6 +4750,13 @@
|
|
|
4716
4750
|
enableMultiSelect() {
|
|
4717
4751
|
this.actionManager?.enableMultiSelect();
|
|
4718
4752
|
}
|
|
4753
|
+
/**
|
|
4754
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta)。
|
|
4755
|
+
* 当多选被 `disabledMultiSelect` 禁用时,本方法不会启用多选。
|
|
4756
|
+
*/
|
|
4757
|
+
setAlwaysMultiSelect(value) {
|
|
4758
|
+
this.actionManager?.setAlwaysMultiSelect(value);
|
|
4759
|
+
}
|
|
4719
4760
|
reloadIframe(url) {
|
|
4720
4761
|
this.renderer?.reloadIframe(url);
|
|
4721
4762
|
}
|
|
@@ -4770,8 +4811,10 @@
|
|
|
4770
4811
|
container: this.mask.content,
|
|
4771
4812
|
disabledDragStart: config.disabledDragStart,
|
|
4772
4813
|
disabledMultiSelect: config.disabledMultiSelect,
|
|
4814
|
+
alwaysMultiSelect: config.alwaysMultiSelect,
|
|
4773
4815
|
canSelect: config.canSelect,
|
|
4774
4816
|
isContainer: config.isContainer,
|
|
4817
|
+
canDropIn: config.canDropIn,
|
|
4775
4818
|
updateDragEl: config.updateDragEl,
|
|
4776
4819
|
getRootContainer: () => this.container,
|
|
4777
4820
|
getRenderDocument: () => this.renderer.getDocument(),
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.7.
|
|
2
|
+
"version": "1.7.14-beta.0",
|
|
3
3
|
"name": "@tmagic/stage",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"typescript": "^6.0.3",
|
|
47
|
-
"@tmagic/core": "1.7.
|
|
47
|
+
"@tmagic/core": "1.7.14-beta.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependenciesMeta": {
|
|
50
50
|
"typescript": {
|
package/src/ActionManager.ts
CHANGED
|
@@ -42,6 +42,7 @@ import StageMultiDragResize from './StageMultiDragResize';
|
|
|
42
42
|
import type {
|
|
43
43
|
ActionManagerConfig,
|
|
44
44
|
ActionManagerEvents,
|
|
45
|
+
CanDropIn,
|
|
45
46
|
CanSelect,
|
|
46
47
|
CustomizeMoveableOptions,
|
|
47
48
|
CustomizeMoveableOptionsCallbackConfig,
|
|
@@ -88,8 +89,12 @@ export default class ActionManager extends EventEmitter {
|
|
|
88
89
|
private getElementsFromPoint: GetElementsFromPoint;
|
|
89
90
|
private canSelect: CanSelect;
|
|
90
91
|
private isContainer?: IsContainer;
|
|
92
|
+
/** 见 ActionManagerConfig.canDropIn */
|
|
93
|
+
private canDropIn?: CanDropIn;
|
|
91
94
|
private getRenderDocument: GetRenderDocument;
|
|
92
95
|
private disabledMultiSelect = false;
|
|
96
|
+
/** 始终启用多选模式(无需按住 Ctrl/Meta),优先级低于 disabledMultiSelect */
|
|
97
|
+
private alwaysMultiSelect = false;
|
|
93
98
|
private config: ActionManagerConfig;
|
|
94
99
|
|
|
95
100
|
private mouseMoveHandler = throttle((event: MouseEvent): void => {
|
|
@@ -120,16 +125,21 @@ export default class ActionManager extends EventEmitter {
|
|
|
120
125
|
this.containerHighlightDuration = config.containerHighlightDuration || defaultContainerHighlightDuration;
|
|
121
126
|
this.containerHighlightType = config.containerHighlightType;
|
|
122
127
|
this.disabledMultiSelect = config.disabledMultiSelect ?? false;
|
|
128
|
+
this.alwaysMultiSelect = config.alwaysMultiSelect ?? false;
|
|
123
129
|
this.getTargetElement = config.getTargetElement;
|
|
124
130
|
this.getElementsFromPoint = config.getElementsFromPoint;
|
|
125
131
|
this.canSelect = config.canSelect || ((el: HTMLElement) => Boolean(getIdFromEl()(el)));
|
|
126
132
|
this.getRenderDocument = config.getRenderDocument;
|
|
127
133
|
this.isContainer = config.isContainer;
|
|
134
|
+
this.canDropIn = config.canDropIn;
|
|
128
135
|
|
|
129
136
|
this.dr = this.createDr(config);
|
|
130
137
|
|
|
131
138
|
if (!this.disabledMultiSelect) {
|
|
132
139
|
this.multiDr = this.createMultiDr(config);
|
|
140
|
+
if (this.alwaysMultiSelect) {
|
|
141
|
+
this.isMultiSelectStatus = true;
|
|
142
|
+
}
|
|
133
143
|
}
|
|
134
144
|
|
|
135
145
|
this.highlightLayer = new StageHighlight({
|
|
@@ -144,6 +154,7 @@ export default class ActionManager extends EventEmitter {
|
|
|
144
154
|
|
|
145
155
|
public disableMultiSelect() {
|
|
146
156
|
this.disabledMultiSelect = true;
|
|
157
|
+
this.isMultiSelectStatus = false;
|
|
147
158
|
if (this.multiDr) {
|
|
148
159
|
this.multiDr.destroy();
|
|
149
160
|
this.multiDr = null;
|
|
@@ -156,6 +167,20 @@ export default class ActionManager extends EventEmitter {
|
|
|
156
167
|
if (!this.multiDr) {
|
|
157
168
|
this.multiDr = this.createMultiDr(this.config);
|
|
158
169
|
}
|
|
170
|
+
|
|
171
|
+
if (this.alwaysMultiSelect) {
|
|
172
|
+
this.isMultiSelectStatus = true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta),
|
|
178
|
+
* 当 `disabledMultiSelect` 为 true 时本方法不会启用多选。
|
|
179
|
+
*/
|
|
180
|
+
public setAlwaysMultiSelect(value: boolean) {
|
|
181
|
+
this.alwaysMultiSelect = value;
|
|
182
|
+
if (this.disabledMultiSelect) return;
|
|
183
|
+
this.isMultiSelectStatus = value;
|
|
159
184
|
}
|
|
160
185
|
|
|
161
186
|
/**
|
|
@@ -371,14 +396,28 @@ export default class ActionManager extends EventEmitter {
|
|
|
371
396
|
if (!doc) return;
|
|
372
397
|
|
|
373
398
|
const els = this.getElementsFromPoint(event);
|
|
399
|
+
// 取出源元素的节点 id 列表(多选拖动时为多个;从组件列表拖入时为空数组)
|
|
400
|
+
const sourceIds: Id[] = excludeElList
|
|
401
|
+
.map((el) => (el instanceof HTMLElement ? getIdFromEl()(el) : undefined))
|
|
402
|
+
.filter((id): id is string => Boolean(id));
|
|
374
403
|
|
|
375
404
|
for (const el of els) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
405
|
+
const targetId = getIdFromEl()(el);
|
|
406
|
+
if (!targetId?.startsWith(GHOST_EL_ID_PREFIX) && (await this.isContainer?.(el)) && !excludeElList.includes(el)) {
|
|
407
|
+
// 用户配置的钩子可以:
|
|
408
|
+
// - 返回 false 阻止某些源拖入命中的容器(例如禁止 button 拖入 list)
|
|
409
|
+
// - 返回 Id 将拖入目标重定向到另一个容器(例如把命中的 list 重定向到其内层的 list-content)
|
|
410
|
+
let highlightEl: HTMLElement = el;
|
|
411
|
+
if (targetId && this.canDropIn) {
|
|
412
|
+
const result = this.canDropIn(sourceIds, targetId);
|
|
413
|
+
if (result === false) continue;
|
|
414
|
+
if (typeof result === 'string' || typeof result === 'number') {
|
|
415
|
+
const redirectedEl = this.getTargetElement(result);
|
|
416
|
+
if (!redirectedEl) continue;
|
|
417
|
+
highlightEl = redirectedEl;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
addClassName(highlightEl, doc, this.containerHighlightClassName);
|
|
382
421
|
break;
|
|
383
422
|
}
|
|
384
423
|
}
|
|
@@ -615,14 +654,14 @@ export default class ActionManager extends EventEmitter {
|
|
|
615
654
|
});
|
|
616
655
|
// ctrl+tab切到其他窗口,需要将多选状态置为false
|
|
617
656
|
KeyController.global.on('blur', () => {
|
|
618
|
-
if (!this.disabledMultiSelect) {
|
|
657
|
+
if (!this.disabledMultiSelect && !this.alwaysMultiSelect) {
|
|
619
658
|
this.isMultiSelectStatus = false;
|
|
620
659
|
}
|
|
621
660
|
this.isAltKeydown = false;
|
|
622
661
|
});
|
|
623
662
|
KeyController.global.keyup(ctrl, (e) => {
|
|
624
663
|
e.inputEvent.preventDefault();
|
|
625
|
-
if (!this.disabledMultiSelect) {
|
|
664
|
+
if (!this.disabledMultiSelect && !this.alwaysMultiSelect) {
|
|
626
665
|
this.isMultiSelectStatus = false;
|
|
627
666
|
}
|
|
628
667
|
});
|
package/src/StageCore.ts
CHANGED
|
@@ -269,6 +269,14 @@ export default class StageCore extends EventEmitter {
|
|
|
269
269
|
this.actionManager?.enableMultiSelect();
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
+
/**
|
|
273
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta)。
|
|
274
|
+
* 当多选被 `disabledMultiSelect` 禁用时,本方法不会启用多选。
|
|
275
|
+
*/
|
|
276
|
+
public setAlwaysMultiSelect(value: boolean) {
|
|
277
|
+
this.actionManager?.setAlwaysMultiSelect(value);
|
|
278
|
+
}
|
|
279
|
+
|
|
272
280
|
public reloadIframe(url: string) {
|
|
273
281
|
this.renderer?.reloadIframe(url);
|
|
274
282
|
}
|
|
@@ -346,8 +354,10 @@ export default class StageCore extends EventEmitter {
|
|
|
346
354
|
container: this.mask!.content,
|
|
347
355
|
disabledDragStart: config.disabledDragStart,
|
|
348
356
|
disabledMultiSelect: config.disabledMultiSelect,
|
|
357
|
+
alwaysMultiSelect: config.alwaysMultiSelect,
|
|
349
358
|
canSelect: config.canSelect,
|
|
350
359
|
isContainer: config.isContainer,
|
|
360
|
+
canDropIn: config.canDropIn,
|
|
351
361
|
updateDragEl: config.updateDragEl,
|
|
352
362
|
getRootContainer: () => this.container,
|
|
353
363
|
getRenderDocument: () => this.renderer!.getDocument(),
|
package/src/types.ts
CHANGED
|
@@ -30,6 +30,18 @@ export type TargetElement = HTMLElement | SVGElement;
|
|
|
30
30
|
|
|
31
31
|
export type CanSelect = (el: HTMLElement, event: MouseEvent, stop: () => boolean) => boolean | Promise<boolean>;
|
|
32
32
|
export type IsContainer = (el: HTMLElement) => boolean | Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* 判断当前正在拖动的源是否可以拖入目标容器(用于画布上拖入组件时的容器高亮命中)
|
|
35
|
+
* @param sourceIds 当前正在拖动的源节点 id 列表
|
|
36
|
+
* - 在画布上拖动已有组件时:为被拖动的组件 id(多选拖动时为多个)
|
|
37
|
+
* - 从组件列表拖入新组件时:为空数组(此时尚无 id,可仅依据 targetId 判断)
|
|
38
|
+
* @param targetId 已通过 isContainer 命中的候选容器节点 id
|
|
39
|
+
* @returns
|
|
40
|
+
* - `false`:阻止该容器被视为合法拖入目标(不会被高亮命中)
|
|
41
|
+
* - `Id`(string | number):将拖入目标重定向到该 id 对应的节点
|
|
42
|
+
* - 其他(`true` / `void` / `undefined`):按命中的 targetId 正常拖入
|
|
43
|
+
*/
|
|
44
|
+
export type CanDropIn = (sourceIds: Id[], targetId: Id) => Id | boolean | void;
|
|
33
45
|
export type CustomizeRender = (renderer: StageCore) => Promise<HTMLElement | void> | HTMLElement | void;
|
|
34
46
|
|
|
35
47
|
export type CustomizeMoveableOptionsFunction = (config: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions;
|
|
@@ -54,6 +66,11 @@ export interface StageCoreConfig {
|
|
|
54
66
|
zoom?: number;
|
|
55
67
|
canSelect?: CanSelect;
|
|
56
68
|
isContainer?: IsContainer;
|
|
69
|
+
/**
|
|
70
|
+
* 画布上拖动组件时,对已通过 isContainer 命中的候选容器进行二次过滤,
|
|
71
|
+
* 用于实现"某些源不允许拖入某些容器内部"的场景。返回 false 时阻止该容器被高亮命中
|
|
72
|
+
*/
|
|
73
|
+
canDropIn?: CanDropIn;
|
|
57
74
|
containerHighlightClassName?: string;
|
|
58
75
|
containerHighlightDuration?: number;
|
|
59
76
|
containerHighlightType?: ContainerHighlightType;
|
|
@@ -67,6 +84,11 @@ export interface StageCoreConfig {
|
|
|
67
84
|
renderType?: RenderType;
|
|
68
85
|
guidesOptions?: Partial<GuidesOptions>;
|
|
69
86
|
disabledMultiSelect?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* 始终启用多选模式(无需按住 Ctrl/Meta),默认 false。
|
|
89
|
+
* 当 `disabledMultiSelect` 为 true 时,本配置失效。
|
|
90
|
+
*/
|
|
91
|
+
alwaysMultiSelect?: boolean;
|
|
70
92
|
disabledRule?: boolean;
|
|
71
93
|
}
|
|
72
94
|
|
|
@@ -78,8 +100,15 @@ export interface ActionManagerConfig {
|
|
|
78
100
|
moveableOptions?: CustomizeMoveableOptions;
|
|
79
101
|
disabledDragStart?: boolean;
|
|
80
102
|
disabledMultiSelect?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* 始终启用多选模式(无需按住 Ctrl/Meta),默认 false。
|
|
105
|
+
* 当 `disabledMultiSelect` 为 true 时,本配置失效。
|
|
106
|
+
*/
|
|
107
|
+
alwaysMultiSelect?: boolean;
|
|
81
108
|
canSelect?: CanSelect;
|
|
82
109
|
isContainer?: IsContainer;
|
|
110
|
+
/** 见 StageCoreConfig.canDropIn */
|
|
111
|
+
canDropIn?: CanDropIn;
|
|
83
112
|
getRootContainer: GetRootContainer;
|
|
84
113
|
getRenderDocument: GetRenderDocument;
|
|
85
114
|
updateDragEl?: UpdateDragEl;
|
package/types/index.d.ts
CHANGED
|
@@ -160,6 +160,18 @@ declare class DragResizeHelper {
|
|
|
160
160
|
type TargetElement = HTMLElement | SVGElement;
|
|
161
161
|
type CanSelect = (el: HTMLElement, event: MouseEvent, stop: () => boolean) => boolean | Promise<boolean>;
|
|
162
162
|
type IsContainer = (el: HTMLElement) => boolean | Promise<boolean>;
|
|
163
|
+
/**
|
|
164
|
+
* 判断当前正在拖动的源是否可以拖入目标容器(用于画布上拖入组件时的容器高亮命中)
|
|
165
|
+
* @param sourceIds 当前正在拖动的源节点 id 列表
|
|
166
|
+
* - 在画布上拖动已有组件时:为被拖动的组件 id(多选拖动时为多个)
|
|
167
|
+
* - 从组件列表拖入新组件时:为空数组(此时尚无 id,可仅依据 targetId 判断)
|
|
168
|
+
* @param targetId 已通过 isContainer 命中的候选容器节点 id
|
|
169
|
+
* @returns
|
|
170
|
+
* - `false`:阻止该容器被视为合法拖入目标(不会被高亮命中)
|
|
171
|
+
* - `Id`(string | number):将拖入目标重定向到该 id 对应的节点
|
|
172
|
+
* - 其他(`true` / `void` / `undefined`):按命中的 targetId 正常拖入
|
|
173
|
+
*/
|
|
174
|
+
type CanDropIn = (sourceIds: Id[], targetId: Id) => Id | boolean | void;
|
|
163
175
|
type CustomizeRender = (renderer: StageCore) => Promise<HTMLElement | void> | HTMLElement | void;
|
|
164
176
|
type CustomizeMoveableOptionsFunction = (config: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions;
|
|
165
177
|
/** 业务方自定义的moveableOptions,可以是配置,也可以是回调函数 */
|
|
@@ -180,6 +192,11 @@ interface StageCoreConfig {
|
|
|
180
192
|
zoom?: number;
|
|
181
193
|
canSelect?: CanSelect;
|
|
182
194
|
isContainer?: IsContainer;
|
|
195
|
+
/**
|
|
196
|
+
* 画布上拖动组件时,对已通过 isContainer 命中的候选容器进行二次过滤,
|
|
197
|
+
* 用于实现"某些源不允许拖入某些容器内部"的场景。返回 false 时阻止该容器被高亮命中
|
|
198
|
+
*/
|
|
199
|
+
canDropIn?: CanDropIn;
|
|
183
200
|
containerHighlightClassName?: string;
|
|
184
201
|
containerHighlightDuration?: number;
|
|
185
202
|
containerHighlightType?: ContainerHighlightType;
|
|
@@ -193,6 +210,11 @@ interface StageCoreConfig {
|
|
|
193
210
|
renderType?: RenderType;
|
|
194
211
|
guidesOptions?: Partial<GuidesOptions$1>;
|
|
195
212
|
disabledMultiSelect?: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* 始终启用多选模式(无需按住 Ctrl/Meta),默认 false。
|
|
215
|
+
* 当 `disabledMultiSelect` 为 true 时,本配置失效。
|
|
216
|
+
*/
|
|
217
|
+
alwaysMultiSelect?: boolean;
|
|
196
218
|
disabledRule?: boolean;
|
|
197
219
|
}
|
|
198
220
|
interface ActionManagerConfig {
|
|
@@ -203,8 +225,15 @@ interface ActionManagerConfig {
|
|
|
203
225
|
moveableOptions?: CustomizeMoveableOptions;
|
|
204
226
|
disabledDragStart?: boolean;
|
|
205
227
|
disabledMultiSelect?: boolean;
|
|
228
|
+
/**
|
|
229
|
+
* 始终启用多选模式(无需按住 Ctrl/Meta),默认 false。
|
|
230
|
+
* 当 `disabledMultiSelect` 为 true 时,本配置失效。
|
|
231
|
+
*/
|
|
232
|
+
alwaysMultiSelect?: boolean;
|
|
206
233
|
canSelect?: CanSelect;
|
|
207
234
|
isContainer?: IsContainer;
|
|
235
|
+
/** 见 StageCoreConfig.canDropIn */
|
|
236
|
+
canDropIn?: CanDropIn;
|
|
208
237
|
getRootContainer: GetRootContainer;
|
|
209
238
|
getRenderDocument: GetRenderDocument;
|
|
210
239
|
updateDragEl?: UpdateDragEl;
|
|
@@ -433,13 +462,22 @@ declare class ActionManager extends EventEmitter$1 {
|
|
|
433
462
|
private getElementsFromPoint;
|
|
434
463
|
private canSelect;
|
|
435
464
|
private isContainer?;
|
|
465
|
+
/** 见 ActionManagerConfig.canDropIn */
|
|
466
|
+
private canDropIn?;
|
|
436
467
|
private getRenderDocument;
|
|
437
468
|
private disabledMultiSelect;
|
|
469
|
+
/** 始终启用多选模式(无需按住 Ctrl/Meta),优先级低于 disabledMultiSelect */
|
|
470
|
+
private alwaysMultiSelect;
|
|
438
471
|
private config;
|
|
439
472
|
private mouseMoveHandler;
|
|
440
473
|
constructor(config: ActionManagerConfig);
|
|
441
474
|
disableMultiSelect(): void;
|
|
442
475
|
enableMultiSelect(): void;
|
|
476
|
+
/**
|
|
477
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta),
|
|
478
|
+
* 当 `disabledMultiSelect` 为 true 时本方法不会启用多选。
|
|
479
|
+
*/
|
|
480
|
+
setAlwaysMultiSelect(value: boolean): void;
|
|
443
481
|
/**
|
|
444
482
|
* 设置水平/垂直参考线
|
|
445
483
|
* @param type 参考线类型
|
|
@@ -814,6 +852,11 @@ declare class StageCore extends EventEmitter {
|
|
|
814
852
|
getDragStatus(): _$_tmagic_editor0.StageDragStatus | undefined;
|
|
815
853
|
disableMultiSelect(): void;
|
|
816
854
|
enableMultiSelect(): void;
|
|
855
|
+
/**
|
|
856
|
+
* 设置是否始终启用多选模式(无需按住 Ctrl/Meta)。
|
|
857
|
+
* 当多选被 `disabledMultiSelect` 禁用时,本方法不会启用多选。
|
|
858
|
+
*/
|
|
859
|
+
setAlwaysMultiSelect(value: boolean): void;
|
|
817
860
|
reloadIframe(url: string): void;
|
|
818
861
|
/**
|
|
819
862
|
* 将指定id的dom元素生成为图片
|
|
@@ -1060,4 +1103,4 @@ declare const _default: (handler: (type: AbleActionEventType) => void, customize
|
|
|
1060
1103
|
render(moveable: MoveableManagerInterface<any, any>, React: Renderer): any;
|
|
1061
1104
|
};
|
|
1062
1105
|
//#endregion
|
|
1063
|
-
export { AbleActionEventType, AbleCustomizedButton, ActionManagerConfig, ActionManagerEvents, CONTAINER_HIGHLIGHT_CLASS_NAME, CanSelect, ContainerHighlightType, CoreEvents, CustomizeMoveableOptions, CustomizeMoveableOptionsCallbackConfig, CustomizeMoveableOptionsFunction, CustomizeRender, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, DelayedMarkContainer, DrEvents, DragResizeHelperConfig, GHOST_EL_ID_PREFIX, GetElementsFromPoint, GetRenderDocument, GetRootContainer, GetTargetElement, GuidesEventData, type GuidesOptions, GuidesType, HIGHLIGHT_EL_ID_PREFIX, IsContainer, Magic, MarkContainerEnd, MaskEvents, Mode, MouseButton, _default as MoveableActionsAble, MoveableOptionsManagerConfig, MultiDrEvents, Offset, PAGE_CLASS, Point, Rect, RemoveData, RemoveEventData, RenderEvents, RenderType, RuleOptions, Runtime, RuntimeWindow, SELECTED_CLASS, SelectStatus, SortEventData, StageCoreConfig, StageDragResize, StageDragResizeConfig, StageDragStatus, StageHighlightConfig, StageMask, StageMaskConfig, StageMultiDragResizeConfig, StageRender, StageRenderConfig, TargetElement, TargetShadowConfig, UpdateData, UpdateDragEl, UpdateEventData, ZIndex, addSelectedClassName, StageCore as default, down, getAbsolutePosition, getBorderWidth, getMarginValue, getMode, getOffset, getScrollParent, getTargetElStyle, isAbsolute, isFixed, isFixedParent, isMoveableButton, isRelative, isStatic, removeSelectedClassName, up };
|
|
1106
|
+
export { AbleActionEventType, AbleCustomizedButton, ActionManagerConfig, ActionManagerEvents, CONTAINER_HIGHLIGHT_CLASS_NAME, CanDropIn, CanSelect, ContainerHighlightType, CoreEvents, CustomizeMoveableOptions, CustomizeMoveableOptionsCallbackConfig, CustomizeMoveableOptionsFunction, CustomizeRender, DEFAULT_ZOOM, DRAG_EL_ID_PREFIX, DelayedMarkContainer, DrEvents, DragResizeHelperConfig, GHOST_EL_ID_PREFIX, GetElementsFromPoint, GetRenderDocument, GetRootContainer, GetTargetElement, GuidesEventData, type GuidesOptions, GuidesType, HIGHLIGHT_EL_ID_PREFIX, IsContainer, Magic, MarkContainerEnd, MaskEvents, Mode, MouseButton, _default as MoveableActionsAble, MoveableOptionsManagerConfig, MultiDrEvents, Offset, PAGE_CLASS, Point, Rect, RemoveData, RemoveEventData, RenderEvents, RenderType, RuleOptions, Runtime, RuntimeWindow, SELECTED_CLASS, SelectStatus, SortEventData, StageCoreConfig, StageDragResize, StageDragResizeConfig, StageDragStatus, StageHighlightConfig, StageMask, StageMaskConfig, StageMultiDragResizeConfig, StageRender, StageRenderConfig, TargetElement, TargetShadowConfig, UpdateData, UpdateDragEl, UpdateEventData, ZIndex, addSelectedClassName, StageCore as default, down, getAbsolutePosition, getBorderWidth, getMarginValue, getMode, getOffset, getScrollParent, getTargetElStyle, isAbsolute, isFixed, isFixedParent, isMoveableButton, isRelative, isStatic, removeSelectedClassName, up };
|