@tmagic/editor 1.0.0-beta.1 → 1.0.0-beta.10

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 (47) hide show
  1. package/LICENSE +5432 -0
  2. package/dist/style.css +53 -24
  3. package/dist/tmagic-editor.es.js +832 -403
  4. package/dist/tmagic-editor.es.js.map +1 -1
  5. package/dist/tmagic-editor.umd.js +849 -403
  6. package/dist/tmagic-editor.umd.js.map +1 -1
  7. package/dist/types/src/Editor.vue.d.ts +5 -5
  8. package/dist/types/src/components/ScrollViewer.vue.d.ts +23 -0
  9. package/dist/types/src/layouts/CodeEditor.vue.d.ts +5 -4
  10. package/dist/types/src/layouts/NavMenu.vue.d.ts +2 -1
  11. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +10 -3
  12. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +8 -3
  13. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +77 -42
  14. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +2 -9
  15. package/dist/types/src/services/BaseService.d.ts +4 -1
  16. package/dist/types/src/services/editor.d.ts +11 -4
  17. package/dist/types/src/services/ui.d.ts +10 -3
  18. package/dist/types/src/type.d.ts +20 -6
  19. package/dist/types/src/utils/editor.d.ts +1 -2
  20. package/dist/types/src/utils/scroll-viewer.d.ts +35 -0
  21. package/package.json +15 -12
  22. package/src/Editor.vue +5 -5
  23. package/src/components/ScrollViewer.vue +66 -0
  24. package/src/components/ToolButton.vue +5 -3
  25. package/src/layouts/AddPageBox.vue +3 -1
  26. package/src/layouts/CodeEditor.vue +35 -59
  27. package/src/layouts/NavMenu.vue +7 -3
  28. package/src/layouts/PropsPanel.vue +6 -10
  29. package/src/layouts/sidebar/LayerMenu.vue +14 -39
  30. package/src/layouts/sidebar/LayerPanel.vue +63 -16
  31. package/src/layouts/workspace/PageBar.vue +113 -14
  32. package/src/layouts/workspace/Stage.vue +67 -61
  33. package/src/layouts/workspace/ViewerMenu.vue +5 -3
  34. package/src/layouts/workspace/Workspace.vue +3 -37
  35. package/src/services/BaseService.ts +70 -22
  36. package/src/services/editor.ts +98 -52
  37. package/src/services/ui.ts +42 -5
  38. package/src/theme/common/var.scss +2 -2
  39. package/src/theme/layer-panel.scss +9 -0
  40. package/src/theme/nav-menu.scss +3 -3
  41. package/src/theme/page-bar.scss +21 -2
  42. package/src/theme/props-panel.scss +8 -0
  43. package/src/theme/stage.scss +8 -7
  44. package/src/type.ts +23 -6
  45. package/src/utils/editor.ts +5 -23
  46. package/src/utils/scroll-viewer.ts +216 -0
  47. package/dist/types/src/layouts/sidebar/LayerMenu.vue.d.ts +0 -31
@@ -1,12 +1,31 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue'), require('serialize-javascript'), require('@tmagic/utils'), require('@element-plus/icons'), require('lodash-es'), require('events'), require('@tmagic/core'), require('element-plus'), require('@tmagic/stage')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'vue', 'serialize-javascript', '@tmagic/utils', '@element-plus/icons', 'lodash-es', 'events', '@tmagic/core', 'element-plus', '@tmagic/stage'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TMagicEditor = {}, global.vue, global.serialize, global.utils, global.icons, global.lodashEs, global.events, global.core, global.elementPlus, global.StageCore));
5
- })(this, (function (exports, vue, serialize, utils, icons, lodashEs, 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('@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';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = {__proto__: null, [Symbol.toStringTag]: 'Module'};
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n["default"] = e;
24
+ return Object.freeze(n);
25
+ }
26
+
9
27
  var serialize__default = /*#__PURE__*/_interopDefaultLegacy(serialize);
28
+ var monaco__namespace = /*#__PURE__*/_interopNamespace(monaco);
10
29
  var StageCore__default = /*#__PURE__*/_interopDefaultLegacy(StageCore);
11
30
 
12
31
  var _export_sfc = (sfc, props) => {
@@ -17,7 +36,7 @@
17
36
  return target;
18
37
  };
19
38
 
20
- const _sfc_main$j = vue.defineComponent({
39
+ const _sfc_main$k = vue.defineComponent({
21
40
  name: "m-fields-vs-code",
22
41
  props: ["model", "name", "config", "prop"],
23
42
  emits: ["change"],
@@ -34,7 +53,7 @@
34
53
  };
35
54
  }
36
55
  });
37
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
56
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
38
57
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
39
58
  return vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
40
59
  style: vue.normalizeStyle(`height: ${_ctx.height}`),
@@ -43,9 +62,9 @@
43
62
  onSave: _ctx.save
44
63
  }, null, 8, ["style", "init-values", "language", "onSave"]);
45
64
  }
46
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
65
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
47
66
 
48
- const _sfc_main$i = vue.defineComponent({
67
+ const _sfc_main$j = vue.defineComponent({
49
68
  name: "m-fields-code-link",
50
69
  props: {
51
70
  config: {
@@ -100,7 +119,7 @@
100
119
  };
101
120
  }
102
121
  });
103
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
122
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
104
123
  const _component_m_fields_link = vue.resolveComponent("m-fields-link");
105
124
  return vue.openBlock(), vue.createBlock(_component_m_fields_link, {
106
125
  config: _ctx.formConfig,
@@ -109,11 +128,11 @@
109
128
  onChange: _ctx.changeHandler
110
129
  }, null, 8, ["config", "model", "onChange"]);
111
130
  }
112
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
131
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
113
132
 
114
133
  var UISelect_vue_vue_type_style_index_0_lang = '';
115
134
 
116
- const _sfc_main$h = vue.defineComponent({
135
+ const _sfc_main$i = vue.defineComponent({
117
136
  name: "m-fields-ui-select",
118
137
  props: {
119
138
  labelWidth: String,
@@ -175,15 +194,15 @@
175
194
  };
176
195
  }
177
196
  });
178
- const _hoisted_1$d = /* @__PURE__ */ vue.createElementVNode("i", {
197
+ const _hoisted_1$e = /* @__PURE__ */ vue.createElementVNode("i", {
179
198
  class: "el-icon-delete",
180
199
  style: { "color": "rgb(221, 75, 57)" }
181
200
  }, "\u53D6\u6D88", -1);
182
201
  const _hoisted_2$7 = [
183
- _hoisted_1$d
202
+ _hoisted_1$e
184
203
  ];
185
204
  const _hoisted_3$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
186
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
205
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
187
206
  return _ctx.uiSelectMode ? (vue.openBlock(), vue.createElementBlock("div", {
188
207
  key: 0,
189
208
  class: "m-fields-ui-select",
@@ -202,23 +221,8 @@
202
221
  })) : vue.createCommentVNode("", true)
203
222
  ]));
204
223
  }
205
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
224
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
206
225
 
207
- const initEditor = () => {
208
- if (globalThis.monaco) {
209
- Promise.resolve(globalThis.monaco);
210
- }
211
- return utils.asyncLoadJs(`https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js`).then(() => {
212
- globalThis.require.config({
213
- paths: { vs: `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs` }
214
- });
215
- return new Promise((resolve) => {
216
- globalThis.require(["vs/editor/editor.main"], () => {
217
- resolve(globalThis.monaco);
218
- });
219
- });
220
- });
221
- };
222
226
  const toString = (v, language) => {
223
227
  let value = "";
224
228
  if (typeof v !== "string") {
@@ -234,7 +238,7 @@
234
238
  }
235
239
  return value;
236
240
  };
