@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,8 +1,10 @@
1
- import { defineComponent, computed, resolveComponent, openBlock, createBlock, normalizeStyle, ref, watchEffect, inject, createElementBlock, createElementVNode, toDisplayString, withModifiers, createCommentVNode, watch, onMounted, onUnmounted, reactive, toRaw, createVNode, withCtx, renderSlot, Fragment, normalizeClass, resolveDynamicComponent, renderList, createTextVNode, normalizeProps, mergeProps, getCurrentInstance, withDirectives, vShow, Teleport, toHandlers, createSlots, nextTick, provide } from 'vue';
1
+ import { defineComponent, computed, resolveComponent, openBlock, createBlock, normalizeStyle, ref, watchEffect, inject, createElementBlock, createElementVNode, toDisplayString, withModifiers, createCommentVNode, watch, onMounted, onUnmounted, reactive, toRaw, createVNode, withCtx, renderSlot, Fragment, normalizeClass, resolveDynamicComponent, renderList, createTextVNode, normalizeProps, mergeProps, getCurrentInstance, withDirectives, vShow, Teleport, toHandlers, createSlots, markRaw, provide } from 'vue';
2
2
  import serialize from 'serialize-javascript';
3
- import { asyncLoadJs, toLine, isPop, getNodePath } from '@tmagic/utils';
4
- import { Plus, Edit, ArrowDown, Grid, ScaleToOriginal, ZoomOut, ZoomIn, Right, Back, Delete, Files, Coin, CaretBottom } from '@element-plus/icons';
5
- import { cloneDeep, random } from 'lodash-es';
3
+ import * as monaco from 'monaco-editor';
4
+ import { Plus, Edit, ArrowDown, Grid, ScaleToOriginal, ZoomOut, ZoomIn, Right, Back, Delete, Files, Coin, ArrowLeftBold, ArrowRightBold, CaretBottom } from '@element-plus/icons';
5
+ import { NodeType } from '@tmagic/schema';
6
+ import { cloneDeep, random, mergeWith, throttle } from 'lodash-es';
7
+ import { toLine, isPop, getNodePath } from '@tmagic/utils';
6
8
  import { EventEmitter as EventEmitter$2 } from 'events';
7
9
  import { DEFAULT_EVENTS, DEFAULT_METHODS } from '@tmagic/core';
8
10
  import { ElMessage } from 'element-plus';
@@ -16,7 +18,7 @@ var _export_sfc = (sfc, props) => {
16
18
  return target;
17
19
  };
18
20
 
