@tmagic/editor 1.0.0-rc.5 → 1.0.0-rc.8

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 (85) hide show
  1. package/dist/style.css +3 -0
  2. package/dist/tmagic-editor.es.js +160 -118
  3. package/dist/tmagic-editor.es.js.map +1 -1
  4. package/dist/tmagic-editor.umd.js +160 -120
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/dist/types/src/Editor.vue.d.ts +36 -2
  7. package/dist/types/src/fields/Code.vue.d.ts +4 -4
  8. package/dist/types/src/fields/CodeLink.vue.d.ts +1 -3
  9. package/dist/types/src/layouts/PropsPanel.vue.d.ts +2 -4
  10. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +3 -31
  11. package/dist/types/src/services/history.d.ts +1 -18
  12. package/dist/types/src/services/props.d.ts +8 -2
  13. package/dist/types/src/type.d.ts +9 -0
  14. package/dist/types/src/utils/editor.d.ts +0 -6
  15. package/dist/types/src/utils/props.d.ts +8 -1
  16. package/package.json +11 -20
  17. package/src/Editor.vue +35 -9
  18. package/src/components/ContentMenu.vue +58 -25
  19. package/src/layouts/sidebar/LayerMenu.vue +3 -0
  20. package/src/layouts/workspace/Stage.vue +11 -31
  21. package/src/layouts/workspace/ViewerMenu.vue +3 -0
  22. package/src/layouts/workspace/Workspace.vue +2 -28
  23. package/src/services/editor.ts +3 -4
  24. package/src/services/props.ts +64 -9
  25. package/src/theme/workspace.scss +4 -0
  26. package/src/type.ts +10 -0
  27. package/src/utils/editor.ts +1 -50
  28. package/src/utils/props.ts +30 -7
  29. package/LICENSE +0 -5432
  30. package/coverage/clover.xml +0 -1593
  31. package/coverage/coverage-final.json +0 -36
  32. package/coverage/lcov-report/base.css +0 -224
  33. package/coverage/lcov-report/block-navigation.js +0 -87
  34. package/coverage/lcov-report/favicon.png +0 -0
  35. package/coverage/lcov-report/index.html +0 -206
  36. package/coverage/lcov-report/prettify.css +0 -1
  37. package/coverage/lcov-report/prettify.js +0 -2
  38. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  39. package/coverage/lcov-report/sorter.js +0 -196
  40. package/coverage/lcov-report/src/Editor.vue.html +0 -814
  41. package/coverage/lcov-report/src/components/ContentMenu.vue.html +0 -406
  42. package/coverage/lcov-report/src/components/Icon.vue.html +0 -172
  43. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +0 -283
  44. package/coverage/lcov-report/src/components/ToolButton.vue.html +0 -772
  45. package/coverage/lcov-report/src/components/index.html +0 -161
  46. package/coverage/lcov-report/src/index.html +0 -131
  47. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +0 -214
  48. package/coverage/lcov-report/src/layouts/Framework.vue.html +0 -343
  49. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +0 -208
  50. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +0 -319
  51. package/coverage/lcov-report/src/layouts/Resizer.vue.html +0 -268
  52. package/coverage/lcov-report/src/layouts/index.html +0 -176
  53. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +0 -358
  54. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +0 -421
  55. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +0 -775
  56. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +0 -226
  57. package/coverage/lcov-report/src/layouts/sidebar/TabPane.vue.html +0 -289
  58. package/coverage/lcov-report/src/layouts/sidebar/index.html +0 -176
  59. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +0 -718
  60. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +0 -766
  61. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +0 -568
  62. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +0 -649
  63. package/coverage/lcov-report/src/layouts/workspace/index.html +0 -161
  64. package/coverage/lcov-report/src/services/BaseService.ts.html +0 -643
  65. package/coverage/lcov-report/src/services/componentList.ts.html +0 -229
  66. package/coverage/lcov-report/src/services/editor.ts.html +0 -2167
  67. package/coverage/lcov-report/src/services/events.ts.html +0 -331
  68. package/coverage/lcov-report/src/services/history.ts.html +0 -478
  69. package/coverage/lcov-report/src/services/index.html +0 -206
  70. package/coverage/lcov-report/src/services/props.ts.html +0 -415
  71. package/coverage/lcov-report/src/services/ui.ts.html +0 -580
  72. package/coverage/lcov-report/src/type.ts.html +0 -850
  73. package/coverage/lcov-report/src/utils/compose.ts.html +0 -184
  74. package/coverage/lcov-report/src/utils/config.ts.html +0 -172
  75. package/coverage/lcov-report/src/utils/editor.ts.html +0 -838
  76. package/coverage/lcov-report/src/utils/index.html +0 -221
  77. package/coverage/lcov-report/src/utils/index.ts.html +0 -151
  78. package/coverage/lcov-report/src/utils/logger.ts.html +0 -226
  79. package/coverage/lcov-report/src/utils/props.ts.html +0 -796
  80. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +0 -733
  81. package/coverage/lcov-report/src/utils/undo-redo.ts.html +0 -313
  82. package/coverage/lcov.info +0 -3846
  83. package/dist/types/src/components/ToolButton.vue.d.ts +0 -46
  84. package/dist/types/src/fields/UISelect.vue.d.ts +0 -35
  85. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +0 -18
