@tmagic/editor 1.0.0-beta.8 → 1.0.0-rc.2
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 +802 -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 +760 -0
- package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
- package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +598 -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 +91 -45
- package/dist/tmagic-editor.es.js +1462 -2003
- package/dist/tmagic-editor.es.js.map +1 -1
- package/dist/tmagic-editor.umd.js +1461 -2003
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/dist/types/src/Editor.vue.d.ts +10 -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 +4 -6
- package/dist/types/src/services/BaseService.d.ts +4 -1
- package/dist/types/src/services/editor.d.ts +16 -6
- 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 +16 -9
- package/dist/types/src/utils/editor.d.ts +5 -4
- package/dist/types/src/utils/polyfills.d.ts +0 -0
- package/package.json +44 -12
- package/src/Editor.vue +6 -1
- package/src/components/ContentMenu.vue +107 -0
- package/src/components/ScrollViewer.vue +1 -1
- package/src/components/ToolButton.vue +72 -31
- package/src/fields/UISelect.vue +14 -6
- package/src/index.ts +2 -0
- package/src/layouts/AddPageBox.vue +3 -1
- 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 +80 -59
- package/src/layouts/sidebar/Sidebar.vue +13 -52
- package/src/layouts/sidebar/TabPane.vue +68 -0
- package/src/layouts/workspace/PageBar.vue +145 -17
- package/src/layouts/workspace/Stage.vue +56 -64
- package/src/layouts/workspace/ViewerMenu.vue +107 -68
- package/src/layouts/workspace/Workspace.vue +110 -18
- package/src/services/BaseService.ts +70 -22
- package/src/services/editor.ts +197 -64
- 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 +3 -2
- package/src/theme/component-list-panel.scss +2 -0
- package/src/theme/content-menu.scss +33 -26
- package/src/theme/layer-panel.scss +10 -0
- package/src/theme/nav-menu.scss +6 -2
- package/src/theme/page-bar.scss +42 -2
- package/src/theme/props-panel.scss +19 -17
- package/src/type.ts +17 -9
- package/src/utils/editor.ts +35 -9
- 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 -973
- package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -192
- package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
- package/tsconfig.json +0 -9
- package/vite.config.ts +0 -30
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="menuData.length" v-show="visible" class="magic-editor-content-menu" ref="menu" :style="menuStyle">
|
|
3
|
+
<div>
|
|
4
|
+
<tool-button
|
|
5
|
+
v-for="(item, index) in menuData"
|
|
6
|
+
event-type="mouseup"
|
|
7
|
+
:data="item"
|
|
8
|
+
:key="index"
|
|
9
|
+
@mouseup="hide"
|
|
10
|
+
@mouseenter="showSubMenu(item)"
|
|
11
|
+
></tool-button>
|
|
12
|
+
</div>
|
|
13
|
+
<teleport to="body">
|
|
14
|
+
<content-menu class="sub-menu" ref="subMenu" :menu-data="subMenuData"></content-menu>
|
|
15
|
+
</teleport>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script lang="ts">
|
|
20
|
+
import { defineComponent, nextTick, onMounted, PropType, ref } from 'vue';
|
|
21
|
+
|
|
22
|
+
import { MenuButton, MenuItem } from '@editor/type';
|
|
23
|
+
|
|
24
|
+
import ToolButton from './ToolButton.vue';
|
|
25
|
+
|
|
26
|
+
export default defineComponent({
|
|
27
|
+
components: { ToolButton },
|
|
28
|
+
|
|
29
|
+
props: {
|
|
30
|
+
menuData: {
|
|
31
|
+
type: Array as PropType<MenuItem[]>,
|
|
32
|
+
default: () => [],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
setup() {
|
|
37
|
+
const menu = ref<HTMLDivElement>();
|
|
38
|
+
const subMenu = ref<any>();
|
|
39
|
+
const visible = ref(false);
|
|
40
|
+
const subMenuData = ref<MenuItem[]>([]);
|
|
41
|
+
const menuStyle = ref({
|
|
42
|
+
left: '0',
|
|
43
|
+
top: '0',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const hide = () => {
|
|
47
|
+
visible.value = false;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
onMounted(() => {
|
|
51
|
+
globalThis.addEventListener(
|
|
52
|
+
'mousedown',
|
|
53
|
+
(e: MouseEvent) => {
|
|
54
|
+
if (!visible.value || (e.target && menu.value?.contains(e.target as HTMLElement))) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
hide();
|
|
58
|
+
},
|
|
59
|
+
true,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
menu,
|
|
65
|
+
subMenu,
|
|
66
|
+
visible,
|
|
67
|
+
menuStyle,
|
|
68
|
+
subMenuData,
|
|
69
|
+
|
|
70
|
+
hide,
|
|
71
|
+
|
|
72
|
+
show(e: MouseEvent) {
|
|
73
|
+
visible.value = true;
|
|
74
|
+
|
|
75
|
+
nextTick(() => {
|
|
76
|
+
const menuHeight = menu.value?.clientHeight || 0;
|
|
77
|
+
|
|
78
|
+
let top = e.clientY;
|
|
79
|
+
if (menuHeight + e.clientY > document.body.clientHeight) {
|
|
80
|
+
top = document.body.clientHeight - menuHeight;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
menuStyle.value = {
|
|
84
|
+
top: `${top}px`,
|
|
85
|
+
left: `${e.clientX}px`,
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
showSubMenu(item: MenuItem) {
|
|
91
|
+
const menuItem = item as MenuButton;
|
|
92
|
+
if (typeof item !== 'object' || !menuItem.items?.length) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
subMenuData.value = menuItem.items;
|
|
97
|
+
if (menu.value) {
|
|
98
|
+
subMenu.value.show({
|
|
99
|
+
clientX: menu.value.offsetLeft + menu.value.clientWidth,
|
|
100
|
+
clientY: menu.value.offsetTop,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
</script>
|
|
@@ -1,24 +1,37 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
2
|
+
<div
|
|
3
|
+
v-if="display"
|
|
4
|
+
class="menu-item"
|
|
5
|
+
:class="item.type"
|
|
6
|
+
@click="clickHandler(item, $event)"
|
|
7
|
+
@mousedown="mousedownHandler(item, $event)"
|
|
8
|
+
@mouseup="mouseupHandler(item, $event)"
|
|
9
|
+
>
|
|
10
|
+
<el-divider v-if="item.type === 'divider'" :direction="item.direction || 'vertical'"></el-divider>
|
|
4
11
|
<div v-else-if="item.type === 'text'" class="menu-item-text">{{ item.text }}</div>
|
|
5
12
|
|
|
6
13
|
<template v-else-if="item.type === 'zoom'">
|
|
7
|
-
<
|
|
14
|
+
<tool-button
|
|
15
|
+
:data="{ type: 'button', icon: ZoomOut, handler: zoomOutHandler, tooltip: '缩小' }"
|
|
16
|
+
:event-type="eventType"
|
|
17
|
+
></tool-button>
|
|
8
18
|
<span class="menu-item-text" style="margin: 0 5px">{{ parseInt(`${zoom * 100}`, 10) }}%</span>
|
|
9
|
-
<
|
|
19
|
+
<tool-button
|
|
20
|
+
:data="{ type: 'button', icon: ZoomIn, handler: zoomInHandler, tooltip: '放大' }"
|
|
21
|
+
:event-type="eventType"
|
|
22
|
+
></tool-button>
|
|
10
23
|
</template>
|
|
11
24
|
|
|
12
|
-
<
|
|
13
|
-
v-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<el-button size="small"
|
|
19
|
-
><m-icon :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
|
|
25
|
+
<template v-else-if="item.type === 'button'">
|
|
26
|
+
<el-tooltip v-if="item.tooltip" effect="dark" placement="bottom-start" :content="item.tooltip">
|
|
27
|
+
<el-button size="small" text :disabled="disabled"
|
|
28
|
+
><m-icon v-if="item.icon" :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
|
|
29
|
+
>
|
|
30
|
+
</el-tooltip>
|
|
31
|
+
<el-button v-else size="small" text :disabled="disabled"
|
|
32
|
+
><m-icon v-if="item.icon" :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
|
|
20
33
|
>
|
|
21
|
-
</
|
|
34
|
+
</template>
|
|
22
35
|
|
|
23
36
|
<el-dropdown v-else-if="item.type === 'dropdown'" trigger="click" :disabled="disabled" @command="dropdownHandler">
|
|
24
37
|
<span class="el-dropdown-link menubar-menu-button">
|
|
@@ -38,9 +51,11 @@
|
|
|
38
51
|
</template>
|
|
39
52
|
|
|
40
53
|
<script lang="ts">
|
|
41
|
-
import { computed, defineComponent, inject, PropType } from 'vue';
|
|
54
|
+
import { computed, defineComponent, inject, markRaw, PropType } from 'vue';
|
|
42
55
|
import { ArrowDown, Back, Delete, Grid, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons';
|
|
43
56
|
|
|
57
|
+
import { NodeType } from '@tmagic/schema';
|
|
58
|
+
|
|
44
59
|
import MIcon from '@editor/components/Icon.vue';
|
|
45
60
|
import type { MenuButton, MenuComponent, MenuItem, Services } from '@editor/type';
|
|
46
61
|
|
|
@@ -56,19 +71,24 @@ export default defineComponent({
|
|
|
56
71
|
display: false,
|
|
57
72
|
}),
|
|
58
73
|
},
|
|
74
|
+
|
|
75
|
+
eventType: {
|
|
76
|
+
type: String as PropType<'mousedown' | 'mouseup' | 'click'>,
|
|
77
|
+
default: 'click',
|
|
78
|
+
},
|
|
59
79
|
},
|
|
60
80
|
|
|
61
81
|
setup(props) {
|
|
62
82
|
const services = inject<Services>('services');
|
|
63
83
|
const uiService = services?.uiService;
|
|
64
84
|
|
|
65
|
-
const zoomInHandler = () => uiService?.set('zoom', zoom.value + 0.1);
|
|
66
|
-
const zoomOutHandler = () => uiService?.set('zoom', zoom.value - 0.1);
|
|
67
|
-
|
|
68
85
|
const zoom = computed((): number => uiService?.get<number>('zoom') ?? 1);
|
|
69
86
|
const showGuides = computed((): boolean => uiService?.get<boolean>('showGuides') ?? true);
|
|
70
87
|
const showRule = computed((): boolean => uiService?.get<boolean>('showRule') ?? true);
|
|
71
88
|
|
|
89
|
+
const zoomInHandler = () => uiService?.zoom(0.1);
|
|
90
|
+
const zoomOutHandler = () => uiService?.zoom(-0.1);
|
|
91
|
+
|
|
72
92
|
const item = computed((): MenuButton | MenuComponent => {
|
|
73
93
|
if (typeof props.data !== 'string') {
|
|
74
94
|
return props.data;
|
|
@@ -85,15 +105,15 @@ export default defineComponent({
|
|
|
85
105
|
case 'delete':
|
|
86
106
|
return {
|
|
87
107
|
type: 'button',
|
|
88
|
-
icon: Delete,
|
|
108
|
+
icon: markRaw(Delete),
|
|
89
109
|
tooltip: '刪除',
|
|
90
|
-
disabled: () => services?.editorService.get('node')?.type ===
|
|
110
|
+
disabled: () => services?.editorService.get('node')?.type === NodeType.PAGE,
|
|
91
111
|
handler: () => services?.editorService.remove(services?.editorService.get('node')),
|
|
92
112
|
};
|
|
93
113
|
case 'undo':
|
|
94
114
|
return {
|
|
95
115
|
type: 'button',
|
|
96
|
-
icon: Back,
|
|
116
|
+
icon: markRaw(Back),
|
|
97
117
|
tooltip: '后退',
|
|
98
118
|
disabled: () => !services?.historyService.state.canUndo,
|
|
99
119
|
handler: () => services?.editorService.undo(),
|
|
@@ -101,7 +121,7 @@ export default defineComponent({
|
|
|
101
121
|
case 'redo':
|
|
102
122
|
return {
|
|
103
123
|
type: 'button',
|
|
104
|
-
icon: Right,
|
|
124
|
+
icon: markRaw(Right),
|
|
105
125
|
tooltip: '前进',
|
|
106
126
|
disabled: () => !services?.historyService.state.canRedo,
|
|
107
127
|
handler: () => services?.editorService.redo(),
|
|
@@ -109,28 +129,28 @@ export default defineComponent({
|
|
|
109
129
|
case 'zoom-in':
|
|
110
130
|
return {
|
|
111
131
|
type: 'button',
|
|
112
|
-
icon: ZoomIn,
|
|
132
|
+
icon: markRaw(ZoomIn),
|
|
113
133
|
tooltip: '放大',
|
|
114
134
|
handler: zoomInHandler,
|
|
115
135
|
};
|
|
116
136
|
case 'zoom-out':
|
|
117
137
|
return {
|
|
118
138
|
type: 'button',
|
|
119
|
-
icon: ZoomOut,
|
|
139
|
+
icon: markRaw(ZoomOut),
|
|
120
140
|
tooltip: '縮小',
|
|
121
141
|
handler: zoomOutHandler,
|
|
122
142
|
};
|
|
123
143
|
case 'rule':
|
|
124
144
|
return {
|
|
125
145
|
type: 'button',
|
|
126
|
-
icon: ScaleToOriginal,
|
|
146
|
+
icon: markRaw(ScaleToOriginal),
|
|
127
147
|
tooltip: showRule.value ? '隐藏标尺' : '显示标尺',
|
|
128
148
|
handler: () => uiService?.set('showRule', !showRule.value),
|
|
129
149
|
};
|
|
130
150
|
case 'guides':
|
|
131
151
|
return {
|
|
132
152
|
type: 'button',
|
|
133
|
-
icon: Grid,
|
|
153
|
+
icon: markRaw(Grid),
|
|
134
154
|
tooltip: showGuides.value ? '隐藏参考线' : '显示参考线',
|
|
135
155
|
handler: () => uiService?.set('showGuides', !showGuides.value),
|
|
136
156
|
};
|
|
@@ -151,9 +171,16 @@ export default defineComponent({
|
|
|
151
171
|
return item.value.disabled;
|
|
152
172
|
});
|
|
153
173
|
|
|
174
|
+
const buttonHandler = (item: MenuButton | MenuComponent, event: MouseEvent) => {
|
|
175
|
+
if (disabled.value) return;
|
|
176
|
+
if (typeof (item as MenuButton).handler === 'function' && services) {
|
|
177
|
+
(item as MenuButton).handler?.(services, event);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
154
181
|
return {
|
|
155
|
-
ZoomIn,
|
|
156
|
-
ZoomOut,
|
|
182
|
+
ZoomIn: markRaw(ZoomIn),
|
|
183
|
+
ZoomOut: markRaw(ZoomOut),
|
|
157
184
|
|
|
158
185
|
item,
|
|
159
186
|
zoom,
|
|
@@ -176,10 +203,24 @@ export default defineComponent({
|
|
|
176
203
|
}
|
|
177
204
|
},
|
|
178
205
|
|
|
179
|
-
|
|
180
|
-
if (
|
|
181
|
-
if (
|
|
182
|
-
(item
|
|
206
|
+
clickHandler(item: MenuButton | MenuComponent, event: MouseEvent) {
|
|
207
|
+
if (props.eventType !== 'click') return;
|
|
208
|
+
if (item.type === 'button') {
|
|
209
|
+
buttonHandler(item, event);
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
mousedownHandler(item: MenuButton | MenuComponent, event: MouseEvent) {
|
|
214
|
+
if (props.eventType !== 'mousedown') return;
|
|
215
|
+
if (item.type === 'button') {
|
|
216
|
+
buttonHandler(item, event);
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
mouseupHandler(item: MenuButton | MenuComponent, event: MouseEvent) {
|
|
221
|
+
if (props.eventType !== 'mouseup') return;
|
|
222
|
+
if (item.type === 'button') {
|
|
223
|
+
buttonHandler(item, event);
|
|
183
224
|
}
|
|
184
225
|
},
|
|
185
226
|
};
|
package/src/fields/UISelect.vue
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-fields-ui-select" v-if="uiSelectMode" @click="cancelHandler">
|
|
3
|
-
<
|
|
3
|
+
<el-button type="danger" :icon="Delete" text style="padding: 0">取消</el-button>
|
|
4
4
|
</div>
|
|
5
|
-
<div class="m-fields-ui-select" v-else @click="startSelect">
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
<div class="m-fields-ui-select" v-else @click="startSelect" style="display: flex">
|
|
6
|
+
<el-tooltip content="清除">
|
|
7
|
+
<el-button v-if="val" style="padding: 0" type="danger" :icon="Close" text @click.stop="deleteHandler"></el-button>
|
|
8
|
+
</el-tooltip>
|
|
9
|
+
<el-tooltip :content="val ? toName + '_' + val : '点击此处选择'">
|
|
10
|
+
<el-button text style="padding: 0; margin: 0">{{ val ? toName + '_' + val : '点击此处选择' }}</el-button>
|
|
11
|
+
</el-tooltip>
|
|
9
12
|
</div>
|
|
10
13
|
</template>
|
|
11
14
|
|
|
12
15
|
<script lang="ts">
|
|
13
|
-
import { computed, defineComponent, inject, ref } from 'vue';
|
|
16
|
+
import { computed, defineComponent, inject, markRaw, ref } from 'vue';
|
|
17
|
+
import { Close, Delete, Pointer } from '@element-plus/icons';
|
|
14
18
|
|
|
15
19
|
import { FormState } from '@tmagic/form';
|
|
16
20
|
|
|
@@ -60,6 +64,10 @@ export default defineComponent({
|
|
|
60
64
|
};
|
|
61
65
|
|
|
62
66
|
return {
|
|
67
|
+
Delete: markRaw(Delete),
|
|
68
|
+
Pointer: markRaw(Pointer),
|
|
69
|
+
Close: markRaw(Close),
|
|
70
|
+
|
|
63
71
|
val,
|
|
64
72
|
uiSelectMode,
|
|
65
73
|
toName: computed(() => {
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* See the License for the specific language governing permissions and
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
|
+
import './utils/polyfills';
|
|
18
19
|
|
|
19
20
|
import { App } from 'vue';
|
|
20
21
|
|
|
@@ -41,6 +42,7 @@ export { default as uiService } from './services/ui';
|
|
|
41
42
|
export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPanel.vue';
|
|
42
43
|
export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
|
|
43
44
|
export { default as PropsPanel } from './layouts/PropsPanel.vue';
|
|
45
|
+
export { default as ToolButton } from './components/ToolButton.vue';
|
|
44
46
|
|
|
45
47
|
const defaultInstallOpt: InstallOptions = {
|
|
46
48
|
// @todo, 自定义图片上传方法等编辑器依赖的外部选项
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
import { defineComponent, inject, toRaw } from 'vue';
|
|
16
16
|
import { Plus } from '@element-plus/icons';
|
|
17
17
|
|
|
18
|
+
import { NodeType } from '@tmagic/schema';
|
|
19
|
+
|
|
18
20
|
import { Services } from '@editor/type';
|
|
19
21
|
import { generatePageNameByApp } from '@editor/utils';
|
|
20
22
|
|
|
@@ -31,7 +33,7 @@ export default defineComponent({
|
|
|
31
33
|
if (!editorService) return;
|
|
32
34
|
|
|
33
35
|
editorService.add({
|
|
34
|
-
type:
|
|
36
|
+
type: NodeType.PAGE,
|
|
35
37
|
name: generatePageNameByApp(toRaw(editorService.get('root'))),
|
|
36
38
|
});
|
|
37
39
|
},
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
7
|
+
import { throttle } from 'lodash-es';
|
|
7
8
|
import * as monaco from 'monaco-editor';
|
|
8
9
|
import serialize from 'serialize-javascript';
|
|
9
10
|
|
|
@@ -36,14 +37,19 @@ export default defineComponent({
|
|
|
36
37
|
},
|
|
37
38
|
|
|
38
39
|
type: {
|
|
39
|
-
type:
|
|
40
|
+
type: String,
|
|
40
41
|
default: () => '',
|
|
41
42
|
},
|
|
42
43
|
|
|
43
44
|
language: {
|
|
44
|
-
type:
|
|
45
|
+
type: String,
|
|
45
46
|
default: () => 'javascript',
|
|
46
47
|
},
|
|
48
|
+
|
|
49
|
+
options: {
|
|
50
|
+
type: Object,
|
|
51
|
+
default: () => ({}),
|
|
52
|
+
},
|
|
47
53
|
},
|
|
48
54
|
|
|
49
55
|
emits: ['initd', 'save'],
|
|
@@ -51,10 +57,18 @@ export default defineComponent({
|
|
|
51
57
|
setup(props, { emit }) {
|
|
52
58
|
let vsEditor: monaco.editor.IStandaloneCodeEditor | null = null;
|
|
53
59
|
let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
|
|
60
|
+
|
|
54
61
|
const values = ref('');
|
|
55
62
|
const loading = ref(false);
|
|
56
63
|
const codeEditor = ref<HTMLDivElement>();
|
|
57
64
|
|
|
65
|
+
const resizeObserver = new globalThis.ResizeObserver(
|
|
66
|
+
throttle((): void => {
|
|
67
|
+
vsEditor?.layout();
|
|
68
|
+
vsDiffEditor?.layout();
|
|
69
|
+
}, 300),
|
|
70
|
+
);
|
|
71
|
+
|
|
58
72
|
const setEditorValue = (v: string | any, m: string | any) => {
|
|
59
73
|
values.value = toString(v, props.language);
|
|
60
74
|
|
|
@@ -71,11 +85,6 @@ export default defineComponent({
|
|
|
71
85
|
return vsEditor?.setValue(values.value);
|
|
72
86
|
};
|
|
73
87
|
|
|
74
|
-
const resizeHandler = () => {
|
|
75
|
-
vsEditor?.layout();
|
|
76
|
-
vsDiffEditor?.layout();
|
|
77
|
-
};
|
|
78
|
-
|
|
79
88
|
const getEditorValue = () =>
|
|
80
89
|
props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
|
|
81
90
|
|
|
@@ -85,11 +94,8 @@ export default defineComponent({
|
|
|
85
94
|
const options = {
|
|
86
95
|
value: values.value,
|
|
87
96
|
language: props.language,
|
|
88
|
-
tabSize: 2,
|
|
89
97
|
theme: 'vs-dark',
|
|
90
|
-
|
|
91
|
-
fontSize: 15,
|
|
92
|
-
formatOnPaste: true,
|
|
98
|
+
...props.options,
|
|
93
99
|
};
|
|
94
100
|
|
|
95
101
|
if (props.type === 'diff') {
|
|
@@ -107,6 +113,7 @@ export default defineComponent({
|
|
|
107
113
|
codeEditor.value.addEventListener('keydown', (e) => {
|
|
108
114
|
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
|
109
115
|
e.preventDefault();
|
|
116
|
+
e.stopPropagation();
|
|
110
117
|
emit('save', getEditorValue());
|
|
111
118
|
}
|
|
112
119
|
});
|
|
@@ -117,7 +124,7 @@ export default defineComponent({
|
|
|
117
124
|
});
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
|
|
127
|
+
resizeObserver.observe(codeEditor.value);
|
|
121
128
|
};
|
|
122
129
|
|
|
123
130
|
watch(
|
|
@@ -140,7 +147,7 @@ export default defineComponent({
|
|
|
140
147
|
});
|
|
141
148
|
|
|
142
149
|
onUnmounted(() => {
|
|
143
|
-
|
|
150
|
+
resizeObserver.disconnect();
|
|
144
151
|
});
|
|
145
152
|
|
|
146
153
|
return {
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
<div class="m-editor">
|
|
3
3
|
<slot name="nav" class="m-editor-nav-menu"></slot>
|
|
4
4
|
|
|
5
|
-
<magic-code-editor
|
|
5
|
+
<magic-code-editor
|
|
6
|
+
v-if="showSrc"
|
|
7
|
+
class="m-editor-content"
|
|
8
|
+
:init-values="root"
|
|
9
|
+
:options="codeOptions"
|
|
10
|
+
@save="saveCode"
|
|
11
|
+
></magic-code-editor>
|
|
6
12
|
|
|
7
13
|
<div class="m-editor-content" v-else>
|
|
8
14
|
<div class="m-editor-framework-left" :style="`width: ${columnWidth?.left}px`">
|
|
@@ -48,21 +54,28 @@ export default defineComponent({
|
|
|
48
54
|
Resizer,
|
|
49
55
|
},
|
|
50
56
|
|
|
57
|
+
props: {
|
|
58
|
+
codeOptions: {
|
|
59
|
+
type: Object,
|
|
60
|
+
default: () => ({}),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
|
|
51
64
|
setup() {
|
|
52
|
-
const
|
|
65
|
+
const { editorService, uiService } = inject<Services>('services') || {};
|
|
53
66
|
|
|
54
|
-
const root = computed(() =>
|
|
67
|
+
const root = computed(() => editorService?.get<MApp>('root'));
|
|
55
68
|
|
|
56
69
|
return {
|
|
57
70
|
root,
|
|
58
|
-
pageLength: computed(() =>
|
|
59
|
-
showSrc: computed(() =>
|
|
60
|
-
columnWidth: computed(() =>
|
|
71
|
+
pageLength: computed(() => editorService?.get<number>('pageLength') || 0),
|
|
72
|
+
showSrc: computed(() => uiService?.get<boolean>('showSrc')),
|
|
73
|
+
columnWidth: computed(() => uiService?.get<GetColumnWidth>('columnWidth')),
|
|
61
74
|
|
|
62
75
|
saveCode(value: string) {
|
|
63
76
|
try {
|
|
64
77
|
// eslint-disable-next-line no-eval
|
|
65
|
-
|
|
78
|
+
editorService?.set('root', eval(value));
|
|
66
79
|
} catch (e: any) {
|
|
67
80
|
console.error(e);
|
|
68
81
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<m-form
|
|
3
|
-
class="m-editor-props-panel"
|
|
4
|
-
popper-class="m-editor-props-panel-popper"
|
|
3
|
+
:class="`m-editor-props-panel ${propsPanelSize}`"
|
|
4
|
+
:popper-class="`m-editor-props-panel-popper ${propsPanelSize}`"
|
|
5
5
|
ref="configForm"
|
|
6
|
-
size="
|
|
6
|
+
:size="propsPanelSize"
|
|
7
7
|
:init-values="values"
|
|
8
8
|
:config="curFormConfig"
|
|
9
9
|
@change="submit"
|
|
@@ -39,9 +39,9 @@ export default defineComponent({
|
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
values.value = node.value;
|
|
43
42
|
const type = node.value.type || (node.value.items ? 'container' : 'text');
|
|
44
43
|
curFormConfig.value = (await services?.propsService.getPropsConfig(type)) || [];
|
|
44
|
+
values.value = node.value;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
watchEffect(init);
|
|
@@ -55,6 +55,7 @@ export default defineComponent({
|
|
|
55
55
|
values,
|
|
56
56
|
configForm,
|
|
57
57
|
curFormConfig,
|
|
58
|
+
propsPanelSize: computed(() => services?.uiService.get('propsPanelSize') || 'small'),
|
|
58
59
|
|
|
59
60
|
async submit() {
|
|
60
61
|
try {
|
|
@@ -12,7 +12,14 @@
|
|
|
12
12
|
<template v-for="(group, index) in list">
|
|
13
13
|
<el-collapse-item v-if="group.items && group.items.length" :key="index" :name="index">
|
|
14
14
|
<template #title><i class="el-icon-s-grid"></i>{{ group.title }}</template>
|
|
15
|
-
<div
|
|
15
|
+
<div
|
|
16
|
+
class="component-item"
|
|
17
|
+
v-for="item in group.items"
|
|
18
|
+
draggable="true"
|
|
19
|
+
:key="item.type"
|
|
20
|
+
@click="appendComponent(item)"
|
|
21
|
+
@dragstart="dragstartHandler(item, $event)"
|
|
22
|
+
>
|
|
16
23
|
<m-icon :icon="item.icon"></m-icon>
|
|
17
24
|
|
|
18
25
|
<el-tooltip effect="dark" placement="bottom" :content="item.text">
|
|
@@ -27,6 +34,7 @@
|
|
|
27
34
|
|
|
28
35
|
<script lang="ts">
|
|
29
36
|
import { computed, defineComponent, inject, ref } from 'vue';
|
|
37
|
+
import serialize from 'serialize-javascript';
|
|
30
38
|
|
|
31
39
|
import MIcon from '@editor/components/Icon.vue';
|
|
32
40
|
import type { ComponentGroup, ComponentItem, Services } from '@editor/type';
|
|
@@ -56,13 +64,27 @@ export default defineComponent({
|
|
|
56
64
|
collapseValue,
|
|
57
65
|
list,
|
|
58
66
|
|
|
59
|
-
appendComponent({ text, type,
|
|
67
|
+
appendComponent({ text, type, data = {} }: ComponentItem): void {
|
|
60
68
|
services?.editorService.add({
|
|
61
69
|
name: text,
|
|
62
70
|
type,
|
|
63
|
-
...
|
|
71
|
+
...data,
|
|
64
72
|
});
|
|
65
73
|
},
|
|
74
|
+
|
|
75
|
+
dragstartHandler({ text, type, data = {} }: ComponentItem, e: DragEvent) {
|
|
76
|
+
if (e.dataTransfer) {
|
|
77
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
78
|
+
e.dataTransfer.setData(
|
|
79
|
+
'data',
|
|
80
|
+
serialize({
|
|
81
|
+
name: text,
|
|
82
|
+
type,
|
|
83
|
+
...data,
|
|
84
|
+
}).replace(/"(\w+)":\s/g, '$1: '),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
66
88
|
};
|
|
67
89
|
},
|
|
68
90
|
});
|