@tmagic/editor 1.0.0-beta.2 → 1.0.0-beta.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/package.json +8 -6
- package/src/Editor.vue +5 -5
- package/src/components/ScrollViewer.vue +65 -0
- package/src/layouts/CodeEditor.vue +35 -59
- package/src/layouts/workspace/Stage.vue +62 -50
- package/src/layouts/workspace/Workspace.vue +2 -21
- package/src/services/ui.ts +36 -2
- package/src/theme/stage.scss +7 -7
- package/src/type.ts +17 -6
- package/src/utils/scroll-viewer.ts +213 -0
- package/dist/style.css +0 -505
- package/dist/tmagic-editor.es.js +0 -4233
- package/dist/tmagic-editor.es.js.map +0 -1
- package/dist/tmagic-editor.umd.js +0 -4276
- package/dist/tmagic-editor.umd.js.map +0 -1
- package/dist/types/src/Editor.vue.d.ts +0 -136
- package/dist/types/src/components/Icon.vue.d.ts +0 -13
- package/dist/types/src/components/ToolButton.vue.d.ts +0 -35
- package/dist/types/src/fields/Code.vue.d.ts +0 -24
- package/dist/types/src/fields/CodeLink.vue.d.ts +0 -54
- package/dist/types/src/fields/UISelect.vue.d.ts +0 -32
- package/dist/types/src/index.d.ts +0 -19
- package/dist/types/src/layouts/AddPageBox.vue.d.ts +0 -5
- package/dist/types/src/layouts/CodeEditor.vue.d.ts +0 -46
- package/dist/types/src/layouts/Framework.vue.d.ts +0 -11
- package/dist/types/src/layouts/NavMenu.vue.d.ts +0 -24
- package/dist/types/src/layouts/PropsPanel.vue.d.ts +0 -13
- package/dist/types/src/layouts/Resizer.vue.d.ts +0 -13
- package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +0 -12
- 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/sidebar/Sidebar.vue.d.ts +0 -27
- package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +0 -11
- package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -153
- package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
- package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +0 -37
- package/dist/types/src/services/BaseService.d.ts +0 -56
- package/dist/types/src/services/editor.d.ts +0 -122
- package/dist/types/src/services/events.d.ts +0 -16
- package/dist/types/src/services/history.d.ts +0 -51
- package/dist/types/src/services/props.d.ts +0 -36
- package/dist/types/src/services/ui.d.ts +0 -26
- package/dist/types/src/shims-vue.d.ts +0 -6
- package/dist/types/src/type.d.ts +0 -183
- package/dist/types/src/utils/compose.d.ts +0 -5
- package/dist/types/src/utils/config.d.ts +0 -4
- package/dist/types/src/utils/editor.d.ts +0 -45
- package/dist/types/src/utils/index.d.ts +0 -4
- package/dist/types/src/utils/logger.d.ts +0 -5
- package/dist/types/src/utils/props.d.ts +0 -49
- package/dist/types/src/utils/undo-redo.d.ts +0 -12
- package/dist/types/src/vite-env.d.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.0-beta.
|
|
2
|
+
"version": "1.0.0-beta.3",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
|
+
"sideEffects": false,
|
|
4
5
|
"main": "dist/tmagic-editor.umd.js",
|
|
5
6
|
"module": "dist/tmagic-editor.es.js",
|
|
6
7
|
"style": "dist/style.css",
|
|
@@ -27,15 +28,16 @@
|
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
30
|
"@element-plus/icons": "0.0.11",
|
|
30
|
-
"@tmagic/core": "^1.0.0-beta.
|
|
31
|
-
"@tmagic/form": "^1.0.0-beta.
|
|
32
|
-
"@tmagic/schema": "^1.0.0-beta.
|
|
33
|
-
"@tmagic/stage": "^1.0.0-beta.
|
|
34
|
-
"@tmagic/utils": "^1.0.0-beta.
|
|
31
|
+
"@tmagic/core": "^1.0.0-beta.3",
|
|
32
|
+
"@tmagic/form": "^1.0.0-beta.3",
|
|
33
|
+
"@tmagic/schema": "^1.0.0-beta.3",
|
|
34
|
+
"@tmagic/stage": "^1.0.0-beta.3",
|
|
35
|
+
"@tmagic/utils": "^1.0.0-beta.3",
|
|
35
36
|
"color": "^3.1.3",
|
|
36
37
|
"element-plus": "^2.0.2",
|
|
37
38
|
"events": "^3.3.0",
|
|
38
39
|
"lodash-es": "^4.17.21",
|
|
40
|
+
"monaco-editor": "^0.32.1",
|
|
39
41
|
"serialize-javascript": "^6.0.0",
|
|
40
42
|
"vue": "^3.2.0"
|
|
41
43
|
},
|
package/src/Editor.vue
CHANGED
|
@@ -55,7 +55,7 @@ import eventsService from '@editor/services/events';
|
|
|
55
55
|
import historyService from '@editor/services/history';
|
|
56
56
|
import propsService from '@editor/services/props';
|
|
57
57
|
import uiService from '@editor/services/ui';
|
|
58
|
-
import type { ComponentGroup, MenuBarData, Services, SideBarData } from '@editor/type';
|
|
58
|
+
import type { ComponentGroup, MenuBarData, Services, SideBarData, StageRect } from '@editor/type';
|
|
59
59
|
|
|
60
60
|
export default defineComponent({
|
|
61
61
|
name: 'm-editor',
|
|
@@ -133,8 +133,8 @@ export default defineComponent({
|
|
|
133
133
|
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
134
134
|
},
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
type: [String, Object] as PropType<
|
|
136
|
+
stageRect: {
|
|
137
|
+
type: [String, Object] as PropType<StageRect>,
|
|
138
138
|
},
|
|
139
139
|
},
|
|
140
140
|
|
|
@@ -208,8 +208,8 @@ export default defineComponent({
|
|
|
208
208
|
);
|
|
209
209
|
|
|
210
210
|
watch(
|
|
211
|
-
() => props.
|
|
212
|
-
(
|
|
211
|
+
() => props.stageRect,
|
|
212
|
+
(stageRect) => stageRect && uiService.set('stageRect', stageRect),
|
|
213
213
|
{
|
|
214
214
|
immediate: true,
|
|
215
215
|
},
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-editor-scroll-viewer-container" ref="container">
|
|
3
|
+
<div ref="el" :style="style">
|
|
4
|
+
<slot></slot>
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { computed, defineComponent, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
11
|
+
|
|
12
|
+
import { ScrollViewer } from '@editor/utils/scroll-viewer';
|
|
13
|
+
|
|
14
|
+
export default defineComponent({
|
|
15
|
+
name: 'm-editor-scroll-viewer',
|
|
16
|
+
|
|
17
|
+
props: {
|
|
18
|
+
width: Number,
|
|
19
|
+
height: Number,
|
|
20
|
+
zoom: {
|
|
21
|
+
type: Number,
|
|
22
|
+
default: 1,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
setup(props) {
|
|
27
|
+
const container = ref<HTMLDivElement>();
|
|
28
|
+
const el = ref<HTMLDivElement>();
|
|
29
|
+
let scrollViewer: ScrollViewer;
|
|
30
|
+
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
if (!container.value || !el.value) return;
|
|
33
|
+
scrollViewer = new ScrollViewer({
|
|
34
|
+
container: container.value,
|
|
35
|
+
target: el.value,
|
|
36
|
+
zoom: props.zoom,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
onUnmounted(() => {
|
|
41
|
+
scrollViewer.destroy();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
watch(
|
|
45
|
+
() => props.zoom,
|
|
46
|
+
() => {
|
|
47
|
+
scrollViewer.setZoom(props.zoom);
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
container,
|
|
53
|
+
el,
|
|
54
|
+
|
|
55
|
+
style: computed(
|
|
56
|
+
() => `
|
|
57
|
+
width: ${props.width}px;
|
|
58
|
+
height: ${props.height}px;
|
|
59
|
+
position: absolute;
|
|
60
|
+
`,
|
|
61
|
+
),
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
</script>
|
|
@@ -4,28 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
7
|
+
import * as monaco from 'monaco-editor';
|
|
7
8
|
import serialize from 'serialize-javascript';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const initEditor = () => {
|
|
12
|
-
if ((globalThis as any).monaco) {
|
|
13
|
-
Promise.resolve((globalThis as any).monaco);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return asyncLoadJs(`https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js`).then(() => {
|
|
17
|
-
(globalThis as any).require.config({
|
|
18
|
-
paths: { vs: `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs` },
|
|
19
|
-
});
|
|
20
|
-
return new Promise((resolve) => {
|
|
21
|
-
(globalThis as any).require(['vs/editor/editor.main'], () => {
|
|
22
|
-
resolve((globalThis as any).monaco);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const toString = (v: any, language: string): string => {
|
|
10
|
+
const toString = (v: string | any, language: string): string => {
|
|
29
11
|
let value = '';
|
|
30
12
|
if (typeof v !== 'string') {
|
|
31
13
|
value = serialize(v, {
|
|
@@ -64,60 +46,63 @@ export default defineComponent({
|
|
|
64
46
|
},
|
|
65
47
|
},
|
|
66
48
|
|
|
67
|
-
emits: ['
|
|
49
|
+
emits: ['initd', 'save'],
|
|
68
50
|
|
|
69
51
|
setup(props, { emit }) {
|
|
70
|
-
let vsEditor:
|
|
52
|
+
let vsEditor: monaco.editor.IStandaloneCodeEditor | null = null;
|
|
53
|
+
let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
|
|
71
54
|
const values = ref('');
|
|
72
55
|
const loading = ref(false);
|
|
73
56
|
const codeEditor = ref<HTMLDivElement>();
|
|
74
57
|
|
|
75
|
-
const setEditorValue = (v: any, m: any) => {
|
|
58
|
+
const setEditorValue = (v: string | any, m: string | any) => {
|
|
76
59
|
values.value = toString(v, props.language);
|
|
77
60
|
|
|
78
61
|
if (props.type === 'diff') {
|
|
79
|
-
const originalModel =
|
|
80
|
-
const modifiedModel =
|
|
81
|
-
toString(m, props.language),
|
|
82
|
-
'text/javascript',
|
|
83
|
-
);
|
|
62
|
+
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
|
|
63
|
+
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
|
|
84
64
|
|
|
85
|
-
return
|
|
65
|
+
return vsDiffEditor?.setModel({
|
|
86
66
|
original: originalModel,
|
|
87
67
|
modified: modifiedModel,
|
|
88
68
|
});
|
|
89
69
|
}
|
|
90
70
|
|
|
91
|
-
return vsEditor
|
|
71
|
+
return vsEditor?.setValue(values.value);
|
|
92
72
|
};
|
|
93
73
|
|
|
94
74
|
const resizeHandler = () => {
|
|
95
75
|
vsEditor?.layout();
|
|
76
|
+
vsDiffEditor?.layout();
|
|
96
77
|
};
|
|
97
78
|
|
|
98
|
-
const getEditorValue = () =>
|
|
79
|
+
const getEditorValue = () =>
|
|
80
|
+
props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
|
|
99
81
|
|
|
100
82
|
const init = async () => {
|
|
101
83
|
if (!codeEditor.value) return;
|
|
102
84
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
85
|
+
const options = {
|
|
86
|
+
value: values.value,
|
|
87
|
+
language: props.language,
|
|
88
|
+
tabSize: 2,
|
|
89
|
+
theme: 'vs-dark',
|
|
90
|
+
fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
|
|
91
|
+
fontSize: 15,
|
|
92
|
+
formatOnPaste: true,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if (props.type === 'diff') {
|
|
96
|
+
vsDiffEditor = monaco.editor.createDiffEditor(codeEditor.value, options);
|
|
97
|
+
} else {
|
|
98
|
+
vsEditor = monaco.editor.create(codeEditor.value, options);
|
|
99
|
+
}
|
|
115
100
|
|
|
116
101
|
setEditorValue(props.initValues, props.modifiedValues);
|
|
117
102
|
|
|
118
103
|
loading.value = false;
|
|
119
104
|
|
|
120
|
-
emit('
|
|
105
|
+
emit('initd', vsEditor);
|
|
121
106
|
|
|
122
107
|
codeEditor.value.addEventListener('keydown', (e) => {
|
|
123
108
|
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
|
@@ -127,7 +112,7 @@ export default defineComponent({
|
|
|
127
112
|
});
|
|
128
113
|
|
|
129
114
|
if (props.type !== 'diff') {
|
|
130
|
-
vsEditor
|
|
115
|
+
vsEditor?.onDidBlurEditorWidget(() => {
|
|
131
116
|
emit('save', getEditorValue());
|
|
132
117
|
});
|
|
133
118
|
}
|
|
@@ -138,7 +123,7 @@ export default defineComponent({
|
|
|
138
123
|
watch(
|
|
139
124
|
() => props.initValues,
|
|
140
125
|
(v, preV) => {
|
|
141
|
-
if (
|
|
126
|
+
if (v !== preV) {
|
|
142
127
|
setEditorValue(props.initValues, props.modifiedValues);
|
|
143
128
|
}
|
|
144
129
|
},
|
|
@@ -151,17 +136,7 @@ export default defineComponent({
|
|
|
151
136
|
onMounted(async () => {
|
|
152
137
|
loading.value = true;
|
|
153
138
|
|
|
154
|
-
|
|
155
|
-
if (!(globalThis as any).monaco) {
|
|
156
|
-
const interval = setInterval(() => {
|
|
157
|
-
if ((globalThis as any).monaco) {
|
|
158
|
-
clearInterval(interval);
|
|
159
|
-
init();
|
|
160
|
-
}
|
|
161
|
-
}, 300);
|
|
162
|
-
} else {
|
|
163
|
-
init();
|
|
164
|
-
}
|
|
139
|
+
init();
|
|
165
140
|
});
|
|
166
141
|
|
|
167
142
|
onUnmounted(() => {
|
|
@@ -174,13 +149,14 @@ export default defineComponent({
|
|
|
174
149
|
codeEditor,
|
|
175
150
|
|
|
176
151
|
getEditor() {
|
|
177
|
-
return vsEditor;
|
|
152
|
+
return vsEditor || vsDiffEditor;
|
|
178
153
|
},
|
|
179
154
|
|
|
180
155
|
setEditorValue,
|
|
181
156
|
|
|
182
157
|
focus() {
|
|
183
|
-
vsEditor
|
|
158
|
+
vsEditor?.focus();
|
|
159
|
+
vsDiffEditor?.focus();
|
|
184
160
|
},
|
|
185
161
|
};
|
|
186
162
|
},
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<scroll-viewer
|
|
3
|
+
class="m-editor-stage"
|
|
4
|
+
ref="stageWrap"
|
|
5
|
+
:width="stageRect?.width"
|
|
6
|
+
:height="stageRect?.height"
|
|
7
|
+
:zoom="zoom"
|
|
8
|
+
>
|
|
3
9
|
<div
|
|
4
10
|
class="m-editor-stage-container"
|
|
5
11
|
ref="stageContainer"
|
|
6
|
-
:style="stageStyle"
|
|
7
12
|
@contextmenu="contextmenuHandler"
|
|
13
|
+
:style="`transform: scale(${zoom})`"
|
|
8
14
|
></div>
|
|
9
15
|
<teleport to="body">
|
|
10
16
|
<viewer-menu ref="menu" :style="menuStyle"></viewer-menu>
|
|
11
17
|
</teleport>
|
|
12
|
-
</
|
|
18
|
+
</scroll-viewer>
|
|
13
19
|
</template>
|
|
14
20
|
|
|
15
21
|
<script lang="ts">
|
|
@@ -17,6 +23,7 @@ import {
|
|
|
17
23
|
computed,
|
|
18
24
|
defineComponent,
|
|
19
25
|
inject,
|
|
26
|
+
nextTick,
|
|
20
27
|
onMounted,
|
|
21
28
|
onUnmounted,
|
|
22
29
|
PropType,
|
|
@@ -31,7 +38,8 @@ import type { MApp, MNode, MPage } from '@tmagic/schema';
|
|
|
31
38
|
import type { MoveableOptions, Runtime, SortEventData, UpdateEventData } from '@tmagic/stage';
|
|
32
39
|
import StageCore from '@tmagic/stage';
|
|
33
40
|
|
|
34
|
-
import
|
|
41
|
+
import ScrollViewer from '@editor/components/ScrollViewer.vue';
|
|
42
|
+
import type { Services, StageRect } from '@editor/type';
|
|
35
43
|
|
|
36
44
|
import ViewerMenu from './ViewerMenu.vue';
|
|
37
45
|
|
|
@@ -79,6 +87,7 @@ export default defineComponent({
|
|
|
79
87
|
|
|
80
88
|
components: {
|
|
81
89
|
ViewerMenu,
|
|
90
|
+
ScrollViewer,
|
|
82
91
|
},
|
|
83
92
|
|
|
84
93
|
props: {
|
|
@@ -88,26 +97,6 @@ export default defineComponent({
|
|
|
88
97
|
|
|
89
98
|
runtimeUrl: String,
|
|
90
99
|
|
|
91
|
-
root: {
|
|
92
|
-
type: Object as PropType<MApp>,
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
page: {
|
|
96
|
-
type: Object as PropType<MPage>,
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
node: {
|
|
100
|
-
type: Object as PropType<MNode>,
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
uiSelectMode: {
|
|
104
|
-
type: Boolean,
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
zoom: {
|
|
108
|
-
type: Number,
|
|
109
|
-
},
|
|
110
|
-
|
|
111
100
|
canSelect: {
|
|
112
101
|
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
113
102
|
default: (el: HTMLElement) => Boolean(el.id),
|
|
@@ -125,12 +114,16 @@ export default defineComponent({
|
|
|
125
114
|
|
|
126
115
|
setup(props, { emit }) {
|
|
127
116
|
const services = inject<Services>('services');
|
|
117
|
+
|
|
118
|
+
const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
|
|
128
119
|
const stageContainer = ref<HTMLDivElement>();
|
|
129
120
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
121
|
+
const stageRect = computed(() => services?.uiService.get<StageRect>('stageRect'));
|
|
122
|
+
const uiSelectMode = computed(() => services?.uiService.get<boolean>('uiSelectMode'));
|
|
123
|
+
const root = computed(() => services?.editorService.get<MApp>('root'));
|
|
124
|
+
const page = computed(() => services?.editorService.get<MPage>('page'));
|
|
125
|
+
const zoom = computed(() => services?.uiService.get<number>('zoom'));
|
|
126
|
+
const node = computed(() => services?.editorService.get<MNode>('node'));
|
|
134
127
|
|
|
135
128
|
let stage: StageCore | null = null;
|
|
136
129
|
let runtime: Runtime | null = null;
|
|
@@ -139,16 +132,16 @@ export default defineComponent({
|
|
|
139
132
|
if (stage) return;
|
|
140
133
|
|
|
141
134
|
if (!stageContainer.value) return;
|
|
142
|
-
if (!(props.runtimeUrl || props.render) || !
|
|
135
|
+
if (!(props.runtimeUrl || props.render) || !root.value) return;
|
|
143
136
|
|
|
144
137
|
stage = new StageCore({
|
|
145
138
|
render: props.render,
|
|
146
139
|
runtimeUrl: props.runtimeUrl,
|
|
147
|
-
zoom:
|
|
140
|
+
zoom: zoom.value,
|
|
148
141
|
canSelect: (el, stop) => {
|
|
149
142
|
const elCanSelect = props.canSelect(el);
|
|
150
143
|
// 在组件联动过程中不能再往下选择,返回并触发 ui-select
|
|
151
|
-
if (
|
|
144
|
+
if (uiSelectMode.value && elCanSelect) {
|
|
152
145
|
document.dispatchEvent(new CustomEvent('ui-select', { detail: el }));
|
|
153
146
|
return stop();
|
|
154
147
|
}
|
|
@@ -176,45 +169,64 @@ export default defineComponent({
|
|
|
176
169
|
services?.uiService.set('showGuides', true);
|
|
177
170
|
});
|
|
178
171
|
|
|
179
|
-
if (!
|
|
172
|
+
if (!node.value?.id) return;
|
|
180
173
|
stage?.on('runtime-ready', (rt) => {
|
|
181
174
|
runtime = rt;
|
|
182
175
|
// toRaw返回的值是一个引用而非快照,需要cloneDeep
|
|
183
|
-
|
|
184
|
-
|
|
176
|
+
root.value && runtime?.updateRootConfig(cloneDeep(toRaw(root.value)));
|
|
177
|
+
page.value?.id && runtime?.updatePageId?.(page.value.id);
|
|
185
178
|
setTimeout(() => {
|
|
186
|
-
|
|
179
|
+
node.value && stage?.select(toRaw(node.value.id));
|
|
187
180
|
});
|
|
188
181
|
});
|
|
189
182
|
});
|
|
190
183
|
|
|
191
|
-
watch(
|
|
192
|
-
(
|
|
193
|
-
(zoom)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
184
|
+
watch(zoom, (zoom) => {
|
|
185
|
+
if (!stage || !zoom) return;
|
|
186
|
+
stage.setZoom(zoom);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
watch(root, (root) => {
|
|
190
|
+
if (runtime && root) {
|
|
191
|
+
runtime.updateRootConfig(cloneDeep(toRaw(root)));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
198
194
|
|
|
199
195
|
watch(
|
|
200
|
-
() =>
|
|
201
|
-
(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
196
|
+
() => node.value?.id,
|
|
197
|
+
(id) => {
|
|
198
|
+
nextTick(() => {
|
|
199
|
+
// 等待相关dom变更完成后,再select,适用大多数场景
|
|
200
|
+
id && stage?.select(id);
|
|
201
|
+
});
|
|
205
202
|
},
|
|
206
203
|
);
|
|
207
204
|
|
|
205
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
206
|
+
for (const { contentRect } of entries) {
|
|
207
|
+
services?.uiService.set('stageContainerRect', {
|
|
208
|
+
width: contentRect.width,
|
|
209
|
+
height: contentRect.height,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
onMounted(() => {
|
|
215
|
+
stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
|
|
216
|
+
});
|
|
217
|
+
|
|
208
218
|
onUnmounted(() => {
|
|
209
219
|
stage?.destroy();
|
|
220
|
+
resizeObserver.disconnect();
|
|
210
221
|
services?.editorService.set('stage', null);
|
|
211
222
|
});
|
|
212
223
|
|
|
213
224
|
return {
|
|
214
|
-
|
|
215
|
-
...useMenu(),
|
|
216
|
-
|
|
225
|
+
stageWrap,
|
|
217
226
|
stageContainer,
|
|
227
|
+
stageRect,
|
|
228
|
+
zoom,
|
|
229
|
+
...useMenu(),
|
|
218
230
|
};
|
|
219
231
|
},
|
|
220
232
|
});
|
|
@@ -4,11 +4,6 @@
|
|
|
4
4
|
:key="page?.id"
|
|
5
5
|
:runtime-url="runtimeUrl"
|
|
6
6
|
:render="render"
|
|
7
|
-
:ui-select-mode="uiSelectMode"
|
|
8
|
-
:root="root"
|
|
9
|
-
:page="page"
|
|
10
|
-
:node="node"
|
|
11
|
-
:zoom="zoom"
|
|
12
7
|
:moveable-options="moveableOptions"
|
|
13
8
|
:can-select="canSelect"
|
|
14
9
|
@select="selectHandler"
|
|
@@ -26,9 +21,9 @@
|
|
|
26
21
|
</template>
|
|
27
22
|
|
|
28
23
|
<script lang="ts">
|
|
29
|
-
import { computed, defineComponent, inject,
|
|
24
|
+
import { computed, defineComponent, inject, PropType } from 'vue';
|
|
30
25
|
|
|
31
|
-
import type {
|
|
26
|
+
import type { MComponent, MContainer, MPage } from '@tmagic/schema';
|
|
32
27
|
import type { MoveableOptions, SortEventData } from '@tmagic/stage';
|
|
33
28
|
import StageCore from '@tmagic/stage';
|
|
34
29
|
|
|
@@ -63,23 +58,9 @@ export default defineComponent({
|
|
|
63
58
|
|
|
64
59
|
setup() {
|
|
65
60
|
const services = inject<Services>('services');
|
|
66
|
-
const node = computed(() => services?.editorService.get<MNode>('node'));
|
|
67
|
-
const stage = computed(() => services?.editorService.get<StageCore>('stage'));
|
|
68
|
-
|
|
69
|
-
watch([() => node.value?.id, stage], ([id, stage]) => {
|
|
70
|
-
nextTick(() => {
|
|
71
|
-
// 等待相关dom变更完成后,再select,适用大多数场景
|
|
72
|
-
id && stage?.select(id);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
61
|
|
|
76
62
|
return {
|
|
77
|
-
uiSelectMode: computed(() => services?.uiService.get<boolean>('uiSelectMode')),
|
|
78
|
-
root: computed(() => services?.editorService.get<MApp>('root')),
|
|
79
63
|
page: computed(() => services?.editorService.get<MPage>('page')),
|
|
80
|
-
zoom: computed(() => services?.uiService.get<number>('zoom')),
|
|
81
|
-
|
|
82
|
-
node,
|
|
83
64
|
|
|
84
65
|
selectHandler(el: HTMLElement) {
|
|
85
66
|
services?.editorService.select(el.id);
|
package/src/services/ui.ts
CHANGED
|
@@ -21,7 +21,7 @@ import { reactive, toRaw } from 'vue';
|
|
|
21
21
|
import type StageCore from '@tmagic/stage';
|
|
22
22
|
|
|
23
23
|
import editorService from '@editor/services/editor';
|
|
24
|
-
import { GetColumnWidth, SetColumnWidth, UiState } from '@editor/type';
|
|
24
|
+
import type { GetColumnWidth, SetColumnWidth, StageRect, UiState } from '@editor/type';
|
|
25
25
|
|
|
26
26
|
import BaseService from './BaseService';
|
|
27
27
|
|
|
@@ -29,7 +29,14 @@ const state = reactive<UiState>({
|
|
|
29
29
|
uiSelectMode: false,
|
|
30
30
|
showSrc: false,
|
|
31
31
|
zoom: 1,
|
|
32
|
-
|
|
32
|
+
stageContainerRect: {
|
|
33
|
+
width: 0,
|
|
34
|
+
height: 0,
|
|
35
|
+
},
|
|
36
|
+
stageRect: {
|
|
37
|
+
width: 375,
|
|
38
|
+
height: 817,
|
|
39
|
+
},
|
|
33
40
|
columnWidth: {
|
|
34
41
|
left: 310,
|
|
35
42
|
center: globalThis.document.body.clientWidth - 310 - 400,
|
|
@@ -57,6 +64,11 @@ class Ui extends BaseService {
|
|
|
57
64
|
return;
|
|
58
65
|
}
|
|
59
66
|
|
|
67
|
+
if (name === 'stageRect') {
|
|
68
|
+
this.setStageRect(value as unknown as StageRect);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
if (name === 'showGuides') {
|
|
61
73
|
mask?.showGuides(value as unknown as boolean);
|
|
62
74
|
}
|
|
@@ -66,6 +78,10 @@ class Ui extends BaseService {
|
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
(state as any)[name] = value;
|
|
81
|
+
|
|
82
|
+
if (name === 'stageContainerRect') {
|
|
83
|
+
state.zoom = this.calcZoom();
|
|
84
|
+
}
|
|
69
85
|
}
|
|
70
86
|
|
|
71
87
|
public get<T>(name: keyof typeof state): T {
|
|
@@ -94,6 +110,24 @@ class Ui extends BaseService {
|
|
|
94
110
|
|
|
95
111
|
state.columnWidth = columnWidth;
|
|
96
112
|
}
|
|
113
|
+
|
|
114
|
+
private setStageRect(value: StageRect) {
|
|
115
|
+
state.stageRect = {
|
|
116
|
+
...state.stageRect,
|
|
117
|
+
...value,
|
|
118
|
+
};
|
|
119
|
+
state.zoom = this.calcZoom();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private calcZoom() {
|
|
123
|
+
const { stageRect, stageContainerRect } = state;
|
|
124
|
+
const { height, width } = stageContainerRect;
|
|
125
|
+
if (!width || !height) return 1;
|
|
126
|
+
if (width > stageRect.width && height > stageRect.height) {
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
return Math.min((width - 100) / stageRect.width || 1, (height - 100) / stageRect.height || 1);
|
|
130
|
+
}
|
|
97
131
|
}
|
|
98
132
|
|
|
99
133
|
export type UiService = Ui;
|
package/src/theme/stage.scss
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
position: relative;
|
|
3
3
|
width: 100%;
|
|
4
4
|
height: calc(100% - $--page-bar-height);
|
|
5
|
-
overflow:
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
display: flex;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
align-items: center;
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
.m-editor-stage-container {
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
11
14
|
z-index: 0;
|
|
12
|
-
top: 50%;
|
|
13
|
-
margin: 0 auto;
|
|
14
15
|
position: relative;
|
|
15
|
-
width: 375px;
|
|
16
|
-
height: 80%;
|
|
17
16
|
border: 1px solid $--border-color;
|
|
17
|
+
transition: transform 0.3s;
|
|
18
18
|
|
|
19
19
|
&::-webkit-scrollbar {
|
|
20
20
|
width: 0 !important;
|