@tmagic/editor 1.1.0-beta.4 → 1.1.0-beta.7

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.
Files changed (100) hide show
  1. package/dist/{tmagic-editor.es.js → tmagic-editor.mjs} +1361 -1144
  2. package/dist/tmagic-editor.mjs.map +1 -0
  3. package/dist/tmagic-editor.umd.js +1375 -1158
  4. package/dist/tmagic-editor.umd.js.map +1 -1
  5. package/package.json +21 -19
  6. package/src/Editor.vue +14 -12
  7. package/src/components/ContentMenu.vue +87 -99
  8. package/src/components/ScrollViewer.vue +1 -1
  9. package/src/components/ToolButton.vue +150 -167
  10. package/src/fields/UISelect.vue +49 -70
  11. package/src/index.ts +2 -1
  12. package/src/layouts/AddPageBox.vue +2 -2
  13. package/src/layouts/Framework.vue +1 -1
  14. package/src/layouts/NavMenu.vue +2 -2
  15. package/src/layouts/PropsPanel.vue +1 -1
  16. package/src/layouts/Resizer.vue +1 -1
  17. package/src/layouts/sidebar/ComponentListPanel.vue +2 -2
  18. package/src/layouts/sidebar/LayerMenu.vue +2 -2
  19. package/src/layouts/sidebar/LayerPanel.vue +13 -4
  20. package/src/layouts/sidebar/Sidebar.vue +1 -1
  21. package/src/layouts/sidebar/TabPane.vue +2 -2
  22. package/src/layouts/workspace/PageBar.vue +63 -192
  23. package/src/layouts/workspace/PageBarScrollContainer.vue +111 -0
  24. package/src/layouts/workspace/Stage.vue +195 -222
  25. package/src/layouts/workspace/ViewerMenu.vue +142 -146
  26. package/src/layouts/workspace/Workspace.vue +11 -11
  27. package/src/services/BaseService.ts +1 -1
  28. package/src/services/componentList.ts +3 -3
  29. package/src/services/editor.ts +117 -135
  30. package/src/services/events.ts +1 -1
  31. package/src/services/history.ts +1 -1
  32. package/src/services/props.ts +62 -10
  33. package/src/services/storage.ts +133 -0
  34. package/src/services/ui.ts +2 -2
  35. package/src/type.ts +22 -6
  36. package/src/utils/config.ts +1 -1
  37. package/src/utils/editor.ts +1 -1
  38. package/src/utils/operator.ts +210 -0
  39. package/src/utils/props.ts +2 -24
  40. package/src/utils/scroll-viewer.ts +1 -1
  41. package/tsconfig.build.json +13 -0
  42. package/{dist/types/src → types}/Editor.vue.d.ts +7 -8
  43. package/types/components/ContentMenu.vue.d.ts +116 -0
  44. package/types/components/Icon.vue.d.ts +13 -0
  45. package/types/components/ScrollViewer.vue.d.ts +22 -0
  46. package/types/components/ToolButton.vue.d.ts +109 -0
  47. package/types/fields/Code.vue.d.ts +23 -0
  48. package/{dist/types/src → types}/fields/CodeLink.vue.d.ts +4 -6
  49. package/types/fields/UISelect.vue.d.ts +83 -0
  50. package/{dist/types/src → types}/index.d.ts +4 -1
  51. package/types/layouts/AddPageBox.vue.d.ts +4 -0
  52. package/{dist/types/src → types}/layouts/CodeEditor.vue.d.ts +11 -13
  53. package/types/layouts/Framework.vue.d.ts +22 -0
  54. package/types/layouts/NavMenu.vue.d.ts +25 -0
  55. package/types/layouts/PropsPanel.vue.d.ts +245 -0
  56. package/types/layouts/Resizer.vue.d.ts +12 -0
  57. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +14 -0
  58. package/types/layouts/sidebar/LayerMenu.vue.d.ts +100 -0
  59. package/types/layouts/sidebar/LayerPanel.vue.d.ts +1099 -0
  60. package/{dist/types/src → types}/layouts/sidebar/Sidebar.vue.d.ts +3 -5
  61. package/types/layouts/sidebar/TabPane.vue.d.ts +14 -0
  62. package/types/layouts/workspace/PageBar.vue.d.ts +54 -0
  63. package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +48 -0
  64. package/types/layouts/workspace/Stage.vue.d.ts +46 -0
  65. package/types/layouts/workspace/ViewerMenu.vue.d.ts +88 -0
  66. package/types/layouts/workspace/Workspace.vue.d.ts +6 -0
  67. package/{dist/types/src → types}/services/BaseService.d.ts +0 -0
  68. package/types/services/componentList.d.ts +14 -0
  69. package/{dist/types/src → types}/services/editor.d.ts +26 -11
  70. package/{dist/types/src → types}/services/events.d.ts +0 -0
  71. package/{dist/types/src → types}/services/history.d.ts +0 -0
  72. package/{dist/types/src → types}/services/props.d.ts +25 -1
  73. package/types/services/storage.d.ts +56 -0
  74. package/{dist/types/src → types}/services/ui.d.ts +1 -1
  75. package/{dist/types/src → types}/type.d.ts +15 -0
  76. package/{dist/types/src → types}/utils/compose.d.ts +1 -1
  77. package/{dist/types/src → types}/utils/config.d.ts +0 -0
  78. package/{dist/types/src → types}/utils/editor.d.ts +2 -2
  79. package/{dist/types/src → types}/utils/index.d.ts +0 -0
  80. package/{dist/types/src → types}/utils/logger.d.ts +0 -0
  81. package/types/utils/operator.d.ts +44 -0
  82. package/{dist/types/src → types}/utils/polyfills.d.ts +0 -0
  83. package/{dist/types/src → types}/utils/props.d.ts +2 -22
  84. package/{dist/types/src → types}/utils/scroll-viewer.d.ts +0 -0
  85. package/{dist/types/src → types}/utils/undo-redo.d.ts +0 -0
  86. package/dist/tmagic-editor.es.js.map +0 -1
  87. package/dist/types/src/components/Icon.vue.d.ts +0 -14
  88. package/dist/types/src/components/ScrollViewer.vue.d.ts +0 -24
  89. package/dist/types/src/fields/Code.vue.d.ts +0 -25
  90. package/dist/types/src/layouts/AddPageBox.vue.d.ts +0 -5
  91. package/dist/types/src/layouts/Framework.vue.d.ts +0 -24
  92. package/dist/types/src/layouts/NavMenu.vue.d.ts +0 -27
  93. package/dist/types/src/layouts/PropsPanel.vue.d.ts +0 -13
  94. package/dist/types/src/layouts/Resizer.vue.d.ts +0 -14
  95. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +0 -16
  96. package/dist/types/src/layouts/sidebar/TabPane.vue.d.ts +0 -16
  97. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +0 -8
  98. package/dist/types/src/shims-vue.d.ts +0 -6
  99. package/dist/types/src/vite-env.d.ts +0 -1
  100. package/src/vite-env.d.ts +0 -1