237
- const _sfc_main$g = vue.defineComponent({
241
+ const _sfc_main$h = vue.defineComponent({
238
242
  name: "magic-code-editor",
239
243
  props: {
240
244
  initValues: {
@@ -252,32 +256,34 @@
252
256
  default: () => "javascript"
253
257
  }
254
258
  },
255
- emits: ["inited", "save"],
259
+ emits: ["initd", "save"],
256
260
  setup(props, { emit }) {
257
261
  let vsEditor = null;
262
+ let vsDiffEditor = null;
258
263
  const values = vue.ref("");
259
264
  const loading = vue.ref(false);
260
265
  const codeEditor = vue.ref();
261
266
  const setEditorValue = (v, m) => {
262
267
  values.value = toString(v, props.language);
263
268
  if (props.type === "diff") {
264
- const originalModel = globalThis.monaco.editor.createModel(values.value, "text/javascript");
265
- const modifiedModel = globalThis.monaco.editor.createModel(toString(m, props.language), "text/javascript");
266
- return vsEditor.setModel({
269
+ const originalModel = monaco__namespace.editor.createModel(values.value, "text/javascript");
270
+ const modifiedModel = monaco__namespace.editor.createModel(toString(m, props.language), "text/javascript");
271
+ return vsDiffEditor?.setModel({
267
272
  original: originalModel,
268
273
  modified: modifiedModel
269
274
  });
270
275
  }
271
- return vsEditor.setValue?.(values.value);
276
+ return vsEditor?.setValue(values.value);
272
277
  };
273
278
  const resizeHandler = () => {
274
279
  vsEditor?.layout();
280
+ vsDiffEditor?.layout();
275
281
  };
276
- const getEditorValue = () => vsEditor.getValue?.() || "";
282
+ const getEditorValue = () => props.type === "diff" ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
277
283
  const init = async () => {
278
284
  if (!codeEditor.value)
279
285
  return;
280
- vsEditor = globalThis.monaco.editor[props.type === "diff" ? "createDiffEditor" : "create"](codeEditor.value, {
286
+ const options = {
281
287
  value: values.value,
282
288
  language: props.language,
283
289
  tabSize: 2,
@@ -285,10 +291,15 @@
285
291
  fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
286
292
  fontSize: 15,
287
293
  formatOnPaste: true
288
- });
294
+ };
295
+ if (props.type === "diff") {
296
+ vsDiffEditor = monaco__namespace.editor.createDiffEditor(codeEditor.value, options);
297
+ } else {
298
+ vsEditor = monaco__namespace.editor.create(codeEditor.value, options);
299
+ }
289
300
  setEditorValue(props.initValues, props.modifiedValues);
290
301
  loading.value = false;
291
- emit("inited", vsEditor);
302
+ emit("initd", vsEditor);
292
303
  codeEditor.value.addEventListener("keydown", (e) => {
293
304
  if (e.keyCode === 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
294
305
  e.preventDefault();
@@ -296,14 +307,14 @@
296
307
  }
297
308
  });
298
309
  if (props.type !== "diff") {
299
- vsEditor.onDidBlurEditorWidget(() => {
310
+ vsEditor?.onDidBlurEditorWidget(() => {
300
311
  emit("save", getEditorValue());
301
312
  });
302
313
  }
303
314
  globalThis.addEventListener("resize", resizeHandler);
304
315
  };
305
316
  vue.watch(() => props.initValues, (v, preV) => {
306
- if (vsEditor && v !== preV) {
317
+ if (v !== preV) {
307
318
  setEditorValue(props.initValues, props.modifiedValues);
308
319
  }
309
320
  }, {
@@ -312,17 +323,7 @@
312
323
  });
313
324
  vue.onMounted(async () => {
314
325
  loading.value = true;
315
- await initEditor();
316
- if (!globalThis.monaco) {
317
- const interval = setInterval(() => {
318
- if (globalThis.monaco) {
319
- clearInterval(interval);
320
- init();
321
- }
322
- }, 300);
323
- } else {
324
- init();
325
- }
326
+ init();
326
327
  });
327
328
  vue.onUnmounted(() => {
328
329
  globalThis.removeEventListener("resize", resizeHandler);
@@ -332,23 +333,24 @@
332
333
  loading,
333
334
  codeEditor,
334
335
  getEditor() {
335
- return vsEditor;
336
+ return vsEditor || vsDiffEditor;
336
337
  },
337
338
  setEditorValue,
338
339
  focus() {
339
- vsEditor.focus();
340
+ vsEditor?.focus();
341
+ vsDiffEditor?.focus();
340
342
  }
341
343
  };
342
344
  }
343
345
  });
344
- const _hoisted_1$c = {
346
+ const _hoisted_1$d = {
345
347
  ref: "codeEditor",
346
348
  class: "magic-code-editor"
347
349
  };
348
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
349
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, null, 512);
350
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
351
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$d, null, 512);
350
352
  }
351
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
353
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
352
354
 
353
355
  let $TMAGIC_EDITOR = {};
354
356
  const setConfig = (option) => {
@@ -432,10 +434,39 @@
432
434
 
433
435
  const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
434
436
  const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
437
+ const doAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
438
+ try {
439
+ let beforeArgs = args;
440
+ for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
441
+ let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
442
+ if (isError(beforeReturnValue))
443
+ throw beforeReturnValue;
444
+ if (!Array.isArray(beforeReturnValue)) {
445
+ beforeReturnValue = [beforeReturnValue];
446
+ }
447
+ beforeArgs = beforeArgs.map((v, index) => {
448
+ if (typeof beforeReturnValue[index] === "undefined")
449
+ return v;
450
+ return beforeReturnValue[index];
451
+ });
452
+ }
453
+ let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
454
+ for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
455
+ returnValue = await afterMethod(...beforeArgs, returnValue);
456
+ if (isError(returnValue))
457
+ throw returnValue;
458
+ }
459
+ return returnValue;
460
+ } catch (error) {
461
+ throw error;
462
+ }
463
+ };
435
464
  class BaseService extends events.EventEmitter {
436
465
  pluginOptionsList = {};
437
466
  middleware = {};
438
- constructor(methods) {
467
+ taskList = [];
468
+ doingTask = false;
469
+ constructor(methods = [], serialMethods = []) {
439
470
  super();
440
471
  methods.forEach((propertyName) => {
441
472
  const scope = this;
@@ -448,27 +479,23 @@
448
479
  const fn = compose(this.middleware[propertyName]);
449
480
  Object.defineProperty(scope, propertyName, {
450
481
  value: async (...args) => {
451
- let beforeArgs = args;
452
- for (const beforeMethod of this.pluginOptionsList[beforeMethodName]) {
453
- let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
454
- if (isError(beforeReturnValue))
455
- throw beforeReturnValue;
456
- if (!Array.isArray(beforeReturnValue)) {
457
- beforeReturnValue = [beforeReturnValue];
458
- }
459
- beforeArgs = beforeArgs.map((v, index) => {
460
- if (typeof beforeReturnValue[index] === "undefined")
461
- return v;
462
- return beforeReturnValue[index];
463
- });
482
+ if (!serialMethods.includes(propertyName)) {
483
+ return doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
464
484
  }
465
- let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
466
- for (const afterMethod of this.pluginOptionsList[afterMethodName]) {
467
- returnValue = await afterMethod(...beforeArgs, returnValue);
468
- if (isError(returnValue))
469
- throw returnValue;
485
+ const promise = new Promise((resolve, reject) => {
486
+ this.taskList.push(async () => {
487
+ try {
488
+ const value = await doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
489
+ resolve(value);
490
+ } catch (e) {
491
+ reject(e);
492
+ }
493
+ });
494
+ });
495
+ if (!this.doingTask) {
496
+ this.doTask();
470
497
  }
471
- return returnValue;
498
+ return promise;
472
499
  }
473
500
  });
474
501
  });
@@ -485,6 +512,15 @@
485
512
  this.pluginOptionsList[methodName2].push(method);
486
513
  });
487
514
  }
515
+ async doTask() {
516
+ this.doingTask = true;
517
+ let task = this.taskList.shift();
518
+ while (task) {
519
+ await task();
520
+ task = this.taskList.shift();
521
+ }
522
+ this.doingTask = false;
523
+ }
488
524
  }
489
525
 
490
526
  class History extends BaseService {
@@ -621,12 +657,16 @@
621
657
  Layout2["ABSOLUTE"] = "absolute";
622
658
  return Layout2;
623
659
  })(Layout || {});
660
+ var Keys = /* @__PURE__ */ ((Keys2) => {
661
+ Keys2["ESCAPE"] = "Space";
662
+ return Keys2;
663
+ })(Keys || {});
624
664
 
625
665
  const COPY_STORAGE_KEY = "$MagicEditorCopyData";
626
666
  const generateId = (type) => `${type}_${lodashEs.random(1e4, false)}`;
627
667
  const getPageList = (app) => {
628
668
  if (app.items && Array.isArray(app.items)) {
629
- return app.items.filter((item) => item.type === "page");
669
+ return app.items.filter((item) => item.type === schema.NodeType.PAGE);
630
670
  }
631
671
  return [];
632
672
  };
@@ -662,7 +702,7 @@
662
702
  const oldId = config.id;
663
703
  config.id = generateId(config.type);
664
704
  config.name = `${config.name?.replace(/_(\d+)$/, "")}_${config.id}`;
665
- if (utils.isPop(config) && parent?.type === "page") {
705
+ if (utils.isPop(config) && parent?.type === schema.NodeType.PAGE) {
666
706
  updatePopId(oldId, config.id, parent);
667
707
  }
668
708
  if (config.items && Array.isArray(config.items)) {
@@ -755,22 +795,6 @@
755
795
  }
756
796
  return toRelative(node);
757
797
  };
758
- const defaults = (object, source) => {
759
- let o = source;
760
- if (Array.isArray(object)) {
761
- o = object;
762
- }
763
- Object.entries(o).forEach(([key, value]) => {
764
- if (typeof object[key] === "undefined") {
765
- object[key] = value;
766
- return;
767
- }
768
- if (value && typeof value !== "string" && Object.keys(value).length) {
769
- object[key] = defaults(lodashEs.cloneDeep(object[key]), value);
770
- }
771
- });
772
- return object;
773
- };
774
798
 
775
799
  const log = (...args) => {
776
800
  };
@@ -791,6 +815,7 @@
791
815
  parent: null,
792
816
  node: null,
793
817
  stage: null,
818
+ highlightNode: null,
794
819
  modifiedNodeIds: /* @__PURE__ */ new Map()
795
820
  });
796
821
  constructor() {
@@ -806,8 +831,9 @@
806
831
  "alignCenter",
807
832
  "moveLayer",
808
833
  "undo",
809
- "redo"
810
- ]);
834
+ "redo",
835
+ "highlight"
836
+ ], ["select", "update", "moveLayer"]);
811
837
  }
