@tmagic/editor 1.0.0-beta.12 → 1.0.0-beta.15
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/coverage/clover.xml +1540 -0
- package/coverage/coverage-final.json +35 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +206 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/Editor.vue.html +787 -0
- package/coverage/lcov-report/src/components/ContentMenu.vue.html +406 -0
- package/coverage/lcov-report/src/components/Icon.vue.html +172 -0
- package/coverage/lcov-report/src/components/ScrollViewer.vue.html +283 -0
- package/coverage/lcov-report/src/components/ToolButton.vue.html +772 -0
- package/coverage/lcov-report/src/components/index.html +161 -0
- package/coverage/lcov-report/src/index.html +131 -0
- package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +214 -0
- package/coverage/lcov-report/src/layouts/Framework.vue.html +304 -0
- package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
- package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +316 -0
- package/coverage/lcov-report/src/layouts/Resizer.vue.html +268 -0
- package/coverage/lcov-report/src/layouts/index.html +176 -0
- package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +358 -0
- package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +421 -0
- package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +775 -0
- package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +343 -0
- package/coverage/lcov-report/src/layouts/sidebar/index.html +161 -0
- package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
- package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +757 -0
- package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
- package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +586 -0
- package/coverage/lcov-report/src/layouts/workspace/index.html +161 -0
- package/coverage/lcov-report/src/services/BaseService.ts.html +643 -0
- package/coverage/lcov-report/src/services/componentList.ts.html +229 -0
- package/coverage/lcov-report/src/services/editor.ts.html +2077 -0
- package/coverage/lcov-report/src/services/events.ts.html +331 -0
- package/coverage/lcov-report/src/services/history.ts.html +478 -0
- package/coverage/lcov-report/src/services/index.html +206 -0
- package/coverage/lcov-report/src/services/props.ts.html +415 -0
- package/coverage/lcov-report/src/services/ui.ts.html +514 -0
- package/coverage/lcov-report/src/type.ts.html +844 -0
- package/coverage/lcov-report/src/utils/compose.ts.html +184 -0
- package/coverage/lcov-report/src/utils/config.ts.html +172 -0
- package/coverage/lcov-report/src/utils/editor.ts.html +838 -0
- package/coverage/lcov-report/src/utils/index.html +221 -0
- package/coverage/lcov-report/src/utils/index.ts.html +151 -0
- package/coverage/lcov-report/src/utils/logger.ts.html +226 -0
- package/coverage/lcov-report/src/utils/props.ts.html +796 -0
- package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +733 -0
- package/coverage/lcov-report/src/utils/undo-redo.ts.html +313 -0
- package/coverage/lcov-report/undo-redo.ts.html +313 -0
- package/coverage/lcov.info +3676 -0
- package/dist/style.css +47 -22
- package/dist/tmagic-editor.es.js +921 -603
- package/dist/tmagic-editor.es.js.map +1 -1
- package/dist/tmagic-editor.umd.js +920 -602
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/dist/types/src/Editor.vue.d.ts +1 -1
- package/dist/types/src/components/ToolButton.vue.d.ts +12 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -0
- package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +2 -0
- package/dist/types/src/services/editor.d.ts +5 -2
- package/dist/types/src/services/history.d.ts +1 -0
- package/dist/types/src/services/props.d.ts +2 -2
- package/dist/types/src/services/ui.d.ts +1 -0
- package/dist/types/src/type.d.ts +6 -8
- package/dist/types/src/utils/editor.d.ts +2 -2
- package/dist/types/src/utils/polyfills.d.ts +0 -0
- package/package.json +26 -12
- package/src/components/ContentMenu.vue +107 -0
- package/src/components/ScrollViewer.vue +1 -1
- package/src/components/ToolButton.vue +69 -30
- package/src/index.ts +2 -0
- package/src/layouts/Framework.vue +6 -6
- package/src/layouts/sidebar/ComponentListPanel.vue +23 -1
- package/src/layouts/sidebar/LayerMenu.vue +91 -72
- package/src/layouts/sidebar/LayerPanel.vue +23 -49
- package/src/layouts/workspace/PageBar.vue +35 -6
- package/src/layouts/workspace/Stage.vue +41 -44
- package/src/layouts/workspace/ViewerMenu.vue +104 -67
- package/src/layouts/workspace/Workspace.vue +74 -16
- package/src/services/BaseService.ts +1 -1
- package/src/services/editor.ts +97 -10
- package/src/services/history.ts +7 -0
- package/src/services/props.ts +2 -3
- package/src/services/ui.ts +5 -0
- package/src/theme/common/var.scss +1 -0
- package/src/theme/component-list-panel.scss +2 -0
- package/src/theme/content-menu.scss +33 -26
- package/src/theme/layer-panel.scss +2 -1
- package/src/theme/nav-menu.scss +6 -2
- package/src/theme/page-bar.scss +22 -1
- package/src/type.ts +6 -8
- package/src/utils/editor.ts +7 -3
- package/{vite.config.ts → src/utils/polyfills.ts} +4 -12
- package/src/utils/props.ts +19 -0
- package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -980
- package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -188
- package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
- package/tsconfig.json +0 -9
|
@@ -1,47 +1,31 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<div>
|
|
4
|
-
<div class="magic-editor-content-menu-item" @click="() => center()" v-if="canCenter">水平居中</div>
|
|
5
|
-
<div class="magic-editor-content-menu-item" @click="() => copy()">复制</div>
|
|
6
|
-
<div class="magic-editor-content-menu-item" @click="paste" v-if="canPaste">粘贴</div>
|
|
7
|
-
<template v-if="canMoveZPos">
|
|
8
|
-
<div class="separation"></div>
|
|
9
|
-
<div class="magic-editor-content-menu-item" @click="topItem">上移一层</div>
|
|
10
|
-
<div class="magic-editor-content-menu-item" @click="bottomItem">下移一层</div>
|
|
11
|
-
<div class="magic-editor-content-menu-item" @click="top">置顶</div>
|
|
12
|
-
<div class="magic-editor-content-menu-item" @click="bottom">置底</div>
|
|
13
|
-
</template>
|
|
14
|
-
<template v-if="canDelete">
|
|
15
|
-
<div class="separation"></div>
|
|
16
|
-
<div class="magic-editor-content-menu-item" @click="() => remove()">删除</div>
|
|
17
|
-
</template>
|
|
18
|
-
<div class="separation"></div>
|
|
19
|
-
<div class="magic-editor-content-menu-item" @click="clearGuides">清空参考线</div>
|
|
20
|
-
</div>
|
|
21
|
-
</div>
|
|
2
|
+
<content-menu :menu-data="menuData" ref="menu"></content-menu>
|
|
22
3
|
</template>
|
|
23
4
|
|
|
24
5
|
<script lang="ts">
|
|
25
|
-
import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue';
|
|
6
|
+
import { computed, defineComponent, inject, markRaw, onMounted, reactive, ref, watch } from 'vue';
|
|
7
|
+
import { Bottom, Delete, DocumentCopy, Top } from '@element-plus/icons';
|
|
26
8
|
|
|
27
9
|
import { NodeType } from '@tmagic/schema';
|
|
28
10
|
import type StageCore from '@tmagic/stage';
|
|
29
11
|
|
|
30
|
-
import
|
|
12
|
+
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
13
|
+
import { LayerOffset, Layout, MenuItem, Services } from '@editor/type';
|
|
31
14
|
import { COPY_STORAGE_KEY } from '@editor/utils/editor';
|
|
32
15
|
|
|
33
16
|
export default defineComponent({
|
|
34
|
-
|
|
17
|
+
components: { ContentMenu },
|
|
35
18
|
|
|
36
19
|
setup() {
|
|
37
20
|
const services = inject<Services>('services');
|
|
38
21
|
const editorService = services?.editorService;
|
|
39
|
-
const menu = ref<
|
|
22
|
+
const menu = ref<InstanceType<typeof ContentMenu>>();
|
|
40
23
|
const canPaste = ref(false);
|
|
41
24
|
const canCenter = ref(false);
|
|
42
25
|
|
|
43
26
|
const node = computed(() => editorService?.get('node'));
|
|
44
27
|
const parent = computed(() => editorService?.get('parent'));
|
|
28
|
+
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
45
29
|
|
|
46
30
|
onMounted(() => {
|
|
47
31
|
const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
|
|
@@ -62,49 +46,102 @@ export default defineComponent({
|
|
|
62
46
|
|
|
63
47
|
return {
|
|
64
48
|
menu,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
49
|
+
menuData: reactive<MenuItem[]>([
|
|
50
|
+
{
|
|
51
|
+
type: 'button',
|
|
52
|
+
text: '水平居中',
|
|
53
|
+
display: () => canCenter.value,
|
|
54
|
+
handler: () => {
|
|
55
|
+
node.value && editorService?.alignCenter(node.value);
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: 'button',
|
|
60
|
+
text: '复制',
|
|
61
|
+
icon: markRaw(DocumentCopy),
|
|
62
|
+
handler: () => {
|
|
63
|
+
node.value && editorService?.copy(node.value);
|
|
64
|
+
canPaste.value = true;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'button',
|
|
69
|
+
text: '粘贴',
|
|
70
|
+
display: () => canPaste.value,
|
|
71
|
+
handler: () => {
|
|
72
|
+
const top = menu.value?.$el.offsetTop || 0;
|
|
73
|
+
const left = menu.value?.$el.offsetLeft || 0;
|
|
74
|
+
editorService?.paste({ left, top });
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: 'divider',
|
|
79
|
+
direction: 'horizontal',
|
|
80
|
+
display: () => !isPage.value,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'button',
|
|
84
|
+
text: '上移一层',
|
|
85
|
+
icon: markRaw(Top),
|
|
86
|
+
display: () => !isPage.value,
|
|
87
|
+
handler: () => {
|
|
88
|
+
editorService?.moveLayer(1);
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'button',
|
|
93
|
+
text: '下移一层',
|
|
94
|
+
icon: markRaw(Bottom),
|
|
95
|
+
display: () => !isPage.value,
|
|
96
|
+
handler: () => {
|
|
97
|
+
editorService?.moveLayer(-1);
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: 'button',
|
|
102
|
+
text: '置顶',
|
|
103
|
+
display: () => !isPage.value,
|
|
104
|
+
handler: () => {
|
|
105
|
+
editorService?.moveLayer(LayerOffset.TOP);
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
type: 'button',
|
|
110
|
+
text: '置底',
|
|
111
|
+
display: () => !isPage.value,
|
|
112
|
+
handler: () => {
|
|
113
|
+
editorService?.moveLayer(LayerOffset.BOTTOM);
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'divider',
|
|
118
|
+
direction: 'horizontal',
|
|
119
|
+
display: () => !isPage.value,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
type: 'button',
|
|
123
|
+
text: '删除',
|
|
124
|
+
icon: Delete,
|
|
125
|
+
display: () => !isPage.value,
|
|
126
|
+
handler: () => {
|
|
127
|
+
node.value && editorService?.remove(node.value);
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'divider',
|
|
132
|
+
direction: 'horizontal',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: 'button',
|
|
136
|
+
text: '清空参考线',
|
|
137
|
+
handler: () => {
|
|
138
|
+
editorService?.get<StageCore>('stage').clearGuides();
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
]),
|
|
142
|
+
|
|
143
|
+
show(e: MouseEvent) {
|
|
144
|
+
menu.value?.show(e);
|
|
108
145
|
},
|
|
109
146
|
};
|
|
110
147
|
},
|
|
@@ -24,6 +24,7 @@ import KeyController from 'keycon';
|
|
|
24
24
|
import type { MNode, MPage } from '@tmagic/schema';
|
|
25
25
|
import type { MoveableOptions } from '@tmagic/stage';
|
|
26
26
|
import StageCore from '@tmagic/stage';
|
|
27
|
+
import { isPage } from '@tmagic/utils';
|
|
27
28
|
|
|
28
29
|
import type { Services } from '@editor/type';
|
|
29
30
|
|
|
@@ -64,38 +65,95 @@ export default defineComponent({
|
|
|
64
65
|
workspace.value?.focus();
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
const mouseleaveHandler = () => {
|
|
68
|
-
workspace.value?.blur();
|
|
69
|
-
};
|
|
70
|
-
|
|
71
68
|
onMounted(() => {
|
|
72
69
|
workspace.value?.addEventListener('mouseenter', mouseenterHandler);
|
|
73
70
|
|
|
74
|
-
workspace.value?.addEventListener('mouseleave', mouseleaveHandler);
|
|
75
|
-
|
|
76
71
|
keycon = new KeyController(workspace.value);
|
|
77
72
|
|
|
73
|
+
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
|
|
74
|
+
|
|
75
|
+
const ctrl = isMac ? 'meta' : 'ctrl';
|
|
76
|
+
|
|
78
77
|
keycon
|
|
79
|
-
.keyup('delete', () => {
|
|
80
|
-
|
|
78
|
+
.keyup('delete', (e) => {
|
|
79
|
+
e.inputEvent.preventDefault();
|
|
80
|
+
if (!node.value || isPage(node.value)) return;
|
|
81
|
+
services?.editorService.remove(node.value);
|
|
81
82
|
})
|
|
82
|
-
.
|
|
83
|
+
.keydown([ctrl, 'c'], (e) => {
|
|
84
|
+
e.inputEvent.preventDefault();
|
|
83
85
|
node.value && services?.editorService.copy(node.value);
|
|
84
86
|
})
|
|
85
|
-
.
|
|
87
|
+
.keydown([ctrl, 'v'], (e) => {
|
|
88
|
+
e.inputEvent.preventDefault();
|
|
86
89
|
node.value && services?.editorService.paste();
|
|
87
90
|
})
|
|
88
|
-
.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
.keydown([ctrl, 'x'], (e) => {
|
|
92
|
+
e.inputEvent.preventDefault();
|
|
93
|
+
if (!node.value || isPage(node.value)) return;
|
|
94
|
+
services?.editorService.copy(node.value);
|
|
95
|
+
services?.editorService.remove(node.value);
|
|
96
|
+
})
|
|
97
|
+
.keydown([ctrl, 'z'], (e) => {
|
|
98
|
+
e.inputEvent.preventDefault();
|
|
99
|
+
services?.editorService.undo();
|
|
100
|
+
})
|
|
101
|
+
.keydown([ctrl, 'shift', 'z'], (e) => {
|
|
102
|
+
e.inputEvent.preventDefault();
|
|
103
|
+
services?.editorService.redo();
|
|
104
|
+
})
|
|
105
|
+
.keydown('up', (e) => {
|
|
106
|
+
e.inputEvent.preventDefault();
|
|
107
|
+
services?.editorService.move(0, -1);
|
|
108
|
+
})
|
|
109
|
+
.keydown('down', (e) => {
|
|
110
|
+
e.inputEvent.preventDefault();
|
|
111
|
+
services?.editorService.move(0, 1);
|
|
112
|
+
})
|
|
113
|
+
.keydown('left', (e) => {
|
|
114
|
+
e.inputEvent.preventDefault();
|
|
115
|
+
services?.editorService.move(-1, 0);
|
|
116
|
+
})
|
|
117
|
+
.keydown('right', (e) => {
|
|
118
|
+
e.inputEvent.preventDefault();
|
|
119
|
+
services?.editorService.move(1, 0);
|
|
120
|
+
})
|
|
121
|
+
.keydown([ctrl, 'up'], (e) => {
|
|
122
|
+
e.inputEvent.preventDefault();
|
|
123
|
+
services?.editorService.move(0, -10);
|
|
124
|
+
})
|
|
125
|
+
.keydown([ctrl, 'down'], (e) => {
|
|
126
|
+
e.inputEvent.preventDefault();
|
|
127
|
+
services?.editorService.move(0, 10);
|
|
128
|
+
})
|
|
129
|
+
.keydown([ctrl, 'left'], (e) => {
|
|
130
|
+
e.inputEvent.preventDefault();
|
|
131
|
+
services?.editorService.move(-10, 0);
|
|
132
|
+
})
|
|
133
|
+
.keydown([ctrl, 'right'], (e) => {
|
|
134
|
+
e.inputEvent.preventDefault();
|
|
135
|
+
services?.editorService.move(10, 0);
|
|
136
|
+
})
|
|
137
|
+
.keydown('tab', (e) => {
|
|
138
|
+
e.inputEvent.preventDefault();
|
|
139
|
+
services?.editorService.selectNextNode();
|
|
140
|
+
})
|
|
141
|
+
.keydown([ctrl, 'tab'], (e) => {
|
|
142
|
+
e.inputEvent.preventDefault();
|
|
143
|
+
services?.editorService.selectNextPage();
|
|
144
|
+
})
|
|
145
|
+
.keydown([ctrl, '='], (e) => {
|
|
146
|
+
e.inputEvent.preventDefault();
|
|
147
|
+
services?.uiService.zoom(0.1);
|
|
148
|
+
})
|
|
149
|
+
.keydown([ctrl, '-'], (e) => {
|
|
150
|
+
e.inputEvent.preventDefault();
|
|
151
|
+
services?.uiService.zoom(-0.1);
|
|
93
152
|
});
|
|
94
153
|
});
|
|
95
154
|
|
|
96
155
|
onUnmounted(() => {
|
|
97
156
|
workspace.value?.removeEventListener('mouseenter', mouseenterHandler);
|
|
98
|
-
workspace.value?.removeEventListener('mouseleave', mouseleaveHandler);
|
|
99
157
|
keycon.destroy();
|
|
100
158
|
});
|
|
101
159
|
|
|
@@ -53,7 +53,7 @@ const doAction = async (
|
|
|
53
53
|
let returnValue: any = await fn(beforeArgs, sourceMethod.bind(scope));
|
|
54
54
|
|
|
55
55
|
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
56
|
-
returnValue = await afterMethod(...beforeArgs
|
|
56
|
+
returnValue = await afterMethod(returnValue, ...beforeArgs);
|
|
57
57
|
|
|
58
58
|
if (isError(returnValue)) throw returnValue;
|
|
59
59
|
}
|
package/src/services/editor.ts
CHANGED
|
@@ -23,7 +23,7 @@ import serialize from 'serialize-javascript';
|
|
|
23
23
|
import type { Id, MApp, MComponent, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
24
24
|
import { NodeType } from '@tmagic/schema';
|
|
25
25
|
import StageCore from '@tmagic/stage';
|
|
26
|
-
import { getNodePath, isPop } from '@tmagic/utils';
|
|
26
|
+
import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
|
|
27
27
|
|
|
28
28
|
import historyService, { StepValue } from '@editor/services/history';
|
|
29
29
|
import propsService from '@editor/services/props';
|
|
@@ -54,6 +54,7 @@ class Editor extends BaseService {
|
|
|
54
54
|
stage: null,
|
|
55
55
|
highlightNode: null,
|
|
56
56
|
modifiedNodeIds: new Map(),
|
|
57
|
+
pageLength: 0,
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
constructor() {
|
|
@@ -69,6 +70,7 @@ class Editor extends BaseService {
|
|
|
69
70
|
'paste',
|
|
70
71
|
'alignCenter',
|
|
71
72
|
'moveLayer',
|
|
73
|
+
'move',
|
|
72
74
|
'undo',
|
|
73
75
|
'redo',
|
|
74
76
|
'highlight',
|
|
@@ -89,6 +91,7 @@ class Editor extends BaseService {
|
|
|
89
91
|
log('store set ', name, ' ', value);
|
|
90
92
|
|
|
91
93
|
if (name === 'root') {
|
|
94
|
+
this.state.pageLength = (value as unknown as MApp)?.items?.length || 0;
|
|
92
95
|
this.emit('root-change', value);
|
|
93
96
|
}
|
|
94
97
|
}
|
|
@@ -108,7 +111,7 @@ class Editor extends BaseService {
|
|
|
108
111
|
* @returns {EditorNodeInfo}
|
|
109
112
|
*/
|
|
110
113
|
public getNodeInfo(id: Id): EditorNodeInfo {
|
|
111
|
-
const root = this.get<MApp | null>('root');
|
|
114
|
+
const root = toRaw(this.get<MApp | null>('root'));
|
|
112
115
|
if (!root) return {};
|
|
113
116
|
|
|
114
117
|
if (id === root.id) {
|
|
@@ -159,13 +162,15 @@ class Editor extends BaseService {
|
|
|
159
162
|
/**
|
|
160
163
|
* 只有容器拥有布局
|
|
161
164
|
*/
|
|
162
|
-
public async getLayout(
|
|
163
|
-
if (node
|
|
164
|
-
|
|
165
|
+
public async getLayout(parent: MNode, node?: MNode): Promise<Layout> {
|
|
166
|
+
if (node && typeof node !== 'function' && isFixed(node)) return Layout.FIXED;
|
|
167
|
+
|
|
168
|
+
if (parent.layout) {
|
|
169
|
+
return parent.layout;
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
// 如果该节点没有设置position,则认为是流式布局,例如获取root的布局时
|
|
168
|
-
if (!
|
|
173
|
+
if (!parent.style?.position) {
|
|
169
174
|
return Layout.RELATIVE;
|
|
170
175
|
}
|
|
171
176
|
|
|
@@ -188,9 +193,45 @@ class Editor extends BaseService {
|
|
|
188
193
|
} else {
|
|
189
194
|
historyService.empty();
|
|
190
195
|
}
|
|
196
|
+
|
|
197
|
+
this.emit('select', node);
|
|
198
|
+
|
|
191
199
|
return node!;
|
|
192
200
|
}
|
|
193
201
|
|
|
202
|
+
public async selectNextNode(): Promise<MNode> | never {
|
|
203
|
+
const node = toRaw(this.get('node'));
|
|
204
|
+
|
|
205
|
+
if (!node || isPage(node) || node.type === NodeType.ROOT) return node;
|
|
206
|
+
|
|
207
|
+
const parent = toRaw(this.getParentById(node.id));
|
|
208
|
+
|
|
209
|
+
if (!parent) return node;
|
|
210
|
+
|
|
211
|
+
const index = getNodeIndex(node, parent);
|
|
212
|
+
|
|
213
|
+
const nextNode = parent.items[index + 1] || parent.items[0];
|
|
214
|
+
|
|
215
|
+
await this.select(nextNode);
|
|
216
|
+
this.get<StageCore>('stage')?.select(nextNode.id);
|
|
217
|
+
|
|
218
|
+
return nextNode;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public async selectNextPage(): Promise<MNode> | never {
|
|
222
|
+
const root = toRaw(this.get<MApp>('root'));
|
|
223
|
+
const page = toRaw(this.get('page'));
|
|
224
|
+
|
|
225
|
+
const index = getNodeIndex(page, root);
|
|
226
|
+
|
|
227
|
+
const nextPage = root.items[index + 1] || root.items[0];
|
|
228
|
+
|
|
229
|
+
await this.select(nextPage);
|
|
230
|
+
this.get<StageCore>('stage')?.select(nextPage.id);
|
|
231
|
+
|
|
232
|
+
return nextPage;
|
|
233
|
+
}
|
|
234
|
+
|
|
194
235
|
/**
|
|
195
236
|
* 高亮指定节点
|
|
196
237
|
* @param config 指定节点配置或者ID
|
|
@@ -209,12 +250,14 @@ class Editor extends BaseService {
|
|
|
209
250
|
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
210
251
|
* @returns 添加后的节点
|
|
211
252
|
*/
|
|
212
|
-
public async add(
|
|
253
|
+
public async add(addNode: AddMNode, parent?: MContainer | null): Promise<MNode> {
|
|
254
|
+
const { type, ...config } = addNode;
|
|
213
255
|
const curNode = this.get<MContainer>('node');
|
|
214
256
|
|
|
215
257
|
let parentNode: MNode | undefined;
|
|
258
|
+
const isPage = type === NodeType.PAGE;
|
|
216
259
|
|
|
217
|
-
if (
|
|
260
|
+
if (isPage) {
|
|
218
261
|
parentNode = this.get<MApp>('root');
|
|
219
262
|
// 由于支持中间件扩展,在parent参数为undefined时,parent会变成next函数
|
|
220
263
|
} else if (parent && typeof parent !== 'function') {
|
|
@@ -227,7 +270,7 @@ class Editor extends BaseService {
|
|
|
227
270
|
|
|
228
271
|
if (!parentNode) throw new Error('未找到父元素');
|
|
229
272
|
|
|
230
|
-
const layout = await this.getLayout(parentNode);
|
|
273
|
+
const layout = await this.getLayout(toRaw(parentNode), addNode as MNode);
|
|
231
274
|
const newNode = initPosition(
|
|
232
275
|
{ ...toRaw(await propsService.getPropsValue(type, config)) },
|
|
233
276
|
layout,
|
|
@@ -254,6 +297,12 @@ class Editor extends BaseService {
|
|
|
254
297
|
|
|
255
298
|
stage?.select(newNode.id);
|
|
256
299
|
|
|
300
|
+
if (isPage) {
|
|
301
|
+
this.state.pageLength += 1;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
this.emit('add', newNode);
|
|
305
|
+
|
|
257
306
|
return newNode;
|
|
258
307
|
}
|
|
259
308
|
|
|
@@ -282,9 +331,23 @@ class Editor extends BaseService {
|
|
|
282
331
|
stage?.remove({ id: node.id, root: this.get('root') });
|
|
283
332
|
|
|
284
333
|
if (node.type === NodeType.PAGE) {
|
|
334
|
+
this.state.pageLength -= 1;
|
|
335
|
+
|
|
285
336
|
if (root.items[0]) {
|
|
286
337
|
await this.select(root.items[0]);
|
|
287
338
|
stage?.select(root.items[0].id);
|
|
339
|
+
} else {
|
|
340
|
+
this.set('node', null);
|
|
341
|
+
this.set('parent', null);
|
|
342
|
+
this.set('page', null);
|
|
343
|
+
this.set('stage', null);
|
|
344
|
+
this.set('highlightNode', null);
|
|
345
|
+
this.resetModifiedNodeId();
|
|
346
|
+
historyService.reset();
|
|
347
|
+
|
|
348
|
+
this.emit('remove', node);
|
|
349
|
+
|
|
350
|
+
return node;
|
|
288
351
|
}
|
|
289
352
|
} else {
|
|
290
353
|
await this.select(parent);
|
|
@@ -294,6 +357,8 @@ class Editor extends BaseService {
|
|
|
294
357
|
this.addModifiedNodeId(parent.id);
|
|
295
358
|
this.pushHistoryState();
|
|
296
359
|
|
|
360
|
+
this.emit('remove', node);
|
|
361
|
+
|
|
297
362
|
return node;
|
|
298
363
|
}
|
|
299
364
|
|
|
@@ -355,6 +420,8 @@ class Editor extends BaseService {
|
|
|
355
420
|
this.addModifiedNodeId(newConfig.id);
|
|
356
421
|
this.pushHistoryState();
|
|
357
422
|
|
|
423
|
+
this.emit('update', newConfig);
|
|
424
|
+
|
|
358
425
|
return newConfig;
|
|
359
426
|
}
|
|
360
427
|
|
|
@@ -432,7 +499,7 @@ class Editor extends BaseService {
|
|
|
432
499
|
public async alignCenter(config: MNode): Promise<MNode | void> {
|
|
433
500
|
const parent = this.get<MContainer>('parent');
|
|
434
501
|
const node = this.get<MNode>('node');
|
|
435
|
-
const layout = await this.getLayout(parent);
|
|
502
|
+
const layout = await this.getLayout(toRaw(parent), toRaw(node));
|
|
436
503
|
if (layout === Layout.RELATIVE) {
|
|
437
504
|
return;
|
|
438
505
|
}
|
|
@@ -490,6 +557,26 @@ class Editor extends BaseService {
|
|
|
490
557
|
return value;
|
|
491
558
|
}
|
|
492
559
|
|
|
560
|
+
public async move(left: number, top: number) {
|
|
561
|
+
const node = toRaw(this.get('node'));
|
|
562
|
+
if (!node || isPage(node)) return;
|
|
563
|
+
|
|
564
|
+
const { style, id } = node;
|
|
565
|
+
if (!style || style.position !== 'absolute') return;
|
|
566
|
+
|
|
567
|
+
if (top && !isNumber(style.top)) return;
|
|
568
|
+
if (left && !isNumber(style.left)) return;
|
|
569
|
+
|
|
570
|
+
this.update({
|
|
571
|
+
id,
|
|
572
|
+
style: {
|
|
573
|
+
...style,
|
|
574
|
+
left: Number(style.left) + left,
|
|
575
|
+
top: Number(style.top) + top,
|
|
576
|
+
},
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
493
580
|
public destroy() {
|
|
494
581
|
this.removeAllListeners();
|
|
495
582
|
this.set('root', null);
|
package/src/services/history.ts
CHANGED
|
@@ -51,6 +51,13 @@ class History extends BaseService {
|
|
|
51
51
|
this.on('change', this.setCanUndoRedo);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
public reset() {
|
|
55
|
+
this.state.pageSteps = {};
|
|
56
|
+
this.state.pageId = undefined;
|
|
57
|
+
this.state.canRedo = false;
|
|
58
|
+
this.state.canUndo = false;
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
public changePage(page: MPage): void {
|
|
55
62
|
if (!page) return;
|
|
56
63
|
|
package/src/services/props.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
|
-
import { cloneDeep } from 'lodash-es';
|
|
20
|
+
import { cloneDeep, mergeWith } from 'lodash-es';
|
|
21
21
|
|
|
22
22
|
import type { FormConfig } from '@tmagic/form';
|
|
23
23
|
import type { MComponent, MNode } from '@tmagic/schema';
|
|
@@ -100,8 +100,7 @@ class Props extends BaseService {
|
|
|
100
100
|
|
|
101
101
|
return cloneDeep({
|
|
102
102
|
...getDefaultPropsValue(type),
|
|
103
|
-
...defaultValue,
|
|
104
|
-
...(this.state.propsValueMap[type] || {}),
|
|
103
|
+
...mergeWith(this.state.propsValueMap[type] || {}, defaultValue),
|
|
105
104
|
});
|
|
106
105
|
}
|
|
107
106
|
}
|
package/src/services/ui.ts
CHANGED
|
@@ -91,6 +91,11 @@ class Ui extends BaseService {
|
|
|
91
91
|
return (state as any)[name];
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
public zoom(zoom: number) {
|
|
95
|
+
this.set('zoom', (this.get<number>('zoom') * 100 + zoom * 100) / 100);
|
|
96
|
+
if (this.get<number>('zoom') < 0.1) this.set('zoom', 0.1);
|
|
97
|
+
}
|
|
98
|
+
|
|
94
99
|
private setColumnWidth({ left, center, right }: SetColumnWidth) {
|
|
95
100
|
const columnWidth = {
|
|
96
101
|
...toRaw(this.get<GetColumnWidth>('columnWidth')),
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
top: 0;
|
|
13
13
|
left: 0;
|
|
14
14
|
box-sizing: border-box;
|
|
15
|
+
z-index: 1;
|
|
15
16
|
|
|
16
17
|
.el-input__prefix {
|
|
17
18
|
padding: 10px;
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
color: $--font-color;
|
|
63
64
|
flex-direction: column;
|
|
64
65
|
width: 42px;
|
|
66
|
+
cursor: pointer;
|
|
65
67
|
|
|
66
68
|
i {
|
|
67
69
|
font-size: 20px;
|