@tmagic/editor 1.0.0-beta.13 → 1.0.0-beta.16

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 (101) hide show
  1. package/coverage/clover.xml +703 -601
  2. package/coverage/coverage-final.json +35 -33
  3. package/coverage/lcov-report/index.html +56 -56
  4. package/coverage/lcov-report/src/Editor.vue.html +1 -1
  5. package/coverage/lcov-report/{layouts/sidebar/LayerMenu.vue.html → src/components/ContentMenu.vue.html} +137 -95
  6. package/coverage/lcov-report/src/components/Icon.vue.html +5 -5
  7. package/coverage/lcov-report/src/components/ScrollViewer.vue.html +1 -1
  8. package/coverage/lcov-report/src/components/ToolButton.vue.html +180 -63
  9. package/coverage/lcov-report/src/components/index.html +34 -19
  10. package/coverage/lcov-report/src/index.html +1 -1
  11. package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +1 -1
  12. package/coverage/lcov-report/src/layouts/Framework.vue.html +13 -13
  13. package/coverage/lcov-report/src/layouts/NavMenu.vue.html +1 -1
  14. package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +1 -1
  15. package/coverage/lcov-report/src/layouts/Resizer.vue.html +1 -1
  16. package/coverage/lcov-report/src/layouts/index.html +15 -15
  17. package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +78 -12
  18. package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +149 -92
  19. package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +43 -121
  20. package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +23 -140
  21. package/coverage/lcov-report/{utils/undo-redo.ts.html → src/layouts/sidebar/TabPane.vue.html} +94 -118
  22. package/coverage/lcov-report/src/layouts/sidebar/index.html +64 -49
  23. package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +99 -12
  24. package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +86 -95
  25. package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +208 -97
  26. package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +3 -3
  27. package/coverage/lcov-report/src/layouts/workspace/index.html +35 -35
  28. package/coverage/lcov-report/src/services/BaseService.ts.html +11 -11
  29. package/coverage/lcov-report/src/services/componentList.ts.html +1 -1
  30. package/coverage/lcov-report/src/services/editor.ts.html +103 -10
  31. package/coverage/lcov-report/src/services/events.ts.html +1 -1
  32. package/coverage/lcov-report/src/services/history.ts.html +29 -8
  33. package/coverage/lcov-report/src/services/index.html +25 -25
  34. package/coverage/lcov-report/src/services/props.ts.html +4 -7
  35. package/coverage/lcov-report/src/services/ui.ts.html +1 -1
  36. package/coverage/lcov-report/src/type.ts.html +8 -14
  37. package/coverage/lcov-report/src/utils/compose.ts.html +4 -4
  38. package/coverage/lcov-report/src/utils/config.ts.html +1 -1
  39. package/coverage/lcov-report/src/utils/editor.ts.html +2 -2
  40. package/coverage/lcov-report/src/utils/index.html +1 -1
  41. package/coverage/lcov-report/src/utils/index.ts.html +1 -1
  42. package/coverage/lcov-report/src/utils/logger.ts.html +1 -1
  43. package/coverage/lcov-report/src/utils/props.ts.html +59 -2
  44. package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +1 -1
  45. package/coverage/lcov-report/src/utils/undo-redo.ts.html +1 -1
  46. package/coverage/lcov.info +1679 -1402
  47. package/dist/style.css +47 -20
  48. package/dist/tmagic-editor.es.js +732 -485
  49. package/dist/tmagic-editor.es.js.map +1 -1
  50. package/dist/tmagic-editor.umd.js +733 -485
  51. package/dist/tmagic-editor.umd.js.map +1 -1
  52. package/dist/types/src/Editor.vue.d.ts +1 -1
  53. package/dist/types/src/components/ToolButton.vue.d.ts +12 -1
  54. package/dist/types/src/fields/UISelect.vue.d.ts +4 -1
  55. package/dist/types/src/index.d.ts +1 -0
  56. package/dist/types/src/layouts/CodeEditor.vue.d.ts +13 -4
  57. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -0
  58. package/dist/types/src/layouts/sidebar/Sidebar.vue.d.ts +2 -3
  59. package/dist/types/src/layouts/sidebar/TabPane.vue.d.ts +14 -0
  60. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +2 -0
  61. package/dist/types/src/services/history.d.ts +1 -0
  62. package/dist/types/src/services/props.d.ts +2 -2
  63. package/dist/types/src/type.d.ts +6 -8
  64. package/dist/types/src/utils/polyfills.d.ts +0 -0
  65. package/package.json +15 -10
  66. package/src/components/ContentMenu.vue +107 -0
  67. package/src/components/ToolButton.vue +66 -27
  68. package/src/fields/UISelect.vue +14 -6
  69. package/src/index.ts +2 -0
  70. package/src/layouts/CodeEditor.vue +20 -10
  71. package/src/layouts/Framework.vue +6 -6
  72. package/src/layouts/sidebar/ComponentListPanel.vue +23 -1
  73. package/src/layouts/sidebar/LayerMenu.vue +91 -72
  74. package/src/layouts/sidebar/LayerPanel.vue +23 -49
  75. package/src/layouts/sidebar/Sidebar.vue +13 -52
  76. package/src/layouts/sidebar/TabPane.vue +68 -0
  77. package/src/layouts/workspace/PageBar.vue +35 -6
  78. package/src/layouts/workspace/Stage.vue +41 -44
  79. package/src/layouts/workspace/ViewerMenu.vue +104 -67
  80. package/src/layouts/workspace/Workspace.vue +2 -2
  81. package/src/services/editor.ts +33 -2
  82. package/src/services/history.ts +7 -0
  83. package/src/services/props.ts +2 -3
  84. package/src/theme/common/var.scss +1 -0
  85. package/src/theme/component-list-panel.scss +2 -0
  86. package/src/theme/content-menu.scss +33 -26
  87. package/src/theme/layer-panel.scss +1 -1
  88. package/src/theme/nav-menu.scss +6 -2
  89. package/src/theme/page-bar.scss +22 -1
  90. package/src/theme/props-panel.scss +4 -0
  91. package/src/type.ts +6 -8
  92. package/src/utils/editor.ts +1 -1
  93. package/src/utils/polyfills.ts +22 -0
  94. package/src/utils/props.ts +19 -0
  95. package/coverage/lcov-report/Icon.vue.html +0 -172
  96. package/coverage/lcov-report/ToolButton.vue.html +0 -655
  97. package/coverage/lcov-report/layouts/sidebar/index.html +0 -116
  98. package/coverage/lcov-report/utils/index.html +0 -116
  99. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +0 -980
  100. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +0 -188
  101. package/dist/types/src/layouts/workspace/ViewerMenu.vue.d.ts +0 -18
@@ -1,8 +1,8 @@
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('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';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('@element-plus/icons'), require('lodash-es'), require('monaco-editor'), require('@tmagic/schema'), 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', '@element-plus/icons', 'lodash-es', 'monaco-editor', '@tmagic/schema', '@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.icons, global.lodashEs, global.monaco, global.schema, global.utils, global.events, global.core, global.elementPlus, global.KeyController, global.StageCore));
5
+ })(this, (function (exports, vue, serialize, icons, lodashEs, monaco, schema, 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
 
@@ -29,6 +29,10 @@
29
29
  var KeyController__default = /*#__PURE__*/_interopDefaultLegacy(KeyController);
30
30
  var StageCore__default = /*#__PURE__*/_interopDefaultLegacy(StageCore);
31
31
 
32
+ if (typeof window.global === "undefined") {
33
+ window.global = window;
34
+ }
35
+
32
36
  var _export_sfc = (sfc, props) => {
33
37
  const target = sfc.__vccOpts || sfc;
34
38
  for (const [key, val] of props) {
@@ -37,7 +41,7 @@
37
41
  return target;
38
42
  };
39
43
 
40
- const _sfc_main$k = vue.defineComponent({
44
+ const _sfc_main$m = vue.defineComponent({
41
45
  name: "m-fields-vs-code",
42
46
  props: ["model", "name", "config", "prop"],
43
47
  emits: ["change"],
@@ -54,7 +58,7 @@
54
58
  };
55
59
  }
56
60
  });
57
- function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
61
+ function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
58
62
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
59
63
  return vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
60
64
  style: vue.normalizeStyle(`height: ${_ctx.height}`),
@@ -63,9 +67,9 @@
63
67
  onSave: _ctx.save
64
68
  }, null, 8, ["style", "init-values", "language", "onSave"]);
65
69
  }
66
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
70
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$m]]);
67
71
 
68
- const _sfc_main$j = vue.defineComponent({
72
+ const _sfc_main$l = vue.defineComponent({
69
73
  name: "m-fields-code-link",
70
74
  props: {
71
75
  config: {
@@ -120,7 +124,7 @@
120
124
  };
121
125
  }
122
126
  });
123
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
127
+ function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
124
128
  const _component_m_fields_link = vue.resolveComponent("m-fields-link");
125
129
  return vue.openBlock(), vue.createBlock(_component_m_fields_link, {
126
130
  config: _ctx.formConfig,
@@ -129,11 +133,11 @@
129
133
  onChange: _ctx.changeHandler
130
134
  }, null, 8, ["config", "model", "onChange"]);
131
135
  }
132
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
136
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$l]]);
133
137
 
134
138
  var UISelect_vue_vue_type_style_index_0_lang = '';
135
139
 