812
838
  set(name, value) {
813
839
  this.state[name] = value;
@@ -833,7 +859,7 @@
833
859
  info.node = path[path.length - 1];
834
860
  info.parent = path[path.length - 2];
835
861
  path.forEach((item) => {
836
- if (item.type === "page") {
862
+ if (item.type === schema.NodeType.PAGE) {
837
863
  info.page = item;
838
864
  return;
839
865
  }
@@ -860,18 +886,7 @@
860
886
  return Layout.ABSOLUTE;
861
887
  }
862
888
  async select(config2) {
863
- let id;
864
- if (typeof config2 === "string" || typeof config2 === "number") {
865
- id = config2;
866
- } else {
867
- id = config2.id;
868
- }
869
- if (!id) {
870
- throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
871
- }
872
- const { node, parent, page } = this.getNodeInfo(id);
873
- if (!node)
874
- throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
889
+ const { node, page, parent } = this.selectedConfigExceptionHandler(config2);
875
890
  this.set("node", node);
876
891
  this.set("page", page || null);
877
892
  this.set("parent", parent || null);
@@ -882,10 +897,17 @@
882
897
  }
883
898
  return node;
884
899
  }
900
+ highlight(config2) {
901
+ const { node } = this.selectedConfigExceptionHandler(config2);
902
+ const currentHighlightNode = this.get("highlightNode");
903
+ if (currentHighlightNode === node)
904
+ return;
905
+ this.set("highlightNode", node);
906
+ }
885
907
  async add({ type, ...config2 }, parent) {
886
908
  const curNode = this.get("node");
887
909
  let parentNode;
888
- if (type === "page") {
910
+ if (type === schema.NodeType.PAGE) {
889
911
  parentNode = this.get("root");
890
912
  } else if (parent && typeof parent !== "function") {
891
913
  parentNode = parent;
@@ -898,14 +920,18 @@
898
920
  throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
899
921
  const layout = await this.getLayout(parentNode);
900
922
  const newNode = initPosition({ ...vue.toRaw(await propsService.getPropsValue(type)), ...config2 }, layout);
901
- if ((parentNode?.type === "app" || curNode.type === "app") && newNode.type !== "page") {
923
+ if ((parentNode?.type === schema.NodeType.ROOT || curNode.type === schema.NodeType.ROOT) && newNode.type !== schema.NodeType.PAGE) {
902
924
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
903
925
  }
904
926
  parentNode?.items?.push(newNode);
905
- await this.get("stage")?.add({ config: lodashEs.cloneDeep(newNode), root: lodashEs.cloneDeep(this.get("root")) });
927
+ const stage = this.get("stage");
928
+ await stage?.add({ config: lodashEs.cloneDeep(newNode), root: lodashEs.cloneDeep(this.get("root")) });
906
929
  await this.select(newNode);
907
930
  this.addModifiedNodeId(newNode.id);
908
- this.pushHistoryState();
931
+ if (type !== schema.NodeType.PAGE) {
932
+ this.pushHistoryState();
933
+ }
934
+ stage?.select(newNode.id);
909
935
  return newNode;
910
936
  }
911
937
  async remove(node) {
@@ -921,11 +947,16 @@
921
947
  if (typeof index !== "number" || index === -1)
922
948
  throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
923
949
  parent.items?.splice(index, 1);
924
- this.get("stage")?.remove({ id: node.id, root: this.get("root") });
925
- if (node.type === "page") {
926
- await this.select(root.items[0] || root);
950
+ const stage = this.get("stage");
951
+ stage?.remove({ id: node.id, root: this.get("root") });
952
+ if (node.type === schema.NodeType.PAGE) {
953
+ if (root.items[0]) {
954
+ await this.select(root.items[0]);
955
+ stage?.select(root.items[0].id);
956
+ }
927
957
  } else {
928
958
  await this.select(parent);
959
+ stage?.select(parent.id);
929
960
  }
930
961
  this.addModifiedNodeId(parent.id);
931
962
  this.pushHistoryState();
@@ -938,17 +969,21 @@
938
969
  if (!info.node)
939
970
  throw new Error(`\u83B7\u53D6\u4E0D\u5230id\u4E3A${config2.id}\u7684\u8282\u70B9`);
940
971
  const node = lodashEs.cloneDeep(vue.toRaw(info.node));
941
- const { parent } = info;
942
- if (!parent)
943
- throw new Error("\u83B7\u53D6\u4E0D\u5230\u7236\u7EA7\u8282\u70B9");
944
972
  let newConfig = await this.toggleFixedPosition(vue.toRaw(config2), node, this.get("root"));
945
- defaults(newConfig, node);
973
+ newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), newConfig, (objValue, srcValue) => {
974
+ if (Array.isArray(srcValue)) {
975
+ return srcValue;
976
+ }
977
+ });
946
978
  if (!newConfig.type)
947
979
  throw new Error("\u914D\u7F6E\u7F3A\u5C11type\u503C");
948
- if (newConfig.type === "app") {
980
+ if (newConfig.type === schema.NodeType.ROOT) {
949
981
  this.set("root", newConfig);
950
982
  return newConfig;
951
983
  }
984
+ const { parent } = info;
985
+ if (!parent)
986
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7236\u7EA7\u8282\u70B9");
952
987
  const parentNodeItems = parent.items;
953
988
  const index = getNodeIndex(newConfig, parent);
954
989
  if (!parentNodeItems || typeof index === "undefined" || index === -1)
@@ -959,11 +994,11 @@
959
994
  newConfig = setLayout(newConfig, newLayout);
960
995
  }
961
996
  parentNodeItems[index] = newConfig;
962
- if (newConfig.id === this.get("node").id) {
997
+ if (`${newConfig.id}` === `${this.get("node").id}`) {
963
998
  this.set("node", newConfig);
999
+ this.get("stage")?.update({ config: lodashEs.cloneDeep(newConfig), root: this.get("root") });
964
1000
  }
965
- this.get("stage")?.update({ config: lodashEs.cloneDeep(newConfig), root: this.get("root") });
966
- if (newConfig.type === "page") {
1001
+ if (newConfig.type === schema.NodeType.PAGE) {
967
1002
  this.set("page", newConfig);
968
1003
  }
969
1004
  this.addModifiedNodeId(newConfig.id);
@@ -980,6 +1015,7 @@
980
1015
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
981
1016
  await this.update(parent);
982
1017
  await this.select(node);
1018
+ this.get("stage")?.update({ config: lodashEs.cloneDeep(node), root: this.get("root") });
983
1019
  this.addModifiedNodeId(parent.id);
984
1020
  this.pushHistoryState();
985
1021
  }
@@ -1092,6 +1128,28 @@
1092
1128
  }
1093
1129
  return newConfig;
1094
1130
  }
1131
+ selectedConfigExceptionHandler(config2) {
1132
+ let id;
1133
+ if (typeof config2 === "string" || typeof config2 === "number") {
1134
+ id = config2;
1135
+ } else {
1136
+ id = config2.id;
1137
+ }
1138
+ if (!id) {
1139
+ throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
1140
+ }
1141
+ const { node, parent, page } = this.getNodeInfo(id);
1142
+ if (!node)
1143
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
1144
+ if (node.id === this.state.root?.id) {
1145
+ throw new Error("\u4E0D\u80FD\u9009\u6839\u8282\u70B9");
1146
+ }
1147
+ return {
1148
+ node,
1149
+ parent,
1150
+ page
1151
+ };
1152
+ }
1095
1153
  }
1096
1154
  var editorService = new Editor$1();
1097
1155
 
@@ -1316,7 +1374,7 @@
1316
1374
  name: type
1317
1375
  });
1318
1376
 
1319
- const _sfc_main$f = vue.defineComponent({
1377
+ const _sfc_main$g = vue.defineComponent({
1320
1378
  components: { Plus: icons.Plus },
1321
1379
  setup() {
1322
1380
  const services = vue.inject("services");
@@ -1326,20 +1384,20 @@
1326
1384
  if (!editorService)
1327
1385
  return;
1328
1386
  editorService.add({
1329
- type: "page",
1387
+ type: schema.NodeType.PAGE,
1330
1388
  name: generatePageNameByApp(vue.toRaw(editorService.get("root")))
1331
1389
  });
1332
1390
  }
1333
1391
  };
1334
1392
  }
1335
1393
  });
1336
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
1394
+ const _hoisted_1$c = { class: "m-editor-empty-panel" };
1337
1395
  const _hoisted_2$6 = { class: "m-editor-empty-content" };
1338
1396
  const _hoisted_3$4 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1339
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
1397
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1340
1398
  const _component_plus = vue.resolveComponent("plus");
1341
1399
  const _component_el_icon = vue.resolveComponent("el-icon");
1342
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, [
1400
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, [
1343
1401
  vue.createElementVNode("div", _hoisted_2$6, [
1344
1402
  vue.createElementVNode("div", {
1345
1403
  class: "m-editor-empty-button",
@@ -1358,7 +1416,7 @@
1358
1416
  ])
1359
1417
  ]);
1360
1418
  }
1361
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
1419
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1362
1420
 
1363
1421
  /*
1364
1422
  Copyright (c) 2018 Daybrush
@@ -2527,7 +2585,7 @@
2527
2585
 
2528
2586
  var Gesto$1 = Gesto;
2529
2587
 
2530
- const _sfc_main$e = vue.defineComponent({
2588
+ const _sfc_main$f = vue.defineComponent({
2531
2589
  name: "m-editor-resize",
2532
2590
  props: {
2533
2591
  type: {
@@ -2569,18 +2627,18 @@
2569
2627
  };
2570
2628
  }
2571
2629
  });
2572
- const _hoisted_1$a = {
2630
+ const _hoisted_1$b = {
2573
2631
  ref: "target",
2574
2632
  class: "m-editor-resizer"
2575
2633
  };
2576
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2577
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$a, [
2634
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2635
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$b, [
2578
2636
  vue.renderSlot(_ctx.$slots, "default")
2579
2637
  ], 512);
2580
2638
  }
2581
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2639
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2582
2640
 
2583
- const _sfc_main$d = vue.defineComponent({
2641
+ const _sfc_main$e = vue.defineComponent({
2584
2642
  components: {
2585
2643
  AddPageBox,
2586
2644
  Resizer
@@ -2603,17 +2661,17 @@
2603
2661
  };
2604
2662
  }
2605
2663
  });
2606
- const _hoisted_1$9 = { class: "m-editor" };
2664
+ const _hoisted_1$a = { class: "m-editor" };
2607
2665
  const _hoisted_2$5 = {
2608
2666
  key: 1,
2609
2667
  class: "m-editor-content"
2610
2668
  };
2611
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2669
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2612
2670
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
2613
2671
  const _component_resizer = vue.resolveComponent("resizer");
2614
2672
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
2615
2673
  const _component_add_page_box = vue.resolveComponent("add-page-box");
2616
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
2674
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
2617
2675
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2618
2676
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
2619
2677
  key: 0,
@@ -2653,9 +2711,9 @@
2653
2711
  ]))
2654
2712
  ]);
2655
2713
  }
2656
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2714
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2657
2715
 
2658
- const _sfc_main$c = vue.defineComponent({
2716
+ const _sfc_main$d = vue.defineComponent({
2659
2717
  name: "m-icon",
2660
2718
  components: { Edit: icons.Edit },
2661
2719
  props: {
@@ -2669,8 +2727,8 @@
2669
2727
  };
2670
2728
  }
2671
2729
  });
2672
- const _hoisted_1$8 = ["src"];
2673
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2730
+ const _hoisted_1$9 = ["src"];
2731
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2674
2732
  const _component_edit = vue.resolveComponent("edit");
2675
2733
  const _component_el_icon = vue.resolveComponent("el-icon");
2676
2734
  return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
@@ -2681,7 +2739,7 @@
2681
2739
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createElementBlock("img", {
2682
2740
  key: 1,
2683
2741
  src: _ctx.icon
2684
- }, null, 8, _hoisted_1$8)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2742
+ }, null, 8, _hoisted_1$9)) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2685
2743
  key: 2,
2686
2744
  class: vue.normalizeClass(_ctx.icon)
2687
2745
  }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
@@ -2691,9 +2749,9 @@
2691
2749
  _: 1
2692
2750
  }));
2693
2751
  }
2694
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
2752
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2695
2753
 
2696
- const _sfc_main$b = vue.defineComponent({
2754
+ const _sfc_main$c = vue.defineComponent({
2697
2755
  components: { MIcon, ArrowDown: icons.ArrowDown },
2698
2756
  props: {
2699
2757
  data: {
@@ -2731,7 +2789,7 @@
2731
2789
  type: "button",
2732
2790
  icon: icons.Delete,
2733
2791
  tooltip: "\u522A\u9664",
2734
- disabled: () => services?.editorService.get("node")?.type === "page",
2792
+ disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2735
2793
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
2736
2794
  };
2737
2795
  case "undo":
@@ -2828,7 +2886,7 @@
2828
2886
  };
2829
2887
  }
2830
2888
  });
2831
- const _hoisted_1$7 = {
2889
+ const _hoisted_1$8 = {
2832
2890
  key: 0,
2833
2891
  class: "menu-item"
2834
2892
  };
@@ -2840,8 +2898,8 @@
2840
2898
  class: "menu-item-text",
2841
2899
  style: { "margin": "0 5px" }
2842
2900
  };
2843
- const _hoisted_4$3 = { class: "el-dropdown-link menubar-menu-button" };
2844
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2901
+ const _hoisted_4$2 = { class: "el-dropdown-link menubar-menu-button" };
2902
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2845
2903
  const _component_el_divider = vue.resolveComponent("el-divider");
2846
2904
  const _component_m_icon = vue.resolveComponent("m-icon");
2847
2905
  const _component_el_button = vue.resolveComponent("el-button");
@@ -2851,20 +2909,36 @@
2851
2909
  const _component_el_dropdown_item = vue.resolveComponent("el-dropdown-item");
2852
2910
  const _component_el_dropdown_menu = vue.resolveComponent("el-dropdown-menu");
2853
2911
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
2854
- return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$7, [
2912
+ return _ctx.display ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$8, [
2855
2913
  _ctx.item.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2856
2914
  key: 0,
2857
2915
  direction: "vertical"
2858
2916
  })) : _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 }, [
2859
- vue.createVNode(_component_m_icon, {
2860
- icon: _ctx.ZoomIn,
2861
- onClick: _ctx.zoomInHandler
2862
- }, null, 8, ["icon", "onClick"]),
2917
+ vue.createVNode(_component_el_button, {
2918
+ size: "small",
2919
+ type: "text"
2920
+ }, {
2921
+ default: vue.withCtx(() => [
2922
+ vue.createVNode(_component_m_icon, {
2923
+ icon: _ctx.ZoomIn,
2924
+ onClick: _ctx.zoomInHandler
2925
+ }, null, 8, ["icon", "onClick"])
2926
+ ]),
2927
+ _: 1
2928
+ }),
2863
2929
  vue.createElementVNode("span", _hoisted_3$3, vue.toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
2864
- vue.createVNode(_component_m_icon, {
2865
- icon: _ctx.ZoomOut,
2866
- onClick: _ctx.zoomOutHandler
2867
- }, null, 8, ["icon", "onClick"])
2930
+ vue.createVNode(_component_el_button, {
2931
+ size: "small",
2932
+ type: "text"
2933
+ }, {
2934
+ default: vue.withCtx(() => [
2935
+ vue.createVNode(_component_m_icon, {
2936
+ icon: _ctx.ZoomOut,
2937
+ onClick: _ctx.zoomOutHandler
2938
+ }, null, 8, ["icon", "onClick"])
2939
+ ]),
2940
+ _: 1
2941
+ })
2868
2942
  ], 64)) : _ctx.item.type === "button" ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
2869
2943
  key: 3,
2870
2944
  effect: "dark",
@@ -2913,7 +2987,7 @@
2913
2987
  })) : vue.createCommentVNode("", true)
2914
2988
  ]),
2915
2989
  default: vue.withCtx(() => [
2916
- vue.createElementVNode("span", _hoisted_4$3, [
2990
+ vue.createElementVNode("span", _hoisted_4$2, [
2917
2991
  vue.createTextVNode(vue.toDisplayString(_ctx.item.text), 1),
2918
2992
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
2919
2993
  default: vue.withCtx(() => [
@@ -2927,9 +3001,9 @@
2927
3001
  }, 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)
2928
3002
  ])) : vue.createCommentVNode("", true);
2929
3003
  }
2930
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3004
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
2931
3005
 
2932
- const _sfc_main$a = vue.defineComponent({
3006
+ const _sfc_main$b = vue.defineComponent({
2933
3007
  name: "nav-menu",
2934
3008
  components: { ToolButton },
2935
3009
  props: {
@@ -2942,12 +3016,14 @@
2942
3016
  }
2943
3017
  },
2944
3018
  setup(props) {
3019
+ const services = vue.inject("services");
2945
3020
  return {
2946
- keys: vue.computed(() => Object.keys(props.data))
3021
+ keys: vue.computed(() => Object.keys(props.data)),
3022
+ columnWidth: vue.computed(() => services?.uiService.get("columnWidth"))
2947
3023
  };
2948
3024
  }
2949
3025
  });
2950
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3026
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2951
3027
  const _component_tool_button = vue.resolveComponent("tool-button");
2952
3028
  return vue.openBlock(), vue.createElementBlock("div", {
2953
3029
  class: "m-editor-nav-menu",
@@ -2956,7 +3032,8 @@
2956
3032
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.keys, (key) => {
2957
3033
  return vue.openBlock(), vue.createElementBlock("div", {
2958
3034
  class: vue.normalizeClass(`menu-${key}`),
2959
- key
3035
+ key,
3036
+ style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.[key]}px`)
2960
3037
  }, [
2961
3038
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.data[key], (item, index) => {
2962
3039
  return vue.openBlock(), vue.createBlock(_component_tool_button, {
@@ -2964,13 +3041,13 @@
2964
3041
  key: index
2965
3042
  }, null, 8, ["data"]);
2966
3043
  }), 128))
2967
- ], 2);
3044
+ ], 6);
2968
3045
  }), 128))
2969
3046
  ], 4);
2970
3047
  }
2971
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3048
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
2972
3049
 
2973
- const _sfc_main$9 = vue.defineComponent({
3050
+ const _sfc_main$a = vue.defineComponent({
2974
3051
  name: "m-editor-props-panel",
2975
3052
  emits: ["mounted"],
2976
3053
  setup(props, { emit }) {
@@ -2979,17 +3056,14 @@
2979
3056
  const configForm = vue.ref();
2980
3057
  const curFormConfig = vue.ref([]);
2981
3058
  const services = vue.inject("services");
3059
+ const node = vue.computed(() => services?.editorService.get("node"));
2982
3060
  const init = async () => {
2983
- const node = services?.editorService.get("node");
2984
- if (!node) {
3061
+ if (!node.value) {
2985
3062
  curFormConfig.value = [];
2986
3063
  return;
2987
3064
  }
2988
- if (node.devconfig && node.style && !isNaN(+node.style.height) && !isNaN(+node.style.width)) {
2989
- node.devconfig.ratio = node.style.height / node.style.width || 1;
2990
- }
2991
- values.value = node;
2992
- const type = node.type || (node.items ? "container" : "text");
3065
+ values.value = node.value;
3066
+ const type = node.value.type || (node.value.items ? "container" : "text");
2993
3067
  curFormConfig.value = await services?.propsService.getPropsConfig(type) || [];
2994
3068
  };
2995
3069
  vue.watchEffect(init);
@@ -3019,10 +3093,11 @@
3019
3093
  };
3020
3094
  }
3021
3095
  });
3022
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3096
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3023
3097
  const _component_m_form = vue.resolveComponent("m-form");
3024
3098
  return vue.openBlock(), vue.createBlock(_component_m_form, {
3025
3099
  class: "m-editor-props-panel",
3100
+ "popper-class": "m-editor-props-panel-popper",
3026
3101
  ref: "configForm",
3027
3102
  size: "small",
3028
3103
  "init-values": _ctx.values,
@@ -3030,9 +3105,9 @@
3030
3105
  onChange: _ctx.submit
3031
3106
  }, null, 8, ["init-values", "config", "onChange"]);
3032
3107
  }
3033
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3108
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3034
3109
 
3035
- const _sfc_main$8 = vue.defineComponent({
3110
+ const _sfc_main$9 = vue.defineComponent({
3036
3111
  name: "ui-component-panel",
3037
3112
  components: { MIcon },
3038
3113
  setup() {
@@ -3057,9 +3132,9 @@
3057
3132
  };
3058
3133
  }
3059
3134
  });
3060
- const _hoisted_1$6 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3135
+ const _hoisted_1$7 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3061
3136
  const _hoisted_2$3 = ["onClick"];
3062
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3137
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3063
3138
  const _component_el_input = vue.resolveComponent("el-input");
3064
3139
  const _component_m_icon = vue.resolveComponent("m-icon");
3065
3140
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -3089,7 +3164,7 @@
3089
3164
  name: index
3090
3165
  }, {
3091
3166
  title: vue.withCtx(() => [
3092
- _hoisted_1$6,
3167
+ _hoisted_1$7,
3093
3168
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
3094
3169
  ]),
3095
3170
  default: vue.withCtx(() => [
@@ -3126,32 +3201,18 @@
3126
3201
  _: 1
3127
3202
  });
3128
3203
  }
3129
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3204
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3130
3205
 
3131
- const _sfc_main$7 = vue.defineComponent({
3206
+ const _sfc_main$8 = vue.defineComponent({
3132
3207
  name: "magic-editor-content-menu",
3133
- props: {
3134
- componentGroupList: {
3135
- type: Array,
3136
- default: () => []
3137
- }
3138
- },
3139
- setup(props) {
3208
+ setup() {
3140
3209
  const services = vue.inject("services");
3141
3210
  const subVisible = vue.ref(false);
3142
3211
  const node = vue.computed(() => services?.editorService.get("node"));
3143
3212
  return {
3144
3213
  subVisible,
3145
3214
  node,
3146
- menu: vue.computed(() => ({
3147
- app: [
3148
- {
3149
- type: "page",
3150
- text: "\u9875\u9762"
3151
- }
3152
- ],
3153
- component: props.componentGroupList
3154
- })),
3215
+ componentGroupList: vue.computed(() => services?.componentListService.getList()),
3155
3216
  append(config) {
3156
3217
  services?.editorService.add({
3157
3218
  name: config.text,
@@ -3162,29 +3223,28 @@
3162
3223
  node.value && services?.editorService.remove(node.value);
3163
3224
  },
3164
3225
  copy(node2) {
3165
- services?.editorService.copy(node2);
3226
+ node2 && services?.editorService.copy(node2);
3166
3227
  },
3167
- setSubVisiable(v) {
3228
+ setSubVisitable(v) {
3168
3229
  subVisible.value = v;
3169
3230
  }
3170
3231
  };
3171
3232
  }
3172
3233
  });
3173
- const _hoisted_1$5 = {
3234
+ const _hoisted_1$6 = {
3174
3235
  key: 0,
3175
3236
  class: "magic-editor-content-menu"
3176
3237
  };
3177
3238
  const _hoisted_2$2 = ["onClick"];
3178
- const _hoisted_3$2 = ["onClick"];
3179
- const _hoisted_4$2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3180
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3239
+ const _hoisted_3$2 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3240
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3181
3241
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
3182
- return _ctx.node ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, [
3242
+ return _ctx.node ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
3183
3243
  _ctx.node.items ? (vue.openBlock(), vue.createElementBlock("div", {
3184
3244
  key: 0,
3185
3245
  class: "magic-editor-content-menu-item",
3186
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisiable(true)),
3187
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisiable(false))
3246
+ onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisitable(true)),
3247
+ onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisitable(false))
3188
3248
  }, " \u65B0\u589E ", 32)) : vue.createCommentVNode("", true),
3189
3249
  _ctx.node.type !== "app" ? (vue.openBlock(), vue.createElementBlock("div", {
3190
3250
  key: 1,
@@ -3198,8 +3258,8 @@
3198
3258
  }, " \u5220\u9664 ")) : vue.createCommentVNode("", true),
3199
3259
  vue.withDirectives(vue.createElementVNode("div", {
3200
3260
  class: "subMenu",
3201
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisiable(true)),
3202
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisiable(false))
3261
+ onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisitable(true)),
3262
+ onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisitable(false))
3203
3263
  }, [
3204
3264
  vue.createVNode(_component_el_scrollbar, null, {
3205
3265
  default: vue.withCtx(() => [
@@ -3209,13 +3269,7 @@
3209
3269
  onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3210
3270
  type: "tab-pane"
3211
3271
  }))
3212
- }, " \u6807\u7B7E ")) : _ctx.node.type === "app" ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.menu.app, (item) => {
3213
- return vue.openBlock(), vue.createElementBlock("div", {
3214
- class: "magic-editor-content-menu-item",
3215
- key: item.type,
3216
- onClick: () => _ctx.append(item)
3217
- }, vue.toDisplayString(item.text), 9, _hoisted_2$2);
3218
- }), 128)) : _ctx.node.items ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 2 }, vue.renderList(_ctx.menu.component, (list) => {
3272
+ }, " \u6807\u7B7E ")) : _ctx.node.items ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.componentGroupList, (list) => {
3219
3273
  return vue.openBlock(), vue.createElementBlock("div", {
3220
3274
  key: list.title
3221
3275
  }, [
@@ -3225,10 +3279,10 @@
3225
3279
  class: "magic-editor-content-menu-item",
3226
3280
  key: item.type,
3227
3281
  onClick: () => _ctx.append(item)
3228
- }, vue.toDisplayString(item.text), 9, _hoisted_3$2)) : vue.createCommentVNode("", true)
3282
+ }, vue.toDisplayString(item.text), 9, _hoisted_2$2)) : vue.createCommentVNode("", true)
3229
3283
  ], 64);
3230
3284
  }), 256)),
3231
- _hoisted_4$2
3285
+ _hoisted_3$2
3232
3286
  ]);
3233
3287
  }), 128)) : vue.createCommentVNode("", true)
3234
3288
  ]),
@@ -3239,22 +3293,31 @@
3239
3293
  ])
3240
3294
  ])) : vue.createCommentVNode("", true);
3241
3295
  }
3242
- var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3296
+ var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3243
3297
 
3244
- const select = (data, editorService) => {
3298
+ const throttleTime = 150;
3299
+ const select = async (data, editorService) => {
3245
3300
  if (!data.id) {
3246
3301
  throw new Error("\u6CA1\u6709id");
3247
3302
  }
3248
- editorService?.select(data);
3303
+ await editorService?.select(data);
3304
+ editorService?.get("stage")?.select(data.id);
3305
+ };
3306
+ const highlight = (data, editorService) => {
3307
+ if (!data?.id) {
3308
+ throw new Error("\u6CA1\u6709id");
3309
+ }
3310
+ editorService?.highlight(data);
3311
+ editorService?.get("stage")?.highlight(data.id);
3249
3312
  };
3250
3313
  const useDrop = (tree, editorService) => ({
3251
3314
  allowDrop: (draggingNode, dropNode, type) => {
3252
3315
  const { data } = dropNode || {};
3253
3316
  const { data: ingData } = draggingNode;
3254
3317
  const { type: ingType } = ingData;
3255
- if (ingType !== "page" && data.type === "page")
3318
+ if (ingType !== schema.NodeType.PAGE && data.type === schema.NodeType.PAGE)
3256
3319
  return false;
3257
- if (ingType === "page" && data.type !== "page")
3320
+ if (ingType === schema.NodeType.PAGE && data.type !== schema.NodeType.PAGE)
3258
3321
  return false;
3259
3322
  if (!data || !data.type)
3260
3323
  return false;
@@ -3273,29 +3336,35 @@
3273
3336
  }
3274
3337
  });
3275
3338
  const useStatus = (tree, editorService) => {
3339
+ const highlightNode = vue.ref();
3340
+ const node = vue.ref();
3276
3341
  const page = vue.computed(() => editorService?.get("page"));
3277
3342
  vue.watchEffect(() => {
3278
3343
  if (!tree.value)
3279
3344
  return;
3280
- const node = editorService?.get("node");
3281
- node && tree.value.setCurrentKey(node.id, true);
3345
+ node.value = editorService?.get("node");
3346
+ node.value && tree.value.setCurrentKey(node.value.id, true);
3282
3347
  const parent = editorService?.get("parent");
3283
3348
  if (!parent?.id)
3284
3349
  return;
3285
3350
  const treeNode = tree.value.getNode(parent.id);
3286
3351
  treeNode?.updateChildren();
3352
+ highlightNode.value = editorService?.get("highlightNode");
3287
3353
  });
3288
3354
  return {
3289
3355
  values: vue.computed(() => page.value ? [page.value] : []),
3290
- loadItems: (node, resolve) => {
3291
- if (Array.isArray(node.data)) {
3292
- return resolve(node.data);
3356
+ loadItems: (node2, resolve) => {
3357
+ if (Array.isArray(node2.data)) {
3358
+ return resolve(node2.data);
3293
3359
  }
3294
- if (Array.isArray(node.data?.items)) {
3295
- return resolve(node.data?.items);
3360
+ if (Array.isArray(node2.data?.items)) {
3361
+ return resolve(node2.data?.items);
3296
3362
  }
3297
3363
  resolve([]);
3298
- }
3364
+ },
3365
+ highlightNode,
3366
+ clickNode: node,
3367
+ expandedKeys: vue.computed(() => node.value ? [node.value.id] : [])
3299
3368
  };
3300
3369
  };
3301
3370
  const useFilter = (tree) => ({
@@ -3307,12 +3376,10 @@
3307
3376
  let name = "";
3308
3377
  if (data.name) {
3309
3378
  name = data.name;
3310
- } else if (data.type) {
3311
- name = data.type;
3312
3379
  } else if (data.items) {
3313
3380
  name = "container";
3314
3381
  }
3315
- return name.indexOf(value) !== -1;
3382
+ return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
3316
3383
  },
3317
3384
  filterTextChangeHandler(val) {
3318
3385
  tree.value?.filter(val);
@@ -3346,17 +3413,26 @@
3346
3413
  }
3347
3414
  };
3348
3415
  };
3349
- const _sfc_main$6 = vue.defineComponent({
3416
+ const _sfc_main$7 = vue.defineComponent({
3350
3417
  name: "magic-editor-layer-panel",
3351
3418
  components: { LayerMenu },
3352
3419
  setup() {
3353
3420
  const services = vue.inject("services");
3354
3421
  const tree = vue.ref();
3422
+ const clicked = vue.ref(false);
3355
3423
  const editorService = services?.editorService;
3424
+ const highlightHandler = lodashEs.throttle((data) => {
3425
+ highlight(data, editorService);
3426
+ }, throttleTime);
3427
+ const toogleClickFlag = () => {
3428
+ clicked.value = !clicked.value;
3429
+ };
3430
+ const statusData = useStatus(tree, editorService);
3431
+ const canHighlight = vue.computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3356
3432
  return {
3357
3433
  tree,
3434
+ ...statusData,
3358
3435
  ...useDrop(tree, editorService),
3359
- ...useStatus(tree, editorService),
3360
3436
  ...useFilter(tree),
3361
3437
  ...useContentMenu(editorService),
3362
3438
  clickHandler(data) {
@@ -3364,12 +3440,17 @@
3364
3440
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
3365
3441
  return;
3366
3442
  }
3443
+ tree.value?.setCurrentKey(data.id);
3367
3444
  select(data, editorService);
3368
- }
3445
+ },
3446
+ highlightHandler,
3447
+ toogleClickFlag,
3448
+ canHighlight
3369
3449
  };
3370
3450
  }
3371
3451
  });
3372
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3452
+ const _hoisted_1$5 = ["id", "onMouseenter"];
3453
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3373
3454
  const _component_el_input = vue.resolveComponent("el-input");
3374
3455
  const _component_el_tree = vue.resolveComponent("el-tree");
3375
3456
  const _component_layer_menu = vue.resolveComponent("layer-menu");
@@ -3390,6 +3471,7 @@
3390
3471
  ref: "tree",
3391
3472
  "node-key": "id",
3392
3473
  draggable: "",
3474
+ "default-expanded-keys": _ctx.expandedKeys,
3393
3475
  load: _ctx.loadItems,
3394
3476
  data: _ctx.values,
3395
3477
  "expand-on-click-node": false,
@@ -3405,15 +3487,23 @@
3405
3487
  "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3406
3488
  }, {
3407
3489
  default: vue.withCtx(({ node, data }) => [
3408
- vue.renderSlot(_ctx.$slots, "layer-node-content", {
3409
- node,
3410
- data
3411
- }, () => [
3412
- vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3413
- ])
3490
+ vue.createElementVNode("div", {
3491
+ id: data.id,
3492
+ class: vue.normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3493
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3494
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3495
+ onMouseenter: ($event) => _ctx.highlightHandler(data)
3496
+ }, [
3497
+ vue.renderSlot(_ctx.$slots, "layer-node-content", {
3498
+ node,
3499
+ data
3500
+ }, () => [
3501
+ vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3502
+ ])
3503
+ ], 42, _hoisted_1$5)
3414
3504
  ]),
3415
3505
  _: 3
3416
- }, 8, ["load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3506
+ }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3417
3507
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3418
3508
  vue.createVNode(_component_layer_menu, {
3419
3509
  style: vue.normalizeStyle(_ctx.menuStyle)
@@ -3423,9 +3513,9 @@
3423
3513
  _: 3
3424
3514
  });
3425
3515
  }
3426
- var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3516
+ var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3427
3517
 
3428
- const _sfc_main$5 = vue.defineComponent({
3518
+ const _sfc_main$6 = vue.defineComponent({
3429
3519
  name: "m-sidebar",
3430
3520
  components: { MIcon },
3431
3521
  props: {
@@ -3473,7 +3563,7 @@
3473
3563
  key: 1,
3474
3564
  class: "magic-editor-tab-panel-title"
3475
3565
  };
3476
- function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3566
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3477
3567
  const _component_m_icon = vue.resolveComponent("m-icon");
3478
3568
  const _component_el_tab_pane = vue.resolveComponent("el-tab-pane");
3479
3569
  const _component_el_tabs = vue.resolveComponent("el-tabs");
@@ -3520,15 +3610,81 @@
3520
3610
  _: 1
3521
3611
  }, 8, ["modelValue"])) : vue.createCommentVNode("", true);
3522
3612
  }
3523
- var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3524
-
3525
- const _sfc_main$4 = vue.defineComponent({
3526
- components: { CaretBottom: icons.CaretBottom, Plus: icons.Plus },
3613
+ var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3614
+
3615
+ const useScroll = (root) => {
3616
+ const pageBar = vue.ref();
3617
+ const itemsContainer = vue.ref();
3618
+ const pageBarWidth = vue.ref(0);
3619
+ const canScroll = vue.ref(false);
3620
+ const itemsContainerWidth = vue.computed(() => pageBarWidth.value - 105);
3621
+ let translateLeft = 0;
3622
+ const resizeObserver = new ResizeObserver((entries) => {
3623
+ for (const { contentRect } of entries) {
3624
+ const { width } = contentRect;
3625
+ pageBarWidth.value = width || 0;
3626
+ setCanScroll();
3627
+ }
3628
+ });
3629
+ const setCanScroll = () => {
3630
+ if (itemsContainer.value) {
3631
+ canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
3632
+ }
3633
+ };
3634
+ const scroll = (type) => {
3635
+ if (!itemsContainer.value)
3636
+ return;
3637
+ const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
3638
+ if (type === "left") {
3639
+ translateLeft += 100;
3640
+ if (translateLeft > 0) {
3641
+ translateLeft = 0;
3642
+ }
3643
+ } else if (type === "right") {
3644
+ translateLeft -= 100;
3645
+ if (-translateLeft > maxScrollLeft) {
3646
+ translateLeft = -maxScrollLeft;
3647
+ }
3648
+ } else if (type === "start") {
3649
+ translateLeft = 0;
3650
+ } else if (type === "end") {
3651
+ translateLeft = -maxScrollLeft;
3652
+ }
3653
+ itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
3654
+ };
3655
+ vue.onMounted(() => {
3656
+ pageBar.value && resizeObserver.observe(pageBar.value);
3657
+ });
3658
+ vue.onUnmounted(() => {
3659
+ resizeObserver.disconnect();
3660
+ });
3661
+ vue.watch(() => root.value?.items.length, (length = 0, preLength = 0) => {
3662
+ setTimeout(() => {
3663
+ setCanScroll();
3664
+ if (length < preLength) {
3665
+ scroll("start");
3666
+ } else {
3667
+ scroll("end");
3668
+ }
3669
+ });
3670
+ });
3671
+ return {
3672
+ pageBar,
3673
+ itemsContainer,
3674
+ canScroll,
3675
+ itemsContainerWidth,
3676
+ scroll
3677
+ };
3678
+ };
3679
+ const _sfc_main$5 = vue.defineComponent({
3680
+ components: { ArrowLeftBold: icons.ArrowLeftBold, ArrowRightBold: icons.ArrowRightBold, CaretBottom: icons.CaretBottom, Plus: icons.Plus },
3527
3681
  setup() {
3528
3682
  const services = vue.inject("services");
3529
3683
  const editorService = services?.editorService;
3684
+ const root = vue.computed(() => editorService?.get("root"));
3530
3685
  return {
3531
- root: vue.computed(() => editorService?.get("root")),
3686
+ ...useScroll(root),
3687
+ root,
3532
3688
  page: vue.computed(() => editorService?.get("page")),
3533
3689
  switchPage(page) {
3534
3690
  editorService?.select(page);
@@ -3537,7 +3693,7 @@
3537
3693
  if (!editorService)
3538
3694
  return;
3539
3695
  const pageConfig = {
3540
- type: "page",
3696
+ type: schema.NodeType.PAGE,
3541
3697
  name: generatePageNameByApp(vue.toRaw(editorService.get("root")))
3542
3698
  };
3543
3699
  editorService.add(pageConfig);
@@ -3555,70 +3711,339 @@
3555
3711
  };
3556
3712
  }
3557
3713
  });
3558
- const _hoisted_1$3 = { class: "m-editor-page-bar" };
3714
+ const _hoisted_1$3 = {
3715
+ class: "m-editor-page-bar",
3716
+ ref: "pageBar"
3717
+ };
3559
3718
  const _hoisted_2$1 = ["onClick"];
3560
- const _hoisted_3$1 = ["onClick"];
3719
+ const _hoisted_3$1 = { class: "m-editor-page-bar-title" };
3561
3720
  const _hoisted_4$1 = ["onClick"];
3562
- function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3721
+ const _hoisted_5 = ["onClick"];
3722
+ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3563
3723
  const _component_plus = vue.resolveComponent("plus");
3564
3724
  const _component_el_icon = vue.resolveComponent("el-icon");
3725
+ const _component_arrow_left_bold = vue.resolveComponent("arrow-left-bold");
3726
+ const _component_el_tooltip = vue.resolveComponent("el-tooltip");
3565
3727
  const _component_caret_bottom = vue.resolveComponent("caret-bottom");
3566
3728
  const _component_el_popover = vue.resolveComponent("el-popover");
3729
+ const _component_arrow_right_bold = vue.resolveComponent("arrow-right-bold");
3567
3730
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
3568
3731
  vue.createElementVNode("div", {
3569
- class: "m-editor-page-bar-item",
3732
+ id: "m-editor-page-bar-add-icon",
3733
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3570
3734
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.addPage && _ctx.addPage(...args))
3571
3735
  }, [
3572
- vue.createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-add-icon" }, {
3736
+ vue.createVNode(_component_el_icon, null, {
3573
3737
  default: vue.withCtx(() => [
3574
3738
  vue.createVNode(_component_plus)
3575
3739
  ]),
3576
3740
  _: 1
3577
3741
  })
3578
3742
  ]),
3579
- _ctx.root ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(_ctx.root.items, (item) => {
3580
- return vue.openBlock(), vue.createElementBlock("div", {
3581
- key: item.key,
3582
- class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3583
- onClick: ($event) => _ctx.switchPage(item)
3584
- }, [
3585
- vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3586
- vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1)
3743
+ _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
3744
+ key: 0,
3745
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3746
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.scroll("left"))
3747
+ }, [
3748
+ vue.createVNode(_component_el_icon, null, {
3749
+ default: vue.withCtx(() => [
3750
+ vue.createVNode(_component_arrow_left_bold)
3587
3751
  ]),
3588
- vue.createVNode(_component_el_popover, {
3589
- placement: "top",
3590
- width: 160,
3591
- trigger: "hover"
3592
- }, {
3593
- reference: vue.withCtx(() => [
3594
- vue.createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
3595
- default: vue.withCtx(() => [
3596
- vue.createVNode(_component_caret_bottom)
3597
- ]),
3598
- _: 1
3599
- })
3600
- ]),
3601
- default: vue.withCtx(() => [
3602
- vue.createElementVNode("div", null, [
3603
- vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3604
- vue.createElementVNode("div", {
3605
- class: "magic-editor-content-menu-item",
3606
- onClick: () => _ctx.copy(item)
3607
- }, "\u590D\u5236", 8, _hoisted_3$1),
3608
- vue.createElementVNode("div", {
3609
- class: "magic-editor-content-menu-item",
3610
- onClick: () => _ctx.remove(item)
3611
- }, "\u5220\u9664", 8, _hoisted_4$1)
3612
- ])
3752
+ _: 1
3753
+ })
3754
+ ])) : vue.createCommentVNode("", true),
3755
+ _ctx.root ? (vue.openBlock(), vue.createElementBlock("div", {
3756
+ key: 1,
3757
+ class: "m-editor-page-bar-items",
3758
+ ref: "itemsContainer",
3759
+ style: vue.normalizeStyle(`width: ${_ctx.itemsContainerWidth}px`)
3760
+ }, [
3761
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.root.items, (item) => {
3762
+ return vue.openBlock(), vue.createElementBlock("div", {
3763
+ key: item.key,
3764
+ class: vue.normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3765
+ onClick: ($event) => _ctx.switchPage(item)
3766
+ }, [
3767
+ vue.createElementVNode("div", _hoisted_3$1, [
3768
+ vue.renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3769
+ vue.createVNode(_component_el_tooltip, {
3770
+ effect: "dark",
3771
+ placement: "top-start",
3772
+ content: item.name
3773
+ }, {
3774
+ default: vue.withCtx(() => [
3775
+ vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1)
3776
+ ]),
3777
+ _: 2
3778
+ }, 1032, ["content"])
3613
3779
  ])
3614
3780
  ]),
3615
- _: 2
3616
- }, 1024)
3617
- ], 10, _hoisted_2$1);
3618
- }), 128)) : vue.createCommentVNode("", true)
3619
- ]);
3781
+ vue.createVNode(_component_el_popover, {
3782
+ placement: "top",
3783
+ width: 160,
3784
+ trigger: "hover"
3785
+ }, {
3786
+ reference: vue.withCtx(() => [
3787
+ vue.createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
3788
+ default: vue.withCtx(() => [
3789
+ vue.createVNode(_component_caret_bottom)
3790
+ ]),
3791
+ _: 1
3792
+ })
3793
+ ]),
3794
+ default: vue.withCtx(() => [
3795
+ vue.createElementVNode("div", null, [
3796
+ vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3797
+ vue.createElementVNode("div", {
3798
+ class: "magic-editor-content-menu-item",
3799
+ onClick: () => _ctx.copy(item)
3800
+ }, "\u590D\u5236", 8, _hoisted_4$1),
3801
+ vue.createElementVNode("div", {
3802
+ class: "magic-editor-content-menu-item",
3803
+ onClick: () => _ctx.remove(item)
3804
+ }, "\u5220\u9664", 8, _hoisted_5)
3805
+ ])
3806
+ ])
3807
+ ]),
3808
+ _: 2
3809
+ }, 1024)
3810
+ ], 10, _hoisted_2$1);
3811
+ }), 128))
3812
+ ], 4)) : vue.createCommentVNode("", true),
3813
+ _ctx.canScroll ? (vue.openBlock(), vue.createElementBlock("div", {
3814
+ key: 2,
3815
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3816
+ onClick: _cache[2] || (_cache[2] = ($event) => _ctx.scroll("right"))
3817
+ }, [
3818
+ vue.createVNode(_component_el_icon, null, {
3819
+ default: vue.withCtx(() => [
3820
+ vue.createVNode(_component_arrow_right_bold)
3821
+ ]),
3822
+ _: 1
3823
+ })
3824
+ ])) : vue.createCommentVNode("", true)
3825
+ ], 512);
3826
+ }
3827
+ var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3828
+
3829
+ class ScrollViewer$1 {
3830
+ enter = false;
3831
+ targetEnter = false;
3832
+ keydown = false;
3833
+ container;
3834
+ target;
3835
+ zoom = 1;
3836
+ scrollLeft = 0;
3837
+ scrollTop = 0;
3838
+ x = 0;
3839
+ y = 0;
3840
+ resizeObserver = new ResizeObserver((entries) => {
3841
+ for (const { contentRect } of entries) {
3842
+ const { width, height } = contentRect;
3843
+ const targetRect = this.target.getBoundingClientRect();
3844
+ const targetWidth = targetRect.width * this.zoom;
3845
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
3846
+ const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3847
+ if (targetWidth < width) {
3848
+ this.target._left = 0;
3849
+ }
3850
+ if (targetHeight < height) {
3851
+ this.target._top = 0;
3852
+ }
3853
+ this.scroll();
3854
+ }
3855
+ });
3856
+ constructor(options) {
3857
+ this.container = options.container;
3858
+ this.target = options.target;
3859
+ this.zoom = options.zoom;
3860
+ globalThis.addEventListener("keydown", this.keydownHandler);
3861
+ globalThis.addEventListener("keyup", this.keyupHandler);
3862
+ this.container.addEventListener("mouseenter", this.mouseEnterHandler);
3863
+ this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
3864
+ this.target.addEventListener("mouseenter", this.targetMouseEnterHandler);
3865
+ this.target.addEventListener("mouseleave", this.targetMouseLeaveHandler);
3866
+ this.container.addEventListener("wheel", this.wheelHandler);
3867
+ this.resizeObserver.observe(this.container);
3868
+ }
3869
+ destroy() {
3870
+ this.resizeObserver.disconnect();
3871
+ this.container.removeEventListener("mouseenter", this.mouseEnterHandler);
3872
+ this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
3873
+ this.target.removeEventListener("mouseenter", this.targetMouseEnterHandler);
3874
+ this.target.removeEventListener("mouseleave", this.targetMouseLeaveHandler);
3875
+ globalThis.removeEventListener("keydown", this.keydownHandler);
3876
+ globalThis.removeEventListener("keyup", this.keyupHandler);
3877
+ }
3878
+ setZoom(zoom) {
3879
+ this.zoom = zoom;
3880
+ }
3881
+ scroll() {
3882
+ const scrollLeft = this.target._left;
3883
+ const scrollTop = this.target._top;
3884
+ this.target.style.transform = `translate(${scrollLeft}px, ${scrollTop}px)`;
3885
+ }
3886
+ removeHandler() {
3887
+ this.target.style.cursor = "";
3888
+ this.target.removeEventListener("mousedown", this.mousedownHandler);
3889
+ document.removeEventListener("mousemove", this.mousemoveHandler);
3890
+ document.removeEventListener("mouseup", this.mouseupHandler);
3891
+ }
3892
+ wheelHandler = (event) => {
3893
+ if (this.targetEnter)
3894
+ return;
3895
+ const { deltaX, deltaY, currentTarget } = event;
3896
+ if (currentTarget !== this.container)
3897
+ return;
3898
+ this.setScrollOffset(deltaX, deltaY);
3899
+ this.scroll();
3900
+ this.scrollLeft = this.target._left;
3901
+ this.scrollTop = this.target._top;
3902
+ };
3903
+ mouseEnterHandler = () => {
3904
+ this.enter = true;
3905
+ };
3906
+ mouseLeaveHandler = () => {
3907
+ this.enter = false;
3908
+ };
3909
+ targetMouseEnterHandler = () => {
3910
+ this.targetEnter = true;
3911
+ };
3912
+ targetMouseLeaveHandler = () => {
3913
+ this.targetEnter = false;
3914
+ };
3915
+ mousedownHandler = (event) => {
3916
+ if (!this.keydown)
3917
+ return;
3918
+ event.stopImmediatePropagation();
3919
+ event.stopPropagation();
3920
+ this.target.style.cursor = "grabbing";
3921
+ this.x = event.clientX;
3922
+ this.y = event.clientY;
3923
+ document.addEventListener("mousemove", this.mousemoveHandler);
3924
+ document.addEventListener("mouseup", this.mouseupHandler);
3925
+ };
3926
+ mouseupHandler = () => {
3927
+ this.x = 0;
3928
+ this.y = 0;
3929
+ this.scrollLeft = this.target._left;
3930
+ this.scrollTop = this.target._top;
3931
+ this.removeHandler();
3932
+ };
3933
+ mousemoveHandler = (event) => {
3934
+ event.stopImmediatePropagation();
3935
+ event.stopPropagation();
3936
+ const deltaX = event.clientX - this.x;
3937
+ const deltaY = event.clientY - this.y;
3938
+ this.setScrollOffset(deltaX, deltaY);
3939
+ this.scroll();
3940
+ };
3941
+ keydownHandler = (event) => {
3942
+ if (event.code === Keys.ESCAPE && this.enter) {
3943
+ event.preventDefault();
3944
+ event.stopImmediatePropagation();
3945
+ event.stopPropagation();
3946
+ }
3947
+ if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3948
+ return;
3949
+ }
3950
+ this.keydown = true;
3951
+ this.target.style.cursor = "grab";
3952
+ this.container.addEventListener("mousedown", this.mousedownHandler);
3953
+ };
3954
+ keyupHandler = (event) => {
3955
+ if (event.code !== Keys.ESCAPE || !this.keydown) {
3956
+ return;
3957
+ }
3958
+ event.preventDefault();
3959
+ event.stopImmediatePropagation();
3960
+ event.stopPropagation();
3961
+ this.keydown = false;
3962
+ event.preventDefault();
3963
+ this.removeHandler();
3964
+ };
3965
+ setScrollOffset(deltaX, deltaY) {
3966
+ const { width, height } = this.container.getBoundingClientRect();
3967
+ const targetRect = this.target.getBoundingClientRect();
3968
+ const targetWidth = targetRect.width * this.zoom;
3969
+ const targetHeight = targetRect.height * this.zoom;
3970
+ let y = 0;
3971
+ if (targetHeight > height) {
3972
+ if (deltaY > 0) {
3973
+ y = this.scrollTop + Math.min(targetHeight - height - this.scrollTop, deltaY);
3974
+ } else {
3975
+ y = this.scrollTop + Math.max(-(targetHeight - height + this.scrollTop), deltaY);
3976
+ }
3977
+ }
3978
+ let x = 0;
3979
+ if (targetWidth > width) {
3980
+ if (deltaX > 0) {
3981
+ x = this.scrollLeft + Math.min(targetWidth - width - this.scrollLeft, deltaX);
3982
+ } else {
3983
+ x = this.scrollLeft + Math.max(-(targetWidth - width + this.scrollLeft), deltaX);
3984
+ }
3985
+ }
3986
+ this.target._left = x;
3987
+ this.target._top = y;
3988
+ }
3620
3989
  }
3621
- var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
3990
+
3991
+ const _sfc_main$4 = vue.defineComponent({
3992
+ name: "m-editor-scroll-viewer",
3993
+ props: {
3994
+ width: Number,
3995
+ height: Number,
3996
+ zoom: {
3997
+ type: Number,
3998
+ default: 1
3999
+ }
4000
+ },
4001
+ setup(props) {
4002
+ const container = vue.ref();
4003
+ const el = vue.ref();
4004
+ let scrollViewer;
4005
+ vue.onMounted(() => {
4006
+ if (!container.value || !el.value)
4007
+ return;
4008
+ scrollViewer = new ScrollViewer$1({
4009
+ container: container.value,
4010
+ target: el.value,
4011
+ zoom: props.zoom
4012
+ });
4013
+ });
4014
+ vue.onUnmounted(() => {
4015
+ scrollViewer.destroy();
4016
+ });
4017
+ vue.watch(() => props.zoom, () => {
4018
+ scrollViewer.setZoom(props.zoom);
4019
+ });
4020
+ return {
4021
+ container,
4022
+ el,
4023
+ style: vue.computed(() => `
4024
+ width: ${props.width}px;
4025
+ height: ${props.height}px;
4026
+ position: absolute;
4027
+ margin-top: 30px;
4028
+ `)
4029
+ };
4030
+ }
4031
+ });
4032
+ const _hoisted_1$2 = {
4033
+ class: "m-editor-scroll-viewer-container",
4034
+ ref: "container"
4035
+ };
4036
+ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
4037
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
4038
+ vue.createElementVNode("div", {
4039
+ ref: "el",
4040
+ style: vue.normalizeStyle(_ctx.style)
4041
+ }, [
4042
+ vue.renderSlot(_ctx.$slots, "default")
4043
+ ], 4)
4044
+ ], 512);
4045
+ }
4046
+ var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
3622
4047
 
3623
4048
  const _sfc_main$3 = vue.defineComponent({
3624
4049
  name: "magic-editor-ui-viewer-menu",
@@ -3638,13 +4063,13 @@
3638
4063
  if (!parent.value || !editorService)
3639
4064
  return canCenter.value = false;
3640
4065
  const layout = await editorService.getLayout(parent.value);
3641
- canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && !["app", "page", "pop"].includes(`${node.value?.type}`);
4066
+ canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && ![schema.NodeType.ROOT, schema.NodeType.PAGE, "pop"].includes(`${node.value?.type}`);
3642
4067
  }, { immediate: true });
3643
4068
  return {
3644
4069
  menu,
3645
4070
  canPaste,
3646
- canDelete: vue.computed(() => node.value?.type !== "page"),
3647
- canMoveZPos: vue.computed(() => node.value?.type !== "page"),
4071
+ canDelete: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
4072
+ canMoveZPos: vue.computed(() => node.value?.type !== schema.NodeType.PAGE),
3648
4073
  canCenter,
3649
4074
  center() {
3650
4075
  node.value && editorService?.alignCenter(node.value);
@@ -3679,7 +4104,7 @@
3679
4104
  };
3680
4105
  }
3681
4106
  });
3682
- const _hoisted_1$2 = {
4107
+ const _hoisted_1$1 = {
3683
4108
  class: "magic-editor-content-menu",
3684
4109
  ref: "menu"
3685
4110
  };
@@ -3687,7 +4112,7 @@
3687
4112
  const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3688
4113
  const _hoisted_4 = /* @__PURE__ */ vue.createElementVNode("div", { class: "separation" }, null, -1);
3689
4114
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3690
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [
4115
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
3691
4116
  vue.createElementVNode("div", null, [
3692
4117
  _ctx.canCenter ? (vue.openBlock(), vue.createElementBlock("div", {
3693
4118
  key: 0,
@@ -3772,28 +4197,14 @@
3772
4197
  const _sfc_main$2 = vue.defineComponent({
3773
4198
  name: "magic-stage",
3774
4199
  components: {
3775
- ViewerMenu
4200
+ ViewerMenu,
4201
+ ScrollViewer
3776
4202
  },
3777
4203
  props: {
3778
4204
  render: {
3779
4205
  type: Function
3780
4206
  },
3781
4207
  runtimeUrl: String,
3782
- root: {
3783
- type: Object
3784
- },
3785
- page: {
3786
- type: Object
3787
- },
3788
- node: {
3789
- type: Object
3790
- },
3791
- uiSelectMode: {
3792
- type: Boolean
3793
- },
3794
- zoom: {
3795
- type: Number
3796
- },
3797
4208
  canSelect: {
3798
4209
  type: Function,
3799
4210
  default: (el) => Boolean(el.id)
@@ -3805,14 +4216,16 @@
3805
4216
  })
3806
4217
  }
3807
4218
  },
3808
- emits: ["select", "update", "sort"],
3809
- setup(props, { emit }) {
4219
+ setup(props) {
3810
4220
  const services = vue.inject("services");
4221
+ const stageWrap = vue.ref();
3811
4222
  const stageContainer = vue.ref();
3812
- const stageStyle = vue.computed(() => ({
3813
- ...services?.uiService.get("stageStyle"),
3814
- transform: `scale(${props.zoom}) translate3d(0, -50%, 0)`
3815
- }));
4223
+ const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
4224
+ const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4225
+ const root = vue.computed(() => services?.editorService.get("root"));
4226
+ const page = vue.computed(() => services?.editorService.get("page"));
4227
+ const zoom = vue.computed(() => services?.uiService.get("zoom"));
4228
+ const node = vue.computed(() => services?.editorService.get("node"));
3816
4229
  let stage = null;
3817
4230
  let runtime = null;
3818
4231
  vue.watchEffect(() => {
@@ -3820,15 +4233,15 @@
3820
4233
  return;
3821
4234
  if (!stageContainer.value)
3822
4235
  return;
3823
- if (!(props.runtimeUrl || props.render) || !props.root)
4236
+ if (!(props.runtimeUrl || props.render) || !root.value)
3824
4237
  return;
3825
4238
  stage = new StageCore__default["default"]({
3826
4239
  render: props.render,
3827
4240
  runtimeUrl: props.runtimeUrl,
3828
- zoom: props.zoom,
3829
- canSelect: (el, stop) => {
4241
+ zoom: zoom.value,
4242
+ canSelect: (el, event, stop) => {
3830
4243
  const elCanSelect = props.canSelect(el);
3831
- if (props.uiSelectMode && elCanSelect) {
4244
+ if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
3832
4245
  document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
3833
4246
  return stop();
3834
4247
  }
@@ -3836,67 +4249,95 @@
3836
4249
  },
3837
4250
  moveableOptions: props.moveableOptions
3838
4251
  });
3839
- services?.editorService.set("stage", stage);
4252
+ services?.editorService.set("stage", vue.markRaw(stage));
3840
4253
  stage?.mount(stageContainer.value);
3841
- stage?.on("select", (el) => emit("select", el));
4254
+ stage?.on("select", (el) => {
4255
+ services?.editorService.select(el.id);
4256
+ });
4257
+ stage?.on("highlight", (el) => {
4258
+ services?.editorService.highlight(el.id);
4259
+ });
3842
4260
  stage?.on("update", (ev) => {
3843
- emit("update", { id: ev.el.id, style: ev.style });
4261
+ services?.editorService.update({ id: ev.el.id, style: ev.style });
3844
4262
  });
3845
4263
  stage?.on("sort", (ev) => {
3846
- emit("sort", ev);
4264
+ services?.editorService.sort(ev.src, ev.dist);
3847
4265
  });
3848
4266
  stage?.on("changeGuides", () => {
3849
4267
  services?.uiService.set("showGuides", true);
3850
4268
  });
3851
- if (!props.node?.id)
4269
+ if (!node.value?.id)
3852
4270
  return;
3853
4271
  stage?.on("runtime-ready", (rt) => {
3854
4272
  runtime = rt;
3855
- props.root && runtime?.updateRootConfig(lodashEs.cloneDeep(vue.toRaw(props.root)));
3856
- props.page?.id && runtime?.updatePageId?.(props.page.id);
4273
+ root.value && runtime?.updateRootConfig(lodashEs.cloneDeep(vue.toRaw(root.value)));
4274
+ page.value?.id && runtime?.updatePageId?.(page.value.id);
3857
4275
  setTimeout(() => {
3858
- props.node && stage?.select(vue.toRaw(props.node.id));
4276
+ node.value && stage?.select(vue.toRaw(node.value.id));
3859
4277
  });
3860
4278
  });
3861
4279
  });
3862
- vue.watch(() => props.zoom, (zoom) => {
3863
- if (!stage || !zoom)
4280
+ vue.watch(zoom, (zoom2) => {
4281
+ if (!stage || !zoom2)
3864
4282
  return;
3865
- stage?.setZoom(zoom);
4283
+ stage.setZoom(zoom2);
3866
4284
  });
3867
- vue.watch(() => props.root, (root) => {
3868
- if (runtime && root) {
3869
- runtime.updateRootConfig(lodashEs.cloneDeep(vue.toRaw(root)));
4285
+ vue.watch(root, (root2) => {
4286
+ if (runtime && root2) {
4287
+ runtime.updateRootConfig(lodashEs.cloneDeep(vue.toRaw(root2)));
3870
4288
  }
3871
4289
  });
4290
+ const resizeObserver = new ResizeObserver((entries) => {
4291
+ for (const { contentRect } of entries) {
4292
+ services?.uiService.set("stageContainerRect", {
4293
+ width: contentRect.width,
4294
+ height: contentRect.height
4295
+ });
4296
+ }
4297
+ });
4298
+ vue.onMounted(() => {
4299
+ stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
4300
+ });
3872
4301
  vue.onUnmounted(() => {
3873
4302
  stage?.destroy();
4303
+ resizeObserver.disconnect();
3874
4304
  services?.editorService.set("stage", null);
3875
4305
  });
3876
4306
  return {
3877
- stageStyle,
3878
- ...useMenu(),
3879
- stageContainer
4307
+ stageWrap,
4308
+ stageContainer,
4309
+ stageRect,
4310
+ zoom,
4311
+ ...useMenu()
3880
4312
  };
3881
4313
  }
3882
4314
  });
3883
- const _hoisted_1$1 = { class: "m-editor-stage" };
3884
4315
  function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3885
4316
  const _component_viewer_menu = vue.resolveComponent("viewer-menu");
3886
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
3887
- vue.createElementVNode("div", {
3888
- class: "m-editor-stage-container",
3889
- ref: "stageContainer",
3890
- style: vue.normalizeStyle(_ctx.stageStyle),
3891
- onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args))
3892
- }, null, 36),
3893
- (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3894
- vue.createVNode(_component_viewer_menu, {
3895
- ref: "menu",
3896
- style: vue.normalizeStyle(_ctx.menuStyle)
3897
- }, null, 8, ["style"])
3898
- ]))
3899
- ]);
4317
+ const _component_scroll_viewer = vue.resolveComponent("scroll-viewer");
4318
+ return vue.openBlock(), vue.createBlock(_component_scroll_viewer, {
4319
+ class: "m-editor-stage",
4320
+ ref: "stageWrap",
4321
+ width: _ctx.stageRect?.width,
4322
+ height: _ctx.stageRect?.height,
4323
+ zoom: _ctx.zoom
4324
+ }, {
4325
+ default: vue.withCtx(() => [
4326
+ vue.createElementVNode("div", {
4327
+ class: "m-editor-stage-container",
4328
+ ref: "stageContainer",
4329
+ onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4330
+ style: vue.normalizeStyle(`transform: scale(${_ctx.zoom})`)
4331
+ }, null, 36),
4332
+ (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
4333
+ vue.createVNode(_component_viewer_menu, {
4334
+ ref: "menu",
4335
+ style: vue.normalizeStyle(_ctx.menuStyle)
4336
+ }, null, 8, ["style"])
4337
+ ]))
4338
+ ]),
4339
+ _: 1
4340
+ }, 8, ["width", "height", "zoom"]);
3900
4341
  }
3901
4342
  var MagicStage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2]]);
3902
4343
 
@@ -3920,28 +4361,8 @@
3920
4361
  },
