@tmagic/editor 1.0.0-beta.13 → 1.0.0-beta.16
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 +703 -601
- package/coverage/coverage-final.json +35 -33
- package/coverage/lcov-report/index.html +56 -56
- package/coverage/lcov-report/src/Editor.vue.html +1 -1
- package/coverage/lcov-report/{layouts/sidebar/LayerMenu.vue.html → src/components/ContentMenu.vue.html} +137 -95
- package/coverage/lcov-report/src/components/Icon.vue.html +5 -5
- package/coverage/lcov-report/src/components/ScrollViewer.vue.html +1 -1
- package/coverage/lcov-report/src/components/ToolButton.vue.html +180 -63
- package/coverage/lcov-report/src/components/index.html +34 -19
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +1 -1
- package/coverage/lcov-report/src/layouts/Framework.vue.html +13 -13
- package/coverage/lcov-report/src/layouts/NavMenu.vue.html +1 -1
- package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +1 -1
- package/coverage/lcov-report/src/layouts/Resizer.vue.html +1 -1
- package/coverage/lcov-report/src/layouts/index.html +15 -15
- package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +78 -12
- package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +149 -92
- package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +43 -121
- package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +23 -140
- package/coverage/lcov-report/{utils/undo-redo.ts.html → src/layouts/sidebar/TabPane.vue.html} +94 -118
- package/coverage/lcov-report/src/layouts/sidebar/index.html +64 -49
- package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +99 -12
- package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +86 -95
- package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +208 -97
- package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +3 -3
- package/coverage/lcov-report/src/layouts/workspace/index.html +35 -35
- package/coverage/lcov-report/src/services/BaseService.ts.html +11 -11
- package/coverage/lcov-report/src/services/componentList.ts.html +1 -1
- package/coverage/lcov-report/src/services/editor.ts.html +103 -10
- package/coverage/lcov-report/src/services/events.ts.html +1 -1
- package/coverage/lcov-report/src/services/history.ts.html +29 -8
- package/coverage/lcov-report/src/services/index.html +25 -25
- package/coverage/lcov-report/src/services/props.ts.html +4 -7
- package/coverage/lcov-report/src/services/ui.ts.html +1 -1
- package/coverage/lcov-report/src/type.ts.html +8 -14
- package/coverage/lcov-report/src/utils/compose.ts.html +4 -4
- package/coverage/lcov-report/src/utils/config.ts.html +1 -1
- package/coverage/lcov-report/src/utils/editor.ts.html +2 -2
- package/coverage/lcov-report/src/utils/index.html +1 -1
- package/coverage/lcov-report/src/utils/index.ts.html +1 -1
- package/coverage/lcov-report/src/utils/logger.ts.html +1 -1
- package/coverage/lcov-report/src/utils/props.ts.html +59 -2
- package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +1 -1
- package/coverage/lcov-report/src/utils/undo-redo.ts.html +1 -1
- package/coverage/lcov.info +1679 -1402
- package/dist/style.css +47 -20
- package/dist/tmagic-editor.es.js +732 -485
- package/dist/tmagic-editor.es.js.map +1 -1
- package/dist/tmagic-editor.umd.js +733 -485
- 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/fields/UISelect.vue.d.ts +4 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/layouts/CodeEditor.vue.d.ts +13 -4
- package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -0
- package/dist/types/src/layouts/sidebar/Sidebar.vue.d.ts +2 -3
- package/dist/types/src/layouts/sidebar/TabPane.vue.d.ts +14 -0
- package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +2 -0
- package/dist/types/src/services/history.d.ts +1 -0
- package/dist/types/src/services/props.d.ts +2 -2
- package/dist/types/src/type.d.ts +6 -8
- package/dist/types/src/utils/polyfills.d.ts +0 -0
- package/package.json +15 -10
- package/src/components/ContentMenu.vue +107 -0
- package/src/components/ToolButton.vue +66 -27
- package/src/fields/UISelect.vue +14 -6
- package/src/index.ts +2 -0
- package/src/layouts/CodeEditor.vue +20 -10
- 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/sidebar/Sidebar.vue +13 -52
- package/src/layouts/sidebar/TabPane.vue +68 -0
- 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 +2 -2
- package/src/services/editor.ts +33 -2
- package/src/services/history.ts +7 -0
- package/src/services/props.ts +2 -3
- 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 +1 -1
- package/src/theme/nav-menu.scss +6 -2
- package/src/theme/page-bar.scss +22 -1
- package/src/theme/props-panel.scss +4 -0
- package/src/type.ts +6 -8
- package/src/utils/editor.ts +1 -1
- package/src/utils/polyfills.ts +22 -0
- package/src/utils/props.ts +19 -0
- package/coverage/lcov-report/Icon.vue.html +0 -172
- package/coverage/lcov-report/ToolButton.vue.html +0 -655
- package/coverage/lcov-report/layouts/sidebar/index.html +0 -116
- package/coverage/lcov-report/utils/index.html +0 -116
- 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
|
@@ -22,11 +22,25 @@
|
|
|
22
22
|
</slot>
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
|
-
<el-popover placement="top" :width="160" trigger="hover">
|
|
25
|
+
<el-popover popper-class="page-bar-popover" placement="top" :width="160" trigger="hover">
|
|
26
26
|
<div>
|
|
27
27
|
<slot name="page-bar-popover" :page="item">
|
|
28
|
-
<
|
|
29
|
-
|
|
28
|
+
<tool-button
|
|
29
|
+
:data="{
|
|
30
|
+
type: 'button',
|
|
31
|
+
text: '复制',
|
|
32
|
+
icon: DocumentCopy,
|
|
33
|
+
handler: () => copy(item),
|
|
34
|
+
}"
|
|
35
|
+
></tool-button>
|
|
36
|
+
<tool-button
|
|
37
|
+
:data="{
|
|
38
|
+
type: 'button',
|
|
39
|
+
text: '删除',
|
|
40
|
+
icon: Delete,
|
|
41
|
+
handler: () => remove(item),
|
|
42
|
+
}"
|
|
43
|
+
></tool-button>
|
|
30
44
|
</slot>
|
|
31
45
|
</div>
|
|
32
46
|
<template #reference>
|
|
@@ -44,12 +58,24 @@
|
|
|
44
58
|
</template>
|
|
45
59
|
|
|
46
60
|
<script lang="ts">
|
|
47
|
-
import {
|
|
48
|
-
|
|
61
|
+
import {
|
|
62
|
+
computed,
|
|
63
|
+
ComputedRef,
|
|
64
|
+
defineComponent,
|
|
65
|
+
inject,
|
|
66
|
+
markRaw,
|
|
67
|
+
onMounted,
|
|
68
|
+
onUnmounted,
|
|
69
|
+
ref,
|
|
70
|
+
toRaw,
|
|
71
|
+
watch,
|
|
72
|
+
} from 'vue';
|
|
73
|
+
import { ArrowLeftBold, ArrowRightBold, CaretBottom, Delete, DocumentCopy, Plus } from '@element-plus/icons';
|
|
49
74
|
|
|
50
75
|
import type { MApp, MPage } from '@tmagic/schema';
|
|
51
76
|
import { NodeType } from '@tmagic/schema';
|
|
52
77
|
|
|
78
|
+
import ToolButton from '@editor/components/ToolButton.vue';
|
|
53
79
|
import type { Services } from '@editor/type';
|
|
54
80
|
import { generatePageNameByApp } from '@editor/utils/editor';
|
|
55
81
|
|
|
@@ -138,7 +164,7 @@ const useScroll = (root: ComputedRef<MApp | undefined>) => {
|
|
|
138
164
|
};
|
|
139
165
|
|
|
140
166
|
export default defineComponent({
|
|
141
|
-
components: { ArrowLeftBold, ArrowRightBold, CaretBottom, Plus },
|
|
167
|
+
components: { ArrowLeftBold, ArrowRightBold, CaretBottom, Plus, ToolButton },
|
|
142
168
|
|
|
143
169
|
setup() {
|
|
144
170
|
const services = inject<Services>('services');
|
|
@@ -147,6 +173,9 @@ export default defineComponent({
|
|
|
147
173
|
const root = computed(() => editorService?.get<MApp>('root'));
|
|
148
174
|
|
|
149
175
|
return {
|
|
176
|
+
Delete: markRaw(Delete),
|
|
177
|
+
DocumentCopy: markRaw(DocumentCopy),
|
|
178
|
+
|
|
150
179
|
...useScroll(root),
|
|
151
180
|
|
|
152
181
|
root,
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
<div
|
|
10
10
|
class="m-editor-stage-container"
|
|
11
11
|
ref="stageContainer"
|
|
12
|
-
@contextmenu="contextmenuHandler"
|
|
13
12
|
:style="`transform: scale(${zoom})`"
|
|
13
|
+
@contextmenu="contextmenuHandler"
|
|
14
|
+
@drop="dropHandler"
|
|
15
|
+
@dragover="dragoverHandler"
|
|
14
16
|
></div>
|
|
15
17
|
<teleport to="body">
|
|
16
|
-
<viewer-menu ref="menu"
|
|
18
|
+
<viewer-menu ref="menu"></viewer-menu>
|
|
17
19
|
</teleport>
|
|
18
20
|
</scroll-viewer>
|
|
19
21
|
</template>
|
|
@@ -39,49 +41,10 @@ import type { MoveableOptions, Runtime, SortEventData, UpdateEventData } from '@
|
|
|
39
41
|
import StageCore from '@tmagic/stage';
|
|
40
42
|
|
|
41
43
|
import ScrollViewer from '@editor/components/ScrollViewer.vue';
|
|
42
|
-
import
|
|
44
|
+
import { Layout, Services, StageRect } from '@editor/type';
|
|
43
45
|
|
|
44
46
|
import ViewerMenu from './ViewerMenu.vue';
|
|
45
47
|
|
|
46
|
-
const useMenu = () => {
|
|
47
|
-
const menu = ref<InstanceType<typeof ViewerMenu>>();
|
|
48
|
-
const menuStyle = ref({
|
|
49
|
-
display: 'none',
|
|
50
|
-
left: '0',
|
|
51
|
-
top: '0',
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
onMounted(() => {
|
|
55
|
-
document.addEventListener(
|
|
56
|
-
'click',
|
|
57
|
-
() => {
|
|
58
|
-
menuStyle.value.display = 'none';
|
|
59
|
-
},
|
|
60
|
-
true,
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
menu,
|
|
66
|
-
menuStyle,
|
|
67
|
-
|
|
68
|
-
contextmenuHandler(e: MouseEvent) {
|
|
69
|
-
e.preventDefault();
|
|
70
|
-
|
|
71
|
-
const menuHeight = menu.value?.$el.clientHeight;
|
|
72
|
-
let top = e.clientY;
|
|
73
|
-
if (menuHeight + e.clientY > document.body.clientHeight) {
|
|
74
|
-
top = document.body.clientHeight - menuHeight;
|
|
75
|
-
}
|
|
76
|
-
menuStyle.value = {
|
|
77
|
-
display: 'block',
|
|
78
|
-
top: `${top}px`,
|
|
79
|
-
left: `${e.clientX}px`,
|
|
80
|
-
};
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
|
|
85
48
|
export default defineComponent({
|
|
86
49
|
name: 'magic-stage',
|
|
87
50
|
|
|
@@ -115,12 +78,13 @@ export default defineComponent({
|
|
|
115
78
|
|
|
116
79
|
const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
|
|
117
80
|
const stageContainer = ref<HTMLDivElement>();
|
|
81
|
+
const menu = ref<InstanceType<typeof ViewerMenu>>();
|
|
118
82
|
|
|
119
83
|
const stageRect = computed(() => services?.uiService.get<StageRect>('stageRect'));
|
|
120
84
|
const uiSelectMode = computed(() => services?.uiService.get<boolean>('uiSelectMode'));
|
|
121
85
|
const root = computed(() => services?.editorService.get<MApp>('root'));
|
|
122
86
|
const page = computed(() => services?.editorService.get<MPage>('page'));
|
|
123
|
-
const zoom = computed(() => services?.uiService.get<number>('zoom'));
|
|
87
|
+
const zoom = computed(() => services?.uiService.get<number>('zoom') || 1);
|
|
124
88
|
const node = computed(() => services?.editorService.get<MNode>('node'));
|
|
125
89
|
|
|
126
90
|
let stage: StageCore | null = null;
|
|
@@ -218,9 +182,42 @@ export default defineComponent({
|
|
|
218
182
|
return {
|
|
219
183
|
stageWrap,
|
|
220
184
|
stageContainer,
|
|
185
|
+
menu,
|
|
221
186
|
stageRect,
|
|
222
187
|
zoom,
|
|
223
|
-
|
|
188
|
+
|
|
189
|
+
contextmenuHandler(e: MouseEvent) {
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
menu.value?.show(e);
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
dragoverHandler(e: DragEvent) {
|
|
195
|
+
e.preventDefault();
|
|
196
|
+
if (e.dataTransfer) {
|
|
197
|
+
e.dataTransfer.dropEffect = 'move';
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
async dropHandler(e: DragEvent) {
|
|
202
|
+
e.preventDefault();
|
|
203
|
+
if (e.dataTransfer && page.value && stageContainer.value && stage) {
|
|
204
|
+
// eslint-disable-next-line no-eval
|
|
205
|
+
const config = eval(`(${e.dataTransfer.getData('data')})`);
|
|
206
|
+
const layout = await services?.editorService.getLayout(page.value);
|
|
207
|
+
|
|
208
|
+
const containerRect = stageContainer.value.getBoundingClientRect();
|
|
209
|
+
const { scrollTop, scrollLeft } = stage.mask;
|
|
210
|
+
if (layout === Layout.ABSOLUTE) {
|
|
211
|
+
config.style = {
|
|
212
|
+
position: 'absolute',
|
|
213
|
+
top: e.clientY - containerRect.top + scrollTop,
|
|
214
|
+
left: e.clientX - containerRect.left + scrollLeft,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
services?.editorService.add(config, page.value);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
224
221
|
};
|
|
225
222
|
},
|
|
226
223
|
});
|
|
@@ -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
|
},
|
|
@@ -84,11 +84,11 @@ export default defineComponent({
|
|
|
84
84
|
e.inputEvent.preventDefault();
|
|
85
85
|
node.value && services?.editorService.copy(node.value);
|
|
86
86
|
})
|
|
87
|
-
.
|
|
87
|
+
.keydown([ctrl, 'v'], (e) => {
|
|
88
88
|
e.inputEvent.preventDefault();
|
|
89
89
|
node.value && services?.editorService.paste();
|
|
90
90
|
})
|
|
91
|
-
.
|
|
91
|
+
.keydown([ctrl, 'x'], (e) => {
|
|
92
92
|
e.inputEvent.preventDefault();
|
|
93
93
|
if (!node.value || isPage(node.value)) return;
|
|
94
94
|
services?.editorService.copy(node.value);
|
package/src/services/editor.ts
CHANGED
|
@@ -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
|
}
|
|
@@ -190,6 +193,9 @@ class Editor extends BaseService {
|
|
|
190
193
|
} else {
|
|
191
194
|
historyService.empty();
|
|
192
195
|
}
|
|
196
|
+
|
|
197
|
+
this.emit('select', node);
|
|
198
|
+
|
|
193
199
|
return node!;
|
|
194
200
|
}
|
|
195
201
|
|
|
@@ -249,8 +255,9 @@ class Editor extends BaseService {
|
|
|
249
255
|
const curNode = this.get<MContainer>('node');
|
|
250
256
|
|
|
251
257
|
let parentNode: MNode | undefined;
|
|
258
|
+
const isPage = type === NodeType.PAGE;
|
|
252
259
|
|
|
253
|
-
if (
|
|
260
|
+
if (isPage) {
|
|
254
261
|
parentNode = this.get<MApp>('root');
|
|
255
262
|
// 由于支持中间件扩展,在parent参数为undefined时,parent会变成next函数
|
|
256
263
|
} else if (parent && typeof parent !== 'function') {
|
|
@@ -284,12 +291,18 @@ class Editor extends BaseService {
|
|
|
284
291
|
await this.select(newNode);
|
|
285
292
|
|
|
286
293
|
this.addModifiedNodeId(newNode.id);
|
|
287
|
-
if (
|
|
294
|
+
if (!isPage) {
|
|
288
295
|
this.pushHistoryState();
|
|
289
296
|
}
|
|
290
297
|
|
|
291
298
|
stage?.select(newNode.id);
|
|
292
299
|
|
|
300
|
+
if (isPage) {
|
|
301
|
+
this.state.pageLength += 1;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
this.emit('add', newNode);
|
|
305
|
+
|
|
293
306
|
return newNode;
|
|
294
307
|
}
|
|
295
308
|
|
|
@@ -318,9 +331,23 @@ class Editor extends BaseService {
|
|
|
318
331
|
stage?.remove({ id: node.id, root: this.get('root') });
|
|
319
332
|
|
|
320
333
|
if (node.type === NodeType.PAGE) {
|
|
334
|
+
this.state.pageLength -= 1;
|
|
335
|
+
|
|
321
336
|
if (root.items[0]) {
|
|
322
337
|
await this.select(root.items[0]);
|
|
323
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;
|
|
324
351
|
}
|
|
325
352
|
} else {
|
|
326
353
|
await this.select(parent);
|
|
@@ -330,6 +357,8 @@ class Editor extends BaseService {
|
|
|
330
357
|
this.addModifiedNodeId(parent.id);
|
|
331
358
|
this.pushHistoryState();
|
|
332
359
|
|
|
360
|
+
this.emit('remove', node);
|
|
361
|
+
|
|
333
362
|
return node;
|
|
334
363
|
}
|
|
335
364
|
|
|
@@ -391,6 +420,8 @@ class Editor extends BaseService {
|
|
|
391
420
|
this.addModifiedNodeId(newConfig.id);
|
|
392
421
|
this.pushHistoryState();
|
|
393
422
|
|
|
423
|
+
this.emit('update', newConfig);
|
|
424
|
+
|
|
394
425
|
return newConfig;
|
|
395
426
|
}
|
|
396
427
|
|
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
|
}
|
|
@@ -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;
|
|
@@ -2,38 +2,45 @@
|
|
|
2
2
|
position: fixed;
|
|
3
3
|
font-size: 12px;
|
|
4
4
|
background: #fff;
|
|
5
|
-
color: #333;
|
|
6
5
|
box-shadow: 0 2px 8px 2px rgba(68, 73, 77, 0.16);
|
|
7
6
|
z-index: 9999;
|
|
8
7
|
transform-origin: 0% 0%;
|
|
9
8
|
font-weight: 600;
|
|
10
9
|
padding: 4px 0px;
|
|
10
|
+
overflow: auto;
|
|
11
|
+
max-height: 100%;
|
|
11
12
|
|
|
12
|
-
.
|
|
13
|
-
width: 100%;
|
|
14
|
-
height: 0;
|
|
15
|
-
border-color: rgba(155, 155, 155, 0.1);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.subMenu {
|
|
19
|
-
position: absolute;
|
|
20
|
-
right: 0;
|
|
21
|
-
transform: translate(100%, 0);
|
|
22
|
-
background-color: #fff;
|
|
13
|
+
.menu-item {
|
|
23
14
|
color: #333;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
display: flex;
|
|
16
|
+
-webkit-box-align: center;
|
|
17
|
+
align-items: center;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
min-width: 140px;
|
|
20
|
+
transition: all 0.2s ease 0s;
|
|
21
|
+
padding: 5px 14px;
|
|
22
|
+
border-left: 2px solid transparent;
|
|
23
|
+
|
|
24
|
+
.el-button {
|
|
25
|
+
width: 100%;
|
|
26
|
+
justify-content: flex-start;
|
|
27
|
+
}
|
|
29
28
|
|
|
30
|
-
.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
.el-button--text,
|
|
30
|
+
i {
|
|
31
|
+
color: $--font-color;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&.divider {
|
|
35
|
+
padding: 0 14px;
|
|
36
|
+
|
|
37
|
+
.el-divider {
|
|
38
|
+
margin: 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:hover {
|
|
43
|
+
background-color: $--hover-color;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
39
46
|
}
|
package/src/theme/nav-menu.scss
CHANGED
|
@@ -43,13 +43,17 @@
|
|
|
43
43
|
display: flex !important;
|
|
44
44
|
transition: all 0.3s ease 0s;
|
|
45
45
|
border-bottom: 2px solid transparent;
|
|
46
|
-
margin: 0
|
|
46
|
+
margin: 0;
|
|
47
47
|
|
|
48
48
|
.is-disabled {
|
|
49
49
|
opacity: 0.5;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
.
|
|
52
|
+
.is-text {
|
|
53
|
+
padding: 5px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.is-text,
|
|
53
57
|
i {
|
|
54
58
|
color: $--font-color;
|
|
55
59
|
}
|