136
- const _sfc_main$i = vue.defineComponent({
140
+ const _sfc_main$k = vue.defineComponent({
137
141
  name: "m-fields-ui-select",
138
142
  props: {
139
143
  labelWidth: String,
@@ -171,6 +175,9 @@
171
175
  }
172
176
  };
173
177
  return {
178
+ Delete: vue.markRaw(icons.Delete),
179
+ Pointer: vue.markRaw(icons.Pointer),
180
+ Close: vue.markRaw(icons.Close),
174
181
  val,
175
182
  uiSelectMode,
176
183
  toName: vue.computed(() => {
@@ -195,34 +202,64 @@
195
202
  };
196
203
  }
197
204
  });
198
- const _hoisted_1$e = /* @__PURE__ */ vue.createElementVNode("i", {
199
- class: "el-icon-delete",
200
- style: { "color": "rgb(221, 75, 57)" }
201
- }, "\u53D6\u6D88", -1);
202
- const _hoisted_2$7 = [
203
- _hoisted_1$e
204
- ];
205
- const _hoisted_3$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
206
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
205
+ const _hoisted_1$c = /* @__PURE__ */ vue.createTextVNode("\u53D6\u6D88");
206
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
207
+ const _component_el_button = vue.resolveComponent("el-button");
208
+ const _component_el_tooltip = vue.resolveComponent("el-tooltip");
207
209
  return _ctx.uiSelectMode ? (vue.openBlock(), vue.createElementBlock("div", {
208
210
  key: 0,
209
211
  class: "m-fields-ui-select",
210
212
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.cancelHandler && _ctx.cancelHandler(...args))
211
- }, _hoisted_2$7)) : (vue.openBlock(), vue.createElementBlock("div", {
213
+ }, [
214
+ vue.createVNode(_component_el_button, {
215
+ type: "danger",
216
+ icon: _ctx.Delete,
217
+ text: "",
218
+ style: { "padding": "0" }
219
+ }, {
220
+ default: vue.withCtx(() => [
221
+ _hoisted_1$c
222
+ ]),
223
+ _: 1
224
+ }, 8, ["icon"])
225
+ ])) : (vue.openBlock(), vue.createElementBlock("div", {
212
226
  key: 1,
213
227
  class: "m-fields-ui-select",
214
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.startSelect && _ctx.startSelect(...args))
228
+ onClick: _cache[1] || (_cache[1] = (...args) => _ctx.startSelect && _ctx.startSelect(...args)),
229
+ style: { "display": "flex" }
215
230
  }, [
216
- _hoisted_3$5,
217
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"), 1),
218
- _ctx.val ? (vue.openBlock(), vue.createElementBlock("i", {
219
- key: 0,
220
- class: "el-icon-delete",
221
- onClick: _cache[1] || (_cache[1] = vue.withModifiers((...args) => _ctx.deleteHandler && _ctx.deleteHandler(...args), ["stop"]))
222
- })) : vue.createCommentVNode("", true)
231
+ vue.createVNode(_component_el_tooltip, { content: "\u6E05\u9664" }, {
232
+ default: vue.withCtx(() => [
233
+ _ctx.val ? (vue.openBlock(), vue.createBlock(_component_el_button, {
234
+ key: 0,
235
+ style: { "padding": "0" },
236
+ type: "danger",
237
+ icon: _ctx.Close,
238
+ text: "",
239
+ onClick: vue.withModifiers(_ctx.deleteHandler, ["stop"])
240
+ }, null, 8, ["icon", "onClick"])) : vue.createCommentVNode("", true)
241
+ ]),
242
+ _: 1
243
+ }),
244
+ vue.createVNode(_component_el_tooltip, {
245
+ content: _ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"
246
+ }, {
247
+ default: vue.withCtx(() => [
248
+ vue.createVNode(_component_el_button, {
249
+ text: "",
250
+ style: { "padding": "0", "margin": "0" }
251
+ }, {
252
+ default: vue.withCtx(() => [
253
+ vue.createTextVNode(vue.toDisplayString(_ctx.val ? _ctx.toName + "_" + _ctx.val : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"), 1)
254
+ ]),
255
+ _: 1
256
+ })
257
+ ]),
258
+ _: 1
259
+ }, 8, ["content"])
223
260
  ]));
224
261
  }
225
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
262
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
226
263
 
227
264
  const toString = (v, language) => {
228
265
  let value = "";
@@ -239,7 +276,7 @@
239
276
  }
240
277
  return value;
241
278
  };
242
- const _sfc_main$h = vue.defineComponent({
279
+ const _sfc_main$j = vue.defineComponent({
243
280
  name: "magic-code-editor",
244
281
  props: {
245
282
  initValues: {
@@ -249,12 +286,16 @@
249
286
  type: [String, Object]
250
287
  },
251
288
  type: {
252
- type: [String],
289
+ type: String,
253
290
  default: () => ""
254
291
  },
255
292
  language: {
256
- type: [String],
293
+ type: String,
257
294
  default: () => "javascript"
295
+ },
296
+ options: {
297
+ type: Object,
298
+ default: () => ({})
258
299
  }
259
300
  },
260
301
  emits: ["initd", "save"],
@@ -264,6 +305,10 @@
264
305
  const values = vue.ref("");
265
306
  const loading = vue.ref(false);
266
307
  const codeEditor = vue.ref();
308
+ const resizeObserver = new globalThis.ResizeObserver(lodashEs.throttle(() => {
309
+ vsEditor?.layout();
310
+ vsDiffEditor?.layout();
311
+ }, 300));
267
312
  const setEditorValue = (v, m) => {
268
313
  values.value = toString(v, props.language);
269
314
  if (props.type === "diff") {
@@ -276,10 +321,6 @@
276
321
  }
277
322
  return vsEditor?.setValue(values.value);
278
323
  };
279
- const resizeHandler = () => {
280
- vsEditor?.layout();
281
- vsDiffEditor?.layout();
282
- };
283
324
  const getEditorValue = () => props.type === "diff" ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
284
325
  const init = async () => {
285
326
  if (!codeEditor.value)
@@ -290,8 +331,9 @@
290
331
  tabSize: 2,
291
332
  theme: "vs-dark",
292
333
  fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
293
- fontSize: 15,
294
- formatOnPaste: true
334
+ fontSize: 14,
335
+ formatOnPaste: true,
336
+ ...props.options
295
337
  };
296
338
  if (props.type === "diff") {
297
339
  vsDiffEditor = monaco__namespace.editor.createDiffEditor(codeEditor.value, options);
@@ -312,7 +354,7 @@
312
354
  emit("save", getEditorValue());
313
355
  });
314
356
  }
315
- globalThis.addEventListener("resize", resizeHandler);
357
+ resizeObserver.observe(codeEditor.value);
316
358
  };
317
359
  vue.watch(() => props.initValues, (v, preV) => {
318
360
  if (v !== preV) {
@@ -327,7 +369,7 @@
327
369
  init();
328
370
  });
329
371
  vue.onUnmounted(() => {
330
- globalThis.removeEventListener("resize", resizeHandler);
372
+ resizeObserver.disconnect();
331
373
  });
332
374
  return {
333
375
  values,
@@ -344,14 +386,14 @@
344
386
  };
345
387
  }
346
388
  });
347
- const _hoisted_1$d = {
389
+ const _hoisted_1$b = {
348
390
  ref: "codeEditor",
349
391
  class: "magic-code-editor"
350
392
  };
351
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
352
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$d, null, 512);
393
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
394
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, null, 512);
353
395
  }
354
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
396
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
355
397
 
356
398
  let $TMAGIC_EDITOR = {};
357
399
  const setConfig = (option) => {
@@ -532,6 +574,12 @@
532
574
  });
533
575
  this.on("change", this.setCanUndoRedo);
534
576
  }
577
+ reset() {
578
+ this.state.pageSteps = {};
579
+ this.state.pageId = void 0;
580
+ this.state.canRedo = false;
581
+ this.state.canUndo = false;
582
+ }
535
583
  changePage(page) {
536
584
  if (!page)
537
585
  return;
@@ -637,8 +685,7 @@
637
685
  }
638
686
  return lodashEs.cloneDeep({
639
687
  ...getDefaultPropsValue(type),
640
- ...defaultValue,
641
- ...this.state.propsValueMap[type] || {}
688
+ ...lodashEs.mergeWith(this.state.propsValueMap[type] || {}, defaultValue)
642
689
  });
643
690
  }
644
691
  }
@@ -725,7 +772,7 @@
725
772
  const setTop2Middle = (node, parentNode, stage) => {
726
773
  const style = node.style || {};
727
774
  const height = style.height || 0;
728
- if (!stage || style.top || !parentNode.style || !utils.isNumber(height))
775
+ if (!stage || typeof style.top !== "undefined" || !parentNode.style || !utils.isNumber(height))
729
776
  return style;
730
777
  const { height: parentHeight } = parentNode.style;
731
778
  if (utils.isPage(parentNode)) {
@@ -835,6 +882,7 @@
835
882
  "paste",
836
883
  "alignCenter",
837
884
  "moveLayer",
885
+ "move",
838
886
  "undo",
839
887
  "redo",
840
888
  "highlight"
@@ -847,12 +895,14 @@
847
895
  node: null,
848
896
  stage: null,
849
897
  highlightNode: null,
850
- modifiedNodeIds: /* @__PURE__ */ new Map()
898
+ modifiedNodeIds: /* @__PURE__ */ new Map(),
899
+ pageLength: 0
851
900
  });
852
901
  }
853
902
  set(name, value) {
854
903
  this.state[name] = value;
855
904
  if (name === "root") {
905
+ this.state.pageLength = value?.items?.length || 0;
856
906
  this.emit("root-change", value);
857
907
  }
858
908
  }
@@ -912,6 +962,7 @@
912
962
  } else {
913
963
  historyService.empty();
914
964
  }
965
+ this.emit("select", node);
915
966
  return node;
916
967
  }
917
968
  async selectNextNode() {
@@ -947,7 +998,8 @@
947
998
  const { type, ...config2 } = addNode;
948
999
  const curNode = this.get("node");
949
1000
  let parentNode;
950
- if (type === schema.NodeType.PAGE) {
1001
+ const isPage2 = type === schema.NodeType.PAGE;
1002
+ if (isPage2) {
951
1003
  parentNode = this.get("root");
952
1004
  } else if (parent && typeof parent !== "function") {
953
1005
  parentNode = parent;
@@ -968,10 +1020,14 @@
968
1020
  await stage?.add({ config: lodashEs.cloneDeep(newNode), root: lodashEs.cloneDeep(this.get("root")) });
969
1021
  await this.select(newNode);
970
1022
  this.addModifiedNodeId(newNode.id);
971
- if (type !== schema.NodeType.PAGE) {
1023
+ if (!isPage2) {
972
1024
  this.pushHistoryState();
973
1025
  }
974
1026
  stage?.select(newNode.id);
1027
+ if (isPage2) {
1028
+ this.state.pageLength += 1;
1029
+ }
1030
+ this.emit("add", newNode);
975
1031
  return newNode;
976
1032
  }
977
1033
  async remove(node) {
@@ -990,9 +1046,20 @@
990
1046
  const stage = this.get("stage");
991
1047
  stage?.remove({ id: node.id, root: this.get("root") });
992
1048
  if (node.type === schema.NodeType.PAGE) {
1049
+ this.state.pageLength -= 1;
993
1050
  if (root.items[0]) {
994
1051
  await this.select(root.items[0]);
995
1052
  stage?.select(root.items[0].id);
1053
+ } else {
1054
+ this.set("node", null);
1055
+ this.set("parent", null);
1056
+ this.set("page", null);
1057
+ this.set("stage", null);
1058
+ this.set("highlightNode", null);
1059
+ this.resetModifiedNodeId();
1060
+ historyService.reset();
1061
+ this.emit("remove", node);
1062
+ return node;
996
1063
  }
997
1064
  } else {
998
1065
  await this.select(parent);
@@ -1000,6 +1067,7 @@
1000
1067
  }
1001
1068
  this.addModifiedNodeId(parent.id);
1002
1069
  this.pushHistoryState();
1070
+ this.emit("remove", node);
1003
1071
  return node;
1004
1072
  }
1005
1073
  async update(config2) {
@@ -1043,6 +1111,7 @@
1043
1111
  }
1044
1112
  this.addModifiedNodeId(newConfig.id);
1045
1113
  this.pushHistoryState();
1114
+ this.emit("update", newConfig);
1046
1115
  return newConfig;
1047
1116
  }
1048
1117
  async sort(id1, id2) {
@@ -1372,6 +1441,25 @@
1372
1441
  defaultValue: "100% 100%"
1373
1442
  }
1374
1443
  ]
1444
+ },
1445
+ {
1446
+ type: "fieldset",
1447
+ legend: "\u5B57\u4F53",
1448
+ items: [
1449
+ {
1450
+ name: "color",
1451
+ text: "\u989C\u8272",
1452
+ type: "colorPicker"
1453
+ },
1454
+ {
1455
+ name: "fontSize",
1456
+ text: "\u5927\u5C0F"
1457
+ },
1458
+ {
1459
+ name: "fontWeight",
1460
+ text: "\u7C97\u7EC6"
1461
+ }
1462
+ ]
1375
1463
  }