3921
4362
  setup() {
3922
4363
  const services = vue.inject("services");
3923
- const node = vue.computed(() => services?.editorService.get("node"));
3924
- const stage = vue.computed(() => services?.editorService.get("stage"));
3925
- vue.watch([() => node.value?.id, stage], ([id, stage2]) => {
3926
- vue.nextTick(() => {
3927
- id && stage2?.select(id);
3928
- });
3929
- });
3930
4364
  return {
3931
- uiSelectMode: vue.computed(() => services?.uiService.get("uiSelectMode")),
3932
- root: vue.computed(() => services?.editorService.get("root")),
3933
- page: vue.computed(() => services?.editorService.get("page")),
3934
- zoom: vue.computed(() => services?.uiService.get("zoom")),
3935
- node,
3936
- selectHandler(el) {
3937
- services?.editorService.select(el.id);
3938
- },
3939
- updateNodeHandler(node2) {
3940
- services?.editorService.update(node2);
3941
- },
3942
- sortNodeHandler(ev) {
3943
- services?.editorService.sort(ev.src, ev.dist);
3944
- }
4365
+ page: vue.computed(() => services?.editorService.get("page"))
3945
4366
  };
3946
4367
  }
3947
4368
  });
@@ -3954,17 +4375,9 @@
3954
4375
  key: _ctx.page?.id,