19
- const _sfc_main$j = defineComponent({
21
+ const _sfc_main$k = defineComponent({
20
22
  name: "m-fields-vs-code",
21
23
  props: ["model", "name", "config", "prop"],
22
24
  emits: ["change"],
@@ -33,7 +35,7 @@ const _sfc_main$j = defineComponent({
33
35
  };
34
36
  }
35
37
  });
36
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
38
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
37
39
  const _component_magic_code_editor = resolveComponent("magic-code-editor");
38
40
  return openBlock(), createBlock(_component_magic_code_editor, {
39
41
  style: normalizeStyle(`height: ${_ctx.height}`),
@@ -42,9 +44,9 @@ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
42
44
  onSave: _ctx.save
43
45
  }, null, 8, ["style", "init-values", "language", "onSave"]);
44
46
  }
45
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
47
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
46
48
 
47
- const _sfc_main$i = defineComponent({
49
+ const _sfc_main$j = defineComponent({
48
50
  name: "m-fields-code-link",
49
51
  props: {
50
52
  config: {
@@ -99,7 +101,7 @@ const _sfc_main$i = defineComponent({
99
101
  };
100
102
  }
101
103
  });
102
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
104
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
103
105
  const _component_m_fields_link = resolveComponent("m-fields-link");
104
106
  return openBlock(), createBlock(_component_m_fields_link, {
105
107
  config: _ctx.formConfig,
@@ -108,11 +110,11 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
108
110
  onChange: _ctx.changeHandler
109
111
  }, null, 8, ["config", "model", "onChange"]);
110
112
  }
111
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
113
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
112
114
 
113
115
  var UISelect_vue_vue_type_style_index_0_lang = '';
114
116
 
115
- const _sfc_main$h = defineComponent({
117
+ const _sfc_main$i = defineComponent({
116
118
  name: "m-fields-ui-select",
117
119
  props: {
118
120
  labelWidth: String,
@@ -174,15 +176,15 @@ const _sfc_main$h = defineComponent({
174
176
  };
175
177
  }
176
178
  });
177
- const _hoisted_1$d = /* @__PURE__ */ createElementVNode("i", {
179
+ const _hoisted_1$e = /* @__PURE__ */ createElementVNode("i", {
178
180
  class: "el-icon-delete",
179
181
  style: { "color": "rgb(221, 75, 57)" }
180
182
  }, "\u53D6\u6D88", -1);
181
183
  const _hoisted_2$7 = [
182
- _hoisted_1$d
184
+ _hoisted_1$e
183
185
  ];
184
186
  const _hoisted_3$5 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
185
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
187
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
186
188
  return _ctx.uiSelectMode ? (openBlock(), createElementBlock("div", {
187
189
  key: 0,
188
190
  class: "m-fields-ui-select",
@@ -201,23 +203,8 @@ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
201
203
  })) : createCommentVNode("", true)
202
204
  ]));
203
205
  }
204
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
206
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
205
207
 
206
- const initEditor = () => {
207
- if (globalThis.monaco) {
208
- Promise.resolve(globalThis.monaco);
209
- }
210
- return asyncLoadJs(`https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js`).then(() => {
211
- globalThis.require.config({
212
- paths: { vs: `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs` }
213
- });
214
- return new Promise((resolve) => {
215
- globalThis.require(["vs/editor/editor.main"], () => {
216
- resolve(globalThis.monaco);
217
- });
218
- });
219
- });
220
- };
221
208
  const toString = (v, language) => {
222
209
  let value = "";
223
210
  if (typeof v !== "string") {
@@ -233,7 +220,7 @@ const toString = (v, language) => {
233
220
  }
234
221
  return value;
235
222
  };
236
- const _sfc_main$g = defineComponent({
223
+ const _sfc_main$h = defineComponent({
237
224
  name: "magic-code-editor",
238
225
  props: {
239
226
  initValues: {
@@ -251,32 +238,34 @@ const _sfc_main$g = defineComponent({
251
238
  default: () => "javascript"
252
239
  }
253
240
  },
254
- emits: ["inited", "save"],
241
+ emits: ["initd", "save"],
255
242
  setup(props, { emit }) {
256
243
  let vsEditor = null;
244
+ let vsDiffEditor = null;
257
245
  const values = ref("");
258
246
  const loading = ref(false);
259
247
  const codeEditor = ref();
260
248
  const setEditorValue = (v, m) => {
261
249
  values.value = toString(v, props.language);
262
250
  if (props.type === "diff") {
263
- const originalModel = globalThis.monaco.editor.createModel(values.value, "text/javascript");
264
- const modifiedModel = globalThis.monaco.editor.createModel(toString(m, props.language), "text/javascript");
265
- return vsEditor.setModel({
251
+ const originalModel = monaco.editor.createModel(values.value, "text/javascript");
252
+ const modifiedModel = monaco.editor.createModel(toString(m, props.language), "text/javascript");
253
+ return vsDiffEditor?.setModel({
266
254
  original: originalModel,
267
255
  modified: modifiedModel
268
256
  });
269
257
  }
270
- return vsEditor.setValue?.(values.value);
258
+ return vsEditor?.setValue(values.value);
271
259
  };
272
260
  const resizeHandler = () => {
273
261
  vsEditor?.layout();
262
+ vsDiffEditor?.layout();
274
263
  };
275
- const getEditorValue = () => vsEditor.getValue?.() || "";
264
+ const getEditorValue = () => props.type === "diff" ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
276
265
  const init = async () => {
277
266
  if (!codeEditor.value)
278
267
  return;
279
- vsEditor = globalThis.monaco.editor[props.type === "diff" ? "createDiffEditor" : "create"](codeEditor.value, {
268
+ const options = {
280
269
  value: values.value,
281
270
  language: props.language,
282
271
  tabSize: 2,
@@ -284,10 +273,15 @@ const _sfc_main$g = defineComponent({
284
273
  fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
285
274
  fontSize: 15,
286
275
  formatOnPaste: true
287
- });
276
+ };
277
+ if (props.type === "diff") {
278
+ vsDiffEditor = monaco.editor.createDiffEditor(codeEditor.value, options);
279
+ } else {
280
+ vsEditor = monaco.editor.create(codeEditor.value, options);
281
+ }
288
282
  setEditorValue(props.initValues, props.modifiedValues);
289
283
  loading.value = false;
290
- emit("inited", vsEditor);
284
+ emit("initd", vsEditor);
291
285
  codeEditor.value.addEventListener("keydown", (e) => {
292
286
  if (e.keyCode === 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
293
287
  e.preventDefault();
@@ -295,14 +289,14 @@ const _sfc_main$g = defineComponent({
295
289
  }
296
290
  });
297
291
  if (props.type !== "diff") {
298
- vsEditor.onDidBlurEditorWidget(() => {
292
+ vsEditor?.onDidBlurEditorWidget(() => {
299
293
  emit("save", getEditorValue());
300
294
  });
301
295
  }
302
296
  globalThis.addEventListener("resize", resizeHandler);
303
297
  };
304
298
  watch(() => props.initValues, (v, preV) => {
305
- if (vsEditor && v !== preV) {
299
+ if (v !== preV) {
306
300
  setEditorValue(props.initValues, props.modifiedValues);
307
301
  }
308
302
  }, {
@@ -311,17 +305,7 @@ const _sfc_main$g = defineComponent({
311
305
  });
312
306
  onMounted(async () => {
313
307
  loading.value = true;
314
- await initEditor();
315
- if (!globalThis.monaco) {
316
- const interval = setInterval(() => {
317
- if (globalThis.monaco) {
318
- clearInterval(interval);
319
- init();
320
- }
321
- }, 300);
322
- } else {
323
- init();
324
- }
308
+ init();
325
309
  });
326
310
  onUnmounted(() => {
327
311
  globalThis.removeEventListener("resize", resizeHandler);
@@ -331,23 +315,24 @@ const _sfc_main$g = defineComponent({
331
315
  loading,
332
316
  codeEditor,
333
317
  getEditor() {
334
- return vsEditor;
318
+ return vsEditor || vsDiffEditor;
335
319
  },
336
320
  setEditorValue,
337
321
  focus() {
338
- vsEditor.focus();
322
+ vsEditor?.focus();
323
+ vsDiffEditor?.focus();
339
324
  }
340
325
  };
341
326
  }
342
327
  });
343
- const _hoisted_1$c = {
328
+ const _hoisted_1$d = {
344
329
  ref: "codeEditor",
345
330
  class: "magic-code-editor"
346
331
  };
347
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
348
- return openBlock(), createElementBlock("div", _hoisted_1$c, null, 512);
332
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
333
+ return openBlock(), createElementBlock("div", _hoisted_1$d, null, 512);
349
334
  }
350
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
335
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
351
336
 
352
337
  let $TMAGIC_EDITOR = {};
353
338
  const setConfig = (option) => {
@@ -431,10 +416,39 @@ const compose = (middleware) => {
431
416
 
432
417
  const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
433
418
  const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
419
+ const doAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
420
+ try {
421
+ let beforeArgs = args;
422
+ for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
423
+ let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
424
+ if (isError(beforeReturnValue))
425
+ throw beforeReturnValue;
426
+ if (!Array.isArray(beforeReturnValue)) {
427
+ beforeReturnValue = [beforeReturnValue];
428
+ }
429
+ beforeArgs = beforeArgs.map((v, index) => {
430
+ if (typeof beforeReturnValue[index] === "undefined")
431
+ return v;
432
+ return beforeReturnValue[index];
433
+ });
434
+ }
435
+ let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
436
+ for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
437
+ returnValue = await afterMethod(...beforeArgs, returnValue);
438
+ if (isError(returnValue))
439
+ throw returnValue;
440
+ }
441
+ return returnValue;
442
+ } catch (error) {
443
+ throw error;
444
+ }
445
+ };
434
446
  class BaseService extends EventEmitter$2 {
435
447
  pluginOptionsList = {};
436
448
  middleware = {};
437
- constructor(methods) {
449
+ taskList = [];
450
+ doingTask = false;
451
+ constructor(methods = [], serialMethods = []) {
438
452
  super();
439
453
  methods.forEach((propertyName) => {
440
454
  const scope = this;
@@ -447,27 +461,23 @@ class BaseService extends EventEmitter$2 {
447
461
  const fn = compose(this.middleware[propertyName]);
448
462
  Object.defineProperty(scope, propertyName, {
449
463
  value: async (...args) => {
450
- let beforeArgs = args;
451
- for (const beforeMethod of this.pluginOptionsList[beforeMethodName]) {
452
- let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
453
- if (isError(beforeReturnValue))
454
- throw beforeReturnValue;
455
- if (!Array.isArray(beforeReturnValue)) {
456
- beforeReturnValue = [beforeReturnValue];
457
- }
458
- beforeArgs = beforeArgs.map((v, index) => {
459
- if (typeof beforeReturnValue[index] === "undefined")
460
- return v;
461
- return beforeReturnValue[index];
462
- });
464
+ if (!serialMethods.includes(propertyName)) {
465
+ return doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
463
466
  }
464
- let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
465
- for (const afterMethod of this.pluginOptionsList[afterMethodName]) {
466
- returnValue = await afterMethod(...beforeArgs, returnValue);
467
- if (isError(returnValue))
468
- throw returnValue;
467
+ const promise = new Promise((resolve, reject) => {
468
+ this.taskList.push(async () => {
469
+ try {
470
+ const value = await doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
471
+ resolve(value);
472
+ } catch (e) {
473
+ reject(e);
474
+ }
475
+ });
476
+ });
477
+ if (!this.doingTask) {
478
+ this.doTask();
469
479
  }
470
- return returnValue;
480
+ return promise;
471
481
  }
472
482
  });
473
483
  });
@@ -484,6 +494,15 @@ class BaseService extends EventEmitter$2 {
484
494
  this.pluginOptionsList[methodName2].push(method);
485
495
  });
486
496
  }
497
+ async doTask() {
498
+ this.doingTask = true;
499
+ let task = this.taskList.shift();
500
+ while (task) {
501
+ await task();
502
+ task = this.taskList.shift();
503
+ }
504
+ this.doingTask = false;
505
+ }
487
506
  }
488
507
 
489
508
  class History extends BaseService {
@@ -620,12 +639,16 @@ var Layout = /* @__PURE__ */ ((Layout2) => {
620
639
  Layout2["ABSOLUTE"] = "absolute";
621
640
  return Layout2;
622
641
  })(Layout || {});
642
+ var Keys = /* @__PURE__ */ ((Keys2) => {
643
+ Keys2["ESCAPE"] = "Space";
644
+ return Keys2;
645
+ })(Keys || {});
623
646
 
624
647
  const COPY_STORAGE_KEY = "$MagicEditorCopyData";
625
648
  const generateId = (type) => `${type}_${random(1e4, false)}`;
626
649
  const getPageList = (app) => {
627
650
  if (app.items && Array.isArray(app.items)) {
628
- return app.items.filter((item) => item.type === "page");
651
+ return app.items.filter((item) => item.type === NodeType.PAGE);
629
652
  }
630
653
  return [];
631
654
  };
@@ -661,7 +684,7 @@ const setNewItemId = (config, parent) => {
661
684
  const oldId = config.id;
662
685
  config.id = generateId(config.type);
663
686
  config.name = `${config.name?.replace(/_(\d+)$/, "")}_${config.id}`;
664
- if (isPop(config) && parent?.type === "page") {
687
+ if (isPop(config) && parent?.type === NodeType.PAGE) {
665
688
  updatePopId(oldId, config.id, parent);
666
689
  }
667
690
  if (config.items && Array.isArray(config.items)) {
@@ -754,22 +777,6 @@ const Fixed2Other = async (node, root, getLayout) => {
754
777
  }
755
778
  return toRelative(node);
756
779
  };
757
- const defaults = (object, source) => {
758
- let o = source;
759
- if (Array.isArray(object)) {
760
- o = object;
761
- }
762
- Object.entries(o).forEach(([key, value]) => {
763
- if (typeof object[key] === "undefined") {
764
- object[key] = value;
765
- return;
766
- }
767
- if (value && typeof value !== "string" && Object.keys(value).length) {
768
- object[key] = defaults(cloneDeep(object[key]), value);
769
- }
770
- });
771
- return object;
772
- };
773
780
 
774
781
  const log = (...args) => {
775
782
  };
@@ -790,6 +797,7 @@ class Editor$1 extends BaseService {
790
797
  parent: null,
791
798
  node: null,
792
799
  stage: null,
800
+ highlightNode: null,
793
801
  modifiedNodeIds: /* @__PURE__ */ new Map()
794
802
  });
795
803
  constructor() {
@@ -805,8 +813,9 @@ class Editor$1 extends BaseService {
805
813
  "alignCenter",
806
814
  "moveLayer",
807
815
  "undo",
808
- "redo"
809
- ]);
816
+ "redo",
817
+ "highlight"
818
+ ], ["select", "update", "moveLayer"]);
810
819
  }
811
820
  set(name, value) {
812
821
  this.state[name] = value;
@@ -832,7 +841,7 @@ class Editor$1 extends BaseService {
832
841
  info.node = path[path.length - 1];
833
842
  info.parent = path[path.length - 2];
834
843
  path.forEach((item) => {
835
- if (item.type === "page") {
844
+ if (item.type === NodeType.PAGE) {
836
845
  info.page = item;
837
846
  return;
838
847
  }
@@ -859,18 +868,7 @@ class Editor$1 extends BaseService {
859
868
  return Layout.ABSOLUTE;
860
869
  }
861
870
  async select(config2) {
862
- let id;
863
- if (typeof config2 === "string" || typeof config2 === "number") {
864
- id = config2;
865
- } else {
866
- id = config2.id;
867
- }
868
- if (!id) {
869
- throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
870
- }
871
- const { node, parent, page } = this.getNodeInfo(id);
872
- if (!node)
873
- throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
871
+ const { node, page, parent } = this.selectedConfigExceptionHandler(config2);
874
872
  this.set("node", node);
875
873
  this.set("page", page || null);
876
874
  this.set("parent", parent || null);
@@ -881,10 +879,17 @@ class Editor$1 extends BaseService {
881
879
  }
882
880
  return node;
883
881
  }
882
+ highlight(config2) {
883
+ const { node } = this.selectedConfigExceptionHandler(config2);
884
+ const currentHighlightNode = this.get("highlightNode");
885
+ if (currentHighlightNode === node)
886
+ return;
887
+ this.set("highlightNode", node);
888
+ }
884
889
  async add({ type, ...config2 }, parent) {
885
890
  const curNode = this.get("node");
886
891
  let parentNode;
887
- if (type === "page") {
892
+ if (type === NodeType.PAGE) {
888
893
  parentNode = this.get("root");
889
894
  } else if (parent && typeof parent !== "function") {
890
895
  parentNode = parent;
@@ -897,14 +902,18 @@ class Editor$1 extends BaseService {
897
902
  throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
898
903
  const layout = await this.getLayout(parentNode);
899
904
  const newNode = initPosition({ ...toRaw(await propsService.getPropsValue(type)), ...config2 }, layout);
900
- if ((parentNode?.type === "app" || curNode.type === "app") && newNode.type !== "page") {
905
+ if ((parentNode?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && newNode.type !== NodeType.PAGE) {
901
906
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
902
907
  }
903
908
  parentNode?.items?.push(newNode);
904
- await this.get("stage")?.add({ config: cloneDeep(newNode), root: cloneDeep(this.get("root")) });
909
+ const stage = this.get("stage");
910
+ await stage?.add({ config: cloneDeep(newNode), root: cloneDeep(this.get("root")) });
905
911
  await this.select(newNode);
906
912
  this.addModifiedNodeId(newNode.id);
907
- this.pushHistoryState();
913
+ if (type !== NodeType.PAGE) {
914
+ this.pushHistoryState();
915
+ }
916
+ stage?.select(newNode.id);
908
917
  return newNode;
909
918
  }
910
919
  async remove(node) {
@@ -920,11 +929,16 @@ class Editor$1 extends BaseService {
920
929
  if (typeof index !== "number" || index === -1)
921
930
  throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
922
931
  parent.items?.splice(index, 1);
923
- this.get("stage")?.remove({ id: node.id, root: this.get("root") });
924
- if (node.type === "page") {
925
- await this.select(root.items[0] || root);
932
+ const stage = this.get("stage");
933
+ stage?.remove({ id: node.id, root: this.get("root") });
934
+ if (node.type === NodeType.PAGE) {
935
+ if (root.items[0]) {
936
+ await this.select(root.items[0]);
937
+ stage?.select(root.items[0].id);
938
+ }
926
939
  } else {
927
940
  await this.select(parent);
941
+ stage?.select(parent.id);
928
942
  }
929
943
  this.addModifiedNodeId(parent.id);
930
944
  this.pushHistoryState();
@@ -937,17 +951,21 @@ class Editor$1 extends BaseService {
937
951
  if (!info.node)
938
952
  throw new Error(`\u83B7\u53D6\u4E0D\u5230id\u4E3A${config2.id}\u7684\u8282\u70B9`);
939
953
  const node = cloneDeep(toRaw(info.node));
940
- const { parent } = info;
941
- if (!parent)
942
- throw new Error("\u83B7\u53D6\u4E0D\u5230\u7236\u7EA7\u8282\u70B9");
943
954
  let newConfig = await this.toggleFixedPosition(toRaw(config2), node, this.get("root"));
944
- defaults(newConfig, node);
955
+ newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => {
956
+ if (Array.isArray(srcValue)) {
957
+ return srcValue;
958
+ }
959
+ });
945
960
  if (!newConfig.type)
946
961
  throw new Error("\u914D\u7F6E\u7F3A\u5C11type\u503C");
947
- if (newConfig.type === "app") {
962
+ if (newConfig.type === NodeType.ROOT) {
948
963
  this.set("root", newConfig);
949
964
  return newConfig;
950
965
  }
966
+ const { parent } = info;
967
+ if (!parent)
968
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7236\u7EA7\u8282\u70B9");
951
969
  const parentNodeItems = parent.items;
952
970
  const index = getNodeIndex(newConfig, parent);
953
971
  if (!parentNodeItems || typeof index === "undefined" || index === -1)
@@ -958,11 +976,11 @@ class Editor$1 extends BaseService {
958
976
  newConfig = setLayout(newConfig, newLayout);
959
977
  }
960
978
  parentNodeItems[index] = newConfig;
961
- if (newConfig.id === this.get("node").id) {
979
+ if (`${newConfig.id}` === `${this.get("node").id}`) {
962
980
  this.set("node", newConfig);
981
+ this.get("stage")?.update({ config: cloneDeep(newConfig), root: this.get("root") });
963
982
  }
964
- this.get("stage")?.update({ config: cloneDeep(newConfig), root: this.get("root") });
965
- if (newConfig.type === "page") {
983
+ if (newConfig.type === NodeType.PAGE) {
966
984
  this.set("page", newConfig);
967
985
  }
968
986
  this.addModifiedNodeId(newConfig.id);
@@ -979,6 +997,7 @@ class Editor$1 extends BaseService {
979
997
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
980
998
  await this.update(parent);
981
999
  await this.select(node);
1000
+ this.get("stage")?.update({ config: cloneDeep(node), root: this.get("root") });
982
1001
  this.addModifiedNodeId(parent.id);
983
1002
  this.pushHistoryState();
984
1003
  }
@@ -1091,6 +1110,28 @@ class Editor$1 extends BaseService {
1091
1110
  }
1092
1111
  return newConfig;
1093
1112
  }
1113
+ selectedConfigExceptionHandler(config2) {
1114
+ let id;
1115
+ if (typeof config2 === "string" || typeof config2 === "number") {
1116
+ id = config2;
1117
+ } else {
1118
+ id = config2.id;
1119
+ }
1120
+ if (!id) {
1121
+ throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
1122
+ }
1123
+ const { node, parent, page } = this.getNodeInfo(id);
1124
+ if (!node)
1125
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
1126
+ if (node.id === this.state.root?.id) {
1127
+ throw new Error("\u4E0D\u80FD\u9009\u6839\u8282\u70B9");
1128
+ }
1129
+ return {
1130
+ node,
1131
+ parent,
1132
+ page
1133
+ };
1134
+ }
1094
1135
  }
1095
1136
  var editorService = new Editor$1();
1096
1137
 
@@ -1315,7 +1356,7 @@ const getDefaultPropsValue = (type) => ({
1315
1356
  name: type
1316
1357
  });
1317
1358
 
1318
- const _sfc_main$f = defineComponent({
1359
+ const _sfc_main$g = defineComponent({
1319
1360
  components: { Plus },
1320
1361
  setup() {
1321
1362
  const services = inject("services");
@@ -1325,20 +1366,20 @@ const _sfc_main$f = defineComponent({
1325
1366
  if (!editorService)
1326
1367
  return;
1327
1368
  editorService.add({
1328
- type: "page",
1369
+ type: NodeType.PAGE,
1329
1370
  name: generatePageNameByApp(toRaw(editorService.get("root")))
1330
1371
  });
1331
1372
  }
1332
1373
  };
1333
1374
  }
1334
1375
  });
1335
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
1376
+ const _hoisted_1$c = { class: "m-editor-empty-panel" };
1336
1377
  const _hoisted_2$6 = { class: "m-editor-empty-content" };
1337
1378
  const _hoisted_3$4 = /* @__PURE__ */ createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1338
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
1379
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1339
1380
  const _component_plus = resolveComponent("plus");
1340
1381
  const _component_el_icon = resolveComponent("el-icon");
1341
- return openBlock(), createElementBlock("div", _hoisted_1$b, [
1382
+ return openBlock(), createElementBlock("div", _hoisted_1$c, [
1342
1383
  createElementVNode("div", _hoisted_2$6, [
1343
1384
  createElementVNode("div", {
1344
1385
  class: "m-editor-empty-button",
@@ -1357,7 +1398,7 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
1357
1398
  ])
1358
1399
  ]);
1359
1400
  }
1360
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
1401
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1361
1402
 
1362
1403
  /*
1363
1404
  Copyright (c) 2018 Daybrush
@@ -2526,7 +2567,7 @@ function (_super) {
2526
2567
 
2527
2568
  var Gesto$1 = Gesto;
2528
2569
 
2529
- const _sfc_main$e = defineComponent({
2570
+ const _sfc_main$f = defineComponent({
2530
2571
  name: "m-editor-resize",
2531
2572
  props: {
2532
2573
  type: {
@@ -2568,18 +2609,18 @@ const _sfc_main$e = defineComponent({
2568
2609
  };
2569
2610
  }
2570
2611
  });
2571
- const _hoisted_1$a = {
2612
+ const _hoisted_1$b = {
2572
2613
  ref: "target",
2573
2614
  class: "m-editor-resizer"
2574
2615
  };
2575
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2576
- return openBlock(), createElementBlock("span", _hoisted_1$a, [
2616
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2617
+ return openBlock(), createElementBlock("span", _hoisted_1$b, [
2577
2618
  renderSlot(_ctx.$slots, "default")
2578
2619
  ], 512);
2579
2620
  }
2580
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2621
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2581
2622
 
2582
- const _sfc_main$d = defineComponent({
2623
+ const _sfc_main$e = defineComponent({
2583
2624
  components: {
2584
2625
  AddPageBox,
2585
2626
  Resizer
@@ -2602,17 +2643,17 @@ const _sfc_main$d = defineComponent({
2602
2643
  };
2603
2644
  }
2604
2645
  });
2605
- const _hoisted_1$9 = { class: "m-editor" };
2646
+ const _hoisted_1$a = { class: "m-editor" };
2606
2647
  const _hoisted_2$5 = {
2607
2648
  key: 1,
2608
2649
  class: "m-editor-content"
2609
2650
  };
2610
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2651
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2611
2652
  const _component_magic_code_editor = resolveComponent("magic-code-editor");
2612
2653
  const _component_resizer = resolveComponent("resizer");
2613
2654
  const _component_el_scrollbar = resolveComponent("el-scrollbar");
2614
2655
  const _component_add_page_box = resolveComponent("add-page-box");
2615
- return openBlock(), createElementBlock("div", _hoisted_1$9, [
2656
+ return openBlock(), createElementBlock("div", _hoisted_1$a, [
2616
2657
  renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2617
2658
  _ctx.showSrc ? (openBlock(), createBlock(_component_magic_code_editor, {
2618
2659
  key: 0,
@@ -2652,9 +2693,9 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2652
2693
  ]))
2653
2694
  ]);
2654
2695
  }
2655
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2696
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2656
2697
 
2657
- const _sfc_main$c = defineComponent({
2698
+ const _sfc_main$d = defineComponent({
2658
2699
  name: "m-icon",
2659
2700
  components: { Edit },
2660
2701
  props: {
@@ -2668,8 +2709,8 @@ const _sfc_main$c = defineComponent({
2668
2709
  };
2669
2710
  }
2670
2711
  });
2671
- const _hoisted_1$8 = ["src"];
2672
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2712
+ const _hoisted_1$9 = ["src"];
2713
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2673
2714
  const _component_edit = resolveComponent("edit");
2674
2715
  const _component_el_icon = resolveComponent("el-icon");
2675
2716
  return !_ctx.icon ? (openBlock(), createBlock(_component_el_icon, { key: 0 }, {
@@ -2680,7 +2721,7 @@ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2680
2721
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (openBlock(), createElementBlock("img", {
2681
2722
  key: 1,
2682
2723
  src: _ctx.icon
2683
- }, null, 8, _hoisted_1$8)) : typeof _ctx.icon === "string" ? (openBlock(), createElementBlock("i", {
2724
+ }, null, 8, _hoisted_1$9)) : typeof _ctx.icon === "string" ? (openBlock(), createElementBlock("i", {
2684
2725
  key: 2,
2685
2726
  class: normalizeClass(_ctx.icon)
2686
2727
  }, null, 2)) : (openBlock(), createBlock(_component_el_icon, { key: 3 }, {
@@ -2690,9 +2731,9 @@ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2690
2731
  _: 1
2691
2732
  }));
2692
2733
  }
2693
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
2734
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2694
2735
 
2695
- const _sfc_main$b = defineComponent({
2736
+ const _sfc_main$c = defineComponent({
2696
2737
  components: { MIcon, ArrowDown },
2697
2738
  props: {
2698
2739
  data: {
@@ -2730,7 +2771,7 @@ const _sfc_main$b = defineComponent({
2730
2771
  type: "button",
2731
2772
  icon: Delete,
2732
2773
  tooltip: "\u522A\u9664",
2733
- disabled: () => services?.editorService.get("node")?.type === "page",
2774
+ disabled: () => services?.editorService.get("node")?.type === NodeType.PAGE,
2734
2775
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
2735
2776
  };
2736
2777
  case "undo":
@@ -2827,7 +2868,7 @@ const _sfc_main$b = defineComponent({
2827
2868
  };
2828
2869
  }
2829
2870
  });
2830
- const _hoisted_1$7 = {
2871
+ const _hoisted_1$8 = {
2831
2872
  key: 0,
2832
2873
  class: "menu-item"
2833
2874
  };
@@ -2839,8 +2880,8 @@ const _hoisted_3$3 = {
2839
2880
  class: "menu-item-text",
2840
2881
  style: { "margin": "0 5px" }
2841
2882
  };
2842
- const _hoisted_4$3 = { class: "el-dropdown-link menubar-menu-button" };
2843
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2883
+ const _hoisted_4$2 = { class: "el-dropdown-link menubar-menu-button" };
2884
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2844
2885
  const _component_el_divider = resolveComponent("el-divider");
2845
2886
  const _component_m_icon = resolveComponent("m-icon");
2846
2887
  const _component_el_button = resolveComponent("el-button");
@@ -2850,20 +2891,36 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2850
2891
  const _component_el_dropdown_item = resolveComponent("el-dropdown-item");
2851
2892
  const _component_el_dropdown_menu = resolveComponent("el-dropdown-menu");
2852
2893
  const _component_el_dropdown = resolveComponent("el-dropdown");
2853
- return _ctx.display ? (openBlock(), createElementBlock("div", _hoisted_1$7, [
2894
+ return _ctx.display ? (openBlock(), createElementBlock("div", _hoisted_1$8, [
2854
2895
  _ctx.item.type === "divider" ? (openBlock(), createBlock(_component_el_divider, {
2855
2896
  key: 0,
2856
2897
  direction: "vertical"
2857
2898
  })) : _ctx.item.type === "text" ? (openBlock(), createElementBlock("div", _hoisted_2$4, toDisplayString(_ctx.item.text), 1)) : _ctx.item.type === "zoom" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2858
- createVNode(_component_m_icon, {
2859
- icon: _ctx.ZoomIn,
2860
- onClick: _ctx.zoomInHandler
2861
- }, null, 8, ["icon", "onClick"]),
2899
+ createVNode(_component_el_button, {
2900
+ size: "small",
2901
+ type: "text"
2902
+ }, {
2903
+ default: withCtx(() => [
2904
+ createVNode(_component_m_icon, {
2905
+ icon: _ctx.ZoomIn,
2906
+ onClick: _ctx.zoomInHandler
2907
+ }, null, 8, ["icon", "onClick"])
2908
+ ]),
2909
+ _: 1
2910
+ }),
2862
2911
  createElementVNode("span", _hoisted_3$3, toDisplayString(parseInt(`${_ctx.zoom * 100}`, 10)) + "%", 1),
2863
- createVNode(_component_m_icon, {
2864
- icon: _ctx.ZoomOut,
2865
- onClick: _ctx.zoomOutHandler
2866
- }, null, 8, ["icon", "onClick"])
2912
+ createVNode(_component_el_button, {
2913
+ size: "small",
2914
+ type: "text"
2915
+ }, {
2916
+ default: withCtx(() => [
2917
+ createVNode(_component_m_icon, {
2918
+ icon: _ctx.ZoomOut,
2919
+ onClick: _ctx.zoomOutHandler
2920
+ }, null, 8, ["icon", "onClick"])
2921
+ ]),
2922
+ _: 1
2923
+ })
2867
2924
  ], 64)) : _ctx.item.type === "button" ? (openBlock(), createBlock(_component_el_tooltip, {
2868
2925
  key: 3,
2869
2926
  effect: "dark",
@@ -2912,7 +2969,7 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2912
2969
  })) : createCommentVNode("", true)
2913
2970
  ]),
2914
2971
  default: withCtx(() => [
2915
- createElementVNode("span", _hoisted_4$3, [
2972
+ createElementVNode("span", _hoisted_4$2, [
2916
2973
  createTextVNode(toDisplayString(_ctx.item.text), 1),
2917
2974
  createVNode(_component_el_icon, { class: "el-icon--right" }, {
2918
2975
  default: withCtx(() => [
@@ -2926,9 +2983,9 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2926
2983
  }, 8, ["disabled", "onCommand"])) : _ctx.item.type === "component" ? (openBlock(), createBlock(resolveDynamicComponent(_ctx.item.component), normalizeProps(mergeProps({ key: 5 }, _ctx.item.props || {})), null, 16)) : createCommentVNode("", true)
2927
2984
  ])) : createCommentVNode("", true);
2928
2985
  }
2929
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
2986
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
2930
2987
 
2931
- const _sfc_main$a = defineComponent({
2988
+ const _sfc_main$b = defineComponent({
2932
2989
  name: "nav-menu",
2933
2990
  components: { ToolButton },
2934
2991
  props: {
@@ -2941,12 +2998,14 @@ const _sfc_main$a = defineComponent({
2941
2998
  }
2942
2999
  },
2943
3000
  setup(props) {
3001
+ const services = inject("services");
2944
3002
  return {
2945
- keys: computed(() => Object.keys(props.data))
3003
+ keys: computed(() => Object.keys(props.data)),
3004
+ columnWidth: computed(() => services?.uiService.get("columnWidth"))
2946
3005
  };
2947
3006
  }
2948
3007
  });
2949
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3008
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2950
3009
  const _component_tool_button = resolveComponent("tool-button");
2951
3010
  return openBlock(), createElementBlock("div", {
2952
3011
  class: "m-editor-nav-menu",
@@ -2955,7 +3014,8 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2955
3014
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.keys, (key) => {
2956
3015
  return openBlock(), createElementBlock("div", {
2957
3016
  class: normalizeClass(`menu-${key}`),
2958
- key
3017
+ key,
3018
+ style: normalizeStyle(`width: ${_ctx.columnWidth?.[key]}px`)
2959
3019
  }, [
2960
3020
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.data[key], (item, index) => {
2961
3021
  return openBlock(), createBlock(_component_tool_button, {
@@ -2963,13 +3023,13 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2963
3023
  key: index
2964
3024
  }, null, 8, ["data"]);
2965
3025
  }), 128))
2966
- ], 2);
3026
+ ], 6);
2967
3027
  }), 128))
2968
3028
  ], 4);
2969
3029
  }
2970
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3030
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
2971
3031
 
2972
- const _sfc_main$9 = defineComponent({
3032
+ const _sfc_main$a = defineComponent({
2973
3033
  name: "m-editor-props-panel",
2974
3034
  emits: ["mounted"],
2975
3035
  setup(props, { emit }) {
@@ -2978,17 +3038,14 @@ const _sfc_main$9 = defineComponent({
2978
3038
  const configForm = ref();
2979
3039
  const curFormConfig = ref([]);
2980
3040
  const services = inject("services");
3041
+ const node = computed(() => services?.editorService.get("node"));
2981
3042
  const init = async () => {
2982
- const node = services?.editorService.get("node");
2983
- if (!node) {
3043
+ if (!node.value) {
2984
3044
  curFormConfig.value = [];
2985
3045
  return;
2986
3046
  }
2987
- if (node.devconfig && node.style && !isNaN(+node.style.height) && !isNaN(+node.style.width)) {
2988
- node.devconfig.ratio = node.style.height / node.style.width || 1;
2989
- }
2990
- values.value = node;
2991
- const type = node.type || (node.items ? "container" : "text");
3047
+ values.value = node.value;
3048
+ const type = node.value.type || (node.value.items ? "container" : "text");
2992
3049
  curFormConfig.value = await services?.propsService.getPropsConfig(type) || [];
2993
3050
  };
2994
3051
  watchEffect(init);
@@ -3018,10 +3075,11 @@ const _sfc_main$9 = defineComponent({
3018
3075
  };
3019
3076
  }
3020
3077
  });
3021
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3078
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3022
3079
  const _component_m_form = resolveComponent("m-form");
3023
3080
  return openBlock(), createBlock(_component_m_form, {
3024
3081
  class: "m-editor-props-panel",
3082
+ "popper-class": "m-editor-props-panel-popper",
3025
3083
  ref: "configForm",
3026
3084
  size: "small",
3027
3085
  "init-values": _ctx.values,
@@ -3029,9 +3087,9 @@ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3029
3087
  onChange: _ctx.submit
3030
3088
  }, null, 8, ["init-values", "config", "onChange"]);
3031
3089
  }
3032
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3090
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3033
3091
 
3034
- const _sfc_main$8 = defineComponent({
3092
+ const _sfc_main$9 = defineComponent({
3035
3093
  name: "ui-component-panel",
3036
3094
  components: { MIcon },
3037
3095
  setup() {
@@ -3056,9 +3114,9 @@ const _sfc_main$8 = defineComponent({
3056
3114
  };
3057
3115
  }
3058
3116
  });
3059
- const _hoisted_1$6 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3117
+ const _hoisted_1$7 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3060
3118
  const _hoisted_2$3 = ["onClick"];
3061
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3119
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3062
3120
  const _component_el_input = resolveComponent("el-input");
3063
3121
  const _component_m_icon = resolveComponent("m-icon");
3064
3122
  const _component_el_tooltip = resolveComponent("el-tooltip");
@@ -3088,7 +3146,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3088
3146
  name: index
3089
3147
  }, {
3090
3148
  title: withCtx(() => [
3091
- _hoisted_1$6,
3149
+ _hoisted_1$7,
3092
3150
  createTextVNode(toDisplayString(group.title), 1)
3093
3151
  ]),
3094
3152
  default: withCtx(() => [
@@ -3125,32 +3183,18 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3125
3183
  _: 1
3126
3184
  });
3127
3185
  }
3128
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3186
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3129
3187
 
3130
- const _sfc_main$7 = defineComponent({
3188
+ const _sfc_main$8 = defineComponent({
3131
3189
  name: "magic-editor-content-menu",
3132
- props: {
3133
- componentGroupList: {
3134
- type: Array,
3135
- default: () => []
3136
- }
3137
- },
3138
- setup(props) {
3190
+ setup() {
3139
3191
  const services = inject("services");
3140
3192
  const subVisible = ref(false);
3141
3193
  const node = computed(() => services?.editorService.get("node"));
3142
3194
  return {
3143
3195
  subVisible,
3144
3196
  node,
3145
- menu: computed(() => ({
3146
- app: [
3147
- {
3148
- type: "page",
3149
- text: "\u9875\u9762"
3150
- }
3151
- ],
3152
- component: props.componentGroupList
3153
- })),
3197
+ componentGroupList: computed(() => services?.componentListService.getList()),
3154
3198
  append(config) {
3155
3199
  services?.editorService.add({
3156
3200
  name: config.text,
@@ -3161,29 +3205,28 @@ const _sfc_main$7 = defineComponent({
3161
3205
  node.value && services?.editorService.remove(node.value);
3162
3206
  },
3163
3207
  copy(node2) {
3164
- services?.editorService.copy(node2);
3208
+ node2 && services?.editorService.copy(node2);
3165
3209
  },
3166
- setSubVisiable(v) {
3210
+ setSubVisitable(v) {
3167
3211
  subVisible.value = v;
3168
3212
  }
3169
3213
  };
3170
3214
  }
3171
3215
  });
3172
- const _hoisted_1$5 = {
3216
+ const _hoisted_1$6 = {
3173
3217
  key: 0,
3174
3218
  class: "magic-editor-content-menu"
3175
3219
  };
3176
3220
  const _hoisted_2$2 = ["onClick"];
3177
- const _hoisted_3$2 = ["onClick"];
3178
- const _hoisted_4$2 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3179
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3221
+ const _hoisted_3$2 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3222
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3180
3223
  const _component_el_scrollbar = resolveComponent("el-scrollbar");
3181
- return _ctx.node ? (openBlock(), createElementBlock("div", _hoisted_1$5, [
3224
+ return _ctx.node ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
3182
3225
  _ctx.node.items ? (openBlock(), createElementBlock("div", {
3183
3226
  key: 0,
3184
3227
  class: "magic-editor-content-menu-item",
3185
- onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisiable(true)),
3186
- onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisiable(false))
3228
+ onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisitable(true)),
3229
+ onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisitable(false))
3187
3230
  }, " \u65B0\u589E ", 32)) : createCommentVNode("", true),
3188
3231
  _ctx.node.type !== "app" ? (openBlock(), createElementBlock("div", {
3189
3232
  key: 1,
@@ -3197,8 +3240,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3197
3240
  }, " \u5220\u9664 ")) : createCommentVNode("", true),
3198
3241
  withDirectives(createElementVNode("div", {
3199
3242
  class: "subMenu",
3200
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisiable(true)),
3201
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisiable(false))
3243
+ onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisitable(true)),
3244
+ onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisitable(false))
3202
3245
  }, [
3203
3246
  createVNode(_component_el_scrollbar, null, {
3204
3247
  default: withCtx(() => [
@@ -3208,13 +3251,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3208
3251
  onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3209
3252
  type: "tab-pane"
3210
3253
  }))
3211
- }, " \u6807\u7B7E ")) : _ctx.node.type === "app" ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(_ctx.menu.app, (item) => {
3212
- return openBlock(), createElementBlock("div", {
3213
- class: "magic-editor-content-menu-item",
3214
- key: item.type,
3215
- onClick: () => _ctx.append(item)
3216
- }, toDisplayString(item.text), 9, _hoisted_2$2);
3217
- }), 128)) : _ctx.node.items ? (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(_ctx.menu.component, (list) => {
3254
+ }, " \u6807\u7B7E ")) : _ctx.node.items ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(_ctx.componentGroupList, (list) => {
3218
3255
  return openBlock(), createElementBlock("div", {
3219
3256
  key: list.title
3220
3257
  }, [
@@ -3224,10 +3261,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3224
3261
  class: "magic-editor-content-menu-item",
3225
3262
  key: item.type,
3226
3263
  onClick: () => _ctx.append(item)
3227
- }, toDisplayString(item.text), 9, _hoisted_3$2)) : createCommentVNode("", true)
3264
+ }, toDisplayString(item.text), 9, _hoisted_2$2)) : createCommentVNode("", true)
3228
3265
  ], 64);
3229
3266
  }), 256)),
3230
- _hoisted_4$2
3267
+ _hoisted_3$2
3231
3268
  ]);
3232
3269
  }), 128)) : createCommentVNode("", true)
3233
3270
  ]),
@@ -3238,22 +3275,31 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3238
3275
  ])
3239
3276
  ])) : createCommentVNode("", true);
3240
3277
  }
3241
- var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3278
+ var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3242
3279
 
3243
- const select = (data, editorService) => {
3280
+ const throttleTime = 150;
3281
+ const select = async (data, editorService) => {
3244
3282
  if (!data.id) {
3245
3283
  throw new Error("\u6CA1\u6709id");
3246
3284
  }
3247
- editorService?.select(data);
3285
+ await editorService?.select(data);
3286
+ editorService?.get("stage")?.select(data.id);
3287
+ };
3288
+ const highlight = (data, editorService) => {
3289
+ if (!data?.id) {
3290
+ throw new Error("\u6CA1\u6709id");
3291
+ }
3292
+ editorService?.highlight(data);
3293
+ editorService?.get("stage")?.highlight(data.id);
3248
3294
  };
3249
3295
  const useDrop = (tree, editorService) => ({
3250
3296
  allowDrop: (draggingNode, dropNode, type) => {
3251
3297
  const { data } = dropNode || {};
3252
3298
  const { data: ingData } = draggingNode;
3253
3299
  const { type: ingType } = ingData;
3254
- if (ingType !== "page" && data.type === "page")
3300
+ if (ingType !== NodeType.PAGE && data.type === NodeType.PAGE)
3255
3301
  return false;
3256
- if (ingType === "page" && data.type !== "page")
3302
+ if (ingType === NodeType.PAGE && data.type !== NodeType.PAGE)
3257
3303
  return false;
3258
3304
  if (!data || !data.type)
3259
3305
  return false;
@@ -3272,29 +3318,35 @@ const useDrop = (tree, editorService) => ({
3272
3318
  }
3273
3319
  });
3274
3320
  const useStatus = (tree, editorService) => {
3321
+ const highlightNode = ref();
3322
+ const node = ref();
3275
3323
  const page = computed(() => editorService?.get("page"));
3276
3324
  watchEffect(() => {
3277
3325
  if (!tree.value)
3278
3326
  return;
3279
- const node = editorService?.get("node");
3280
- node && tree.value.setCurrentKey(node.id, true);
3327
+ node.value = editorService?.get("node");
3328
+ node.value && tree.value.setCurrentKey(node.value.id, true);
3281
3329
  const parent = editorService?.get("parent");
3282
3330
  if (!parent?.id)
3283
3331
  return;
3284
3332
  const treeNode = tree.value.getNode(parent.id);
3285
3333
  treeNode?.updateChildren();
3334
+ highlightNode.value = editorService?.get("highlightNode");
3286
3335
  });
3287
3336
  return {
3288
3337
  values: computed(() => page.value ? [page.value] : []),
3289
- loadItems: (node, resolve) => {
3290
- if (Array.isArray(node.data)) {
3291
- return resolve(node.data);
3338
+ loadItems: (node2, resolve) => {
3339
+ if (Array.isArray(node2.data)) {
3340
+ return resolve(node2.data);
3292
3341
  }
3293
- if (Array.isArray(node.data?.items)) {
3294
- return resolve(node.data?.items);
3342
+ if (Array.isArray(node2.data?.items)) {
3343
+ return resolve(node2.data?.items);
3295
3344
  }
3296
3345
  resolve([]);
3297
- }
3346
+ },
3347
+ highlightNode,
3348
+ clickNode: node,
3349
+ expandedKeys: computed(() => node.value ? [node.value.id] : [])
3298
3350
  };
3299
3351
  };
3300
3352
  const useFilter = (tree) => ({
@@ -3306,12 +3358,10 @@ const useFilter = (tree) => ({
3306
3358
  let name = "";
3307
3359
  if (data.name) {
3308
3360
  name = data.name;
3309
- } else if (data.type) {
3310
- name = data.type;
3311
3361
  } else if (data.items) {
3312
3362
  name = "container";
3313
3363
  }
3314
- return name.indexOf(value) !== -1;
3364
+ return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
3315
3365
  },
3316
3366
  filterTextChangeHandler(val) {
3317
3367
  tree.value?.filter(val);
@@ -3345,17 +3395,26 @@ const useContentMenu = (editorService) => {
3345
3395
  }
3346
3396
  };
3347
3397
  };
3348
- const _sfc_main$6 = defineComponent({
3398
+ const _sfc_main$7 = defineComponent({
3349
3399
  name: "magic-editor-layer-panel",
3350
3400
  components: { LayerMenu },
3351
3401
  setup() {
3352
3402
  const services = inject("services");
3353
3403
  const tree = ref();
3404
+ const clicked = ref(false);
3354
3405
  const editorService = services?.editorService;
3406
+ const highlightHandler = throttle((data) => {
3407
+ highlight(data, editorService);
3408
+ }, throttleTime);
3409
+ const toogleClickFlag = () => {
3410
+ clicked.value = !clicked.value;
3411
+ };
3412
+ const statusData = useStatus(tree, editorService);
3413
+ const canHighlight = computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3355
3414
  return {
3356
3415
  tree,
3416
+ ...statusData,
3357
3417
  ...useDrop(tree, editorService),
3358
- ...useStatus(tree, editorService),
3359
3418
  ...useFilter(tree),
3360
3419
  ...useContentMenu(editorService),
3361
3420
  clickHandler(data) {
@@ -3363,12 +3422,17 @@ const _sfc_main$6 = defineComponent({
3363
3422
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
3364
3423
  return;
3365
3424
  }
3425
+ tree.value?.setCurrentKey(data.id);
3366
3426
  select(data, editorService);
3367
- }
3427
+ },
3428
+ highlightHandler,
3429
+ toogleClickFlag,
3430
+ canHighlight
3368
3431
  };
3369
3432
  }
3370
3433
  });
3371
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3434
+ const _hoisted_1$5 = ["id", "onMouseenter"];
3435
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3372
3436
  const _component_el_input = resolveComponent("el-input");
3373
3437
  const _component_el_tree = resolveComponent("el-tree");
3374
3438
  const _component_layer_menu = resolveComponent("layer-menu");
@@ -3389,6 +3453,7 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3389
3453
  ref: "tree",
3390
3454
  "node-key": "id",
3391
3455
  draggable: "",
3456
+ "default-expanded-keys": _ctx.expandedKeys,
3392
3457
  load: _ctx.loadItems,
3393
3458
  data: _ctx.values,
3394
3459
  "expand-on-click-node": false,
@@ -3404,15 +3469,23 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3404
3469
  "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3405
3470
  }, {
3406
3471
  default: withCtx(({ node, data }) => [
3407
- renderSlot(_ctx.$slots, "layer-node-content", {
3408
- node,
3409
- data
3410
- }, () => [
3411
- createElementVNode("span", null, toDisplayString(`${data.name} (${data.id})`), 1)
3412
- ])
3472
+ createElementVNode("div", {
3473
+ id: data.id,
3474
+ class: normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3475
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3476
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3477
+ onMouseenter: ($event) => _ctx.highlightHandler(data)
3478
+ }, [
3479
+ renderSlot(_ctx.$slots, "layer-node-content", {
3480
+ node,
3481
+ data
3482
+ }, () => [
3483
+ createElementVNode("span", null, toDisplayString(`${data.name} (${data.id})`), 1)
3484
+ ])
3485
+ ], 42, _hoisted_1$5)
3413
3486
  ]),
3414
3487
  _: 3
3415
- }, 8, ["load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : createCommentVNode("", true),
3488
+ }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : createCommentVNode("", true),
3416
3489
  (openBlock(), createBlock(Teleport, { to: "body" }, [
3417
3490
  createVNode(_component_layer_menu, {
3418
3491
  style: normalizeStyle(_ctx.menuStyle)
@@ -3422,9 +3495,9 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3422
3495
  _: 3
3423
3496
  });
3424
3497
  }
3425
- var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3498
+ var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3426
3499
 
3427
- const _sfc_main$5 = defineComponent({
3500
+ const _sfc_main$6 = defineComponent({
3428
3501
  name: "m-sidebar",
3429
3502
  components: { MIcon },
3430
3503
  props: {
@@ -3472,7 +3545,7 @@ const _hoisted_1$4 = {
3472
3545
  key: 1,
3473
3546
  class: "magic-editor-tab-panel-title"
3474
3547
  };
3475
- function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3548
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3476
3549
  const _component_m_icon = resolveComponent("m-icon");
3477
3550
  const _component_el_tab_pane = resolveComponent("el-tab-pane");
3478
3551
  const _component_el_tabs = resolveComponent("el-tabs");
@@ -3519,15 +3592,81 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3519
3592
  _: 1
3520
3593
  }, 8, ["modelValue"])) : createCommentVNode("", true);
3521
3594
  }
3522
- var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3523
-
3524
- const _sfc_main$4 = defineComponent({
3525
- components: { CaretBottom, Plus },
3595
+ var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3596
+
3597
+ const useScroll = (root) => {
3598
+ const pageBar = ref();
3599
+ const itemsContainer = ref();
3600
+ const pageBarWidth = ref(0);
3601
+ const canScroll = ref(false);
3602
+ const itemsContainerWidth = computed(() => pageBarWidth.value - 105);
3603
+ let translateLeft = 0;
3604
+ const resizeObserver = new ResizeObserver((entries) => {
3605
+ for (const { contentRect } of entries) {
3606
+ const { width } = contentRect;
3607
+ pageBarWidth.value = width || 0;
3608
+ setCanScroll();
3609
+ }
3610
+ });
3611
+ const setCanScroll = () => {
3612
+ if (itemsContainer.value) {
3613
+ canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
3614
+ }
3615
+ };
3616
+ const scroll = (type) => {
3617
+ if (!itemsContainer.value)
3618
+ return;
3619
+ const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
3620
+ if (type === "left") {
3621
+ translateLeft += 100;
3622
+ if (translateLeft > 0) {
3623
+ translateLeft = 0;
3624
+ }
3625
+ } else if (type === "right") {
3626
+ translateLeft -= 100;
3627
+ if (-translateLeft > maxScrollLeft) {
3628
+ translateLeft = -maxScrollLeft;
3629
+ }
3630
+ } else if (type === "start") {
3631
+ translateLeft = 0;
3632
+ } else if (type === "end") {
3633
+ translateLeft = -maxScrollLeft;
3634
+ }
3635
+ itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
3636
+ };
3637
+ onMounted(() => {
3638
+ pageBar.value && resizeObserver.observe(pageBar.value);
3639
+ });
3640
+ onUnmounted(() => {
3641
+ resizeObserver.disconnect();
3642
+ });
3643
+ watch(() => root.value?.items.length, (length = 0, preLength = 0) => {
3644
+ setTimeout(() => {
3645
+ setCanScroll();
3646
+ if (length < preLength) {
3647
+ scroll("start");
3648
+ } else {
3649
+ scroll("end");
3650
+ }
3651
+ });
3652
+ });
3653
+ return {
3654
+ pageBar,
3655
+ itemsContainer,
3656
+ canScroll,
3657
+ itemsContainerWidth,
3658
+ scroll
3659
+ };
3660
+ };
3661
+ const _sfc_main$5 = defineComponent({
3662
+ components: { ArrowLeftBold, ArrowRightBold, CaretBottom, Plus },
3526
3663
  setup() {
3527
3664
  const services = inject("services");
3528
3665
  const editorService = services?.editorService;
3666
+ const root = computed(() => editorService?.get("root"));
3529
3667
  return {
3530
- root: computed(() => editorService?.get("root")),
3668
+ ...useScroll(root),
3669
+ root,
3531
3670
  page: computed(() => editorService?.get("page")),
3532
3671
  switchPage(page) {
3533
3672
  editorService?.select(page);
@@ -3536,7 +3675,7 @@ const _sfc_main$4 = defineComponent({
3536
3675
  if (!editorService)
3537
3676
  return;
3538
3677
  const pageConfig = {
3539
- type: "page",
3678
+ type: NodeType.PAGE,
3540
3679
  name: generatePageNameByApp(toRaw(editorService.get("root")))
3541
3680
  };
3542
3681
  editorService.add(pageConfig);
@@ -3554,70 +3693,339 @@ const _sfc_main$4 = defineComponent({
3554
3693
  };
3555
3694
  }
3556
3695
  });
3557
- const _hoisted_1$3 = { class: "m-editor-page-bar" };
3696
+ const _hoisted_1$3 = {
3697
+ class: "m-editor-page-bar",
3698
+ ref: "pageBar"
3699
+ };
3558
3700
  const _hoisted_2$1 = ["onClick"];
3559
- const _hoisted_3$1 = ["onClick"];
3701
+ const _hoisted_3$1 = { class: "m-editor-page-bar-title" };
3560
3702
  const _hoisted_4$1 = ["onClick"];
3561
- function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3703
+ const _hoisted_5 = ["onClick"];
3704
+ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3562
3705
  const _component_plus = resolveComponent("plus");
3563
3706
  const _component_el_icon = resolveComponent("el-icon");
3707
+ const _component_arrow_left_bold = resolveComponent("arrow-left-bold");
3708
+ const _component_el_tooltip = resolveComponent("el-tooltip");
3564
3709
  const _component_caret_bottom = resolveComponent("caret-bottom");
3565
3710
  const _component_el_popover = resolveComponent("el-popover");
3711
+ const _component_arrow_right_bold = resolveComponent("arrow-right-bold");
3566
3712
  return openBlock(), createElementBlock("div", _hoisted_1$3, [
3567
3713
  createElementVNode("div", {
3568
- class: "m-editor-page-bar-item",
3714
+ id: "m-editor-page-bar-add-icon",
3715
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3569
3716
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.addPage && _ctx.addPage(...args))
3570
3717
  }, [
3571
- createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-add-icon" }, {
3718
+ createVNode(_component_el_icon, null, {
3572
3719
  default: withCtx(() => [
3573
3720
  createVNode(_component_plus)
3574
3721
  ]),
3575
3722
  _: 1
3576
3723
  })
3577
3724
  ]),
3578
- _ctx.root ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(_ctx.root.items, (item) => {
3579
- return openBlock(), createElementBlock("div", {
3580
- key: item.key,
3581
- class: normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3582
- onClick: ($event) => _ctx.switchPage(item)
3583
- }, [
3584
- renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3585
- createElementVNode("span", null, toDisplayString(item.name), 1)
3725
+ _ctx.canScroll ? (openBlock(), createElementBlock("div", {
3726
+ key: 0,
3727
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3728
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.scroll("left"))
3729
+ }, [
3730
+ createVNode(_component_el_icon, null, {
3731
+ default: withCtx(() => [
3732
+ createVNode(_component_arrow_left_bold)
3586
3733
  ]),
3587
- createVNode(_component_el_popover, {
3588
- placement: "top",
3589
- width: 160,
3590
- trigger: "hover"
3591
- }, {
3592
- reference: withCtx(() => [
3593
- createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
3594
- default: withCtx(() => [
3595
- createVNode(_component_caret_bottom)
3596
- ]),
3597
- _: 1
3598
- })
3599
- ]),
3600
- default: withCtx(() => [
3601
- createElementVNode("div", null, [
3602
- renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3603
- createElementVNode("div", {
3604
- class: "magic-editor-content-menu-item",
3605
- onClick: () => _ctx.copy(item)
3606
- }, "\u590D\u5236", 8, _hoisted_3$1),
3607
- createElementVNode("div", {
3608
- class: "magic-editor-content-menu-item",
3609
- onClick: () => _ctx.remove(item)
3610
- }, "\u5220\u9664", 8, _hoisted_4$1)
3611
- ])
3734
+ _: 1
3735
+ })
3736
+ ])) : createCommentVNode("", true),
3737
+ _ctx.root ? (openBlock(), createElementBlock("div", {
3738
+ key: 1,
3739
+ class: "m-editor-page-bar-items",
3740
+ ref: "itemsContainer",
3741
+ style: normalizeStyle(`width: ${_ctx.itemsContainerWidth}px`)
3742
+ }, [
3743
+ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.root.items, (item) => {
3744
+ return openBlock(), createElementBlock("div", {
3745
+ key: item.key,
3746
+ class: normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3747
+ onClick: ($event) => _ctx.switchPage(item)
3748
+ }, [
3749
+ createElementVNode("div", _hoisted_3$1, [
3750
+ renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3751
+ createVNode(_component_el_tooltip, {
3752
+ effect: "dark",
3753
+ placement: "top-start",
3754
+ content: item.name
3755
+ }, {
3756
+ default: withCtx(() => [
3757
+ createElementVNode("span", null, toDisplayString(item.name), 1)
3758
+ ]),
3759
+ _: 2
3760
+ }, 1032, ["content"])
3612
3761
  ])
3613
3762
  ]),
3614
- _: 2
3615
- }, 1024)
3616
- ], 10, _hoisted_2$1);
3617
- }), 128)) : createCommentVNode("", true)
3618
- ]);
3763
+ createVNode(_component_el_popover, {
3764
+ placement: "top",
3765
+ width: 160,
3766
+ trigger: "hover"
3767
+ }, {
3768
+ reference: withCtx(() => [
3769
+ createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
3770
+ default: withCtx(() => [
3771
+ createVNode(_component_caret_bottom)
3772
+ ]),
3773
+ _: 1
3774
+ })
3775
+ ]),
3776
+ default: withCtx(() => [
3777
+ createElementVNode("div", null, [
3778
+ renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3779
+ createElementVNode("div", {
3780
+ class: "magic-editor-content-menu-item",
3781
+ onClick: () => _ctx.copy(item)
3782
+ }, "\u590D\u5236", 8, _hoisted_4$1),
3783
+ createElementVNode("div", {
3784
+ class: "magic-editor-content-menu-item",
3785
+ onClick: () => _ctx.remove(item)
3786
+ }, "\u5220\u9664", 8, _hoisted_5)
3787
+ ])
3788
+ ])
3789
+ ]),
3790
+ _: 2
3791
+ }, 1024)
3792
+ ], 10, _hoisted_2$1);
3793
+ }), 128))
3794
+ ], 4)) : createCommentVNode("", true),
3795
+ _ctx.canScroll ? (openBlock(), createElementBlock("div", {
3796
+ key: 2,
3797
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3798
+ onClick: _cache[2] || (_cache[2] = ($event) => _ctx.scroll("right"))
3799
+ }, [
3800
+ createVNode(_component_el_icon, null, {
3801
+ default: withCtx(() => [
3802
+ createVNode(_component_arrow_right_bold)
3803
+ ]),
3804
+ _: 1
3805
+ })
3806
+ ])) : createCommentVNode("", true)
3807
+ ], 512);
3808
+ }
3809
+ var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3810
+
3811
+ class ScrollViewer$1 {
3812
+ enter = false;
3813
+ targetEnter = false;
3814
+ keydown = false;
3815
+ container;
3816
+ target;
3817
+ zoom = 1;
3818
+ scrollLeft = 0;
3819
+ scrollTop = 0;
3820
+ x = 0;
3821
+ y = 0;
3822
+ resizeObserver = new ResizeObserver((entries) => {
3823
+ for (const { contentRect } of entries) {
3824
+ const { width, height } = contentRect;
3825
+ const targetRect = this.target.getBoundingClientRect();
3826
+ const targetWidth = targetRect.width * this.zoom;
3827
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
3828
+ const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3829
+ if (targetWidth < width) {
3830
+ this.target._left = 0;
3831
+ }
3832
+ if (targetHeight < height) {
3833
+ this.target._top = 0;
3834
+ }
3835
+ this.scroll();
3836
+ }
3837
+ });
3838
+ constructor(options) {
3839
+ this.container = options.container;
3840
+ this.target = options.target;
3841
+ this.zoom = options.zoom;
3842
+ globalThis.addEventListener("keydown", this.keydownHandler);
3843
+ globalThis.addEventListener("keyup", this.keyupHandler);
3844
+ this.container.addEventListener("mouseenter", this.mouseEnterHandler);
3845
+ this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
3846
+ this.target.addEventListener("mouseenter", this.targetMouseEnterHandler);
3847
+ this.target.addEventListener("mouseleave", this.targetMouseLeaveHandler);
3848
+ this.container.addEventListener("wheel", this.wheelHandler);
3849
+ this.resizeObserver.observe(this.container);
3850
+ }
3851
+ destroy() {
3852
+ this.resizeObserver.disconnect();
3853
+ this.container.removeEventListener("mouseenter", this.mouseEnterHandler);
3854
+ this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
3855
+ this.target.removeEventListener("mouseenter", this.targetMouseEnterHandler);
3856
+ this.target.removeEventListener("mouseleave", this.targetMouseLeaveHandler);
3857
+ globalThis.removeEventListener("keydown", this.keydownHandler);
3858
+ globalThis.removeEventListener("keyup", this.keyupHandler);
3859
+ }
3860
+ setZoom(zoom) {
3861
+ this.zoom = zoom;
3862
+ }
3863
+ scroll() {
3864
+ const scrollLeft = this.target._left;
3865
+ const scrollTop = this.target._top;
3866
+ this.target.style.transform = `translate(${scrollLeft}px, ${scrollTop}px)`;
3867
+ }
3868
+ removeHandler() {
3869
+ this.target.style.cursor = "";
3870
+ this.target.removeEventListener("mousedown", this.mousedownHandler);
3871
+ document.removeEventListener("mousemove", this.mousemoveHandler);
3872
+ document.removeEventListener("mouseup", this.mouseupHandler);
3873
+ }
3874
+ wheelHandler = (event) => {
3875
+ if (this.targetEnter)
3876
+ return;
3877
+ const { deltaX, deltaY, currentTarget } = event;
3878
+ if (currentTarget !== this.container)
3879
+ return;
3880
+ this.setScrollOffset(deltaX, deltaY);
3881
+ this.scroll();
3882
+ this.scrollLeft = this.target._left;
3883
+ this.scrollTop = this.target._top;
3884
+ };
3885
+ mouseEnterHandler = () => {
3886
+ this.enter = true;
3887
+ };
3888
+ mouseLeaveHandler = () => {
3889
+ this.enter = false;
3890
+ };
3891
+ targetMouseEnterHandler = () => {
3892
+ this.targetEnter = true;
3893
+ };
3894
+ targetMouseLeaveHandler = () => {
3895
+ this.targetEnter = false;
3896
+ };
3897
+ mousedownHandler = (event) => {
3898
+ if (!this.keydown)
3899
+ return;
3900
+ event.stopImmediatePropagation();
3901
+ event.stopPropagation();
3902
+ this.target.style.cursor = "grabbing";
3903
+ this.x = event.clientX;
3904
+ this.y = event.clientY;
3905
+ document.addEventListener("mousemove", this.mousemoveHandler);
3906
+ document.addEventListener("mouseup", this.mouseupHandler);
3907
+ };
3908
+ mouseupHandler = () => {
3909
+ this.x = 0;
3910
+ this.y = 0;
3911
+ this.scrollLeft = this.target._left;
3912
+ this.scrollTop = this.target._top;
3913
+ this.removeHandler();
3914
+ };
3915
+ mousemoveHandler = (event) => {
3916
+ event.stopImmediatePropagation();
3917
+ event.stopPropagation();
3918
+ const deltaX = event.clientX - this.x;
3919
+ const deltaY = event.clientY - this.y;
3920
+ this.setScrollOffset(deltaX, deltaY);
3921
+ this.scroll();
3922
+ };
3923
+ keydownHandler = (event) => {
3924
+ if (event.code === Keys.ESCAPE && this.enter) {
3925
+ event.preventDefault();
3926
+ event.stopImmediatePropagation();
3927
+ event.stopPropagation();
3928
+ }
3929
+ if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3930
+ return;
3931
+ }
3932
+ this.keydown = true;
3933
+ this.target.style.cursor = "grab";
3934
+ this.container.addEventListener("mousedown", this.mousedownHandler);
3935
+ };
3936
+ keyupHandler = (event) => {
3937
+ if (event.code !== Keys.ESCAPE || !this.keydown) {
3938
+ return;
3939
+ }
3940
+ event.preventDefault();
3941
+ event.stopImmediatePropagation();
3942
+ event.stopPropagation();
3943
+ this.keydown = false;
3944
+ event.preventDefault();
3945
+ this.removeHandler();
3946
+ };
3947
+ setScrollOffset(deltaX, deltaY) {
3948
+ const { width, height } = this.container.getBoundingClientRect();
3949
+ const targetRect = this.target.getBoundingClientRect();
3950
+ const targetWidth = targetRect.width * this.zoom;
3951
+ const targetHeight = targetRect.height * this.zoom;
3952
+ let y = 0;
3953
+ if (targetHeight > height) {
3954
+ if (deltaY > 0) {
3955
+ y = this.scrollTop + Math.min(targetHeight - height - this.scrollTop, deltaY);
3956
+ } else {
3957
+ y = this.scrollTop + Math.max(-(targetHeight - height + this.scrollTop), deltaY);
3958
+ }
3959
+ }
3960
+ let x = 0;
3961
+ if (targetWidth > width) {
3962
+ if (deltaX > 0) {
3963
+ x = this.scrollLeft + Math.min(targetWidth - width - this.scrollLeft, deltaX);
3964
+ } else {
3965
+ x = this.scrollLeft + Math.max(-(targetWidth - width + this.scrollLeft), deltaX);
3966
+ }
3967
+ }
3968
+ this.target._left = x;
3969
+ this.target._top = y;
3970
+ }
3971
+ }
3972
+
3973
+ const _sfc_main$4 = defineComponent({
3974
+ name: "m-editor-scroll-viewer",
3975
+ props: {
3976
+ width: Number,
3977
+ height: Number,
3978
+ zoom: {
3979
+ type: Number,
3980
+ default: 1
3981
+ }
3982
+ },
3983
+ setup(props) {
3984
+ const container = ref();
3985
+ const el = ref();
3986
+ let scrollViewer;
3987
+ onMounted(() => {
3988
+ if (!container.value || !el.value)
3989
+ return;
3990
+ scrollViewer = new ScrollViewer$1({
3991
+ container: container.value,
3992
+ target: el.value,
3993
+ zoom: props.zoom
3994
+ });
3995
+ });
3996
+ onUnmounted(() => {
3997
+ scrollViewer.destroy();
3998
+ });
3999
+ watch(() => props.zoom, () => {
4000
+ scrollViewer.setZoom(props.zoom);
4001
+ });
4002
+ return {
4003
+ container,
4004
+ el,
4005
+ style: computed(() => `
4006
+ width: ${props.width}px;
4007
+ height: ${props.height}px;
4008
+ position: absolute;
4009
+ margin-top: 30px;
4010
+ `)
4011
+ };
4012
+ }
4013
+ });
4014
+ const _hoisted_1$2 = {
4015
+ class: "m-editor-scroll-viewer-container",
4016
+ ref: "container"
4017
+ };
4018
+ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
4019
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [
4020
+ createElementVNode("div", {
4021
+ ref: "el",
4022
+ style: normalizeStyle(_ctx.style)
4023
+ }, [
4024
+ renderSlot(_ctx.$slots, "default")
4025
+ ], 4)
4026
+ ], 512);
3619
4027
  }
3620
- var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
4028
+ var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
3621
4029
 
3622
4030
  const _sfc_main$3 = defineComponent({
3623
4031
  name: "magic-editor-ui-viewer-menu",
@@ -3637,13 +4045,13 @@ const _sfc_main$3 = defineComponent({
3637
4045
  if (!parent.value || !editorService)
3638
4046
  return canCenter.value = false;
3639
4047
  const layout = await editorService.getLayout(parent.value);
3640
- canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && !["app", "page", "pop"].includes(`${node.value?.type}`);
4048
+ canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && ![NodeType.ROOT, NodeType.PAGE, "pop"].includes(`${node.value?.type}`);
3641
4049
  }, { immediate: true });
3642
4050
  return {
3643
4051
  menu,
3644
4052
  canPaste,
3645
- canDelete: computed(() => node.value?.type !== "page"),
3646
- canMoveZPos: computed(() => node.value?.type !== "page"),
4053
+ canDelete: computed(() => node.value?.type !== NodeType.PAGE),
4054
+ canMoveZPos: computed(() => node.value?.type !== NodeType.PAGE),
3647
4055
  canCenter,
3648
4056
  center() {
3649
4057
  node.value && editorService?.alignCenter(node.value);
@@ -3678,7 +4086,7 @@ const _sfc_main$3 = defineComponent({
3678
4086
  };
3679
4087
  }
3680
4088
  });
3681
- const _hoisted_1$2 = {
4089
+ const _hoisted_1$1 = {
3682
4090
  class: "magic-editor-content-menu",
3683
4091
  ref: "menu"
3684
4092
  };
@@ -3686,7 +4094,7 @@ const _hoisted_2 = /* @__PURE__ */ createElementVNode("div", { class: "separatio
3686
4094
  const _hoisted_3 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3687
4095
  const _hoisted_4 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3688
4096
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3689
- return openBlock(), createElementBlock("div", _hoisted_1$2, [
4097
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [
3690
4098
  createElementVNode("div", null, [
3691
4099
  _ctx.canCenter ? (openBlock(), createElementBlock("div", {
3692
4100
  key: 0,
@@ -3771,28 +4179,14 @@ const useMenu = () => {
3771
4179
  const _sfc_main$2 = defineComponent({
3772
4180
  name: "magic-stage",
3773
4181
  components: {
3774
- ViewerMenu
4182
+ ViewerMenu,
4183
+ ScrollViewer
3775
4184
  },
3776
4185
  props: {
3777
4186
  render: {
3778
4187
  type: Function
3779
4188
  },
3780
4189
  runtimeUrl: String,
3781
- root: {
3782
- type: Object
3783
- },
3784
- page: {
3785
- type: Object
3786
- },
3787
- node: {
3788
- type: Object
3789
- },
3790
- uiSelectMode: {
3791
- type: Boolean
3792
- },
3793
- zoom: {
3794
- type: Number
3795
- },
3796
4190
  canSelect: {
3797
4191
  type: Function,
3798
4192
  default: (el) => Boolean(el.id)
@@ -3804,14 +4198,16 @@ const _sfc_main$2 = defineComponent({
3804
4198
  })
3805
4199
  }
3806
4200
  },
3807
- emits: ["select", "update", "sort"],
3808
- setup(props, { emit }) {
4201
+ setup(props) {
3809
4202
  const services = inject("services");
4203
+ const stageWrap = ref();
3810
4204
  const stageContainer = ref();
3811
- const stageStyle = computed(() => ({
3812
- ...services?.uiService.get("stageStyle"),
3813
- transform: `scale(${props.zoom}) translate3d(0, -50%, 0)`
3814
- }));
4205
+ const stageRect = computed(() => services?.uiService.get("stageRect"));
4206
+ const uiSelectMode = computed(() => services?.uiService.get("uiSelectMode"));
4207
+ const root = computed(() => services?.editorService.get("root"));
4208
+ const page = computed(() => services?.editorService.get("page"));
4209
+ const zoom = computed(() => services?.uiService.get("zoom"));
4210
+ const node = computed(() => services?.editorService.get("node"));
3815
4211
  let stage = null;
3816
4212
  let runtime = null;
3817
4213
  watchEffect(() => {
@@ -3819,15 +4215,15 @@ const _sfc_main$2 = defineComponent({
3819
4215
  return;
3820
4216
  if (!stageContainer.value)
3821
4217
  return;
3822
- if (!(props.runtimeUrl || props.render) || !props.root)
4218
+ if (!(props.runtimeUrl || props.render) || !root.value)
3823
4219
  return;
3824
4220
  stage = new StageCore({
3825
4221
  render: props.render,
3826
4222
  runtimeUrl: props.runtimeUrl,
3827
- zoom: props.zoom,
3828
- canSelect: (el, stop) => {
4223
+ zoom: zoom.value,
4224
+ canSelect: (el, event, stop) => {
3829
4225
  const elCanSelect = props.canSelect(el);
3830
- if (props.uiSelectMode && elCanSelect) {
4226
+ if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
3831
4227
  document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
3832
4228
  return stop();
3833
4229
  }
@@ -3835,67 +4231,95 @@ const _sfc_main$2 = defineComponent({
3835
4231
  },
3836
4232
  moveableOptions: props.moveableOptions
3837
4233
  });
3838
- services?.editorService.set("stage", stage);
4234
+ services?.editorService.set("stage", markRaw(stage));
3839
4235
  stage?.mount(stageContainer.value);
3840
- stage?.on("select", (el) => emit("select", el));
4236
+ stage?.on("select", (el) => {
4237
+ services?.editorService.select(el.id);
4238
+ });
4239
+ stage?.on("highlight", (el) => {
4240
+ services?.editorService.highlight(el.id);
4241
+ });
3841
4242
  stage?.on("update", (ev) => {
3842
- emit("update", { id: ev.el.id, style: ev.style });
4243
+ services?.editorService.update({ id: ev.el.id, style: ev.style });
3843
4244
  });
3844
4245
  stage?.on("sort", (ev) => {
3845
- emit("sort", ev);
4246
+ services?.editorService.sort(ev.src, ev.dist);
3846
4247
  });
3847
4248
  stage?.on("changeGuides", () => {
3848
4249
  services?.uiService.set("showGuides", true);
3849
4250
  });
3850
- if (!props.node?.id)
4251
+ if (!node.value?.id)
3851
4252
  return;
3852
4253
  stage?.on("runtime-ready", (rt) => {
3853
4254
  runtime = rt;
3854
- props.root && runtime?.updateRootConfig(cloneDeep(toRaw(props.root)));
3855
- props.page?.id && runtime?.updatePageId?.(props.page.id);
4255
+ root.value && runtime?.updateRootConfig(cloneDeep(toRaw(root.value)));
4256
+ page.value?.id && runtime?.updatePageId?.(page.value.id);
3856
4257
  setTimeout(() => {
3857
- props.node && stage?.select(toRaw(props.node.id));
4258
+ node.value && stage?.select(toRaw(node.value.id));
3858
4259
  });
3859
4260
  });
3860
4261
  });
3861
- watch(() => props.zoom, (zoom) => {
3862
- if (!stage || !zoom)
4262
+ watch(zoom, (zoom2) => {
4263
+ if (!stage || !zoom2)
3863
4264
  return;
3864
- stage?.setZoom(zoom);
4265
+ stage.setZoom(zoom2);
3865
4266
  });
3866
- watch(() => props.root, (root) => {
3867
- if (runtime && root) {
3868
- runtime.updateRootConfig(cloneDeep(toRaw(root)));
4267
+ watch(root, (root2) => {
4268
+ if (runtime && root2) {
4269
+ runtime.updateRootConfig(cloneDeep(toRaw(root2)));
3869
4270
  }
3870
4271
  });
4272
+ const resizeObserver = new ResizeObserver((entries) => {
4273
+ for (const { contentRect } of entries) {
4274
+ services?.uiService.set("stageContainerRect", {
4275
+ width: contentRect.width,
4276
+ height: contentRect.height
4277
+ });
4278
+ }
4279
+ });
4280
+ onMounted(() => {
4281
+ stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
4282
+ });
3871
4283
  onUnmounted(() => {
3872
4284
  stage?.destroy();
4285
+ resizeObserver.disconnect();
3873
4286
  services?.editorService.set("stage", null);
3874
4287
  });
3875
4288
  return {
3876
- stageStyle,
3877
- ...useMenu(),
3878
- stageContainer
4289
+ stageWrap,
4290
+ stageContainer,
4291
+ stageRect,
4292
+ zoom,
4293
+ ...useMenu()
3879
4294
  };
3880
4295
  }
3881
4296
  });
3882
- const _hoisted_1$1 = { class: "m-editor-stage" };
3883
4297
  function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3884
4298
  const _component_viewer_menu = resolveComponent("viewer-menu");
3885
- return openBlock(), createElementBlock("div", _hoisted_1$1, [
3886
- createElementVNode("div", {
3887
- class: "m-editor-stage-container",
3888
- ref: "stageContainer",
3889
- style: normalizeStyle(_ctx.stageStyle),
3890
- onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args))
3891
- }, null, 36),
3892
- (openBlock(), createBlock(Teleport, { to: "body" }, [
3893
- createVNode(_component_viewer_menu, {
3894
- ref: "menu",
3895
- style: normalizeStyle(_ctx.menuStyle)
3896
- }, null, 8, ["style"])
3897
- ]))
3898
- ]);
4299
+ const _component_scroll_viewer = resolveComponent("scroll-viewer");
4300
+ return openBlock(), createBlock(_component_scroll_viewer, {
4301
+ class: "m-editor-stage",
4302
+ ref: "stageWrap",
4303
+ width: _ctx.stageRect?.width,
4304
+ height: _ctx.stageRect?.height,
4305
+ zoom: _ctx.zoom
4306
+ }, {
4307
+ default: withCtx(() => [
4308
+ createElementVNode("div", {
4309
+ class: "m-editor-stage-container",
4310
+ ref: "stageContainer",
4311
+ onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4312
+ style: normalizeStyle(`transform: scale(${_ctx.zoom})`)
4313
+ }, null, 36),
4314
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
4315
+ createVNode(_component_viewer_menu, {
4316
+ ref: "menu",
4317
+ style: normalizeStyle(_ctx.menuStyle)
4318
+ }, null, 8, ["style"])
4319
+ ]))
4320
+ ]),
4321
+ _: 1
4322
+ }, 8, ["width", "height", "zoom"]);
3899
4323
  }
3900
4324
  var MagicStage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2]]);
3901
4325
 
@@ -3919,28 +4343,8 @@ const _sfc_main$1 = defineComponent({
3919
4343
  },
3920
4344
  setup() {
3921
4345
  const services = inject("services");
3922
- const node = computed(() => services?.editorService.get("node"));
3923
- const stage = computed(() => services?.editorService.get("stage"));
3924
- watch([() => node.value?.id, stage], ([id, stage2]) => {
3925
- nextTick(() => {
3926
- id && stage2?.select(id);
3927
- });
3928
- });
3929
4346
  return {
3930
- uiSelectMode: computed(() => services?.uiService.get("uiSelectMode")),
3931
- root: computed(() => services?.editorService.get("root")),
3932
- page: computed(() => services?.editorService.get("page")),
3933
- zoom: computed(() => services?.uiService.get("zoom")),
3934
- node,
3935
- selectHandler(el) {
3936
- services?.editorService.select(el.id);
3937
- },
3938
- updateNodeHandler(node2) {
3939
- services?.editorService.update(node2);
3940
- },
3941
- sortNodeHandler(ev) {
3942
- services?.editorService.sort(ev.src, ev.dist);
3943
- }
4347
+ page: computed(() => services?.editorService.get("page"))
3944
4348
  };
3945
4349
  }
3946
4350
  });
@@ -3953,17 +4357,9 @@ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3953
4357
  key: _ctx.page?.id,
3954
4358
  "runtime-url": _ctx.runtimeUrl,
3955
4359
  render: _ctx.render,
3956
- "ui-select-mode": _ctx.uiSelectMode,
3957
- root: _ctx.root,
3958
- page: _ctx.page,
3959
- node: _ctx.node,
3960
- zoom: _ctx.zoom,
3961
4360
  "moveable-options": _ctx.moveableOptions,
3962
- "can-select": _ctx.canSelect,
3963
- onSelect: _ctx.selectHandler,
3964
- onUpdate: _ctx.updateNodeHandler,
3965
- onSort: _ctx.sortNodeHandler
3966
- }, null, 8, ["runtime-url", "render", "ui-select-mode", "root", "page", "node", "zoom", "moveable-options", "can-select", "onSelect", "onUpdate", "onSort"])),
4361
+ "can-select": _ctx.canSelect
4362
+ }, null, 8, ["runtime-url", "render", "moveable-options", "can-select"])),
3967
4363
  renderSlot(_ctx.$slots, "workspace-content"),
3968
4364
  createVNode(_component_page_bar, null, {
3969
4365
  "page-bar-title": withCtx(({ page }) => [
@@ -3994,15 +4390,24 @@ class ComponentList extends BaseService {
3994
4390
  }
3995
4391
  var componentListService = new ComponentList();
3996
4392
 
4393
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4394
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
3997
4395
  const state = reactive({
3998
4396
  uiSelectMode: false,
3999
4397
  showSrc: false,
4000
4398
  zoom: 1,
4001
- stageStyle: {},
4399
+ stageContainerRect: {
4400
+ width: 0,
4401
+ height: 0
4402
+ },
4403
+ stageRect: {
4404
+ width: 375,
4405
+ height: 817
4406
+ },
4002
4407
  columnWidth: {
4003
- left: 310,
4004
- center: globalThis.document.body.clientWidth - 310 - 400,
4005
- right: 400
4408
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
4409
+ center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4410
+ right: DEFAULT_RIGHT_COLUMN_WIDTH
4006
4411
  },
4007
4412
  showGuides: true,
4008
4413
  showRule: true
@@ -4022,6 +4427,10 @@ class Ui extends BaseService {
4022
4427
  this.setColumnWidth(value);
4023
4428
  return;
4024
4429
  }
4430
+ if (name === "stageRect") {
4431
+ this.setStageRect(value);
4432
+ return;
4433
+ }
4025
4434
  if (name === "showGuides") {
4026
4435
  mask?.showGuides(value);
4027
4436
  }
@@ -4029,6 +4438,9 @@ class Ui extends BaseService {
4029
4438
  mask?.showRule(value);
4030
4439
  }
4031
4440
  state[name] = value;
4441
+ if (name === "stageContainerRect") {
4442
+ state.zoom = this.calcZoom();
4443
+ }
4032
4444
  }
4033
4445
  get(name) {
4034
4446
  return state[name];
@@ -4051,6 +4463,23 @@ class Ui extends BaseService {
4051
4463
  }
4052
4464
  state.columnWidth = columnWidth;
4053
4465
  }
4466
+ setStageRect(value) {
4467
+ state.stageRect = {
4468
+ ...state.stageRect,
4469
+ ...value
4470
+ };
4471
+ state.zoom = this.calcZoom();
4472
+ }
4473
+ calcZoom() {
4474
+ const { stageRect, stageContainerRect } = state;
4475
+ const { height, width } = stageContainerRect;
4476
+ if (!width || !height)
4477
+ return 1;
4478
+ if (width > stageRect.width && height > stageRect.height) {
4479
+ return 1;
4480
+ }
4481
+ return Math.min((width - 100) / stageRect.width || 1, (height - 100) / stageRect.height || 1);
4482
+ }
4054
4483
  }
4055
4484
  var uiService = new Ui();
4056
4485
 
@@ -4105,7 +4534,7 @@ const _sfc_main = defineComponent({
4105
4534
  canSelect: {
4106
4535
  type: Function
4107
4536
  },
4108
- stageStyle: {
4537
+ stageRect: {
4109
4538
  type: [String, Object]
4110
4539
  }
4111
4540
  },
@@ -4143,7 +4572,7 @@ const _sfc_main = defineComponent({
4143
4572
  watch(() => props.defaultSelected, (defaultSelected) => defaultSelected && editorService.select(defaultSelected), {
4144
4573
  immediate: true
4145
4574
  });
4146
- watch(() => props.stageStyle, (stageStyle) => uiService.set("stageStyle", stageStyle), {
4575
+ watch(() => props.stageRect, (stageRect) => stageRect && uiService.set("stageRect", stageRect), {
4147
4576
  immediate: true
4148
4577
  });
4149
4578
  onUnmounted(() => editorService.destroy());
@@ -4229,5 +4658,5 @@ var index = {
4229
4658
  }
4230
4659
  };
4231
4660
 
4232
- export { COPY_STORAGE_KEY, ComponentListPanel, DEFAULT_CONFIG, Fixed2Other, LayerOffset, LayerPanel, Layout, PropsPanel, CodeEditor as TMagicCodeEditor, Editor as TMagicEditor, change2Fixed, debug, index as default, defaults, editorService, error, eventsService, fillConfig, generateId, generatePageName, generatePageNameByApp, getConfig, getDefaultPropsValue, getNodeIndex, getPageList, getPageNameList, historyService, info, initPosition, isFixed, log, propsService, setConfig, setLayout, setNewItemId, toRelative, uiService, warn };
4661
+ export { COPY_STORAGE_KEY, ComponentListPanel, DEFAULT_CONFIG, Fixed2Other, Keys, LayerOffset, LayerPanel, Layout, PropsPanel, CodeEditor as TMagicCodeEditor, Editor as TMagicEditor, change2Fixed, debug, index as default, editorService, error, eventsService, fillConfig, generateId, generatePageName, generatePageNameByApp, getConfig, getDefaultPropsValue, getNodeIndex, getPageList, getPageNameList, historyService, info, initPosition, isFixed, log, propsService, setConfig, setLayout, setNewItemId, toRelative, uiService, warn };
4233
4662
  //# sourceMappingURL=tmagic-editor.es.js.map