@tmagic/editor 1.7.14-beta.2 → 1.8.0-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/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/services/editor.js +120 -32
- package/dist/es/style.css +15 -14
- package/dist/style.css +15 -14
- package/dist/tmagic-editor.umd.cjs +121 -33
- package/package.json +7 -7
- package/src/layouts/props-panel/FormPanel.vue +1 -1
- package/src/services/editor.ts +164 -41
- package/src/theme/props-panel.scss +20 -20
- package/src/type.ts +10 -0
- package/types/index.d.ts +44 -13
package/src/services/editor.ts
CHANGED
|
@@ -33,6 +33,7 @@ import type {
|
|
|
33
33
|
AddMNode,
|
|
34
34
|
AsyncHookPlugin,
|
|
35
35
|
AsyncMethodName,
|
|
36
|
+
DslOpOptions,
|
|
36
37
|
EditorEvents,
|
|
37
38
|
EditorNodeInfo,
|
|
38
39
|
HistoryOpType,
|
|
@@ -65,6 +66,25 @@ import type { HistoryOpContext } from '@editor/utils/editor-history';
|
|
|
65
66
|
import { applyHistoryAddOp, applyHistoryRemoveOp, applyHistoryUpdateOp } from '@editor/utils/editor-history';
|
|
66
67
|
import { beforePaste, getAddParent } from '@editor/utils/operator';
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* 经过 BaseService 的插件 / 中间件包装后,源方法的最后一个形参可能被注入为 dispatch 函数
|
|
71
|
+
* 当 options 形参位置被注入为函数(或为 null)时,将其归一为空对象,避免后续逻辑误读
|
|
72
|
+
*/
|
|
73
|
+
const safeOptions = <T extends object>(options: unknown): T => {
|
|
74
|
+
const empty = {};
|
|
75
|
+
if (!options || typeof options === 'function') return empty as T;
|
|
76
|
+
return options as T;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 经过 BaseService 的插件 / 中间件包装后,源方法的形参可能被注入为 dispatch 函数
|
|
81
|
+
* 当 parent 形参位置被注入为函数(或为空值)时,归一为 null,由调用方继续走默认 parent 逻辑
|
|
82
|
+
*/
|
|
83
|
+
const safeParent = (parent: unknown): MContainer | null => {
|
|
84
|
+
if (!parent || typeof parent === 'function') return null;
|
|
85
|
+
return parent as MContainer;
|
|
86
|
+
};
|
|
87
|
+
|
|
68
88
|
class Editor extends BaseService {
|
|
69
89
|
public state: StoreState = reactive({
|
|
70
90
|
root: null,
|
|
@@ -172,6 +192,22 @@ class Editor extends BaseService {
|
|
|
172
192
|
return parent;
|
|
173
193
|
}
|
|
174
194
|
|
|
195
|
+
/**
|
|
196
|
+
* 判断给定节点是否位于非当前页面(即选中该节点将会引起当前页面切换)
|
|
197
|
+
* @param node 节点
|
|
198
|
+
* @returns true 表示该节点位于非当前页面
|
|
199
|
+
*/
|
|
200
|
+
public isOnDifferentPage(node: MNode): boolean {
|
|
201
|
+
const currentPageId = this.get('page')?.id;
|
|
202
|
+
if (currentPageId === undefined || currentPageId === null) return false;
|
|
203
|
+
if (isPage(node) || isPageFragment(node)) {
|
|
204
|
+
return `${node.id}` !== `${currentPageId}`;
|
|
205
|
+
}
|
|
206
|
+
const nodePage = this.getNodeInfo(node.id, false).page;
|
|
207
|
+
if (!nodePage) return false;
|
|
208
|
+
return `${nodePage.id}` !== `${currentPageId}`;
|
|
209
|
+
}
|
|
210
|
+
|
|
175
211
|
/**
|
|
176
212
|
* 只有容器拥有布局
|
|
177
213
|
*/
|
|
@@ -349,9 +385,19 @@ class Editor extends BaseService {
|
|
|
349
385
|
* 向指点容器添加组件节点
|
|
350
386
|
* @param addConfig 将要添加的组件节点配置
|
|
351
387
|
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
388
|
+
* @param options 可选配置
|
|
389
|
+
* @param options.doNotSelect 添加后是否不更新当前选中节点(默认 false,添加后会选中新增的节点)
|
|
390
|
+
* @param options.doNotSwitchPage 添加后是否不切换当前页面(默认 false;新增页面 / 跨页新增时为 true 会跳过会引发页面切换的选中操作)
|
|
352
391
|
* @returns 添加后的节点
|
|
353
392
|
*/
|
|
354
|
-
public async add(
|
|
393
|
+
public async add(
|
|
394
|
+
addNode: AddMNode | MNode[],
|
|
395
|
+
parent?: MContainer | null,
|
|
396
|
+
options?: DslOpOptions,
|
|
397
|
+
): Promise<MNode | MNode[]> {
|
|
398
|
+
const safeParentNode = safeParent(parent);
|
|
399
|
+
const { doNotSelect = false, doNotSwitchPage = false } = safeOptions<DslOpOptions>(options);
|
|
400
|
+
|
|
355
401
|
this.captureSelectionBeforeOp();
|
|
356
402
|
|
|
357
403
|
const stage = this.get('stage');
|
|
@@ -374,25 +420,34 @@ class Editor extends BaseService {
|
|
|
374
420
|
if ((isPage(node) || isPageFragment(node)) && root) {
|
|
375
421
|
return this.doAdd(node, root);
|
|
376
422
|
}
|
|
377
|
-
const parentNode =
|
|
423
|
+
const parentNode = safeParentNode ?? getAddParent(node);
|
|
378
424
|
if (!parentNode) throw new Error('未找到父元素');
|
|
379
425
|
return this.doAdd(node, parentNode);
|
|
380
426
|
}),
|
|
381
427
|
);
|
|
382
428
|
|
|
383
429
|
if (newNodes.length > 1) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
430
|
+
// 多选时只要任一新增节点位于非当前页面,触发的 multiSelect 就会引起页面切换
|
|
431
|
+
const wouldSwitchPage = newNodes.some((n) => this.isOnDifferentPage(n));
|
|
432
|
+
if (!doNotSelect && !(doNotSwitchPage && wouldSwitchPage)) {
|
|
433
|
+
const newNodeIds = newNodes.map((node) => node.id);
|
|
434
|
+
// 触发选中样式
|
|
435
|
+
stage?.multiSelect(newNodeIds);
|
|
436
|
+
await this.multiSelect(newNodeIds);
|
|
437
|
+
}
|
|
388
438
|
} else {
|
|
389
|
-
|
|
439
|
+
const wouldSwitchPage = this.isOnDifferentPage(newNodes[0]);
|
|
440
|
+
const skipSelect = doNotSelect || (doNotSwitchPage && wouldSwitchPage);
|
|
441
|
+
|
|
442
|
+
if (!skipSelect) {
|
|
443
|
+
await this.select(newNodes[0]);
|
|
444
|
+
}
|
|
390
445
|
|
|
391
446
|
if (isPage(newNodes[0])) {
|
|
392
447
|
this.state.pageLength += 1;
|
|
393
448
|
} else if (isPageFragment(newNodes[0])) {
|
|
394
449
|
this.state.pageFragmentLength += 1;
|
|
395
|
-
} else {
|
|
450
|
+
} else if (!skipSelect) {
|
|
396
451
|
// 新增页面,这个时候页面还有渲染出来,此时select会出错,在runtime-ready的时候回去select
|
|
397
452
|
stage?.select(newNodes[0].id);
|
|
398
453
|
}
|
|
@@ -421,7 +476,9 @@ class Editor extends BaseService {
|
|
|
421
476
|
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
422
477
|
}
|
|
423
478
|
|
|
424
|
-
public async doRemove(node: MNode): Promise<void> {
|
|
479
|
+
public async doRemove(node: MNode, options?: DslOpOptions): Promise<void> {
|
|
480
|
+
const { doNotSelect = false, doNotSwitchPage = false } = safeOptions<DslOpOptions>(options);
|
|
481
|
+
|
|
425
482
|
const root = this.get('root');
|
|
426
483
|
if (!root) throw new Error('root不能为空');
|
|
427
484
|
|
|
@@ -437,6 +494,22 @@ class Editor extends BaseService {
|
|
|
437
494
|
const stage = this.get('stage');
|
|
438
495
|
stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
439
496
|
|
|
497
|
+
// 始终清理已删除节点在 state 中的残留引用:
|
|
498
|
+
// - 即使后续会调用 selectDefault / select(parent) 覆盖,跳过这些调用(doNotSelect / doNotSwitchPage)时也不能让 state 持有已删除节点
|
|
499
|
+
const selectedNodes = this.get('nodes');
|
|
500
|
+
const removedSelectedIndex = selectedNodes.findIndex((n: MNode) => `${n.id}` === `${node.id}`);
|
|
501
|
+
if (removedSelectedIndex !== -1) {
|
|
502
|
+
const nextSelected = [...selectedNodes];
|
|
503
|
+
nextSelected.splice(removedSelectedIndex, 1);
|
|
504
|
+
this.set('nodes', nextSelected);
|
|
505
|
+
}
|
|
506
|
+
if (isPage(node) || isPageFragment(node)) {
|
|
507
|
+
const currentPage = this.get('page');
|
|
508
|
+
if (currentPage && `${currentPage.id}` === `${node.id}`) {
|
|
509
|
+
this.set('page', null);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
440
513
|
const selectDefault = async (pages: MNode[]) => {
|
|
441
514
|
if (pages[0]) {
|
|
442
515
|
await this.select(pages[0]);
|
|
@@ -453,14 +526,21 @@ class Editor extends BaseService {
|
|
|
453
526
|
if (isPage(node)) {
|
|
454
527
|
this.state.pageLength -= 1;
|
|
455
528
|
|
|
456
|
-
|
|
529
|
+
// 删除页面后默认会切到首个剩余页面(selectDefault),doNotSwitchPage 时跳过这次自动切换
|
|
530
|
+
if (!doNotSelect && !doNotSwitchPage) {
|
|
531
|
+
await selectDefault(rootItems);
|
|
532
|
+
}
|
|
457
533
|
} else if (isPageFragment(node)) {
|
|
458
534
|
this.state.pageFragmentLength -= 1;
|
|
459
535
|
|
|
460
|
-
|
|
536
|
+
if (!doNotSelect && !doNotSwitchPage) {
|
|
537
|
+
await selectDefault(rootItems);
|
|
538
|
+
}
|
|
461
539
|
} else {
|
|
462
|
-
|
|
463
|
-
|
|
540
|
+
if (!doNotSelect) {
|
|
541
|
+
await this.select(parent);
|
|
542
|
+
stage?.select(parent.id);
|
|
543
|
+
}
|
|
464
544
|
|
|
465
545
|
this.addModifiedNodeId(parent.id);
|
|
466
546
|
}
|
|
@@ -473,9 +553,14 @@ class Editor extends BaseService {
|
|
|
473
553
|
|
|
474
554
|
/**
|
|
475
555
|
* 删除组件
|
|
476
|
-
* @param {Object} node
|
|
556
|
+
* @param {Object} node 要删除的节点或节点集合
|
|
557
|
+
* @param options 可选配置
|
|
558
|
+
* @param options.doNotSelect 删除后是否不更新当前选中节点(默认 false,删除后会选中父节点或首个页面)
|
|
559
|
+
* @param options.doNotSwitchPage 删除后是否不切换当前页面(默认 false;删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
|
|
477
560
|
*/
|
|
478
|
-
public async remove(nodeOrNodeList: MNode | MNode[]): Promise<void> {
|
|
561
|
+
public async remove(nodeOrNodeList: MNode | MNode[], options?: DslOpOptions): Promise<void> {
|
|
562
|
+
const { doNotSelect = false, doNotSwitchPage = false } = safeOptions<DslOpOptions>(options);
|
|
563
|
+
|
|
479
564
|
this.captureSelectionBeforeOp();
|
|
480
565
|
|
|
481
566
|
const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
|
|
@@ -499,7 +584,7 @@ class Editor extends BaseService {
|
|
|
499
584
|
}
|
|
500
585
|
}
|
|
501
586
|
|
|
502
|
-
await Promise.all(nodes.map((node) => this.doRemove(node)));
|
|
587
|
+
await Promise.all(nodes.map((node) => this.doRemove(node, { doNotSelect, doNotSwitchPage })));
|
|
503
588
|
|
|
504
589
|
if (removedItems.length > 0 && pageForOp) {
|
|
505
590
|
this.pushOpHistory('remove', { removedItems }, pageForOp);
|
|
@@ -510,10 +595,7 @@ class Editor extends BaseService {
|
|
|
510
595
|
|
|
511
596
|
public async doUpdate(
|
|
512
597
|
config: MNode,
|
|
513
|
-
{
|
|
514
|
-
changeRecords = [],
|
|
515
|
-
selectedAfterUpdate = true,
|
|
516
|
-
}: { changeRecords?: ChangeRecord[]; selectedAfterUpdate?: boolean } = {},
|
|
598
|
+
{ changeRecords = [] }: { changeRecords?: ChangeRecord[] } = {},
|
|
517
599
|
): Promise<{ newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }> {
|
|
518
600
|
const root = this.get('root');
|
|
519
601
|
if (!root) throw new Error('root为空');
|
|
@@ -557,16 +639,20 @@ class Editor extends BaseService {
|
|
|
557
639
|
|
|
558
640
|
parentNodeItems[index] = newConfig;
|
|
559
641
|
|
|
560
|
-
//
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
this.set('nodes', [...
|
|
642
|
+
// 当被更新节点正好在当前选中列表中时,必须同步引用,否则 state 会持有已被替换的旧节点
|
|
643
|
+
const selectedNodes = this.get('nodes');
|
|
644
|
+
const targetIndex = selectedNodes.findIndex((nodeItem: MNode) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
645
|
+
if (targetIndex !== -1) {
|
|
646
|
+
selectedNodes.splice(targetIndex, 1, newConfig);
|
|
647
|
+
this.set('nodes', [...selectedNodes]);
|
|
566
648
|
}
|
|
567
649
|
|
|
650
|
+
// 只有被更新节点正好是当前选中页面时才同步 state.page,避免「更新非当前页」误将编辑器切到该页
|
|
568
651
|
if (isPage(newConfig) || isPageFragment(newConfig)) {
|
|
569
|
-
this.
|
|
652
|
+
const currentPage = this.get('page');
|
|
653
|
+
if (currentPage && `${currentPage.id}` === `${newConfig.id}`) {
|
|
654
|
+
this.set('page', newConfig as MPage | MPageFragment);
|
|
655
|
+
}
|
|
570
656
|
}
|
|
571
657
|
|
|
572
658
|
this.addModifiedNodeId(newConfig.id);
|
|
@@ -586,7 +672,7 @@ class Editor extends BaseService {
|
|
|
586
672
|
*/
|
|
587
673
|
public async update(
|
|
588
674
|
config: MNode | MNode[],
|
|
589
|
-
data: { changeRecords?: ChangeRecord[]
|
|
675
|
+
data: { changeRecords?: ChangeRecord[] } = {},
|
|
590
676
|
): Promise<MNode | MNode[]> {
|
|
591
677
|
this.captureSelectionBeforeOp();
|
|
592
678
|
|
|
@@ -620,9 +706,14 @@ class Editor extends BaseService {
|
|
|
620
706
|
* 将id为id1的组件移动到id为id2的组件位置上,例如:[1,2,3,4] -> sort(1,3) -> [2,1,3,4]
|
|
621
707
|
* @param id1 组件ID
|
|
622
708
|
* @param id2 组件ID
|
|
709
|
+
* @param options 可选配置
|
|
710
|
+
* @param options.doNotSelect 排序后是否不更新当前选中节点(默认 false)
|
|
711
|
+
* @param options.doNotSwitchPage 排序后是否不切换当前页面(排序只发生在同一父节点内,方法内为空操作;保留以与其它 DSL 操作 API 一致)
|
|
623
712
|
* @returns void
|
|
624
713
|
*/
|
|
625
|
-
public async sort(id1: Id, id2: Id): Promise<void> {
|
|
714
|
+
public async sort(id1: Id, id2: Id, options?: DslOpOptions): Promise<void> {
|
|
715
|
+
const { doNotSelect = false } = safeOptions<DslOpOptions>(options);
|
|
716
|
+
|
|
626
717
|
this.captureSelectionBeforeOp();
|
|
627
718
|
|
|
628
719
|
const root = this.get('root');
|
|
@@ -642,7 +733,9 @@ class Editor extends BaseService {
|
|
|
642
733
|
parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
|
|
643
734
|
|
|
644
735
|
await this.update(parent);
|
|
645
|
-
|
|
736
|
+
if (!doNotSelect) {
|
|
737
|
+
await this.select(node);
|
|
738
|
+
}
|
|
646
739
|
|
|
647
740
|
this.get('stage')?.update({
|
|
648
741
|
config: cloneDeep(node),
|
|
@@ -682,9 +775,19 @@ class Editor extends BaseService {
|
|
|
682
775
|
/**
|
|
683
776
|
* 从localStorage中获取节点,然后添加到当前容器中
|
|
684
777
|
* @param position 粘贴的坐标
|
|
778
|
+
* @param collectorOptions 可选的依赖收集器配置
|
|
779
|
+
* @param options 可选配置
|
|
780
|
+
* @param options.doNotSelect 粘贴后是否不更新当前选中节点(默认 false)
|
|
781
|
+
* @param options.doNotSwitchPage 粘贴后是否不切换当前页面(默认 false;跨页粘贴时为 true 会跳过页面切换)
|
|
685
782
|
* @returns 添加后的组件节点配置
|
|
686
783
|
*/
|
|
687
|
-
public async paste(
|
|
784
|
+
public async paste(
|
|
785
|
+
position: PastePosition = {},
|
|
786
|
+
collectorOptions?: TargetOptions,
|
|
787
|
+
options?: DslOpOptions,
|
|
788
|
+
): Promise<MNode | MNode[] | void> {
|
|
789
|
+
const { doNotSelect = false, doNotSwitchPage = false } = safeOptions<DslOpOptions>(options);
|
|
790
|
+
|
|
688
791
|
const config: MNode[] = storageService.getItem(COPY_STORAGE_KEY);
|
|
689
792
|
if (!Array.isArray(config)) return;
|
|
690
793
|
|
|
@@ -704,7 +807,7 @@ class Editor extends BaseService {
|
|
|
704
807
|
propsService.replaceRelateId(config, pasteConfigs, collectorOptions);
|
|
705
808
|
}
|
|
706
809
|
|
|
707
|
-
return this.add(pasteConfigs, parent);
|
|
810
|
+
return this.add(pasteConfigs, parent, { doNotSelect, doNotSwitchPage });
|
|
708
811
|
}
|
|
709
812
|
|
|
710
813
|
public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
|
|
@@ -732,9 +835,14 @@ class Editor extends BaseService {
|
|
|
732
835
|
/**
|
|
733
836
|
* 将指点节点设置居中
|
|
734
837
|
* @param config 组件节点配置
|
|
838
|
+
* @param options 可选配置
|
|
839
|
+
* @param options.doNotSelect 居中后是否不更新当前选中节点(默认 false)
|
|
840
|
+
* @param options.doNotSwitchPage 居中后是否不切换当前页面(居中只更新节点 style,方法内为空操作;保留以与其它 DSL 操作 API 一致)
|
|
735
841
|
* @returns 当前组件节点配置
|
|
736
842
|
*/
|
|
737
|
-
public async alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]> {
|
|
843
|
+
public async alignCenter(config: MNode | MNode[], options?: DslOpOptions): Promise<MNode | MNode[]> {
|
|
844
|
+
const { doNotSelect = false } = safeOptions<DslOpOptions>(options);
|
|
845
|
+
|
|
738
846
|
const nodes = Array.isArray(config) ? config : [config];
|
|
739
847
|
const stage = this.get('stage');
|
|
740
848
|
|
|
@@ -742,10 +850,12 @@ class Editor extends BaseService {
|
|
|
742
850
|
|
|
743
851
|
const newNode = await this.update(newNodes);
|
|
744
852
|
|
|
745
|
-
if (
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
853
|
+
if (!doNotSelect) {
|
|
854
|
+
if (newNodes.length > 1) {
|
|
855
|
+
await stage?.multiSelect(newNodes.map((node) => node.id));
|
|
856
|
+
} else {
|
|
857
|
+
await stage?.select(newNodes[0].id);
|
|
858
|
+
}
|
|
749
859
|
}
|
|
750
860
|
|
|
751
861
|
return newNode;
|
|
@@ -808,8 +918,13 @@ class Editor extends BaseService {
|
|
|
808
918
|
* 移动到指定容器中
|
|
809
919
|
* @param config 需要移动的节点
|
|
810
920
|
* @param targetId 容器ID
|
|
921
|
+
* @param options 可选配置
|
|
922
|
+
* @param options.doNotSelect 移动后是否不更新当前选中节点(默认 false)
|
|
923
|
+
* @param options.doNotSwitchPage 移动后是否不切换当前页面(默认 false;目标容器位于其它页面时为 true 会跳过自动选中以避免页面切换)
|
|
811
924
|
*/
|
|
812
|
-
public async moveToContainer(config: MNode, targetId: Id): Promise<MNode | undefined> {
|
|
925
|
+
public async moveToContainer(config: MNode, targetId: Id, options?: DslOpOptions): Promise<MNode | undefined> {
|
|
926
|
+
const { doNotSelect = false, doNotSwitchPage = false } = safeOptions<DslOpOptions>(options);
|
|
927
|
+
|
|
813
928
|
this.captureSelectionBeforeOp();
|
|
814
929
|
|
|
815
930
|
const root = this.get('root');
|
|
@@ -837,7 +952,13 @@ class Editor extends BaseService {
|
|
|
837
952
|
|
|
838
953
|
target.items.push(newConfig);
|
|
839
954
|
|
|
840
|
-
|
|
955
|
+
// 目标容器是否在非当前页面:选中目标会触发当前页面切换
|
|
956
|
+
const targetWouldSwitchPage = this.isOnDifferentPage(target);
|
|
957
|
+
const skipSelect = doNotSelect || (doNotSwitchPage && targetWouldSwitchPage);
|
|
958
|
+
|
|
959
|
+
if (!skipSelect) {
|
|
960
|
+
await stage.select(targetId);
|
|
961
|
+
}
|
|
841
962
|
|
|
842
963
|
const targetParent = this.getParentById(target.id);
|
|
843
964
|
await stage.update({
|
|
@@ -846,8 +967,10 @@ class Editor extends BaseService {
|
|
|
846
967
|
root: cloneDeep(root),
|
|
847
968
|
});
|
|
848
969
|
|
|
849
|
-
|
|
850
|
-
|
|
970
|
+
if (!skipSelect) {
|
|
971
|
+
await this.select(newConfig);
|
|
972
|
+
stage.select(newConfig.id);
|
|
973
|
+
}
|
|
851
974
|
|
|
852
975
|
this.addModifiedNodeId(target.id);
|
|
853
976
|
this.addModifiedNodeId(parent.id);
|
|
@@ -25,26 +25,6 @@
|
|
|
25
25
|
right: calc(15px + var(--props-style-panel-width));
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
.tmagic-design-form {
|
|
30
|
-
padding-right: 10px;
|
|
31
|
-
padding-left: 10px;
|
|
32
|
-
|
|
33
|
-
> .m-container-tab {
|
|
34
|
-
> .tmagic-design-tabs {
|
|
35
|
-
> .el-tabs__content {
|
|
36
|
-
padding-top: 55px;
|
|
37
|
-
}
|
|
38
|
-
> .el-tabs__header.is-top {
|
|
39
|
-
position: absolute;
|
|
40
|
-
top: 0;
|
|
41
|
-
width: 100%;
|
|
42
|
-
background: #fff;
|
|
43
|
-
z-index: 3;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
28
|
}
|
|
49
29
|
|
|
50
30
|
.m-editor-props-style-panel {
|
|
@@ -142,6 +122,26 @@
|
|
|
142
122
|
}
|
|
143
123
|
}
|
|
144
124
|
|
|
125
|
+
.m-editor-props-form-panel-form {
|
|
126
|
+
padding-right: 10px;
|
|
127
|
+
padding-left: 10px;
|
|
128
|
+
|
|
129
|
+
> .m-container-tab {
|
|
130
|
+
> .tmagic-design-tabs {
|
|
131
|
+
> .el-tabs__content {
|
|
132
|
+
padding-top: 55px;
|
|
133
|
+
}
|
|
134
|
+
> .el-tabs__header.is-top {
|
|
135
|
+
position: absolute;
|
|
136
|
+
top: 0;
|
|
137
|
+
width: 100%;
|
|
138
|
+
background: #fff;
|
|
139
|
+
z-index: 3;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
145
|
.m-editor-props-panel-popper {
|
|
146
146
|
&.small {
|
|
147
147
|
span,
|
package/src/type.ts
CHANGED
|
@@ -873,3 +873,13 @@ export const canUsePluginMethods = {
|
|
|
873
873
|
};
|
|
874
874
|
|
|
875
875
|
export type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* DSL 修改类操作的通用配置
|
|
879
|
+
* - doNotSelect: 操作后是否不要自动触发选中(不调用 this.select / this.multiSelect / stage.select / stage.multiSelect)
|
|
880
|
+
* - doNotSwitchPage: 操作若会引发当前页面切换(如新增 / 删除 / 跨页移动),是否跳过这次切换
|
|
881
|
+
*/
|
|
882
|
+
export type DslOpOptions = {
|
|
883
|
+
doNotSelect?: boolean;
|
|
884
|
+
doNotSwitchPage?: boolean;
|
|
885
|
+
};
|
package/types/index.d.ts
CHANGED
|
@@ -375,6 +375,12 @@ declare class Editor extends export_default {
|
|
|
375
375
|
* @returns 指点组件的父节点配置
|
|
376
376
|
*/
|
|
377
377
|
getParentById(id: Id, raw?: boolean): MContainer | null;
|
|
378
|
+
/**
|
|
379
|
+
* 判断给定节点是否位于非当前页面(即选中该节点将会引起当前页面切换)
|
|
380
|
+
* @param node 节点
|
|
381
|
+
* @returns true 表示该节点位于非当前页面
|
|
382
|
+
*/
|
|
383
|
+
isOnDifferentPage(node: MNode): boolean;
|
|
378
384
|
/**
|
|
379
385
|
* 只有容器拥有布局
|
|
380
386
|
*/
|
|
@@ -405,21 +411,25 @@ declare class Editor extends export_default {
|
|
|
405
411
|
* 向指点容器添加组件节点
|
|
406
412
|
* @param addConfig 将要添加的组件节点配置
|
|
407
413
|
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
414
|
+
* @param options 可选配置
|
|
415
|
+
* @param options.doNotSelect 添加后是否不更新当前选中节点(默认 false,添加后会选中新增的节点)
|
|
416
|
+
* @param options.doNotSwitchPage 添加后是否不切换当前页面(默认 false;新增页面 / 跨页新增时为 true 会跳过会引发页面切换的选中操作)
|
|
408
417
|
* @returns 添加后的节点
|
|
409
418
|
*/
|
|
410
|
-
add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]>;
|
|
411
|
-
doRemove(node: MNode): Promise<void>;
|
|
419
|
+
add(addNode: AddMNode | MNode[], parent?: MContainer | null, options?: DslOpOptions): Promise<MNode | MNode[]>;
|
|
420
|
+
doRemove(node: MNode, options?: DslOpOptions): Promise<void>;
|
|
412
421
|
/**
|
|
413
422
|
* 删除组件
|
|
414
|
-
* @param {Object} node
|
|
423
|
+
* @param {Object} node 要删除的节点或节点集合
|
|
424
|
+
* @param options 可选配置
|
|
425
|
+
* @param options.doNotSelect 删除后是否不更新当前选中节点(默认 false,删除后会选中父节点或首个页面)
|
|
426
|
+
* @param options.doNotSwitchPage 删除后是否不切换当前页面(默认 false;删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
|
|
415
427
|
*/
|
|
416
|
-
remove(nodeOrNodeList: MNode | MNode[]): Promise<void>;
|
|
428
|
+
remove(nodeOrNodeList: MNode | MNode[], options?: DslOpOptions): Promise<void>;
|
|
417
429
|
doUpdate(config: MNode, {
|
|
418
|
-
changeRecords
|
|
419
|
-
selectedAfterUpdate
|
|
430
|
+
changeRecords
|
|
420
431
|
}?: {
|
|
421
432
|
changeRecords?: ChangeRecord[];
|
|
422
|
-
selectedAfterUpdate?: boolean;
|
|
423
433
|
}): Promise<{
|
|
424
434
|
newNode: MNode;
|
|
425
435
|
oldNode: MNode;
|
|
@@ -433,15 +443,17 @@ declare class Editor extends export_default {
|
|
|
433
443
|
*/
|
|
434
444
|
update(config: MNode | MNode[], data?: {
|
|
435
445
|
changeRecords?: ChangeRecord[];
|
|
436
|
-
selectedAfterUpdate?: boolean;
|
|
437
446
|
}): Promise<MNode | MNode[]>;
|
|
438
447
|
/**
|
|
439
448
|
* 将id为id1的组件移动到id为id2的组件位置上,例如:[1,2,3,4] -> sort(1,3) -> [2,1,3,4]
|
|
440
449
|
* @param id1 组件ID
|
|
441
450
|
* @param id2 组件ID
|
|
451
|
+
* @param options 可选配置
|
|
452
|
+
* @param options.doNotSelect 排序后是否不更新当前选中节点(默认 false)
|
|
453
|
+
* @param options.doNotSwitchPage 排序后是否不切换当前页面(排序只发生在同一父节点内,方法内为空操作;保留以与其它 DSL 操作 API 一致)
|
|
442
454
|
* @returns void
|
|
443
455
|
*/
|
|
444
|
-
sort(id1: Id, id2: Id): Promise<void>;
|
|
456
|
+
sort(id1: Id, id2: Id, options?: DslOpOptions): Promise<void>;
|
|
445
457
|
/**
|
|
446
458
|
* 将组件节点配置存储到localStorage中
|
|
447
459
|
* @param config 组件节点配置
|
|
@@ -457,17 +469,24 @@ declare class Editor extends export_default {
|
|
|
457
469
|
/**
|
|
458
470
|
* 从localStorage中获取节点,然后添加到当前容器中
|
|
459
471
|
* @param position 粘贴的坐标
|
|
472
|
+
* @param collectorOptions 可选的依赖收集器配置
|
|
473
|
+
* @param options 可选配置
|
|
474
|
+
* @param options.doNotSelect 粘贴后是否不更新当前选中节点(默认 false)
|
|
475
|
+
* @param options.doNotSwitchPage 粘贴后是否不切换当前页面(默认 false;跨页粘贴时为 true 会跳过页面切换)
|
|
460
476
|
* @returns 添加后的组件节点配置
|
|
461
477
|
*/
|
|
462
|
-
paste(position?: PastePosition, collectorOptions?: TargetOptions): Promise<MNode | MNode[] | void>;
|
|
478
|
+
paste(position?: PastePosition, collectorOptions?: TargetOptions, options?: DslOpOptions): Promise<MNode | MNode[] | void>;
|
|
463
479
|
doPaste(config: MNode[], position?: PastePosition): Promise<MNode[]>;
|
|
464
480
|
doAlignCenter(config: MNode): Promise<MNode>;
|
|
465
481
|
/**
|
|
466
482
|
* 将指点节点设置居中
|
|
467
483
|
* @param config 组件节点配置
|
|
484
|
+
* @param options 可选配置
|
|
485
|
+
* @param options.doNotSelect 居中后是否不更新当前选中节点(默认 false)
|
|
486
|
+
* @param options.doNotSwitchPage 居中后是否不切换当前页面(居中只更新节点 style,方法内为空操作;保留以与其它 DSL 操作 API 一致)
|
|
468
487
|
* @returns 当前组件节点配置
|
|
469
488
|
*/
|
|
470
|
-
alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]>;
|
|
489
|
+
alignCenter(config: MNode | MNode[], options?: DslOpOptions): Promise<MNode | MNode[]>;
|
|
471
490
|
/**
|
|
472
491
|
* 移动当前选中节点位置
|
|
473
492
|
* @param offset 偏移量
|
|
@@ -477,8 +496,11 @@ declare class Editor extends export_default {
|
|
|
477
496
|
* 移动到指定容器中
|
|
478
497
|
* @param config 需要移动的节点
|
|
479
498
|
* @param targetId 容器ID
|
|
499
|
+
* @param options 可选配置
|
|
500
|
+
* @param options.doNotSelect 移动后是否不更新当前选中节点(默认 false)
|
|
501
|
+
* @param options.doNotSwitchPage 移动后是否不切换当前页面(默认 false;目标容器位于其它页面时为 true 会跳过自动选中以避免页面切换)
|
|
480
502
|
*/
|
|
481
|
-
moveToContainer(config: MNode, targetId: Id): Promise<MNode | undefined>;
|
|
503
|
+
moveToContainer(config: MNode, targetId: Id, options?: DslOpOptions): Promise<MNode | undefined>;
|
|
482
504
|
dragTo(config: MNode | MNode[], targetParent: MContainer, targetIndex: number): Promise<void>;
|
|
483
505
|
/**
|
|
484
506
|
* 撤销当前操作
|
|
@@ -1485,6 +1507,15 @@ declare const canUsePluginMethods: {
|
|
|
1485
1507
|
sync: never[];
|
|
1486
1508
|
};
|
|
1487
1509
|
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
1510
|
+
/**
|
|
1511
|
+
* DSL 修改类操作的通用配置
|
|
1512
|
+
* - doNotSelect: 操作后是否不要自动触发选中(不调用 this.select / this.multiSelect / stage.select / stage.multiSelect)
|
|
1513
|
+
* - doNotSwitchPage: 操作若会引发当前页面切换(如新增 / 删除 / 跨页移动),是否跳过这次切换
|
|
1514
|
+
*/
|
|
1515
|
+
type DslOpOptions = {
|
|
1516
|
+
doNotSelect?: boolean;
|
|
1517
|
+
doNotSwitchPage?: boolean;
|
|
1518
|
+
};
|
|
1488
1519
|
//#endregion
|
|
1489
1520
|
//#region temp/packages/form/src/schema.d.ts
|
|
1490
1521
|
interface ChangeRecord$1 {
|
|
@@ -4148,4 +4179,4 @@ declare const _default$36: {
|
|
|
4148
4179
|
install: (app: App, opt?: Partial<EditorInstallOptions | DesignPluginOptions | FormInstallOptions>) => void;
|
|
4149
4180
|
};
|
|
4150
4181
|
//#endregion
|
|
4151
|
-
export { AddMNode, AddPrefixToObject, AsyncAfterHook, AsyncBeforeHook, AsyncHookPlugin, AsyncMethodName, BeforeAdd, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CanDropInFunction, CanDropInScene, _default as CodeBlockEditor, _default$1 as CodeBlockList, _default$2 as CodeBlockListPanel, CodeBlockListPanelSlots, CodeBlockListSlots, CodeDeleteErrorType, CodeDslItem, CodeParamStatement, CodeRelation, _default$3 as CodeSelect, _default$4 as CodeSelectCol, CodeState, ColumnLayout, CombineInfo, ComponentGroup, ComponentGroupState, ComponentItem, _default$5 as ComponentListPanel, ComponentListPanelSlots, _default$6 as CondOpSelect, _default$7 as ContentMenu, CustomContentMenuFunction, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, _default$8 as DataSourceAddButton, _default$9 as DataSourceConfigPanel, _default$10 as DataSourceFieldSelect, _default$11 as DataSourceFields, _default$12 as DataSourceInput, DataSourceListSlots, _default$13 as DataSourceMethodSelect, _default$14 as DataSourceMethods, _default$15 as DataSourceMocks, _default$16 as DataSourceSelect, DatasourceTypeOption, DepTargetType, _default$17 as DisplayConds, DragClassification, DragType, EditorEvents, EditorInstallOptions, EditorNodeInfo, EditorSlots, EventBus, EventBusEvent, _default$18 as EventSelect, Fixed2Other, _default$19 as FloatingBox, FrameworkSlots, GetColumnWidth, GetConfig, H_GUIDE_LINE_STORAGE_KEY, HistoryOpType, HistoryState, _default$20 as Icon, IdleTask, IdleTaskEvents, IsExpandableFunction, KeyBindingCacheItem, KeyBindingCommand, KeyBindingItem, _default$21 as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, LayerNodeSlots, LayerNodeStatus, LayerOffset, _default$22 as LayerPanel, LayerPanelSlots, Layout, _default$23 as LayoutContainer, _default$23 as SplitView, ListState, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, MenuBarData, MenuButton, MenuComponent, MenuItem, type OnDrag, PROPS_PANEL_WIDTH_STORAGE_KEY, PageBarSortOptions, _default$24 as PageFragmentSelect, PartSortableOptions, PastePosition, PropsFormConfigFunction, _default$25 as PropsFormPanel, PropsFormValueFunction, _default$26 as PropsPanel, PropsPanelSlots, PropsState, RIGHT_COLUMN_WIDTH_STORAGE_KEY, _default$27 as Resizer, ScrollViewer, ScrollViewerEvent, ScrollViewerSlots, Services, SetColumnWidth, SideBarData, SideComponent, SideItem, SideItemKey, SidebarSlots, StageCore, StageOptions, StageOverlayState, StageRect, StageSlots, StepValue, StoreState, StoreStateKey, _default$28 as StyleSetter, SyncAfterHook, SyncBeforeHook, SyncHookPlugin, _default$29 as TMagicCodeEditor, _default$30 as TMagicEditor, _default$31 as ToolButton, _default$32 as Tree, _default$33 as TreeNode, TreeNodeData, UI_SELECT_MODE_EVENT_NAME, UiState, UndoRedo, V_GUIDE_LINE_STORAGE_KEY, WorkspaceSlots, advancedTabConfig, arrayOptions, beforePaste, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, _default$34 as codeBlockService, collectRelatedNodes, _default$35 as dataSourceService, debug, _default$36 as default, defaultIsExpandable, _default$37 as depService, designPlugin, displayTabConfig, editorNodeMergeCustomizer, _default$38 as editorService, eqOptions, error, eventTabConfig, _default$39 as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getDefaultConfig, getDisplayField, getEditorConfig, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, _default$40 as historyService, info, isIncludeDataSource, _default$41 as loadMonaco, log, moveItemsInContainer, numberOptions, _default$42 as propsService, resolveSelectedNode, serializeConfig, setChildrenLayout, setEditorConfig, setLayout, _default$43 as stageOverlayService, _default$44 as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, _default$45 as uiService, updateStatus, useCodeBlockEdit, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, warn };
|
|
4182
|
+
export { AddMNode, AddPrefixToObject, AsyncAfterHook, AsyncBeforeHook, AsyncHookPlugin, AsyncMethodName, BeforeAdd, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CanDropInFunction, CanDropInScene, _default as CodeBlockEditor, _default$1 as CodeBlockList, _default$2 as CodeBlockListPanel, CodeBlockListPanelSlots, CodeBlockListSlots, CodeDeleteErrorType, CodeDslItem, CodeParamStatement, CodeRelation, _default$3 as CodeSelect, _default$4 as CodeSelectCol, CodeState, ColumnLayout, CombineInfo, ComponentGroup, ComponentGroupState, ComponentItem, _default$5 as ComponentListPanel, ComponentListPanelSlots, _default$6 as CondOpSelect, _default$7 as ContentMenu, CustomContentMenuFunction, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, _default$8 as DataSourceAddButton, _default$9 as DataSourceConfigPanel, _default$10 as DataSourceFieldSelect, _default$11 as DataSourceFields, _default$12 as DataSourceInput, DataSourceListSlots, _default$13 as DataSourceMethodSelect, _default$14 as DataSourceMethods, _default$15 as DataSourceMocks, _default$16 as DataSourceSelect, DatasourceTypeOption, DepTargetType, _default$17 as DisplayConds, DragClassification, DragType, DslOpOptions, EditorEvents, EditorInstallOptions, EditorNodeInfo, EditorSlots, EventBus, EventBusEvent, _default$18 as EventSelect, Fixed2Other, _default$19 as FloatingBox, FrameworkSlots, GetColumnWidth, GetConfig, H_GUIDE_LINE_STORAGE_KEY, HistoryOpType, HistoryState, _default$20 as Icon, IdleTask, IdleTaskEvents, IsExpandableFunction, KeyBindingCacheItem, KeyBindingCommand, KeyBindingItem, _default$21 as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, LayerNodeSlots, LayerNodeStatus, LayerOffset, _default$22 as LayerPanel, LayerPanelSlots, Layout, _default$23 as LayoutContainer, _default$23 as SplitView, ListState, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, MenuBarData, MenuButton, MenuComponent, MenuItem, type OnDrag, PROPS_PANEL_WIDTH_STORAGE_KEY, PageBarSortOptions, _default$24 as PageFragmentSelect, PartSortableOptions, PastePosition, PropsFormConfigFunction, _default$25 as PropsFormPanel, PropsFormValueFunction, _default$26 as PropsPanel, PropsPanelSlots, PropsState, RIGHT_COLUMN_WIDTH_STORAGE_KEY, _default$27 as Resizer, ScrollViewer, ScrollViewerEvent, ScrollViewerSlots, Services, SetColumnWidth, SideBarData, SideComponent, SideItem, SideItemKey, SidebarSlots, StageCore, StageOptions, StageOverlayState, StageRect, StageSlots, StepValue, StoreState, StoreStateKey, _default$28 as StyleSetter, SyncAfterHook, SyncBeforeHook, SyncHookPlugin, _default$29 as TMagicCodeEditor, _default$30 as TMagicEditor, _default$31 as ToolButton, _default$32 as Tree, _default$33 as TreeNode, TreeNodeData, UI_SELECT_MODE_EVENT_NAME, UiState, UndoRedo, V_GUIDE_LINE_STORAGE_KEY, WorkspaceSlots, advancedTabConfig, arrayOptions, beforePaste, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, _default$34 as codeBlockService, collectRelatedNodes, _default$35 as dataSourceService, debug, _default$36 as default, defaultIsExpandable, _default$37 as depService, designPlugin, displayTabConfig, editorNodeMergeCustomizer, _default$38 as editorService, eqOptions, error, eventTabConfig, _default$39 as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getDefaultConfig, getDisplayField, getEditorConfig, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, _default$40 as historyService, info, isIncludeDataSource, _default$41 as loadMonaco, log, moveItemsInContainer, numberOptions, _default$42 as propsService, resolveSelectedNode, serializeConfig, setChildrenLayout, setEditorConfig, setLayout, _default$43 as stageOverlayService, _default$44 as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, _default$45 as uiService, updateStatus, useCodeBlockEdit, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, warn };
|