@@ -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>
@@ -15,24 +15,13 @@
15
15
  @dragover="dragoverHandler"
16
16
  ></div>
17
17
  <teleport to="body">
18
- <viewer-menu ref="menu"></viewer-menu>
18
+ <viewer-menu ref="menu" :is-multi-select="isMultiSelect"></viewer-menu>
19
19
  </teleport>
20
20
  </scroll-viewer>
21
21
  </template>
22
22
 
23
- <script lang="ts">
24
- import {
25
- computed,
26
- defineComponent,
27
- inject,
28
- markRaw,
29
- onMounted,
30
- onUnmounted,
31
- ref,
32
- toRaw,
33
- watch,
34
- watchEffect,
35
- } from 'vue';
23
+ <script lang="ts" setup>
24
+ import { computed, inject, markRaw, onMounted, onUnmounted, ref, toRaw, watch, watchEffect } from 'vue';
36
25
  import { cloneDeep } from 'lodash-es';
37
26
 
38
27
  import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
@@ -45,7 +34,7 @@ import StageCore, {
45
34
  UpdateEventData,
46
35
  } from '@tmagic/stage';
47
36
 
48
- import ScrollViewer from '@editor/components/ScrollViewer.vue';
37
+ import ScrollViewer from '../../components/ScrollViewer.vue';
49
38
  import {
50
39
  H_GUIDE_LINE_STORAGE_KEY,
51
40
  Layout,
@@ -53,223 +42,207 @@ import {
53
42
  StageOptions,
54
43
  StageRect,
55
44
  V_GUIDE_LINE_STORAGE_KEY,
56
- } from '@editor/type';
57
- import { getGuideLineFromCache } from '@editor/utils';
45
+ } from '../../type';
46
+ import { getGuideLineFromCache } from '../../utils';
58
47
 
