@tmagic/editor 1.1.0-beta.9 → 1.1.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.
Files changed (70) hide show
  1. package/dist/style.css +53 -4
  2. package/dist/tmagic-editor.mjs +1134 -928
  3. package/dist/tmagic-editor.mjs.map +1 -1
  4. package/dist/tmagic-editor.umd.js +1138 -929
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/package.json +10 -10
  7. package/src/Editor.vue +28 -8
  8. package/src/components/ContentMenu.vue +4 -4
  9. package/src/components/Icon.vue +11 -23
  10. package/src/components/ScrollBar.vue +147 -0
  11. package/src/components/ScrollViewer.vue +89 -44
  12. package/src/components/ToolButton.vue +40 -138
  13. package/src/fields/UISelect.vue +2 -2
  14. package/src/index.ts +2 -2
  15. package/src/layouts/NavMenu.vue +156 -23
  16. package/src/layouts/PropsPanel.vue +49 -51
  17. package/src/layouts/sidebar/ComponentListPanel.vue +78 -90
  18. package/src/layouts/sidebar/LayerMenu.vue +3 -3
  19. package/src/layouts/sidebar/LayerPanel.vue +39 -8
  20. package/src/layouts/sidebar/Sidebar.vue +4 -0
  21. package/src/layouts/sidebar/TabPane.vue +12 -0
  22. package/src/layouts/workspace/PageBar.vue +2 -2
  23. package/src/layouts/workspace/PageBarScrollContainer.vue +13 -3
  24. package/src/layouts/workspace/Stage.vue +10 -92
  25. package/src/layouts/workspace/ViewerMenu.vue +3 -3
  26. package/src/layouts/workspace/Workspace.vue +133 -138
  27. package/src/services/componentList.ts +5 -0
  28. package/src/services/editor.ts +57 -20
  29. package/src/services/events.ts +8 -2
  30. package/src/services/props.ts +31 -52
  31. package/src/services/storage.ts +4 -0
  32. package/src/services/ui.ts +33 -30
  33. package/src/theme/component-list-panel.scss +0 -5
  34. package/src/theme/content-menu.scss +4 -0
  35. package/src/theme/icon.scss +6 -0
  36. package/src/theme/index.scss +1 -0
  37. package/src/theme/nav-menu.scss +6 -0
  38. package/src/type.ts +28 -10
  39. package/src/utils/index.ts +1 -0
  40. package/src/utils/operator.ts +3 -3
  41. package/src/utils/props.ts +0 -3
  42. package/src/utils/scroll-viewer.ts +90 -158
  43. package/src/utils/stage.ts +91 -0
  44. package/types/Editor.vue.d.ts +7 -7
  45. package/types/components/ContentMenu.vue.d.ts +8 -8
  46. package/types/components/Icon.vue.d.ts +62 -12
  47. package/types/components/ScrollBar.vue.d.ts +83 -0
  48. package/types/components/ScrollViewer.vue.d.ts +131 -19
  49. package/types/components/ToolButton.vue.d.ts +56 -59
  50. package/types/index.d.ts +2 -1
  51. package/types/layouts/NavMenu.vue.d.ts +92 -23
  52. package/types/layouts/PropsPanel.vue.d.ts +25 -208
  53. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +50 -12
  54. package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
  55. package/types/layouts/sidebar/LayerPanel.vue.d.ts +17 -15
  56. package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
  57. package/types/services/componentList.d.ts +1 -0
  58. package/types/services/editor.d.ts +1 -0
  59. package/types/services/events.d.ts +1 -0
  60. package/types/services/props.d.ts +41 -9
  61. package/types/services/storage.d.ts +1 -0
  62. package/types/services/ui.d.ts +4 -1
  63. package/types/type.d.ts +25 -10
  64. package/types/utils/index.d.ts +1 -0
  65. package/types/utils/operator.d.ts +1 -1
  66. package/types/utils/props.d.ts +0 -1
  67. package/types/utils/scroll-viewer.d.ts +16 -18
  68. package/types/utils/stage.d.ts +3 -0
  69. package/src/utils/polyfills.ts +0 -8
  70. package/types/utils/polyfills.d.ts +0 -0
