@tmagic/editor 1.0.0-rc.3 → 1.0.0-rc.6

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 (63) hide show
  1. package/coverage/clover.xml +505 -446
  2. package/coverage/coverage-final.json +10 -10
  3. package/coverage/lcov-report/index.html +60 -60
  4. package/coverage/lcov-report/src/Editor.vue.html +48 -9
  5. package/coverage/lcov-report/src/components/ContentMenu.vue.html +143 -44
  6. package/coverage/lcov-report/src/components/Icon.vue.html +2 -2
  7. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +1 -1
  8. package/coverage/lcov-report/src/components/ToolButton.vue.html +25 -25
  9. package/coverage/lcov-report/src/components/index.html +20 -20
  10. package/coverage/lcov-report/src/index.html +15 -15
  11. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +1 -1
  12. package/coverage/lcov-report/src/layouts/Framework.vue.html +1 -1
  13. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +1 -1
  14. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +1 -1
  15. package/coverage/lcov-report/src/layouts/Resizer.vue.html +1 -1
  16. package/coverage/lcov-report/src/layouts/index.html +1 -1
  17. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +1 -1
  18. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +27 -18
  19. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +1 -1
  20. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +1 -1
  21. package/coverage/lcov-report/src/layouts/sidebar/TabPane.vue.html +2 -2
  22. package/coverage/lcov-report/src/layouts/sidebar/index.html +19 -19
  23. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +1 -1
  24. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +1 -1
  25. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +78 -33
  26. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +79 -34
  27. package/coverage/lcov-report/src/layouts/workspace/index.html +28 -28
  28. package/coverage/lcov-report/src/services/BaseService.ts.html +2 -2
  29. package/coverage/lcov-report/src/services/componentList.ts.html +1 -1
  30. package/coverage/lcov-report/src/services/editor.ts.html +102 -12
  31. package/coverage/lcov-report/src/services/events.ts.html +1 -1
  32. package/coverage/lcov-report/src/services/history.ts.html +1 -1
  33. package/coverage/lcov-report/src/services/index.html +15 -15
  34. package/coverage/lcov-report/src/services/props.ts.html +4 -4
  35. package/coverage/lcov-report/src/services/ui.ts.html +1 -1
  36. package/coverage/lcov-report/src/type.ts.html +1 -1
  37. package/coverage/lcov-report/src/utils/compose.ts.html +1 -1
  38. package/coverage/lcov-report/src/utils/config.ts.html +1 -1
  39. package/coverage/lcov-report/src/utils/editor.ts.html +21 -9
  40. package/coverage/lcov-report/src/utils/index.html +12 -12
  41. package/coverage/lcov-report/src/utils/index.ts.html +1 -1
  42. package/coverage/lcov-report/src/utils/logger.ts.html +1 -1
  43. package/coverage/lcov-report/src/utils/props.ts.html +1 -1
  44. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +1 -1
  45. package/coverage/lcov-report/src/utils/undo-redo.ts.html +1 -1
  46. package/coverage/lcov.info +1132 -986
  47. package/dist/tmagic-editor.es.js +148 -62
  48. package/dist/tmagic-editor.es.js.map +1 -1
  49. package/dist/tmagic-editor.umd.js +148 -62
  50. package/dist/tmagic-editor.umd.js.map +1 -1
  51. package/dist/types/src/Editor.vue.d.ts +19 -1
  52. package/dist/types/src/services/BaseService.d.ts +1 -1
  53. package/package.json +7 -7
  54. package/src/Editor.vue +14 -1
  55. package/src/components/ContentMenu.vue +59 -26
  56. package/src/layouts/sidebar/LayerMenu.vue +3 -0
  57. package/src/layouts/sidebar/TabPane.vue +1 -1
  58. package/src/layouts/workspace/ViewerMenu.vue +17 -2
  59. package/src/layouts/workspace/Workspace.vue +38 -23
  60. package/src/services/BaseService.ts +1 -1
  61. package/src/services/editor.ts +33 -3
  62. package/src/services/props.ts +3 -3
  63. package/src/utils/editor.ts +6 -2
@@ -3,7 +3,7 @@ import type { FormConfig } from '@tmagic/form';
3
3
  import type { MApp, MNode } from '@tmagic/schema';
4
4
  import type StageCore from '@tmagic/stage';
5
5
  import type { MoveableOptions } from '@tmagic/stage';