1376
1464
  ]
1377
1465
  }
@@ -1439,7 +1527,7 @@
1439
1527
  name: type
1440
1528
  });
1441
1529
 
1442
- const _sfc_main$g = vue.defineComponent({
1530
+ const _sfc_main$i = vue.defineComponent({
1443
1531
  components: { Plus: icons.Plus },
1444
1532
  setup() {
1445
1533
  const services = vue.inject("services");
@@ -1456,14 +1544,14 @@
1456
1544
  };
1457
1545
  }
1458
1546
  });
1459
- const _hoisted_1$c = { class: "m-editor-empty-panel" };
1460
- const _hoisted_2$6 = { class: "m-editor-empty-content" };
1461
- const _hoisted_3$4 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1462
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1547
+ const _hoisted_1$a = { class: "m-editor-empty-panel" };
1548
+ const _hoisted_2$4 = { class: "m-editor-empty-content" };
1549
+ const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1550
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1463
1551
  const _component_plus = vue.resolveComponent("plus");
1464
1552
  const _component_el_icon = vue.resolveComponent("el-icon");
1465
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, [
1466
- vue.createElementVNode("div", _hoisted_2$6, [
1553
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
1554
+ vue.createElementVNode("div", _hoisted_2$4, [
1467
1555
  vue.createElementVNode("div", {
1468
1556
  class: "m-editor-empty-button",
1469
1557
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.clickHandler && _ctx.clickHandler(...args))
@@ -1476,12 +1564,12 @@
1476
1564
  _: 1
1477
1565
  })
1478
1566
  ]),
1479
- _hoisted_3$4
1567
+ _hoisted_3$2
1480
1568
  ])
1481
1569
  ])
1482
1570
  ]);
1483
1571
  }
1484
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1572
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
1485
1573
 
