@tmagic/editor 1.0.0-beta.9 → 1.0.0-rc.3
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/README.md +1 -0
- package/coverage/clover.xml +1556 -0
- package/coverage/coverage-final.json +36 -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 +814 -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 +343 -0
- package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
- package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +319 -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 +226 -0
- package/coverage/lcov-report/src/layouts/sidebar/TabPane.vue.html +289 -0
- package/coverage/lcov-report/src/layouts/sidebar/index.html +176 -0
- package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
- package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +766 -0
- package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
- package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +604 -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 +580 -0
- package/coverage/lcov-report/src/type.ts.html +850 -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.info +3747 -0
- package/dist/style.css +68 -36
- package/dist/tmagic-editor.es.js +1431 -2048
- package/dist/tmagic-editor.es.js.map +1 -1
- package/dist/tmagic-editor.umd.js +1431 -2048
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/dist/types/src/Editor.vue.d.ts +15 -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/Framework.vue.d.ts +15 -3
- package/dist/types/src/layouts/PropsPanel.vue.d.ts +2 -1
- package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -1
- 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 +10 -3
- package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +9 -8
- package/dist/types/src/services/BaseService.d.ts +4 -1
- 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 +2 -0
- package/dist/types/src/type.d.ts +15 -9
- package/dist/types/src/utils/editor.d.ts +4 -3
- package/dist/types/src/utils/polyfills.d.ts +0 -0
- package/package.json +44 -12
- package/src/Editor.vue +10 -1
- package/src/components/ContentMenu.vue +107 -0
- package/src/components/ScrollViewer.vue +1 -1
- package/src/components/ToolButton.vue +69 -30
- package/src/fields/UISelect.vue +14 -6
- package/src/index.ts +2 -0
- package/src/layouts/CodeEditor.vue +20 -13
- package/src/layouts/Framework.vue +20 -7
- package/src/layouts/PropsPanel.vue +5 -4
- package/src/layouts/sidebar/ComponentListPanel.vue +25 -3
- package/src/layouts/sidebar/LayerMenu.vue +91 -96
- package/src/layouts/sidebar/LayerPanel.vue +31 -54
- package/src/layouts/sidebar/Sidebar.vue +13 -52
- package/src/layouts/sidebar/TabPane.vue +68 -0
- package/src/layouts/workspace/PageBar.vue +136 -13
- package/src/layouts/workspace/Stage.vue +53 -75
- package/src/layouts/workspace/ViewerMenu.vue +104 -67
- package/src/layouts/workspace/Workspace.vue +111 -22
- package/src/services/BaseService.ts +70 -22
- package/src/services/editor.ts +148 -39
- package/src/services/history.ts +7 -0
- package/src/services/props.ts +3 -3
- package/src/services/ui.ts +35 -5
- 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 +35 -3
- package/src/theme/props-panel.scss +19 -17
- package/src/type.ts +16 -9
- package/src/utils/editor.ts +31 -6
- package/src/utils/polyfills.ts +8 -0
- package/src/utils/props.ts +20 -1
- package/dist/types/src/layouts/sidebar/LayerMenu.vue.d.ts +0 -31
- package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -979
- package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -193
- package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -30
|
@@ -1,115 +1,110 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<div
|
|
4
|
-
v-if="node.items"
|
|
5
|
-
class="magic-editor-content-menu-item"
|
|
6
|
-
@mouseenter="setSubVisiable(true)"
|
|
7
|
-
@mouseleave="setSubVisiable(false)"
|
|
8
|
-
>
|
|
9
|
-
新增
|
|
10
|
-
</div>
|
|
11
|
-
<div v-if="node.type !== 'app'" class="magic-editor-content-menu-item" @click="() => copy(node)">复制</div>
|
|
12
|
-
<div
|
|
13
|
-
v-if="node.type !== 'app' && node.type !== 'page'"
|
|
14
|
-
class="magic-editor-content-menu-item"
|
|
15
|
-
@click="() => remove()"
|
|
16
|
-
>
|
|
17
|
-
删除
|
|
18
|
-
</div>
|
|
19
|
-
<div class="subMenu" v-show="subVisible" @mouseenter="setSubVisiable(true)" @mouseleave="setSubVisiable(false)">
|
|
20
|
-
<el-scrollbar>
|
|
21
|
-
<template v-if="node.type === 'tabs'">
|
|
22
|
-
<div
|
|
23
|
-
class="magic-editor-content-menu-item"
|
|
24
|
-
@click="
|
|
25
|
-
() =>
|
|
26
|
-
append({
|
|
27
|
-
type: 'tab-pane',
|
|
28
|
-
})
|
|
29
|
-
"
|
|
30
|
-
>
|
|
31
|
-
标签
|
|
32
|
-
</div>
|
|
33
|
-
</template>
|
|
34
|
-
|
|
35
|
-
<template v-else-if="node.type === 'app'">
|
|
36
|
-
<div
|
|
37
|
-
class="magic-editor-content-menu-item"
|
|
38
|
-
v-for="item in menu.app"
|
|
39
|
-
:key="item.type"
|
|
40
|
-
@click="() => append(item)"
|
|
41
|
-
>
|
|
42
|
-
{{ item.text }}
|
|
43
|
-
</div>
|
|
44
|
-
</template>
|
|
45
|
-
|
|
46
|
-
<template v-else-if="node.items">
|
|
47
|
-
<div v-for="list in menu.component" :key="list.title">
|
|
48
|
-
<template v-for="item in list.items">
|
|
49
|
-
<div class="magic-editor-content-menu-item" v-if="item" :key="item.type" @click="() => append(item)">
|
|
50
|
-
{{ item.text }}
|
|
51
|
-
</div>
|
|
52
|
-
</template>
|
|
53
|
-
<div class="separation"></div>
|
|
54
|
-
</div>
|
|
55
|
-
</template>
|
|
56
|
-
</el-scrollbar>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
2
|
+
<content-menu :menu-data="menuData" ref="menu" style="overflow: initial"></content-menu>
|
|
59
3
|
</template>
|
|
60
4
|
|
|
61
5
|
<script lang="ts">
|
|
62
|
-
import { computed, defineComponent, inject,
|
|
6
|
+
import { computed, defineComponent, inject, markRaw, ref } from 'vue';
|
|
7
|
+
import { Delete, DocumentCopy, Files, Plus } from '@element-plus/icons';
|
|
63
8
|
|
|
64
|
-
import
|
|
9
|
+
import { NodeType } from '@tmagic/schema';
|
|
65
10
|
|
|
66
|
-
|
|
67
|
-
|
|
11
|
+
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
12
|
+
import type { ComponentGroup, MenuButton, MenuItem, Services } from '@editor/type';
|
|
68
13
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
type: Array as PropType<ComponentGroup[]>,
|
|
72
|
-
default: () => [],
|
|
73
|
-
},
|
|
74
|
-
},
|
|
14
|
+
export default defineComponent({
|
|
15
|
+
components: { ContentMenu },
|
|
75
16
|
|
|
76
|
-
setup(
|
|
17
|
+
setup() {
|
|
77
18
|
const services = inject<Services>('services');
|
|
78
|
-
const
|
|
19
|
+
const menu = ref<InstanceType<typeof ContentMenu>>();
|
|
79
20
|
const node = computed(() => services?.editorService.get('node'));
|
|
21
|
+
const isRoot = computed(() => node.value?.type === NodeType.ROOT);
|
|
22
|
+
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
23
|
+
const componentList = computed(() => services?.componentListService.getList() || []);
|
|
80
24
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
25
|
+
const createMenuItems = (group: ComponentGroup): MenuButton[] =>
|
|
26
|
+
group.items.map((component) => ({
|
|
27
|
+
text: component.text,
|
|
28
|
+
type: 'button',
|
|
29
|
+
icon: component.icon,
|
|
30
|
+
handler: () => {
|
|
31
|
+
services?.editorService.add({
|
|
32
|
+
name: component.text,
|
|
33
|
+
type: component.type,
|
|
34
|
+
...(component.data || {}),
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
85
38
|
|
|
86
|
-
|
|
87
|
-
|
|
39
|
+
const getSubMenuData = computed<MenuButton[]>(() => {
|
|
40
|
+
if (node.value?.type === 'tabs') {
|
|
41
|
+
return [
|
|
88
42
|
{
|
|
89
|
-
|
|
90
|
-
|
|
43
|
+
text: '标签页',
|
|
44
|
+
type: 'button',
|
|
45
|
+
icon: Files,
|
|
46
|
+
handler: () => {
|
|
47
|
+
services?.editorService.add({
|
|
48
|
+
type: 'tab-pane',
|
|
49
|
+
});
|
|
50
|
+
},
|
|
91
51
|
},
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
if (node.value?.items) {
|
|
55
|
+
return (
|
|
56
|
+
componentList.value.reduce(
|
|
57
|
+
(subMenuData: MenuButton[], group: ComponentGroup, index) =>
|
|
58
|
+
subMenuData.concat(
|
|
59
|
+
createMenuItems(group),
|
|
60
|
+
index < componentList.value.length - 1
|
|
61
|
+
? [
|
|
62
|
+
{
|
|
63
|
+
type: 'divider',
|
|
64
|
+
direction: 'horizontal',
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
: [],
|
|
68
|
+
),
|
|
69
|
+
[],
|
|
70
|
+
) || []
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return [];
|
|
74
|
+
});
|
|
95
75
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
76
|
+
return {
|
|
77
|
+
menu,
|
|
78
|
+
menuData: computed<MenuItem[]>(() => [
|
|
79
|
+
{
|
|
80
|
+
type: 'button',
|
|
81
|
+
text: '新增',
|
|
82
|
+
icon: markRaw(Plus),
|
|
83
|
+
display: () => node.value?.items,
|
|
84
|
+
items: getSubMenuData.value,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: 'button',
|
|
88
|
+
text: '复制',
|
|
89
|
+
icon: markRaw(DocumentCopy),
|
|
90
|
+
display: () => !isRoot.value,
|
|
91
|
+
handler: () => {
|
|
92
|
+
node.value && services?.editorService.copy(node.value);
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
type: 'button',
|
|
97
|
+
text: '删除',
|
|
98
|
+
icon: markRaw(Delete),
|
|
99
|
+
display: () => !isRoot.value && !isPage.value,
|
|
100
|
+
handler: () => {
|
|
101
|
+
node.value && services?.editorService.remove(node.value);
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
]),
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
show(e: MouseEvent) {
|
|
107
|
+
menu.value?.show(e);
|
|
113
108
|
},
|
|
114
109
|
};
|
|
115
110
|
},
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
ref="tree"
|
|
15
15
|
node-key="id"
|
|
16
16
|
draggable
|
|
17
|
+
:default-expanded-keys="expandedKeys"
|
|
17
18
|
:load="loadItems"
|
|
18
19
|
:data="values"
|
|
19
20
|
:expand-on-click-node="false"
|
|
@@ -32,8 +33,8 @@
|
|
|
32
33
|
<div
|
|
33
34
|
:id="data.id"
|
|
34
35
|
class="cus-tree-node"
|
|
35
|
-
@mousedown="
|
|
36
|
-
@mouseup="
|
|
36
|
+
@mousedown="toggleClickFlag"
|
|
37
|
+
@mouseup="toggleClickFlag"
|
|
37
38
|
@mouseenter="highlightHandler(data)"
|
|
38
39
|
:class="{ 'cus-tree-node-hover': canHighlight && data.id === highlightNode?.id }"
|
|
39
40
|
>
|
|
@@ -47,18 +48,19 @@
|
|
|
47
48
|
</el-tree>
|
|
48
49
|
|
|
49
50
|
<teleport to="body">
|
|
50
|
-
<layer-menu
|
|
51
|
+
<layer-menu ref="menu"></layer-menu>
|
|
51
52
|
</teleport>
|
|
52
53
|
</el-scrollbar>
|
|
53
54
|
</template>
|
|
54
55
|
|
|
55
56
|
<script lang="ts">
|
|
56
|
-
import { computed, defineComponent, inject,
|
|
57
|
+
import { computed, defineComponent, inject, Ref, ref, watchEffect } from 'vue';
|
|
57
58
|
import type { ElTree } from 'element-plus';
|
|
58
59
|
import { throttle } from 'lodash-es';
|
|
59
60
|
|
|
60
61
|
import type { MNode, MPage } from '@tmagic/schema';
|
|
61
62
|
import { NodeType } from '@tmagic/schema';
|
|
63
|
+
import StageCore from '@tmagic/stage';
|
|
62
64
|
|
|
63
65
|
import type { EditorService } from '@editor/services/editor';
|
|
64
66
|
import type { Services } from '@editor/type';
|
|
@@ -67,12 +69,13 @@ import LayerMenu from './LayerMenu.vue';
|
|
|
67
69
|
|
|
68
70
|
const throttleTime = 150;
|
|
69
71
|
|
|
70
|
-
const select = (data: MNode, editorService?: EditorService) => {
|
|
72
|
+
const select = async (data: MNode, editorService?: EditorService) => {
|
|
71
73
|
if (!data.id) {
|
|
72
74
|
throw new Error('没有id');
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
editorService?.select(data);
|
|
77
|
+
await editorService?.select(data);
|
|
78
|
+
editorService?.get<StageCore>('stage')?.select(data.id);
|
|
76
79
|
};
|
|
77
80
|
|
|
78
81
|
const highlight = (data: MNode, editorService?: EditorService) => {
|
|
@@ -80,6 +83,7 @@ const highlight = (data: MNode, editorService?: EditorService) => {
|
|
|
80
83
|
throw new Error('没有id');
|
|
81
84
|
}
|
|
82
85
|
editorService?.highlight(data);
|
|
86
|
+
editorService?.get<StageCore>('stage')?.highlight(data.id);
|
|
83
87
|
};
|
|
84
88
|
|
|
85
89
|
const useDrop = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorService?: EditorService) => ({
|
|
@@ -140,6 +144,7 @@ const useStatus = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorSer
|
|
|
140
144
|
|
|
141
145
|
highlightNode,
|
|
142
146
|
clickNode: node,
|
|
147
|
+
expandedKeys: computed(() => (node.value ? [node.value.id] : [])),
|
|
143
148
|
};
|
|
144
149
|
};
|
|
145
150
|
|
|
@@ -153,12 +158,10 @@ const useFilter = (tree: Ref<InstanceType<typeof ElTree> | undefined>) => ({
|
|
|
153
158
|
let name = '';
|
|
154
159
|
if (data.name) {
|
|
155
160
|
name = data.name;
|
|
156
|
-
} else if (data.type) {
|
|
157
|
-
name = data.type;
|
|
158
161
|
} else if (data.items) {
|
|
159
162
|
name = 'container';
|
|
160
163
|
}
|
|
161
|
-
return name.indexOf(value) !== -1;
|
|
164
|
+
return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
|
|
162
165
|
},
|
|
163
166
|
|
|
164
167
|
filterTextChangeHandler(val: string) {
|
|
@@ -166,46 +169,6 @@ const useFilter = (tree: Ref<InstanceType<typeof ElTree> | undefined>) => ({
|
|
|
166
169
|
},
|
|
167
170
|
});
|
|
168
171
|
|
|
169
|
-
const useContentMenu = (editorService?: EditorService) => {
|
|
170
|
-
const menuStyle = ref({
|
|
171
|
-
position: 'absolute',
|
|
172
|
-
left: '0',
|
|
173
|
-
top: '0',
|
|
174
|
-
display: 'none',
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
onMounted(() => {
|
|
178
|
-
document.addEventListener(
|
|
179
|
-
'click',
|
|
180
|
-
() => {
|
|
181
|
-
menuStyle.value.display = 'none';
|
|
182
|
-
},
|
|
183
|
-
true,
|
|
184
|
-
);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
return {
|
|
188
|
-
menuStyle,
|
|
189
|
-
|
|
190
|
-
contextmenu(event: MouseEvent, data: MNode) {
|
|
191
|
-
const bodyHeight = globalThis.document.body.clientHeight;
|
|
192
|
-
|
|
193
|
-
const left = `${event.clientX + 20}px`;
|
|
194
|
-
let top = `${event.clientY - 10}px`;
|
|
195
|
-
|
|
196
|
-
if (event.clientY + 300 > bodyHeight) {
|
|
197
|
-
top = `${bodyHeight - 300}px`;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
menuStyle.value.left = left;
|
|
201
|
-
menuStyle.value.top = top;
|
|
202
|
-
menuStyle.value.display = '';
|
|
203
|
-
|
|
204
|
-
select(data, editorService);
|
|
205
|
-
},
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
|
-
|
|
209
172
|
export default defineComponent({
|
|
210
173
|
name: 'magic-editor-layer-panel',
|
|
211
174
|
|
|
@@ -214,13 +177,14 @@ export default defineComponent({
|
|
|
214
177
|
setup() {
|
|
215
178
|
const services = inject<Services>('services');
|
|
216
179
|
const tree = ref<InstanceType<typeof ElTree>>();
|
|
180
|
+
const menu = ref<InstanceType<typeof LayerMenu>>();
|
|
217
181
|
const clicked = ref(false);
|
|
218
182
|
const editorService = services?.editorService;
|
|
219
183
|
const highlightHandler = throttle((data: MNode) => {
|
|
220
184
|
highlight(data, editorService);
|
|
221
185
|
}, throttleTime);
|
|
222
186
|
|
|
223
|
-
const
|
|
187
|
+
const toggleClickFlag = () => {
|
|
224
188
|
clicked.value = !clicked.value;
|
|
225
189
|
};
|
|
226
190
|
|
|
@@ -229,12 +193,22 @@ export default defineComponent({
|
|
|
229
193
|
() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value,
|
|
230
194
|
);
|
|
231
195
|
|
|
196
|
+
editorService?.on('remove', () => {
|
|
197
|
+
setTimeout(() => {
|
|
198
|
+
tree.value?.getNode(editorService.get('node').id)?.updateChildren();
|
|
199
|
+
}, 0);
|
|
200
|
+
});
|
|
201
|
+
|
|
232
202
|
return {
|
|
233
203
|
tree,
|
|
204
|
+
menu,
|
|
234
205
|
...statusData,
|
|
235
206
|
...useDrop(tree, editorService),
|
|
236
207
|
...useFilter(tree),
|
|
237
|
-
|
|
208
|
+
|
|
209
|
+
highlightHandler,
|
|
210
|
+
toggleClickFlag,
|
|
211
|
+
canHighlight,
|
|
238
212
|
|
|
239
213
|
clickHandler(data: MNode): void {
|
|
240
214
|
if (services?.uiService.get<boolean>('uiSelectMode')) {
|
|
@@ -244,9 +218,12 @@ export default defineComponent({
|
|
|
244
218
|
tree.value?.setCurrentKey(data.id);
|
|
245
219
|
select(data, editorService);
|
|
246
220
|
},
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
221
|
+
|
|
222
|
+
async contextmenu(event: MouseEvent, data: MNode) {
|
|
223
|
+
event.preventDefault();
|
|
224
|
+
await select(data, editorService);
|
|
225
|
+
menu.value?.show(event);
|
|
226
|
+
},
|
|
250
227
|
};
|
|
251
228
|
},
|
|
252
229
|
});
|
|
@@ -1,36 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-tabs
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<component :is="item.component" v-bind="item.props || {}" v-on="item.listeners || {}">
|
|
12
|
-
<template #layer-node-content="{ data, node }" v-if="item.slots?.layerNodeContent">
|
|
13
|
-
<component :is="item.slots.layerNodeContent" :data="data" :node="node" />
|
|
14
|
-
</template>
|
|
15
|
-
</component>
|
|
16
|
-
</el-tab-pane>
|
|
2
|
+
<el-tabs
|
|
3
|
+
v-if="data.type === 'tabs' && data.items.length"
|
|
4
|
+
class="m-editor-sidebar"
|
|
5
|
+
v-model="activeTabName"
|
|
6
|
+
type="card"
|
|
7
|
+
tab-position="left"
|
|
8
|
+
>
|
|
9
|
+
<tab-pane v-for="(item, index) in data.items" :key="index" :data="item"></tab-pane>
|
|
17
10
|
</el-tabs>
|
|
18
11
|
</template>
|
|
19
12
|
|
|
20
13
|
<script lang="ts">
|
|
21
|
-
import {
|
|
22
|
-
import { Coin, Files } from '@element-plus/icons';
|
|
14
|
+
import { defineComponent, PropType, ref, watch } from 'vue';
|
|
23
15
|
|
|
24
|
-
import
|
|
25
|
-
import { SideBarData, SideComponent } from '@editor/type';
|
|
16
|
+
import { SideBarData } from '@editor/type';
|
|
26
17
|
|
|
27
|
-
import
|
|
28
|
-
import LayerPanel from './LayerPanel.vue';
|
|
18
|
+
import TabPane from './TabPane.vue';
|
|
29
19
|
|
|
30
20
|
export default defineComponent({
|
|
31
|
-
|
|
21
|
+
components: { TabPane },
|
|
32
22
|
|
|
33
|
-
|
|
23
|
+
name: 'm-sidebar',
|
|
34
24
|
|
|
35
25
|
props: {
|
|
36
26
|
data: {
|
|
@@ -51,35 +41,6 @@ export default defineComponent({
|
|
|
51
41
|
|
|
52
42
|
return {
|
|
53
43
|
activeTabName,
|
|
54
|
-
|
|
55
|
-
items: computed<SideComponent[] | Record<string, any>[]>(() =>
|
|
56
|
-
props.data?.items.map((item) => {
|
|
57
|
-
if (typeof item !== 'string') {
|
|
58
|
-
return item;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
switch (item) {
|
|
62
|
-
case 'component-list':
|
|
63
|
-
return {
|
|
64
|
-
type: 'component',
|
|
65
|
-
icon: Coin,
|
|
66
|
-
text: '组件',
|
|
67
|
-
component: ComponentListPanel,
|
|
68
|
-
slots: {},
|
|
69
|
-
};
|
|
70
|
-
case 'layer':
|
|
71
|
-
return {
|
|
72
|
-
type: 'component',
|
|
73
|
-
icon: Files,
|
|
74
|
-
text: '已选组件',
|
|
75
|
-
component: LayerPanel,
|
|
76
|
-
slots: {},
|
|
77
|
-
};
|
|
78
|
-
default:
|
|
79
|
-
return {};
|
|
80
|
-
}
|
|
81
|
-
}),
|
|
82
|
-
),
|
|
83
44
|
};
|
|
84
45
|
},
|
|
85
46
|
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-tab-pane v-if="config" :name="config.text">
|
|
3
|
+
<template #label>
|
|
4
|
+
<div :key="config.text">
|
|
5
|
+
<m-icon v-if="config.icon" :icon="config.icon"></m-icon>
|
|
6
|
+
<div v-if="config.text" class="magic-editor-tab-panel-title">{{ config.text }}</div>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<component :is="config.component" v-bind="config.props || {}" v-on="config?.listeners || {}">
|
|
11
|
+
<template #layer-node-content="{ data, node }" v-if="config.slots?.layerNodeContent">
|
|
12
|
+
<component :is="config.slots?.layerNodeContent" :data="data" :node="node" />
|
|
13
|
+
</template>
|
|
14
|
+
</component>
|
|
15
|
+
</el-tab-pane>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script lang="ts">
|
|
19
|
+
import { computed, defineComponent, PropType } from 'vue';
|
|
20
|
+
import { Coin, Files } from '@element-plus/icons';
|
|
21
|
+
|
|
22
|
+
import MIcon from '@editor/components/Icon.vue';
|
|
23
|
+
import { SideComponent, SideItem } from '@editor/type';
|
|
24
|
+
|
|
25
|
+
import ComponentListPanel from './ComponentListPanel.vue';
|
|
26
|
+
import LayerPanel from './LayerPanel.vue';
|
|
27
|
+
|
|
28
|
+
export default defineComponent({
|
|
29
|
+
components: { MIcon },
|
|
30
|
+
|
|
31
|
+
props: {
|
|
32
|
+
data: {
|
|
33
|
+
type: Object as PropType<SideItem>,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
setup(props) {
|
|
38
|
+
return {
|
|
39
|
+
config: computed<SideComponent | undefined>(() => {
|
|
40
|
+
if (typeof props.data !== 'string') {
|
|
41
|
+
return props.data;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
switch (props.data) {
|
|
45
|
+
case 'component-list':
|
|
46
|
+
return {
|
|
47
|
+
type: 'component',
|
|
48
|
+
icon: Coin,
|
|
49
|
+
text: '组件',
|
|
50
|
+
component: ComponentListPanel,
|
|
51
|
+
slots: {},
|
|
52
|
+
};
|
|
53
|
+
case 'layer':
|
|
54
|
+
return {
|
|
55
|
+
type: 'component',
|
|
56
|
+
icon: Files,
|
|
57
|
+
text: '已选组件',
|
|
58
|
+
component: LayerPanel,
|
|
59
|
+
slots: {},
|
|
60
|
+
};
|
|
61
|
+
default:
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
}),
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
</script>
|