6
- import type { ComponentGroup, MenuBarData, Services, SideBarData, StageRect } from './type';
6
+ import type { ComponentGroup, MenuBarData, MenuItem, Services, SideBarData, StageRect } from './type';
7
7
  declare const _default: DefineComponent<{
8
8
  /** 页面初始值 */
9
9
  modelValue: {
@@ -20,6 +20,14 @@ declare const _default: DefineComponent<{
20
20
  sidebar: {
21
21
  type: PropType<SideBarData>;
22
22
  };
23
+ layerContentMenu: {
24
+ type: PropType<MenuItem[]>;
25
+ default: () => never[];
26
+ };
27
+ stageContentMenu: {
28
+ type: PropType<MenuItem[]>;
29
+ default: () => never[];
30
+ };
23
31
  /** 顶部工具栏配置 */
24
32
  menu: {
25
33
  type: PropType<MenuBarData>;
@@ -85,6 +93,14 @@ declare const _default: DefineComponent<{
85
93
  sidebar: {
86
94
  type: PropType<SideBarData>;
87
95
  };
96
+ layerContentMenu: {
97
+ type: PropType<MenuItem[]>;
98
+ default: () => never[];
99
+ };
100
+ stageContentMenu: {
101
+ type: PropType<MenuItem[]>;
102
+ default: () => never[];
103
+ };
88
104
  /** 顶部工具栏配置 */
89
105
  menu: {
90
106
  type: PropType<MenuBarData>;
@@ -139,6 +155,8 @@ declare const _default: DefineComponent<{
139
155
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
140
156
  }, {
141
157
  menu: MenuBarData;
158
+ layerContentMenu: MenuItem[];
159
+ stageContentMenu: MenuItem[];
142
160
  autoScrollIntoView: boolean;
143
161
  codeOptions: Record<string, any>;
144
162
  modelValue: MApp;
@@ -27,7 +27,7 @@ import { EventEmitter } from 'events';
27
27
  * editorService.afterAdd();
28
28
  * }
29
29
  *
30
- * 调用时的参数会透传到before方法的参数中, 然后before的return 会作为原方法的参数和after的参数,after最后一个参数则是原方法的return值;
30
+ * 调用时的参数会透传到before方法的参数中, 然后before的return 会作为原方法的参数和after的参数,after第一个参数则是原方法的return值;
31
31
  * 如需终止后续方法调用可以return new Error();
32
32
  *
33
33
  * 方法2:
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-rc.3",
2
+ "version": "1.0.0-rc.6",
3
3
  "name": "@tmagic/editor",
4
4
  "sideEffects": [
5
5
  "dist/*",
@@ -45,11 +45,11 @@
45
45
  "dependencies": {
46
46
  "@babel/core": "^7.18.0",
47
47
  "@element-plus/icons": "0.0.11",
48
- "@tmagic/core": "^1.0.0-rc.3",
49
- "@tmagic/form": "^1.0.0-rc.3",
50
- "@tmagic/schema": "^1.0.0-rc.3",
51
- "@tmagic/stage": "^1.0.0-rc.3",
52
- "@tmagic/utils": "^1.0.0-rc.3",
48
+ "@tmagic/core": "^1.0.0-rc.6",
49
+ "@tmagic/form": "^1.0.0-rc.6",
50
+ "@tmagic/schema": "^1.0.0-rc.6",
51
+ "@tmagic/stage": "^1.0.0-rc.6",
52
+ "@tmagic/utils": "^1.0.0-rc.6",
53
53
  "buffer": "^6.0.3",
54
54
  "color": "^3.1.3",
55
55
  "element-plus": "^2.2.0",
@@ -88,5 +88,5 @@
88
88
  "vite-plugin-dts": "^0.9.6",
89
89
  "vue-tsc": "^0.0.24"
90
90
  },
91
- "gitHead": "d9f6ca25a0a6efba35d183e643a306e164b74af7"
91
+ "gitHead": "a93928e56d73b7924991e899a4dfaf9614cd357c"
92
92
  }
package/src/Editor.vue CHANGED
@@ -56,7 +56,7 @@ import eventsService from '@editor/services/events';
56
56
  import historyService from '@editor/services/history';
57
57
  import propsService from '@editor/services/props';
58
58
  import uiService from '@editor/services/ui';
59
- import type { ComponentGroup, MenuBarData, Services, SideBarData, StageRect } from '@editor/type';
59
+ import type { ComponentGroup, MenuBarData, MenuItem, Services, SideBarData, StageRect } from '@editor/type';
60
60
 
61
61
  export default defineComponent({
62
62
  name: 'm-editor',
@@ -88,6 +88,16 @@ export default defineComponent({
88
88
  type: Object as PropType<SideBarData>,
89
89
  },
90
90
 
91
+ layerContentMenu: {
92
+ type: Array as PropType<MenuItem[]>,
93
+ default: () => [],
94
+ },
95
+
96
+ stageContentMenu: {
97
+ type: Array as PropType<MenuItem[]>,
98
+ default: () => [],
99
+ },
100
+
91
101
  /** 顶部工具栏配置 */
92
102
  menu: {
93
103
  type: Object as PropType<MenuBarData>,
@@ -237,6 +247,9 @@ export default defineComponent({
237
247
 
238
248
  provide('services', services);
239
249
 
250
+ provide('layerContentMenu', props.layerContentMenu);
251
+ provide('stageContentMenu', props.stageContentMenu);
252
+
240
253
  return services;
241
254
  },
242
255
  });
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div v-if="menuData.length" v-show="visible" class="magic-editor-content-menu" ref="menu" :style="menuStyle">
2
+ <div v-if="menuData.length && visible" class="magic-editor-content-menu" ref="menu" :style="menuStyle">
3
3
  <div>
4
4
  <tool-button
5
5
  v-for="(item, index) in menuData"
@@ -11,13 +11,19 @@
11
11
  ></tool-button>
12
12
  </div>
13
13
  <teleport to="body">
14
- <content-menu class="sub-menu" ref="subMenu" :menu-data="subMenuData"></content-menu>
14
+ <content-menu
15
+ class="sub-menu"
16
+ ref="subMenu"
17
+ :menu-data="subMenuData"
18
+ :is-sub-menu="true"
19
+ @hide="hide"
20
+ ></content-menu>
15
21
  </teleport>
16
22
  </div>
17
23
  </template>
18
24
 
19
25
  <script lang="ts">
20
- import { defineComponent, nextTick, onMounted, PropType, ref } from 'vue';
26
+ import { defineComponent, nextTick, onMounted, onUnmounted, PropType, ref } from 'vue';
21
27
 
22
28
  import { MenuButton, MenuItem } from '@editor/type';
23
29
 
@@ -31,9 +37,16 @@ export default defineComponent({
31
37
  type: Array as PropType<MenuItem[]>,
32
38
  default: () => [],
33
39
  },
40
+
41
+ isSubMenu: {
42
+ type: Boolean,
43
+ default: false,
44
+ },
34
45
  },
35
46
 
36
- setup() {
47
+ emits: ['hide', 'show'],
48
+
49
+ setup(props, { emit }) {
37
50
  const menu = ref<HTMLDivElement>();
38
51
  const subMenu = ref<any>();
39
52
  const visible = ref(false);
@@ -44,20 +57,35 @@ export default defineComponent({
44
57
  });
45
58
 
46
59
  const hide = () => {
60
+ if (!visible.value) return;
61
+
47
62
  visible.value = false;
63
+ subMenu.value?.hide();
64
+
65
+ emit('hide');
66
+ };
67
+
68
+ const hideHandler = (e: MouseEvent) => {
69
+ const target = e.target as HTMLElement | undefined;
70
+ if (!visible.value || !target) {
71
+ return;
72
+ }
73
+ if (menu.value?.contains(target) || subMenu.value?.$el?.contains(target)) {
74
+ return;
75
+ }
76
+ hide();
48
77
  };
49
78
 
50
79
  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
- );
80
+ if (props.isSubMenu) return;
81
+
82
+ globalThis.addEventListener('mousedown', hideHandler, true);
83
+ });
84
+
85
+ onUnmounted(() => {
86
+ if (props.isSubMenu) return;
87
+
88
+ globalThis.removeEventListener('mousedown', hideHandler, true);
61
89
  });
62
90
 
63
91
  return {
@@ -70,21 +98,26 @@ export default defineComponent({
70
98
  hide,
71
99
 
72
100
  show(e: MouseEvent) {
73
- visible.value = true;
101
+ // 加settimeout是以为,如果菜单中的按钮监听的是mouseup,那么菜单显示出来时鼠标如果正好在菜单上就会马上触发按钮的mouseup
102
+ setTimeout(() => {
103
+ visible.value = true;
104
+
105
+ nextTick(() => {
106
+ const menuHeight = menu.value?.clientHeight || 0;
74
107
 
75
- nextTick(() => {
76
- const menuHeight = menu.value?.clientHeight || 0;
108
+ let top = e.clientY;
109
+ if (menuHeight + e.clientY > document.body.clientHeight) {
110
+ top = document.body.clientHeight - menuHeight;
111
+ }
77
112
 
78
- let top = e.clientY;
79
- if (menuHeight + e.clientY > document.body.clientHeight) {
80
- top = document.body.clientHeight - menuHeight;
81
- }
113
+ menuStyle.value = {
114
+ top: `${top}px`,
115
+ left: `${e.clientX}px`,
116
+ };
82
117
 
83
- menuStyle.value = {
84
- top: `${top}px`,
85
- left: `${e.clientX}px`,
86
- };
87
- });
118
+ emit('show');
119
+ });
120
+ }, 300);
88
121
  },
89
122
 
90
123
  showSubMenu(item: MenuItem) {
@@ -22,6 +22,8 @@ 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', []);
26
+
25
27
  const createMenuItems = (group: ComponentGroup): MenuButton[] =>
26
28
  group.items.map((component) => ({
27
29
  text: component.text,
@@ -101,6 +103,7 @@ export default defineComponent({
101
103
  node.value && services?.editorService.remove(node.value);
102
104
  },
103
105
  },
106
+ ...layerContentMenu,
104
107
  ]),
105
108
 
106
109
  show(e: MouseEvent) {
@@ -30,7 +30,7 @@ export default defineComponent({
30
30
 
31
31
  props: {
32
32
  data: {
33
- type: Object as PropType<SideItem>,
33
+ type: [Object, String] as PropType<SideItem>,
34
34
  },
35
35
  },
36
36
 
@@ -27,6 +27,8 @@ export default defineComponent({
27
27
  const parent = computed(() => editorService?.get('parent'));
28
28
  const isPage = computed(() => node.value?.type === NodeType.PAGE);
29
29
 
30
+ const stageContentMenu = inject<MenuItem[]>('stageContentMenu', []);
31
+
30
32
  onMounted(() => {
31
33
  const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
32
34
  canPaste.value = data !== 'undefined' && !!data;
@@ -69,8 +71,20 @@ export default defineComponent({
69
71
  text: '粘贴',
70
72
  display: () => canPaste.value,
71
73
  handler: () => {
72
- const top = menu.value?.$el.offsetTop || 0;
73
- const left = menu.value?.$el.offsetLeft || 0;
74
+ const stage = editorService?.get<StageCore>('stage');
75
+
76
+ const rect = menu.value?.$el.getBoundingClientRect();
77
+ const parentRect = stage?.container?.getBoundingClientRect();
78
+ let left = (rect?.left || 0) - (parentRect?.left || 0);
79
+ let top = (rect?.top || 0) - (parentRect?.top || 0);
80
+
81
+ if (node.value?.items && stage) {
82
+ const parentEl = stage.renderer.contentWindow?.document.getElementById(`${node.value.id}`);
83
+ const parentElRect = parentEl?.getBoundingClientRect();
84
+ left = left - (parentElRect?.left || 0);
85
+ top = top - (parentElRect?.top || 0);
86
+ }
87
+
74
88
  editorService?.paste({ left, top });
75
89
  },
76
90
  },
@@ -138,6 +152,7 @@ export default defineComponent({
138
152
  editorService?.get<StageCore>('stage').clearGuides();
139
153
  },
140
154
  },
155
+ ...stageContentMenu,
141
156
  ]),
142
157
 
143
158
  show(e: MouseEvent) {
@@ -82,10 +82,6 @@ export default defineComponent({
82
82
  const ctrl = isMac ? 'meta' : 'ctrl';
83
83
 
84
84
  keycon
85
- .keydown((e) => {
86
- console.log(e);
87
- e.inputEvent.preventDefault();
88
- })
89
85
  .keyup('delete', (e) => {
90
86
  e.inputEvent.preventDefault();
91
87
  if (!node.value || isPage(node.value)) return;
@@ -96,63 +92,82 @@ export default defineComponent({
96
92
  if (!node.value || isPage(node.value)) return;
97
93
  services?.editorService.remove(node.value);
98
94
  })
99
- .keydown([ctrl, 'c'], () => {
95
+ .keydown([ctrl, 'c'], (e) => {
96
+ e.inputEvent.preventDefault();
100
97
  node.value && services?.editorService.copy(node.value);
101
98
  })
102
- .keydown([ctrl, 'v'], () => {
99
+ .keydown([ctrl, 'v'], (e) => {
100
+ e.inputEvent.preventDefault();
103
101
  node.value && services?.editorService.paste();
104
102
  })
105
- .keydown([ctrl, 'x'], () => {
103
+ .keydown([ctrl, 'x'], (e) => {
104
+ e.inputEvent.preventDefault();
106
105
  if (!node.value || isPage(node.value)) return;
107
106
  services?.editorService.copy(node.value);
108
107
  services?.editorService.remove(node.value);
109
108
  })
110
- .keydown([ctrl, 'z'], () => {
109
+ .keydown([ctrl, 'z'], (e) => {
110
+ e.inputEvent.preventDefault();
111
111
  services?.editorService.undo();
112
112
  })
113
- .keydown([ctrl, 'shift', 'z'], () => {
113
+ .keydown([ctrl, 'shift', 'z'], (e) => {
114
+ e.inputEvent.preventDefault();
114
115
  services?.editorService.redo();
115
116
  })
116
- .keydown('up', () => {
117
+ .keydown('up', (e) => {
118
+ e.inputEvent.preventDefault();
117
119
  services?.editorService.move(0, -1);
118
120
  })
119
- .keydown('down', () => {
121
+ .keydown('down', (e) => {
122
+ e.inputEvent.preventDefault();
120
123
  services?.editorService.move(0, 1);
121
124
  })
122
- .keydown('left', () => {
125
+ .keydown('left', (e) => {
126
+ e.inputEvent.preventDefault();
123
127
  services?.editorService.move(-1, 0);
124
128
  })
125
- .keydown('right', () => {
129
+ .keydown('right', (e) => {
130
+ e.inputEvent.preventDefault();
126
131
  services?.editorService.move(1, 0);
127
132
  })
128
- .keydown([ctrl, 'up'], () => {
133
+ .keydown([ctrl, 'up'], (e) => {
134
+ e.inputEvent.preventDefault();
129
135
  services?.editorService.move(0, -10);
130
136
  })
131
- .keydown([ctrl, 'down'], () => {
137
+ .keydown([ctrl, 'down'], (e) => {
138
+ e.inputEvent.preventDefault();
132
139
  services?.editorService.move(0, 10);
133
140
  })
134
- .keydown([ctrl, 'left'], () => {
141
+ .keydown([ctrl, 'left'], (e) => {
142
+ e.inputEvent.preventDefault();
135
143
  services?.editorService.move(-10, 0);
136
144
  })
137
- .keydown([ctrl, 'right'], () => {
145
+ .keydown([ctrl, 'right'], (e) => {
146
+ e.inputEvent.preventDefault();
138
147
  services?.editorService.move(10, 0);
139
148
  })
140
- .keydown('tab', () => {
149
+ .keydown('tab', (e) => {
150
+ e.inputEvent.preventDefault();
141
151
  services?.editorService.selectNextNode();
142
152
  })
143
- .keydown([ctrl, 'tab'], () => {
153
+ .keydown([ctrl, 'tab'], (e) => {
154
+ e.inputEvent.preventDefault();
144
155
  services?.editorService.selectNextPage();
145
156
  })
146
- .keydown([ctrl, '='], () => {
157
+ .keydown([ctrl, '='], (e) => {
158
+ e.inputEvent.preventDefault();
147
159
  services?.uiService.zoom(0.1);
148
160
  })
149
- .keydown([ctrl, 'numpadplus'], () => {
161
+ .keydown([ctrl, 'numpadplus'], (e) => {
162
+ e.inputEvent.preventDefault();
150
163
  services?.uiService.zoom(0.1);
151
164
  })
152
- .keydown([ctrl, '-'], () => {
165
+ .keydown([ctrl, '-'], (e) => {
166
+ e.inputEvent.preventDefault();
153
167
  services?.uiService.zoom(-0.1);
154
168
  })
155
- .keydown([ctrl, 'numpad-'], () => {
169
+ .keydown([ctrl, 'numpad-'], (e) => {
170
+ e.inputEvent.preventDefault();
156
171
  services?.uiService.zoom(-0.1);
157
172
  });
158
173
  });
@@ -91,7 +91,7 @@ const doAction = async (
91
91
  * editorService.afterAdd();
92
92
  * }
93
93
  *
94
- * 调用时的参数会透传到before方法的参数中, 然后before的return 会作为原方法的参数和after的参数,after最后一个参数则是原方法的return值;
94
+ * 调用时的参数会透传到before方法的参数中, 然后before的return 会作为原方法的参数和after的参数,after第一个参数则是原方法的return值;
95
95
  * 如需终止后续方法调用可以return new Error();
96
96
  *
97
97
  * 方法2:
@@ -33,6 +33,7 @@ import {
33
33
  change2Fixed,
34
34
  COPY_STORAGE_KEY,
35
35
  Fixed2Other,
36
+ generatePageNameByApp,
36
37
  getNodeIndex,
37
38
  initPosition,
38
39
  isFixed,
@@ -194,6 +195,20 @@ class Editor extends BaseService {
194
195
  historyService.empty();
195
196
  }
196
197
 
198
+ if (node?.id) {
199
+ this.get<StageCore>('stage')
200
+ ?.renderer.runtime?.getApp?.()
201
+ ?.emit(
202
+ 'editor:select',
203
+ {
204
+ node,
205
+ page,
206
+ parent,
207
+ },
208
+ getNodePath(node.id, this.get<MApp>('root').items),
209
+ );
210
+ }
211
+
197
212
  this.emit('select', node);
198
213
 
199
214
  return node!;
@@ -488,6 +503,10 @@ class Editor extends BaseService {
488
503
  };
489
504
  }
490
505
 
506
+ if (isPage(config)) {
507
+ config.name = generatePageNameByApp(this.get('root'));
508
+ }
509
+
491
510
  return await this.add(config);
492
511
  }
493
512
 
@@ -504,7 +523,18 @@ class Editor extends BaseService {
504
523
  return;
505
524
  }
506
525
 
507
- if (parent.style?.width && node.style?.width) {
526
+ if (!node.style) return;
527
+
528
+ const stage = this.get<StageCore>('stage');
529
+ const doc = stage?.renderer.contentWindow?.document;
530
+
531
+ if (doc) {
532
+ const parentEl = doc.getElementById(`${parent.id}`);
533
+ const el = doc.getElementById(`${node.id}`);
534
+ if (parentEl && el) {
535
+ node.style.left = (parentEl.clientWidth - el.clientWidth) / 2;
536
+ }
537
+ } else if (parent.style && isNumber(parent.style?.width) && isNumber(node.style?.width)) {
508
538
  node.style.left = (parent.style.width - node.style.width) / 2;
509
539
  }
510
540
 
@@ -526,9 +556,9 @@ class Editor extends BaseService {
526
556
  const brothers: MNode[] = parent?.items || [];
527
557
  const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
528
558
 
529
- if (offset === LayerOffset.BOTTOM) {
559
+ if (offset === LayerOffset.TOP) {
530
560
  brothers.splice(brothers.length - 1, 0, brothers.splice(index, 1)[0]);
531
- } else if (offset === LayerOffset.TOP) {
561
+ } else if (offset === LayerOffset.BOTTOM) {
532
562
  brothers.splice(0, 0, brothers.splice(index, 1)[0]);
533
563
  } else {
534
564
  brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
@@ -98,10 +98,10 @@ class Props extends BaseService {
98
98
  return value;
99
99
  }
100
100
 
101
- return cloneDeep({
101
+ return {
102
102
  ...getDefaultPropsValue(type),
103
- ...mergeWith(this.state.propsValueMap[type] || {}, defaultValue),
104
- });
103
+ ...mergeWith(cloneDeep(this.state.propsValueMap[type] || {}), cloneDeep(defaultValue)),
104
+ };
105
105
  }
106
106
  }
107
107
 
@@ -142,9 +142,13 @@ export const toRelative = (node: MNode) => {
142
142
 
143
143
  const setTop2Middle = (node: MNode, parentNode: MNode, stage: StageCore) => {
144
144
  const style = node.style || {};
145
- const height = style.height || 0;
145
+ let height = style.height || 0;
146
146
 
147
- if (!stage || typeof style.top !== 'undefined' || !parentNode.style || !isNumber(height)) return style;
147
+ if (!stage || typeof style.top !== 'undefined' || !parentNode.style) return style;
148
+
149
+ if (!isNumber(height)) {
150
+ height = 0;
151
+ }
148
152
 
149
153
  const { height: parentHeight } = parentNode.style;
150
154