@tmagic/editor 1.1.0-beta.7 → 1.1.0-beta.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/dist/style.css +4 -0
- package/dist/tmagic-editor.mjs +84 -87
- package/dist/tmagic-editor.mjs.map +1 -1
- package/dist/tmagic-editor.umd.js +84 -86
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/package.json +7 -7
- package/src/components/Icon.vue +1 -1
- package/src/layouts/workspace/ViewerMenu.vue +4 -7
- package/src/layouts/workspace/Workspace.vue +1 -1
- package/src/services/editor.ts +64 -47
- package/src/theme/component-list-panel.scss +5 -0
- package/src/utils/editor.ts +17 -10
- package/src/utils/operator.ts +25 -72
- package/types/layouts/workspace/ViewerMenu.vue.d.ts +3 -3
- package/types/services/editor.d.ts +3 -8
- package/types/utils/editor.d.ts +4 -1
- package/types/utils/operator.d.ts +3 -20
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.1.0-beta.
|
|
2
|
+
"version": "1.1.0-beta.8",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"dist/*",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@babel/core": "^7.18.0",
|
|
47
47
|
"@element-plus/icons-vue": "^2.0.6",
|
|
48
|
-
"@tmagic/core": "1.1.0-beta.
|
|
49
|
-
"@tmagic/form": "1.1.0-beta.
|
|
50
|
-
"@tmagic/schema": "1.1.0-beta.
|
|
51
|
-
"@tmagic/stage": "1.1.0-beta.
|
|
52
|
-
"@tmagic/utils": "1.1.0-beta.
|
|
48
|
+
"@tmagic/core": "1.1.0-beta.8",
|
|
49
|
+
"@tmagic/form": "1.1.0-beta.8",
|
|
50
|
+
"@tmagic/schema": "1.1.0-beta.8",
|
|
51
|
+
"@tmagic/stage": "1.1.0-beta.8",
|
|
52
|
+
"@tmagic/utils": "1.1.0-beta.8",
|
|
53
53
|
"buffer": "^6.0.3",
|
|
54
54
|
"color": "^3.1.3",
|
|
55
55
|
"element-plus": "^2.2.6",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"vue": "^3.2.37"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"@tmagic/form": "1.1.0-beta.
|
|
65
|
+
"@tmagic/form": "1.1.0-beta.8",
|
|
66
66
|
"element-plus": "^2.2.6",
|
|
67
67
|
"monaco-editor": "^0.32.1",
|
|
68
68
|
"vue": "^3.2.37"
|
package/src/components/Icon.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-icon v-if="!icon"><edit></edit></el-icon>
|
|
3
|
-
<
|
|
3
|
+
<el-icon v-else-if="typeof icon === 'string' && icon.startsWith('http')"><img :src="icon" /></el-icon>
|
|
4
4
|
<i v-else-if="typeof icon === 'string'" :class="icon"></i>
|
|
5
5
|
<el-icon v-else><component :is="toRaw(icon)"></component></el-icon>
|
|
6
6
|
</template>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script lang="ts" setup>
|
|
6
|
-
import { computed, inject, markRaw,
|
|
6
|
+
import { computed, inject, markRaw, reactive, ref, watch } from 'vue';
|
|
7
7
|
import { Bottom, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
|
|
8
8
|
|
|
9
9
|
import { MNode, NodeType } from '@tmagic/schema';
|
|
@@ -133,11 +133,6 @@ const menuData = reactive<MenuItem[]>([
|
|
|
133
133
|
...stageContentMenu,
|
|
134
134
|
]);
|
|
135
135
|
|
|
136
|
-
onMounted(async () => {
|
|
137
|
-
const data = await storageService.getItem(COPY_STORAGE_KEY);
|
|
138
|
-
canPaste.value = data !== 'undefined' && !!data;
|
|
139
|
-
});
|
|
140
|
-
|
|
141
136
|
watch(
|
|
142
137
|
parent,
|
|
143
138
|
async () => {
|
|
@@ -152,8 +147,10 @@ watch(
|
|
|
152
147
|
{ immediate: true },
|
|
153
148
|
);
|
|
154
149
|
|
|
155
|
-
const show = (e: MouseEvent) => {
|
|
150
|
+
const show = async (e: MouseEvent) => {
|
|
156
151
|
menu.value?.show(e);
|
|
152
|
+
const data = await storageService.getItem(COPY_STORAGE_KEY);
|
|
153
|
+
canPaste.value = data !== 'undefined' && !!data;
|
|
157
154
|
};
|
|
158
155
|
|
|
159
156
|
defineExpose({ show });
|
|
@@ -72,7 +72,7 @@ export default defineComponent({
|
|
|
72
72
|
})
|
|
73
73
|
.keydown([ctrl, 'v'], (e) => {
|
|
74
74
|
e.inputEvent.preventDefault();
|
|
75
|
-
nodes.value && services?.editorService.paste();
|
|
75
|
+
nodes.value && services?.editorService.paste({ offsetX: 10, offsetY: 10 });
|
|
76
76
|
})
|
|
77
77
|
.keydown([ctrl, 'x'], (e) => {
|
|
78
78
|
e.inputEvent.preventDefault();
|
package/src/services/editor.ts
CHANGED
|
@@ -32,14 +32,16 @@ import {
|
|
|
32
32
|
change2Fixed,
|
|
33
33
|
COPY_STORAGE_KEY,
|
|
34
34
|
Fixed2Other,
|
|
35
|
+
fixNodePosition,
|
|
35
36
|
getInitPositionStyle,
|
|
36
37
|
getNodeIndex,
|
|
37
38
|
isFixed,
|
|
38
39
|
setLayout,
|
|
39
40
|
} from '../utils/editor';
|
|
40
|
-
import {
|
|
41
|
+
import { beforePaste, beforeRemove, getAddParent } from '../utils/operator';
|
|
41
42
|
|
|
42
43
|
import BaseService from './BaseService';
|
|
44
|
+
import propsService from './props';
|
|
43
45
|
|
|
44
46
|
class Editor extends BaseService {
|
|
45
47
|
public state: StoreState = reactive({
|
|
@@ -60,6 +62,7 @@ class Editor extends BaseService {
|
|
|
60
62
|
[
|
|
61
63
|
'getLayout',
|
|
62
64
|
'select',
|
|
65
|
+
'doAdd',
|
|
63
66
|
'add',
|
|
64
67
|
'remove',
|
|
65
68
|
'update',
|
|
@@ -281,34 +284,30 @@ class Editor extends BaseService {
|
|
|
281
284
|
this.set('nodes', nodes);
|
|
282
285
|
}
|
|
283
286
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
* @returns 添加后的节点
|
|
288
|
-
*/
|
|
289
|
-
public async multiAdd(configs: MNode[]): Promise<MNode[]> {
|
|
287
|
+
public async doAdd(node: MNode, parent: MContainer): Promise<MNode> {
|
|
288
|
+
const root = this.get<MApp>('root');
|
|
289
|
+
const curNode = this.get<MNode>('node');
|
|
290
290
|
const stage = this.get<StageCore | null>('stage');
|
|
291
|
-
const newNodes: MNode[] = await Promise.all(
|
|
292
|
-
configs.map(async (configItem: MNode): Promise<MNode> => {
|
|
293
|
-
// 新增元素到配置
|
|
294
|
-
const { parentNode, newNode, layout } = await beforeAdd(configItem as AddMNode);
|
|
295
|
-
// 将新增元素事件通知到stage以更新渲染
|
|
296
|
-
await notifyAddToStage(parentNode, newNode, layout);
|
|
297
|
-
return newNode;
|
|
298
|
-
}),
|
|
299
|
-
);
|
|
300
|
-
const newNodeIds: Id[] = newNodes.map((node) => node.id);
|
|
301
291
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
292
|
+
if ((parent?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
|
|
293
|
+
throw new Error('app下不能添加组件');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const layout = await this.getLayout(toRaw(parent), node as MNode);
|
|
297
|
+
node.style = getInitPositionStyle(node.style, layout);
|
|
298
|
+
|
|
299
|
+
await stage?.add({ config: cloneDeep(node), parent: cloneDeep(parent), root: cloneDeep(root) });
|
|
305
300
|
|
|
306
|
-
|
|
307
|
-
stage?.multiSelect(newNodeIds);
|
|
301
|
+
node.style = fixNodePosition(node, parent, stage);
|
|
308
302
|
|
|
309
|
-
|
|
303
|
+
await stage?.update({ config: cloneDeep(node), root: cloneDeep(root) });
|
|
310
304
|
|
|
311
|
-
|
|
305
|
+
// 新增节点添加到配置中
|
|
306
|
+
parent?.items?.push(node);
|
|
307
|
+
|
|
308
|
+
this.addModifiedNodeId(node.id);
|
|
309
|
+
|
|
310
|
+
return node;
|
|
312
311
|
}
|
|
313
312
|
|
|
314
313
|
/**
|
|
@@ -317,30 +316,47 @@ class Editor extends BaseService {
|
|
|
317
316
|
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
318
317
|
* @returns 添加后的节点
|
|
319
318
|
*/
|
|
320
|
-
public async add(addNode: AddMNode, parent?: MContainer | null): Promise<MNode> {
|
|
319
|
+
public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
|
|
321
320
|
const stage = this.get<StageCore | null>('stage');
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
321
|
+
|
|
322
|
+
const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(addNode);
|
|
323
|
+
if (!parentNode) throw new Error('未找到父元素');
|
|
324
|
+
|
|
325
|
+
// 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
|
|
326
|
+
const addNodes = [];
|
|
327
|
+
if (!Array.isArray(addNode)) {
|
|
328
|
+
const { type, inputEvent, ...config } = addNode;
|
|
329
|
+
|
|
330
|
+
if (!type) throw new Error('组件类型不能为空');
|
|
331
|
+
|
|
332
|
+
addNodes.push({ ...toRaw(await propsService.getPropsValue(type, config)) });
|
|
333
|
+
} else {
|
|
334
|
+
addNodes.push(...addNode);
|
|
332
335
|
}
|
|
333
336
|
|
|
334
|
-
|
|
335
|
-
|
|
337
|
+
const newNodes = await Promise.all(addNodes.map((node) => this.doAdd(node, parentNode)));
|
|
338
|
+
|
|
339
|
+
if (newNodes.length > 1) {
|
|
340
|
+
const newNodeIds = newNodes.map((node) => node.id);
|
|
341
|
+
// 触发选中样式
|
|
342
|
+
stage?.multiSelect(newNodeIds);
|
|
343
|
+
await this.multiSelect(newNodeIds);
|
|
336
344
|
} else {
|
|
337
|
-
|
|
338
|
-
|
|
345
|
+
await this.select(newNodes[0]);
|
|
346
|
+
|
|
347
|
+
if (isPage(newNodes[0])) {
|
|
348
|
+
this.state.pageLength += 1;
|
|
349
|
+
} else {
|
|
350
|
+
// 新增页面,这个时候页面还有渲染出来,此时select会出错,在runtime-ready的时候回去select
|
|
351
|
+
stage?.select(newNodes[0].id);
|
|
352
|
+
}
|
|
339
353
|
}
|
|
340
354
|
|
|
341
|
-
this.
|
|
355
|
+
this.pushHistoryState();
|
|
356
|
+
|
|
357
|
+
this.emit('add', newNodes);
|
|
342
358
|
|
|
343
|
-
return
|
|
359
|
+
return newNodes.length > 1 ? newNodes[0] : newNodes;
|
|
344
360
|
}
|
|
345
361
|
|
|
346
362
|
/**
|
|
@@ -492,14 +508,14 @@ class Editor extends BaseService {
|
|
|
492
508
|
* @param position 粘贴的坐标
|
|
493
509
|
* @returns 添加后的组件节点配置
|
|
494
510
|
*/
|
|
495
|
-
public async paste(position: PastePosition = {}): Promise<MNode[] | void> {
|
|
496
|
-
const config = await storageService.getItem(COPY_STORAGE_KEY);
|
|
511
|
+
public async paste(position: PastePosition = {}): Promise<MNode | MNode[] | void> {
|
|
512
|
+
const config: MNode[] = await storageService.getItem(COPY_STORAGE_KEY);
|
|
497
513
|
|
|
498
|
-
if (!config) return;
|
|
514
|
+
if (!Array.isArray(config)) return;
|
|
499
515
|
|
|
500
516
|
const pasteConfigs = await beforePaste(position, config);
|
|
501
517
|
|
|
502
|
-
return
|
|
518
|
+
return this.add(pasteConfigs);
|
|
503
519
|
}
|
|
504
520
|
|
|
505
521
|
/**
|
|
@@ -590,7 +606,7 @@ class Editor extends BaseService {
|
|
|
590
606
|
return srcValue;
|
|
591
607
|
}
|
|
592
608
|
});
|
|
593
|
-
newConfig.style = getInitPositionStyle(newConfig.style, layout
|
|
609
|
+
newConfig.style = getInitPositionStyle(newConfig.style, layout);
|
|
594
610
|
|
|
595
611
|
target.items.push(newConfig);
|
|
596
612
|
|
|
@@ -633,7 +649,7 @@ class Editor extends BaseService {
|
|
|
633
649
|
const node = toRaw(this.get('node'));
|
|
634
650
|
if (!node || isPage(node)) return;
|
|
635
651
|
|
|
636
|
-
const { style, id } = node;
|
|
652
|
+
const { style, id, type } = node;
|
|
637
653
|
if (!style || style.position !== 'absolute') return;
|
|
638
654
|
|
|
639
655
|
if (top && !isNumber(style.top)) return;
|
|
@@ -641,6 +657,7 @@ class Editor extends BaseService {
|
|
|
641
657
|
|
|
642
658
|
this.update({
|
|
643
659
|
id,
|
|
660
|
+
type,
|
|
644
661
|
style: {
|
|
645
662
|
...style,
|
|
646
663
|
left: Number(style.left) + left,
|
package/src/utils/editor.ts
CHANGED
|
@@ -88,10 +88,10 @@ export const getRelativeStyle = (style: Record<string, any> = {}): Record<string
|
|
|
88
88
|
left: 0,
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
const getMiddleTop = (
|
|
92
|
-
let height = style
|
|
91
|
+
const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) => {
|
|
92
|
+
let height = node.style?.height || 0;
|
|
93
93
|
|
|
94
|
-
if (!stage || typeof style
|
|
94
|
+
if (!stage || typeof node.style?.top !== 'undefined' || !parentNode.style) return node.style?.top;
|
|
95
95
|
|
|
96
96
|
if (!isNumber(height)) {
|
|
97
97
|
height = 0;
|
|
@@ -103,20 +103,15 @@ const getMiddleTop = (style: Record<string, any> = {}, parentNode: MNode, stage:
|
|
|
103
103
|
const { scrollTop = 0, wrapperHeight } = stage.mask;
|
|
104
104
|
return (wrapperHeight - height) / 2 + scrollTop;
|
|
105
105
|
}
|
|
106
|
+
|
|
106
107
|
return (parentHeight - height) / 2;
|
|
107
108
|
};
|
|
108
109
|
|
|
109
|
-
export const getInitPositionStyle = (
|
|
110
|
-
style: Record<string, any> = {},
|
|
111
|
-
layout: Layout,
|
|
112
|
-
parentNode: MNode,
|
|
113
|
-
stage: StageCore,
|
|
114
|
-
) => {
|
|
110
|
+
export const getInitPositionStyle = (style: Record<string, any> = {}, layout: Layout) => {
|
|
115
111
|
if (layout === Layout.ABSOLUTE) {
|
|
116
112
|
return {
|
|
117
113
|
...style,
|
|
118
114
|
position: 'absolute',
|
|
119
|
-
top: getMiddleTop(style, parentNode, stage),
|
|
120
115
|
};
|
|
121
116
|
}
|
|
122
117
|
|
|
@@ -230,3 +225,15 @@ export const fixNodeLeft = (config: MNode, parent: MContainer, doc?: Document) =
|
|
|
230
225
|
|
|
231
226
|
return config.style.left;
|
|
232
227
|
};
|
|
228
|
+
|
|
229
|
+
export const fixNodePosition = (config: MNode, parent: MContainer, stage: StageCore | null) => {
|
|
230
|
+
if (config.style?.position !== 'absolute') {
|
|
231
|
+
return config.style;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
...(config.style || {}),
|
|
236
|
+
top: getMiddleTop(config, parent, stage),
|
|
237
|
+
left: fixNodeLeft(config, parent, stage?.renderer.contentWindow?.document),
|
|
238
|
+
};
|
|
239
|
+
};
|
package/src/utils/operator.ts
CHANGED
|
@@ -8,8 +8,8 @@ import { isPage } from '@tmagic/utils';
|
|
|
8
8
|
import editorService from '../services/editor';
|
|
9
9
|
import historyService from '../services/history';
|
|
10
10
|
import propsService from '../services/props';
|
|
11
|
-
import { AddMNode,
|
|
12
|
-
import {
|
|
11
|
+
import { AddMNode, PastePosition } from '../type';
|
|
12
|
+
import { generatePageNameByApp, getInitPositionStyle, getNodeIndex } from '../utils/editor';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* 粘贴前置操作:返回分配了新id以及校准了坐标的配置
|
|
@@ -17,7 +17,7 @@ import { fixNodeLeft, generatePageNameByApp, getInitPositionStyle, getNodeIndex
|
|
|
17
17
|
* @param config 待粘贴的元素配置(复制时保存的那份配置)
|
|
18
18
|
* @returns
|
|
19
19
|
*/
|
|
20
|
-
export const beforePaste = async (position: PastePosition, config: MNode[]) => {
|
|
20
|
+
export const beforePaste = async (position: PastePosition, config: MNode[]): Promise<MNode[]> => {
|
|
21
21
|
if (!config[0]?.style) return config;
|
|
22
22
|
const curNode = editorService.get<MContainer>('node');
|
|
23
23
|
// 将数组中第一个元素的坐标作为参照点
|
|
@@ -69,54 +69,6 @@ export const beforePaste = async (position: PastePosition, config: MNode[]) => {
|
|
|
69
69
|
return pasteConfigs;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
/**
|
|
73
|
-
* 新增元素前置操作,实现了在编辑器中新增元素节点,并返回新增元素信息以供stage更新
|
|
74
|
-
* @param addNode 待添加元素的配置
|
|
75
|
-
* @param parent 父级容器(可选)
|
|
76
|
-
* @returns 新增的元素,父级元素,布局方式,是否为根页面
|
|
77
|
-
*/
|
|
78
|
-
export const beforeAdd = async (
|
|
79
|
-
addNode: AddMNode,
|
|
80
|
-
parent?: MContainer | null,
|
|
81
|
-
): Promise<{ parentNode: MContainer; newNode: MNode; layout: Layout; isPage: boolean }> => {
|
|
82
|
-
// 加入inputEvent是为给业务扩展时可以获取到更多的信息,只有在使用拖拽添加组件时才有改对象
|
|
83
|
-
const { type, inputEvent, ...config } = addNode;
|
|
84
|
-
const curNode = editorService.get<MContainer>('node');
|
|
85
|
-
|
|
86
|
-
let parentNode: MContainer | undefined;
|
|
87
|
-
const isPage = type === NodeType.PAGE;
|
|
88
|
-
|
|
89
|
-
if (isPage) {
|
|
90
|
-
parentNode = editorService.get<MApp>('root');
|
|
91
|
-
// 由于支持中间件扩展,在parent参数为undefined时,parent会变成next函数
|
|
92
|
-
} else if (parent && typeof parent !== 'function') {
|
|
93
|
-
parentNode = parent;
|
|
94
|
-
} else if (curNode.items) {
|
|
95
|
-
parentNode = curNode;
|
|
96
|
-
} else {
|
|
97
|
-
parentNode = editorService.getParentById(curNode.id, false);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (!parentNode) throw new Error('未找到父元素');
|
|
101
|
-
|
|
102
|
-
const layout = await editorService.getLayout(toRaw(parentNode), addNode as MNode);
|
|
103
|
-
const newNode = { ...toRaw(await propsService.getPropsValue(type, config)) };
|
|
104
|
-
newNode.style = getInitPositionStyle(newNode.style, layout, parentNode, editorService.get<StageCore>('stage'));
|
|
105
|
-
|
|
106
|
-
if ((parentNode?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && newNode.type !== NodeType.PAGE) {
|
|
107
|
-
throw new Error('app下不能添加组件');
|
|
108
|
-
}
|
|
109
|
-
// 新增节点添加到配置中
|
|
110
|
-
parentNode?.items?.push(newNode);
|
|
111
|
-
// 返回新增信息以供stage更新
|
|
112
|
-
return {
|
|
113
|
-
parentNode,
|
|
114
|
-
newNode,
|
|
115
|
-
layout,
|
|
116
|
-
isPage,
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
|
|
120
72
|
/**
|
|
121
73
|
* 将元素粘贴到容器内时,将相对于画布坐标转换为相对于容器的坐标
|
|
122
74
|
* @param position PastePosition 粘贴时相对于画布的坐标
|
|
@@ -135,27 +87,6 @@ export const getPositionInContainer = (position: PastePosition = {}, id: Id) =>
|
|
|
135
87
|
};
|
|
136
88
|
};
|
|
137
89
|
|
|
138
|
-
/**
|
|
139
|
-
* 将新增元素事件通知到stage以更新渲染
|
|
140
|
-
* @param parentNode 父元素
|
|
141
|
-
* @param newNode 当前新增元素
|
|
142
|
-
* @param layout 布局方式
|
|
143
|
-
*/
|
|
144
|
-
export const notifyAddToStage = async (parentNode: MContainer, newNode: MNode, layout: Layout) => {
|
|
145
|
-
const stage = editorService.get<StageCore | null>('stage');
|
|
146
|
-
const root = editorService.get<MApp>('root');
|
|
147
|
-
|
|
148
|
-
await stage?.add({ config: cloneDeep(newNode), parent: cloneDeep(parentNode), root: cloneDeep(root) });
|
|
149
|
-
|
|
150
|
-
if (layout === Layout.ABSOLUTE) {
|
|
151
|
-
const fixedLeft = fixNodeLeft(newNode, parentNode, stage?.renderer.contentWindow?.document);
|
|
152
|
-
if (typeof fixedLeft !== 'undefined' && newNode.style) {
|
|
153
|
-
newNode.style.left = fixedLeft;
|
|
154
|
-
await stage?.update({ config: cloneDeep(newNode), root: cloneDeep(root) });
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
|
|
159
90
|
/**
|
|
160
91
|
* 删除前置操作:实现了在编辑器中删除元素节点,并返回父级元素信息以供stage更新
|
|
161
92
|
* @param node 待删除的节点
|
|
@@ -208,3 +139,25 @@ export const beforeRemove = async (node: MNode): Promise<MContainer | void> => {
|
|
|
208
139
|
}
|
|
209
140
|
return parent;
|
|
210
141
|
};
|
|
142
|
+
|
|
143
|
+
export const getAddParent = (addNode: AddMNode | MNode[]) => {
|
|
144
|
+
const curNode = editorService.get<MContainer>('node');
|
|
145
|
+
|
|
146
|
+
let parentNode;
|
|
147
|
+
if (!Array.isArray(addNode) && isPage(addNode as MNode)) {
|
|
148
|
+
parentNode = editorService.get<MApp>('root');
|
|
149
|
+
} else if (curNode.items) {
|
|
150
|
+
parentNode = curNode;
|
|
151
|
+
} else {
|
|
152
|
+
parentNode = editorService.getParentById(curNode.id, false);
|
|
153
|
+
}
|
|
154
|
+
return parentNode;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const getDefaultConfig = async (addNode: AddMNode, parentNode: MContainer) => {
|
|
158
|
+
const { type, inputEvent, ...config } = addNode;
|
|
159
|
+
const layout = await editorService.getLayout(toRaw(parentNode), addNode as MNode);
|
|
160
|
+
const newNode = { ...toRaw(await propsService.getPropsValue(type, config)) };
|
|
161
|
+
newNode.style = getInitPositionStyle(newNode.style, layout);
|
|
162
|
+
return newNode;
|
|
163
|
+
};
|
|
@@ -27,7 +27,7 @@ declare const _default: {
|
|
|
27
27
|
}>, {
|
|
28
28
|
isMultiSelect: boolean;
|
|
29
29
|
}>>>, {
|
|
30
|
-
show: (e: MouseEvent) => void
|
|
30
|
+
show: (e: MouseEvent) => Promise<void>;
|
|
31
31
|
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, {
|
|
32
32
|
isMultiSelect: boolean;
|
|
33
33
|
}> & {
|
|
@@ -55,7 +55,7 @@ declare const _default: {
|
|
|
55
55
|
}>, {
|
|
56
56
|
isMultiSelect: boolean;
|
|
57
57
|
}>>> & import("vue").ShallowUnwrapRef<{
|
|
58
|
-
show: (e: MouseEvent) => void
|
|
58
|
+
show: (e: MouseEvent) => Promise<void>;
|
|
59
59
|
}> & {} & import("vue").ComponentCustomProperties;
|
|
60
60
|
__isFragment?: undefined;
|
|
61
61
|
__isTeleport?: undefined;
|
|
@@ -65,7 +65,7 @@ declare const _default: {
|
|
|
65
65
|
}>, {
|
|
66
66
|
isMultiSelect: boolean;
|
|
67
67
|
}>>>, {
|
|
68
|
-
show: (e: MouseEvent) => void
|
|
68
|
+
show: (e: MouseEvent) => Promise<void>;
|
|
69
69
|
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, Record<string, any>, string, {
|
|
70
70
|
isMultiSelect: boolean;
|
|
71
71
|
}> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
|
|
@@ -65,19 +65,14 @@ declare class Editor extends BaseService {
|
|
|
65
65
|
* @returns 加入多选的节点配置
|
|
66
66
|
*/
|
|
67
67
|
multiSelect(ids: Id[]): void;
|
|
68
|
-
|
|
69
|
-
* 批量向容器添加节点
|
|
70
|
-
* @param configs 将要添加的节点数组
|
|
71
|
-
* @returns 添加后的节点
|
|
72
|
-
*/
|
|
73
|
-
multiAdd(configs: MNode[]): Promise<MNode[]>;
|
|
68
|
+
doAdd(node: MNode, parent: MContainer): Promise<MNode>;
|
|
74
69
|
/**
|
|
75
70
|
* 向指点容器添加组件节点
|
|
76
71
|
* @param addConfig 将要添加的组件节点配置
|
|
77
72
|
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
78
73
|
* @returns 添加后的节点
|
|
79
74
|
*/
|
|
80
|
-
add(addNode: AddMNode, parent?: MContainer | null): Promise<MNode>;
|
|
75
|
+
add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]>;
|
|
81
76
|
/**
|
|
82
77
|
* 删除组件
|
|
83
78
|
* @param {Object} node
|
|
@@ -114,7 +109,7 @@ declare class Editor extends BaseService {
|
|
|
114
109
|
* @param position 粘贴的坐标
|
|
115
110
|
* @returns 添加后的组件节点配置
|
|
116
111
|
*/
|
|
117
|
-
paste(position?: PastePosition): Promise<MNode[] | void>;
|
|
112
|
+
paste(position?: PastePosition): Promise<MNode | MNode[] | void>;
|
|
118
113
|
/**
|
|
119
114
|
* 将指点节点设置居中
|
|
120
115
|
* @param config 组件节点配置
|
package/types/utils/editor.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare const generatePageNameByApp: (app: MApp) => string;
|
|
|
33
33
|
export declare const isFixed: (node: MNode) => boolean;
|
|
34
34
|
export declare const getNodeIndex: (node: MNode, parent: MContainer | MApp) => number;
|
|
35
35
|
export declare const getRelativeStyle: (style?: Record<string, any>) => Record<string, any>;
|
|
36
|
-
export declare const getInitPositionStyle: (style: Record<string, any> | undefined, layout: Layout
|
|
36
|
+
export declare const getInitPositionStyle: (style: Record<string, any> | undefined, layout: Layout) => Record<string, any>;
|
|
37
37
|
export declare const setLayout: (node: MNode, layout: Layout) => MNode;
|
|
38
38
|
export declare const change2Fixed: (node: MNode, root: MApp) => {
|
|
39
39
|
left: number;
|
|
@@ -42,3 +42,6 @@ export declare const change2Fixed: (node: MNode, root: MApp) => {
|
|
|
42
42
|
export declare const Fixed2Other: (node: MNode, root: MApp, getLayout: (parent: MNode, node?: MNode) => Promise<Layout>) => Promise<Record<string, any>>;
|
|
43
43
|
export declare const getGuideLineFromCache: (key: string) => number[];
|
|
44
44
|
export declare const fixNodeLeft: (config: MNode, parent: MContainer, doc?: Document) => any;
|
|
45
|
+
export declare const fixNodePosition: (config: MNode, parent: MContainer, stage: StageCore | null) => {
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
} | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Id, MContainer, MNode } from '@tmagic/schema';
|
|
2
|
-
import { AddMNode,
|
|
2
|
+
import { AddMNode, PastePosition } from '../type';
|
|
3
3
|
/**
|
|
4
4
|
* 粘贴前置操作:返回分配了新id以及校准了坐标的配置
|
|
5
5
|
* @param position 粘贴的坐标
|
|
@@ -7,18 +7,6 @@ import { AddMNode, Layout, PastePosition } from '../type';
|
|
|
7
7
|
* @returns
|
|
8
8
|
*/
|
|
9
9
|
export declare const beforePaste: (position: PastePosition, config: MNode[]) => Promise<MNode[]>;
|
|
10
|
-
/**
|
|
11
|
-
* 新增元素前置操作,实现了在编辑器中新增元素节点,并返回新增元素信息以供stage更新
|
|
12
|
-
* @param addNode 待添加元素的配置
|
|
13
|
-
* @param parent 父级容器(可选)
|
|
14
|
-
* @returns 新增的元素,父级元素,布局方式,是否为根页面
|
|
15
|
-
*/
|
|
16
|
-
export declare const beforeAdd: (addNode: AddMNode, parent?: MContainer | null) => Promise<{
|
|
17
|
-
parentNode: MContainer;
|
|
18
|
-
newNode: MNode;
|
|
19
|
-
layout: Layout;
|
|
20
|
-
isPage: boolean;
|
|
21
|
-
}>;
|
|
22
10
|
/**
|
|
23
11
|
* 将元素粘贴到容器内时,将相对于画布坐标转换为相对于容器的坐标
|
|
24
12
|
* @param position PastePosition 粘贴时相对于画布的坐标
|
|
@@ -29,16 +17,11 @@ export declare const getPositionInContainer: (position: PastePosition | undefine
|
|
|
29
17
|
left: number;
|
|
30
18
|
top: number;
|
|
31
19
|
};
|
|
32
|
-
/**
|
|
33
|
-
* 将新增元素事件通知到stage以更新渲染
|
|
34
|
-
* @param parentNode 父元素
|
|
35
|
-
* @param newNode 当前新增元素
|
|
36
|
-
* @param layout 布局方式
|
|
37
|
-
*/
|
|
38
|
-
export declare const notifyAddToStage: (parentNode: MContainer, newNode: MNode, layout: Layout) => Promise<void>;
|
|
39
20
|
/**
|
|
40
21
|
* 删除前置操作:实现了在编辑器中删除元素节点,并返回父级元素信息以供stage更新
|
|
41
22
|
* @param node 待删除的节点
|
|
42
23
|
* @returns 父级元素,root根元素
|
|
43
24
|
*/
|
|
44
25
|
export declare const beforeRemove: (node: MNode) => Promise<MContainer | void>;
|
|
26
|
+
export declare const getAddParent: (addNode: AddMNode | MNode[]) => MContainer | undefined;
|
|
27
|
+
export declare const getDefaultConfig: (addNode: AddMNode, parentNode: MContainer) => Promise<any>;
|