59
48
  import ViewerMenu from './ViewerMenu.vue';
60
49
 
61
- export default defineComponent({
62
- name: 'magic-stage',
63
-
64
- components: {
65
- ViewerMenu,
66
- ScrollViewer,
67
- },
68
-
69
- setup() {
70
- const services = inject<Services>('services');
71
- const stageOptions = inject<StageOptions>('stageOptions');
72
-
73
- const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
74
- const stageContainer = ref<HTMLDivElement>();
75
- const menu = ref<InstanceType<typeof ViewerMenu>>();
76
-
77
- const stageRect = computed(() => services?.uiService.get<StageRect>('stageRect'));
78
- const uiSelectMode = computed(() => services?.uiService.get<boolean>('uiSelectMode'));
79
- const root = computed(() => services?.editorService.get<MApp>('root'));
80
- const page = computed(() => services?.editorService.get<MPage>('page'));
81
- const zoom = computed(() => services?.uiService.get<number>('zoom') || 1);
82
- const node = computed(() => services?.editorService.get<MNode>('node'));
83
-
84
- let stage: StageCore | null = null;
85
- let runtime: Runtime | null = null;
86
-
87
- const getGuideLineKey = (key: string) => `${key}_${root.value?.id}_${page.value?.id}`;
88
-
89
- watchEffect(() => {
90
- if (stage) return;
91
-
92
- if (!stageContainer.value) return;
93
- if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value) return;
94
-
95
- stage = new StageCore({
96
- render: stageOptions.render,
97
- runtimeUrl: stageOptions.runtimeUrl,
98
- zoom: zoom.value,
99
- autoScrollIntoView: stageOptions.autoScrollIntoView,
100
- isContainer: stageOptions.isContainer,
101
- containerHighlightClassName: stageOptions.containerHighlightClassName,
102
- containerHighlightDuration: stageOptions.containerHighlightDuration,
103
- canSelect: (el, event, stop) => {
104
- const elCanSelect = stageOptions.canSelect(el);
105
- // 在组件联动过程中不能再往下选择,返回并触发 ui-select
106
- if (uiSelectMode.value && elCanSelect && event.type === 'mousedown') {
107
- document.dispatchEvent(new CustomEvent('ui-select', { detail: el }));
108
- return stop();
109
- }
110
-
111
- return elCanSelect;
112
- },
113
- moveableOptions: stageOptions.moveableOptions,
114
- updateDragEl: stageOptions.updateDragEl,
115
- });
116
-
117
- services?.editorService.set('stage', markRaw(stage));
118
-
119
- stage?.mount(stageContainer.value);
120
-
121
- stage.mask.setGuides([
122
- getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
123
- getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY)),
124
- ]);
125
-
126
- stage?.on('select', (el: HTMLElement) => {
127
- services?.editorService.select(el.id);
128
- });
129
-
130
- stage?.on('highlight', (el: HTMLElement) => {
131
- services?.editorService.highlight(el.id);
132
- });
133
-
134
- stage?.on('update', (ev: UpdateEventData) => {
135
- if (ev.parentEl) {
136
- services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
137
- return;
138
- }
139
- services?.editorService.update({ id: ev.el.id, style: ev.style });
140
- });
141
-
142
- stage?.on('sort', (ev: SortEventData) => {
143
- services?.editorService.sort(ev.src, ev.dist);
144
- });
145
-
146
- stage?.on('changeGuides', (e) => {
147
- services?.uiService.set('showGuides', true);
148
-
149
- if (!root.value || !page.value) return;
150
-
151
- const storageKey = getGuideLineKey(
152
- e.type === GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY,
153
- );
154
- if (e.guides.length) {
155
- globalThis.localStorage.setItem(storageKey, JSON.stringify(e.guides));
156
- } else {
157
- globalThis.localStorage.removeItem(storageKey);
158
- }
159
- });
160
-
161
- if (!node.value?.id) return;
162
- stage?.on('runtime-ready', (rt) => {
163
- runtime = rt;
164
- // toRaw返回的值是一个引用而非快照,需要cloneDeep
165
- root.value && runtime?.updateRootConfig?.(cloneDeep(toRaw(root.value)));
166
- page.value?.id && runtime?.updatePageId?.(page.value.id);
167
- setTimeout(() => {
168
- node.value && stage?.select(toRaw(node.value.id));
169
- });
170
- });
171
- });
50
+ let stage: StageCore | null = null;
51
+ let runtime: Runtime | null = null;
52
+
53
+ const services = inject<Services>('services');
54
+ const stageOptions = inject<StageOptions>('stageOptions');
55
+
56
+ const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
57
+ const stageContainer = ref<HTMLDivElement>();
58
+ const menu = ref<InstanceType<typeof ViewerMenu>>();
59
+
60
+ const isMultiSelect = computed(() => services?.editorService.get('nodes')?.length > 1);
61
+ const stageRect = computed(() => services?.uiService.get<StageRect>('stageRect'));
62
+ const uiSelectMode = computed(() => services?.uiService.get<boolean>('uiSelectMode'));
63
+ const root = computed(() => services?.editorService.get<MApp>('root'));
64
+ const page = computed(() => services?.editorService.get<MPage>('page'));
65
+ const zoom = computed(() => services?.uiService.get<number>('zoom') || 1);
66
+ const node = computed(() => services?.editorService.get<MNode>('node'));
67
+
68
+ const getGuideLineKey = (key: string) => `${key}_${root.value?.id}_${page.value?.id}`;
69
+
70
+ watchEffect(() => {
71
+ if (stage) return;
72
+
73
+ if (!stageContainer.value) return;
74
+ if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value) return;
75
+
76
+ stage = new StageCore({
77
+ render: stageOptions.render,
78
+ runtimeUrl: stageOptions.runtimeUrl,
79
+ zoom: zoom.value,
80
+ autoScrollIntoView: stageOptions.autoScrollIntoView,
81
+ isContainer: stageOptions.isContainer,
82
+ containerHighlightClassName: stageOptions.containerHighlightClassName,
83
+ containerHighlightDuration: stageOptions.containerHighlightDuration,
84
+ canSelect: (el, event, stop) => {
85
+ const elCanSelect = stageOptions.canSelect(el);
86
+ // 在组件联动过程中不能再往下选择,返回并触发 ui-select
87
+ if (uiSelectMode.value && elCanSelect && event.type === 'mousedown') {
88
+ document.dispatchEvent(new CustomEvent('ui-select', { detail: el }));
89
+ return stop();
90
+ }
172
91
 
173
- watch(zoom, (zoom) => {
174
- if (!stage || !zoom) return;
175
- stage.setZoom(zoom);
92
+ return elCanSelect;
93
+ },
94
+ moveableOptions: stageOptions.moveableOptions,
95
+ updateDragEl: stageOptions.updateDragEl,
96
+ });
97
+
98
+ services?.editorService.set('stage', markRaw(stage));
99
+
100
+ stage?.mount(stageContainer.value);
101
+
102
+ stage.mask.setGuides([
103
+ getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
104
+ getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY)),
105
+ ]);
106
+
107
+ stage?.on('select', (el: HTMLElement) => {
108
+ services?.editorService.select(el.id);
109
+ });
110
+
111
+ stage?.on('highlight', (el: HTMLElement) => {
112
+ services?.editorService.highlight(el.id);
113
+ });
114
+
115
+ stage?.on('multiSelect', (els: HTMLElement[]) => {
116
+ services?.editorService.multiSelect(els.map((el) => el.id));
117
+ });
118
+
119
+ stage?.on('update', (ev: UpdateEventData) => {
120
+ if (ev.parentEl) {
121
+ services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
122
+ return;
123
+ }
124
+ services?.editorService.update({ id: ev.el.id, style: ev.style });
125
+ });
126
+
127
+ stage?.on('sort', (ev: SortEventData) => {
128
+ services?.editorService.sort(ev.src, ev.dist);
129
+ });
130
+
131
+ stage?.on('changeGuides', (e) => {
132
+ services?.uiService.set('showGuides', true);
133
+
134
+ if (!root.value || !page.value) return;
135
+
136
+ const storageKey = getGuideLineKey(
137
+ e.type === GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY,
138
+ );
139
+ if (e.guides.length) {
140
+ globalThis.localStorage.setItem(storageKey, JSON.stringify(e.guides));
141
+ } else {
142
+ globalThis.localStorage.removeItem(storageKey);
143
+ }
144
+ });
145
+
146
+ if (!node.value?.id) return;
147
+ stage?.on('runtime-ready', (rt) => {
148
+ runtime = rt;
149
+ // toRaw返回的值是一个引用而非快照,需要cloneDeep
150
+ root.value && runtime?.updateRootConfig?.(cloneDeep(toRaw(root.value)));
151
+ page.value?.id && runtime?.updatePageId?.(page.value.id);
152
+ setTimeout(() => {
153
+ node.value && stage?.select(toRaw(node.value.id));
176
154
  });
155
+ });
156
+ });
177
157
 
