@tmagic/editor 1.0.0-beta.12 → 1.0.0-beta.15

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 (102) hide show
  1. package/coverage/clover.xml +1540 -0
  2. package/coverage/coverage-final.json +35 -0
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +206 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +196 -0
  11. package/coverage/lcov-report/src/Editor.vue.html +787 -0
  12. package/coverage/lcov-report/src/components/ContentMenu.vue.html +406 -0
  13. package/coverage/lcov-report/src/components/Icon.vue.html +172 -0
  14. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +283 -0
  15. package/coverage/lcov-report/src/components/ToolButton.vue.html +772 -0
  16. package/coverage/lcov-report/src/components/index.html +161 -0
  17. package/coverage/lcov-report/src/index.html +131 -0
  18. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +214 -0
  19. package/coverage/lcov-report/src/layouts/Framework.vue.html +304 -0
  20. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
  21. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +316 -0
  22. package/coverage/lcov-report/src/layouts/Resizer.vue.html +268 -0
  23. package/coverage/lcov-report/src/layouts/index.html +176 -0
  24. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +358 -0
  25. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +421 -0
  26. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +775 -0
  27. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +343 -0
  28. package/coverage/lcov-report/src/layouts/sidebar/index.html +161 -0
  29. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
  30. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +757 -0
  31. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
  32. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +586 -0
  33. package/coverage/lcov-report/src/layouts/workspace/index.html +161 -0
  34. package/coverage/lcov-report/src/services/BaseService.ts.html +643 -0
  35. package/coverage/lcov-report/src/services/componentList.ts.html +229 -0
  36. package/coverage/lcov-report/src/services/editor.ts.html +2077 -0
  37. package/coverage/lcov-report/src/services/events.ts.html +331 -0
  38. package/coverage/lcov-report/src/services/history.ts.html +478 -0
  39. package/coverage/lcov-report/src/services/index.html +206 -0
  40. package/coverage/lcov-report/src/services/props.ts.html +415 -0
  41. package/coverage/lcov-report/src/services/ui.ts.html +514 -0
  42. package/coverage/lcov-report/src/type.ts.html +844 -0
  43. package/coverage/lcov-report/src/utils/compose.ts.html +184 -0
  44. package/coverage/lcov-report/src/utils/config.ts.html +172 -0
  45. package/coverage/lcov-report/src/utils/editor.ts.html +838 -0
  46. package/coverage/lcov-report/src/utils/index.html +221 -0
  47. package/coverage/lcov-report/src/utils/index.ts.html +151 -0
  48. package/coverage/lcov-report/src/utils/logger.ts.html +226 -0
  49. package/coverage/lcov-report/src/utils/props.ts.html +796 -0
  50. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +733 -0
  51. package/coverage/lcov-report/src/utils/undo-redo.ts.html +313 -0
  52. package/coverage/lcov-report/undo-redo.ts.html +313 -0
  53. package/coverage/lcov.info +3676 -0
  54. package/dist/style.css +47 -22
  55. package/dist/tmagic-editor.es.js +921 -603
  56. package/dist/tmagic-editor.es.js.map +1 -1
  57. package/dist/tmagic-editor.umd.js +920 -602
  58. package/dist/tmagic-editor.umd.js.map +1 -1
  59. package/dist/types/src/Editor.vue.d.ts +1 -1
  60. package/dist/types/src/components/ToolButton.vue.d.ts +12 -1
  61. package/dist/types/src/index.d.ts +1 -0
  62. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -0
  63. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +2 -0
  64. package/dist/types/src/services/editor.d.ts +5 -2
  65. package/dist/types/src/services/history.d.ts +1 -0
  66. package/dist/types/src/services/props.d.ts +2 -2
  67. package/dist/types/src/services/ui.d.ts +1 -0
  68. package/dist/types/src/type.d.ts +6 -8
  69. package/dist/types/src/utils/editor.d.ts +2 -2
  70. package/dist/types/src/utils/polyfills.d.ts +0 -0
  71. package/package.json +26 -12
  72. package/src/components/ContentMenu.vue +107 -0
  73. package/src/components/ScrollViewer.vue +1 -1
  74. package/src/components/ToolButton.vue +69 -30
  75. package/src/index.ts +2 -0
  76. package/src/layouts/Framework.vue +6 -6
  77. package/src/layouts/sidebar/ComponentListPanel.vue +23 -1
  78. package/src/layouts/sidebar/LayerMenu.vue +91 -72
  79. package/src/layouts/sidebar/LayerPanel.vue +23 -49
  80. package/src/layouts/workspace/PageBar.vue +35 -6
  81. package/src/layouts/workspace/Stage.vue +41 -44
  82. package/src/layouts/workspace/ViewerMenu.vue +104 -67
  83. package/src/layouts/workspace/Workspace.vue +74 -16
  84. package/src/services/BaseService.ts +1 -1
  85. package/src/services/editor.ts +97 -10
  86. package/src/services/history.ts +7 -0
  87. package/src/services/props.ts +2 -3
  88. package/src/services/ui.ts +5 -0
  89. package/src/theme/common/var.scss +1 -0
  90. package/src/theme/component-list-panel.scss +2 -0
  91. package/src/theme/content-menu.scss +33 -26
  92. package/src/theme/layer-panel.scss +2 -1
  93. package/src/theme/nav-menu.scss +6 -2
  94. package/src/theme/page-bar.scss +22 -1
  95. package/src/type.ts +6 -8
  96. package/src/utils/editor.ts +7 -3
  97. package/{vite.config.ts → src/utils/polyfills.ts} +4 -12
  98. package/src/utils/props.ts +19 -0
  99. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -980
  100. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -188
  101. package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
  102. package/tsconfig.json +0 -9