3955
4376
  "runtime-url": _ctx.runtimeUrl,
3956
4377
  render: _ctx.render,
3957
- "ui-select-mode": _ctx.uiSelectMode,
3958
- root: _ctx.root,
3959
- page: _ctx.page,
3960
- node: _ctx.node,
3961
- zoom: _ctx.zoom,
3962
4378
  "moveable-options": _ctx.moveableOptions,
3963
- "can-select": _ctx.canSelect,
3964
- onSelect: _ctx.selectHandler,
3965
- onUpdate: _ctx.updateNodeHandler,
3966
- onSort: _ctx.sortNodeHandler
3967
- }, null, 8, ["runtime-url", "render", "ui-select-mode", "root", "page", "node", "zoom", "moveable-options", "can-select", "onSelect", "onUpdate", "onSort"])),
4379
+ "can-select": _ctx.canSelect
4380
+ }, null, 8, ["runtime-url", "render", "moveable-options", "can-select"])),
3968
4381
  vue.renderSlot(_ctx.$slots, "workspace-content"),
3969
4382
  vue.createVNode(_component_page_bar, null, {
3970
4383
  "page-bar-title": vue.withCtx(({ page }) => [
@@ -3995,15 +4408,24 @@
3995
4408
  }
3996
4409
  var componentListService = new ComponentList();
3997
4410
 
4411
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4412
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
3998
4413
  const state = vue.reactive({
3999
4414
  uiSelectMode: false,
4000
4415
  showSrc: false,
4001
4416
  zoom: 1,
4002
- stageStyle: {},
4417
+ stageContainerRect: {
4418
+ width: 0,
4419
+ height: 0
4420
+ },
4421
+ stageRect: {
4422
+ width: 375,
4423
+ height: 817
4424
+ },
4003
4425
  columnWidth: {
4004
- left: 310,
4005
- center: globalThis.document.body.clientWidth - 310 - 400,
4006
- right: 400
4426
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
4427
+ center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4428
+ right: DEFAULT_RIGHT_COLUMN_WIDTH
4007
4429
  },
4008
4430
  showGuides: true,
4009
4431
  showRule: true
@@ -4023,6 +4445,10 @@
4023
4445
  this.setColumnWidth(value);
4024
4446
  return;
4025
4447
  }
4448
+ if (name === "stageRect") {
4449
+ this.setStageRect(value);
4450
+ return;
4451
+ }
4026
4452
  if (name === "showGuides") {
4027
4453
  mask?.showGuides(value);
4028
4454
  }
@@ -4030,6 +4456,9 @@
4030
4456
  mask?.showRule(value);
4031
4457
  }
4032
4458
  state[name] = value;
4459
+ if (name === "stageContainerRect") {
4460
+ state.zoom = this.calcZoom();
4461
+ }
4033
4462
  }
4034
4463
  get(name) {
4035
4464
  return state[name];
@@ -4052,6 +4481,23 @@
4052
4481
  }
4053
4482
  state.columnWidth = columnWidth;
4054
4483
  }
4484
+ setStageRect(value) {
4485
+ state.stageRect = {
4486
+ ...state.stageRect,
4487
+ ...value
4488
+ };
4489
+ state.zoom = this.calcZoom();
4490
+ }
4491
+ calcZoom() {
4492
+ const { stageRect, stageContainerRect } = state;
4493
+ const { height, width } = stageContainerRect;
4494
+ if (!width || !height)
4495
+ return 1;
4496
+ if (width > stageRect.width && height > stageRect.height) {
4497
+ return 1;
4498
+ }
4499
+ return Math.min((width - 100) / stageRect.width || 1, (height - 100) / stageRect.height || 1);
4500
+ }
4055
4501
  }
