@tmagic/editor 1.1.0-beta.6 → 1.1.0-beta.9
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 +322 -320
- package/dist/tmagic-editor.mjs.map +1 -1
- package/dist/tmagic-editor.umd.js +321 -318
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/package.json +7 -7
- package/src/Editor.vue +8 -2
- package/src/components/Icon.vue +1 -1
- package/src/fields/UISelect.vue +0 -1
- package/src/index.ts +1 -1
- package/src/layouts/workspace/PageBar.vue +43 -161
- package/src/layouts/workspace/PageBarScrollContainer.vue +111 -0
- package/src/layouts/workspace/Stage.vue +6 -2
- package/src/layouts/workspace/ViewerMenu.vue +7 -10
- package/src/layouts/workspace/Workspace.vue +1 -1
- package/src/services/editor.ts +158 -106
- package/src/theme/component-list-panel.scss +5 -0
- package/src/type.ts +2 -1
- package/src/utils/editor.ts +17 -10
- package/src/utils/operator.ts +21 -122
- package/types/Editor.vue.d.ts +10 -1
- package/types/fields/UISelect.vue.d.ts +0 -4
- package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +48 -0
- package/types/layouts/workspace/ViewerMenu.vue.d.ts +3 -3
- package/types/services/editor.d.ts +9 -17
- package/types/type.d.ts +2 -1
- package/types/utils/editor.d.ts +4 -1
- package/types/utils/operator.d.ts +3 -26
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.1.0-beta.
|
|
2
|
+
"version": "1.1.0-beta.9",
|
|
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.9",
|
|
49
|
+
"@tmagic/form": "1.1.0-beta.9",
|
|
50
|
+
"@tmagic/schema": "1.1.0-beta.9",
|
|
51
|
+
"@tmagic/stage": "1.1.0-beta.9",
|
|
52
|
+
"@tmagic/utils": "1.1.0-beta.9",
|
|
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.9",
|
|
66
66
|
"element-plus": "^2.2.6",
|
|
67
67
|
"monaco-editor": "^0.32.1",
|
|
68
68
|
"vue": "^3.2.37"
|
package/src/Editor.vue
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
<template #props-panel>
|
|
32
32
|
<slot name="props-panel">
|
|
33
|
-
<props-panel ref="propsPanel" @mounted="(instance) => $emit('props-panel-mounted', instance)">
|
|
33
|
+
<props-panel ref="propsPanel" @mounted="(instance: any) => $emit('props-panel-mounted', instance)">
|
|
34
34
|
<template #props-panel-header>
|
|
35
35
|
<slot name="props-panel-header"></slot>
|
|
36
36
|
</template>
|
|
@@ -49,7 +49,7 @@ import { EventOption } from '@tmagic/core';
|
|
|
49
49
|
import type { FormConfig } from '@tmagic/form';
|
|
50
50
|
import type { MApp, MNode } from '@tmagic/schema';
|
|
51
51
|
import type StageCore from '@tmagic/stage';
|
|
52
|
-
import { CONTAINER_HIGHLIGHT_CLASS, MoveableOptions } from '@tmagic/stage';
|
|
52
|
+
import { CONTAINER_HIGHLIGHT_CLASS, ContainerHighlightType, MoveableOptions } from '@tmagic/stage';
|
|
53
53
|
|
|
54
54
|
import Framework from './layouts/Framework.vue';
|
|
55
55
|
import NavMenu from './layouts/NavMenu.vue';
|
|
@@ -170,6 +170,11 @@ export default defineComponent({
|
|
|
170
170
|
default: 800,
|
|
171
171
|
},
|
|
172
172
|
|
|
173
|
+
containerHighlightType: {
|
|
174
|
+
type: String as PropType<ContainerHighlightType>,
|
|
175
|
+
default: ContainerHighlightType.DEFAULT,
|
|
176
|
+
},
|
|
177
|
+
|
|
173
178
|
stageRect: {
|
|
174
179
|
type: [String, Object] as PropType<StageRect>,
|
|
175
180
|
},
|
|
@@ -289,6 +294,7 @@ export default defineComponent({
|
|
|
289
294
|
isContainer: props.isContainer,
|
|
290
295
|
containerHighlightClassName: props.containerHighlightClassName,
|
|
291
296
|
containerHighlightDuration: props.containerHighlightDuration,
|
|
297
|
+
containerHighlightType: props.containerHighlightType,
|
|
292
298
|
}),
|
|
293
299
|
);
|
|
294
300
|
|
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>
|
package/src/fields/UISelect.vue
CHANGED
package/src/index.ts
CHANGED
|
@@ -58,7 +58,7 @@ export default {
|
|
|
58
58
|
setConfig(option);
|
|
59
59
|
|
|
60
60
|
app.component(Editor.name, Editor);
|
|
61
|
-
app.component(
|
|
61
|
+
app.component('m-fields-ui-select', uiSelect);
|
|
62
62
|
app.component(CodeLink.name, CodeLink);
|
|
63
63
|
app.component(Code.name, Code);
|
|
64
64
|
app.component(CodeEditor.name, CodeEditor);
|
|
@@ -1,191 +1,73 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<div id="m-editor-page-bar-add-icon" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="addPage">
|
|
4
|
-
<el-icon><plus></plus></el-icon>
|
|
5
|
-
</div>
|
|
2
|
+
<PageBarScrollContainer>
|
|
6
3
|
<div
|
|
7
|
-
v-
|
|
8
|
-
class="m-editor-page-bar-item
|
|
9
|
-
|
|
4
|
+
v-for="item in (root && root.items) || []"
|
|
5
|
+
class="m-editor-page-bar-item"
|
|
6
|
+
:key="item.key"
|
|
7
|
+
:class="{ active: page?.id === item.id }"
|
|
8
|
+
@click="switchPage(item)"
|
|
10
9
|
>
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
10
|
+
<div class="m-editor-page-bar-title">
|
|
11
|
+
<slot name="page-bar-title" :page="item">
|
|
12
|
+
<el-tooltip effect="dark" placement="top-start" :content="item.name">
|
|
13
|
+
<span>{{ item.name }}</span>
|
|
14
|
+
</el-tooltip>
|
|
15
|
+
</slot>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<el-popover popper-class="page-bar-popover" placement="top" :width="160" trigger="hover">
|
|
19
|
+
<div>
|
|
20
|
+
<slot name="page-bar-popover" :page="item">
|
|
21
|
+
<tool-button
|
|
22
|
+
:data="{
|
|
23
|
+
type: 'button',
|
|
24
|
+
text: '复制',
|
|
25
|
+
icon: DocumentCopy,
|
|
26
|
+
handler: () => copy(item),
|
|
27
|
+
}"
|
|
28
|
+
></tool-button>
|
|
29
|
+
<tool-button
|
|
30
|
+
:data="{
|
|
31
|
+
type: 'button',
|
|
32
|
+
text: '删除',
|
|
33
|
+
icon: Delete,
|
|
34
|
+
handler: () => remove(item),
|
|
35
|
+
}"
|
|
36
|
+
></tool-button>
|
|
31
37
|
</slot>
|
|
32
38
|
</div>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
type: 'button',
|
|
40
|
-
text: '复制',
|
|
41
|
-
icon: DocumentCopy,
|
|
42
|
-
handler: () => copy(item),
|
|
43
|
-
}"
|
|
44
|
-
></tool-button>
|
|
45
|
-
<tool-button
|
|
46
|
-
:data="{
|
|
47
|
-
type: 'button',
|
|
48
|
-
text: '删除',
|
|
49
|
-
icon: Delete,
|
|
50
|
-
handler: () => remove(item),
|
|
51
|
-
}"
|
|
52
|
-
></tool-button>
|
|
53
|
-
</slot>
|
|
54
|
-
</div>
|
|
55
|
-
<template #reference>
|
|
56
|
-
<el-icon class="m-editor-page-bar-menu-icon">
|
|
57
|
-
<caret-bottom></caret-bottom>
|
|
58
|
-
</el-icon>
|
|
59
|
-
</template>
|
|
60
|
-
</el-popover>
|
|
61
|
-
</div>
|
|
39
|
+
<template #reference>
|
|
40
|
+
<el-icon class="m-editor-page-bar-menu-icon">
|
|
41
|
+
<caret-bottom></caret-bottom>
|
|
42
|
+
</el-icon>
|
|
43
|
+
</template>
|
|
44
|
+
</el-popover>
|
|
62
45
|
</div>
|
|
63
|
-
|
|
64
|
-
v-if="scrollState.canScroll"
|
|
65
|
-
class="m-editor-page-bar-item m-editor-page-bar-item-icon"
|
|
66
|
-
@click="scrollState.scroll('right')"
|
|
67
|
-
>
|
|
68
|
-
<el-icon><arrow-right-bold></arrow-right-bold></el-icon>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
46
|
+
</PageBarScrollContainer>
|
|
71
47
|
</template>
|
|
72
48
|
|
|
73
49
|
<script lang="ts" setup>
|
|
74
|
-
import { computed,
|
|
75
|
-
import {
|
|
50
|
+
import { computed, inject } from 'vue';
|
|
51
|
+
import { CaretBottom, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
|
76
52
|
|
|
77
53
|
import type { MApp, MPage } from '@tmagic/schema';
|
|
78
|
-
import { NodeType } from '@tmagic/schema';
|
|
79
54
|
|
|
80
55
|
import ToolButton from '../../components/ToolButton.vue';
|
|
81
56
|
import type { Services } from '../../type';
|
|
82
|
-
import { generatePageNameByApp } from '../../utils/editor';
|
|
83
|
-
|
|
84
|
-
const useScroll = (root: ComputedRef<MApp | undefined>) => {
|
|
85
|
-
const pageBar = ref<HTMLDivElement>();
|
|
86
|
-
const itemsContainer = ref<HTMLDivElement>();
|
|
87
|
-
|
|
88
|
-
const pageBarWidth = ref(0);
|
|
89
|
-
const canScroll = ref(false);
|
|
90
|
-
|
|
91
|
-
const itemsContainerWidth = computed(() => pageBarWidth.value - 105);
|
|
92
|
-
|
|
93
|
-
let translateLeft = 0;
|
|
94
|
-
const resizeObserver = new ResizeObserver((entries) => {
|
|
95
|
-
for (const { contentRect } of entries) {
|
|
96
|
-
const { width } = contentRect;
|
|
97
|
-
pageBarWidth.value = width || 0;
|
|
98
|
-
|
|
99
|
-
setCanScroll();
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
57
|
|
|
103
|
-
|
|
104
|
-
if (itemsContainer.value) {
|
|
105
|
-
canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
|
|
110
|
-
if (!itemsContainer.value) return;
|
|
111
|
-
|
|
112
|
-
const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
|
|
113
|
-
|
|
114
|
-
if (type === 'left') {
|
|
115
|
-
translateLeft += 100;
|
|
116
|
-
|
|
117
|
-
if (translateLeft > 0) {
|
|
118
|
-
translateLeft = 0;
|
|
119
|
-
}
|
|
120
|
-
} else if (type === 'right') {
|
|
121
|
-
translateLeft -= 100;
|
|
122
|
-
|
|
123
|
-
if (-translateLeft > maxScrollLeft) {
|
|
124
|
-
translateLeft = -maxScrollLeft;
|
|
125
|
-
}
|
|
126
|
-
} else if (type === 'start') {
|
|
127
|
-
translateLeft = 0;
|
|
128
|
-
} else if (type === 'end') {
|
|
129
|
-
translateLeft = -maxScrollLeft;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
onMounted(() => {
|
|
136
|
-
pageBar.value && resizeObserver.observe(pageBar.value);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
onUnmounted(() => {
|
|
140
|
-
resizeObserver.disconnect();
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
watch(
|
|
144
|
-
() => root.value?.items.length,
|
|
145
|
-
(length = 0, preLength = 0) => {
|
|
146
|
-
setTimeout(() => {
|
|
147
|
-
setCanScroll();
|
|
148
|
-
if (length < preLength) {
|
|
149
|
-
scroll('start');
|
|
150
|
-
} else {
|
|
151
|
-
scroll('end');
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
},
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
pageBar,
|
|
159
|
-
itemsContainer,
|
|
160
|
-
canScroll,
|
|
161
|
-
|
|
162
|
-
itemsContainerWidth,
|
|
163
|
-
|
|
164
|
-
scroll,
|
|
165
|
-
};
|
|
166
|
-
};
|
|
58
|
+
import PageBarScrollContainer from './PageBarScrollContainer.vue';
|
|
167
59
|
|
|
168
60
|
const services = inject<Services>('services');
|
|
169
61
|
const editorService = services?.editorService;
|
|
170
62
|
|
|
171
63
|
const root = computed(() => editorService?.get<MApp>('root'));
|
|
172
64
|
|
|
173
|
-
const scrollState = useScroll(root);
|
|
174
65
|
const page = computed(() => editorService?.get('page'));
|
|
175
66
|
|
|
176
67
|
const switchPage = (page: MPage) => {
|
|
177
68
|
editorService?.select(page);
|
|
178
69
|
};
|
|
179
70
|
|
|
180
|
-
const addPage = () => {
|
|
181
|
-
if (!editorService) return;
|
|
182
|
-
const pageConfig = {
|
|
183
|
-
type: NodeType.PAGE,
|
|
184
|
-
name: generatePageNameByApp(toRaw(editorService.get('root'))),
|
|
185
|
-
};
|
|
186
|
-
editorService.add(pageConfig);
|
|
187
|
-
};
|
|
188
|
-
|
|
189
71
|
const copy = (node: MPage) => {
|
|
190
72
|
node && editorService?.copy(node);
|
|
191
73
|
editorService?.paste({
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-editor-page-bar" ref="pageBar">
|
|
3
|
+
<div id="m-editor-page-bar-add-icon" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="addPage">
|
|
4
|
+
<el-icon><plus></plus></el-icon>
|
|
5
|
+
</div>
|
|
6
|
+
<div v-if="canScroll" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="scroll('left')">
|
|
7
|
+
<el-icon><arrow-left-bold></arrow-left-bold></el-icon>
|
|
8
|
+
</div>
|
|
9
|
+
<div v-if="root" class="m-editor-page-bar-items" ref="itemsContainer" :style="`width: ${itemsContainerWidth}px`">
|
|
10
|
+
<slot></slot>
|
|
11
|
+
</div>
|
|
12
|
+
<div v-if="canScroll" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="scroll('right')">
|
|
13
|
+
<el-icon><arrow-right-bold></arrow-right-bold></el-icon>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup lang="ts">
|
|
19
|
+
import { computed, inject, onMounted, onUnmounted, ref, toRaw, watch } from 'vue';
|
|
20
|
+
import { ArrowLeftBold, ArrowRightBold, Plus } from '@element-plus/icons-vue';
|
|
21
|
+
|
|
22
|
+
import { MApp, NodeType } from '@tmagic/schema';
|
|
23
|
+
|
|
24
|
+
import type { Services } from '../../type';
|
|
25
|
+
import { generatePageNameByApp } from '../../utils/editor';
|
|
26
|
+
|
|
27
|
+
const services = inject<Services>('services');
|
|
28
|
+
const editorService = services?.editorService;
|
|
29
|
+
|
|
30
|
+
const pageBar = ref<HTMLDivElement>();
|
|
31
|
+
const itemsContainer = ref<HTMLDivElement>();
|
|
32
|
+
const pageBarWidth = ref(0);
|
|
33
|
+
const canScroll = ref(false);
|
|
34
|
+
|
|
35
|
+
const itemsContainerWidth = computed(() => pageBarWidth.value - 105);
|
|
36
|
+
|
|
37
|
+
let translateLeft = 0;
|
|
38
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
39
|
+
for (const { contentRect } of entries) {
|
|
40
|
+
const { width } = contentRect;
|
|
41
|
+
pageBarWidth.value = width || 0;
|
|
42
|
+
|
|
43
|
+
setCanScroll();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const setCanScroll = () => {
|
|
48
|
+
if (itemsContainer.value) {
|
|
49
|
+
canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
|
|
54
|
+
if (!itemsContainer.value) return;
|
|
55
|
+
|
|
56
|
+
const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
|
|
57
|
+
|
|
58
|
+
if (type === 'left') {
|
|
59
|
+
translateLeft += 100;
|
|
60
|
+
|
|
61
|
+
if (translateLeft > 0) {
|
|
62
|
+
translateLeft = 0;
|
|
63
|
+
}
|
|
64
|
+
} else if (type === 'right') {
|
|
65
|
+
translateLeft -= 100;
|
|
66
|
+
|
|
67
|
+
if (-translateLeft > maxScrollLeft) {
|
|
68
|
+
translateLeft = -maxScrollLeft;
|
|
69
|
+
}
|
|
70
|
+
} else if (type === 'start') {
|
|
71
|
+
translateLeft = 0;
|
|
72
|
+
} else if (type === 'end') {
|
|
73
|
+
translateLeft = -maxScrollLeft;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
onMounted(() => {
|
|
80
|
+
pageBar.value && resizeObserver.observe(pageBar.value);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
onUnmounted(() => {
|
|
84
|
+
resizeObserver.disconnect();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const root = computed(() => editorService?.get<MApp>('root'));
|
|
88
|
+
|
|
89
|
+
watch(
|
|
90
|
+
() => root.value?.items.length,
|
|
91
|
+
(length = 0, preLength = 0) => {
|
|
92
|
+
setTimeout(() => {
|
|
93
|
+
setCanScroll();
|
|
94
|
+
if (length < preLength) {
|
|
95
|
+
scroll('start');
|
|
96
|
+
} else {
|
|
97
|
+
scroll('end');
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const addPage = () => {
|
|
104
|
+
if (!editorService) return;
|
|
105
|
+
const pageConfig = {
|
|
106
|
+
type: NodeType.PAGE,
|
|
107
|
+
name: generatePageNameByApp(toRaw(editorService.get('root'))),
|
|
108
|
+
};
|
|
109
|
+
editorService.add(pageConfig);
|
|
110
|
+
};
|
|
111
|
+
</script>
|
|
@@ -81,6 +81,7 @@ watchEffect(() => {
|
|
|
81
81
|
isContainer: stageOptions.isContainer,
|
|
82
82
|
containerHighlightClassName: stageOptions.containerHighlightClassName,
|
|
83
83
|
containerHighlightDuration: stageOptions.containerHighlightDuration,
|
|
84
|
+
containerHighlightType: stageOptions.containerHighlightType,
|
|
84
85
|
canSelect: (el, event, stop) => {
|
|
85
86
|
const elCanSelect = stageOptions.canSelect(el);
|
|
86
87
|
// 在组件联动过程中不能再往下选择,返回并触发 ui-select
|
|
@@ -118,10 +119,13 @@ watchEffect(() => {
|
|
|
118
119
|
|
|
119
120
|
stage?.on('update', (ev: UpdateEventData) => {
|
|
120
121
|
if (ev.parentEl) {
|
|
121
|
-
|
|
122
|
+
for (const data of ev.data) {
|
|
123
|
+
services?.editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
|
|
124
|
+
}
|
|
122
125
|
return;
|
|
123
126
|
}
|
|
124
|
-
|
|
127
|
+
|
|
128
|
+
services?.editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
|
|
125
129
|
});
|
|
126
130
|
|
|
127
131
|
stage?.on('sort', (ev: SortEventData) => {
|
|
@@ -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';
|
|
@@ -34,10 +34,10 @@ const menuData = reactive<MenuItem[]>([
|
|
|
34
34
|
{
|
|
35
35
|
type: 'button',
|
|
36
36
|
text: '水平居中',
|
|
37
|
-
display: () => canCenter.value
|
|
37
|
+
display: () => canCenter.value,
|
|
38
38
|
handler: () => {
|
|
39
|
-
if (!
|
|
40
|
-
editorService?.alignCenter(
|
|
39
|
+
if (!nodes.value) return;
|
|
40
|
+
editorService?.alignCenter(nodes.value);
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
{
|
|
@@ -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();
|