@@ -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>;
@@ -54,6 +62,9 @@ declare const _default: DefineComponent<{
54
62
  /** 画布中组件选中框的移动范围 */
55
63
  moveableOptions: {
56
64
  type: PropType<MoveableOptions | ((core?: StageCore | undefined) => MoveableOptions)>;
65
+ default: () => (core?: StageCore | undefined) => {
66
+ container: HTMLElement | null | undefined;
67
+ };
57
68
  };
58
69
  /** 编辑器初始化时默认选中的组件ID */
59
70
  defaultSelected: {
@@ -61,6 +72,7 @@ declare const _default: DefineComponent<{
61
72
  };
62
73
  canSelect: {
63
74
  type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
75
+ default: (el: HTMLElement) => boolean;
64
76
  };
65
77
  stageRect: {
66
78
  type: PropType<StageRect>;
@@ -69,6 +81,9 @@ declare const _default: DefineComponent<{
69
81
  type: ObjectConstructor;
70
82
  default: () => {};
71
83
  };
84
+ updateDragEl: {
85
+ type: PropType<(el: HTMLDivElement, target: HTMLElement) => void>;
86
+ };
72
87
  }, Services, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ("props-panel-mounted" | "update:modelValue")[], "props-panel-mounted" | "update:modelValue", VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{
73
88
  /** 页面初始值 */
74
89
  modelValue: {
@@ -85,6 +100,14 @@ declare const _default: DefineComponent<{
85
100
  sidebar: {
86
101
  type: PropType<SideBarData>;
87
102
  };
103
+ layerContentMenu: {
104
+ type: PropType<MenuItem[]>;
105
+ default: () => never[];
106
+ };
107
+ stageContentMenu: {
108
+ type: PropType<MenuItem[]>;
109
+ default: () => never[];
110
+ };
88
111
  /** 顶部工具栏配置 */
89
112
  menu: {
90
113
  type: PropType<MenuBarData>;
@@ -119,6 +142,9 @@ declare const _default: DefineComponent<{
119
142
  /** 画布中组件选中框的移动范围 */
120
143
  moveableOptions: {
121
144
  type: PropType<MoveableOptions | ((core?: StageCore | undefined) => MoveableOptions)>;
145
+ default: () => (core?: StageCore | undefined) => {
146
+ container: HTMLElement | null | undefined;
147
+ };
122
148
  };
123
149
  /** 编辑器初始化时默认选中的组件ID */
124
150
  defaultSelected: {
@@ -126,6 +152,7 @@ declare const _default: DefineComponent<{
126
152
  };
127
153
  canSelect: {
128
154
  type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
155
+ default: (el: HTMLElement) => boolean;
129
156
  };
130
157
  stageRect: {
131
158
  type: PropType<StageRect>;
@@ -134,17 +161,24 @@ declare const _default: DefineComponent<{
134
161
  type: ObjectConstructor;
135
162
  default: () => {};
136
163
  };
164
+ updateDragEl: {
165
+ type: PropType<(el: HTMLDivElement, target: HTMLElement) => void>;
166
+ };
137
167
  }>> & {
138
168
  "onProps-panel-mounted"?: ((...args: any[]) => any) | undefined;
139
169
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
140
170
  }, {
141
171
  menu: MenuBarData;
142
- autoScrollIntoView: boolean;
172
+ layerContentMenu: MenuItem[];
173
+ stageContentMenu: MenuItem[];
143
174
  codeOptions: Record<string, any>;
144
175
  modelValue: MApp;
145
176
  componentGroupList: ComponentGroup[];
177
+ autoScrollIntoView: boolean;
146
178
  propsConfigs: Record<string, FormConfig>;
147
179
  propsValues: Record<string, MNode>;
148
180
  eventMethodList: Record<string, any>;
181
+ moveableOptions: MoveableOptions | ((core?: StageCore | undefined) => MoveableOptions);
182
+ canSelect: (el: HTMLElement) => boolean | Promise<boolean>;
149
183
  }>;
150
184
  export default _default;
@@ -16,9 +16,9 @@ declare const _default: DefineComponent<Readonly<{
16
16
  }>>> & {
17
17
  onChange?: ((...args: any[]) => any) | undefined;
18
18
  }, {
19
- name: any;
20
- config: any;
21
- model: any;
22
- prop: any;
19
+ readonly name?: any;
20
+ readonly config?: any;
21
+ readonly model?: any;
22
+ readonly prop?: any;
23
23
  }>;
24
24
  export default _default;
@@ -20,9 +20,7 @@ declare const _default: DefineComponent<{
20
20
  };
21
21
  }, {
22
22
  modelValue: Ref<{
23
- form: {
24
- [x: string]: any;
25
- };
23
+ form: Record<string, any>;
26
24
  }>;
27
25
  formConfig: ComputedRef<{
28
26
  text: string;
@@ -1,9 +1,7 @@
1
1
  import type { DefineComponent, Ref, ComputedRef, ComponentOptionsMixin, VNodeProps, AllowedComponentProps, ComponentCustomProps, ExtractPropTypes } from 'vue';
2
+ import type { FormValue } from '@tmagic/form';
2
3
  declare const _default: DefineComponent<{}, {
3
- values: Ref<{
4
- [x: string]: any;
5
- [x: number]: any;
6
- }>;
4
+ values: Ref<FormValue>;
7
5
  configForm: Ref<any>;
8
6
  curFormConfig: any;
9
7
  propsPanelSize: ComputedRef<unknown>;
@@ -1,35 +1,7 @@
1
- import type { DefineComponent, Ref, ComputedRef, ComponentOptionsMixin, VNodeProps, AllowedComponentProps, ComponentCustomProps, ExtractPropTypes, PropType } from 'vue';
1
+ import type { DefineComponent, Ref, ComputedRef, ComponentOptionsMixin, EmitsOptions, VNodeProps, AllowedComponentProps, ComponentCustomProps, ExtractPropTypes } from 'vue';
2
2
  import type { MPage } from '@tmagic/schema';
3
- import type { MoveableOptions } from '@tmagic/stage';
4
- import StageCore from '@tmagic/stage';
5
- declare const _default: DefineComponent<{
6
- runtimeUrl: StringConstructor;
7
- autoScrollIntoView: BooleanConstructor;
8
- render: {
9
- type: PropType<() => HTMLDivElement>;
10
- };
11
- moveableOptions: {
12
- type: PropType<MoveableOptions | ((core?: StageCore | undefined) => MoveableOptions)>;
13
- };
14
- canSelect: {
15
- type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
16
- };
17
- }, {
3
+ declare const _default: DefineComponent<{}, {
18
4
  workspace: Ref<HTMLDivElement | undefined>;
19
5
  page: ComputedRef<MPage | undefined>;
20
- }, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, Record<string, any>, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{
21
- runtimeUrl: StringConstructor;
22
- autoScrollIntoView: BooleanConstructor;
23
- render: {
24
- type: PropType<() => HTMLDivElement>;
25
- };
26
- moveableOptions: {
27
- type: PropType<MoveableOptions | ((core?: StageCore | undefined) => MoveableOptions)>;
28
- };
29
- canSelect: {
30
- type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
31
- };
32
- }>>, {
33
- autoScrollIntoView: boolean;
34
- }>;
6
+ }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{}>>, {}>;
35
7
  export default _default;
@@ -15,24 +15,7 @@ export interface HistoryState {
15
15
  declare class History extends BaseService {
16
16
  state: {
17
17
  pageId?: Id | undefined;
18
- pageSteps: {
19
- [x: string]: {
20
- pushElement: (element: StepValue) => void;
21
- canUndo: () => boolean;
22
- undo: () => StepValue | null;
23
- canRedo: () => boolean;
24
- redo: () => StepValue | null;
25
- getCurrentElement: () => StepValue | null;
26
- };
27
- [x: number]: {
28
- pushElement: (element: StepValue) => void;
29
- canUndo: () => boolean;
30
- undo: () => StepValue | null;
31
- canRedo: () => boolean;
32
- redo: () => StepValue | null;
33
- getCurrentElement: () => StepValue | null;
34
- };
35
- };
18
+ pageSteps: Record<Id, UndoRedo<StepValue>>;
36
19
  canRedo: boolean;
37
20
  canUndo: boolean;
38
21
  };
@@ -1,5 +1,5 @@
1
1
  import type { FormConfig } from '@tmagic/form';
2
- import type { MNode } from '@tmagic/schema';
2
+ import type { MNode, MPage } from '@tmagic/schema';
3
3
  import BaseService from './BaseService';
4
4
  declare class Props extends BaseService {
5
5
  private state;
@@ -29,7 +29,13 @@ declare class Props extends BaseService {
29
29
  * @param type 组件类型
30
30
  * @returns 组件初始值
31
31
  */
32
- getPropsValue(type: string, defaultValue?: {}): Promise<any>;
32
+ getPropsValue(type: string, defaultValue?: Record<string, any>): Promise<any>;
33
+ createId(type: string | number): Promise<string>;
34
+ /**
35
+ * 将组件与组件的子元素配置中的id都设置成一个新的ID
36
+ * @param {Object} config 组件配置
37
+ */
38
+ setNewItemId(config: MNode, parent?: MPage): Promise<void>;
33
39
  }
34
40
  export declare type PropsService = Props;
35
41
  declare const _default: Props;
@@ -2,6 +2,7 @@ import type { Component } from 'vue';
2
2
  import type { FormConfig } from '@tmagic/form';
3
3
  import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
4
4
  import type StageCore from '@tmagic/stage';
5
+ import type { MoveableOptions } from '@tmagic/stage';
5
6
  import type { ComponentListService } from './services/componentList';
6
7
  import type { EditorService } from './services/editor';
7
8
  import type { EventsService } from './services/events';
@@ -21,6 +22,14 @@ export interface Services {
21
22
  componentListService: ComponentListService;
22
23
  uiService: UiService;
23
24
  }
25
+ export interface StageOptions {
26
+ runtimeUrl: string;
27
+ autoScrollIntoView: boolean;
28
+ render: () => HTMLDivElement;
29
+ moveableOptions: MoveableOptions | ((core?: StageCore) => MoveableOptions);
30
+ canSelect: (el: HTMLElement) => boolean | Promise<boolean>;
31
+ updateDragEl: (el: HTMLDivElement) => void;
32
+ }
24
33
  export interface StoreState {
25
34
  root: MApp | null;
26
35
  page: MPage | null;
@@ -2,7 +2,6 @@ import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
2
2
  import type StageCore from '@tmagic/stage';
3
3
  import { Layout } from '../type';
4
4
  export declare const COPY_STORAGE_KEY = "$MagicEditorCopyData";
5
- export declare const generateId: (type: string | number) => string;
6
5
  /**
7
6
  * 获取所有页面配置
8
7
  * @param app DSL跟节点
@@ -27,11 +26,6 @@ export declare const generatePageName: (pageNameList: string[]) => string;
27
26
  * @returns {string}
28
27
  */
29
28
  export declare const generatePageNameByApp: (app: MApp) => string;
30
- /**
31
- * 将组件与组件的子元素配置中的id都设置成一个新的ID
32
- * @param {Object} config 组件配置
33
- */
34
- export declare const setNewItemId: (config: MNode, parent?: MPage | undefined) => void;
35
29
  /**
36
30
  * @param {Object} node
37
31
  * @returns {boolean}
@@ -41,9 +41,16 @@ export declare const DEFAULT_CONFIG: FormConfig;
41
41
  * @param type 组件类型
42
42
  * @returns Object
43
43
  */
44
- export declare const getDefaultPropsValue: (type: string) => {
44
+ export declare const getDefaultPropsValue: (type: string, id: string) => {
45
45
  type: string;
46
46
  id: string;
47
47
  style: {};
48
48
  name: string;
49
+ items: never[];
50
+ } | {
51
+ type: string;
52
+ id: string;
53
+ style: {};
54
+ name: string;
55
+ items?: undefined;
49
56
  };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-rc.5",
2
+ "version": "1.0.0-rc.8",
3
3
  "name": "@tmagic/editor",
4
4
  "sideEffects": [
5
5
  "dist/*",
@@ -22,9 +22,7 @@
22
22
  },
23
23
  "license": "Apache-2.0",
24
24
  "scripts": {
25
- "build": "vite build",
26
- "test": "jest --maxWorkers=8",
27
- "test:coverage": "jest --maxWorkers=16 --coverage"
25
+ "build": "vite build"
28
26
  },
29
27
  "engines": {
30
28
  "node": ">=14"
@@ -45,11 +43,11 @@
45
43
  "dependencies": {
46
44
  "@babel/core": "^7.18.0",
47
45
  "@element-plus/icons": "0.0.11",
48
- "@tmagic/core": "^1.0.0-rc.5",
49
- "@tmagic/form": "^1.0.0-rc.5",
50
- "@tmagic/schema": "^1.0.0-rc.5",
51
- "@tmagic/stage": "^1.0.0-rc.5",
52
- "@tmagic/utils": "^1.0.0-rc.5",
46
+ "@tmagic/core": "1.0.0-rc.8",
47
+ "@tmagic/form": "1.0.0-rc.8",
48
+ "@tmagic/schema": "1.0.0-rc.8",
49
+ "@tmagic/stage": "1.0.0-rc.8",
50
+ "@tmagic/utils": "1.0.0-rc.8",
53
51
  "buffer": "^6.0.3",
54
52
  "color": "^3.1.3",
55
53
  "element-plus": "^2.2.0",
@@ -62,31 +60,24 @@
62
60
  "vue": "^3.2.0"
63
61
  },
64
62
  "peerDependencies": {
65
- "@tmagic/form": "^1.0.0-rc.1",
63
+ "@tmagic/form": "1.0.0-rc.8",
66
64
  "element-plus": "^2.2.0",
65
+ "monaco-editor": "^0.32.1",
67
66
  "vue": "^3.2.0"
68
67
  },
69
68
  "devDependencies": {
70
69
  "@types/events": "^3.0.0",
71
- "@types/jest": "^27.5.1",
72
70
  "@types/lodash-es": "^4.17.4",
73
71
  "@types/node": "^15.12.4",
74
72
  "@types/serialize-javascript": "^5.0.1",
75
73
  "@vitejs/plugin-vue": "^1.2.3",
76
74
  "@vitejs/plugin-vue-jsx": "^1.1.6",
77
75
  "@vue/compiler-sfc": "^3.2.0",
78
- "@vue/test-utils": "^2.0.0-rc.20",
79
- "@vue/vue3-jest": "^27.0.0-alpha.4",
80
- "babel-jest": "^27.0.6",
81
- "jest": "^27.5.1",
82
- "jest-serializer-vue": "^2.0.2",
83
- "jest-transform-stub": "^2.0.0",
76
+ "@vue/test-utils": "^2.0.0",
84
77
  "sass": "^1.35.1",
85
- "ts-jest": "^27.1.4",
86
78
  "typescript": "^4.3.4",
87
79
  "vite": "^2.3.7",
88
80
  "vite-plugin-dts": "^0.9.6",
89
81
  "vue-tsc": "^0.0.24"
90
- },
91
- "gitHead": "d147b361d7e6123cda99c6ba68a2ac7e074be37f"
82
+ }
92
83
  }
package/src/Editor.vue CHANGED
@@ -12,13 +12,7 @@
12
12
 
13
13
  <template #workspace :editorService="editorService">
14
14
  <slot name="workspace">
15
- <workspace
16
- :runtime-url="runtimeUrl"
17
- :auto-scroll-into-view="autoScrollIntoView"
18
- :render="render"
19
- :moveable-options="moveableOptions"
20
- :can-select="canSelect"
21
- >
15
+ <workspace>
22
16
  <template #workspace-content><slot name="workspace-content" :editorService="editorService"></slot></template>
23
17
  <template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
24
18
  <template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
@@ -37,7 +31,7 @@
37
31
  </template>
38
32
 
39
33
  <script lang="ts">
40
- import { defineComponent, onUnmounted, PropType, provide, toRaw, watch } from 'vue';
34
+ import { defineComponent, onUnmounted, PropType, provide, reactive, toRaw, watch } from 'vue';
41
35
 
42
36
  import { EventOption } from '@tmagic/core';
43
37
  import type { FormConfig } from '@tmagic/form';
@@ -56,7 +50,7 @@ import eventsService from '@editor/services/events';
56
50
  import historyService from '@editor/services/history';
57
51
  import propsService from '@editor/services/props';
58
52
  import uiService from '@editor/services/ui';
59
- import type { ComponentGroup, MenuBarData, Services, SideBarData, StageRect } from '@editor/type';
53
+ import type { ComponentGroup, MenuBarData, MenuItem, Services, SideBarData, StageRect } from '@editor/type';
60
54
 
61
55
  export default defineComponent({
62
56
  name: 'm-editor',
@@ -88,6 +82,16 @@ export default defineComponent({
88
82
  type: Object as PropType<SideBarData>,
89
83
  },
90
84
 
85
+ layerContentMenu: {
86
+ type: Array as PropType<MenuItem[]>,
87
+ default: () => [],
88
+ },
89
+
90
+ stageContentMenu: {
91
+ type: Array as PropType<MenuItem[]>,
92
+ default: () => [],
93
+ },
94
+
91
95
  /** 顶部工具栏配置 */
92
96
  menu: {
93
97
  type: Object as PropType<MenuBarData>,
@@ -126,6 +130,9 @@ export default defineComponent({
126
130
  /** 画布中组件选中框的移动范围 */
127
131
  moveableOptions: {
128
132
  type: [Object, Function] as PropType<MoveableOptions | ((core?: StageCore) => MoveableOptions)>,
133
+ default: () => (core?: StageCore) => ({
134
+ container: core?.renderer?.contentWindow?.document.getElementById('app'),
135
+ }),
129
136
  },
130
137
 
131
138
  /** 编辑器初始化时默认选中的组件ID */
@@ -135,6 +142,7 @@ export default defineComponent({
135
142
 
136
143
  canSelect: {
137
144
  type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
145
+ default: (el: HTMLElement) => Boolean(el.id),
138
146
  },
139
147
 
140
148
  stageRect: {
@@ -145,6 +153,10 @@ export default defineComponent({
145
153
  type: Object,
146
154
  default: () => ({}),
147
155
  },
156
+
157
+ updateDragEl: {
158
+ type: Function as PropType<(el: HTMLDivElement, target: HTMLElement) => void>,
159
+ },
148
160
  },
149
161
 
150
162
  emits: ['props-panel-mounted', 'update:modelValue'],
@@ -237,6 +249,20 @@ export default defineComponent({
237
249
 
238
250
  provide('services', services);
239
251
 
252
+ provide('layerContentMenu', props.layerContentMenu);
253
+ provide('stageContentMenu', props.stageContentMenu);
254
+ provide(
255
+ 'stageOptions',
256
+ reactive({
257
+ runtimeUrl: props.runtimeUrl,
258
+ autoScrollIntoView: props.autoScrollIntoView,
259
+ render: props.render,
260
+ moveableOptions: props.moveableOptions,
261
+ canSelect: props.canSelect,
262
+ updateDragEl: props.updateDragEl,
263
+ }),
264
+ );
265
+
240
266
  return services;
241
267
  },
242
268
  });
@@ -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
- 'mouseup',
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 + 2}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) {