4056
4502
  var uiService = new Ui();
4057
4503
 
@@ -4106,7 +4552,7 @@
4106
4552
  canSelect: {
4107
4553
  type: Function
4108
4554
  },
4109
- stageStyle: {
4555
+ stageRect: {
4110
4556
  type: [String, Object]
4111
4557
  }
4112
4558
  },
@@ -4144,7 +4590,7 @@
4144
4590
  vue.watch(() => props.defaultSelected, (defaultSelected) => defaultSelected && editorService.select(defaultSelected), {
4145
4591
  immediate: true
4146
4592
  });
4147
- vue.watch(() => props.stageStyle, (stageStyle) => uiService.set("stageStyle", stageStyle), {
4593
+ vue.watch(() => props.stageRect, (stageRect) => stageRect && uiService.set("stageRect", stageRect), {
4148
4594
  immediate: true
4149
4595
  });
4150
4596
  vue.onUnmounted(() => editorService.destroy());
@@ -4234,6 +4680,7 @@
4234
4680
  exports.ComponentListPanel = ComponentListPanel;
4235
4681
  exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
4236
4682
  exports.Fixed2Other = Fixed2Other;
4683
+ exports.Keys = Keys;
4237
4684
  exports.LayerOffset = LayerOffset;
4238
4685
  exports.LayerPanel = LayerPanel;
4239
4686
  exports.Layout = Layout;
@@ -4243,7 +4690,6 @@
4243
4690
  exports.change2Fixed = change2Fixed;
4244
4691
  exports.debug = debug;
4245
4692
  exports["default"] = index;
4246
- exports.defaults = defaults;
4247
4693
  exports.editorService = editorService;
4248
4694
  exports.error = error;
4249
4695
  exports.eventsService = eventsService;