@@ -24,11 +24,13 @@
24
24
  @dragend="dragendHandler"
25
25
  @drag="dragHandler"
26
26
  >
27
- <m-icon :icon="item.icon"></m-icon>
27
+ <slot name="component-list-item" :component="item">
28
+ <MIcon :icon="item.icon"></MIcon>
28
29
 
29
- <el-tooltip effect="dark" placement="bottom" :content="item.text">
30
- <span>{{ item.text }}</span>
31
- </el-tooltip>
30
+ <el-tooltip effect="dark" placement="bottom" :content="item.text">
31
+ <span>{{ item.text }}</span>
32
+ </el-tooltip>
33
+ </slot>
32
34
  </div>
33
35
  </el-collapse-item>
34
36
  </template>
@@ -36,8 +38,8 @@
36
38
  </el-scrollbar>
37
39
  </template>
38
40
 
39
- <script lang="ts">
40
- import { computed, defineComponent, inject, ref } from 'vue';
41
+ <script lang="ts" setup>
42
+ import { computed, inject, ref } from 'vue';
41
43
  import serialize from 'serialize-javascript';
42
44
 
43
45
  import type StageCore from '@tmagic/stage';
@@ -46,89 +48,75 @@ import { removeClassNameByClassName } from '@tmagic/utils';
46
48
  import MIcon from '../../components/Icon.vue';
47
49
  import type { ComponentGroup, ComponentItem, Services, StageOptions } from '../../type';
48
50
 
