@tmagic/editor 1.0.0-beta.11 → 1.0.0-beta.14

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 (103) hide show
  1. package/README.md +1 -0
  2. package/coverage/clover.xml +1540 -0
  3. package/coverage/coverage-final.json +35 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +206 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +196 -0
  12. package/coverage/lcov-report/src/Editor.vue.html +787 -0
  13. package/coverage/lcov-report/src/components/ContentMenu.vue.html +406 -0
  14. package/coverage/lcov-report/src/components/Icon.vue.html +172 -0
  15. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +283 -0
  16. package/coverage/lcov-report/src/components/ToolButton.vue.html +772 -0
  17. package/coverage/lcov-report/src/components/index.html +161 -0
  18. package/coverage/lcov-report/src/index.html +131 -0
  19. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +214 -0
  20. package/coverage/lcov-report/src/layouts/Framework.vue.html +304 -0
  21. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +208 -0
  22. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +316 -0
  23. package/coverage/lcov-report/src/layouts/Resizer.vue.html +268 -0
  24. package/coverage/lcov-report/src/layouts/index.html +176 -0
  25. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +358 -0
  26. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +421 -0
  27. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +775 -0
  28. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +343 -0
  29. package/coverage/lcov-report/src/layouts/sidebar/index.html +161 -0
  30. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +718 -0
  31. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +757 -0
  32. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +532 -0
  33. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +586 -0
  34. package/coverage/lcov-report/src/layouts/workspace/index.html +161 -0
  35. package/coverage/lcov-report/src/services/BaseService.ts.html +643 -0
  36. package/coverage/lcov-report/src/services/componentList.ts.html +229 -0
  37. package/coverage/lcov-report/src/services/editor.ts.html +2077 -0
  38. package/coverage/lcov-report/src/services/events.ts.html +331 -0
  39. package/coverage/lcov-report/src/services/history.ts.html +478 -0
  40. package/coverage/lcov-report/src/services/index.html +206 -0
  41. package/coverage/lcov-report/src/services/props.ts.html +415 -0
  42. package/coverage/lcov-report/src/services/ui.ts.html +514 -0
  43. package/coverage/lcov-report/src/type.ts.html +844 -0
  44. package/coverage/lcov-report/src/utils/compose.ts.html +184 -0
  45. package/coverage/lcov-report/src/utils/config.ts.html +172 -0
  46. package/coverage/lcov-report/src/utils/editor.ts.html +838 -0
  47. package/coverage/lcov-report/src/utils/index.html +221 -0
  48. package/coverage/lcov-report/src/utils/index.ts.html +151 -0
  49. package/coverage/lcov-report/src/utils/logger.ts.html +226 -0
  50. package/coverage/lcov-report/src/utils/props.ts.html +796 -0
  51. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +733 -0
  52. package/coverage/lcov-report/src/utils/undo-redo.ts.html +313 -0
  53. package/coverage/lcov.info +3676 -0
  54. package/dist/style.css +42 -20
  55. package/dist/tmagic-editor.es.js +972 -599
  56. package/dist/tmagic-editor.es.js.map +1 -1
  57. package/dist/tmagic-editor.umd.js +974 -601
  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 +2 -1
  63. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +2 -0
  64. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +2 -1
  65. package/dist/types/src/services/editor.d.ts +5 -2
  66. package/dist/types/src/services/history.d.ts +1 -0
  67. package/dist/types/src/services/props.d.ts +2 -2
  68. package/dist/types/src/services/ui.d.ts +1 -0
  69. package/dist/types/src/type.d.ts +9 -9
  70. package/dist/types/src/utils/editor.d.ts +4 -3
  71. package/dist/types/src/utils/polyfills.d.ts +0 -0
  72. package/package.json +29 -9
  73. package/src/components/ContentMenu.vue +107 -0
  74. package/src/components/ScrollViewer.vue +1 -1
  75. package/src/components/ToolButton.vue +69 -30
  76. package/src/index.ts +2 -0
  77. package/src/layouts/Framework.vue +6 -6
  78. package/src/layouts/PropsPanel.vue +1 -1
  79. package/src/layouts/sidebar/ComponentListPanel.vue +25 -3
  80. package/src/layouts/sidebar/LayerMenu.vue +91 -71
  81. package/src/layouts/sidebar/LayerPanel.vue +23 -49
  82. package/src/layouts/workspace/PageBar.vue +35 -6
  83. package/src/layouts/workspace/Stage.vue +41 -44
  84. package/src/layouts/workspace/ViewerMenu.vue +104 -67
  85. package/src/layouts/workspace/Workspace.vue +106 -3
  86. package/src/services/BaseService.ts +1 -1
  87. package/src/services/editor.ts +104 -12
  88. package/src/services/history.ts +7 -0
  89. package/src/services/props.ts +3 -3
  90. package/src/services/ui.ts +5 -0
  91. package/src/theme/common/var.scss +1 -0
  92. package/src/theme/component-list-panel.scss +2 -0
  93. package/src/theme/content-menu.scss +33 -26
  94. package/src/theme/layer-panel.scss +2 -1
  95. package/src/theme/page-bar.scss +22 -1
  96. package/src/type.ts +9 -9
  97. package/src/utils/editor.ts +31 -6
  98. package/{vite.config.ts → src/utils/polyfills.ts} +4 -12
  99. package/src/utils/props.ts +20 -1
  100. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -980
  101. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -188
  102. package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
  103. package/tsconfig.json +0 -9