@@ -126,9 +126,9 @@ declare const _default: DefineComponent<{
126
126
  "onProps-panel-mounted"?: ((...args: any[]) => any) | undefined;
127
127
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
128
128
  }, {
129
- componentGroupList: ComponentGroup[];
130
129
  menu: MenuBarData;
131
130
  modelValue: MApp;
131
+ componentGroupList: ComponentGroup[];
132
132
  propsConfigs: Record<string, FormConfig>;
133
133
  propsValues: Record<string, MNode>;
134
134
  eventMethodList: Record<string, any>;
@@ -9,6 +9,10 @@ declare const _default: DefineComponent<{
9
9
  display: boolean;
10
10
  };
11
11
  };
12
+ eventType: {
13
+ type: PropType<"mousedown" | "mouseup" | "click">;
14
+ default: string;
15
+ };
12
16
  }, {
13
17
  ZoomIn: DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<{}>, {}>;
14
18
  ZoomOut: DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<{}>, {}>;
@@ -19,7 +23,9 @@ declare const _default: DefineComponent<{
19
23
  zoomInHandler: () => void | undefined;
20
24
  zoomOutHandler: () => void | undefined;
21
25
  dropdownHandler(command: any): void;
22
- buttonHandler(item: MenuButton | MenuComponent): void;
26
+ clickHandler(item: MenuButton | MenuComponent, event: MouseEvent): void;
27
+ mousedownHandler(item: MenuButton | MenuComponent, event: MouseEvent): void;
28
+ mouseupHandler(item: MenuButton | MenuComponent, event: MouseEvent): void;
23
29
  }, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, Record<string, any>, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{
24
30
  data: {
25
31
  type: PropType<string | MenuButton | MenuComponent>;
@@ -29,7 +35,12 @@ declare const _default: DefineComponent<{
29
35
  display: boolean;
30
36
  };
31
37
  };
38
+ eventType: {
39
+ type: PropType<"mousedown" | "mouseup" | "click">;
40
+ default: string;
41
+ };
32
42
  }>>, {
33
43
  data: string | MenuButton | MenuComponent;
44
+ eventType: "mousedown" | "mouseup" | "click";
34
45
  }>;
35
46
  export default _default;
@@ -13,6 +13,7 @@ export { default as uiService } from './services/ui';
13
13
  export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPanel.vue';
14
14
  export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
15
15
  export { default as PropsPanel } from './layouts/PropsPanel.vue';
16
+ export { default as ToolButton } from './components/ToolButton.vue';
16
17
  declare const _default: {
17
18
  install: (app: App, opt?: InstallOptions | undefined) => void;
18
19
  };
@@ -8,5 +8,6 @@ declare const _default: DefineComponent<{}, {
8
8
  title: string;
9
9
  }[] | undefined>;
10
10
  appendComponent({ text, type, data }: ComponentItem): void;
11
+ dragstartHandler({ text, type, data }: ComponentItem, e: DragEvent): void;
11
12
  }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{}>>, {}>;