178
- watch(root, (root) => {
179
- if (runtime && root) {
180
- runtime.updateRootConfig?.(cloneDeep(toRaw(root)));
181
- }
182
- });
158
+ watch(zoom, (zoom) => {
159
+ if (!stage || !zoom) return;
160
+ stage.setZoom(zoom);
161
+ });
183
162
 
184
- const resizeObserver = new ResizeObserver((entries) => {
185
- for (const { contentRect } of entries) {
186
- services?.uiService.set('stageContainerRect', {
187
- width: contentRect.width,
188
- height: contentRect.height,
189
- });
190
- }
191
- });
163
+ watch(root, (root) => {
164
+ if (runtime && root) {
165
+ runtime.updateRootConfig?.(cloneDeep(toRaw(root)));
166
+ }
167
+ });
192
168
 
193
- onMounted(() => {
194
- stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
169
+ const resizeObserver = new ResizeObserver((entries) => {
170
+ for (const { contentRect } of entries) {
171
+ services?.uiService.set('stageContainerRect', {
172
+ width: contentRect.width,
173
+ height: contentRect.height,
195
174
  });
175
+ }
176
+ });
196
177
 
197
- onUnmounted(() => {
198
- stage?.destroy();
199
- resizeObserver.disconnect();
200
- services?.editorService.set('stage', null);
201
- });
178
+ onMounted(() => {
179
+ stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
180
+ });
202
181
 
203
- return {
204
- stageWrap,
205
- stageContainer,
206
- menu,
207
- stageRect,
208
- zoom,
209
-
210
- contextmenuHandler(e: MouseEvent) {
211
- e.preventDefault();
212
- menu.value?.show(e);
213
- },
214
-
215
- dragoverHandler(e: DragEvent) {
216
- e.preventDefault();
217
- if (e.dataTransfer) {
218
- e.dataTransfer.dropEffect = 'move';
219
- }
220
- },
221
-
222
- async dropHandler(e: DragEvent) {
223
- e.preventDefault();
224
-
225
- const doc = stage?.renderer.contentWindow?.document;
226
- const parentEl: HTMLElement | null | undefined = doc?.querySelector(
227
- `.${stageOptions?.containerHighlightClassName}`,
228
- );
229
-
230
- let parent: MContainer | undefined = page.value;
231
- if (parentEl) {
232
- parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer;
233
- }
234
-
235
- if (e.dataTransfer && parent && stageContainer.value && stage) {
236
- // eslint-disable-next-line no-eval
237
- const config = eval(`(${e.dataTransfer.getData('data')})`);
238
- const layout = await services?.editorService.getLayout(parent);
239
-
240
- const containerRect = stageContainer.value.getBoundingClientRect();
241
- const { scrollTop, scrollLeft } = stage.mask;
242
- const { style = {} } = config;
243
-
244
- let top = 0;
245
- let left = 0;
246
- let position = 'relative';
247
-
248
- if (layout === Layout.ABSOLUTE) {
249
- position = 'absolute';
250
- top = e.clientY - containerRect.top + scrollTop;
251
- left = e.clientX - containerRect.left + scrollLeft;
252
-
253
- if (parentEl && doc) {
254
- const { left: parentLeft, top: parentTop } = getOffset(parentEl);
255
- left = left - calcValueByFontsize(doc, parentLeft);
256
- top = top - calcValueByFontsize(doc, parentTop);
257
- }
258
- }
259
-
260
- config.style = {
261
- ...style,
262
- position,
263
- top,
264
- left,
265
- };
266
-
267
- config.inputEvent = e;
268
-
269
- services?.editorService.add(config, parent);
270
- }
271
- },
272
- };
273
- },
182
+ onUnmounted(() => {
183
+ stage?.destroy();
184
+ resizeObserver.disconnect();
185
+ services?.editorService.set('stage', null);
274
186
  });
187
+
188
+ const contextmenuHandler = (e: MouseEvent) => {
189
+ e.preventDefault();
190
+ menu.value?.show(e);
191
+ };
192
+
193
+ const dragoverHandler = (e: DragEvent) => {
194
+ e.preventDefault();
195
+ if (e.dataTransfer) {
196
+ e.dataTransfer.dropEffect = 'move';
197
+ }
198
+ };
199
+
200
+ const dropHandler = async (e: DragEvent) => {
201
+ e.preventDefault();
202
+
203
+ const doc = stage?.renderer.contentWindow?.document;
204
+ const parentEl: HTMLElement | null | undefined = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
205
+
206
+ let parent: MContainer | undefined = page.value;
207
+ if (parentEl) {
208
+ parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer;
209
+ }
210
+
211
+ if (e.dataTransfer && parent && stageContainer.value && stage) {
212
+ // eslint-disable-next-line no-eval
213
+ const config = eval(`(${e.dataTransfer.getData('data')})`);
214
+ const layout = await services?.editorService.getLayout(parent);
215
+
216
+ const containerRect = stageContainer.value.getBoundingClientRect();
217
+ const { scrollTop, scrollLeft } = stage.mask;
218
+ const { style = {} } = config;
219
+
220
+ let top = 0;
221
+ let left = 0;
222
+ let position = 'relative';
223
+
224
+ if (layout === Layout.ABSOLUTE) {
225
+ position = 'absolute';
226
+ top = e.clientY - containerRect.top + scrollTop;
227
+ left = e.clientX - containerRect.left + scrollLeft;
228
+
229
+ if (parentEl && doc) {
230
+ const { left: parentLeft, top: parentTop } = getOffset(parentEl);
231
+ left = left - calcValueByFontsize(doc, parentLeft);
232
+ top = top - calcValueByFontsize(doc, parentTop);
233
+ }
234
+ }
235
+
236
+ config.style = {
237
+ ...style,
238
+ position,
239
+ top,
240
+ left,
241
+ };
242
+
243
+ config.inputEvent = e;
244
+
245
+ services?.editorService.add(config, parent);
246
+ }
247
+ };
275
248
  </script>