@@ -1,14 +1,14 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('monaco-editor'), require('@element-plus/icons'), require('@tmagic/schema'), require('lodash-es'), require('@tmagic/utils'), require('events'), require('@tmagic/core'), require('element-plus'), require('@tmagic/stage')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', 'monaco-editor', '@element-plus/icons', '@tmagic/schema', 'lodash-es', '@tmagic/utils', 'events', '@tmagic/core', 'element-plus', '@tmagic/stage'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.vue, global.serialize, global.monaco, global.icons, global.schema, global.lodashEs, global.utils, global.events, global.core, global.elementPlus, global.StageCore));
5
- })(this, (function (exports, vue, serialize, monaco, icons, schema, lodashEs, utils, events, core, elementPlus, StageCore) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('monaco-editor'), require('@element-plus/icons'), require('@tmagic/schema'), require('lodash-es'), require('@tmagic/utils'), require('events'), require('@tmagic/core'), require('element-plus'), require('keycon'), require('@tmagic/stage')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', 'monaco-editor', '@element-plus/icons', '@tmagic/schema', 'lodash-es', '@tmagic/utils', 'events', '@tmagic/core', 'element-plus', 'keycon', '@tmagic/stage'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.vue, global.serialize, global.monaco, global.icons, global.schema, global.lodashEs, global.utils, global.events, global.core, global.elementPlus, global.KeyController, global.StageCore));
5
+ })(this, (function (exports, vue, serialize, monaco, icons, schema, lodashEs, utils, events, core, elementPlus, KeyController, StageCore) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
9
  function _interopNamespace(e) {
10
10
  if (e && e.__esModule) return e;
11
- var n = {__proto__: null, [Symbol.toStringTag]: 'Module'};
11
+ var n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
12
12
  if (e) {
13
13
  Object.keys(e).forEach(function (k) {
14
14
  if (k !== 'default') {
@@ -26,8 +26,13 @@
26
26
 
27
27
  var serialize__default = /*#__PURE__*/_interopDefaultLegacy(serialize);
28
28
  var monaco__namespace = /*#__PURE__*/_interopNamespace(monaco);
29
+ var KeyController__default = /*#__PURE__*/_interopDefaultLegacy(KeyController);
29
30
  var StageCore__default = /*#__PURE__*/_interopDefaultLegacy(StageCore);
30
31
 
32
+ if (typeof window.global === "undefined") {
33
+ window.global = window;
34
+ }
35
+
31
36
  var _export_sfc = (sfc, props) => {
32
37
  const target = sfc.__vccOpts || sfc;
33
38
  for (const [key, val] of props) {
@@ -36,7 +41,7 @@
36
41
  return target;
37
42
  };
38
43
 
39
- const _sfc_main$k = vue.defineComponent({
44
+ const _sfc_main$l = vue.defineComponent({
40
45
  name: "m-fields-vs-code",
41
46
  props: ["model", "name", "config", "prop"],
42
47
  emits: ["change"],
@@ -53,7 +58,7 @@
53
58
  };
54
59
  }
55
60
  });
56
- function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
61
+ function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
57
62
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
58
63
  return vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
59
64
  style: vue.normalizeStyle(`height: ${_ctx.height}`),
@@ -62,9 +67,9 @@
62
67
  onSave: _ctx.save
63
68
  }, null, 8, ["style", "init-values", "language", "onSave"]);
64
69
  }
65
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
70
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$l]]);
66
71
 
67
- const _sfc_main$j = vue.defineComponent({
72
+ const _sfc_main$k = vue.defineComponent({
68
73
  name: "m-fields-code-link",
69
74
  props: {
70
75
  config: {
@@ -119,7 +124,7 @@
119
124
  };
120
125
  }
121
126
  });
122
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
127
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
123
128
  const _component_m_fields_link = vue.resolveComponent("m-fields-link");
124
129
  return vue.openBlock(), vue.createBlock(_component_m_fields_link, {
125
130
  config: _ctx.formConfig,
@@ -128,11 +133,11 @@
128
133
  onChange: _ctx.changeHandler
129
134
  }, null, 8, ["config", "model", "onChange"]);
130
135
  }
131
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
136
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
132
137
 
133
138
  var UISelect_vue_vue_type_style_index_0_lang = '';
134
139
 
135
- const _sfc_main$i = vue.defineComponent({
140
+ const _sfc_main$j = vue.defineComponent({
136
141
  name: "m-fields-ui-select",
137
142
  props: {
138
143
  labelWidth: String,
@@ -194,25 +199,25 @@
194
199
  };
195
200
  }
196
201
  });
197
- const _hoisted_1$e = /* @__PURE__ */ vue.createElementVNode("i", {
202
+ const _hoisted_1$c = /* @__PURE__ */ vue.createElementVNode("i", {
198
203
  class: "el-icon-delete",
199
204
  style: { "color": "rgb(221, 75, 57)" }
200
205
  }, "\u53D6\u6D88", -1);
201
- const _hoisted_2$7 = [
202
- _hoisted_1$e
206
+ const _hoisted_2$5 = [
207
+ _hoisted_1$c
203
208
  ];
204
- const _hoisted_3$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
205
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
209
+ const _hoisted_3$3 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
210
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
206
211
  return _ctx.uiSelectMode ? (vue.openBlock(), vue.createElementBlock("div", {
207
212
  key: 0,
208
213
  class: "m-fields-ui-select",
209
214
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.cancelHandler && _ctx.cancelHandler(...args))
210
- }, _hoisted_2$7)) : (vue.openBlock(), vue.createElementBlock("div", {
215
+ }, _hoisted_2$5)) : (vue.openBlock(), vue.createElementBlock("div", {
211
216
  key: 1,
212
217
  class: "m-fields-ui-select",
213
218
  onClick: _cache[2] || (_cache[2] = (...args) => _ctx.startSelect && _ctx.startSelect(...args))
214
219
  }, [
215
- _hoisted_3$5,
220
+ _hoisted_3$3,
216
221
  vue.createElementVNode("span", null, vue.toDisplayString(_ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"), 1),
217
222
  _ctx.val ? (vue.openBlock(), vue.createElementBlock("i", {
218
223
  key: 0,
@@ -221,7 +226,7 @@
221
226
  })) : vue.createCommentVNode("", true)
222
227
  ]));
223
228
  }
224
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
229
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
225
230
 
226
231
  const toString = (v, language) => {
227
232
  let value = "";
@@ -238,7 +243,7 @@
238
243
  }
239
244
  return value;
240
245
  };
241
- const _sfc_main$h = vue.defineComponent({
246
+ const _sfc_main$i = vue.defineComponent({
242
247
  name: "magic-code-editor",
243
248
  props: {
244
249
  initValues: {
@@ -343,14 +348,14 @@
343
348
  };
344
349
  }
345
350
  });
346
- const _hoisted_1$d = {
351
+ const _hoisted_1$b = {
347
352
  ref: "codeEditor",
348
353
  class: "magic-code-editor"
349
354
  };
350
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
351
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$d, null, 512);
355
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
356
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, null, 512);
352
357
  }
353
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
358
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
354
359
 
355
360
  let $TMAGIC_EDITOR = {};
356
361
  const setConfig = (option) => {
@@ -359,9 +364,6 @@
359
364
  const getConfig = (key) => $TMAGIC_EDITOR[key];
360
365
 
361
366
  class UndoRedo {
362
- elementList;
363
- listCursor;
364
- listMaxSize;
365
367
  constructor(listMaxSize = 200) {
366
368
  const minListMaxSize = 2;
367
369
  this.elementList = [];
@@ -452,7 +454,7 @@
452
454
  }
453
455
  let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
454
456
  for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
455
- returnValue = await afterMethod(...beforeArgs, returnValue);
457
+ returnValue = await afterMethod(returnValue, ...beforeArgs);
456
458
  if (isError(returnValue))
457
459
  throw returnValue;
458
460
  }
@@ -462,12 +464,12 @@
462
464
  }
463
465
  };
464
466
  class BaseService extends events.EventEmitter {
465
- pluginOptionsList = {};
466
- middleware = {};
467
- taskList = [];
468
- doingTask = false;
469
467
  constructor(methods = [], serialMethods = []) {
470
468
  super();
469
+ this.pluginOptionsList = {};
470
+ this.middleware = {};
471
+ this.taskList = [];
472
+ this.doingTask = false;
471
473
  methods.forEach((propertyName) => {
472
474
  const scope = this;
473
475
  const sourceMethod = scope[propertyName];
@@ -524,16 +526,22 @@
524
526
  }
525
527
 
526
528
  class History extends BaseService {
527
- state = vue.reactive({
528
- pageSteps: {},
529
- pageId: void 0,
530
- canRedo: false,
531
- canUndo: false
532
- });
533
529
  constructor() {
534
530
  super([]);
531
+ this.state = vue.reactive({
532
+ pageSteps: {},
533
+ pageId: void 0,
534
+ canRedo: false,
535
+ canUndo: false
536
+ });
535
537
  this.on("change", this.setCanUndoRedo);
536
538
  }
539
+ reset() {
540
+ this.state.pageSteps = {};
541
+ this.state.pageId = void 0;
542
+ this.state.canRedo = false;
543
+ this.state.canUndo = false;
544
+ }
537
545
  changePage(page) {
538
546
  if (!page)
539
547
  return;
@@ -597,12 +605,12 @@
597
605
  var historyService = new History();
598
606
 
599
607
  class Props extends BaseService {
600
- state = vue.reactive({
601
- propsConfigMap: {},
602
- propsValueMap: {}
603
- });
604
608
  constructor() {
605
609
  super(["setPropsConfig", "getPropsConfig", "setPropsValue", "getPropsValue"]);
610
+ this.state = vue.reactive({
611
+ propsConfigMap: {},
612
+ propsValueMap: {}
613
+ });
606
614
  }
607
615
  setPropsConfigs(configs) {
608
616
  Object.keys(configs).forEach((type) => {
@@ -627,7 +635,7 @@
627
635
  setPropsValue(type, value) {
628
636
  this.state.propsValueMap[type] = value;
629
637
  }
630
- async getPropsValue(type) {
638
+ async getPropsValue(type, defaultValue = {}) {
631
639
  if (type === "area") {
632
640
  const value = await this.getPropsValue("button");
633
641
  value.className = "action-area";
@@ -639,7 +647,7 @@
639
647
  }
640
648
  return lodashEs.cloneDeep({
641
649
  ...getDefaultPropsValue(type),
642
- ...this.state.propsValueMap[type] || {}
650
+ ...lodashEs.mergeWith(this.state.propsValueMap[type] || {}, defaultValue)
643
651
  });
644
652
  }
645
653
  }
@@ -700,7 +708,7 @@
700
708
  };
701
709
  const setNewItemId = (config, parent) => {
702
710
  const oldId = config.id;
703
- config.id = generateId(config.type);
711
+ config.id = generateId(config.type || "component");
704
712
  config.name = `${config.name?.replace(/_(\d+)$/, "")}_${config.id}`;
705
713
  if (utils.isPop(config) && parent?.type === schema.NodeType.PAGE) {
706
714
  updatePopId(oldId, config.id, parent);
@@ -723,11 +731,25 @@
723
731
  };
724
732
  return node;
725
733
  };
726
- const initPosition = (node, layout) => {
734
+ const setTop2Middle = (node, parentNode, stage) => {
735
+ const style = node.style || {};
736
+ const height = style.height || 0;
737
+ if (!stage || typeof style.top !== "undefined" || !parentNode.style || !utils.isNumber(height))
738
+ return style;
739
+ const { height: parentHeight } = parentNode.style;
740
+ if (utils.isPage(parentNode)) {
741
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
742
+ style.top = (wrapperHeight - height) / 2 + scrollTop;
743
+ } else {
744
+ style.top = (parentHeight - height) / 2;
745
+ }
746
+ return style;
747
+ };
748
+ const initPosition = (node, layout, parentNode, stage) => {
727
749
  if (layout === Layout.ABSOLUTE) {
728
750
  node.style = {
729
751
  position: "absolute",
730
- ...node.style || {}
752
+ ...setTop2Middle(node, parentNode, stage)
731
753
  };
732
754
  return node;
733
755
  }
@@ -774,7 +796,9 @@
774
796
  const cur = path.pop();
775
797
  const offset = {
776
798
  left: cur?.style?.left || 0,
777
- top: cur?.style?.top || 0
799
+ top: cur?.style?.top || 0,
800
+ right: "",
801
+ bottom: ""
778
802
  };
779
803
  path.forEach((value) => {
780
804
  offset.left = offset.left - globalThis.parseFloat(value.style?.left || 0);
@@ -808,16 +832,6 @@
808
832
  };
809
833
 
810
834
  class Editor$1 extends BaseService {
811
- isHistoryStateChange = false;
812
- state = vue.reactive({
813
- root: null,
814
- page: null,
815
- parent: null,
816
- node: null,
817
- stage: null,
818
- highlightNode: null,
819
- modifiedNodeIds: /* @__PURE__ */ new Map()
820
- });
821
835
  constructor() {
822
836
  super([
823
837
  "getLayout",
@@ -830,14 +844,27 @@
830
844
  "paste",
831
845
  "alignCenter",
832
846
  "moveLayer",
847
+ "move",
833
848
  "undo",
834
849
  "redo",
835
850
  "highlight"
836
851
  ], ["select", "update", "moveLayer"]);
852
+ this.isHistoryStateChange = false;
853
+ this.state = vue.reactive({
854
+ root: null,
855
+ page: null,
856
+ parent: null,
857
+ node: null,
858
+ stage: null,
859
+ highlightNode: null,
860
+ modifiedNodeIds: /* @__PURE__ */ new Map(),
861
+ pageLength: 0
862
+ });
837
863
  }
838
864
  set(name, value) {
839
865
  this.state[name] = value;
840
866
  if (name === "root") {
867
+ this.state.pageLength = value?.items?.length || 0;
841
868
  this.emit("root-change", value);
842
869
  }
843
870
  }
@@ -845,7 +872,7 @@
845
872
  return this.state[name];
846
873
  }
847
874
  getNodeInfo(id) {
848
- const root = this.get("root");
875
+ const root = vue.toRaw(this.get("root"));
849
876
  if (!root)
850
877
  return {};
851
878
  if (id === root.id) {
@@ -876,11 +903,13 @@
876
903
  const { parent } = this.getNodeInfo(id);
877
904
  return parent;
878
905
  }
879
- async getLayout(node) {
880
- if (node.layout) {
881
- return node.layout;
906
+ async getLayout(parent, node) {
907
+ if (node && typeof node !== "function" && isFixed(node))
908
+ return Layout.FIXED;
909
+ if (parent.layout) {
910
+ return parent.layout;
882
911
  }
883
- if (!node.style?.position) {
912
+ if (!parent.style?.position) {
884
913
  return Layout.RELATIVE;
885
914
  }
886
915
  return Layout.ABSOLUTE;
@@ -895,8 +924,31 @@
895
924
  } else {
896
925
  historyService.empty();
897
926
  }
927
+ this.emit("select", node);
898
928
  return node;
899
929
  }
930
+ async selectNextNode() {
931
+ const node = vue.toRaw(this.get("node"));
932
+ if (!node || utils.isPage(node) || node.type === schema.NodeType.ROOT)
933
+ return node;
934
+ const parent = vue.toRaw(this.getParentById(node.id));
935
+ if (!parent)
936
+ return node;
937
+ const index = getNodeIndex(node, parent);
938
+ const nextNode = parent.items[index + 1] || parent.items[0];
939
+ await this.select(nextNode);
940
+ this.get("stage")?.select(nextNode.id);
941
+ return nextNode;
942
+ }
943
+ async selectNextPage() {
944
+ const root = vue.toRaw(this.get("root"));
945
+ const page = vue.toRaw(this.get("page"));
946
+ const index = getNodeIndex(page, root);
947
+ const nextPage = root.items[index + 1] || root.items[0];
948
+ await this.select(nextPage);
949
+ this.get("stage")?.select(nextPage.id);
950
+ return nextPage;
951
+ }
900
952
  highlight(config2) {
901
953
  const { node } = this.selectedConfigExceptionHandler(config2);
902
954
  const currentHighlightNode = this.get("highlightNode");
@@ -904,10 +956,12 @@
904
956
  return;
905
957
  this.set("highlightNode", node);
906
958
  }
907
- async add({ type, ...config2 }, parent) {
959
+ async add(addNode, parent) {
960
+ const { type, ...config2 } = addNode;
908
961
  const curNode = this.get("node");
909
962
  let parentNode;
910
- if (type === schema.NodeType.PAGE) {
963
+ const isPage2 = type === schema.NodeType.PAGE;
964
+ if (isPage2) {
911
965
  parentNode = this.get("root");
912
966
  } else if (parent && typeof parent !== "function") {
913
967
  parentNode = parent;
@@ -918,8 +972,8 @@
918
972
  }
919
973
  if (!parentNode)
920
974
  throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
921
- const layout = await this.getLayout(parentNode);
922
- const newNode = initPosition({ ...vue.toRaw(await propsService.getPropsValue(type)), ...config2 }, layout);
975
+ const layout = await this.getLayout(vue.toRaw(parentNode), addNode);
976
+ const newNode = initPosition({ ...vue.toRaw(await propsService.getPropsValue(type, config2)) }, layout, parentNode, this.get("stage"));
923
977
  if ((parentNode?.type === schema.NodeType.ROOT || curNode.type === schema.NodeType.ROOT) && newNode.type !== schema.NodeType.PAGE) {
924
978
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
925
979
  }
@@ -932,6 +986,10 @@
932
986
  this.pushHistoryState();
933
987
  }
934
988
  stage?.select(newNode.id);
989
+ if (isPage2) {
990
+ this.state.pageLength += 1;
991
+ }
992
+ this.emit("add", newNode);
935
993
  return newNode;
936
994
  }
937
995
  async remove(node) {
@@ -950,9 +1008,20 @@
950
1008
  const stage = this.get("stage");
951
1009
  stage?.remove({ id: node.id, root: this.get("root") });
952
1010
  if (node.type === schema.NodeType.PAGE) {
1011
+ this.state.pageLength -= 1;
953
1012
  if (root.items[0]) {
954
1013
  await this.select(root.items[0]);
955
1014
  stage?.select(root.items[0].id);
1015
+ } else {
1016
+ this.set("node", null);
1017
+ this.set("parent", null);
1018
+ this.set("page", null);
1019
+ this.set("stage", null);
1020
+ this.set("highlightNode", null);
1021
+ this.resetModifiedNodeId();
1022
+ historyService.reset();
1023
+ this.emit("remove", node);
1024
+ return node;
956
1025
  }
957
1026
  } else {
958
1027
  await this.select(parent);
@@ -960,6 +1029,7 @@
960
1029
  }
961
1030
  this.addModifiedNodeId(parent.id);
962
1031
  this.pushHistoryState();
1032
+ this.emit("remove", node);
963
1033
  return node;
964
1034
  }
965
1035
  async update(config2) {
@@ -1003,6 +1073,7 @@
1003
1073
  }
1004
1074
  this.addModifiedNodeId(newConfig.id);
1005
1075
  this.pushHistoryState();
1076
+ this.emit("update", newConfig);
1006
1077
  return newConfig;
1007
1078
  }
1008
1079
  async sort(id1, id2) {
@@ -1046,7 +1117,7 @@
1046
1117
  async alignCenter(config2) {
1047
1118
  const parent = this.get("parent");
1048
1119
  const node = this.get("node");
1049
- const layout = await this.getLayout(parent);
1120
+ const layout = await this.getLayout(vue.toRaw(parent), vue.toRaw(node));
1050
1121
  if (layout === Layout.RELATIVE) {
1051
1122
  return;
1052
1123
  }
@@ -1083,6 +1154,26 @@
1083
1154
  await this.changeHistoryState(value);
1084
1155
  return value;
1085
1156
  }
1157
+ async move(left, top) {
1158
+ const node = vue.toRaw(this.get("node"));
1159
+ if (!node || utils.isPage(node))
1160
+ return;
1161
+ const { style, id } = node;
1162
+ if (!style || style.position !== "absolute")
1163
+ return;
1164
+ if (top && !utils.isNumber(style.top))
1165
+ return;
1166
+ if (left && !utils.isNumber(style.left))
1167
+ return;
1168
+ this.update({
1169
+ id,
1170
+ style: {
1171
+ ...style,
1172
+ left: Number(style.left) + left,
1173
+ top: Number(style.top) + top
1174
+ }
1175
+ });
1176
+ }
1086
1177
  destroy() {
1087
1178
  this.removeAllListeners();
1088
1179
  this.set("root", null);
@@ -1312,6 +1403,25 @@
1312
1403
  defaultValue: "100% 100%"
1313
1404
  }
1314
1405
  ]
1406
+ },
1407
+ {
1408
+ type: "fieldset",
1409
+ legend: "\u5B57\u4F53",
1410
+ items: [
1411
+ {
1412
+ name: "color",
1413
+ text: "\u989C\u8272",
1414
+ type: "colorPicker"
1415
+ },
1416
+ {
1417
+ name: "fontSize",
1418
+ text: "\u5927\u5C0F"
1419
+ },
1420
+ {
1421
+ name: "fontWeight",
1422
+ text: "\u7C97\u7EC6"
1423
+ }
1424
+ ]
1315
1425
  }
1316
1426
  ]
1317
1427
  }
@@ -1344,7 +1454,7 @@
1344
1454
  type: "select",
1345
1455
  options: (mForm, { model }) => {
1346
1456
  const node = editorService.getNodeById(model.to);
1347
- if (!node)
1457
+ if (!node?.type)
1348
1458
  return [];
1349
1459
  return eventsService.getMethod(node.type).map((option) => ({
1350
1460
  text: option.label,
@@ -1379,7 +1489,7 @@
1379
1489
  name: type
1380
1490
  });
1381
1491
 
1382
- const _sfc_main$g = vue.defineComponent({
1492
+ const _sfc_main$h = vue.defineComponent({
1383
1493
  components: { Plus: icons.Plus },
1384
1494
  setup() {
1385
1495
  const services = vue.inject("services");
@@ -1396,14 +1506,14 @@
1396
1506
  };
1397
1507
  }
1398
1508
  });
1399
- const _hoisted_1$c = { class: "m-editor-empty-panel" };
1400
- const _hoisted_2$6 = { class: "m-editor-empty-content" };
1401
- const _hoisted_3$4 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1402
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1509
+ const _hoisted_1$a = { class: "m-editor-empty-panel" };
1510
+ const _hoisted_2$4 = { class: "m-editor-empty-content" };
1511
+ const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1512
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
1403
1513
  const _component_plus = vue.resolveComponent("plus");
1404
1514
  const _component_el_icon = vue.resolveComponent("el-icon");
1405
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, [
1406
- vue.createElementVNode("div", _hoisted_2$6, [
1515
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
1516
+ vue.createElementVNode("div", _hoisted_2$4, [
1407
1517
  vue.createElementVNode("div", {
1408
1518
  class: "m-editor-empty-button",
1409
1519
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.clickHandler && _ctx.clickHandler(...args))
@@ -1416,12 +1526,12 @@
1416
1526
  _: 1
1417
1527
  })
1418
1528
  ]),
1419
- _hoisted_3$4
1529
+ _hoisted_3$2
1420
1530
  ])
1421
1531
  ])
1422
1532
  ]);
1423
1533
  }
1424
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1534
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
1425
1535
 
1426
1536
  /*
1427
1537
  Copyright (c) 2018 Daybrush
@@ -1825,8 +1935,8 @@
1825
1935
  name: gesto
1826
1936
  license: MIT
1827
1937
  author: Daybrush
1828
- repository: git+https://github.com/daybrush/gesture.git
1829
- version: 1.5.0
1938
+ repository: git+https://github.com/daybrush/gesto.git
1939
+ version: 1.7.0
1830
1940
  */
1831
1941
 
1832
1942
  /*! *****************************************************************************
@@ -1995,19 +2105,6 @@
1995
2105
 
1996
2106
  var __proto = ClientStore.prototype;
1997
2107
 
1998
- __proto.addClients = function (clients) {
1999
- if (clients === void 0) {
2000
- clients = this.prevClients;
2001
- }
2002
-
2003
- var position = this.getPosition(clients);
2004
- var deltaX = position.deltaX,
2005
- deltaY = position.deltaY;
2006
- this.movement += Math.sqrt(deltaX * deltaX + deltaY * deltaY);
2007
- this.prevClients = clients;
2008
- return position;
2009
- };
2010
-
2011
2108
  __proto.getAngle = function (clients) {
2012
2109
  if (clients === void 0) {
2013
2110
  clients = this.prevClients;
@@ -2024,8 +2121,17 @@
2024
2121
  return getRotatiion(clients) - getRotatiion(this.startClients);
2025
2122
  };
2026
2123
 
2027
- __proto.getPosition = function (clients) {
2028
- return getPosition(clients || this.prevClients, this.prevClients, this.startClients);
2124
+ __proto.getPosition = function (clients, isAdd) {
2125
+ if (clients === void 0) {
2126
+ clients = this.prevClients;
2127
+ }
2128
+
2129
+ var position = getPosition(clients || this.prevClients, this.prevClients, this.startClients);
2130
+ var deltaX = position.deltaX,
2131
+ deltaY = position.deltaY;
2132
+ this.movement += Math.sqrt(deltaX * deltaX + deltaY * deltaY);
2133
+ this.prevClients = clients;
2134
+ return position;
2029
2135
  };
2030
2136
 
2031
2137
  __proto.getPositions = function (clients) {
@@ -2074,10 +2180,6 @@
2074
2180
  client.clientX -= deltaX;
2075
2181
  client.clientY -= deltaY;
2076
2182
  });
2077
- this.prevClients.forEach(function (client) {
2078
- client.clientX -= deltaX;
2079
- client.clientY -= deltaY;
2080
- });
2081
2183
  };
2082
2184
 
2083
2185
  return ClientStore;
@@ -2116,6 +2218,7 @@
2116
2218
  _this.targets = [];
2117
2219
  _this.prevTime = 0;
2118
2220
  _this.doubleFlag = false;
2221
+ _this._dragFlag = false;
2119
2222
 
2120
2223
  _this.onDragStart = function (e, isTrusted) {
2121
2224
  if (isTrusted === void 0) {
@@ -2146,7 +2249,8 @@
2146
2249
  if (checkInput || activeElement === target) {
2147
2250
  // force false or already focused.
2148
2251
  return false;
2149
- }
2252
+ } // no focus
2253
+
2150
2254
 
2151
2255
  if (activeElement && hasContentEditable && activeElement.isContentEditable && activeElement.contains(target)) {
2152
2256
  return false;
@@ -2162,6 +2266,7 @@
2162
2266
  _this.clientStores = [new ClientStore(getEventClients(e))];
2163
2267
  _this.flag = true;
2164
2268
  _this.isDrag = false;
2269
+ _this._dragFlag = true;
2165
2270
  _this.datas = {};
2166
2271
 
2167
2272
  if (preventRightClick && (e.which === 3 || e.button === 2)) {
@@ -2177,7 +2282,14 @@
2177
2282
  inputEvent: e,
2178
2283
  isTrusted: isTrusted,
2179
2284
  isDouble: _this.doubleFlag
2180
- }, _this.getCurrentStore().getPosition()));
2285
+ }, _this.getCurrentStore().getPosition(), {
2286
+ preventDefault: function () {
2287
+ e.preventDefault();
2288
+ },
2289
+ preventDrag: function () {
2290
+ _this._dragFlag = false;
2291
+ }
2292
+ }));
2181
2293
 
2182
2294
  if (result === false) {
2183
2295
  _this.initDrag();
@@ -2226,24 +2338,26 @@
2226
2338
 
2227
2339
  var result = _this.moveClients(clients, e, false);
2228
2340
 
2229
- if (_this.pinchFlag || result.deltaX || result.deltaY) {
2230
- var dragResult = _this.emit("drag", __assign({}, result, {
2231
- isScroll: !!isScroll,
2232
- inputEvent: e
2233
- }));
2341
+ if (_this._dragFlag) {
2342
+ if (_this.pinchFlag || result.deltaX || result.deltaY) {
2343
+ var dragResult = _this.emit("drag", __assign({}, result, {
2344
+ isScroll: !!isScroll,
2345
+ inputEvent: e
2346
+ }));
2234
2347
 
2235
- if (dragResult === false) {
2236
- _this.stop();
2348
+ if (dragResult === false) {
2349
+ _this.stop();
2237
2350
 
2238
- return;
2351
+ return;
2352
+ }
2239
2353
  }
2240
- }
2241
2354
 
2242
- if (_this.pinchFlag) {
2243
- _this.onPinch(e, clients);
2355
+ if (_this.pinchFlag) {
2356
+ _this.onPinch(e, clients);
2357
+ }
2244
2358
  }
2245
2359
 
2246
- _this.getCurrentStore().addClients(clients);
2360
+ _this.getCurrentStore().getPosition(clients, true);
2247
2361
  };
2248
2362
 
2249
2363
  _this.onDragEnd = function (e) {
@@ -2261,7 +2375,7 @@
2261
2375
 
2262
2376
  _this.flag = false;
2263
2377
 
2264
- var position = _this.getCurrentStore().getPosition();
2378
+ var position = _this._getPosition();
2265
2379
 
2266
2380
  var currentTime = now();
2267
2381
  var isDouble = !_this.isDrag && _this.doubleFlag;
@@ -2455,7 +2569,23 @@
2455
2569
  return this;
2456
2570
  };
2457
2571
  /**
2458
- * Set the event data while dragging.
2572
+ * Get the current event state while dragging.
2573
+ */
2574
+
2575
+
2576
+ __proto.getCurrentEvent = function (inputEvent) {
2577
+ return __assign({
2578
+ datas: this.datas
2579
+ }, this._getPosition(), {
2580
+ movement: this.getMovement(),
2581
+ isDrag: this.isDrag,
2582
+ isPinch: this.isPinch,
2583
+ isScroll: false,
2584
+ inputEvent: inputEvent
2585
+ });
2586
+ };
2587
+ /**
2588
+ * Get & Set the event data while dragging.
2459
2589
  */
2460
2590
 
2461
2591
 
@@ -2571,9 +2701,12 @@
2571
2701
  };
2572
2702
 
2573
2703
  __proto.moveClients = function (clients, inputEvent, isAdd) {
2574
- var store = this.getCurrentStore();
2575
- var position = store[isAdd ? "addClients" : "getPosition"](clients);
2576
- this.isDrag = true;
2704
+ var position = this._getPosition(clients, isAdd);
2705
+
2706
+ if (position.deltaX || position.deltaY) {
2707
+ this.isDrag = true;
2708
+ }
2709
+
2577
2710
  return __assign({
2578
2711
  datas: this.datas
2579
2712
  }, position, {
@@ -2585,12 +2718,31 @@
2585
2718
  });
2586
2719
  };
2587
2720
 
2721
+ __proto._getPosition = function (clients, isAdd) {
2722
+ var store = this.getCurrentStore();
2723
+ var position = store.getPosition(clients, isAdd);
2724
+
2725
+ var _a = this.clientStores.slice(1).reduce(function (prev, cur) {
2726
+ var storePosition = cur.getPosition();
2727
+ prev.distX += storePosition.distX;
2728
+ prev.distY += storePosition.distY;
2729
+ return prev;
2730
+ }, position),
2731
+ distX = _a.distX,
2732
+ distY = _a.distY;
2733
+
2734
+ return __assign({}, position, {
2735
+ distX: distX,
2736
+ distY: distY
2737
+ });
2738
+ };
2739
+
2588
2740
  return Gesto;
2589
2741
  }(EventEmitter$1);
2590
2742
 
2591
2743
  var Gesto$1 = Gesto;
2592
2744
 
2593
- const _sfc_main$f = vue.defineComponent({
2745
+ const _sfc_main$g = vue.defineComponent({
2594
2746
  name: "m-editor-resize",
2595
2747
  props: {
2596
2748
  type: {
@@ -2632,33 +2784,33 @@
2632
2784
  };
2633
2785
  }
2634
2786
  });
2635
- const _hoisted_1$b = {
2787
+ const _hoisted_1$9 = {
2636
2788
  ref: "target",
2637
2789
  class: "m-editor-resizer"
2638
2790
  };
2639
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2640
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$b, [
2791
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
2792
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$9, [
2641
2793
  vue.renderSlot(_ctx.$slots, "default")
2642
2794
  ], 512);
2643
2795
  }
2644
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2796
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
2645
2797
 
2646
- const _sfc_main$e = vue.defineComponent({
2798
+ const _sfc_main$f = vue.defineComponent({
2647
2799
  components: {
2648
2800
  AddPageBox,
2649
2801
  Resizer
2650
2802
  },
2651
2803
  setup() {
2652
- const services = vue.inject("services");
2653
- const root = vue.computed(() => services?.editorService.get("root"));
2804
+ const { editorService, uiService } = vue.inject("services") || {};
2805
+ const root = vue.computed(() => editorService?.get("root"));
2654
2806
  return {
2655
2807
  root,
2656
- pageLength: vue.computed(() => root.value?.items?.length || 0),
2657
- showSrc: vue.computed(() => services?.uiService.get("showSrc")),
2658
- columnWidth: vue.computed(() => services?.uiService.get("columnWidth")),
2808
+ pageLength: vue.computed(() => editorService?.get("pageLength") || 0),
2809
+ showSrc: vue.computed(() => uiService?.get("showSrc")),
2810
+ columnWidth: vue.computed(() => uiService?.get("columnWidth")),
2659
2811
  saveCode(value) {
2660
2812
  try {
2661
- services?.editorService.set("root", eval(value));
2813
+ editorService?.set("root", eval(value));
2662
2814
  } catch (e) {
2663
2815
  console.error(e);
2664
2816
  }
@@ -2666,24 +2818,24 @@
2666
2818
  };
2667
2819
  }
2668
2820
  });
2669
- const _hoisted_1$a = { class: "m-editor" };
2670
- const _hoisted_2$5 = {
2821
+ const _hoisted_1$8 = { class: "m-editor" };
2822
+ const _hoisted_2$3 = {
2671
2823
  key: 1,
2672
2824
  class: "m-editor-content"
2673
2825
  };
2674
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2826
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2675
2827
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
2676
2828
  const _component_resizer = vue.resolveComponent("resizer");
2677
2829
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
2678
2830
  const _component_add_page_box = vue.resolveComponent("add-page-box");
2679
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
2831
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
2680
2832
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2681
2833
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
2682
2834
  key: 0,
2683
2835
  class: "m-editor-content",
2684
2836
  "init-values": _ctx.root,
2685
2837
  onSave: _ctx.saveCode
2686
- }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$5, [
2838
+ }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, [
2687
2839
  vue.createElementVNode("div", {
2688
2840
  class: "m-editor-framework-left",
2689
2841
  style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.left}px`)
@@ -2716,9 +2868,9 @@
2716
2868
  ]))
2717
2869
  ]);
2718
2870
  }
2719
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2871
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2720
2872
 
2721
- const _sfc_main$d = vue.defineComponent({
2873
+ const _sfc_main$e = vue.defineComponent({
2722
2874
  name: "m-icon",
2723
2875
  components: { Edit: icons.Edit },
2724
2876
  props: {
@@ -2732,8 +2884,8 @@
2732
2884
  };
2733
2885
  }
2734
2886
  });
2735
- const _hoisted_1$9 = ["src"];
2736
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2887
+ const _hoisted_1$7 = ["src"];
2888
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2737
2889
  const _component_edit = vue.resolveComponent("edit");
2738
2890
  const _component_el_icon = vue.resolveComponent("el-icon");
2739
2891
  return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
@@ -2744,7 +2896,7 @@
2744
2896
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createElementBlock("img", {
2745
2897
  key: 1,
2746
2898
  src: _ctx.icon
2747
- }, null, 8, _hoisted_1$9)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2899
+ }, null, 8, _hoisted_1$7)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2748
2900
  key: 2,
2749
2901
  class: vue.normalizeClass(_ctx.icon)
2750
2902
  }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
@@ -2754,9 +2906,9 @@
2754
2906
  _: 1
2755
2907
  }));
2756
2908
  }
2757
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2909
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2758
2910
 
2759
- const _sfc_main$c = vue.defineComponent({
2911
+ const _sfc_main$d = vue.defineComponent({
2760
2912
  components: { MIcon, ArrowDown: icons.ArrowDown },
2761
2913
  props: {
2762
2914
  data: {
@@ -2766,16 +2918,20 @@
2766
2918
  type: "text",
2767
2919
  display: false
2768
2920
  })
2921
+ },
2922
+ eventType: {
2923
+ type: String,
2924
+ default: "click"
2769
2925
  }
2770
2926
  },
2771
2927
  setup(props) {
2772
2928
  const services = vue.inject("services");
2773
2929
  const uiService = services?.uiService;
2774
- const zoomInHandler = () => uiService?.set("zoom", zoom.value + 0.1);
2775
- const zoomOutHandler = () => uiService?.set("zoom", zoom.value - 0.1);
2776
2930
  const zoom = vue.computed(() => uiService?.get("zoom") ?? 1);
2777
2931
  const showGuides = vue.computed(() => uiService?.get("showGuides") ?? true);
2778
2932
  const showRule = vue.computed(() => uiService?.get("showRule") ?? true);
2933
+ const zoomInHandler = () => uiService?.zoom(0.1);
2934
+ const zoomOutHandler = () => uiService?.zoom(-0.1);
2779
2935
  const item = vue.computed(() => {
2780
2936
  if (typeof props.data !== "string") {
2781
2937
  return props.data;
@@ -2792,7 +2948,7 @@
2792
2948
  case "delete":
2793
2949
  return {
2794
2950
  type: "button",
2795
- icon: icons.Delete,
2951
+ icon: vue.markRaw(icons.Delete),
2796
2952
  tooltip: "\u522A\u9664",
2797
2953
  disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2798
2954
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
@@ -2800,7 +2956,7 @@
2800
2956
  case "undo":
2801
2957
  return {
2802
2958
  type: "button",
2803
- icon: icons.Back,
2959
+ icon: vue.markRaw(icons.Back),
2804
2960
  tooltip: "\u540E\u9000",
2805
2961
  disabled: () => !services?.historyService.state.canUndo,
2806
2962
  handler: () => services?.editorService.undo()
@@ -2808,7 +2964,7 @@
2808
2964
  case "redo":
2809
2965
  return {
2810
2966
  type: "button",
2811
- icon: icons.Right,
2967
+ icon: vue.markRaw(icons.Right),
2812
2968
  tooltip: "\u524D\u8FDB",
2813
2969
  disabled: () => !services?.historyService.state.canRedo,
2814
2970
  handler: () => services?.editorService.redo()
@@ -2816,28 +2972,28 @@
2816
2972
  case "zoom-in":
2817
2973
  return {
2818
2974
  type: "button",
2819
- icon: icons.ZoomIn,
2975
+ icon: vue.markRaw(icons.ZoomIn),
2820
2976
  tooltip: "\u653E\u5927",
2821
2977
  handler: zoomInHandler
2822
2978
  };
2823
2979
  case "zoom-out":
2824
2980
  return {
2825
2981
  type: "button",
2826
- icon: icons.ZoomOut,
2982
+ icon: vue.markRaw(icons.ZoomOut),
2827
2983
  tooltip: "\u7E2E\u5C0F",
2828
2984
  handler: zoomOutHandler
2829
2985
  };
2830
2986
  case "rule":
2831
2987
  return {
2832
2988
  type: "button",
2833
- icon: icons.ScaleToOriginal,
2989
+ icon: vue.markRaw(icons.ScaleToOriginal),
2834
2990
  tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2835
2991
  handler: () => uiService?.set("showRule", !showRule.value)
2836
2992
  };
2837
2993
  case "guides":
2838
2994
  return {
2839
2995
  type: "button",
2840
- icon: icons.Grid,
2996
+ icon: vue.markRaw(icons.Grid),
2841
2997
  tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2842
2998
  handler: () => uiService?.set("showGuides", !showGuides.value)
2843
2999
  };
@@ -2858,9 +3014,16 @@
2858
3014
  }
2859
3015
  return item.value.disabled;
2860
3016
  });
3017
+ const buttonHandler = (item2, event) => {
3018
+ if (disabled.value)
3019
+ return;
3020
+ if (typeof item2.handler === "function" && services) {
3021
+ item2.handler?.(services, event);
3022
+ }
3023
+ };
2861
3024
  return {
2862
- ZoomIn: icons.ZoomIn,
2863
- ZoomOut: icons.ZoomOut,
3025
+ ZoomIn: vue.markRaw(icons.ZoomIn),
3026
+ ZoomOut: vue.markRaw(icons.ZoomOut),
2864
3027
  item,
2865
3028
  zoom,
2866
3029
  disabled,
@@ -2881,31 +3044,42 @@
2881
3044
  command.item.handler(services);
2882
3045
  }
2883
3046
  },
2884
- buttonHandler(item2) {
2885
- if (disabled.value)
3047
+ clickHandler(item2, event) {
3048
+ if (props.eventType !== "click")
3049
+ return;
3050
+ if (item2.type === "button") {
3051
+ buttonHandler(item2, event);
3052
+ }
3053
+ },
3054
+ mousedownHandler(item2, event) {
3055
+ if (props.eventType !== "mousedown")
2886
3056
  return;
2887
- if (typeof item2.handler === "function") {
2888
- item2.handler?.(services);
3057
+ if (item2.type === "button") {
3058
+ buttonHandler(item2, event);
3059
+ }
3060
+ },
3061
+ mouseupHandler(item2, event) {
3062
+ if (props.eventType !== "mouseup")
3063
+ return;
3064
+ if (item2.type === "button") {
3065
+ buttonHandler(item2, event);
2889
3066
  }
2890
3067
  }
2891
3068
  };
2892
3069
  }
2893
3070
  });
2894
- const _hoisted_1$8 = {
2895
- key: 0,
2896
- class: "menu-item"
2897
- };
2898
- const _hoisted_2$4 = {
3071
+ const _hoisted_1$6 = {
2899
3072
  key: 1,
2900
3073
  class: "menu-item-text"
2901
3074
  };
2902
- const _hoisted_3$3 = {
3075
+ const _hoisted_2$2 = {
2903
3076
  class: "menu-item-text",
2904
3077
  style: { "margin": "0 5px" }
2905
3078
  };
2906
- const _hoisted_4$2 = { class: "el-dropdown-link menubar-menu-button" };
2907
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3079
+ const _hoisted_3$1 = { class: "el-dropdown-link menubar-menu-button" };
3080
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2908
3081
  const _component_el_divider = vue.resolveComponent("el-divider");
3082
+ const _component_tool_button = vue.resolveComponent("tool-button", true);
2909
3083
  const _component_m_icon = vue.resolveComponent("m-icon");
2910
3084
  const _component_el_button = vue.resolveComponent("el-button");
2911
3085
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -2914,60 +3088,66 @@
2914
3088
  const _component_el_dropdown_item = vue.resolveComponent("el-dropdown-item");
2915
3089
  const _component_el_dropdown_menu = vue.resolveComponent("el-dropdown-menu");
2916
3090
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
2917
- return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
3091
+ return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", {
3092
+ key: 0,
3093
+ class: vue.normalizeClass(["menu-item", _ctx.item.type]),
3094
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.clickHandler(_ctx.item, $event)),
3095
+ onMousedown: _cache[1] || (_cache[1] = ($event) => _ctx.mousedownHandler(_ctx.item, $event)),
3096
+ onMouseup: _cache[2] || (_cache[2] = ($event) => _ctx.mouseupHandler(_ctx.item, $event))
3097
+ }, [
2918
3098
  _ctx.item.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2919
3099
  key: 0,
2920
- direction: "vertical"
2921
- })) : _ctx.item.type === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$4, vue.toDisplayString(_ctx.item.text), 1)) : _ctx.item.type === "zoom" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
2922
- vue.createVNode(_component_el_button, {
2923
- size: "small",
2924
- type: "text"
3100
+ direction: _ctx.item.direction || "vertical"
3101
+ }, null, 8, ["direction"])) : _ctx.item.type === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, vue.toDisplayString(_ctx.item.text), 1)) : _ctx.item.type === "zoom" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
3102
+ vue.createVNode(_component_tool_button, {
3103
+ data: { type: "button", icon: _ctx.ZoomIn, handler: _ctx.zoomInHandler, tooltip: "\u653E\u5927" },
3104
+ "event-type": _ctx.eventType
3105
+ }, null, 8, ["data", "event-type"]),
3106
+ vue.createElementVNode("span", _hoisted_2$2, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
3107
+ vue.createVNode(_component_tool_button, {
3108
+ data: { type: "button", icon: _ctx.ZoomOut, handler: _ctx.zoomOutHandler, tooltip: "\u7F29\u5C0F" },
3109
+ "event-type": _ctx.eventType
3110
+ }, null, 8, ["data", "event-type"])
3111
+ ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
3112
+ _ctx.item.tooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
3113
+ key: 0,
3114
+ effect: "dark",
3115
+ placement: "bottom-start",
3116
+ content: _ctx.item.tooltip
2925
3117
  }, {
2926
3118
  default: vue.withCtx(() => [
2927
- vue.createVNode(_component_m_icon, {
2928
- icon: _ctx.ZoomIn,
2929
- onClick: _ctx.zoomInHandler
2930
- }, null, 8, ["icon", "onClick"])
3119
+ vue.createVNode(_component_el_button, {
3120
+ size: "small",
3121
+ type: "text",
3122
+ disabled: _ctx.disabled
3123
+ }, {
3124
+ default: vue.withCtx(() => [
3125
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3126
+ key: 0,
3127
+ icon: _ctx.item.icon
3128
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3129
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3130
+ ]),
3131
+ _: 1
3132
+ }, 8, ["disabled"])
2931
3133
  ]),
2932
3134
  _: 1
2933
- }),
2934
- vue.createElementVNode("span", _hoisted_3$3, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
2935
- vue.createVNode(_component_el_button, {
3135
+ }, 8, ["content"])) : (vue.openBlock(), vue.createBlock(_component_el_button, {
3136
+ key: 1,
2936
3137
  size: "small",
2937
- type: "text"
3138
+ type: "text",
3139
+ disabled: _ctx.disabled
2938
3140
  }, {
2939
3141
  default: vue.withCtx(() => [
2940
- vue.createVNode(_component_m_icon, {
2941
- icon: _ctx.ZoomOut,
2942
- onClick: _ctx.zoomOutHandler
2943
- }, null, 8, ["icon", "onClick"])
3142
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3143
+ key: 0,
3144
+ icon: _ctx.item.icon
3145
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3146
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
2944
3147
  ]),
2945
3148
  _: 1
2946
- })
2947
- ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
2948
- key: 3,
2949
- effect: "dark",
2950
- placement: "bottom-start",
2951
- content: _ctx.item.tooltip || _ctx.item.text
2952
- }, {
2953
- default: vue.withCtx(() => [
2954
- vue.createVNode(_component_el_button, {
2955
- size: "small",
2956
- type: "text",
2957
- disabled: _ctx.disabled,
2958
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.buttonHandler(_ctx.item))
2959
- }, {
2960
- default: vue.withCtx(() => [
2961
- vue.createVNode(_component_m_icon, {
2962
- icon: _ctx.item.icon
2963
- }, null, 8, ["icon"]),
2964
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
2965
- ]),
2966
- _: 1
2967
- }, 8, ["disabled"])
2968
- ]),
2969
- _: 1
2970
- }, 8, ["content"])) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
3149
+ }, 8, ["disabled"]))
3150
+ ], 64)) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2971
3151
  key: 4,
2972
3152
  trigger: "click",
2973
3153
  disabled: _ctx.disabled,
@@ -2992,7 +3172,7 @@
2992
3172
  })) : vue.createCommentVNode("", true)
2993
3173
  ]),
2994
3174
  default: vue.withCtx(() => [
2995
- vue.createElementVNode("span", _hoisted_4$2, [
3175
+ vue.createElementVNode("span", _hoisted_3$1, [
2996
3176
  vue.createTextVNode(vue.toDisplayString(_ctx.item.text), 1),
2997
3177
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
2998
3178
  default: vue.withCtx(() => [
@@ -3004,11 +3184,11 @@
3004
3184
  ]),
3005
3185
  _: 1
3006
3186
  }, 8, ["disabled", "onCommand"])) : _ctx.item.type === "component" ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.item.component), vue.normalizeProps(vue.mergeProps({ key: 5 }, _ctx.item.props || {})), null, 16)) : vue.createCommentVNode("", true)
3007
- ])) : vue.createCommentVNode("", true);
3187
+ ], 34)) : vue.createCommentVNode("", true);
3008
3188
  }
3009
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3189
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
3010
3190
 
3011
- const _sfc_main$b = vue.defineComponent({
3191
+ const _sfc_main$c = vue.defineComponent({
3012
3192
  name: "nav-menu",
3013
3193
  components: { ToolButton },
3014
3194
  props: {
@@ -3028,7 +3208,7 @@
3028
3208
  };
3029
3209
  }
3030
3210
  });
3031
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3211
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3032
3212
  const _component_tool_button = vue.resolveComponent("tool-button");
3033
3213
  return vue.openBlock(), vue.createElementBlock("div", {
3034
3214
  class: "m-editor-nav-menu",
@@ -3050,9 +3230,9 @@
3050
3230
  }), 128))
3051
3231
  ], 4);
3052
3232
  }
3053
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3233
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3054
3234
 
3055
- const _sfc_main$a = vue.defineComponent({
3235
+ const _sfc_main$b = vue.defineComponent({
3056
3236
  name: "m-editor-props-panel",
3057
3237
  emits: ["mounted"],
3058
3238
  setup(props, { emit }) {
@@ -3067,9 +3247,9 @@
3067
3247
  curFormConfig.value = [];
3068
3248
  return;
3069
3249
  }
3070
- values.value = node.value;
3071
3250
  const type = node.value.type || (node.value.items ? "container" : "text");
3072
3251
  curFormConfig.value = await services?.propsService.getPropsConfig(type) || [];
3252
+ values.value = node.value;
3073
3253
  };
3074
3254
  vue.watchEffect(init);
3075
3255
  services?.propsService.on("props-configs-change", init);
@@ -3098,7 +3278,7 @@
3098
3278
  };
3099
3279
  }
3100
3280
  });
3101
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3281
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3102
3282
  const _component_m_form = vue.resolveComponent("m-form");
3103
3283
  return vue.openBlock(), vue.createBlock(_component_m_form, {
3104
3284
  class: "m-editor-props-panel",
@@ -3110,9 +3290,9 @@
3110
3290
  onChange: _ctx.submit
3111
3291
  }, null, 8, ["init-values", "config", "onChange"]);
3112
3292
  }
3113
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3293
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3114
3294
 
3115
- const _sfc_main$9 = vue.defineComponent({
3295
+ const _sfc_main$a = vue.defineComponent({
3116
3296
  name: "ui-component-panel",
3117
3297
  components: { MIcon },
3118
3298
  setup() {
@@ -3127,19 +3307,29 @@
3127
3307
  searchText,
3128
3308
  collapseValue,
3129
3309
  list,
3130
- appendComponent({ text, type, ...config }) {
3310
+ appendComponent({ text, type, data = {} }) {
3131
3311
  services?.editorService.add({
3132
3312
  name: text,
3133
3313
  type,
3134
- ...config
3314
+ ...data
3135
3315
  });
3316
+ },
3317
+ dragstartHandler({ text, type, data = {} }, e) {
3318
+ if (e.dataTransfer) {
3319
+ e.dataTransfer.effectAllowed = "move";
3320
+ e.dataTransfer.setData("data", serialize__default["default"]({
3321
+ name: text,
3322
+ type,
3323
+ ...data
3324
+ }).replace(/"(\w+)":\s/g, "$1: "));
3325
+ }
3136
3326
  }
3137
3327
  };
3138
3328
  }
3139
3329
  });
3140
- const _hoisted_1$7 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3141
- const _hoisted_2$3 = ["onClick"];
3142
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3330
+ const _hoisted_1$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3331
+ const _hoisted_2$1 = ["onClick", "onDragstart"];
3332
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3143
3333
  const _component_el_input = vue.resolveComponent("el-input");
3144
3334
  const _component_m_icon = vue.resolveComponent("m-icon");
3145
3335
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -3169,15 +3359,17 @@
3169
3359
  name: index
3170
3360
  }, {
3171
3361
  title: vue.withCtx(() => [
3172
- _hoisted_1$7,
3362
+ _hoisted_1$5,
3173
3363
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
3174
3364
  ]),
3175
3365
  default: vue.withCtx(() => [
3176
3366
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(group.items, (item) => {
3177
3367
  return vue.openBlock(), vue.createElementBlock("div", {
3178
3368
  class: "component-item",
3369
+ draggable: "true",
3179
3370
  key: item.type,
3180
- onClick: ($event) => _ctx.appendComponent(item)
3371
+ onClick: ($event) => _ctx.appendComponent(item),
3372
+ onDragstart: ($event) => _ctx.dragstartHandler(item, $event)
3181
3373
  }, [
3182
3374
  vue.createVNode(_component_m_icon, {
3183
3375
  icon: item.icon
@@ -3192,7 +3384,7 @@
3192
3384
  ]),
3193
3385
  _: 2
3194
3386
  }, 1032, ["content"])
3195
- ], 8, _hoisted_2$3);
3387
+ ], 40, _hoisted_2$1);
3196
3388
  }), 128))
3197
3389
  ]),
3198
3390
  _: 2
@@ -3206,97 +3398,194 @@
3206
3398
  _: 1
3207
3399
  });
3208
3400
  }
3209
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3401
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3402
+
3403
+ const _sfc_main$9 = vue.defineComponent({
3404
+ components: { ToolButton },
3405
+ props: {
3406
+ menuData: {
3407
+ type: Array,
3408
+ default: () => []
3409
+ }
3410
+ },
3411
+ setup() {
3412
+ const menu = vue.ref();
3413
+ const subMenu = vue.ref();
3414
+ const visible = vue.ref(false);
3415
+ const subMenuData = vue.ref([]);
3416
+ const menuStyle = vue.ref({
3417
+ left: "0",
3418
+ top: "0"
3419
+ });
3420
+ const hide = () => {
3421
+ visible.value = false;
3422
+ };
3423
+ vue.onMounted(() => {
3424
+ globalThis.addEventListener("mousedown", (e) => {
3425
+ if (!visible.value || e.target && menu.value?.contains(e.target)) {
3426
+ return;
3427
+ }
3428
+ hide();
3429
+ }, true);
3430
+ });
3431
+ return {
3432
+ menu,
3433
+ subMenu,
3434
+ visible,
3435
+ menuStyle,
3436
+ subMenuData,
3437
+ hide,
3438
+ show(e) {
3439
+ visible.value = true;
3440
+ vue.nextTick(() => {
3441
+ const menuHeight = menu.value?.clientHeight || 0;
3442
+ let top = e.clientY;
3443
+ if (menuHeight + e.clientY > document.body.clientHeight) {
3444
+ top = document.body.clientHeight - menuHeight;
3445
+ }
3446
+ menuStyle.value = {
3447
+ top: `${top}px`,
3448
+ left: `${e.clientX}px`
3449
+ };
3450
+ });
3451
+ },
3452
+ showSubMenu(item) {
3453
+ const menuItem = item;
3454
+ if (typeof item !== "object" || !menuItem.items?.length) {
3455
+ return;
3456
+ }
3457
+ subMenuData.value = menuItem.items;
3458
+ if (menu.value) {
3459
+ subMenu.value.show({
3460
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
3461
+ clientY: menu.value.offsetTop
3462
+ });
3463
+ }
3464
+ }
3465
+ };
3466
+ }
3467
+ });
3468
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3469
+ const _component_tool_button = vue.resolveComponent("tool-button");
3470
+ const _component_content_menu = vue.resolveComponent("content-menu", true);
3471
+ return _ctx.menuData.length ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", {
3472
+ key: 0,
3473
+ class: "magic-editor-content-menu",
3474
+ ref: "menu",
3475
+ style: vue.normalizeStyle(_ctx.menuStyle)
3476
+ }, [
3477
+ vue.createElementVNode("div", null, [
3478
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.menuData, (item, index) => {
3479
+ return vue.openBlock(), vue.createBlock(_component_tool_button, {
3480
+ "event-type": "mouseup",
3481
+ data: item,
3482
+ key: index,
3483
+ onMouseup: _ctx.hide,
3484
+ onMouseenter: ($event) => _ctx.showSubMenu(item)
3485
+ }, null, 8, ["data", "onMouseup", "onMouseenter"]);
3486
+ }), 128))
3487
+ ]),
3488
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3489
+ vue.createVNode(_component_content_menu, {
3490
+ class: "sub-menu",
3491
+ ref: "subMenu",
3492
+ "menu-data": _ctx.subMenuData
3493
+ }, null, 8, ["menu-data"])
3494
+ ]))
3495
+ ], 4)), [
3496
+ [vue.vShow, _ctx.visible]
3497
+ ]) : vue.createCommentVNode("", true);
3498
+ }
3499
+ var ContentMenu = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3210
3500
 
3211
3501
  const _sfc_main$8 = vue.defineComponent({
3212
- name: "magic-editor-content-menu",
3502
+ components: { ContentMenu },
3213
3503
  setup() {
3214
3504
  const services = vue.inject("services");
3215
- const subVisible = vue.ref(false);
3505
+ const menu = vue.ref();
3216
3506
  const node = vue.computed(() => services?.editorService.get("node"));
3217
- return {
3218
- subVisible,
3219
- node,
3220
- componentGroupList: vue.computed(() => services?.componentListService.getList()),
3221
- append(config) {
3507
+ const isRoot = vue.computed(() => node.value?.type === schema.NodeType.ROOT);
3508
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
3509
+ const componentList = vue.computed(() => services?.componentListService.getList() || []);
3510
+ const createMenuItems = (group) => group.items.map((component) => ({
3511
+ text: component.text,
3512
+ type: "button",
3513
+ icon: component.icon,
3514
+ handler: () => {
3222
3515
  services?.editorService.add({
3223
- name: config.text,
3224
- type: config.type
3516
+ name: component.text,
3517
+ type: component.type,
3518
+ ...component.data || {}
3225
3519
  });
3226
- },
3227
- remove() {
3228
- node.value && services?.editorService.remove(node.value);
3229
- },
3230
- copy(node2) {
3231
- node2 && services?.editorService.copy(node2);
3232
- },
3233
- setSubVisitable(v) {
3234
- subVisible.value = v;
3520
+ }
3521
+ }));
3522
+ const getSubMenuData = vue.computed(() => {
3523
+ if (node.value?.type === "tabs") {
3524
+ return [
3525
+ {
3526
+ text: "\u6807\u7B7E\u9875",
3527
+ type: "button",
3528
+ icon: icons.Files,
3529
+ handler: () => {
3530
+ services?.editorService.add({
3531
+ type: "tab-pane"
3532
+ });
3533
+ }
3534
+ }
3535
+ ];
3536
+ }
3537
+ if (node.value?.items) {
3538
+ return componentList.value.reduce((subMenuData, group, index) => subMenuData.concat(createMenuItems(group), index < componentList.value.length - 1 ? [
3539
+ {
3540
+ type: "divider",
3541
+ direction: "horizontal"
3542
+ }
3543
+ ] : []), []) || [];
3544
+ }
3545
+ return [];
3546
+ });
3547
+ return {
3548
+ menu,
3549
+ menuData: vue.computed(() => [
3550
+ {
3551
+ type: "button",
3552
+ text: "\u65B0\u589E",
3553
+ icon: vue.markRaw(icons.Plus),
3554
+ display: () => node.value?.items,
3555
+ items: getSubMenuData.value
3556
+ },
3557
+ {
3558
+ type: "button",
3559
+ text: "\u590D\u5236",
3560
+ icon: vue.markRaw(icons.DocumentCopy),
3561
+ display: () => !isRoot.value,
3562
+ handler: () => {
3563
+ node.value && services?.editorService.copy(node.value);
3564
+ }
3565
+ },
3566
+ {
3567
+ type: "button",
3568
+ text: "\u5220\u9664",
3569
+ icon: vue.markRaw(icons.Delete),
3570
+ display: () => !isRoot.value && !isPage.value,
3571
+ handler: () => {
3572
+ node.value && services?.editorService.remove(node.value);
3573
+ }
3574
+ }
3575
+ ]),
3576
+ show(e) {
3577
+ menu.value?.show(e);
3235
3578
  }
3236
3579
  };
3237
3580
  }
3238
3581
  });
3239
- const _hoisted_1$6 = {
3240
- key: 0,
3241
- class: "magic-editor-content-menu"
3242
- };
3243
- const _hoisted_2$2 = ["onClick"];
3244
- const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3245
3582
  function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3246
- const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
3247
- return _ctx.node ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
3248
- _ctx.node.items ? (vue.openBlock(), vue.createElementBlock("div", {
3249
- key: 0,
3250
- class: "magic-editor-content-menu-item",
3251
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisitable(true)),
3252
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisitable(false))
3253
- }, " \u65B0\u589E ", 32)) : vue.createCommentVNode("", true),
3254
- _ctx.node.type !== "app" ? (vue.openBlock(), vue.createElementBlock("div", {
3255
- key: 1,
3256
- class: "magic-editor-content-menu-item",
3257
- onClick: _cache[2] || (_cache[2] = () => _ctx.copy(_ctx.node))
3258
- }, "\u590D\u5236")) : vue.createCommentVNode("", true),
3259
- _ctx.node.type !== "app" && _ctx.node.type !== "page" ? (vue.openBlock(), vue.createElementBlock("div", {
3260
- key: 2,
3261
- class: "magic-editor-content-menu-item",
3262
- onClick: _cache[3] || (_cache[3] = () => _ctx.remove())
3263
- }, " \u5220\u9664 ")) : vue.createCommentVNode("", true),
3264
- vue.withDirectives(vue.createElementVNode("div", {
3265
- class: "subMenu",
3266
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisitable(true)),
3267
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisitable(false))
3268
- }, [
3269
- vue.createVNode(_component_el_scrollbar, null, {
3270
- default: vue.withCtx(() => [
3271
- _ctx.node.type === "tabs" ? (vue.openBlock(), vue.createElementBlock("div", {
3272
- key: 0,
3273
- class: "magic-editor-content-menu-item",
3274
- onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3275
- type: "tab-pane"
3276
- }))
3277
- }, " \u6807\u7B7E ")) : _ctx.node.items ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.componentGroupList, (list) => {
3278
- return vue.openBlock(), vue.createElementBlock("div", {
3279
- key: list.title
3280
- }, [
3281
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(list.items, (item) => {
3282
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
3283
- item ? (vue.openBlock(), vue.createElementBlock("div", {
3284
- class: "magic-editor-content-menu-item",
3285
- key: item.type,
3286
- onClick: () => _ctx.append(item)
3287
- }, vue.toDisplayString(item.text), 9, _hoisted_2$2)) : vue.createCommentVNode("", true)
3288
- ], 64);
3289
- }), 256)),
3290
- _hoisted_3$2
3291
- ]);
3292
- }), 128)) : vue.createCommentVNode("", true)
3293
- ]),
3294
- _: 1
3295
- })
3296
- ], 544), [
3297
- [vue.vShow, _ctx.subVisible]
3298
- ])
3299
- ])) : vue.createCommentVNode("", true);
3583
+ const _component_content_menu = vue.resolveComponent("content-menu");
3584
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
3585
+ "menu-data": _ctx.menuData,
3586
+ ref: "menu",
3587
+ style: { "overflow": "initial" }
3588
+ }, null, 8, ["menu-data"]);
3300
3589
  }
3301
3590
  var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3302
3591
 
@@ -3390,56 +3679,37 @@
3390
3679
  tree.value?.filter(val);
3391
3680
  }
3392
3681
  });
3393
- const useContentMenu = (editorService) => {
3394
- const menuStyle = vue.ref({
3395
- position: "absolute",
3396
- left: "0",
3397
- top: "0",
3398
- display: "none"
3399
- });
3400
- vue.onMounted(() => {
3401
- document.addEventListener("click", () => {
3402
- menuStyle.value.display = "none";
3403
- }, true);
3404
- });
3405
- return {
3406
- menuStyle,
3407
- contextmenu(event, data) {
3408
- const bodyHeight = globalThis.document.body.clientHeight;
3409
- const left = `${event.clientX + 20}px`;
3410
- let top = `${event.clientY - 10}px`;
3411
- if (event.clientY + 300 > bodyHeight) {
3412
- top = `${bodyHeight - 300}px`;
3413
- }
3414
- menuStyle.value.left = left;
3415
- menuStyle.value.top = top;
3416
- menuStyle.value.display = "";
3417
- select(data, editorService);
3418
- }
3419
- };
3420
- };
3421
3682
  const _sfc_main$7 = vue.defineComponent({
3422
3683
  name: "magic-editor-layer-panel",
3423
3684
  components: { LayerMenu },
3424
3685
  setup() {
3425
3686
  const services = vue.inject("services");
3426
3687
  const tree = vue.ref();
3688
+ const menu = vue.ref();
3427
3689
  const clicked = vue.ref(false);
3428
3690
  const editorService = services?.editorService;
3429
3691
  const highlightHandler = lodashEs.throttle((data) => {
3430
3692
  highlight(data, editorService);
3431
3693
  }, throttleTime);
3432
- const toogleClickFlag = () => {
3694
+ const toggleClickFlag = () => {
3433
3695
  clicked.value = !clicked.value;
3434
3696
  };
3435
3697
  const statusData = useStatus(tree, editorService);
3436
3698
  const canHighlight = vue.computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3699
+ editorService?.on("remove", () => {
3700
+ setTimeout(() => {
3701
+ tree.value?.getNode(editorService.get("node").id)?.updateChildren();
3702
+ }, 0);
3703
+ });
3437
3704
  return {
3438
3705
  tree,
3706
+ menu,
3439
3707
  ...statusData,
3440
3708
  ...useDrop(tree, editorService),
3441
3709
  ...useFilter(tree),
3442
- ...useContentMenu(editorService),
3710
+ highlightHandler,
3711
+ toggleClickFlag,
3712
+ canHighlight,
3443
3713
  clickHandler(data) {
3444
3714
  if (services?.uiService.get("uiSelectMode")) {
3445
3715
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
@@ -3448,13 +3718,15 @@
3448
3718
  tree.value?.setCurrentKey(data.id);
3449
3719
  select(data, editorService);
3450
3720
  },
3451
- highlightHandler,
3452
- toogleClickFlag,
3453
- canHighlight
3721
+ async contextmenu(event, data) {
3722
+ event.preventDefault();
3723
+ await select(data, editorService);
3724
+ menu.value?.show(event);
3725
+ }
3454
3726
  };
3455
3727
  }
3456
3728
  });
3457
- const _hoisted_1$5 = ["id", "onMouseenter"];
3729
+ const _hoisted_1$4 = ["id", "onMouseenter"];
3458
3730
  function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3459
3731
  const _component_el_input = vue.resolveComponent("el-input");
3460
3732
  const _component_el_tree = vue.resolveComponent("el-tree");
@@ -3495,8 +3767,8 @@
3495
3767
  vue.createElementVNode("div", {
3496
3768
  id: data.id,
3497
3769
  class: vue.normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3498
- onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3499
- onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3770
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3771
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3500
3772
  onMouseenter: ($event) => _ctx.highlightHandler(data)
3501
3773
  }, [
3502
3774
  vue.renderSlot(_ctx.$slots, "layer-node-content", {
@@ -3505,14 +3777,12 @@
3505
3777
  }, () => [
3506
3778
  vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3507
3779
  ])
3508
- ], 42, _hoisted_1$5)
3780
+ ], 42, _hoisted_1$4)
3509
3781
  ]),
3510
3782
  _: 3
3511
3783
  }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3512
3784
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3513
- vue.createVNode(_component_layer_menu, {
3514
- style: vue.normalizeStyle(_ctx.menuStyle)
3515
- }, null, 8, ["style"])
3785
+ vue.createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
3516
3786
  ]))
3517
3787
  ]),
3518
3788
  _: 3
@@ -3564,7 +3834,7 @@
3564
3834
  };
3565
3835
  }
3566
3836
  });
3567
- const _hoisted_1$4 = {
3837
+ const _hoisted_1$3 = {
3568
3838
  key: 1,
3569
3839
  class: "magic-editor-tab-panel-title"
3570
3840
  };
@@ -3592,7 +3862,7 @@
3592
3862
  key: 0,
3593
3863
  icon: item.icon
3594
3864
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3595
- item.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, vue.toDisplayString(item.text), 1)) : vue.createCommentVNode("", true)
3865
+ item.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, vue.toDisplayString(item.text), 1)) : vue.createCommentVNode("", true)
3596
3866
  ])
3597
3867
  ]),
3598
3868
  default: vue.withCtx(() => [
@@ -3682,12 +3952,14 @@
3682
3952
  };
3683
3953
  };
3684
3954
  const _sfc_main$5 = vue.defineComponent({
3685
- components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus },
3955
+ components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus, ToolButton },
3686
3956
  setup() {
3687
3957
  const services = vue.inject("services");
3688
3958
  const editorService = services?.editorService;
3689
3959
  const root = vue.computed(() => editorService?.get("root"));
3690
3960
  return {
3961
+ Delete: vue.markRaw(icons.Delete),
3962
+ DocumentCopy: vue.markRaw(icons.DocumentCopy),
3691
3963
  ...useScroll(root),
3692
3964
  root,
3693
3965
  page: vue.computed(() => editorService?.get("page")),
@@ -3716,23 +3988,22 @@
3716
3988
  };
3717
3989
  }
3718
3990
  });
3719
- const _hoisted_1$3 = {
3991
+ const _hoisted_1$2 = {
3720
3992
  class: "m-editor-page-bar",
3721
3993
  ref: "pageBar"
3722
3994
  };
3723
- const _hoisted_2$1 = ["onClick"];
3724
- const _hoisted_3$1 = { class: "m-editor-page-bar-title" };
3725
- const _hoisted_4$1 = ["onClick"];
3726
- const _hoisted_5 = ["onClick"];
3995
+ const _hoisted_2 = ["onClick"];
3996
+ const _hoisted_3 = { class: "m-editor-page-bar-title" };
3727
3997
  function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3728
3998
  const _component_plus = vue.resolveComponent("plus");
3729
3999
  const _component_el_icon = vue.resolveComponent("el-icon");
3730
4000
  const _component_arrow_left_bold = vue.resolveComponent("arrow-left-bold");
3731
4001
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
4002
+ const _component_tool_button = vue.resolveComponent("tool-button");
3732
4003
  const _component_caret_bottom = vue.resolveComponent("caret-bottom");
3733
4004
  const _component_el_popover = vue.resolveComponent("el-popover");
3734
4005
  const _component_arrow_right_bold = vue.resolveComponent("arrow-right-bold");
3735
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
4006
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
3736
4007
  vue.createElementVNode("div", {
3737
4008
  id: "m-editor-page-bar-add-icon",
3738
4009
  class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
@@ -3769,7 +4040,7 @@
3769
4040
  class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3770
4041
  onClick: ($event) => _ctx.switchPage(item)
3771
4042
  }, [
3772
- vue.createElementVNode("div", _hoisted_3$1, [
4043
+ vue.createElementVNode("div", _hoisted_3, [
3773
4044
  vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3774
4045
  vue.createVNode(_component_el_tooltip, {
3775
4046
  effect: "dark",
@@ -3784,6 +4055,7 @@
3784
4055
  ])
3785
4056
  ]),
3786
4057
  vue.createVNode(_component_el_popover, {
4058
+ "popper-class": "page-bar-popover",
3787
4059
  placement: "top",
3788
4060
  width: 160,
3789
4061
  trigger: "hover"
@@ -3799,20 +4071,28 @@
3799
4071
  default: vue.withCtx(() => [
3800
4072
  vue.createElementVNode("div", null, [
3801
4073
  vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3802
- vue.createElementVNode("div", {
3803
- class: "magic-editor-content-menu-item",
3804
- onClick: () => _ctx.copy(item)
3805
- }, "\u590D\u5236", 8, _hoisted_4$1),
3806
- vue.createElementVNode("div", {
3807
- class: "magic-editor-content-menu-item",
3808
- onClick: () => _ctx.remove(item)
3809
- }, "\u5220\u9664", 8, _hoisted_5)
4074
+ vue.createVNode(_component_tool_button, {
4075
+ data: {
4076
+ type: "button",
4077
+ text: "\u590D\u5236",
4078
+ icon: _ctx.DocumentCopy,
4079
+ handler: () => _ctx.copy(item)
4080
+ }
4081
+ }, null, 8, ["data"]),
4082
+ vue.createVNode(_component_tool_button, {
4083
+ data: {
4084
+ type: "button",
4085
+ text: "\u5220\u9664",
4086
+ icon: _ctx.Delete,
4087
+ handler: () => _ctx.remove(item)
4088
+ }
4089
+ }, null, 8, ["data"])
3810
4090
  ])
3811
4091
  ])
3812
4092
  ]),
3813
4093
  _: 2
3814
4094
  }, 1024)
3815
- ], 10, _hoisted_2$1);
4095
+ ], 10, _hoisted_2);
3816
4096
  }), 128))
3817
4097
  ], 4)) : vue.createCommentVNode("", true),
3818
4098
  _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -3832,33 +4112,104 @@
3832
4112
  var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3833
4113
 
3834
4114
  class ScrollViewer$1 {
3835
- enter = false;
3836
- targetEnter = false;
3837
- keydown = false;
3838
- container;
3839
- target;
3840
- zoom = 1;
3841
- scrollLeft = 0;
3842
- scrollTop = 0;
3843
- x = 0;
3844
- y = 0;
3845
- resizeObserver = new ResizeObserver((entries) => {
3846
- for (const { contentRect } of entries) {
3847
- const { width, height } = contentRect;
3848
- const targetRect = this.target.getBoundingClientRect();
3849
- const targetWidth = targetRect.width * this.zoom;
3850
- const targetMarginTop = Number(this.target.style.marginTop) || 0;
3851
- const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3852
- if (targetWidth < width) {
3853
- this.target._left = 0;
3854
- }
3855
- if (targetHeight < height) {
3856
- this.target._top = 0;
4115
+ constructor(options) {
4116
+ this.enter = false;
4117
+ this.targetEnter = false;
4118
+ this.keydown = false;
4119
+ this.zoom = 1;
4120
+ this.scrollLeft = 0;
4121
+ this.scrollTop = 0;
4122
+ this.x = 0;
4123
+ this.y = 0;
4124
+ this.resizeObserver = new ResizeObserver((entries) => {
4125
+ for (const { contentRect } of entries) {
4126
+ const { width, height } = contentRect;
4127
+ const targetRect = this.target.getBoundingClientRect();
4128
+ const targetWidth = targetRect.width * this.zoom;
4129
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
4130
+ const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
4131
+ if (targetWidth < width) {
4132
+ this.target._left = 0;
4133
+ }
4134
+ if (targetHeight < height) {
4135
+ this.target._top = 0;
4136
+ }
4137
+ this.scroll();
3857
4138
  }
4139
+ });
4140
+ this.wheelHandler = (event) => {
4141
+ if (this.targetEnter)
4142
+ return;
4143
+ const { deltaX, deltaY, currentTarget } = event;
4144
+ if (currentTarget !== this.container)
4145
+ return;
4146
+ this.setScrollOffset(deltaX, deltaY);
3858
4147
  this.scroll();
3859
- }
3860
- });
3861
- constructor(options) {
4148
+ this.scrollLeft = this.target._left;
4149
+ this.scrollTop = this.target._top;
4150
+ };
4151
+ this.mouseEnterHandler = () => {
4152
+ this.enter = true;
4153
+ };
4154
+ this.mouseLeaveHandler = () => {
4155
+ this.enter = false;
4156
+ };
4157
+ this.targetMouseEnterHandler = () => {
4158
+ this.targetEnter = true;
4159
+ };
4160
+ this.targetMouseLeaveHandler = () => {
4161
+ this.targetEnter = false;
4162
+ };
4163
+ this.mousedownHandler = (event) => {
4164
+ if (!this.keydown)
4165
+ return;
4166
+ event.stopImmediatePropagation();
4167
+ event.stopPropagation();
4168
+ this.target.style.cursor = "grabbing";
4169
+ this.x = event.clientX;
4170
+ this.y = event.clientY;
4171
+ document.addEventListener("mousemove", this.mousemoveHandler);
4172
+ document.addEventListener("mouseup", this.mouseupHandler);
4173
+ };
4174
+ this.mouseupHandler = () => {
4175
+ this.x = 0;
4176
+ this.y = 0;
4177
+ this.scrollLeft = this.target._left;
4178
+ this.scrollTop = this.target._top;
4179
+ this.removeHandler();
4180
+ };
4181
+ this.mousemoveHandler = (event) => {
4182
+ event.stopImmediatePropagation();
4183
+ event.stopPropagation();
4184
+ const deltaX = event.clientX - this.x;
4185
+ const deltaY = event.clientY - this.y;
4186
+ this.setScrollOffset(deltaX, deltaY);
4187
+ this.scroll();
4188
+ };
4189
+ this.keydownHandler = (event) => {
4190
+ if (event.code === Keys.ESCAPE && this.enter) {
4191
+ event.preventDefault();
4192
+ event.stopImmediatePropagation();
4193
+ event.stopPropagation();
4194
+ }
4195
+ if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
4196
+ return;
4197
+ }
4198
+ this.keydown = true;
4199
+ this.target.style.cursor = "grab";
4200
+ this.container.addEventListener("mousedown", this.mousedownHandler);
4201
+ };
4202
+ this.keyupHandler = (event) => {
4203
+ if (event.code !== Keys.ESCAPE || !this.keydown) {
4204
+ return;
4205
+ }
4206
+ event.preventDefault();
4207
+ event.stopImmediatePropagation();
4208
+ event.stopPropagation();
4209
+ this.keydown = false;
4210
+ event.preventDefault();
4211
+ this.removeHandler();
4212
+ };
3862
4213
  this.container = options.container;
3863
4214
  this.target = options.target;
3864
4215
  this.zoom = options.zoom;
@@ -3894,79 +4245,6 @@
3894
4245
  document.removeEventListener("mousemove", this.mousemoveHandler);
3895
4246
  document.removeEventListener("mouseup", this.mouseupHandler);
3896
4247
  }
3897
- wheelHandler = (event) => {
3898
- if (this.targetEnter)
3899
- return;
3900
- const { deltaX, deltaY, currentTarget } = event;
3901
- if (currentTarget !== this.container)
3902
- return;
3903
- this.setScrollOffset(deltaX, deltaY);
3904
- this.scroll();
3905
- this.scrollLeft = this.target._left;
3906
- this.scrollTop = this.target._top;
3907
- };
3908
- mouseEnterHandler = () => {
3909
- this.enter = true;
3910
- };
3911
- mouseLeaveHandler = () => {
3912
- this.enter = false;
3913
- };
3914
- targetMouseEnterHandler = () => {
3915
- this.targetEnter = true;
3916
- };
3917
- targetMouseLeaveHandler = () => {
3918
- this.targetEnter = false;
3919
- };
3920
- mousedownHandler = (event) => {
3921
- if (!this.keydown)
3922
- return;
3923
- event.stopImmediatePropagation();
3924
- event.stopPropagation();
3925
- this.target.style.cursor = "grabbing";
3926
- this.x = event.clientX;
3927
- this.y = event.clientY;
3928
- document.addEventListener("mousemove", this.mousemoveHandler);
3929
- document.addEventListener("mouseup", this.mouseupHandler);
3930
- };
3931
- mouseupHandler = () => {
3932
- this.x = 0;
3933
- this.y = 0;
3934
- this.scrollLeft = this.target._left;
3935
- this.scrollTop = this.target._top;
3936
- this.removeHandler();
3937
- };
3938
- mousemoveHandler = (event) => {
3939
- event.stopImmediatePropagation();
3940
- event.stopPropagation();
3941
- const deltaX = event.clientX - this.x;
3942
- const deltaY = event.clientY - this.y;
3943
- this.setScrollOffset(deltaX, deltaY);
3944
- this.scroll();
3945
- };
3946
- keydownHandler = (event) => {
3947
- if (event.code === Keys.ESCAPE && this.enter) {
3948
- event.preventDefault();
3949
- event.stopImmediatePropagation();
3950
- event.stopPropagation();
3951
- }
3952
- if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3953
- return;
3954
- }
3955
- this.keydown = true;
3956
- this.target.style.cursor = "grab";
3957
- this.container.addEventListener("mousedown", this.mousedownHandler);
3958
- };
3959
- keyupHandler = (event) => {
3960
- if (event.code !== Keys.ESCAPE || !this.keydown) {
3961
- return;
3962
- }
3963
- event.preventDefault();
3964
- event.stopImmediatePropagation();
3965
- event.stopPropagation();
3966
- this.keydown = false;
3967
- event.preventDefault();
3968
- this.removeHandler();
3969
- };
3970
4248
  setScrollOffset(deltaX, deltaY) {
3971
4249
  const { width, height } = this.container.getBoundingClientRect();
3972
4250
  const targetRect = this.target.getBoundingClientRect();
@@ -4027,19 +4305,19 @@
4027
4305
  el,
4028
4306
  style: vue.computed(() => `
4029
4307
  width: ${props.width}px;
4030
- height: ${props.height}px;
4308
+ height: ${(props.height || 0) - 40}px;
4031
4309
  position: absolute;
4032
4310
  margin-top: 30px;
4033
4311
  `)
4034
4312
  };
4035
4313
  }
4036
4314
  });
4037
- const _hoisted_1$2 = {
4315
+ const _hoisted_1$1 = {
4038
4316
  class: "m-editor-scroll-viewer-container",
4039
4317
  ref: "container"
4040
4318
  };
4041
4319
  function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
4042
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
4320
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
4043
4321
  vue.createElementVNode("div", {
4044
4322
  ref: "el",
4045
4323
  style: vue.normalizeStyle(_ctx.style)
@@ -4051,7 +4329,7 @@
4051
4329
  var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
4052
4330
 
4053
4331
  const _sfc_main$3 = vue.defineComponent({
4054
- name: "magic-editor-ui-viewer-menu",
4332
+ components: { ContentMenu },
4055
4333
  setup() {
4056
4334
  const services = vue.inject("services");
4057
4335
  const editorService = services?.editorService;
@@ -4060,6 +4338,7 @@
4060
4338
  const canCenter = vue.ref(false);
4061
4339
  const node = vue.computed(() => editorService?.get("node"));
4062
4340
  const parent = vue.computed(() => editorService?.get("parent"));
4341
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
4063
4342
  vue.onMounted(() => {
4064
4343
  const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
4065
4344
  canPaste.value = data !== "undefined" && !!data;
@@ -4072,133 +4351,114 @@
4072
4351
  }, { immediate: true });
4073
4352
  return {
4074
4353
  menu,
4075
- canPaste,
4076
- canDelete: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4077
- canMoveZPos: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4078
- canCenter,
4079
- center() {
4080
- node.value && editorService?.alignCenter(node.value);
4081
- },
4082
- copy() {
4083
- node.value && editorService?.copy(node.value);
4084
- canPaste.value = true;
4085
- },
4086
- paste() {
4087
- const top = menu.value?.offsetTop || 0;
4088
- const left = menu.value?.offsetLeft || 0;
4089
- editorService?.paste({ left, top });
4090
- },
4091
- remove() {
4092
- node.value && editorService?.remove(node.value);
4093
- },
4094
- top() {
4095
- editorService?.moveLayer(LayerOffset.TOP);
4096
- },
4097
- bottom() {
4098
- editorService?.moveLayer(LayerOffset.BOTTOM);
4099
- },
4100
- topItem() {
4101
- editorService?.moveLayer(1);
4102
- },
4103
- bottomItem() {
4104
- editorService?.moveLayer(-1);
4105
- },
4106
- clearGuides() {
4107
- editorService?.get("stage").clearGuides();
4354
+ menuData: vue.reactive([
4355
+ {
4356
+ type: "button",
4357
+ text: "\u6C34\u5E73\u5C45\u4E2D",
4358
+ display: () => canCenter.value,
4359
+ handler: () => {
4360
+ node.value && editorService?.alignCenter(node.value);
4361
+ }
4362
+ },
4363
+ {
4364
+ type: "button",
4365
+ text: "\u590D\u5236",
4366
+ icon: vue.markRaw(icons.DocumentCopy),
4367
+ handler: () => {
4368
+ node.value && editorService?.copy(node.value);
4369
+ canPaste.value = true;
4370
+ }
4371
+ },
4372
+ {
4373
+ type: "button",
4374
+ text: "\u7C98\u8D34",
4375
+ display: () => canPaste.value,
4376
+ handler: () => {
4377
+ const top = menu.value?.$el.offsetTop || 0;
4378
+ const left = menu.value?.$el.offsetLeft || 0;
4379
+ editorService?.paste({ left, top });
4380
+ }
4381
+ },
4382
+ {
4383
+ type: "divider",
4384
+ direction: "horizontal",
4385
+ display: () => !isPage.value
4386
+ },
4387
+ {
4388
+ type: "button",
4389
+ text: "\u4E0A\u79FB\u4E00\u5C42",
4390
+ icon: vue.markRaw(icons.Top),
4391
+ display: () => !isPage.value,
4392
+ handler: () => {
4393
+ editorService?.moveLayer(1);
4394
+ }
4395
+ },
4396
+ {
4397
+ type: "button",
4398
+ text: "\u4E0B\u79FB\u4E00\u5C42",
4399
+ icon: vue.markRaw(icons.Bottom),
4400
+ display: () => !isPage.value,
4401
+ handler: () => {
4402
+ editorService?.moveLayer(-1);
4403
+ }
4404
+ },
4405
+ {
4406
+ type: "button",
4407
+ text: "\u7F6E\u9876",
4408
+ display: () => !isPage.value,
4409
+ handler: () => {
4410
+ editorService?.moveLayer(LayerOffset.TOP);
4411
+ }
4412
+ },
4413
+ {
4414
+ type: "button",
4415
+ text: "\u7F6E\u5E95",
4416
+ display: () => !isPage.value,
4417
+ handler: () => {
4418
+ editorService?.moveLayer(LayerOffset.BOTTOM);
4419
+ }
4420
+ },
4421
+ {
4422
+ type: "divider",
4423
+ direction: "horizontal",
4424
+ display: () => !isPage.value
4425
+ },
4426
+ {
4427
+ type: "button",
4428
+ text: "\u5220\u9664",
4429
+ icon: icons.Delete,
4430
+ display: () => !isPage.value,
4431
+ handler: () => {
4432
+ node.value && editorService?.remove(node.value);
4433
+ }
4434
+ },
4435
+ {
4436
+ type: "divider",
4437
+ direction: "horizontal"
4438
+ },
4439
+ {
4440
+ type: "button",
4441
+ text: "\u6E05\u7A7A\u53C2\u8003\u7EBF",
4442
+ handler: () => {
4443
+ editorService?.get("stage").clearGuides();
4444
+ }
4445
+ }
4446
+ ]),
4447
+ show(e) {
4448
+ menu.value?.show(e);
4108
4449
  }
4109
4450
  };
4110
4451
  }
4111
4452
  });
4112
- const _hoisted_1$1 = {
4113
- class: "magic-editor-content-menu",
4114
- ref: "menu"
4115
- };
4116
- const _hoisted_2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4117
- const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4118
- const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4119
4453
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
4120
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
4121
- vue.createElementVNode("div", null, [
4122
- _ctx.canCenter ? (vue.openBlock(), vue.createElementBlock("div", {
4123
- key: 0,
4124
- class: "magic-editor-content-menu-item",
4125
- onClick: _cache[0] || (_cache[0] = () => _ctx.center())
4126
- }, "\u6C34\u5E73\u5C45\u4E2D")) : vue.createCommentVNode("", true),
4127
- vue.createElementVNode("div", {
4128
- class: "magic-editor-content-menu-item",
4129
- onClick: _cache[1] || (_cache[1] = () => _ctx.copy())
4130
- }, "\u590D\u5236"),
4131
- _ctx.canPaste ? (vue.openBlock(), vue.createElementBlock("div", {
4132
- key: 1,
4133
- class: "magic-editor-content-menu-item",
4134
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.paste && _ctx.paste(...args))
4135
- }, "\u7C98\u8D34")) : vue.createCommentVNode("", true),
4136
- _ctx.canMoveZPos ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
4137
- _hoisted_2,
4138
- vue.createElementVNode("div", {
4139
- class: "magic-editor-content-menu-item",
4140
- onClick: _cache[3] || (_cache[3] = (...args) => _ctx.topItem && _ctx.topItem(...args))
4141
- }, "\u4E0A\u79FB\u4E00\u5C42"),
4142
- vue.createElementVNode("div", {
4143
- class: "magic-editor-content-menu-item",
4144
- onClick: _cache[4] || (_cache[4] = (...args) => _ctx.bottomItem && _ctx.bottomItem(...args))
4145
- }, "\u4E0B\u79FB\u4E00\u5C42"),
4146
- vue.createElementVNode("div", {
4147
- class: "magic-editor-content-menu-item",
4148
- onClick: _cache[5] || (_cache[5] = (...args) => _ctx.top && _ctx.top(...args))
4149
- }, "\u7F6E\u9876"),
4150
- vue.createElementVNode("div", {
4151
- class: "magic-editor-content-menu-item",
4152
- onClick: _cache[6] || (_cache[6] = (...args) => _ctx.bottom && _ctx.bottom(...args))
4153
- }, "\u7F6E\u5E95")
4154
- ], 64)) : vue.createCommentVNode("", true),
4155
- _ctx.canDelete ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
4156
- _hoisted_3,
4157
- vue.createElementVNode("div", {
4158
- class: "magic-editor-content-menu-item",
4159
- onClick: _cache[7] || (_cache[7] = () => _ctx.remove())
4160
- }, "\u5220\u9664")
4161
- ], 64)) : vue.createCommentVNode("", true),
4162
- _hoisted_4,
4163
- vue.createElementVNode("div", {
4164
- class: "magic-editor-content-menu-item",
4165
- onClick: _cache[8] || (_cache[8] = (...args) => _ctx.clearGuides && _ctx.clearGuides(...args))
4166
- }, "\u6E05\u7A7A\u53C2\u8003\u7EBF")
4167
- ])
4168
- ], 512);
4454
+ const _component_content_menu = vue.resolveComponent("content-menu");
4455
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
4456
+ "menu-data": _ctx.menuData,
4457
+ ref: "menu"
4458
+ }, null, 8, ["menu-data"]);
4169
4459
  }
4170
4460
  var ViewerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
4171
4461
 
4172
- const useMenu = () => {
4173
- const menu = vue.ref();
4174
- const menuStyle = vue.ref({
4175
- display: "none",
4176
- left: "0",
4177
- top: "0"
4178
- });
4179
- vue.onMounted(() => {
4180
- document.addEventListener("click", () => {
4181
- menuStyle.value.display = "none";
4182
- }, true);
4183
- });
4184
- return {
4185
- menu,
4186
- menuStyle,
4187
- contextmenuHandler(e) {
4188
- e.preventDefault();
4189
- const menuHeight = menu.value?.$el.clientHeight;
4190
- let top = e.clientY;
4191
- if (menuHeight + e.clientY > document.body.clientHeight) {
4192
- top = document.body.clientHeight - menuHeight;
4193
- }
4194
- menuStyle.value = {
4195
- display: "block",
4196
- top: `${top}px`,
4197
- left: `${e.clientX}px`
4198
- };
4199
- }
4200
- };
4201
- };
4202
4462
  const _sfc_main$2 = vue.defineComponent({
4203
4463
  name: "magic-stage",
4204
4464
  components: {
@@ -4225,11 +4485,12 @@
4225
4485
  const services = vue.inject("services");
4226
4486
  const stageWrap = vue.ref();
4227
4487
  const stageContainer = vue.ref();
4488
+ const menu = vue.ref();
4228
4489
  const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
4229
4490
  const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4230
4491
  const root = vue.computed(() => services?.editorService.get("root"));
4231
4492
  const page = vue.computed(() => services?.editorService.get("page"));
4232
- const zoom = vue.computed(() => services?.uiService.get("zoom"));
4493
+ const zoom = vue.computed(() => services?.uiService.get("zoom") || 1);
4233
4494
  const node = vue.computed(() => services?.editorService.get("node"));
4234
4495
  let stage = null;
4235
4496
  let runtime = null;
@@ -4311,9 +4572,36 @@
4311
4572
  return {
4312
4573
  stageWrap,
4313
4574
  stageContainer,
4575
+ menu,
4314
4576
  stageRect,
4315
4577
  zoom,
4316
- ...useMenu()
4578
+ contextmenuHandler(e2) {
4579
+ e2.preventDefault();
4580
+ menu.value?.show(e2);
4581
+ },
4582
+ dragoverHandler(e2) {
4583
+ e2.preventDefault();
4584
+ if (e2.dataTransfer) {
4585
+ e2.dataTransfer.dropEffect = "move";
4586
+ }
4587
+ },
4588
+ async dropHandler(e) {
4589
+ e.preventDefault();
4590
+ if (e.dataTransfer && page.value && stageContainer.value && stage) {
4591
+ const config = eval(`(${e.dataTransfer.getData("data")})`);
4592
+ const layout = await services?.editorService.getLayout(page.value);
4593
+ const containerRect = stageContainer.value.getBoundingClientRect();
4594
+ const { scrollTop, scrollLeft } = stage.mask;
4595
+ if (layout === Layout.ABSOLUTE) {
4596
+ config.style = {
4597
+ position: "absolute",
4598
+ top: e.clientY - containerRect.top + scrollTop,
4599
+ left: e.clientX - containerRect.left + scrollLeft
4600
+ };
4601
+ }
4602
+ services?.editorService.add(config, page.value);
4603
+ }
4604
+ }
4317
4605
  };
4318
4606
  }
4319
4607
  });
@@ -4331,14 +4619,13 @@
4331
4619
  vue.createElementVNode("div", {
4332
4620
  class: "m-editor-stage-container",
4333
4621
  ref: "stageContainer",
4622
+ style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`),
4334
4623
  onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4335
- style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`)
4624
+ onDrop: _cache[1] || (_cache[1] = (...args) => _ctx.dropHandler && _ctx.dropHandler(...args)),
4625
+ onDragover: _cache[2] || (_cache[2] = (...args) => _ctx.dragoverHandler && _ctx.dragoverHandler(...args))
4336
4626
  }, null, 36),
4337
4627
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4338
- vue.createVNode(_component_viewer_menu, {
4339
- ref: "menu",
4340
- style: vue.normalizeStyle(_ctx.menuStyle)
4341
- }, null, 8, ["style"])
4628
+ vue.createVNode(_component_viewer_menu, { ref: "menu" }, null, 512)
4342
4629
  ]))
4343
4630
  ]),
4344
4631
  _: 1
@@ -4366,12 +4653,93 @@
4366
4653
  },
4367
4654
  setup() {
4368
4655
  const services = vue.inject("services");
4656
+ const workspace = vue.ref();
4657
+ const node = vue.computed(() => services?.editorService.get("node"));
4658
+ let keycon;
4659
+ const mouseenterHandler = () => {
4660
+ workspace.value?.focus();
4661
+ };
4662
+ vue.onMounted(() => {
4663
+ workspace.value?.addEventListener("mouseenter", mouseenterHandler);
4664
+ keycon = new KeyController__default["default"](workspace.value);
4665
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
4666
+ const ctrl = isMac ? "meta" : "ctrl";
4667
+ keycon.keyup("delete", (e) => {
4668
+ e.inputEvent.preventDefault();
4669
+ if (!node.value || utils.isPage(node.value))
4670
+ return;
4671
+ services?.editorService.remove(node.value);
4672
+ }).keydown([ctrl, "c"], (e) => {
4673
+ e.inputEvent.preventDefault();
4674
+ node.value && services?.editorService.copy(node.value);
4675
+ }).keydown([ctrl, "v"], (e) => {
4676
+ e.inputEvent.preventDefault();
4677
+ node.value && services?.editorService.paste();
4678
+ }).keydown([ctrl, "x"], (e) => {
4679
+ e.inputEvent.preventDefault();
4680
+ if (!node.value || utils.isPage(node.value))
4681
+ return;
4682
+ services?.editorService.copy(node.value);
4683
+ services?.editorService.remove(node.value);
4684
+ }).keydown([ctrl, "z"], (e) => {
4685
+ e.inputEvent.preventDefault();
4686
+ services?.editorService.undo();
4687
+ }).keydown([ctrl, "shift", "z"], (e) => {
4688
+ e.inputEvent.preventDefault();
4689
+ services?.editorService.redo();
4690
+ }).keydown("up", (e) => {
4691
+ e.inputEvent.preventDefault();
4692
+ services?.editorService.move(0, -1);
4693
+ }).keydown("down", (e) => {
4694
+ e.inputEvent.preventDefault();
4695
+ services?.editorService.move(0, 1);
4696
+ }).keydown("left", (e) => {
4697
+ e.inputEvent.preventDefault();
4698
+ services?.editorService.move(-1, 0);
4699
+ }).keydown("right", (e) => {
4700
+ e.inputEvent.preventDefault();
4701
+ services?.editorService.move(1, 0);
4702
+ }).keydown([ctrl, "up"], (e) => {
4703
+ e.inputEvent.preventDefault();
4704
+ services?.editorService.move(0, -10);
4705
+ }).keydown([ctrl, "down"], (e) => {
4706
+ e.inputEvent.preventDefault();
4707
+ services?.editorService.move(0, 10);
4708
+ }).keydown([ctrl, "left"], (e) => {
4709
+ e.inputEvent.preventDefault();
4710
+ services?.editorService.move(-10, 0);
4711
+ }).keydown([ctrl, "right"], (e) => {
4712
+ e.inputEvent.preventDefault();
4713
+ services?.editorService.move(10, 0);
4714
+ }).keydown("tab", (e) => {
4715
+ e.inputEvent.preventDefault();
4716
+ services?.editorService.selectNextNode();
4717
+ }).keydown([ctrl, "tab"], (e) => {
4718
+ e.inputEvent.preventDefault();
4719
+ services?.editorService.selectNextPage();
4720
+ }).keydown([ctrl, "="], (e) => {
4721
+ e.inputEvent.preventDefault();
4722
+ services?.uiService.zoom(0.1);
4723
+ }).keydown([ctrl, "-"], (e) => {
4724
+ e.inputEvent.preventDefault();
4725
+ services?.uiService.zoom(-0.1);
4726
+ });
4727
+ });
4728
+ vue.onUnmounted(() => {
4729
+ workspace.value?.removeEventListener("mouseenter", mouseenterHandler);
4730
+ keycon.destroy();
4731
+ });
4369
4732
  return {
4733
+ workspace,
4370
4734
  page: vue.computed(() => services?.editorService.get("page"))
4371
4735
  };
4372
4736
  }
4373
4737
  });
4374
- const _hoisted_1 = { class: "m-editor-workspace" };
4738
+ const _hoisted_1 = {
4739
+ class: "m-editor-workspace",
4740
+ tabindex: "1",
4741
+ ref: "workspace"
4742
+ };
4375
4743
  function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
4376
4744
  const _component_magic_stage = vue.resolveComponent("magic-stage");
4377
4745
  const _component_page_bar = vue.resolveComponent("page-bar");
@@ -4393,16 +4761,16 @@
4393
4761
  ]),
4394
4762
  _: 3
4395
4763
  })
4396
- ]);
4764
+ ], 512);
4397
4765
  }
4398
4766
  var Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
4399
4767
 
4400
4768
  class ComponentList extends BaseService {
4401
- state = vue.reactive({
4402
- list: []
4403
- });
4404
4769
  constructor() {
4405
4770
  super([]);
4771
+ this.state = vue.reactive({
4772
+ list: []
4773
+ });
4406
4774
  }
4407
4775
  setList(componentGroupList) {
4408
4776
  this.state.list = componentGroupList;
@@ -4468,6 +4836,11 @@
4468
4836
  get(name) {
4469
4837
  return state[name];
4470
4838
  }
4839
+ zoom(zoom) {
4840
+ this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
4841
+ if (this.get("zoom") < 0.1)
4842
+ this.set("zoom", 0.1);
4843
+ }
4471
4844
  setColumnWidth({ left, center, right }) {
4472
4845
  const columnWidth = {
4473
4846
  ...vue.toRaw(this.get("columnWidth"))
@@ -4692,6 +5065,7 @@
4692
5065
  exports.PropsPanel = PropsPanel;
4693
5066
  exports.TMagicCodeEditor = CodeEditor;
4694
5067
  exports.TMagicEditor = Editor;
5068
+ exports.ToolButton = ToolButton;
4695
5069
  exports.change2Fixed = change2Fixed;
4696
5070
  exports.debug = debug;
4697
5071
  exports["default"] = index;
@@ -4720,8 +5094,7 @@
4720
5094
  exports.uiService = uiService;
4721
5095
  exports.warn = warn;
4722
5096
 
4723
- Object.defineProperty(exports, '__esModule', { value: true });
4724
- exports[Symbol.toStringTag] = 'Module';
5097
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4725
5098
 
4726
5099
  }));
4727
5100
  //# sourceMappingURL=tmagic-editor.umd.js.map