1486
1574
  /*
1487
1575
  Copyright (c) 2018 Daybrush
@@ -2692,7 +2780,7 @@
2692
2780
 
2693
2781
  var Gesto$1 = Gesto;
2694
2782
 
2695
- const _sfc_main$f = vue.defineComponent({
2783
+ const _sfc_main$h = vue.defineComponent({
2696
2784
  name: "m-editor-resize",
2697
2785
  props: {
2698
2786
  type: {
@@ -2734,33 +2822,33 @@
2734
2822
  };
2735
2823
  }
2736
2824
  });
2737
- const _hoisted_1$b = {
2825
+ const _hoisted_1$9 = {
2738
2826
  ref: "target",
2739
2827
  class: "m-editor-resizer"
2740
2828
  };
2741
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2742
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$b, [
2829
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
2830
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$9, [
2743
2831
  vue.renderSlot(_ctx.$slots, "default")
2744
2832
  ], 512);
2745
2833
  }
2746
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2834
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
2747
2835
 
2748
- const _sfc_main$e = vue.defineComponent({
2836
+ const _sfc_main$g = vue.defineComponent({
2749
2837
  components: {
2750
2838
  AddPageBox,
2751
2839
  Resizer
2752
2840
  },
2753
2841
  setup() {
2754
- const services = vue.inject("services");
2755
- const root = vue.computed(() => services?.editorService.get("root"));
2842
+ const { editorService, uiService } = vue.inject("services") || {};
2843
+ const root = vue.computed(() => editorService?.get("root"));
2756
2844
  return {
2757
2845
  root,
2758
- pageLength: vue.computed(() => root.value?.items?.length || 0),
2759
- showSrc: vue.computed(() => services?.uiService.get("showSrc")),
2760
- columnWidth: vue.computed(() => services?.uiService.get("columnWidth")),
2846
+ pageLength: vue.computed(() => editorService?.get("pageLength") || 0),
2847
+ showSrc: vue.computed(() => uiService?.get("showSrc")),
2848
+ columnWidth: vue.computed(() => uiService?.get("columnWidth")),
2761
2849
  saveCode(value) {
2762
2850
  try {
2763
- services?.editorService.set("root", eval(value));
2851
+ editorService?.set("root", eval(value));
2764
2852
  } catch (e) {
2765
2853
  console.error(e);
2766
2854
  }
@@ -2768,24 +2856,24 @@
2768
2856
  };
2769
2857
  }
2770
2858
  });
2771
- const _hoisted_1$a = { class: "m-editor" };
2772
- const _hoisted_2$5 = {
2859
+ const _hoisted_1$8 = { class: "m-editor" };
2860
+ const _hoisted_2$3 = {
2773
2861
  key: 1,
2774
2862
  class: "m-editor-content"
2775
2863
  };
2776
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2864
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
2777
2865
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
2778
2866
  const _component_resizer = vue.resolveComponent("resizer");
2779
2867
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
2780
2868
  const _component_add_page_box = vue.resolveComponent("add-page-box");
2781
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
2869
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
2782
2870
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2783
2871
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
2784
2872
  key: 0,
2785
2873
  class: "m-editor-content",
2786
2874
  "init-values": _ctx.root,
2787
2875
  onSave: _ctx.saveCode
2788
- }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$5, [
2876
+ }, null, 8, ["init-values", "onSave"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, [
2789
2877
  vue.createElementVNode("div", {
2790
2878
  class: "m-editor-framework-left",
2791
2879
  style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.left}px`)
@@ -2818,9 +2906,9 @@
2818
2906
  ]))
2819
2907
  ]);
2820
2908
  }
2821
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2909
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
2822
2910
 
2823
- const _sfc_main$d = vue.defineComponent({
2911
+ const _sfc_main$f = vue.defineComponent({
2824
2912
  name: "m-icon",
2825
2913
  components: { Edit: icons.Edit },
2826
2914
  props: {
@@ -2834,8 +2922,8 @@
2834
2922
  };
2835
2923
  }
2836
2924
  });
2837
- const _hoisted_1$9 = ["src"];
2838
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2925
+ const _hoisted_1$7 = ["src"];
2926
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2839
2927
  const _component_edit = vue.resolveComponent("edit");
2840
2928
  const _component_el_icon = vue.resolveComponent("el-icon");
2841
2929
  return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
@@ -2846,7 +2934,7 @@
2846
2934
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createElementBlock("img", {
2847
2935
  key: 1,
2848
2936
  src: _ctx.icon
2849
- }, null, 8, _hoisted_1$9)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2937
+ }, null, 8, _hoisted_1$7)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2850
2938
  key: 2,
2851
2939
  class: vue.normalizeClass(_ctx.icon)
2852
2940
  }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
@@ -2856,9 +2944,9 @@
2856
2944
  _: 1
2857
2945
  }));
2858
2946
  }
2859
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2947
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2860
2948
 
2861
- const _sfc_main$c = vue.defineComponent({
2949
+ const _sfc_main$e = vue.defineComponent({
2862
2950
  components: { MIcon, ArrowDown: icons.ArrowDown },
2863
2951
  props: {
2864
2952
  data: {
@@ -2868,6 +2956,10 @@
2868
2956
  type: "text",
2869
2957
  display: false
2870
2958
  })
2959
+ },
2960
+ eventType: {
2961
+ type: String,
2962
+ default: "click"
2871
2963
  }
2872
2964
  },
2873
2965
  setup(props) {
@@ -2894,7 +2986,7 @@
2894
2986
  case "delete":
2895
2987
  return {
2896
2988
  type: "button",
2897
- icon: icons.Delete,
2989
+ icon: vue.markRaw(icons.Delete),
2898
2990
  tooltip: "\u522A\u9664",
2899
2991
  disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2900
2992
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
@@ -2902,7 +2994,7 @@
2902
2994
  case "undo":
2903
2995
  return {
2904
2996
  type: "button",
2905
- icon: icons.Back,
2997
+ icon: vue.markRaw(icons.Back),
2906
2998
  tooltip: "\u540E\u9000",
2907
2999
  disabled: () => !services?.historyService.state.canUndo,
2908
3000
  handler: () => services?.editorService.undo()
@@ -2910,7 +3002,7 @@
2910
3002
  case "redo":
2911
3003
  return {
2912
3004
  type: "button",
2913
- icon: icons.Right,
3005
+ icon: vue.markRaw(icons.Right),
2914
3006
  tooltip: "\u524D\u8FDB",
2915
3007
  disabled: () => !services?.historyService.state.canRedo,
2916
3008
  handler: () => services?.editorService.redo()
@@ -2918,28 +3010,28 @@
2918
3010
  case "zoom-in":
2919
3011
  return {
2920
3012
  type: "button",
2921
- icon: icons.ZoomIn,
3013
+ icon: vue.markRaw(icons.ZoomIn),
2922
3014
  tooltip: "\u653E\u5927",
2923
3015
  handler: zoomInHandler
2924
3016
  };
2925
3017
  case "zoom-out":
2926
3018
  return {
2927
3019
  type: "button",
2928
- icon: icons.ZoomOut,
3020
+ icon: vue.markRaw(icons.ZoomOut),
2929
3021
  tooltip: "\u7E2E\u5C0F",
2930
3022
  handler: zoomOutHandler
2931
3023
  };
2932
3024
  case "rule":
2933
3025
  return {
2934
3026
  type: "button",
2935
- icon: icons.ScaleToOriginal,
3027
+ icon: vue.markRaw(icons.ScaleToOriginal),
2936
3028
  tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2937
3029
  handler: () => uiService?.set("showRule", !showRule.value)
2938
3030
  };
2939
3031
  case "guides":
2940
3032
  return {
2941
3033
  type: "button",
2942
- icon: icons.Grid,
3034
+ icon: vue.markRaw(icons.Grid),
2943
3035
  tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2944
3036
  handler: () => uiService?.set("showGuides", !showGuides.value)
2945
3037
  };
@@ -2960,9 +3052,16 @@
2960
3052
  }
2961
3053
  return item.value.disabled;
2962
3054
  });
3055
+ const buttonHandler = (item2, event) => {
3056
+ if (disabled.value)
3057
+ return;
3058
+ if (typeof item2.handler === "function" && services) {
3059
+ item2.handler?.(services, event);
3060
+ }
3061
+ };
2963
3062
  return {
2964
- ZoomIn: icons.ZoomIn,
2965
- ZoomOut: icons.ZoomOut,
3063
+ ZoomIn: vue.markRaw(icons.ZoomIn),
3064
+ ZoomOut: vue.markRaw(icons.ZoomOut),
2966
3065
  item,
2967
3066
  zoom,
2968
3067
  disabled,
@@ -2983,31 +3082,42 @@
2983
3082
  command.item.handler(services);
2984
3083
  }
2985
3084
  },
2986
- buttonHandler(item2) {
2987
- if (disabled.value)
3085
+ clickHandler(item2, event) {
3086
+ if (props.eventType !== "click")
3087
+ return;
3088
+ if (item2.type === "button") {
3089
+ buttonHandler(item2, event);
3090
+ }
3091
+ },
3092
+ mousedownHandler(item2, event) {
3093
+ if (props.eventType !== "mousedown")
3094
+ return;
3095
+ if (item2.type === "button") {
3096
+ buttonHandler(item2, event);
3097
+ }
3098
+ },
3099
+ mouseupHandler(item2, event) {
3100
+ if (props.eventType !== "mouseup")
2988
3101
  return;
2989
- if (typeof item2.handler === "function") {
2990
- item2.handler?.(services);
3102
+ if (item2.type === "button") {
3103
+ buttonHandler(item2, event);
2991
3104
  }
2992
3105
  }
2993
3106
  };
2994
3107
  }
2995
3108
  });
2996
- const _hoisted_1$8 = {
2997
- key: 0,
2998
- class: "menu-item"
2999
- };
3000
- const _hoisted_2$4 = {
3109
+ const _hoisted_1$6 = {
3001
3110
  key: 1,
3002
3111
  class: "menu-item-text"
3003
3112
  };
3004
- const _hoisted_3$3 = {
3113
+ const _hoisted_2$2 = {
3005
3114
  class: "menu-item-text",
3006
3115
  style: { "margin": "0 5px" }
3007
3116
  };
3008
- const _hoisted_4$2 = { class: "el-dropdown-link menubar-menu-button" };
3009
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3117
+ const _hoisted_3$1 = { class: "el-dropdown-link menubar-menu-button" };
3118
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
3010
3119
  const _component_el_divider = vue.resolveComponent("el-divider");
3120
+ const _component_tool_button = vue.resolveComponent("tool-button", true);
3011
3121
  const _component_m_icon = vue.resolveComponent("m-icon");
3012
3122
  const _component_el_button = vue.resolveComponent("el-button");
3013
3123
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -3016,60 +3126,66 @@
3016
3126
  const _component_el_dropdown_item = vue.resolveComponent("el-dropdown-item");
3017
3127
  const _component_el_dropdown_menu = vue.resolveComponent("el-dropdown-menu");
3018
3128
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
3019
- return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
3129
+ return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", {
3130
+ key: 0,
3131
+ class: vue.normalizeClass(["menu-item", _ctx.item.type]),
3132
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.clickHandler(_ctx.item, $event)),
3133
+ onMousedown: _cache[1] || (_cache[1] = ($event) => _ctx.mousedownHandler(_ctx.item, $event)),
3134
+ onMouseup: _cache[2] || (_cache[2] = ($event) => _ctx.mouseupHandler(_ctx.item, $event))
3135
+ }, [
3020
3136
  _ctx.item.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
3021
3137
  key: 0,
3022
- direction: "vertical"
3023
- })) : _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 }, [
3024
- vue.createVNode(_component_el_button, {
3025
- size: "small",
3026
- type: "text"
3138
+ direction: _ctx.item.direction || "vertical"
3139
+ }, 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 }, [
3140
+ vue.createVNode(_component_tool_button, {
3141
+ data: { type: "button", icon: _ctx.ZoomOut, handler: _ctx.zoomOutHandler, tooltip: "\u7F29\u5C0F" },
3142
+ "event-type": _ctx.eventType
3143
+ }, null, 8, ["data", "event-type"]),
3144
+ vue.createElementVNode("span", _hoisted_2$2, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
3145
+ vue.createVNode(_component_tool_button, {
3146
+ data: { type: "button", icon: _ctx.ZoomIn, handler: _ctx.zoomInHandler, tooltip: "\u653E\u5927" },
3147
+ "event-type": _ctx.eventType
3148
+ }, null, 8, ["data", "event-type"])
3149
+ ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
3150
+ _ctx.item.tooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
3151
+ key: 0,
3152
+ effect: "dark",
3153
+ placement: "bottom-start",
3154
+ content: _ctx.item.tooltip
3027
3155
  }, {
3028
3156
  default: vue.withCtx(() => [
3029
- vue.createVNode(_component_m_icon, {
3030
- icon: _ctx.ZoomIn,
3031
- onClick: _ctx.zoomInHandler
3032
- }, null, 8, ["icon", "onClick"])
3157
+ vue.createVNode(_component_el_button, {
3158
+ size: "small",
3159
+ text: "",
3160
+ disabled: _ctx.disabled
3161
+ }, {
3162
+ default: vue.withCtx(() => [
3163
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3164
+ key: 0,
3165
+ icon: _ctx.item.icon
3166
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3167
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3168
+ ]),
3169
+ _: 1
3170
+ }, 8, ["disabled"])
3033
3171
  ]),
3034
3172
  _: 1
3035
- }),
3036
- vue.createElementVNode("span", _hoisted_3$3, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
3037
- vue.createVNode(_component_el_button, {
3173
+ }, 8, ["content"])) : (vue.openBlock(), vue.createBlock(_component_el_button, {
3174
+ key: 1,
3038
3175
  size: "small",
3039
- type: "text"
3176
+ text: "",
3177
+ disabled: _ctx.disabled
3040
3178
  }, {
3041
3179
  default: vue.withCtx(() => [
3042
- vue.createVNode(_component_m_icon, {
3043
- icon: _ctx.ZoomOut,
3044
- onClick: _ctx.zoomOutHandler
3045
- }, null, 8, ["icon", "onClick"])
3180
+ _ctx.item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3181
+ key: 0,
3182
+ icon: _ctx.item.icon
3183
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3184
+ vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3046
3185
  ]),
3047
3186
  _: 1
3048
- })
3049
- ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
3050
- key: 3,
3051
- effect: "dark",
3052
- placement: "bottom-start",
3053
- content: _ctx.item.tooltip || _ctx.item.text
3054
- }, {
3055
- default: vue.withCtx(() => [
3056
- vue.createVNode(_component_el_button, {
3057
- size: "small",
3058
- type: "text",
3059
- disabled: _ctx.disabled,
3060
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.buttonHandler(_ctx.item))
3061
- }, {
3062
- default: vue.withCtx(() => [
3063
- vue.createVNode(_component_m_icon, {
3064
- icon: _ctx.item.icon
3065
- }, null, 8, ["icon"]),
3066
- vue.createElementVNode("span", null, vue.toDisplayString(_ctx.item.text), 1)
3067
- ]),
3068
- _: 1
3069
- }, 8, ["disabled"])
3070
- ]),
3071
- _: 1
3072
- }, 8, ["content"])) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
3187
+ }, 8, ["disabled"]))
3188
+ ], 64)) : _ctx.item.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
3073
3189
  key: 4,
3074
3190
  trigger: "click",
3075
3191
  disabled: _ctx.disabled,
@@ -3094,7 +3210,7 @@
3094
3210
  })) : vue.createCommentVNode("", true)
3095
3211
  ]),
3096
3212
  default: vue.withCtx(() => [
3097
- vue.createElementVNode("span", _hoisted_4$2, [
3213
+ vue.createElementVNode("span", _hoisted_3$1, [
3098
3214
  vue.createTextVNode(vue.toDisplayString(_ctx.item.text), 1),
3099
3215
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
3100
3216
  default: vue.withCtx(() => [
@@ -3106,11 +3222,11 @@
3106
3222
  ]),
3107
3223
  _: 1
3108
3224
  }, 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)
3109
- ])) : vue.createCommentVNode("", true);
3225
+ ], 34)) : vue.createCommentVNode("", true);
3110
3226
  }
3111
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3227
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
3112
3228
 
3113
- const _sfc_main$b = vue.defineComponent({
3229
+ const _sfc_main$d = vue.defineComponent({
3114
3230
  name: "nav-menu",
3115
3231
  components: { ToolButton },
3116
3232
  props: {
@@ -3130,7 +3246,7 @@
3130
3246
  };
3131
3247
  }
3132
3248
  });
3133
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3249
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
3134
3250
  const _component_tool_button = vue.resolveComponent("tool-button");
3135
3251
  return vue.openBlock(), vue.createElementBlock("div", {
3136
3252
  class: "m-editor-nav-menu",
@@ -3152,9 +3268,9 @@
3152
3268
  }), 128))
3153
3269
  ], 4);
3154
3270
  }
3155
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3271
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
3156
3272
 
3157
- const _sfc_main$a = vue.defineComponent({
3273
+ const _sfc_main$c = vue.defineComponent({
3158
3274
  name: "m-editor-props-panel",
3159
3275
  emits: ["mounted"],
3160
3276
  setup(props, { emit }) {
@@ -3200,7 +3316,7 @@
3200
3316
  };
3201
3317
  }
3202
3318
  });
3203
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3319
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
3204
3320
  const _component_m_form = vue.resolveComponent("m-form");
3205
3321
  return vue.openBlock(), vue.createBlock(_component_m_form, {
3206
3322
  class: "m-editor-props-panel",
@@ -3212,9 +3328,9 @@
3212
3328
  onChange: _ctx.submit
3213
3329
  }, null, 8, ["init-values", "config", "onChange"]);
3214
3330
  }
3215
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3331
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
3216
3332
 
3217
- const _sfc_main$9 = vue.defineComponent({
3333
+ const _sfc_main$b = vue.defineComponent({
3218
3334
  name: "ui-component-panel",
3219
3335
  components: { MIcon },
3220
3336
  setup() {
@@ -3235,13 +3351,23 @@
3235
3351
  type,
3236
3352
  ...data
3237
3353
  });
3354
+ },
3355
+ dragstartHandler({ text, type, data = {} }, e) {
3356
+ if (e.dataTransfer) {
3357
+ e.dataTransfer.effectAllowed = "move";
3358
+ e.dataTransfer.setData("data", serialize__default["default"]({
3359
+ name: text,
3360
+ type,
3361
+ ...data
3362
+ }).replace(/"(\w+)":\s/g, "$1: "));
3363
+ }
3238
3364
  }
3239
3365
  };
3240
3366
  }
3241
3367
  });
3242
- const _hoisted_1$7 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3243
- const _hoisted_2$3 = ["onClick"];
3244
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3368
+ const _hoisted_1$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3369
+ const _hoisted_2$1 = ["onClick", "onDragstart"];
3370
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
3245
3371
  const _component_el_input = vue.resolveComponent("el-input");
3246
3372
  const _component_m_icon = vue.resolveComponent("m-icon");
3247
3373
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -3271,15 +3397,17 @@
3271
3397
  name: index
3272
3398
  }, {
3273
3399
  title: vue.withCtx(() => [
3274
- _hoisted_1$7,
3400
+ _hoisted_1$5,
3275
3401
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
3276
3402
  ]),
3277
3403
  default: vue.withCtx(() => [
3278
3404
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(group.items, (item) => {
3279
3405
  return vue.openBlock(), vue.createElementBlock("div", {
3280
3406
  class: "component-item",
3407
+ draggable: "true",
3281
3408
  key: item.type,
3282
- onClick: ($event) => _ctx.appendComponent(item)
3409
+ onClick: ($event) => _ctx.appendComponent(item),
3410
+ onDragstart: ($event) => _ctx.dragstartHandler(item, $event)
3283
3411
  }, [
3284
3412
  vue.createVNode(_component_m_icon, {
3285
3413
  icon: item.icon
@@ -3294,7 +3422,7 @@
3294
3422
  ]),
3295
3423
  _: 2
3296
3424
  }, 1032, ["content"])
3297
- ], 8, _hoisted_2$3);
3425
+ ], 40, _hoisted_2$1);
3298
3426
  }), 128))
3299
3427
  ]),
3300
3428
  _: 2
@@ -3308,100 +3436,196 @@
3308
3436
  _: 1
3309
3437
  });
3310
3438
  }
3311
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3439
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3312
3440
 
3313
- const _sfc_main$8 = vue.defineComponent({
3314
- name: "magic-editor-content-menu",
3441
+ const _sfc_main$a = vue.defineComponent({
3442
+ components: { ToolButton },
3443
+ props: {
3444
+ menuData: {
3445
+ type: Array,
3446
+ default: () => []
3447
+ }
3448
+ },
3449
+ setup() {
3450
+ const menu = vue.ref();
3451
+ const subMenu = vue.ref();
3452
+ const visible = vue.ref(false);
3453
+ const subMenuData = vue.ref([]);
3454
+ const menuStyle = vue.ref({
3455
+ left: "0",
3456
+ top: "0"
3457
+ });
3458
+ const hide = () => {
3459
+ visible.value = false;
3460
+ };
3461
+ vue.onMounted(() => {
3462
+ globalThis.addEventListener("mousedown", (e) => {
3463
+ if (!visible.value || e.target && menu.value?.contains(e.target)) {
3464
+ return;
3465
+ }
3466
+ hide();
3467
+ }, true);
3468
+ });
3469
+ return {
3470
+ menu,
3471
+ subMenu,
3472
+ visible,
3473
+ menuStyle,
3474
+ subMenuData,
3475
+ hide,
3476
+ show(e) {
3477
+ visible.value = true;
3478
+ vue.nextTick(() => {
3479
+ const menuHeight = menu.value?.clientHeight || 0;
3480
+ let top = e.clientY;
3481
+ if (menuHeight + e.clientY > document.body.clientHeight) {
3482
+ top = document.body.clientHeight - menuHeight;
3483
+ }
3484
+ menuStyle.value = {
3485
+ top: `${top}px`,
3486
+ left: `${e.clientX}px`
3487
+ };
3488
+ });
3489
+ },
3490
+ showSubMenu(item) {
3491
+ const menuItem = item;
3492
+ if (typeof item !== "object" || !menuItem.items?.length) {
3493
+ return;
3494
+ }
3495
+ subMenuData.value = menuItem.items;
3496
+ if (menu.value) {
3497
+ subMenu.value.show({
3498
+ clientX: menu.value.offsetLeft + menu.value.clientWidth,
3499
+ clientY: menu.value.offsetTop
3500
+ });
3501
+ }
3502
+ }
3503
+ };
3504
+ }
3505
+ });
3506
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3507
+ const _component_tool_button = vue.resolveComponent("tool-button");
3508
+ const _component_content_menu = vue.resolveComponent("content-menu", true);
3509
+ return _ctx.menuData.length ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", {
3510
+ key: 0,
3511
+ class: "magic-editor-content-menu",
3512
+ ref: "menu",
3513
+ style: vue.normalizeStyle(_ctx.menuStyle)
3514
+ }, [
3515
+ vue.createElementVNode("div", null, [
3516
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.menuData, (item, index) => {
3517
+ return vue.openBlock(), vue.createBlock(_component_tool_button, {
3518
+ "event-type": "mouseup",
3519
+ data: item,
3520
+ key: index,
3521
+ onMouseup: _ctx.hide,
3522
+ onMouseenter: ($event) => _ctx.showSubMenu(item)
3523
+ }, null, 8, ["data", "onMouseup", "onMouseenter"]);
3524
+ }), 128))
3525
+ ]),
3526
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3527
+ vue.createVNode(_component_content_menu, {
3528
+ class: "sub-menu",
3529
+ ref: "subMenu",
3530
+ "menu-data": _ctx.subMenuData
3531
+ }, null, 8, ["menu-data"])
3532
+ ]))
3533
+ ], 4)), [
3534
+ [vue.vShow, _ctx.visible]
3535
+ ]) : vue.createCommentVNode("", true);
3536
+ }
3537
+ var ContentMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3538
+
3539
+ const _sfc_main$9 = vue.defineComponent({
3540
+ components: { ContentMenu },
3315
3541
  setup() {
3316
3542
  const services = vue.inject("services");
3317
- const subVisible = vue.ref(false);
3543
+ const menu = vue.ref();
3318
3544
  const node = vue.computed(() => services?.editorService.get("node"));
3319
- return {
3320
- subVisible,
3321
- node,
3322
- componentGroupList: vue.computed(() => services?.componentListService.getList()),
3323
- append(config) {
3545
+ const isRoot = vue.computed(() => node.value?.type === schema.NodeType.ROOT);
3546
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
3547
+ const componentList = vue.computed(() => services?.componentListService.getList() || []);
3548
+ const createMenuItems = (group) => group.items.map((component) => ({
3549
+ text: component.text,
3550
+ type: "button",
3551
+ icon: component.icon,
3552
+ handler: () => {
3324
3553
  services?.editorService.add({
3325
- name: config.text,
3326
- type: config.type,
3327
- ...config.data || {}
3554
+ name: component.text,
3555
+ type: component.type,
3556
+ ...component.data || {}
3328
3557
  });
3329
- },
3330
- remove() {
3331
- node.value && services?.editorService.remove(node.value);
3332
- },
3333
- copy(node2) {
3334
- node2 && services?.editorService.copy(node2);
3335
- },
3336
- setSubVisitable(v) {
3337
- subVisible.value = v;
3558
+ }
3559
+ }));
3560
+ const getSubMenuData = vue.computed(() => {
3561
+ if (node.value?.type === "tabs") {
3562
+ return [
3563
+ {
3564
+ text: "\u6807\u7B7E\u9875",
3565
+ type: "button",
3566
+ icon: icons.Files,
3567
+ handler: () => {
3568
+ services?.editorService.add({
3569
+ type: "tab-pane"
3570
+ });
3571
+ }
3572
+ }
3573
+ ];
3574
+ }
3575
+ if (node.value?.items) {
3576
+ return componentList.value.reduce((subMenuData, group, index) => subMenuData.concat(createMenuItems(group), index < componentList.value.length - 1 ? [
3577
+ {
3578
+ type: "divider",
3579
+ direction: "horizontal"
3580
+ }
3581
+ ] : []), []) || [];
3582
+ }
3583
+ return [];
3584
+ });
3585
+ return {
3586
+ menu,
3587
+ menuData: vue.computed(() => [
3588
+ {
3589
+ type: "button",
3590
+ text: "\u65B0\u589E",
3591
+ icon: vue.markRaw(icons.Plus),
3592
+ display: () => node.value?.items,
3593
+ items: getSubMenuData.value
3594
+ },
3595
+ {
3596
+ type: "button",
3597
+ text: "\u590D\u5236",
3598
+ icon: vue.markRaw(icons.DocumentCopy),
3599
+ display: () => !isRoot.value,
3600
+ handler: () => {
3601
+ node.value && services?.editorService.copy(node.value);
3602
+ }
3603
+ },
3604
+ {
3605
+ type: "button",
3606
+ text: "\u5220\u9664",
3607
+ icon: vue.markRaw(icons.Delete),
3608
+ display: () => !isRoot.value && !isPage.value,
3609
+ handler: () => {
3610
+ node.value && services?.editorService.remove(node.value);
3611
+ }
3612
+ }
3613
+ ]),
3614
+ show(e) {
3615
+ menu.value?.show(e);
3338
3616
  }
3339
3617
  };
3340
3618
  }
3341
3619
  });
3342
- const _hoisted_1$6 = {
3343
- key: 0,
3344
- class: "magic-editor-content-menu"
3345
- };
3346
- const _hoisted_2$2 = ["onClick"];
3347
- const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3348
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3349
- const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
3350
- return _ctx.node ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
3351
- _ctx.node.items ? (vue.openBlock(), vue.createElementBlock("div", {
3352
- key: 0,
3353
- class: "magic-editor-content-menu-item",
3354
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisitable(true)),
3355
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisitable(false))
3356
- }, " \u65B0\u589E ", 32)) : vue.createCommentVNode("", true),
3357
- _ctx.node.type !== "app" ? (vue.openBlock(), vue.createElementBlock("div", {
3358
- key: 1,
3359
- class: "magic-editor-content-menu-item",
3360
- onClick: _cache[2] || (_cache[2] = () => _ctx.copy(_ctx.node))
3361
- }, "\u590D\u5236")) : vue.createCommentVNode("", true),
3362
- _ctx.node.type !== "app" && _ctx.node.type !== "page" ? (vue.openBlock(), vue.createElementBlock("div", {
3363
- key: 2,
3364
- class: "magic-editor-content-menu-item",
3365
- onClick: _cache[3] || (_cache[3] = () => _ctx.remove())
3366
- }, " \u5220\u9664 ")) : vue.createCommentVNode("", true),
3367
- vue.withDirectives(vue.createElementVNode("div", {
3368
- class: "subMenu",
3369
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisitable(true)),
3370
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisitable(false))
3371
- }, [
3372
- vue.createVNode(_component_el_scrollbar, null, {
3373
- default: vue.withCtx(() => [
3374
- _ctx.node.type === "tabs" ? (vue.openBlock(), vue.createElementBlock("div", {
3375
- key: 0,
3376
- class: "magic-editor-content-menu-item",
3377
- onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3378
- type: "tab-pane"
3379
- }))
3380
- }, " \u6807\u7B7E ")) : _ctx.node.items ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.componentGroupList, (list) => {
3381
- return vue.openBlock(), vue.createElementBlock("div", {
3382
- key: list.title
3383
- }, [
3384
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(list.items, (item) => {
3385
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
3386
- item ? (vue.openBlock(), vue.createElementBlock("div", {
3387
- class: "magic-editor-content-menu-item",
3388
- key: item.type,
3389
- onClick: () => _ctx.append(item)
3390
- }, vue.toDisplayString(item.text), 9, _hoisted_2$2)) : vue.createCommentVNode("", true)
3391
- ], 64);
3392
- }), 256)),
3393
- _hoisted_3$2
3394
- ]);
3395
- }), 128)) : vue.createCommentVNode("", true)
3396
- ]),
3397
- _: 1
3398
- })
3399
- ], 544), [
3400
- [vue.vShow, _ctx.subVisible]
3401
- ])
3402
- ])) : vue.createCommentVNode("", true);
3620
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3621
+ const _component_content_menu = vue.resolveComponent("content-menu");
3622
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
3623
+ "menu-data": _ctx.menuData,
3624
+ ref: "menu",
3625
+ style: { "overflow": "initial" }
3626
+ }, null, 8, ["menu-data"]);
3403
3627
  }
3404
- var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3628
+ var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3405
3629
 
3406
3630
  const throttleTime = 150;
3407
3631
  const select = async (data, editorService) => {
@@ -3493,56 +3717,37 @@
3493
3717
  tree.value?.filter(val);
3494
3718
  }
3495
3719
  });
3496
- const useContentMenu = (editorService) => {
3497
- const menuStyle = vue.ref({
3498
- position: "absolute",
3499
- left: "0",
3500
- top: "0",
3501
- display: "none"
3502
- });
3503
- vue.onMounted(() => {
3504
- document.addEventListener("click", () => {
3505
- menuStyle.value.display = "none";
3506
- }, true);
3507
- });
3508
- return {
3509
- menuStyle,
3510
- contextmenu(event, data) {
3511
- const bodyHeight = globalThis.document.body.clientHeight;
3512
- const left = `${event.clientX + 20}px`;
3513
- let top = `${event.clientY - 10}px`;
3514
- if (event.clientY + 300 > bodyHeight) {
3515
- top = `${bodyHeight - 300}px`;
3516
- }
3517
- menuStyle.value.left = left;
3518
- menuStyle.value.top = top;
3519
- menuStyle.value.display = "";
3520
- select(data, editorService);
3521
- }
3522
- };
3523
- };
3524
- const _sfc_main$7 = vue.defineComponent({
3720
+ const _sfc_main$8 = vue.defineComponent({
3525
3721
  name: "magic-editor-layer-panel",
3526
3722
  components: { LayerMenu },
3527
3723
  setup() {
3528
3724
  const services = vue.inject("services");
3529
3725
  const tree = vue.ref();
3726
+ const menu = vue.ref();
3530
3727
  const clicked = vue.ref(false);
3531
3728
  const editorService = services?.editorService;
3532
3729
  const highlightHandler = lodashEs.throttle((data) => {
3533
3730
  highlight(data, editorService);
3534
3731
  }, throttleTime);
3535
- const toogleClickFlag = () => {
3732
+ const toggleClickFlag = () => {
3536
3733
  clicked.value = !clicked.value;
3537
3734
  };
3538
3735
  const statusData = useStatus(tree, editorService);
3539
3736
  const canHighlight = vue.computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3737
+ editorService?.on("remove", () => {
3738
+ setTimeout(() => {
3739
+ tree.value?.getNode(editorService.get("node").id)?.updateChildren();
3740
+ }, 0);
3741
+ });
3540
3742
  return {
3541
3743
  tree,
3744
+ menu,
3542
3745
  ...statusData,
3543
3746
  ...useDrop(tree, editorService),
3544
3747
  ...useFilter(tree),
3545
- ...useContentMenu(editorService),
3748
+ highlightHandler,
3749
+ toggleClickFlag,
3750
+ canHighlight,
3546
3751
  clickHandler(data) {
3547
3752
  if (services?.uiService.get("uiSelectMode")) {
3548
3753
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
@@ -3551,14 +3756,16 @@
3551
3756
  tree.value?.setCurrentKey(data.id);
3552
3757
  select(data, editorService);
3553
3758
  },
3554
- highlightHandler,
3555
- toogleClickFlag,
3556
- canHighlight
3759
+ async contextmenu(event, data) {
3760
+ event.preventDefault();
3761
+ await select(data, editorService);
3762
+ menu.value?.show(event);
3763
+ }
3557
3764
  };
3558
3765
  }
3559
3766
  });
3560
- const _hoisted_1$5 = ["id", "onMouseenter"];
3561
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3767
+ const _hoisted_1$4 = ["id", "onMouseenter"];
3768
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3562
3769
  const _component_el_input = vue.resolveComponent("el-input");
3563
3770
  const _component_el_tree = vue.resolveComponent("el-tree");
3564
3771
  const _component_layer_menu = vue.resolveComponent("layer-menu");
@@ -3598,8 +3805,8 @@
3598
3805
  vue.createElementVNode("div", {
3599
3806
  id: data.id,
3600
3807
  class: vue.normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3601
- onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3602
- onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3808
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3809
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toggleClickFlag && _ctx.toggleClickFlag(...args)),
3603
3810
  onMouseenter: ($event) => _ctx.highlightHandler(data)
3604
3811
  }, [
3605
3812
  vue.renderSlot(_ctx.$slots, "layer-node-content", {
@@ -3608,42 +3815,33 @@
3608
3815
  }, () => [
3609
3816
  vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3610
3817
  ])
3611
- ], 42, _hoisted_1$5)
3818
+ ], 42, _hoisted_1$4)
3612
3819
  ]),
3613
3820
  _: 3
3614
3821
  }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3615
3822
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3616
- vue.createVNode(_component_layer_menu, {
3617
- style: vue.normalizeStyle(_ctx.menuStyle)
3618
- }, null, 8, ["style"])
3823
+ vue.createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
3619
3824
  ]))
3620
3825
  ]),
3621
3826
  _: 3
3622
3827
  });
3623
3828
  }
3624
- var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3829
+ var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3625
3830
 
3626
- const _sfc_main$6 = vue.defineComponent({
3627
- name: "m-sidebar",
3831
+ const _sfc_main$7 = vue.defineComponent({
3628
3832
  components: { MIcon },
3629
3833
  props: {
3630
3834
  data: {
3631
- type: Object,
3632
- default: () => ({ type: "tabs", status: "\u7EC4\u4EF6", items: ["component-list", "layer"] })
3835
+ type: Object
3633
3836
  }
3634
3837
  },
3635
3838
  setup(props) {
3636
- const activeTabName = vue.ref(props.data?.status);
3637
- vue.watch(() => props.data?.status, (status) => {
3638
- activeTabName.value = status || "0";
3639
- });
3640
3839
  return {
3641
- activeTabName,
3642
- items: vue.computed(() => props.data?.items.map((item) => {
3643
- if (typeof item !== "string") {
3644
- return item;
3840
+ config: vue.computed(() => {
3841
+ if (typeof props.data !== "string") {
3842
+ return props.data;
3645
3843
  }
3646
- switch (item) {
3844
+ switch (props.data) {
3647
3845
  case "component-list":
3648
3846
  return {
3649
3847
  type: "component",
@@ -3661,21 +3859,75 @@
3661
3859
  slots: {}
3662
3860
  };
3663
3861
  default:
3664
- return {};
3862
+ return void 0;
3665
3863
  }
3666
- }))
3864
+ })
3667
3865
  };
3668
3866
  }
3669
3867
  });
3670
- const _hoisted_1$4 = {
3868
+ const _hoisted_1$3 = {
3671
3869
  key: 1,
3672
3870
  class: "magic-editor-tab-panel-title"
3673
3871
  };
3674
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3872
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3675
3873
  const _component_m_icon = vue.resolveComponent("m-icon");
3676
3874
  const _component_el_tab_pane = vue.resolveComponent("el-tab-pane");
3875
+ return _ctx.config ? (vue.openBlock(), vue.createBlock(_component_el_tab_pane, {
3876
+ key: 0,
3877
+ name: _ctx.config.text
3878
+ }, {
3879
+ label: vue.withCtx(() => [
3880
+ (vue.openBlock(), vue.createElementBlock("div", {
3881
+ key: _ctx.config.text
3882
+ }, [
3883
+ _ctx.config.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3884
+ key: 0,
3885
+ icon: _ctx.config.icon
3886
+ }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3887
+ _ctx.config.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, vue.toDisplayString(_ctx.config.text), 1)) : vue.createCommentVNode("", true)
3888
+ ]))
3889
+ ]),
3890
+ default: vue.withCtx(() => [
3891
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.config.component), vue.mergeProps(_ctx.config.props || {}, vue.toHandlers(_ctx.config?.listeners || {})), vue.createSlots({ _: 2 }, [
3892
+ _ctx.config.slots?.layerNodeContent ? {
3893
+ name: "layer-node-content",
3894
+ fn: vue.withCtx(({ data, node }) => [
3895
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.config.slots?.layerNodeContent), {
3896
+ data,
3897
+ node
3898
+ }, null, 8, ["data", "node"]))
3899
+ ])
3900
+ } : void 0
3901
+ ]), 1040))
3902
+ ]),
3903
+ _: 1
3904
+ }, 8, ["name"])) : vue.createCommentVNode("", true);
3905
+ }
3906
+ var TabPane = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3907
+
3908
+ const _sfc_main$6 = vue.defineComponent({
3909
+ components: { TabPane },
3910
+ name: "m-sidebar",
3911
+ props: {
3912
+ data: {
3913
+ type: Object,
3914
+ default: () => ({ type: "tabs", status: "\u7EC4\u4EF6", items: ["component-list", "layer"] })
3915
+ }
3916
+ },
3917
+ setup(props) {
3918
+ const activeTabName = vue.ref(props.data?.status);
3919
+ vue.watch(() => props.data?.status, (status) => {
3920
+ activeTabName.value = status || "0";
3921
+ });
3922
+ return {
3923
+ activeTabName
3924
+ };
3925
+ }
3926
+ });
3927
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3928
+ const _component_tab_pane = vue.resolveComponent("tab-pane");
3677
3929
  const _component_el_tabs = vue.resolveComponent("el-tabs");
3678
- return _ctx.data.type === "tabs" ? (vue.openBlock(), vue.createBlock(_component_el_tabs, {
3930
+ return _ctx.data.type === "tabs" && _ctx.data.items.length ? (vue.openBlock(), vue.createBlock(_component_el_tabs, {
3679
3931
  key: 0,
3680
3932
  class: "m-editor-sidebar",
3681
3933
  modelValue: _ctx.activeTabName,
@@ -3684,35 +3936,11 @@
3684
3936
  "tab-position": "left"
3685
3937
  }, {
3686
3938
  default: vue.withCtx(() => [
3687
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.items, (item) => {
3688
- return vue.openBlock(), vue.createBlock(_component_el_tab_pane, {
3689
- key: item.text,
3690
- name: item.text
3691
- }, {
3692
- label: vue.withCtx(() => [
3693
- vue.createElementVNode("span", null, [
3694
- item.icon ? (vue.openBlock(), vue.createBlock(_component_m_icon, {
3695
- key: 0,
3696
- icon: item.icon
3697
- }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3698
- item.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, vue.toDisplayString(item.text), 1)) : vue.createCommentVNode("", true)
3699
- ])
3700
- ]),
3701
- default: vue.withCtx(() => [
3702
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.component), vue.mergeProps(item.props || {}, vue.toHandlers(item.listeners || {})), vue.createSlots({ _: 2 }, [
3703
- item.slots?.layerNodeContent ? {
3704
- name: "layer-node-content",
3705
- fn: vue.withCtx(({ data, node }) => [
3706
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.slots.layerNodeContent), {
3707
- data,
3708
- node
3709
- }, null, 8, ["data", "node"]))
3710
- ])
3711
- } : void 0
3712
- ]), 1040))
3713
- ]),
3714
- _: 2
3715
- }, 1032, ["name"]);
3939
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.data.items, (item, index) => {
3940
+ return vue.openBlock(), vue.createBlock(_component_tab_pane, {
3941
+ key: index,
3942
+ data: item
3943
+ }, null, 8, ["data"]);
3716
3944
  }), 128))
3717
3945
  ]),
3718
3946
  _: 1
@@ -3785,12 +4013,14 @@
3785
4013
  };
3786
4014
  };
3787
4015
  const _sfc_main$5 = vue.defineComponent({
3788
- components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus },
4016
+ components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus, ToolButton },
3789
4017
  setup() {
3790
4018
  const services = vue.inject("services");
3791
4019
  const editorService = services?.editorService;
3792
4020
  const root = vue.computed(() => editorService?.get("root"));
3793
4021
  return {
4022
+ Delete: vue.markRaw(icons.Delete),
4023
+ DocumentCopy: vue.markRaw(icons.DocumentCopy),
3794
4024
  ...useScroll(root),
3795
4025
  root,
3796
4026
  page: vue.computed(() => editorService?.get("page")),
@@ -3819,23 +4049,22 @@
3819
4049
  };
3820
4050
  }
3821
4051
  });
3822
- const _hoisted_1$3 = {
4052
+ const _hoisted_1$2 = {
3823
4053
  class: "m-editor-page-bar",
3824
4054
  ref: "pageBar"
3825
4055
  };
3826
- const _hoisted_2$1 = ["onClick"];
3827
- const _hoisted_3$1 = { class: "m-editor-page-bar-title" };
3828
- const _hoisted_4$1 = ["onClick"];
3829
- const _hoisted_5 = ["onClick"];
4056
+ const _hoisted_2 = ["onClick"];
4057
+ const _hoisted_3 = { class: "m-editor-page-bar-title" };
3830
4058
  function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3831
4059
  const _component_plus = vue.resolveComponent("plus");
3832
4060
  const _component_el_icon = vue.resolveComponent("el-icon");
3833
4061
  const _component_arrow_left_bold = vue.resolveComponent("arrow-left-bold");
3834
4062
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
4063
+ const _component_tool_button = vue.resolveComponent("tool-button");
3835
4064
  const _component_caret_bottom = vue.resolveComponent("caret-bottom");
3836
4065
  const _component_el_popover = vue.resolveComponent("el-popover");
3837
4066
  const _component_arrow_right_bold = vue.resolveComponent("arrow-right-bold");
3838
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
4067
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
3839
4068
  vue.createElementVNode("div", {
3840
4069
  id: "m-editor-page-bar-add-icon",
3841
4070
  class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
@@ -3872,7 +4101,7 @@
3872
4101
  class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3873
4102
  onClick: ($event) => _ctx.switchPage(item)
3874
4103
  }, [
3875
- vue.createElementVNode("div", _hoisted_3$1, [
4104
+ vue.createElementVNode("div", _hoisted_3, [
3876
4105
  vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3877
4106
  vue.createVNode(_component_el_tooltip, {
3878
4107
  effect: "dark",
@@ -3887,6 +4116,7 @@
3887
4116
  ])
3888
4117
  ]),
3889
4118
  vue.createVNode(_component_el_popover, {
4119
+ "popper-class": "page-bar-popover",
3890
4120
  placement: "top",
3891
4121
  width: 160,
3892
4122
  trigger: "hover"
@@ -3902,20 +4132,28 @@
3902
4132
  default: vue.withCtx(() => [
3903
4133
  vue.createElementVNode("div", null, [
3904
4134
  vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3905
- vue.createElementVNode("div", {
3906
- class: "magic-editor-content-menu-item",
3907
- onClick: () => _ctx.copy(item)
3908
- }, "\u590D\u5236", 8, _hoisted_4$1),
3909
- vue.createElementVNode("div", {
3910
- class: "magic-editor-content-menu-item",
3911
- onClick: () => _ctx.remove(item)
3912
- }, "\u5220\u9664", 8, _hoisted_5)
4135
+ vue.createVNode(_component_tool_button, {
4136
+ data: {
4137
+ type: "button",
4138
+ text: "\u590D\u5236",
4139
+ icon: _ctx.DocumentCopy,
4140
+ handler: () => _ctx.copy(item)
4141
+ }
4142
+ }, null, 8, ["data"]),
4143
+ vue.createVNode(_component_tool_button, {
4144
+ data: {
4145
+ type: "button",
4146
+ text: "\u5220\u9664",
4147
+ icon: _ctx.Delete,
4148
+ handler: () => _ctx.remove(item)
4149
+ }
4150
+ }, null, 8, ["data"])
3913
4151
  ])
3914
4152
  ])
3915
4153
  ]),
3916
4154
  _: 2
3917
4155
  }, 1024)
3918
- ], 10, _hoisted_2$1);
4156
+ ], 10, _hoisted_2);
3919
4157
  }), 128))
3920
4158
  ], 4)) : vue.createCommentVNode("", true),
3921
4159
  _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
@@ -4135,12 +4373,12 @@
4135
4373
  };
4136
4374
  }
4137
4375
  });
4138
- const _hoisted_1$2 = {
4376
+ const _hoisted_1$1 = {
4139
4377
  class: "m-editor-scroll-viewer-container",
4140
4378
  ref: "container"
4141
4379
  };
4142
4380
  function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
4143
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
4381
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
4144
4382
  vue.createElementVNode("div", {
4145
4383
  ref: "el",
4146
4384
  style: vue.normalizeStyle(_ctx.style)
@@ -4152,7 +4390,7 @@
4152
4390
  var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
4153
4391
 
4154
4392
  const _sfc_main$3 = vue.defineComponent({
4155
- name: "magic-editor-ui-viewer-menu",
4393
+ components: { ContentMenu },
4156
4394
  setup() {
4157
4395
  const services = vue.inject("services");
4158
4396
  const editorService = services?.editorService;
@@ -4161,6 +4399,7 @@
4161
4399
  const canCenter = vue.ref(false);
4162
4400
  const node = vue.computed(() => editorService?.get("node"));
4163
4401
  const parent = vue.computed(() => editorService?.get("parent"));
4402
+ const isPage = vue.computed(() => node.value?.type === schema.NodeType.PAGE);
4164
4403
  vue.onMounted(() => {
4165
4404
  const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
4166
4405
  canPaste.value = data !== "undefined" && !!data;
@@ -4173,133 +4412,114 @@
4173
4412
  }, { immediate: true });
4174
4413
  return {
4175
4414
  menu,
4176
- canPaste,
4177
- canDelete: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4178
- canMoveZPos: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4179
- canCenter,
4180
- center() {
4181
- node.value && editorService?.alignCenter(node.value);
4182
- },
4183
- copy() {
4184
- node.value && editorService?.copy(node.value);
4185
- canPaste.value = true;
4186
- },
4187
- paste() {
4188
- const top = menu.value?.offsetTop || 0;
4189
- const left = menu.value?.offsetLeft || 0;
4190
- editorService?.paste({ left, top });
4191
- },
4192
- remove() {
4193
- node.value && editorService?.remove(node.value);
4194
- },
4195
- top() {
4196
- editorService?.moveLayer(LayerOffset.TOP);
4197
- },
4198
- bottom() {
4199
- editorService?.moveLayer(LayerOffset.BOTTOM);
4200
- },
4201
- topItem() {
4202
- editorService?.moveLayer(1);
4203
- },
4204
- bottomItem() {
4205
- editorService?.moveLayer(-1);
4206
- },
4207
- clearGuides() {
4208
- editorService?.get("stage").clearGuides();
4415
+ menuData: vue.reactive([
4416
+ {
4417
+ type: "button",
4418
+ text: "\u6C34\u5E73\u5C45\u4E2D",
4419
+ display: () => canCenter.value,
4420
+ handler: () => {
4421
+ node.value && editorService?.alignCenter(node.value);
4422
+ }
4423
+ },
4424
+ {
4425
+ type: "button",
4426
+ text: "\u590D\u5236",
4427
+ icon: vue.markRaw(icons.DocumentCopy),
4428
+ handler: () => {
4429
+ node.value && editorService?.copy(node.value);
4430
+ canPaste.value = true;
4431
+ }
4432
+ },
4433
+ {
4434
+ type: "button",
4435
+ text: "\u7C98\u8D34",
4436
+ display: () => canPaste.value,
4437
+ handler: () => {
4438
+ const top = menu.value?.$el.offsetTop || 0;
4439
+ const left = menu.value?.$el.offsetLeft || 0;
4440
+ editorService?.paste({ left, top });
4441
+ }
4442
+ },
4443
+ {
4444
+ type: "divider",
4445
+ direction: "horizontal",
4446
+ display: () => !isPage.value
4447
+ },
4448
+ {
4449
+ type: "button",
4450
+ text: "\u4E0A\u79FB\u4E00\u5C42",
4451
+ icon: vue.markRaw(icons.Top),
4452
+ display: () => !isPage.value,
4453
+ handler: () => {
4454
+ editorService?.moveLayer(1);
4455
+ }
4456
+ },
4457
+ {
4458
+ type: "button",
4459
+ text: "\u4E0B\u79FB\u4E00\u5C42",
4460
+ icon: vue.markRaw(icons.Bottom),
4461
+ display: () => !isPage.value,
4462
+ handler: () => {
4463
+ editorService?.moveLayer(-1);
4464
+ }
4465
+ },
4466
+ {
4467
+ type: "button",
4468
+ text: "\u7F6E\u9876",
4469
+ display: () => !isPage.value,
4470
+ handler: () => {
4471
+ editorService?.moveLayer(LayerOffset.TOP);
4472
+ }
4473
+ },
4474
+ {
4475
+ type: "button",
4476
+ text: "\u7F6E\u5E95",
4477
+ display: () => !isPage.value,
4478
+ handler: () => {
4479
+ editorService?.moveLayer(LayerOffset.BOTTOM);
4480
+ }
4481
+ },
4482
+ {
4483
+ type: "divider",
4484
+ direction: "horizontal",
4485
+ display: () => !isPage.value
4486
+ },
4487
+ {
4488
+ type: "button",
4489
+ text: "\u5220\u9664",
4490
+ icon: icons.Delete,
4491
+ display: () => !isPage.value,
4492
+ handler: () => {
4493
+ node.value && editorService?.remove(node.value);
4494
+ }
4495
+ },
4496
+ {
4497
+ type: "divider",
4498
+ direction: "horizontal"
4499
+ },
4500
+ {
4501
+ type: "button",
4502
+ text: "\u6E05\u7A7A\u53C2\u8003\u7EBF",
4503
+ handler: () => {
4504
+ editorService?.get("stage").clearGuides();
4505
+ }
4506
+ }
4507
+ ]),
4508
+ show(e) {
4509
+ menu.value?.show(e);
4209
4510
  }
4210
4511
  };
4211
4512
  }
4212
4513
  });
4213
- const _hoisted_1$1 = {
4214
- class: "magic-editor-content-menu",
4215
- ref: "menu"
4216
- };
4217
- const _hoisted_2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4218
- const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4219
- const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
4220
4514
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
4221
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
4222
- vue.createElementVNode("div", null, [
4223
- _ctx.canCenter ? (vue.openBlock(), vue.createElementBlock("div", {
4224
- key: 0,
4225
- class: "magic-editor-content-menu-item",
4226
- onClick: _cache[0] || (_cache[0] = () => _ctx.center())
4227
- }, "\u6C34\u5E73\u5C45\u4E2D")) : vue.createCommentVNode("", true),
4228
- vue.createElementVNode("div", {
4229
- class: "magic-editor-content-menu-item",
4230
- onClick: _cache[1] || (_cache[1] = () => _ctx.copy())
4231
- }, "\u590D\u5236"),
4232
- _ctx.canPaste ? (vue.openBlock(), vue.createElementBlock("div", {
4233
- key: 1,
4234
- class: "magic-editor-content-menu-item",
4235
- onClick: _cache[2] || (_cache[2] = (...args) => _ctx.paste && _ctx.paste(...args))
4236
- }, "\u7C98\u8D34")) : vue.createCommentVNode("", true),
4237
- _ctx.canMoveZPos ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
4238
- _hoisted_2,
4239
- vue.createElementVNode("div", {
4240
- class: "magic-editor-content-menu-item",
4241
- onClick: _cache[3] || (_cache[3] = (...args) => _ctx.topItem && _ctx.topItem(...args))
4242
- }, "\u4E0A\u79FB\u4E00\u5C42"),
4243
- vue.createElementVNode("div", {
4244
- class: "magic-editor-content-menu-item",
4245
- onClick: _cache[4] || (_cache[4] = (...args) => _ctx.bottomItem && _ctx.bottomItem(...args))
4246
- }, "\u4E0B\u79FB\u4E00\u5C42"),
4247
- vue.createElementVNode("div", {
4248
- class: "magic-editor-content-menu-item",
4249
- onClick: _cache[5] || (_cache[5] = (...args) => _ctx.top && _ctx.top(...args))
4250
- }, "\u7F6E\u9876"),
4251
- vue.createElementVNode("div", {
4252
- class: "magic-editor-content-menu-item",
4253
- onClick: _cache[6] || (_cache[6] = (...args) => _ctx.bottom && _ctx.bottom(...args))
4254
- }, "\u7F6E\u5E95")
4255
- ], 64)) : vue.createCommentVNode("", true),
4256
- _ctx.canDelete ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
4257
- _hoisted_3,
4258
- vue.createElementVNode("div", {
4259
- class: "magic-editor-content-menu-item",
4260
- onClick: _cache[7] || (_cache[7] = () => _ctx.remove())
4261
- }, "\u5220\u9664")
4262
- ], 64)) : vue.createCommentVNode("", true),
4263
- _hoisted_4,
4264
- vue.createElementVNode("div", {
4265
- class: "magic-editor-content-menu-item",
4266
- onClick: _cache[8] || (_cache[8] = (...args) => _ctx.clearGuides && _ctx.clearGuides(...args))
4267
- }, "\u6E05\u7A7A\u53C2\u8003\u7EBF")
4268
- ])
4269
- ], 512);
4515
+ const _component_content_menu = vue.resolveComponent("content-menu");
4516
+ return vue.openBlock(), vue.createBlock(_component_content_menu, {
4517
+ "menu-data": _ctx.menuData,
4518
+ ref: "menu"
4519
+ }, null, 8, ["menu-data"]);
4270
4520
  }
4271
4521
  var ViewerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
4272
4522
 
4273
- const useMenu = () => {
4274
- const menu = vue.ref();
4275
- const menuStyle = vue.ref({
4276
- display: "none",
4277
- left: "0",
4278
- top: "0"
4279
- });
4280
- vue.onMounted(() => {
4281
- document.addEventListener("click", () => {
4282
- menuStyle.value.display = "none";
4283
- }, true);
4284
- });
4285
- return {
4286
- menu,
4287
- menuStyle,
4288
- contextmenuHandler(e) {
4289
- e.preventDefault();
4290
- const menuHeight = menu.value?.$el.clientHeight;
4291
- let top = e.clientY;
4292
- if (menuHeight + e.clientY > document.body.clientHeight) {
4293
- top = document.body.clientHeight - menuHeight;
4294
- }
4295
- menuStyle.value = {
4296
- display: "block",
4297
- top: `${top}px`,
4298
- left: `${e.clientX}px`
4299
- };
4300
- }
4301
- };
4302
- };
4303
4523
  const _sfc_main$2 = vue.defineComponent({
4304
4524
  name: "magic-stage",
4305
4525
  components: {
@@ -4326,11 +4546,12 @@
4326
4546
  const services = vue.inject("services");
4327
4547
  const stageWrap = vue.ref();
4328
4548
  const stageContainer = vue.ref();
4549
+ const menu = vue.ref();
4329
4550
  const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
4330
4551
  const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4331
4552
  const root = vue.computed(() => services?.editorService.get("root"));
4332
4553
  const page = vue.computed(() => services?.editorService.get("page"));
4333
- const zoom = vue.computed(() => services?.uiService.get("zoom"));
4554
+ const zoom = vue.computed(() => services?.uiService.get("zoom") || 1);
4334
4555
  const node = vue.computed(() => services?.editorService.get("node"));
4335
4556
  let stage = null;
4336
4557
  let runtime = null;
@@ -4412,9 +4633,36 @@
4412
4633
  return {
4413
4634
  stageWrap,
4414
4635
  stageContainer,
4636
+ menu,
4415
4637
  stageRect,
4416
4638
  zoom,
4417
- ...useMenu()
4639
+ contextmenuHandler(e2) {
4640
+ e2.preventDefault();
4641
+ menu.value?.show(e2);
4642
+ },
4643
+ dragoverHandler(e2) {
4644
+ e2.preventDefault();
4645
+ if (e2.dataTransfer) {
4646
+ e2.dataTransfer.dropEffect = "move";
4647
+ }
4648
+ },
4649
+ async dropHandler(e) {
4650
+ e.preventDefault();
4651
+ if (e.dataTransfer && page.value && stageContainer.value && stage) {
4652
+ const config = eval(`(${e.dataTransfer.getData("data")})`);
4653
+ const layout = await services?.editorService.getLayout(page.value);
4654
+ const containerRect = stageContainer.value.getBoundingClientRect();
4655
+ const { scrollTop, scrollLeft } = stage.mask;
4656
+ if (layout === Layout.ABSOLUTE) {
4657
+ config.style = {
4658
+ position: "absolute",
4659
+ top: e.clientY - containerRect.top + scrollTop,
4660
+ left: e.clientX - containerRect.left + scrollLeft
4661
+ };
4662
+ }
4663
+ services?.editorService.add(config, page.value);
4664
+ }
4665
+ }
4418
4666
  };
4419
4667
  }
4420
4668
  });
@@ -4432,14 +4680,13 @@
4432
4680
  vue.createElementVNode("div", {
4433
4681
  class: "m-editor-stage-container",
4434
4682
  ref: "stageContainer",
4683
+ style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`),
4435
4684
  onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4436
- style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`)
4685
+ onDrop: _cache[1] || (_cache[1] = (...args) => _ctx.dropHandler && _ctx.dropHandler(...args)),
4686
+ onDragover: _cache[2] || (_cache[2] = (...args) => _ctx.dragoverHandler && _ctx.dragoverHandler(...args))
4437
4687
  }, null, 36),
4438
4688
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4439
- vue.createVNode(_component_viewer_menu, {
4440
- ref: "menu",
4441
- style: vue.normalizeStyle(_ctx.menuStyle)
4442
- }, null, 8, ["style"])
4689
+ vue.createVNode(_component_viewer_menu, { ref: "menu" }, null, 512)
4443
4690
  ]))
4444
4691
  ]),
4445
4692
  _: 1
@@ -4486,10 +4733,10 @@
4486
4733
  }).keydown([ctrl, "c"], (e) => {
4487
4734
  e.inputEvent.preventDefault();
4488
4735
  node.value && services?.editorService.copy(node.value);
4489
- }).keyup([ctrl, "v"], (e) => {
4736
+ }).keydown([ctrl, "v"], (e) => {
4490
4737
  e.inputEvent.preventDefault();
4491
4738
  node.value && services?.editorService.paste();
4492
- }).keyup([ctrl, "x"], (e) => {
4739
+ }).keydown([ctrl, "x"], (e) => {
4493
4740
  e.inputEvent.preventDefault();
4494
4741
  if (!node.value || utils.isPage(node.value))
4495
4742
  return;
@@ -4879,6 +5126,7 @@
4879
5126
  exports.PropsPanel = PropsPanel;
4880
5127
  exports.TMagicCodeEditor = CodeEditor;
4881
5128
  exports.TMagicEditor = Editor;
5129
+ exports.ToolButton = ToolButton;
4882
5130
  exports.change2Fixed = change2Fixed;
4883
5131
  exports.debug = debug;
4884
5132
  exports["default"] = index;