49
- export default defineComponent({
50
- name: 'ui-component-panel',
51
-
52
- components: { MIcon },
53
-
54
- setup() {
55
- const searchText = ref('');
56
- const services = inject<Services>('services');
57
- const stageOptions = inject<StageOptions>('stageOptions');
58
-
59
- const stage = computed(() => services?.editorService.get<StageCore>('stage'));
60
- const list = computed(() =>
61
- services?.componentListService.getList().map((group: ComponentGroup) => ({
62
- ...group,
63
- items: group.items.filter((item: ComponentItem) => item.text.includes(searchText.value)),
64
- })),
51
+ const searchText = ref('');
52
+ const services = inject<Services>('services');
53
+ const stageOptions = inject<StageOptions>('stageOptions');
54
+
55
+ const stage = computed(() => services?.editorService.get<StageCore>('stage'));
56
+ const list = computed(() =>
57
+ services?.componentListService.getList().map((group: ComponentGroup) => ({
58
+ ...group,
59
+ items: group.items.filter((item: ComponentItem) => item.text.includes(searchText.value)),
60
+ })),
61
+ );
62
+ const collapseValue = computed(() =>
63
+ Array(list.value?.length)
64
+ .fill(1)
65
+ .map((x, i) => i),
66
+ );
67
+
68
+ let timeout: NodeJS.Timeout | undefined;
69
+ let clientX: number;
70
+ let clientY: number;
71
+
72
+ const appendComponent = ({ text, type, data = {} }: ComponentItem): void => {
73
+ services?.editorService.add({
74
+ name: text,
75
+ type,
76
+ ...data,
77
+ });
78
+ };
79
+
80
+ const dragstartHandler = ({ text, type, data = {} }: ComponentItem, e: DragEvent) => {
81
+ if (e.dataTransfer) {
82
+ e.dataTransfer.effectAllowed = 'move';
83
+ e.dataTransfer.setData(
84
+ 'data',
85
+ serialize({
86
+ name: text,
87
+ type,
88
+ ...data,
89
+ }).replace(/"(\w+)":\s/g, '$1: '),
65
90
  );
66
- const collapseValue = computed(() =>
67
- Array(list.value?.length)
68
- .fill(1)
69
- .map((x, i) => i),
70
- );
71
-
72
- let timeout: NodeJS.Timeout | undefined;
73
- let clientX: number;
74
- let clientY: number;
75
-
76
- return {
77
- searchText,
78
- collapseValue,
79
- list,
80
-
81
- appendComponent({ text, type, data = {} }: ComponentItem): void {
82
- services?.editorService.add({
83
- name: text,
84
- type,
85
- ...data,
86
- });
87
- },
88
-
89
- dragstartHandler({ text, type, data = {} }: ComponentItem, e: DragEvent) {
90
- if (e.dataTransfer) {
91
- e.dataTransfer.effectAllowed = 'move';
92
- e.dataTransfer.setData(
93
- 'data',
94
- serialize({
95
- name: text,
96
- type,
97
- ...data,
98
- }).replace(/"(\w+)":\s/g, '$1: '),
99
- );
100
- }
101
- },
102
-
103
- dragendHandler() {
104
- if (timeout) {
105
- globalThis.clearTimeout(timeout);
106
- timeout = undefined;
107
- }
108
- const doc = stage.value?.renderer.contentWindow?.document;
109
- if (doc && stageOptions) {
110
- removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
111
- }
112
- clientX = 0;
113
- clientY = 0;
114
- },
115
-
116
- dragHandler(e: DragEvent) {
117
- if (e.clientX !== clientX || e.clientY !== clientY) {
118
- clientX = e.clientX;
119
- clientY = e.clientY;
120
- if (timeout) {
121
- globalThis.clearTimeout(timeout);
122
- timeout = undefined;
123
- }
124
- return;
125
- }
126
-
127
- if (timeout || !stage.value) return;
128
-
129
- timeout = stage.value.getAddContainerHighlightClassNameTimeout(e);
130
- },
131
- };
132
- },
133
- });
91
+ }
92
+ };
93
+
94
+ const dragendHandler = () => {
95
+ if (timeout) {
96
+ globalThis.clearTimeout(timeout);
97
+ timeout = undefined;
98
+ }
99
+ const doc = stage.value?.renderer.contentWindow?.document;
100
+ if (doc && stageOptions) {
101
+ removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
102
+ }
103
+ clientX = 0;
104
+ clientY = 0;
105
+ };
106
+
107
+ const dragHandler = (e: DragEvent) => {
108
+ if (e.clientX !== clientX || e.clientY !== clientY) {
109
+ clientX = e.clientX;
110
+ clientY = e.clientY;
111
+ if (timeout) {
112
+ globalThis.clearTimeout(timeout);
113
+ timeout = undefined;
114
+ }
115
+ return;
116
+ }
117
+
118
+ if (timeout || !stage.value) return;
119
+
120
+ timeout = stage.value.getAddContainerHighlightClassNameTimeout(e);
121
+ };
134
122
  </script>
@@ -9,7 +9,7 @@ import { Delete, DocumentCopy, Files, Plus } from '@element-plus/icons-vue';
9
9
  import { NodeType } from '@tmagic/schema';
10
10
 
11
11
  import ContentMenu from '../../components/ContentMenu.vue';
12
- import type { ComponentGroup, MenuButton, MenuItem, Services } from '../../type';
12
+ import type { ComponentGroup, MenuButton, MenuComponent, Services } from '../../type';
13
13
 
14
14
  export default defineComponent({
15
15
  components: { ContentMenu },
@@ -22,7 +22,7 @@ export default defineComponent({
22
22
  const isPage = computed(() => node.value?.type === NodeType.PAGE);
23
23
  const componentList = computed(() => services?.componentListService.getList() || []);
24
24
 
25
- const layerContentMenu = inject<MenuItem[]>('layerContentMenu', []);
25
+ const layerContentMenu = inject<(MenuComponent | MenuButton)[]>('layerContentMenu', []);
26
26
 
27
27
  const createMenuItems = (group: ComponentGroup): MenuButton[] =>
28
28
  group.items.map((component) => ({
@@ -77,7 +77,7 @@ export default defineComponent({
77
77
 
78
78
  return {
79
79
  menu,
80
- menuData: computed<MenuItem[]>(() => [
80
+ menuData: computed<(MenuButton | MenuComponent)[]>(() => [
81
81
  {
82
82
  type: 'button',
83
83
  text: '新增',
@@ -15,6 +15,7 @@
15
15
  v-if="values.length"
16
16
  ref="tree"
17
17
  node-key="id"
18
+ empty-text="页面空荡荡的"
18
19
  draggable
19
20
  :default-expanded-keys="expandedKeys"
20
21
  :load="loadItems"
@@ -29,7 +30,8 @@
29
30
  @node-click="clickHandler"
30
31
  @node-contextmenu="contextmenu"
31
32
  @node-drag-end="handleDragEnd"
32
- empty-text="页面空荡荡的"
33
+ @node-collapse="handleCollapse"
34
+ @node-expand="handleExpand"
33
35
  >
34
36
  <template #default="{ node, data }">
35
37
  <div
@@ -60,7 +62,7 @@ import { computed, defineComponent, inject, Ref, ref, watchEffect } from 'vue';
60
62
  import type { ElTree } from 'element-plus';
61
63
  import { throttle } from 'lodash-es';
62
64
 
63
- import type { MNode, MPage } from '@tmagic/schema';
65
+ import type { Id, MNode, MPage } from '@tmagic/schema';
64
66
  import { MContainer, NodeType } from '@tmagic/schema';
65
67
  import StageCore from '@tmagic/stage';
66
68
 
@@ -122,22 +124,41 @@ const useDrop = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorServi
122
124
  });
123
125
 
124
126
  const useStatus = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorService?: EditorService) => {
125
- const highlightNode = ref<MNode>();
126
127
  const node = ref<MNode>();
127
128
  const page = computed(() => editorService?.get('page'));
129
+ const expandedKeys = new Map<Id, Id>();
130
+
131
+ const expandNodes = () => {
132
+ expandedKeys.forEach((key) => {
133
+ if (!tree.value) return;
134
+ tree.value.getNode(key)?.expand();
135
+ });
136
+ };
128
137
 
129
138
  watchEffect(() => {
130
139
  if (!tree.value) return;
131
- node.value = editorService?.get('node');
132
- node.value && tree.value.setCurrentKey(node.value.id, true);
140
+ if (!editorService) return;
141
+ node.value = editorService.get('node');
142
+
143
+ if (!node.value) return;
133
144
 
134
- const parent = editorService?.get('parent');
145
+ tree.value.setCurrentKey(node.value.id, true);
146
+
147
+ const parent = editorService.get('parent');
135
148
  if (!parent?.id) return;
136
149
 
137
150
  const treeNode = tree.value.getNode(parent.id);
138
151
  treeNode?.updateChildren();
139
152
 
140
- highlightNode.value = editorService?.get('highlightNode');
153
+ setTimeout(() => {
154
+ tree.value &&
155
+ Object.entries(tree.value.store.nodesMap).forEach(([id, node]) => {
156
+ if (node.expanded && node.data.items) {
157
+ expandedKeys.set(id, id);
158
+ }
159
+ });
160
+ expandNodes();
161
+ });
141
162
  });
142
163
 
143
164
  return {
@@ -153,9 +174,19 @@ const useStatus = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorSer
153
174
  resolve([]);
154
175
  },
155
176
 
156
- highlightNode,
177
+ highlightNode: computed(() => editorService?.get('highlightNode')),
157
178
  clickNode: node,
158
179
  expandedKeys: computed(() => (node.value ? [node.value.id] : [])),
180
+
181
+ handleCollapse: (data: MNode) => {
182
+ expandedKeys.delete(data.id);
183
+ },
184
+
185
+ handleExpand: (data: MNode) => {
186
+ const parent = editorService?.getParentById(data.id);
187
+ if (!parent?.id) return;
188
+ expandedKeys.set(parent.id, parent.id);
189
+ },
159
190
  };
160
191
  };
161
192
 
@@ -14,6 +14,10 @@
14
14
  <template #component-list-panel-header v-if="item === 'component-list'">
15
15
  <slot name="component-list-panel-header"></slot>
16
16
  </template>
17
+
18
+ <template #component-list-item="{ component }" v-if="item === 'component-list'">
19
+ <slot name="component-list-item" :component="component"></slot>
20
+ </template>
17
21
  </tab-pane>
18
22
  </el-tabs>
19
23
  </template>
@@ -13,6 +13,18 @@
13
13
  <component v-else-if="config.slots?.componentListPanelHeader" :is="config.slots.componentListPanelHeader" />
14
14
  </template>
15
15
 
16
+ <template
17
+ #component-list-item="{ component }"
18
+ v-if="data === 'component-list' || config.slots?.componentListItem"
19
+ >
20
+ <slot v-if="data === 'component-list'" name="component-list-item" :component="component"></slot>
21
+ <component
22
+ v-else-if="config.slots?.componentListItem"
23
+ :is="config.slots.componentListItem"
24
+ :component="component"
25
+ />
26
+ </template>
27
+
16
28
  <template #layer-panel-header v-if="data === 'layer' || config.slots?.layerPanelHeader">
17
29
  <slot v-if="data === 'layer'" name="layer-panel-header"></slot>
18
30
  <component v-else-if="config.slots?.layerPanelHeader" :is="config.slots.layerPanelHeader" />
@@ -10,7 +10,7 @@
10
10
  <div class="m-editor-page-bar-title">
11
11
  <slot name="page-bar-title" :page="item">
12
12
  <el-tooltip effect="dark" placement="top-start" :content="item.name">
13
- <span>{{ item.name }}</span>
13
+ <span>{{ item.name || item.id }}</span>
14
14
  </el-tooltip>
15
15
  </slot>
16
16
  </div>
@@ -38,7 +38,7 @@
38
38
  </div>
39
39
  <template #reference>
40
40
  <el-icon class="m-editor-page-bar-menu-icon">
41
- <caret-bottom></caret-bottom>
41
+ <CaretBottom></CaretBottom>
42
42
  </el-icon>
43
43
  </template>
44
44
  </el-popover>
@@ -1,8 +1,14 @@
1
1
  <template>
2
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">
3
+ <div
4
+ v-if="showAddPageButton"
5
+ id="m-editor-page-bar-add-icon"
6
+ class="m-editor-page-bar-item m-editor-page-bar-item-icon"
7
+ @click="addPage"
8
+ >
4
9
  <el-icon><plus></plus></el-icon>
5
10
  </div>
11
+ <div v-else style="width: 21px"></div>
6
12
  <div v-if="canScroll" class="m-editor-page-bar-item m-editor-page-bar-item-icon" @click="scroll('left')">
7
13
  <el-icon><arrow-left-bold></arrow-left-bold></el-icon>
8
14
  </div>
@@ -26,13 +32,17 @@ import { generatePageNameByApp } from '../../utils/editor';
26
32
 
27
33
  const services = inject<Services>('services');
28
34
  const editorService = services?.editorService;
35
+ const uiService = services?.uiService;
29
36
 
30
37
  const pageBar = ref<HTMLDivElement>();
31
38
  const itemsContainer = ref<HTMLDivElement>();
32
39
  const pageBarWidth = ref(0);
33
40
  const canScroll = ref(false);
34
41
 
35
- const itemsContainerWidth = computed(() => pageBarWidth.value - 105);
42
+ const showAddPageButton = computed(() => uiService?.get('showAddPageButton'));
43
+
44
+ // 减去新增、左移、右移三个按钮的宽度
45
+ const itemsContainerWidth = computed(() => pageBarWidth.value - 35 * 2 - (showAddPageButton.value ? 35 : 21));
36
46
 
37
47
  let translateLeft = 0;
38
48
  const resizeObserver = new ResizeObserver((entries) => {
@@ -46,7 +56,7 @@ const resizeObserver = new ResizeObserver((entries) => {
46
56
 
47
57
  const setCanScroll = () => {
48
58
  if (itemsContainer.value) {
49
- canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
59
+ canScroll.value = itemsContainer.value.scrollWidth > itemsContainerWidth.value;
50
60
  }
51
61
  };
52
62
 
@@ -4,12 +4,14 @@
4
4
  ref="stageWrap"
5
5
  :width="stageRect?.width"
6
6
  :height="stageRect?.height"
7
+ :wrap-width="stageContainerRect?.width"
8
+ :wrap-height="stageContainerRect?.height"
7
9
  :zoom="zoom"
8
10
  >
9
11
  <div
10
12
  class="m-editor-stage-container"
11
13
  ref="stageContainer"
12
- :style="`transform: scale(${zoom})`"
14
+ :style="`transform: scale(${zoom});`"
13
15
  @contextmenu="contextmenuHandler"
14
16
  @drop="dropHandler"
15
17
  @dragover="dragoverHandler"
@@ -25,25 +27,11 @@ import { computed, inject, markRaw, onMounted, onUnmounted, ref, toRaw, watch, w
25
27
  import { cloneDeep } from 'lodash-es';
26
28
 
27
29
  import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
28
- import StageCore, {
29
- calcValueByFontsize,
30
- getOffset,
31
- GuidesType,
32
- Runtime,
33
- SortEventData,
34
- UpdateEventData,
35
- } from '@tmagic/stage';
30
+ import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stage';
36
31
 
37
32
  import ScrollViewer from '../../components/ScrollViewer.vue';
38
- import {
39
- H_GUIDE_LINE_STORAGE_KEY,
40
- Layout,
41
- Services,
42
- StageOptions,
43
- StageRect,
44
- V_GUIDE_LINE_STORAGE_KEY,
45
- } from '../../type';
46
- import { getGuideLineFromCache } from '../../utils';
33
+ import { Layout, Services, StageOptions, StageRect } from '../../type';
34
+ import { useStage } from '../../utils/stage';
47
35
 
48
36
  import ViewerMenu from './ViewerMenu.vue';
49
37
 
@@ -59,94 +47,24 @@ const menu = ref<InstanceType<typeof ViewerMenu>>();
59
47
 
60
48
  const isMultiSelect = computed(() => services?.editorService.get('nodes')?.length > 1);
61
49
  const stageRect = computed(() => services?.uiService.get<StageRect>('stageRect'));
62
- const uiSelectMode = computed(() => services?.uiService.get<boolean>('uiSelectMode'));
50
+ const stageContainerRect = computed(() => services?.uiService.get<StageRect>('stageContainerRect'));
63
51
  const root = computed(() => services?.editorService.get<MApp>('root'));
64
52
  const page = computed(() => services?.editorService.get<MPage>('page'));
65
53
  const zoom = computed(() => services?.uiService.get<number>('zoom') || 1);
66
54
  const node = computed(() => services?.editorService.get<MNode>('node'));
67
55
 
68
- const getGuideLineKey = (key: string) => `${key}_${root.value?.id}_${page.value?.id}`;
69
-
70
56
  watchEffect(() => {
71
57
  if (stage) return;
72
58
 
73
59
  if (!stageContainer.value) return;
74
60
  if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value) return;
75
61
 
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
- containerHighlightType: stageOptions.containerHighlightType,
85
- canSelect: (el, event, stop) => {
86
- const elCanSelect = stageOptions.canSelect(el);
87
- // 在组件联动过程中不能再往下选择,返回并触发 ui-select
88
- if (uiSelectMode.value && elCanSelect && event.type === 'mousedown') {
89
- document.dispatchEvent(new CustomEvent('ui-select', { detail: el }));
90
- return stop();
91
- }
92
-
93
- return elCanSelect;
94
- },
95
- moveableOptions: stageOptions.moveableOptions,
96
- updateDragEl: stageOptions.updateDragEl,
97
- });
62
+ stage = useStage(stageOptions);
98
63
 
99
64
  services?.editorService.set('stage', markRaw(stage));
100
65
 
101
66
  stage?.mount(stageContainer.value);
102
67
 
103
- stage.mask.setGuides([
104
- getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
105
- getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY)),
106
- ]);
107
-
108
- stage?.on('select', (el: HTMLElement) => {
109
- services?.editorService.select(el.id);
110
- });
111
-
112
- stage?.on('highlight', (el: HTMLElement) => {
113
- services?.editorService.highlight(el.id);
114
- });
115
-
116
- stage?.on('multiSelect', (els: HTMLElement[]) => {
117
- services?.editorService.multiSelect(els.map((el) => el.id));
118
- });
119
-
120
- stage?.on('update', (ev: UpdateEventData) => {
121
- if (ev.parentEl) {
122
- for (const data of ev.data) {
123
- services?.editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
124
- }
125
- return;
126
- }
127
-
128
- services?.editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
129
- });
130
-
131
- stage?.on('sort', (ev: SortEventData) => {
132
- services?.editorService.sort(ev.src, ev.dist);
133
- });
134
-
135
- stage?.on('changeGuides', (e) => {
136
- services?.uiService.set('showGuides', true);
137
-
138
- if (!root.value || !page.value) return;
139
-
140
- const storageKey = getGuideLineKey(
141
- e.type === GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY,
142
- );
143
- if (e.guides.length) {
144
- globalThis.localStorage.setItem(storageKey, JSON.stringify(e.guides));
145
- } else {
146
- globalThis.localStorage.removeItem(storageKey);
147
- }
148
- });
149
-
150
68
  if (!node.value?.id) return;
151
69
  stage?.on('runtime-ready', (rt) => {
152
70
  runtime = rt;
@@ -240,8 +158,8 @@ const dropHandler = async (e: DragEvent) => {
240
158
  config.style = {
241
159
  ...style,
242
160
  position,
243
- top,
244
- left,
161
+ top: top / zoom.value,
162
+ left: left / zoom.value,
245
163
  };
246
164
 
247
165
  config.inputEvent = e;
@@ -12,7 +12,7 @@ import { isPage } from '@tmagic/utils';
12
12
 
13
13
  import ContentMenu from '../../components/ContentMenu.vue';
14
14
  import storageService from '../../services/storage';
15
- import { LayerOffset, Layout, MenuItem, Services } from '../../type';
15
+ import { LayerOffset, Layout, MenuButton, MenuComponent, Services } from '../../type';
16
16
  import { COPY_STORAGE_KEY } from '../../utils/editor';
17
17
 
18
18
  const props = withDefaults(defineProps<{ isMultiSelect?: boolean }>(), { isMultiSelect: false });
@@ -28,9 +28,9 @@ const nodes = computed(() => editorService?.get<MNode[]>('nodes'));
28
28
  const parent = computed(() => editorService?.get('parent'));
29
29
  const stage = computed(() => editorService?.get<StageCore>('stage'));
30
30
 
31
- const stageContentMenu = inject<MenuItem[]>('stageContentMenu', []);
31
+ const stageContentMenu = inject<(MenuButton | MenuComponent)[]>('stageContentMenu', []);
32
32
 
33
- const menuData = reactive<MenuItem[]>([
33
+ const menuData = reactive<(MenuButton | MenuComponent)[]>([
34
34
  {
35
35
  type: 'button',
36
36
  text: '水平居中',