12
13
  export default _default;
@@ -12,5 +12,7 @@ declare const _default: DefineComponent<{}, {
12
12
  canScroll: Ref<boolean>;
13
13
  itemsContainerWidth: ComputedRef<number>;
14
14
  scroll: (type: "left" | "right" | "start" | "end") => void;
15
+ Delete: DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<{}>, {}>;
16
+ DocumentCopy: DefineComponent<{}, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<{}>, {}>;
15
17
  }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{}>>, {}>;
16
18
  export default _default;
@@ -41,13 +41,15 @@ declare class Editor extends BaseService {
41
41
  /**
42
42
  * 只有容器拥有布局
43
43
  */
44
- getLayout(node: MNode): Promise<Layout>;
44
+ getLayout(parent: MNode, node?: MNode): Promise<Layout>;
45
45
  /**
46
46
  * 选中指定节点(将指定节点设置成当前选中状态)
47
47
  * @param config 指定节点配置或者ID
48
48
  * @returns 当前选中的节点配置
49
49
  */
50
50
  select(config: MNode | Id): Promise<MNode> | never;
51
+ selectNextNode(): Promise<MNode> | never;
52
+ selectNextPage(): Promise<MNode> | never;
51
53
  /**
52
54
  * 高亮指定节点
53
55
  * @param config 指定节点配置或者ID
@@ -60,7 +62,7 @@ declare class Editor extends BaseService {
60
62
  * @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
61
63
  * @returns 添加后的节点
62
64
  */
63
- add({ type, ...config }: AddMNode, parent?: MContainer | null): Promise<MNode>;
65
+ add(addNode: AddMNode, parent?: MContainer | null): Promise<MNode>;
64
66
  /**
65
67
  * 删除组件
66
68
  * @param {Object} node
@@ -116,6 +118,7 @@ declare class Editor extends BaseService {
116
118
  * @returns 下一步数据
117
119
  */
118
120
  redo(): Promise<StepValue | null>;
121
+ move(left: number, top: number): Promise<void>;
119
122
  destroy(): void;
120
123
  resetModifiedNodeId(): void;
121
124
  private addModifiedNodeId;
@@ -37,6 +37,7 @@ declare class History extends BaseService {
37
37
  canUndo: boolean;
38
38
  };
39
39
  constructor();
40
+ reset(): void;
40
41
  changePage(page: MPage): void;
41
42
  empty(): void;
42
43
  push(state: StepValue): StepValue | null;
@@ -1,5 +1,5 @@
1
1
  import type { FormConfig } from '@tmagic/form';
2
- import type { MComponent, MNode } from '@tmagic/schema';
2
+ import type { MNode } from '@tmagic/schema';
3
3
  import BaseService from './BaseService';
4
4
  declare class Props extends BaseService {
5
5
  private state;
@@ -29,7 +29,7 @@ declare class Props extends BaseService {
29
29
  * @param type 组件类型
30
30
  * @returns 组件初始值
31
31
  */
32
- getPropsValue(type: string, defaultValue?: {}): Promise<MComponent>;
32
+ getPropsValue(type: string, defaultValue?: {}): Promise<any>;
33
33
  }
34
34
  export declare type PropsService = Props;
35
35
  declare const _default: Props;
@@ -24,6 +24,7 @@ declare class Ui extends BaseService {
24
24
  constructor();
25
25
  set<T = any>(name: keyof UiState, value: T): void;
26
26
  get<T>(name: keyof typeof state): T;
27
+ zoom(zoom: number): void;
27
28
  private setColumnWidth;
28
29
  private setStageRect;
29
30
  private calcZoom;
@@ -29,6 +29,7 @@ export interface StoreState {
29
29
  highlightNode: MNode | null;
30
30
  stage: StageCore | null;
31
31
  modifiedNodeIds: Map<Id, Id>;
32
+ pageLength: number;
32
33
  }
33
34
  export interface PropsState {
34
35
  propsConfigMap: Record<string, FormConfig>;
@@ -92,6 +93,8 @@ export interface MenuButton {
92
93
  * zoom: 放大缩小
93
94
  */
94
95
  type: 'button' | 'dropdown' | 'text' | 'divider' | 'zoom';
96
+ /** 当type为divider时有效,分割线方向, 默认vertical */
97
+ direction?: 'horizontal' | 'vertical';
95
98
  /** 展示的文案 */
96
99
  text?: string;
97
100
  /** 鼠标悬浮是显示的气泡中的文案 */
@@ -103,14 +106,9 @@ export interface MenuButton {
103
106
  /** 是否显示,默认为true */
104
107
  display?: boolean | ((data?: Services) => boolean);
105
108
  /** type为button/dropdown时点击运行的方法 */
106
- handler?: (data?: Services) => Promise<any> | any;
107
- /** type为dropdown时,下拉的菜单列表 */
108
- items?: {
109
- /** 展示的文案 */
110
- text: string;
111
- /** 点击运行的方法 */
112
- handler(data: Services): any;
113
- }[];
109
+ handler?: (data: Services, event: MouseEvent) => Promise<any> | any;
110
+ /** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
111
+ items?: MenuButton[];
114
112
  }
115
113
  export interface MenuComponent {
116
114
  type: 'component';
@@ -37,9 +37,9 @@ export declare const setNewItemId: (config: MNode, parent?: MPage | undefined) =
37
37
  * @returns {boolean}
38
38
  */
39
39
  export declare const isFixed: (node: MNode) => boolean;
40
- export declare const getNodeIndex: (node: MNode, parent: MContainer) => number;
40
+ export declare const getNodeIndex: (node: MNode, parent: MContainer | MApp) => number;
41
41
  export declare const toRelative: (node: MNode) => MNode;
42
42
  export declare const initPosition: (node: MNode, layout: Layout, parentNode: MNode, stage: StageCore) => MNode;
43
43
  export declare const setLayout: (node: MNode, layout: Layout) => MNode;
44
44
  export declare const change2Fixed: (node: MNode, root: MApp) => MNode;
45
- export declare const Fixed2Other: (node: MNode, root: MApp, getLayout: (node: MNode) => Promise<Layout>) => Promise<MNode>;
45
+ export declare const Fixed2Other: (node: MNode, root: MApp, getLayout: (parent: MNode, node?: MNode | undefined) => Promise<Layout>) => Promise<MNode>;
File without changes
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
- "version": "1.0.0-beta.12",
2
+ "version": "1.0.0-beta.15",
3
3
  "name": "@tmagic/editor",
4
- "sideEffects": false,
4
+ "sideEffects": [
5
+ "dist/*",
6
+ "src/theme/*"
7
+ ],
5
8
  "main": "dist/tmagic-editor.umd.js",
6
9
  "module": "dist/tmagic-editor.es.js",
7
10
  "style": "dist/style.css",
@@ -14,10 +17,14 @@
14
17
  "./dist/style.css": {
15
18
  "import": "./dist/style.css",
16
19
  "require": "./dist/style.css"
17
- }
20
+ },
21
+ "./*": "./*"
18
22
  },
23
+ "license": "Apache-2.0",
19
24
  "scripts": {
20
- "build": "vite build"
25
+ "build": "vite build",
26
+ "test": "jest --maxWorkers=8",
27
+ "test:coverage": "jest --maxWorkers=16 --coverage"
21
28
  },
22
29
  "engines": {
23
30
  "node": ">=14"
@@ -37,13 +44,14 @@
37
44
  ],
38
45
  "dependencies": {
39
46
  "@element-plus/icons": "0.0.11",
40
- "@tmagic/core": "^1.0.0-beta.12",
41
- "@tmagic/form": "^1.0.0-beta.12",
42
- "@tmagic/schema": "^1.0.0-beta.12",
43
- "@tmagic/stage": "^1.0.0-beta.12",
44
- "@tmagic/utils": "^1.0.0-beta.12",
47
+ "@tmagic/core": "^1.0.0-beta.15",
48
+ "@tmagic/form": "^1.0.0-beta.15",
49
+ "@tmagic/schema": "^1.0.0-beta.15",
50
+ "@tmagic/stage": "^1.0.0-beta.15",
51
+ "@tmagic/utils": "^1.0.0-beta.15",
52
+ "buffer": "^6.0.3",
45
53
  "color": "^3.1.3",
46
- "element-plus": "^2.1.7",
54
+ "element-plus": "^2.2.0",
47
55
  "events": "^3.3.0",
48
56
  "keycon": "^1.1.2",
49
57
  "lodash-es": "^4.17.21",
@@ -53,18 +61,24 @@
53
61
  },
54
62
  "devDependencies": {
55
63
  "@types/events": "^3.0.0",
64
+ "@types/jest": "^26.0.23",
56
65
  "@types/lodash-es": "^4.17.4",
57
66
  "@types/node": "^15.12.4",
58
67
  "@types/serialize-javascript": "^5.0.1",
59
68
  "@vitejs/plugin-vue": "^1.2.3",
60
69
  "@vitejs/plugin-vue-jsx": "^1.1.6",
61
70
  "@vue/compiler-sfc": "^3.2.0",
62
- "@vue/test-utils": "^2.0.0-rc.12",
71
+ "@vue/test-utils": "^2.0.0-rc.20",
72
+ "@vue/vue3-jest": "^27.0.0-alpha.4",
73
+ "jest": "^27.5.1",
74
+ "jest-serializer-vue": "^2.0.2",
75
+ "jest-transform-stub": "^2.0.0",
63
76
  "sass": "^1.35.1",
77
+ "ts-jest": "^27.1.4",
64
78
  "typescript": "^4.3.4",
65
79
  "vite": "^2.3.7",
66
80
  "vite-plugin-dts": "^0.9.6",
67
81
  "vue-tsc": "^0.0.24"
68
82
  },
69
- "gitHead": "ae00dd242d593ac8f57ffcd34e10e99399c7d00b"
83
+ "gitHead": "340e4e3018c8699d6cf49001e0c367996ecea857"
70
84
  }
@@ -0,0 +1,107 @@
1
+ <template>
2
+ <div v-if="menuData.length" v-show="visible" class="magic-editor-content-menu" ref="menu" :style="menuStyle">
3
+ <div>
4
+ <tool-button
5
+ v-for="(item, index) in menuData"
6
+ event-type="mouseup"
7
+ :data="item"
8
+ :key="index"
9
+ @mouseup="hide"
10
+ @mouseenter="showSubMenu(item)"
11
+ ></tool-button>
12
+ </div>
13
+ <teleport to="body">
14
+ <content-menu class="sub-menu" ref="subMenu" :menu-data="subMenuData"></content-menu>
15
+ </teleport>
16
+ </div>
17
+ </template>
18
+
19
+ <script lang="ts">
20
+ import { defineComponent, nextTick, onMounted, PropType, ref } from 'vue';
21
+
22
+ import { MenuButton, MenuItem } from '@editor/type';
23
+
24
+ import ToolButton from './ToolButton.vue';
25
+
26
+ export default defineComponent({
27
+ components: { ToolButton },
28
+
29
+ props: {
30
+ menuData: {
31
+ type: Array as PropType<MenuItem[]>,
32
+ default: () => [],
33
+ },
34
+ },
35
+
36
+ setup() {
37
+ const menu = ref<HTMLDivElement>();
38
+ const subMenu = ref<any>();
39
+ const visible = ref(false);
40
+ const subMenuData = ref<MenuItem[]>([]);
41
+ const menuStyle = ref({
42
+ left: '0',
43
+ top: '0',
44
+ });
45
+
46
+ const hide = () => {
47
+ visible.value = false;
48
+ };
49
+
50
+ 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
+ );
61
+ });
62
+
63
+ return {
64
+ menu,
65
+ subMenu,
66
+ visible,
67
+ menuStyle,
68
+ subMenuData,
69
+
70
+ hide,
71
+
72
+ show(e: MouseEvent) {
73
+ visible.value = true;
74
+
75
+ nextTick(() => {
76
+ const menuHeight = menu.value?.clientHeight || 0;
77
+
78
+ let top = e.clientY;
79
+ if (menuHeight + e.clientY > document.body.clientHeight) {
80
+ top = document.body.clientHeight - menuHeight;
81
+ }
82
+
83
+ menuStyle.value = {
84
+ top: `${top}px`,
85
+ left: `${e.clientX}px`,
86
+ };
87
+ });
88
+ },
89
+
90
+ showSubMenu(item: MenuItem) {
91
+ const menuItem = item as MenuButton;
92
+ if (typeof item !== 'object' || !menuItem.items?.length) {
93
+ return;
94
+ }
95
+
96
+ subMenuData.value = menuItem.items;
97
+ if (menu.value) {
98
+ subMenu.value.show({
99
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
100
+ clientY: menu.value.offsetTop,
101
+ });
102
+ }
103
+ },
104
+ };
105
+ },
106
+ });
107
+ </script>
@@ -55,7 +55,7 @@ export default defineComponent({
55
55
  style: computed(
56
56
  () => `
57
57
  width: ${props.width}px;
58
- height: ${props.height}px;
58
+ height: ${(props.height || 0) - 40}px;
59
59
  position: absolute;
60
60
  margin-top: 30px;
61
61
  `,
@@ -1,24 +1,37 @@
1
1
  <template>
2
- <div v-if="display" class="menu-item">
3
- <el-divider v-if="item.type === 'divider'" direction="vertical"></el-divider>
2
+ <div
3
+ v-if="display"
4
+ class="menu-item"
5
+ :class="item.type"
6
+ @click="clickHandler(item, $event)"
7
+ @mousedown="mousedownHandler(item, $event)"
8
+ @mouseup="mouseupHandler(item, $event)"
9
+ >
10
+ <el-divider v-if="item.type === 'divider'" :direction="item.direction || 'vertical'"></el-divider>
4
11
  <div v-else-if="item.type === 'text'" class="menu-item-text">{{ item.text }}</div>
5
12
 
6
13
  <template v-else-if="item.type === 'zoom'">
7
- <el-button size="small" type="text"><m-icon :icon="ZoomIn" @click="zoomInHandler"></m-icon></el-button>
14
+ <tool-button
15
+ :data="{ type: 'button', icon: ZoomIn, handler: zoomInHandler, tooltip: '放大' }"
16
+ :event-type="eventType"
17
+ ></tool-button>
8
18
  <span class="menu-item-text" style="margin: 0 5px">{{ parseInt(`${zoom * 100}`, 10) }}%</span>
9
- <el-button size="small" type="text"><m-icon :icon="ZoomOut" @click="zoomOutHandler"></m-icon></el-button>
19
+ <tool-button
20
+ :data="{ type: 'button', icon: ZoomOut, handler: zoomOutHandler, tooltip: '缩小' }"
21
+ :event-type="eventType"
22
+ ></tool-button>
10
23
  </template>
11
24
 
12
- <el-tooltip
13
- v-else-if="item.type === 'button'"
14
- effect="dark"
15
- placement="bottom-start"
16
- :content="item.tooltip || item.text"
17
- >
18
- <el-button size="small" type="text" :disabled="disabled" @click="buttonHandler(item)"
19
- ><m-icon :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
25
+ <template v-else-if="item.type === 'button'">
26
+ <el-tooltip v-if="item.tooltip" effect="dark" placement="bottom-start" :content="item.tooltip">
27
+ <el-button size="small" text :disabled="disabled"
28
+ ><m-icon v-if="item.icon" :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
29
+ >
30
+ </el-tooltip>
31
+ <el-button v-else size="small" text :disabled="disabled"
32
+ ><m-icon v-if="item.icon" :icon="item.icon"></m-icon><span>{{ item.text }}</span></el-button
20
33
  >
21
- </el-tooltip>
34
+ </template>
22
35
 
23
36
  <el-dropdown v-else-if="item.type === 'dropdown'" trigger="click" :disabled="disabled" @command="dropdownHandler">
24
37
  <span class="el-dropdown-link menubar-menu-button">
@@ -38,7 +51,7 @@
38
51
  </template>
39
52
 
40
53
  <script lang="ts">
41
- import { computed, defineComponent, inject, PropType } from 'vue';
54
+ import { computed, defineComponent, inject, markRaw, PropType } from 'vue';
42
55
  import { ArrowDown, Back, Delete, Grid, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons';
43
56
 
44
57
  import { NodeType } from '@tmagic/schema';
@@ -58,19 +71,24 @@ export default defineComponent({
58
71
  display: false,
59
72
  }),
60
73
  },
74
+
75
+ eventType: {
76
+ type: String as PropType<'mousedown' | 'mouseup' | 'click'>,
77
+ default: 'click',
78
+ },
61
79
  },
62
80
 
63
81
  setup(props) {
64
82
  const services = inject<Services>('services');
65
83
  const uiService = services?.uiService;
66
84
 
67
- const zoomInHandler = () => uiService?.set('zoom', zoom.value + 0.1);
68
- const zoomOutHandler = () => uiService?.set('zoom', zoom.value - 0.1);
69
-
70
85
  const zoom = computed((): number => uiService?.get<number>('zoom') ?? 1);
71
86
  const showGuides = computed((): boolean => uiService?.get<boolean>('showGuides') ?? true);
72
87
  const showRule = computed((): boolean => uiService?.get<boolean>('showRule') ?? true);
73
88
 
89
+ const zoomInHandler = () => uiService?.zoom(0.1);
90
+ const zoomOutHandler = () => uiService?.zoom(-0.1);
91
+
74
92
  const item = computed((): MenuButton | MenuComponent => {
75
93
  if (typeof props.data !== 'string') {
76
94
  return props.data;
@@ -87,7 +105,7 @@ export default defineComponent({
87
105
  case 'delete':
88
106
  return {
89
107
  type: 'button',
90
- icon: Delete,
108
+ icon: markRaw(Delete),
91
109
  tooltip: '刪除',
92
110
  disabled: () => services?.editorService.get('node')?.type === NodeType.PAGE,
93
111
  handler: () => services?.editorService.remove(services?.editorService.get('node')),
@@ -95,7 +113,7 @@ export default defineComponent({
95
113
  case 'undo':
96
114
  return {
97
115
  type: 'button',
98
- icon: Back,
116
+ icon: markRaw(Back),
99
117
  tooltip: '后退',
100
118
  disabled: () => !services?.historyService.state.canUndo,
101
119
  handler: () => services?.editorService.undo(),
@@ -103,7 +121,7 @@ export default defineComponent({
103
121
  case 'redo':
104
122
  return {
105
123
  type: 'button',
106
- icon: Right,
124
+ icon: markRaw(Right),
107
125
  tooltip: '前进',
108
126
  disabled: () => !services?.historyService.state.canRedo,
109
127
  handler: () => services?.editorService.redo(),
@@ -111,28 +129,28 @@ export default defineComponent({
111
129
  case 'zoom-in':
112
130
  return {
113
131
  type: 'button',
114
- icon: ZoomIn,
132
+ icon: markRaw(ZoomIn),
115
133
  tooltip: '放大',
116
134
  handler: zoomInHandler,
117
135
  };
118
136
  case 'zoom-out':
119
137
  return {
120
138
  type: 'button',
121
- icon: ZoomOut,
139
+ icon: markRaw(ZoomOut),
122
140
  tooltip: '縮小',
123
141
  handler: zoomOutHandler,
124
142
  };
125
143
  case 'rule':
126
144
  return {
127
145
  type: 'button',
128
- icon: ScaleToOriginal,
146
+ icon: markRaw(ScaleToOriginal),
129
147
  tooltip: showRule.value ? '隐藏标尺' : '显示标尺',
130
148
  handler: () => uiService?.set('showRule', !showRule.value),
131
149
  };
132
150
  case 'guides':
133
151
  return {
134
152
  type: 'button',
135
- icon: Grid,
153
+ icon: markRaw(Grid),
136
154
  tooltip: showGuides.value ? '隐藏参考线' : '显示参考线',
137
155
  handler: () => uiService?.set('showGuides', !showGuides.value),
138
156
  };
@@ -153,9 +171,16 @@ export default defineComponent({
153
171
  return item.value.disabled;
154
172
  });
155
173
 
174
+ const buttonHandler = (item: MenuButton | MenuComponent, event: MouseEvent) => {
175
+ if (disabled.value) return;
176
+ if (typeof (item as MenuButton).handler === 'function' && services) {
177
+ (item as MenuButton).handler?.(services, event);
178
+ }
179
+ };
180
+
156
181
  return {
157
- ZoomIn,
158
- ZoomOut,
182
+ ZoomIn: markRaw(ZoomIn),
183
+ ZoomOut: markRaw(ZoomOut),
159
184
 
160
185
  item,
161
186
  zoom,
@@ -178,10 +203,24 @@ export default defineComponent({
178
203
  }
179
204
  },
180
205
 
181
- buttonHandler(item: MenuButton | MenuComponent) {
182
- if (disabled.value) return;
183
- if (typeof (item as MenuButton).handler === 'function') {
184
- (item as MenuButton).handler?.(services);
206
+ clickHandler(item: MenuButton | MenuComponent, event: MouseEvent) {
207
+ if (props.eventType !== 'click') return;
208
+ if (item.type === 'button') {
209
+ buttonHandler(item, event);
210
+ }
211
+ },
212
+
213
+ mousedownHandler(item: MenuButton | MenuComponent, event: MouseEvent) {
214
+ if (props.eventType !== 'mousedown') return;
215
+ if (item.type === 'button') {
216
+ buttonHandler(item, event);
217
+ }
218
+ },
219
+
220
+ mouseupHandler(item: MenuButton | MenuComponent, event: MouseEvent) {
221
+ if (props.eventType !== 'mouseup') return;
222
+ if (item.type === 'button') {
223
+ buttonHandler(item, event);
185
224
  }
186
225
  },
187
226
  };
package/src/index.ts CHANGED
@@ -15,6 +15,7 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
+ import './utils/polyfills';
18
19
 
19
20
  import { App } from 'vue';
20
21
 
@@ -41,6 +42,7 @@ export { default as uiService } from './services/ui';
41
42
  export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPanel.vue';
42
43
  export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
43
44
  export { default as PropsPanel } from './layouts/PropsPanel.vue';
45
+ export { default as ToolButton } from './components/ToolButton.vue';
44
46
 
45
47
  const defaultInstallOpt: InstallOptions = {
46
48
  // @todo, 自定义图片上传方法等编辑器依赖的外部选项
@@ -49,20 +49,20 @@ export default defineComponent({
49
49
  },
50
50
 
51
51
  setup() {
52
- const services = inject<Services>('services');
52
+ const { editorService, uiService } = inject<Services>('services') || {};
53
53
 
54
- const root = computed(() => services?.editorService.get<MApp>('root'));
54
+ const root = computed(() => editorService?.get<MApp>('root'));
55
55
 
56
56
  return {
57
57
  root,
58
- pageLength: computed(() => root.value?.items?.length || 0),
59
- showSrc: computed(() => services?.uiService.get<boolean>('showSrc')),
60
- columnWidth: computed(() => services?.uiService.get<GetColumnWidth>('columnWidth')),
58
+ pageLength: computed(() => editorService?.get<number>('pageLength') || 0),
59
+ showSrc: computed(() => uiService?.get<boolean>('showSrc')),
60
+ columnWidth: computed(() => uiService?.get<GetColumnWidth>('columnWidth')),
61
61
 
62
62
  saveCode(value: string) {
63
63
  try {
64
64
  // eslint-disable-next-line no-eval
65
- services?.editorService.set('root', eval(value));
65
+ editorService?.set('root', eval(value));
66
66
  } catch (e: any) {
67
67
  console.error(e);
68
68
  }