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

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 (53) hide show
  1. package/LICENSE +5432 -0
  2. package/README.md +1 -0
  3. package/dist/style.css +53 -24
  4. package/dist/tmagic-editor.es.js +901 -412
  5. package/dist/tmagic-editor.es.js.map +1 -1
  6. package/dist/tmagic-editor.umd.js +918 -412
  7. package/dist/tmagic-editor.umd.js.map +1 -1
  8. package/dist/types/src/Editor.vue.d.ts +5 -5
  9. package/dist/types/src/components/ScrollViewer.vue.d.ts +23 -0
  10. package/dist/types/src/layouts/CodeEditor.vue.d.ts +5 -4
  11. package/dist/types/src/layouts/NavMenu.vue.d.ts +2 -1
  12. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
  13. package/dist/types/src/layouts/sidebar/LayerPanel.vue.d.ts +10 -3
  14. package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +8 -3
  15. package/dist/types/src/layouts/workspace/Stage.vue.d.ts +77 -42
  16. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +4 -10
  17. package/dist/types/src/services/BaseService.d.ts +4 -1
  18. package/dist/types/src/services/editor.d.ts +11 -4
  19. package/dist/types/src/services/props.d.ts +1 -1
  20. package/dist/types/src/services/ui.d.ts +10 -3
  21. package/dist/types/src/type.d.ts +23 -7
  22. package/dist/types/src/utils/editor.d.ts +3 -3
  23. package/dist/types/src/utils/scroll-viewer.d.ts +35 -0
  24. package/package.json +25 -12
  25. package/src/Editor.vue +5 -5
  26. package/src/components/ScrollViewer.vue +66 -0
  27. package/src/components/ToolButton.vue +5 -3
  28. package/src/layouts/AddPageBox.vue +3 -1
  29. package/src/layouts/CodeEditor.vue +35 -59
  30. package/src/layouts/NavMenu.vue +7 -3
  31. package/src/layouts/PropsPanel.vue +6 -10
  32. package/src/layouts/sidebar/ComponentListPanel.vue +2 -2
  33. package/src/layouts/sidebar/LayerMenu.vue +15 -39
  34. package/src/layouts/sidebar/LayerPanel.vue +63 -16
  35. package/src/layouts/workspace/PageBar.vue +113 -14
  36. package/src/layouts/workspace/Stage.vue +67 -61
  37. package/src/layouts/workspace/ViewerMenu.vue +5 -3
  38. package/src/layouts/workspace/Workspace.vue +45 -34
  39. package/src/services/BaseService.ts +70 -22
  40. package/src/services/editor.ts +111 -55
  41. package/src/services/props.ts +2 -1
  42. package/src/services/ui.ts +42 -5
  43. package/src/theme/common/var.scss +2 -2
  44. package/src/theme/layer-panel.scss +9 -0
  45. package/src/theme/nav-menu.scss +3 -3
  46. package/src/theme/page-bar.scss +21 -2
  47. package/src/theme/props-panel.scss +8 -0
  48. package/src/theme/stage.scss +8 -7
  49. package/src/type.ts +26 -7
  50. package/src/utils/editor.ts +30 -27
  51. package/src/utils/props.ts +1 -1
  52. package/src/utils/scroll-viewer.ts +216 -0
  53. package/dist/types/src/layouts/sidebar/LayerMenu.vue.d.ts +0 -31
@@ -1,11 +1,14 @@
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, isNumber, isPage } 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';
11
+ import KeyController from 'keycon';
9
12
  import StageCore from '@tmagic/stage';
10
13
 
11
14
  var _export_sfc = (sfc, props) => {
@@ -16,7 +19,7 @@ var _export_sfc = (sfc, props) => {
16
19
  return target;
17
20
  };
18
21
 
19
- const _sfc_main$j = defineComponent({
22
+ const _sfc_main$k = defineComponent({
20
23
  name: "m-fields-vs-code",
21
24
  props: ["model", "name", "config", "prop"],
22
25
  emits: ["change"],
@@ -33,7 +36,7 @@ const _sfc_main$j = defineComponent({
33
36
  };
34
37
  }
35
38
  });
36
- function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
39
+ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
37
40
  const _component_magic_code_editor = resolveComponent("magic-code-editor");
38
41
  return openBlock(), createBlock(_component_magic_code_editor, {
39
42
  style: normalizeStyle(`height: ${_ctx.height}`),
@@ -42,9 +45,9 @@ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
42
45
  onSave: _ctx.save
43
46
  }, null, 8, ["style", "init-values", "language", "onSave"]);
44
47
  }
45
- var Code = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
48
+ var Code = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
46
49
 
47
- const _sfc_main$i = defineComponent({
50
+ const _sfc_main$j = defineComponent({
48
51
  name: "m-fields-code-link",
49
52
  props: {
50
53
  config: {
@@ -99,7 +102,7 @@ const _sfc_main$i = defineComponent({
99
102
  };
100
103
  }
101
104
  });
102
- function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
105
+ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
103
106
  const _component_m_fields_link = resolveComponent("m-fields-link");
104
107
  return openBlock(), createBlock(_component_m_fields_link, {
105
108
  config: _ctx.formConfig,
@@ -108,11 +111,11 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
108
111
  onChange: _ctx.changeHandler
109
112
  }, null, 8, ["config", "model", "onChange"]);
110
113
  }
111
- var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
114
+ var CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
112
115
 
113
116
  var UISelect_vue_vue_type_style_index_0_lang = '';
114
117
 
115
- const _sfc_main$h = defineComponent({
118
+ const _sfc_main$i = defineComponent({
116
119
  name: "m-fields-ui-select",
117
120
  props: {
118
121
  labelWidth: String,
@@ -174,15 +177,15 @@ const _sfc_main$h = defineComponent({
174
177
  };
175
178
  }
176
179
  });
177
- const _hoisted_1$d = /* @__PURE__ */ createElementVNode("i", {
180
+ const _hoisted_1$e = /* @__PURE__ */ createElementVNode("i", {
178
181
  class: "el-icon-delete",
179
182
  style: { "color": "rgb(221, 75, 57)" }
180
183
  }, "\u53D6\u6D88", -1);
181
184
  const _hoisted_2$7 = [
182
- _hoisted_1$d
185
+ _hoisted_1$e
183
186
  ];
184
187
  const _hoisted_3$5 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-thumb" }, null, -1);
185
- function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
188
+ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
186
189
  return _ctx.uiSelectMode ? (openBlock(), createElementBlock("div", {
187
190
  key: 0,
188
191
  class: "m-fields-ui-select",
@@ -201,23 +204,8 @@ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
201
204
  })) : createCommentVNode("", true)
202
205
  ]));
203
206
  }
204
- var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
207
+ var uiSelect = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
205
208
 
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
209
  const toString = (v, language) => {
222
210
  let value = "";
223
211
  if (typeof v !== "string") {
@@ -233,7 +221,7 @@ const toString = (v, language) => {
233
221
  }
234
222
  return value;
235
223
  };
236
- const _sfc_main$g = defineComponent({
224
+ const _sfc_main$h = defineComponent({
237
225
  name: "magic-code-editor",
238
226
  props: {
239
227
  initValues: {
@@ -251,32 +239,34 @@ const _sfc_main$g = defineComponent({
251
239
  default: () => "javascript"
252
240
  }
253
241
  },
254
- emits: ["inited", "save"],
242
+ emits: ["initd", "save"],
255
243
  setup(props, { emit }) {
256
244
  let vsEditor = null;
245
+ let vsDiffEditor = null;
257
246
  const values = ref("");
258
247
  const loading = ref(false);
259
248
  const codeEditor = ref();
260
249
  const setEditorValue = (v, m) => {
261
250
  values.value = toString(v, props.language);
262
251
  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({
252
+ const originalModel = monaco.editor.createModel(values.value, "text/javascript");
253
+ const modifiedModel = monaco.editor.createModel(toString(m, props.language), "text/javascript");
254
+ return vsDiffEditor?.setModel({
266
255
  original: originalModel,
267
256
  modified: modifiedModel
268
257
  });
269
258
  }
270
- return vsEditor.setValue?.(values.value);
259
+ return vsEditor?.setValue(values.value);
271
260
  };
272
261
  const resizeHandler = () => {
273
262
  vsEditor?.layout();
263
+ vsDiffEditor?.layout();
274
264
  };
275
- const getEditorValue = () => vsEditor.getValue?.() || "";
265
+ const getEditorValue = () => props.type === "diff" ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
276
266
  const init = async () => {
277
267
  if (!codeEditor.value)
278
268
  return;
279
- vsEditor = globalThis.monaco.editor[props.type === "diff" ? "createDiffEditor" : "create"](codeEditor.value, {
269
+ const options = {
280
270
  value: values.value,
281
271
  language: props.language,
282
272
  tabSize: 2,
@@ -284,10 +274,15 @@ const _sfc_main$g = defineComponent({
284
274
  fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
285
275
  fontSize: 15,
286
276
  formatOnPaste: true
287
- });
277
+ };
278
+ if (props.type === "diff") {
279
+ vsDiffEditor = monaco.editor.createDiffEditor(codeEditor.value, options);
280
+ } else {
281
+ vsEditor = monaco.editor.create(codeEditor.value, options);
282
+ }
288
283
  setEditorValue(props.initValues, props.modifiedValues);
289
284
  loading.value = false;
290
- emit("inited", vsEditor);
285
+ emit("initd", vsEditor);
291
286
  codeEditor.value.addEventListener("keydown", (e) => {
292
287
  if (e.keyCode === 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
293
288
  e.preventDefault();
@@ -295,14 +290,14 @@ const _sfc_main$g = defineComponent({
295
290
  }
296
291
  });
297
292
  if (props.type !== "diff") {
298
- vsEditor.onDidBlurEditorWidget(() => {
293
+ vsEditor?.onDidBlurEditorWidget(() => {
299
294
  emit("save", getEditorValue());
300
295
  });
301
296
  }
302
297
  globalThis.addEventListener("resize", resizeHandler);
303
298
  };
304
299
  watch(() => props.initValues, (v, preV) => {
305
- if (vsEditor && v !== preV) {
300
+ if (v !== preV) {
306
301
  setEditorValue(props.initValues, props.modifiedValues);
307
302
  }
308
303
  }, {
@@ -311,17 +306,7 @@ const _sfc_main$g = defineComponent({
311
306
  });
312
307
  onMounted(async () => {
313
308
  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
- }
309
+ init();
325
310
  });
326
311
  onUnmounted(() => {
327
312
  globalThis.removeEventListener("resize", resizeHandler);
@@ -331,23 +316,24 @@ const _sfc_main$g = defineComponent({
331
316
  loading,
332
317
  codeEditor,
333
318
  getEditor() {
334
- return vsEditor;
319
+ return vsEditor || vsDiffEditor;
335
320
  },
336
321
  setEditorValue,
337
322
  focus() {
338
- vsEditor.focus();
323
+ vsEditor?.focus();
324
+ vsDiffEditor?.focus();
339
325
  }
340
326
  };
341
327
  }
342
328
  });
343
- const _hoisted_1$c = {
329
+ const _hoisted_1$d = {
344
330
  ref: "codeEditor",
345
331
  class: "magic-code-editor"
346
332
  };
347
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
348
- return openBlock(), createElementBlock("div", _hoisted_1$c, null, 512);
333
+ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
334
+ return openBlock(), createElementBlock("div", _hoisted_1$d, null, 512);
349
335
  }
350
- var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
336
+ var CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
351
337
 
352
338
  let $TMAGIC_EDITOR = {};
353
339
  const setConfig = (option) => {
@@ -431,10 +417,39 @@ const compose = (middleware) => {
431
417
 
432
418
  const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
433
419
  const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
420
+ const doAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
421
+ try {
422
+ let beforeArgs = args;
423
+ for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
424
+ let beforeReturnValue = await beforeMethod(...beforeArgs) || [];
425
+ if (isError(beforeReturnValue))
426
+ throw beforeReturnValue;
427
+ if (!Array.isArray(beforeReturnValue)) {
428
+ beforeReturnValue = [beforeReturnValue];
429
+ }
430
+ beforeArgs = beforeArgs.map((v, index) => {
431
+ if (typeof beforeReturnValue[index] === "undefined")
432
+ return v;
433
+ return beforeReturnValue[index];
434
+ });
435
+ }
436
+ let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
437
+ for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
438
+ returnValue = await afterMethod(...beforeArgs, returnValue);
439
+ if (isError(returnValue))
440
+ throw returnValue;
441
+ }
442
+ return returnValue;
443
+ } catch (error) {
444
+ throw error;
445
+ }
446
+ };
434
447
  class BaseService extends EventEmitter$2 {
435
448
  pluginOptionsList = {};
436
449
  middleware = {};
437
- constructor(methods) {
450
+ taskList = [];
451
+ doingTask = false;
452
+ constructor(methods = [], serialMethods = []) {
438
453
  super();
439
454
  methods.forEach((propertyName) => {
440
455
  const scope = this;
@@ -447,27 +462,23 @@ class BaseService extends EventEmitter$2 {
447
462
  const fn = compose(this.middleware[propertyName]);
448
463
  Object.defineProperty(scope, propertyName, {
449
464
  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
- });
465
+ if (!serialMethods.includes(propertyName)) {
466
+ return doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
463
467
  }
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;
468
+ const promise = new Promise((resolve, reject) => {
469
+ this.taskList.push(async () => {
470
+ try {
471
+ const value = await doAction(args, scope, sourceMethod, beforeMethodName, afterMethodName, fn);
472
+ resolve(value);
473
+ } catch (e) {
474
+ reject(e);
475
+ }
476
+ });
477
+ });
478
+ if (!this.doingTask) {
479
+ this.doTask();
469
480
  }
470
- return returnValue;
481
+ return promise;
471
482
  }
472
483
  });
473
484
  });
@@ -484,6 +495,15 @@ class BaseService extends EventEmitter$2 {
484
495
  this.pluginOptionsList[methodName2].push(method);
485
496
  });
486
497
  }
498
+ async doTask() {
499
+ this.doingTask = true;
500
+ let task = this.taskList.shift();
501
+ while (task) {
502
+ await task();
503
+ task = this.taskList.shift();
504
+ }
505
+ this.doingTask = false;
506
+ }
487
507
  }
488
508
 
489
509
  class History extends BaseService {
@@ -590,7 +610,7 @@ class Props extends BaseService {
590
610
  setPropsValue(type, value) {
591
611
  this.state.propsValueMap[type] = value;
592
612
  }
593
- async getPropsValue(type) {
613
+ async getPropsValue(type, defaultValue = {}) {
594
614
  if (type === "area") {
595
615
  const value = await this.getPropsValue("button");
596
616
  value.className = "action-area";
@@ -602,6 +622,7 @@ class Props extends BaseService {
602
622
  }
603
623
  return cloneDeep({
604
624
  ...getDefaultPropsValue(type),
625
+ ...defaultValue,
605
626
  ...this.state.propsValueMap[type] || {}
606
627
  });
607
628
  }
@@ -620,12 +641,16 @@ var Layout = /* @__PURE__ */ ((Layout2) => {
620
641
  Layout2["ABSOLUTE"] = "absolute";
621
642
  return Layout2;
622
643
  })(Layout || {});
644
+ var Keys = /* @__PURE__ */ ((Keys2) => {
645
+ Keys2["ESCAPE"] = "Space";
646
+ return Keys2;
647
+ })(Keys || {});
623
648
 
624
649
  const COPY_STORAGE_KEY = "$MagicEditorCopyData";
625
650
  const generateId = (type) => `${type}_${random(1e4, false)}`;
626
651
  const getPageList = (app) => {
627
652
  if (app.items && Array.isArray(app.items)) {
628
- return app.items.filter((item) => item.type === "page");
653
+ return app.items.filter((item) => item.type === NodeType.PAGE);
629
654
  }
630
655
  return [];
631
656
  };
@@ -659,9 +684,9 @@ const updatePopId = (oldId, popId, pageConfig) => {
659
684
  };
660
685
  const setNewItemId = (config, parent) => {
661
686
  const oldId = config.id;
662
- config.id = generateId(config.type);
687
+ config.id = generateId(config.type || "component");
663
688
  config.name = `${config.name?.replace(/_(\d+)$/, "")}_${config.id}`;
664
- if (isPop(config) && parent?.type === "page") {
689
+ if (isPop(config) && parent?.type === NodeType.PAGE) {
665
690
  updatePopId(oldId, config.id, parent);
666
691
  }
667
692
  if (config.items && Array.isArray(config.items)) {
@@ -682,11 +707,25 @@ const toRelative = (node) => {
682
707
  };
683
708
  return node;
684
709
  };
685
- const initPosition = (node, layout) => {
710
+ const setTop2Middle = (node, parentNode, stage) => {
711
+ const style = node.style || {};
712
+ const height = style.height || 0;
713
+ if (!stage || style.top || !parentNode.style || !isNumber(height))
714
+ return style;
715
+ const { height: parentHeight } = parentNode.style;
716
+ if (isPage(parentNode)) {
717
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
718
+ style.top = (wrapperHeight - height) / 2 + scrollTop;
719
+ } else {
720
+ style.top = (parentHeight - height) / 2;
721
+ }
722
+ return style;
723
+ };
724
+ const initPosition = (node, layout, parentNode, stage) => {
686
725
  if (layout === Layout.ABSOLUTE) {
687
726
  node.style = {
688
727
  position: "absolute",
689
- ...node.style || {}
728
+ ...setTop2Middle(node, parentNode, stage)
690
729
  };
691
730
  return node;
692
731
  }
@@ -733,7 +772,9 @@ const Fixed2Other = async (node, root, getLayout) => {
733
772
  const cur = path.pop();
734
773
  const offset = {
735
774
  left: cur?.style?.left || 0,
736
- top: cur?.style?.top || 0
775
+ top: cur?.style?.top || 0,
776
+ right: "",
777
+ bottom: ""
737
778
  };
738
779
  path.forEach((value) => {
739
780
  offset.left = offset.left - globalThis.parseFloat(value.style?.left || 0);
@@ -754,22 +795,6 @@ const Fixed2Other = async (node, root, getLayout) => {
754
795
  }
755
796
  return toRelative(node);
756
797
  };
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
798
 
774
799
  const log = (...args) => {
775
800
  };
@@ -790,6 +815,7 @@ class Editor$1 extends BaseService {
790
815
  parent: null,
791
816
  node: null,
792
817
  stage: null,
818
+ highlightNode: null,
793
819
  modifiedNodeIds: /* @__PURE__ */ new Map()
794
820
  });
795
821
  constructor() {
@@ -805,8 +831,9 @@ class Editor$1 extends BaseService {
805
831
  "alignCenter",
806
832
  "moveLayer",
807
833
  "undo",
808
- "redo"
809
- ]);
834
+ "redo",
835
+ "highlight"
836
+ ], ["select", "update", "moveLayer"]);
810
837
  }
811
838
  set(name, value) {
812
839
  this.state[name] = value;
@@ -832,7 +859,7 @@ class Editor$1 extends BaseService {
832
859
  info.node = path[path.length - 1];
833
860
  info.parent = path[path.length - 2];
834
861
  path.forEach((item) => {
835
- if (item.type === "page") {
862
+ if (item.type === NodeType.PAGE) {
836
863
  info.page = item;
837
864
  return;
838
865
  }
@@ -859,18 +886,7 @@ class Editor$1 extends BaseService {
859
886
  return Layout.ABSOLUTE;
860
887
  }
861
888
  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");
889
+ const { node, page, parent } = this.selectedConfigExceptionHandler(config2);
874
890
  this.set("node", node);
875
891
  this.set("page", page || null);
876
892
  this.set("parent", parent || null);
@@ -881,10 +897,17 @@ class Editor$1 extends BaseService {
881
897
  }
882
898
  return node;
883
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
+ }
884
907
  async add({ type, ...config2 }, parent) {
885
908
  const curNode = this.get("node");
886
909
  let parentNode;
887
- if (type === "page") {
910
+ if (type === NodeType.PAGE) {
888
911
  parentNode = this.get("root");
889
912
  } else if (parent && typeof parent !== "function") {
890
913
  parentNode = parent;
@@ -896,15 +919,19 @@ class Editor$1 extends BaseService {
896
919
  if (!parentNode)
897
920
  throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
898
921
  const layout = await this.getLayout(parentNode);
899
- const newNode = initPosition({ ...toRaw(await propsService.getPropsValue(type)), ...config2 }, layout);
900
- if ((parentNode?.type === "app" || curNode.type === "app") && newNode.type !== "page") {
922
+ const newNode = initPosition({ ...toRaw(await propsService.getPropsValue(type, config2)) }, layout, parentNode, this.get("stage"));
923
+ if ((parentNode?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && newNode.type !== NodeType.PAGE) {
901
924
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
902
925
  }
903
926
  parentNode?.items?.push(newNode);
904
- await this.get("stage")?.add({ config: cloneDeep(newNode), root: cloneDeep(this.get("root")) });
927
+ const stage = this.get("stage");
928
+ await stage?.add({ config: cloneDeep(newNode), root: cloneDeep(this.get("root")) });
905
929
  await this.select(newNode);
906
930
  this.addModifiedNodeId(newNode.id);
907
- this.pushHistoryState();
931
+ if (type !== NodeType.PAGE) {
932
+ this.pushHistoryState();
933
+ }
934
+ stage?.select(newNode.id);
908
935
  return newNode;
909
936
  }
910
937
  async remove(node) {
@@ -920,11 +947,16 @@ class Editor$1 extends BaseService {
920
947
  if (typeof index !== "number" || index === -1)
921
948
  throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
922
949
  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);
950
+ const stage = this.get("stage");
951
+ stage?.remove({ id: node.id, root: this.get("root") });
952
+ if (node.type === NodeType.PAGE) {
953
+ if (root.items[0]) {
954
+ await this.select(root.items[0]);
955
+ stage?.select(root.items[0].id);
956
+ }
926
957
  } else {
927
958
  await this.select(parent);
959
+ stage?.select(parent.id);
928
960
  }
929
961
  this.addModifiedNodeId(parent.id);
930
962
  this.pushHistoryState();
@@ -937,17 +969,21 @@ class Editor$1 extends BaseService {
937
969
  if (!info.node)
938
970
  throw new Error(`\u83B7\u53D6\u4E0D\u5230id\u4E3A${config2.id}\u7684\u8282\u70B9`);
939
971
  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
972
  let newConfig = await this.toggleFixedPosition(toRaw(config2), node, this.get("root"));
944
- defaults(newConfig, node);
973
+ newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => {
974
+ if (Array.isArray(srcValue)) {
975
+ return srcValue;
976
+ }
977
+ });
945
978
  if (!newConfig.type)
946
979
  throw new Error("\u914D\u7F6E\u7F3A\u5C11type\u503C");
947
- if (newConfig.type === "app") {
980
+ if (newConfig.type === NodeType.ROOT) {
948
981
  this.set("root", newConfig);
949
982
  return newConfig;
950
983
  }
984
+ const { parent } = info;
985
+ if (!parent)
986
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7236\u7EA7\u8282\u70B9");
951
987
  const parentNodeItems = parent.items;
952
988
  const index = getNodeIndex(newConfig, parent);
953
989
  if (!parentNodeItems || typeof index === "undefined" || index === -1)
@@ -958,11 +994,11 @@ class Editor$1 extends BaseService {
958
994
  newConfig = setLayout(newConfig, newLayout);
959
995
  }
960
996
  parentNodeItems[index] = newConfig;
961
- if (newConfig.id === this.get("node").id) {
997
+ if (`${newConfig.id}` === `${this.get("node").id}`) {
962
998
  this.set("node", newConfig);
963
999
  }
964
1000
  this.get("stage")?.update({ config: cloneDeep(newConfig), root: this.get("root") });
965
- if (newConfig.type === "page") {
1001
+ if (newConfig.type === NodeType.PAGE) {
966
1002
  this.set("page", newConfig);
967
1003
  }
968
1004
  this.addModifiedNodeId(newConfig.id);
@@ -979,6 +1015,7 @@ class Editor$1 extends BaseService {
979
1015
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
980
1016
  await this.update(parent);
981
1017
  await this.select(node);
1018
+ this.get("stage")?.update({ config: cloneDeep(node), root: this.get("root") });
982
1019
  this.addModifiedNodeId(parent.id);
983
1020
  this.pushHistoryState();
984
1021
  }
@@ -1078,7 +1115,12 @@ class Editor$1 extends BaseService {
1078
1115
  this.isHistoryStateChange = true;
1079
1116
  await this.update(value.data);
1080
1117
  this.set("modifiedNodeIds", value.modifiedNodeIds);
1081
- setTimeout(() => value.nodeId && this.select(value.nodeId), 0);
1118
+ setTimeout(async () => {
1119
+ if (!value.nodeId)
1120
+ return;
1121
+ await this.select(value.nodeId);
1122
+ this.get("stage")?.select(value.nodeId);
1123
+ }, 0);
1082
1124
  }
1083
1125
  async toggleFixedPosition(dist, src, root) {
1084
1126
  let newConfig = cloneDeep(dist);
@@ -1091,6 +1133,28 @@ class Editor$1 extends BaseService {
1091
1133
  }
1092
1134
  return newConfig;
1093
1135
  }
1136
+ selectedConfigExceptionHandler(config2) {
1137
+ let id;
1138
+ if (typeof config2 === "string" || typeof config2 === "number") {
1139
+ id = config2;
1140
+ } else {
1141
+ id = config2.id;
1142
+ }
1143
+ if (!id) {
1144
+ throw new Error("\u6CA1\u6709ID\uFF0C\u65E0\u6CD5\u9009\u4E2D");
1145
+ }
1146
+ const { node, parent, page } = this.getNodeInfo(id);
1147
+ if (!node)
1148
+ throw new Error("\u83B7\u53D6\u4E0D\u5230\u7EC4\u4EF6\u4FE1\u606F");
1149
+ if (node.id === this.state.root?.id) {
1150
+ throw new Error("\u4E0D\u80FD\u9009\u6839\u8282\u70B9");
1151
+ }
1152
+ return {
1153
+ node,
1154
+ parent,
1155
+ page
1156
+ };
1157
+ }
1094
1158
  }
1095
1159
  var editorService = new Editor$1();
1096
1160
 
@@ -1280,7 +1344,7 @@ const fillConfig = (config = []) => [
1280
1344
  type: "select",
1281
1345
  options: (mForm, { model }) => {
1282
1346
  const node = editorService.getNodeById(model.to);
1283
- if (!node)
1347
+ if (!node?.type)
1284
1348
  return [];
1285
1349
  return eventsService.getMethod(node.type).map((option) => ({
1286
1350
  text: option.label,
@@ -1315,7 +1379,7 @@ const getDefaultPropsValue = (type) => ({
1315
1379
  name: type
1316
1380
  });
1317
1381
 
1318
- const _sfc_main$f = defineComponent({
1382
+ const _sfc_main$g = defineComponent({
1319
1383
  components: { Plus },
1320
1384
  setup() {
1321
1385
  const services = inject("services");
@@ -1325,20 +1389,20 @@ const _sfc_main$f = defineComponent({
1325
1389
  if (!editorService)
1326
1390
  return;
1327
1391
  editorService.add({
1328
- type: "page",
1392
+ type: NodeType.PAGE,
1329
1393
  name: generatePageNameByApp(toRaw(editorService.get("root")))
1330
1394
  });
1331
1395
  }
1332
1396
  };
1333
1397
  }
1334
1398
  });
1335
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
1399
+ const _hoisted_1$c = { class: "m-editor-empty-panel" };
1336
1400
  const _hoisted_2$6 = { class: "m-editor-empty-content" };
1337
1401
  const _hoisted_3$4 = /* @__PURE__ */ createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1338
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
1402
+ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
1339
1403
  const _component_plus = resolveComponent("plus");
1340
1404
  const _component_el_icon = resolveComponent("el-icon");
1341
- return openBlock(), createElementBlock("div", _hoisted_1$b, [
1405
+ return openBlock(), createElementBlock("div", _hoisted_1$c, [
1342
1406
  createElementVNode("div", _hoisted_2$6, [
1343
1407
  createElementVNode("div", {
1344
1408
  class: "m-editor-empty-button",
@@ -1357,7 +1421,7 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
1357
1421
  ])
1358
1422
  ]);
1359
1423
  }
1360
- var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
1424
+ var AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
1361
1425
 
1362
1426
  /*
1363
1427
  Copyright (c) 2018 Daybrush
@@ -2526,7 +2590,7 @@ function (_super) {
2526
2590
 
2527
2591
  var Gesto$1 = Gesto;
2528
2592
 
2529
- const _sfc_main$e = defineComponent({
2593
+ const _sfc_main$f = defineComponent({
2530
2594
  name: "m-editor-resize",
2531
2595
  props: {
2532
2596
  type: {
@@ -2568,18 +2632,18 @@ const _sfc_main$e = defineComponent({
2568
2632
  };
2569
2633
  }
2570
2634
  });
2571
- const _hoisted_1$a = {
2635
+ const _hoisted_1$b = {
2572
2636
  ref: "target",
2573
2637
  class: "m-editor-resizer"
2574
2638
  };
2575
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2576
- return openBlock(), createElementBlock("span", _hoisted_1$a, [
2639
+ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
2640
+ return openBlock(), createElementBlock("span", _hoisted_1$b, [
2577
2641
  renderSlot(_ctx.$slots, "default")
2578
2642
  ], 512);
2579
2643
  }
2580
- var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2644
+ var Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
2581
2645
 
2582
- const _sfc_main$d = defineComponent({
2646
+ const _sfc_main$e = defineComponent({
2583
2647
  components: {
2584
2648
  AddPageBox,
2585
2649
  Resizer
@@ -2602,17 +2666,17 @@ const _sfc_main$d = defineComponent({
2602
2666
  };
2603
2667
  }
2604
2668
  });
2605
- const _hoisted_1$9 = { class: "m-editor" };
2669
+ const _hoisted_1$a = { class: "m-editor" };
2606
2670
  const _hoisted_2$5 = {
2607
2671
  key: 1,
2608
2672
  class: "m-editor-content"
2609
2673
  };
2610
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2674
+ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
2611
2675
  const _component_magic_code_editor = resolveComponent("magic-code-editor");
2612
2676
  const _component_resizer = resolveComponent("resizer");
2613
2677
  const _component_el_scrollbar = resolveComponent("el-scrollbar");
2614
2678
  const _component_add_page_box = resolveComponent("add-page-box");
2615
- return openBlock(), createElementBlock("div", _hoisted_1$9, [
2679
+ return openBlock(), createElementBlock("div", _hoisted_1$a, [
2616
2680
  renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
2617
2681
  _ctx.showSrc ? (openBlock(), createBlock(_component_magic_code_editor, {
2618
2682
  key: 0,
@@ -2652,9 +2716,9 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2652
2716
  ]))
2653
2717
  ]);
2654
2718
  }
2655
- var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2719
+ var Framework = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
2656
2720
 
2657
- const _sfc_main$c = defineComponent({
2721
+ const _sfc_main$d = defineComponent({
2658
2722
  name: "m-icon",
2659
2723
  components: { Edit },
2660
2724
  props: {
@@ -2668,8 +2732,8 @@ const _sfc_main$c = defineComponent({
2668
2732
  };
2669
2733
  }
2670
2734
  });
2671
- const _hoisted_1$8 = ["src"];
2672
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2735
+ const _hoisted_1$9 = ["src"];
2736
+ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2673
2737
  const _component_edit = resolveComponent("edit");
2674
2738
  const _component_el_icon = resolveComponent("el-icon");
2675
2739
  return !_ctx.icon ? (openBlock(), createBlock(_component_el_icon, { key: 0 }, {
@@ -2680,7 +2744,7 @@ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2680
2744
  })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (openBlock(), createElementBlock("img", {
2681
2745
  key: 1,
2682
2746
  src: _ctx.icon
2683
- }, null, 8, _hoisted_1$8)) : typeof _ctx.icon === "string" ? (openBlock(), createElementBlock("i", {
2747
+ }, null, 8, _hoisted_1$9)) : typeof _ctx.icon === "string" ? (openBlock(), createElementBlock("i", {
2684
2748
  key: 2,
2685
2749
  class: normalizeClass(_ctx.icon)
2686
2750
  }, null, 2)) : (openBlock(), createBlock(_component_el_icon, { key: 3 }, {
@@ -2690,9 +2754,9 @@ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2690
2754
  _: 1
2691
2755
  }));
2692
2756
  }
2693
- var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
2757
+ var MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
2694
2758
 
2695
- const _sfc_main$b = defineComponent({
2759
+ const _sfc_main$c = defineComponent({
2696
2760
  components: { MIcon, ArrowDown },
2697
2761
  props: {
2698
2762
  data: {
@@ -2730,7 +2794,7 @@ const _sfc_main$b = defineComponent({
2730
2794
  type: "button",
2731
2795
  icon: Delete,
2732
2796
  tooltip: "\u522A\u9664",
2733
- disabled: () => services?.editorService.get("node")?.type === "page",
2797
+ disabled: () => services?.editorService.get("node")?.type === NodeType.PAGE,
2734
2798
  handler: () => services?.editorService.remove(services?.editorService.get("node"))
2735
2799
  };
2736
2800
  case "undo":
@@ -2827,7 +2891,7 @@ const _sfc_main$b = defineComponent({
2827
2891
  };
2828
2892
  }
2829
2893
  });
2830
- const _hoisted_1$7 = {
2894
+ const _hoisted_1$8 = {
2831
2895
  key: 0,
2832
2896
  class: "menu-item"
2833
2897
  };
@@ -2839,8 +2903,8 @@ const _hoisted_3$3 = {
2839
2903
  class: "menu-item-text",
2840
2904
  style: { "margin": "0 5px" }
2841
2905
  };
2842
- const _hoisted_4$3 = { class: "el-dropdown-link menubar-menu-button" };
2843
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2906
+ const _hoisted_4$2 = { class: "el-dropdown-link menubar-menu-button" };
2907
+ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
2844
2908
  const _component_el_divider = resolveComponent("el-divider");
2845
2909
  const _component_m_icon = resolveComponent("m-icon");
2846
2910
  const _component_el_button = resolveComponent("el-button");
@@ -2850,20 +2914,36 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2850
2914
  const _component_el_dropdown_item = resolveComponent("el-dropdown-item");
2851
2915
  const _component_el_dropdown_menu = resolveComponent("el-dropdown-menu");
2852
2916
  const _component_el_dropdown = resolveComponent("el-dropdown");
2853
- return _ctx.display ? (openBlock(), createElementBlock("div", _hoisted_1$7, [
2917
+ return _ctx.display ? (openBlock(), createElementBlock("div", _hoisted_1$8, [
2854
2918
  _ctx.item.type === "divider" ? (openBlock(), createBlock(_component_el_divider, {
2855
2919
  key: 0,
2856
2920
  direction: "vertical"
2857
2921
  })) : _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"]),
2922
+ createVNode(_component_el_button, {
2923
+ size: "small",
2924
+ type: "text"
2925
+ }, {
2926
+ default: withCtx(() => [
2927
+ createVNode(_component_m_icon, {
2928
+ icon: _ctx.ZoomIn,
2929
+ onClick: _ctx.zoomInHandler
2930
+ }, null, 8, ["icon", "onClick"])
2931
+ ]),
2932
+ _: 1
2933
+ }),
2862
2934
  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"])
2935
+ createVNode(_component_el_button, {
2936
+ size: "small",
2937
+ type: "text"
2938
+ }, {
2939
+ default: withCtx(() => [
2940
+ createVNode(_component_m_icon, {
2941
+ icon: _ctx.ZoomOut,
2942
+ onClick: _ctx.zoomOutHandler
2943
+ }, null, 8, ["icon", "onClick"])
2944
+ ]),
2945
+ _: 1
2946
+ })
2867
2947
  ], 64)) : _ctx.item.type === "button" ? (openBlock(), createBlock(_component_el_tooltip, {
2868
2948
  key: 3,
2869
2949
  effect: "dark",
@@ -2912,7 +2992,7 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2912
2992
  })) : createCommentVNode("", true)
2913
2993
  ]),
2914
2994
  default: withCtx(() => [
2915
- createElementVNode("span", _hoisted_4$3, [
2995
+ createElementVNode("span", _hoisted_4$2, [
2916
2996
  createTextVNode(toDisplayString(_ctx.item.text), 1),
2917
2997
  createVNode(_component_el_icon, { class: "el-icon--right" }, {
2918
2998
  default: withCtx(() => [
@@ -2926,9 +3006,9 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2926
3006
  }, 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
3007
  ])) : createCommentVNode("", true);
2928
3008
  }
2929
- var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
3009
+ var ToolButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
2930
3010
 
2931
- const _sfc_main$a = defineComponent({
3011
+ const _sfc_main$b = defineComponent({
2932
3012
  name: "nav-menu",
2933
3013
  components: { ToolButton },
2934
3014
  props: {
@@ -2941,12 +3021,14 @@ const _sfc_main$a = defineComponent({
2941
3021
  }
2942
3022
  },
2943
3023
  setup(props) {
3024
+ const services = inject("services");
2944
3025
  return {
2945
- keys: computed(() => Object.keys(props.data))
3026
+ keys: computed(() => Object.keys(props.data)),
3027
+ columnWidth: computed(() => services?.uiService.get("columnWidth"))
2946
3028
  };
2947
3029
  }
2948
3030
  });
2949
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3031
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2950
3032
  const _component_tool_button = resolveComponent("tool-button");
2951
3033
  return openBlock(), createElementBlock("div", {
2952
3034
  class: "m-editor-nav-menu",
@@ -2955,7 +3037,8 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2955
3037
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.keys, (key) => {
2956
3038
  return openBlock(), createElementBlock("div", {
2957
3039
  class: normalizeClass(`menu-${key}`),
2958
- key
3040
+ key,
3041
+ style: normalizeStyle(`width: ${_ctx.columnWidth?.[key]}px`)
2959
3042
  }, [
2960
3043
  (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.data[key], (item, index) => {
2961
3044
  return openBlock(), createBlock(_component_tool_button, {
@@ -2963,13 +3046,13 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2963
3046
  key: index
2964
3047
  }, null, 8, ["data"]);
2965
3048
  }), 128))
2966
- ], 2);
3049
+ ], 6);
2967
3050
  }), 128))
2968
3051
  ], 4);
2969
3052
  }
2970
- var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3053
+ var NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
2971
3054
 
2972
- const _sfc_main$9 = defineComponent({
3055
+ const _sfc_main$a = defineComponent({
2973
3056
  name: "m-editor-props-panel",
2974
3057
  emits: ["mounted"],
2975
3058
  setup(props, { emit }) {
@@ -2978,18 +3061,15 @@ const _sfc_main$9 = defineComponent({
2978
3061
  const configForm = ref();
2979
3062
  const curFormConfig = ref([]);
2980
3063
  const services = inject("services");
3064
+ const node = computed(() => services?.editorService.get("node"));
2981
3065
  const init = async () => {
2982
- const node = services?.editorService.get("node");
2983
- if (!node) {
3066
+ if (!node.value) {
2984
3067
  curFormConfig.value = [];
2985
3068
  return;
2986
3069
  }
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");
3070
+ const type = node.value.type || (node.value.items ? "container" : "text");
2992
3071
  curFormConfig.value = await services?.propsService.getPropsConfig(type) || [];
3072
+ values.value = node.value;
2993
3073
  };
2994
3074
  watchEffect(init);
2995
3075
  services?.propsService.on("props-configs-change", init);
@@ -3018,10 +3098,11 @@ const _sfc_main$9 = defineComponent({
3018
3098
  };
3019
3099
  }
3020
3100
  });
3021
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3101
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
3022
3102
  const _component_m_form = resolveComponent("m-form");
3023
3103
  return openBlock(), createBlock(_component_m_form, {
3024
3104
  class: "m-editor-props-panel",
3105
+ "popper-class": "m-editor-props-panel-popper",
3025
3106
  ref: "configForm",
3026
3107
  size: "small",
3027
3108
  "init-values": _ctx.values,
@@ -3029,9 +3110,9 @@ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3029
3110
  onChange: _ctx.submit
3030
3111
  }, null, 8, ["init-values", "config", "onChange"]);
3031
3112
  }
3032
- var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3113
+ var PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
3033
3114
 
3034
- const _sfc_main$8 = defineComponent({
3115
+ const _sfc_main$9 = defineComponent({
3035
3116
  name: "ui-component-panel",
3036
3117
  components: { MIcon },
3037
3118
  setup() {
@@ -3046,19 +3127,19 @@ const _sfc_main$8 = defineComponent({
3046
3127
  searchText,
3047
3128
  collapseValue,
3048
3129
  list,
3049
- appendComponent({ text, type, ...config }) {
3130
+ appendComponent({ text, type, data = {} }) {
3050
3131
  services?.editorService.add({
3051
3132
  name: text,
3052
3133
  type,
3053
- ...config
3134
+ ...data
3054
3135
  });
3055
3136
  }
3056
3137
  };
3057
3138
  }
3058
3139
  });
3059
- const _hoisted_1$6 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3140
+ const _hoisted_1$7 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
3060
3141
  const _hoisted_2$3 = ["onClick"];
3061
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3142
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3062
3143
  const _component_el_input = resolveComponent("el-input");
3063
3144
  const _component_m_icon = resolveComponent("m-icon");
3064
3145
  const _component_el_tooltip = resolveComponent("el-tooltip");
@@ -3088,7 +3169,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3088
3169
  name: index
3089
3170
  }, {
3090
3171
  title: withCtx(() => [
3091
- _hoisted_1$6,
3172
+ _hoisted_1$7,
3092
3173
  createTextVNode(toDisplayString(group.title), 1)
3093
3174
  ]),
3094
3175
  default: withCtx(() => [
@@ -3125,65 +3206,51 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3125
3206
  _: 1
3126
3207
  });
3127
3208
  }
3128
- var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3209
+ var ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
3129
3210
 
3130
- const _sfc_main$7 = defineComponent({
3211
+ const _sfc_main$8 = defineComponent({
3131
3212
  name: "magic-editor-content-menu",
3132
- props: {
3133
- componentGroupList: {
3134
- type: Array,
3135
- default: () => []
3136
- }
3137
- },
3138
- setup(props) {
3213
+ setup() {
3139
3214
  const services = inject("services");
3140
3215
  const subVisible = ref(false);
3141
3216
  const node = computed(() => services?.editorService.get("node"));
3142
3217
  return {
3143
3218
  subVisible,
3144
3219
  node,
3145
- menu: computed(() => ({
3146
- app: [
3147
- {
3148
- type: "page",
3149
- text: "\u9875\u9762"
3150
- }
3151
- ],
3152
- component: props.componentGroupList
3153
- })),
3220
+ componentGroupList: computed(() => services?.componentListService.getList()),
3154
3221
  append(config) {
3155
3222
  services?.editorService.add({
3156
3223
  name: config.text,
3157
- type: config.type
3224
+ type: config.type,
3225
+ ...config.data || {}
3158
3226
  });
3159
3227
  },
3160
3228
  remove() {
3161
3229
  node.value && services?.editorService.remove(node.value);
3162
3230
  },
3163
3231
  copy(node2) {
3164
- services?.editorService.copy(node2);
3232
+ node2 && services?.editorService.copy(node2);
3165
3233
  },
3166
- setSubVisiable(v) {
3234
+ setSubVisitable(v) {
3167
3235
  subVisible.value = v;
3168
3236
  }
3169
3237
  };
3170
3238
  }
3171
3239
  });
3172
- const _hoisted_1$5 = {
3240
+ const _hoisted_1$6 = {
3173
3241
  key: 0,
3174
3242
  class: "magic-editor-content-menu"
3175
3243
  };
3176
3244
  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) {
3245
+ const _hoisted_3$2 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3246
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3180
3247
  const _component_el_scrollbar = resolveComponent("el-scrollbar");
3181
- return _ctx.node ? (openBlock(), createElementBlock("div", _hoisted_1$5, [
3248
+ return _ctx.node ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
3182
3249
  _ctx.node.items ? (openBlock(), createElementBlock("div", {
3183
3250
  key: 0,
3184
3251
  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))
3252
+ onMouseenter: _cache[0] || (_cache[0] = ($event) => _ctx.setSubVisitable(true)),
3253
+ onMouseleave: _cache[1] || (_cache[1] = ($event) => _ctx.setSubVisitable(false))
3187
3254
  }, " \u65B0\u589E ", 32)) : createCommentVNode("", true),
3188
3255
  _ctx.node.type !== "app" ? (openBlock(), createElementBlock("div", {
3189
3256
  key: 1,
@@ -3197,8 +3264,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3197
3264
  }, " \u5220\u9664 ")) : createCommentVNode("", true),
3198
3265
  withDirectives(createElementVNode("div", {
3199
3266
  class: "subMenu",
3200
- onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisiable(true)),
3201
- onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisiable(false))
3267
+ onMouseenter: _cache[5] || (_cache[5] = ($event) => _ctx.setSubVisitable(true)),
3268
+ onMouseleave: _cache[6] || (_cache[6] = ($event) => _ctx.setSubVisitable(false))
3202
3269
  }, [
3203
3270
  createVNode(_component_el_scrollbar, null, {
3204
3271
  default: withCtx(() => [
@@ -3208,13 +3275,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3208
3275
  onClick: _cache[4] || (_cache[4] = () => _ctx.append({
3209
3276
  type: "tab-pane"
3210
3277
  }))
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) => {
3278
+ }, " \u6807\u7B7E ")) : _ctx.node.items ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(_ctx.componentGroupList, (list) => {
3218
3279
  return openBlock(), createElementBlock("div", {
3219
3280
  key: list.title
3220
3281
  }, [
@@ -3224,10 +3285,10 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3224
3285
  class: "magic-editor-content-menu-item",
3225
3286
  key: item.type,
3226
3287
  onClick: () => _ctx.append(item)
3227
- }, toDisplayString(item.text), 9, _hoisted_3$2)) : createCommentVNode("", true)
3288
+ }, toDisplayString(item.text), 9, _hoisted_2$2)) : createCommentVNode("", true)
3228
3289
  ], 64);
3229
3290
  }), 256)),
3230
- _hoisted_4$2
3291
+ _hoisted_3$2
3231
3292
  ]);
3232
3293
  }), 128)) : createCommentVNode("", true)
3233
3294
  ]),
@@ -3238,22 +3299,31 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3238
3299
  ])
3239
3300
  ])) : createCommentVNode("", true);
3240
3301
  }
3241
- var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3302
+ var LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
3242
3303
 
3243
- const select = (data, editorService) => {
3304
+ const throttleTime = 150;
3305
+ const select = async (data, editorService) => {
3244
3306
  if (!data.id) {
3245
3307
  throw new Error("\u6CA1\u6709id");
3246
3308
  }
3247
- editorService?.select(data);
3309
+ await editorService?.select(data);
3310
+ editorService?.get("stage")?.select(data.id);
3311
+ };
3312
+ const highlight = (data, editorService) => {
3313
+ if (!data?.id) {
3314
+ throw new Error("\u6CA1\u6709id");
3315
+ }
3316
+ editorService?.highlight(data);
3317
+ editorService?.get("stage")?.highlight(data.id);
3248
3318
  };
3249
3319
  const useDrop = (tree, editorService) => ({
3250
3320
  allowDrop: (draggingNode, dropNode, type) => {
3251
3321
  const { data } = dropNode || {};
3252
3322
  const { data: ingData } = draggingNode;
3253
3323
  const { type: ingType } = ingData;
3254
- if (ingType !== "page" && data.type === "page")
3324
+ if (ingType !== NodeType.PAGE && data.type === NodeType.PAGE)
3255
3325
  return false;
3256
- if (ingType === "page" && data.type !== "page")
3326
+ if (ingType === NodeType.PAGE && data.type !== NodeType.PAGE)
3257
3327
  return false;
3258
3328
  if (!data || !data.type)
3259
3329
  return false;
@@ -3272,29 +3342,35 @@ const useDrop = (tree, editorService) => ({
3272
3342
  }
3273
3343
  });
3274
3344
  const useStatus = (tree, editorService) => {
3345
+ const highlightNode = ref();
3346
+ const node = ref();
3275
3347
  const page = computed(() => editorService?.get("page"));
3276
3348
  watchEffect(() => {
3277
3349
  if (!tree.value)
3278
3350
  return;
3279
- const node = editorService?.get("node");
3280
- node && tree.value.setCurrentKey(node.id, true);
3351
+ node.value = editorService?.get("node");
3352
+ node.value && tree.value.setCurrentKey(node.value.id, true);
3281
3353
  const parent = editorService?.get("parent");
3282
3354
  if (!parent?.id)
3283
3355
  return;
3284
3356
  const treeNode = tree.value.getNode(parent.id);
3285
3357
  treeNode?.updateChildren();
3358
+ highlightNode.value = editorService?.get("highlightNode");
3286
3359
  });
3287
3360
  return {
3288
3361
  values: computed(() => page.value ? [page.value] : []),
3289
- loadItems: (node, resolve) => {
3290
- if (Array.isArray(node.data)) {
3291
- return resolve(node.data);
3362
+ loadItems: (node2, resolve) => {
3363
+ if (Array.isArray(node2.data)) {
3364
+ return resolve(node2.data);
3292
3365
  }
3293
- if (Array.isArray(node.data?.items)) {
3294
- return resolve(node.data?.items);
3366
+ if (Array.isArray(node2.data?.items)) {
3367
+ return resolve(node2.data?.items);
3295
3368
  }
3296
3369
  resolve([]);
3297
- }
3370
+ },
3371
+ highlightNode,
3372
+ clickNode: node,
3373
+ expandedKeys: computed(() => node.value ? [node.value.id] : [])
3298
3374
  };
3299
3375
  };
3300
3376
  const useFilter = (tree) => ({
@@ -3306,12 +3382,10 @@ const useFilter = (tree) => ({
3306
3382
  let name = "";
3307
3383
  if (data.name) {
3308
3384
  name = data.name;
3309
- } else if (data.type) {
3310
- name = data.type;
3311
3385
  } else if (data.items) {
3312
3386
  name = "container";
3313
3387
  }
3314
- return name.indexOf(value) !== -1;
3388
+ return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
3315
3389
  },
3316
3390
  filterTextChangeHandler(val) {
3317
3391
  tree.value?.filter(val);
@@ -3345,17 +3419,26 @@ const useContentMenu = (editorService) => {
3345
3419
  }
3346
3420
  };
3347
3421
  };
3348
- const _sfc_main$6 = defineComponent({
3422
+ const _sfc_main$7 = defineComponent({
3349
3423
  name: "magic-editor-layer-panel",
3350
3424
  components: { LayerMenu },
3351
3425
  setup() {
3352
3426
  const services = inject("services");
3353
3427
  const tree = ref();
3428
+ const clicked = ref(false);
3354
3429
  const editorService = services?.editorService;
3430
+ const highlightHandler = throttle((data) => {
3431
+ highlight(data, editorService);
3432
+ }, throttleTime);
3433
+ const toogleClickFlag = () => {
3434
+ clicked.value = !clicked.value;
3435
+ };
3436
+ const statusData = useStatus(tree, editorService);
3437
+ const canHighlight = computed(() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value);
3355
3438
  return {
3356
3439
  tree,
3440
+ ...statusData,
3357
3441
  ...useDrop(tree, editorService),
3358
- ...useStatus(tree, editorService),
3359
3442
  ...useFilter(tree),
3360
3443
  ...useContentMenu(editorService),
3361
3444
  clickHandler(data) {
@@ -3363,12 +3446,17 @@ const _sfc_main$6 = defineComponent({
3363
3446
  document.dispatchEvent(new CustomEvent("ui-select", { detail: data }));
3364
3447
  return;
3365
3448
  }
3449
+ tree.value?.setCurrentKey(data.id);
3366
3450
  select(data, editorService);
3367
- }
3451
+ },
3452
+ highlightHandler,
3453
+ toogleClickFlag,
3454
+ canHighlight
3368
3455
  };
3369
3456
  }
3370
3457
  });
3371
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3458
+ const _hoisted_1$5 = ["id", "onMouseenter"];
3459
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3372
3460
  const _component_el_input = resolveComponent("el-input");
3373
3461
  const _component_el_tree = resolveComponent("el-tree");
3374
3462
  const _component_layer_menu = resolveComponent("layer-menu");
@@ -3389,6 +3477,7 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3389
3477
  ref: "tree",
3390
3478
  "node-key": "id",
3391
3479
  draggable: "",
3480
+ "default-expanded-keys": _ctx.expandedKeys,
3392
3481
  load: _ctx.loadItems,
3393
3482
  data: _ctx.values,
3394
3483
  "expand-on-click-node": false,
@@ -3404,15 +3493,23 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3404
3493
  "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3405
3494
  }, {
3406
3495
  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
- ])
3496
+ createElementVNode("div", {
3497
+ id: data.id,
3498
+ class: normalizeClass(["cus-tree-node", { "cus-tree-node-hover": _ctx.canHighlight && data.id === _ctx.highlightNode?.id }]),
3499
+ onMousedown: _cache[1] || (_cache[1] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3500
+ onMouseup: _cache[2] || (_cache[2] = (...args) => _ctx.toogleClickFlag && _ctx.toogleClickFlag(...args)),
3501
+ onMouseenter: ($event) => _ctx.highlightHandler(data)
3502
+ }, [
3503
+ renderSlot(_ctx.$slots, "layer-node-content", {
3504
+ node,
3505
+ data
3506
+ }, () => [
3507
+ createElementVNode("span", null, toDisplayString(`${data.name} (${data.id})`), 1)
3508
+ ])
3509
+ ], 42, _hoisted_1$5)
3413
3510
  ]),
3414
3511
  _: 3
3415
- }, 8, ["load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : createCommentVNode("", true),
3512
+ }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : createCommentVNode("", true),
3416
3513
  (openBlock(), createBlock(Teleport, { to: "body" }, [
3417
3514
  createVNode(_component_layer_menu, {
3418
3515
  style: normalizeStyle(_ctx.menuStyle)
@@ -3422,9 +3519,9 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3422
3519
  _: 3
3423
3520
  });
3424
3521
  }
3425
- var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3522
+ var LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
3426
3523
 
3427
- const _sfc_main$5 = defineComponent({
3524
+ const _sfc_main$6 = defineComponent({
3428
3525
  name: "m-sidebar",
3429
3526
  components: { MIcon },
3430
3527
  props: {
@@ -3472,7 +3569,7 @@ const _hoisted_1$4 = {
3472
3569
  key: 1,
3473
3570
  class: "magic-editor-tab-panel-title"
3474
3571
  };
3475
- function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3572
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3476
3573
  const _component_m_icon = resolveComponent("m-icon");
3477
3574
  const _component_el_tab_pane = resolveComponent("el-tab-pane");
3478
3575
  const _component_el_tabs = resolveComponent("el-tabs");
@@ -3519,15 +3616,81 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3519
3616
  _: 1
3520
3617
  }, 8, ["modelValue"])) : createCommentVNode("", true);
3521
3618
  }
3522
- var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3523
-
3524
- const _sfc_main$4 = defineComponent({
3525
- components: { CaretBottom, Plus },
3619
+ var Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
3620
+
3621
+ const useScroll = (root) => {
3622
+ const pageBar = ref();
3623
+ const itemsContainer = ref();
3624
+ const pageBarWidth = ref(0);
3625
+ const canScroll = ref(false);
3626
+ const itemsContainerWidth = computed(() => pageBarWidth.value - 105);
3627
+ let translateLeft = 0;
3628
+ const resizeObserver = new ResizeObserver((entries) => {
3629
+ for (const { contentRect } of entries) {
3630
+ const { width } = contentRect;
3631
+ pageBarWidth.value = width || 0;
3632
+ setCanScroll();
3633
+ }
3634
+ });
3635
+ const setCanScroll = () => {
3636
+ if (itemsContainer.value) {
3637
+ canScroll.value = itemsContainer.value.scrollWidth > pageBarWidth.value - 105;
3638
+ }
3639
+ };
3640
+ const scroll = (type) => {
3641
+ if (!itemsContainer.value)
3642
+ return;
3643
+ const maxScrollLeft = itemsContainer.value.scrollWidth - itemsContainerWidth.value;
3644
+ if (type === "left") {
3645
+ translateLeft += 100;
3646
+ if (translateLeft > 0) {
3647
+ translateLeft = 0;
3648
+ }
3649
+ } else if (type === "right") {
3650
+ translateLeft -= 100;
3651
+ if (-translateLeft > maxScrollLeft) {
3652
+ translateLeft = -maxScrollLeft;
3653
+ }
3654
+ } else if (type === "start") {
3655
+ translateLeft = 0;
3656
+ } else if (type === "end") {
3657
+ translateLeft = -maxScrollLeft;
3658
+ }
3659
+ itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
3660
+ };
3661
+ onMounted(() => {
3662
+ pageBar.value && resizeObserver.observe(pageBar.value);
3663
+ });
3664
+ onUnmounted(() => {
3665
+ resizeObserver.disconnect();
3666
+ });
3667
+ watch(() => root.value?.items.length, (length = 0, preLength = 0) => {
3668
+ setTimeout(() => {
3669
+ setCanScroll();
3670
+ if (length < preLength) {
3671
+ scroll("start");
3672
+ } else {
3673
+ scroll("end");
3674
+ }
3675
+ });
3676
+ });
3677
+ return {
3678
+ pageBar,
3679
+ itemsContainer,
3680
+ canScroll,
3681
+ itemsContainerWidth,
3682
+ scroll
3683
+ };
3684
+ };
3685
+ const _sfc_main$5 = defineComponent({
3686
+ components: { ArrowLeftBold, ArrowRightBold, CaretBottom, Plus },
3526
3687
  setup() {
3527
3688
  const services = inject("services");
3528
3689
  const editorService = services?.editorService;
3690
+ const root = computed(() => editorService?.get("root"));
3529
3691
  return {
3530
- root: computed(() => editorService?.get("root")),
3692
+ ...useScroll(root),
3693
+ root,
3531
3694
  page: computed(() => editorService?.get("page")),
3532
3695
  switchPage(page) {
3533
3696
  editorService?.select(page);
@@ -3536,7 +3699,7 @@ const _sfc_main$4 = defineComponent({
3536
3699
  if (!editorService)
3537
3700
  return;
3538
3701
  const pageConfig = {
3539
- type: "page",
3702
+ type: NodeType.PAGE,
3540
3703
  name: generatePageNameByApp(toRaw(editorService.get("root")))
3541
3704
  };
3542
3705
  editorService.add(pageConfig);
@@ -3554,70 +3717,339 @@ const _sfc_main$4 = defineComponent({
3554
3717
  };
3555
3718
  }
3556
3719
  });
3557
- const _hoisted_1$3 = { class: "m-editor-page-bar" };
3720
+ const _hoisted_1$3 = {
3721
+ class: "m-editor-page-bar",
3722
+ ref: "pageBar"
3723
+ };
3558
3724
  const _hoisted_2$1 = ["onClick"];
3559
- const _hoisted_3$1 = ["onClick"];
3725
+ const _hoisted_3$1 = { class: "m-editor-page-bar-title" };
3560
3726
  const _hoisted_4$1 = ["onClick"];
3561
- function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3727
+ const _hoisted_5 = ["onClick"];
3728
+ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3562
3729
  const _component_plus = resolveComponent("plus");
3563
3730
  const _component_el_icon = resolveComponent("el-icon");
3731
+ const _component_arrow_left_bold = resolveComponent("arrow-left-bold");
3732
+ const _component_el_tooltip = resolveComponent("el-tooltip");
3564
3733
  const _component_caret_bottom = resolveComponent("caret-bottom");
3565
3734
  const _component_el_popover = resolveComponent("el-popover");
3735
+ const _component_arrow_right_bold = resolveComponent("arrow-right-bold");
3566
3736
  return openBlock(), createElementBlock("div", _hoisted_1$3, [
3567
3737
  createElementVNode("div", {
3568
- class: "m-editor-page-bar-item",
3738
+ id: "m-editor-page-bar-add-icon",
3739
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3569
3740
  onClick: _cache[0] || (_cache[0] = (...args) => _ctx.addPage && _ctx.addPage(...args))
3570
3741
  }, [
3571
- createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-add-icon" }, {
3742
+ createVNode(_component_el_icon, null, {
3572
3743
  default: withCtx(() => [
3573
3744
  createVNode(_component_plus)
3574
3745
  ]),
3575
3746
  _: 1
3576
3747
  })
3577
3748
  ]),
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)
3749
+ _ctx.canScroll ? (openBlock(), createElementBlock("div", {
3750
+ key: 0,
3751
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3752
+ onClick: _cache[1] || (_cache[1] = ($event) => _ctx.scroll("left"))
3753
+ }, [
3754
+ createVNode(_component_el_icon, null, {
3755
+ default: withCtx(() => [
3756
+ createVNode(_component_arrow_left_bold)
3586
3757
  ]),
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
- ])
3758
+ _: 1
3759
+ })
3760
+ ])) : createCommentVNode("", true),
3761
+ _ctx.root ? (openBlock(), createElementBlock("div", {
3762
+ key: 1,
3763
+ class: "m-editor-page-bar-items",
3764
+ ref: "itemsContainer",
3765
+ style: normalizeStyle(`width: ${_ctx.itemsContainerWidth}px`)
3766
+ }, [
3767
+ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.root.items, (item) => {
3768
+ return openBlock(), createElementBlock("div", {
3769
+ key: item.key,
3770
+ class: normalizeClass(["m-editor-page-bar-item", { active: _ctx.page?.id === item.id }]),
3771
+ onClick: ($event) => _ctx.switchPage(item)
3772
+ }, [
3773
+ createElementVNode("div", _hoisted_3$1, [
3774
+ renderSlot(_ctx.$slots, "page-bar-title", { page: item }, () => [
3775
+ createVNode(_component_el_tooltip, {
3776
+ effect: "dark",
3777
+ placement: "top-start",
3778
+ content: item.name
3779
+ }, {
3780
+ default: withCtx(() => [
3781
+ createElementVNode("span", null, toDisplayString(item.name), 1)
3782
+ ]),
3783
+ _: 2
3784
+ }, 1032, ["content"])
3612
3785
  ])
3613
3786
  ]),
3614
- _: 2
3615
- }, 1024)
3616
- ], 10, _hoisted_2$1);
3617
- }), 128)) : createCommentVNode("", true)
3618
- ]);
3787
+ createVNode(_component_el_popover, {
3788
+ placement: "top",
3789
+ width: 160,
3790
+ trigger: "hover"
3791
+ }, {
3792
+ reference: withCtx(() => [
3793
+ createVNode(_component_el_icon, { class: "m-editor-page-bar-menu-icon" }, {
3794
+ default: withCtx(() => [
3795
+ createVNode(_component_caret_bottom)
3796
+ ]),
3797
+ _: 1
3798
+ })
3799
+ ]),
3800
+ default: withCtx(() => [
3801
+ createElementVNode("div", null, [
3802
+ renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3803
+ createElementVNode("div", {
3804
+ class: "magic-editor-content-menu-item",
3805
+ onClick: () => _ctx.copy(item)
3806
+ }, "\u590D\u5236", 8, _hoisted_4$1),
3807
+ createElementVNode("div", {
3808
+ class: "magic-editor-content-menu-item",
3809
+ onClick: () => _ctx.remove(item)
3810
+ }, "\u5220\u9664", 8, _hoisted_5)
3811
+ ])
3812
+ ])
3813
+ ]),
3814
+ _: 2
3815
+ }, 1024)
3816
+ ], 10, _hoisted_2$1);
3817
+ }), 128))
3818
+ ], 4)) : createCommentVNode("", true),
3819
+ _ctx.canScroll ? (openBlock(), createElementBlock("div", {
3820
+ key: 2,
3821
+ class: "m-editor-page-bar-item m-editor-page-bar-item-icon",
3822
+ onClick: _cache[2] || (_cache[2] = ($event) => _ctx.scroll("right"))
3823
+ }, [
3824
+ createVNode(_component_el_icon, null, {
3825
+ default: withCtx(() => [
3826
+ createVNode(_component_arrow_right_bold)
3827
+ ]),
3828
+ _: 1
3829
+ })
3830
+ ])) : createCommentVNode("", true)
3831
+ ], 512);
3832
+ }
3833
+ var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
3834
+
3835
+ class ScrollViewer$1 {
3836
+ enter = false;
3837
+ targetEnter = false;
3838
+ keydown = false;
3839
+ container;
3840
+ target;
3841
+ zoom = 1;
3842
+ scrollLeft = 0;
3843
+ scrollTop = 0;
3844
+ x = 0;
3845
+ y = 0;
3846
+ resizeObserver = new ResizeObserver((entries) => {
3847
+ for (const { contentRect } of entries) {
3848
+ const { width, height } = contentRect;
3849
+ const targetRect = this.target.getBoundingClientRect();
3850
+ const targetWidth = targetRect.width * this.zoom;
3851
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
3852
+ const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3853
+ if (targetWidth < width) {
3854
+ this.target._left = 0;
3855
+ }
3856
+ if (targetHeight < height) {
3857
+ this.target._top = 0;
3858
+ }
3859
+ this.scroll();
3860
+ }
3861
+ });
3862
+ constructor(options) {
3863
+ this.container = options.container;
3864
+ this.target = options.target;
3865
+ this.zoom = options.zoom;
3866
+ globalThis.addEventListener("keydown", this.keydownHandler);
3867
+ globalThis.addEventListener("keyup", this.keyupHandler);
3868
+ this.container.addEventListener("mouseenter", this.mouseEnterHandler);
3869
+ this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
3870
+ this.target.addEventListener("mouseenter", this.targetMouseEnterHandler);
3871
+ this.target.addEventListener("mouseleave", this.targetMouseLeaveHandler);
3872
+ this.container.addEventListener("wheel", this.wheelHandler);
3873
+ this.resizeObserver.observe(this.container);
3874
+ }
3875
+ destroy() {
3876
+ this.resizeObserver.disconnect();
3877
+ this.container.removeEventListener("mouseenter", this.mouseEnterHandler);
3878
+ this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
3879
+ this.target.removeEventListener("mouseenter", this.targetMouseEnterHandler);
3880
+ this.target.removeEventListener("mouseleave", this.targetMouseLeaveHandler);
3881
+ globalThis.removeEventListener("keydown", this.keydownHandler);
3882
+ globalThis.removeEventListener("keyup", this.keyupHandler);
3883
+ }
3884
+ setZoom(zoom) {
3885
+ this.zoom = zoom;
3886
+ }
3887
+ scroll() {
3888
+ const scrollLeft = this.target._left;
3889
+ const scrollTop = this.target._top;
3890
+ this.target.style.transform = `translate(${scrollLeft}px, ${scrollTop}px)`;
3891
+ }
3892
+ removeHandler() {
3893
+ this.target.style.cursor = "";
3894
+ this.target.removeEventListener("mousedown", this.mousedownHandler);
3895
+ document.removeEventListener("mousemove", this.mousemoveHandler);
3896
+ document.removeEventListener("mouseup", this.mouseupHandler);
3897
+ }
3898
+ wheelHandler = (event) => {
3899
+ if (this.targetEnter)
3900
+ return;
3901
+ const { deltaX, deltaY, currentTarget } = event;
3902
+ if (currentTarget !== this.container)
3903
+ return;
3904
+ this.setScrollOffset(deltaX, deltaY);
3905
+ this.scroll();
3906
+ this.scrollLeft = this.target._left;
3907
+ this.scrollTop = this.target._top;
3908
+ };
3909
+ mouseEnterHandler = () => {
3910
+ this.enter = true;
3911
+ };
3912
+ mouseLeaveHandler = () => {
3913
+ this.enter = false;
3914
+ };
3915
+ targetMouseEnterHandler = () => {
3916
+ this.targetEnter = true;
3917
+ };
3918
+ targetMouseLeaveHandler = () => {
3919
+ this.targetEnter = false;
3920
+ };
3921
+ mousedownHandler = (event) => {
3922
+ if (!this.keydown)
3923
+ return;
3924
+ event.stopImmediatePropagation();
3925
+ event.stopPropagation();
3926
+ this.target.style.cursor = "grabbing";
3927
+ this.x = event.clientX;
3928
+ this.y = event.clientY;
3929
+ document.addEventListener("mousemove", this.mousemoveHandler);
3930
+ document.addEventListener("mouseup", this.mouseupHandler);
3931
+ };
3932
+ mouseupHandler = () => {
3933
+ this.x = 0;
3934
+ this.y = 0;
3935
+ this.scrollLeft = this.target._left;
3936
+ this.scrollTop = this.target._top;
3937
+ this.removeHandler();
3938
+ };
3939
+ mousemoveHandler = (event) => {
3940
+ event.stopImmediatePropagation();
3941
+ event.stopPropagation();
3942
+ const deltaX = event.clientX - this.x;
3943
+ const deltaY = event.clientY - this.y;
3944
+ this.setScrollOffset(deltaX, deltaY);
3945
+ this.scroll();
3946
+ };
3947
+ keydownHandler = (event) => {
3948
+ if (event.code === Keys.ESCAPE && this.enter) {
3949
+ event.preventDefault();
3950
+ event.stopImmediatePropagation();
3951
+ event.stopPropagation();
3952
+ }
3953
+ if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3954
+ return;
3955
+ }
3956
+ this.keydown = true;
3957
+ this.target.style.cursor = "grab";
3958
+ this.container.addEventListener("mousedown", this.mousedownHandler);
3959
+ };
3960
+ keyupHandler = (event) => {
3961
+ if (event.code !== Keys.ESCAPE || !this.keydown) {
3962
+ return;
3963
+ }
3964
+ event.preventDefault();
3965
+ event.stopImmediatePropagation();
3966
+ event.stopPropagation();
3967
+ this.keydown = false;
3968
+ event.preventDefault();
3969
+ this.removeHandler();
3970
+ };
3971
+ setScrollOffset(deltaX, deltaY) {
3972
+ const { width, height } = this.container.getBoundingClientRect();
3973
+ const targetRect = this.target.getBoundingClientRect();
3974
+ const targetWidth = targetRect.width * this.zoom;
3975
+ const targetHeight = targetRect.height * this.zoom;
3976
+ let y = 0;
3977
+ if (targetHeight > height) {
3978
+ if (deltaY > 0) {
3979
+ y = this.scrollTop + Math.min(targetHeight - height - this.scrollTop, deltaY);
3980
+ } else {
3981
+ y = this.scrollTop + Math.max(-(targetHeight - height + this.scrollTop), deltaY);
3982
+ }
3983
+ }
3984
+ let x = 0;
3985
+ if (targetWidth > width) {
3986
+ if (deltaX > 0) {
3987
+ x = this.scrollLeft + Math.min(targetWidth - width - this.scrollLeft, deltaX);
3988
+ } else {
3989
+ x = this.scrollLeft + Math.max(-(targetWidth - width + this.scrollLeft), deltaX);
3990
+ }
3991
+ }
3992
+ this.target._left = x;
3993
+ this.target._top = y;
3994
+ }
3995
+ }
3996
+
3997
+ const _sfc_main$4 = defineComponent({
3998
+ name: "m-editor-scroll-viewer",
3999
+ props: {
4000
+ width: Number,
4001
+ height: Number,
4002
+ zoom: {
4003
+ type: Number,
4004
+ default: 1
4005
+ }
4006
+ },
4007
+ setup(props) {
4008
+ const container = ref();
4009
+ const el = ref();
4010
+ let scrollViewer;
4011
+ onMounted(() => {
4012
+ if (!container.value || !el.value)
4013
+ return;
4014
+ scrollViewer = new ScrollViewer$1({
4015
+ container: container.value,
4016
+ target: el.value,
4017
+ zoom: props.zoom
4018
+ });
4019
+ });
4020
+ onUnmounted(() => {
4021
+ scrollViewer.destroy();
4022
+ });
4023
+ watch(() => props.zoom, () => {
4024
+ scrollViewer.setZoom(props.zoom);
4025
+ });
4026
+ return {
4027
+ container,
4028
+ el,
4029
+ style: computed(() => `
4030
+ width: ${props.width}px;
4031
+ height: ${props.height}px;
4032
+ position: absolute;
4033
+ margin-top: 30px;
4034
+ `)
4035
+ };
4036
+ }
4037
+ });
4038
+ const _hoisted_1$2 = {
4039
+ class: "m-editor-scroll-viewer-container",
4040
+ ref: "container"
4041
+ };
4042
+ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
4043
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [
4044
+ createElementVNode("div", {
4045
+ ref: "el",
4046
+ style: normalizeStyle(_ctx.style)
4047
+ }, [
4048
+ renderSlot(_ctx.$slots, "default")
4049
+ ], 4)
4050
+ ], 512);
3619
4051
  }
3620
- var PageBar = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
4052
+ var ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
3621
4053
 
3622
4054
  const _sfc_main$3 = defineComponent({
3623
4055
  name: "magic-editor-ui-viewer-menu",
@@ -3637,13 +4069,13 @@ const _sfc_main$3 = defineComponent({
3637
4069
  if (!parent.value || !editorService)
3638
4070
  return canCenter.value = false;
3639
4071
  const layout = await editorService.getLayout(parent.value);
3640
- canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && !["app", "page", "pop"].includes(`${node.value?.type}`);
4072
+ canCenter.value = [Layout.ABSOLUTE, Layout.FIXED].includes(layout) && ![NodeType.ROOT, NodeType.PAGE, "pop"].includes(`${node.value?.type}`);
3641
4073
  }, { immediate: true });
3642
4074
  return {
3643
4075
  menu,
3644
4076
  canPaste,
3645
- canDelete: computed(() => node.value?.type !== "page"),
3646
- canMoveZPos: computed(() => node.value?.type !== "page"),
4077
+ canDelete: computed(() => node.value?.type !== NodeType.PAGE),
4078
+ canMoveZPos: computed(() => node.value?.type !== NodeType.PAGE),
3647
4079
  canCenter,
3648
4080
  center() {
3649
4081
  node.value && editorService?.alignCenter(node.value);
@@ -3678,7 +4110,7 @@ const _sfc_main$3 = defineComponent({
3678
4110
  };
3679
4111
  }
3680
4112
  });
3681
- const _hoisted_1$2 = {
4113
+ const _hoisted_1$1 = {
3682
4114
  class: "magic-editor-content-menu",
3683
4115
  ref: "menu"
3684
4116
  };
@@ -3686,7 +4118,7 @@ const _hoisted_2 = /* @__PURE__ */ createElementVNode("div", { class: "separatio
3686
4118
  const _hoisted_3 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3687
4119
  const _hoisted_4 = /* @__PURE__ */ createElementVNode("div", { class: "separation" }, null, -1);
3688
4120
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3689
- return openBlock(), createElementBlock("div", _hoisted_1$2, [
4121
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [
3690
4122
  createElementVNode("div", null, [
3691
4123
  _ctx.canCenter ? (openBlock(), createElementBlock("div", {
3692
4124
  key: 0,
@@ -3771,28 +4203,14 @@ const useMenu = () => {
3771
4203
  const _sfc_main$2 = defineComponent({
3772
4204
  name: "magic-stage",
3773
4205
  components: {
3774
- ViewerMenu
4206
+ ViewerMenu,
4207
+ ScrollViewer
3775
4208
  },
3776
4209
  props: {
3777
4210
  render: {
3778
4211
  type: Function
3779
4212
  },
3780
4213
  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
4214
  canSelect: {
3797
4215
  type: Function,
3798
4216
  default: (el) => Boolean(el.id)
@@ -3804,14 +4222,16 @@ const _sfc_main$2 = defineComponent({
3804
4222
  })
3805
4223
  }
3806
4224
  },
3807
- emits: ["select", "update", "sort"],
3808
- setup(props, { emit }) {
4225
+ setup(props) {
3809
4226
  const services = inject("services");
4227
+ const stageWrap = ref();
3810
4228
  const stageContainer = ref();
3811
- const stageStyle = computed(() => ({
3812
- ...services?.uiService.get("stageStyle"),
3813
- transform: `scale(${props.zoom}) translate3d(0, -50%, 0)`
3814
- }));
4229
+ const stageRect = computed(() => services?.uiService.get("stageRect"));
4230
+ const uiSelectMode = computed(() => services?.uiService.get("uiSelectMode"));
4231
+ const root = computed(() => services?.editorService.get("root"));
4232
+ const page = computed(() => services?.editorService.get("page"));
4233
+ const zoom = computed(() => services?.uiService.get("zoom"));
4234
+ const node = computed(() => services?.editorService.get("node"));
3815
4235
  let stage = null;
3816
4236
  let runtime = null;
3817
4237
  watchEffect(() => {
@@ -3819,15 +4239,15 @@ const _sfc_main$2 = defineComponent({
3819
4239
  return;
3820
4240
  if (!stageContainer.value)
3821
4241
  return;
3822
- if (!(props.runtimeUrl || props.render) || !props.root)
4242
+ if (!(props.runtimeUrl || props.render) || !root.value)
3823
4243
  return;
3824
4244
  stage = new StageCore({
3825
4245
  render: props.render,
3826
4246
  runtimeUrl: props.runtimeUrl,
3827
- zoom: props.zoom,
3828
- canSelect: (el, stop) => {
4247
+ zoom: zoom.value,
4248
+ canSelect: (el, event, stop) => {
3829
4249
  const elCanSelect = props.canSelect(el);
3830
- if (props.uiSelectMode && elCanSelect) {
4250
+ if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
3831
4251
  document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
3832
4252
  return stop();
3833
4253
  }
@@ -3835,67 +4255,95 @@ const _sfc_main$2 = defineComponent({
3835
4255
  },
3836
4256
  moveableOptions: props.moveableOptions
3837
4257
  });
3838
- services?.editorService.set("stage", stage);
4258
+ services?.editorService.set("stage", markRaw(stage));
3839
4259
  stage?.mount(stageContainer.value);
3840
- stage?.on("select", (el) => emit("select", el));
4260
+ stage?.on("select", (el) => {
4261
+ services?.editorService.select(el.id);
4262
+ });
4263
+ stage?.on("highlight", (el) => {
4264
+ services?.editorService.highlight(el.id);
4265
+ });
3841
4266
  stage?.on("update", (ev) => {
3842
- emit("update", { id: ev.el.id, style: ev.style });
4267
+ services?.editorService.update({ id: ev.el.id, style: ev.style });
3843
4268
  });
3844
4269
  stage?.on("sort", (ev) => {
3845
- emit("sort", ev);
4270
+ services?.editorService.sort(ev.src, ev.dist);
3846
4271
  });
3847
4272
  stage?.on("changeGuides", () => {
3848
4273
  services?.uiService.set("showGuides", true);
3849
4274
  });
3850
- if (!props.node?.id)
4275
+ if (!node.value?.id)
3851
4276
  return;
3852
4277
  stage?.on("runtime-ready", (rt) => {
3853
4278
  runtime = rt;
3854
- props.root && runtime?.updateRootConfig(cloneDeep(toRaw(props.root)));
3855
- props.page?.id && runtime?.updatePageId?.(props.page.id);
4279
+ root.value && runtime?.updateRootConfig(cloneDeep(toRaw(root.value)));
4280
+ page.value?.id && runtime?.updatePageId?.(page.value.id);
3856
4281
  setTimeout(() => {
3857
- props.node && stage?.select(toRaw(props.node.id));
4282
+ node.value && stage?.select(toRaw(node.value.id));
3858
4283
  });
3859
4284
  });
3860
4285
  });
3861
- watch(() => props.zoom, (zoom) => {
3862
- if (!stage || !zoom)
4286
+ watch(zoom, (zoom2) => {
4287
+ if (!stage || !zoom2)
3863
4288
  return;
3864
- stage?.setZoom(zoom);
4289
+ stage.setZoom(zoom2);
4290
+ });
4291
+ watch(root, (root2) => {
4292
+ if (runtime && root2) {
4293
+ runtime.updateRootConfig(cloneDeep(toRaw(root2)));
4294
+ }
3865
4295
  });
3866
- watch(() => props.root, (root) => {
3867
- if (runtime && root) {
3868
- runtime.updateRootConfig(cloneDeep(toRaw(root)));
4296
+ const resizeObserver = new ResizeObserver((entries) => {
4297
+ for (const { contentRect } of entries) {
4298
+ services?.uiService.set("stageContainerRect", {
4299
+ width: contentRect.width,
4300
+ height: contentRect.height
4301
+ });
3869
4302
  }
3870
4303
  });
4304
+ onMounted(() => {
4305
+ stageWrap.value?.container && resizeObserver.observe(stageWrap.value.container);
4306
+ });
3871
4307
  onUnmounted(() => {
3872
4308
  stage?.destroy();
4309
+ resizeObserver.disconnect();
3873
4310
  services?.editorService.set("stage", null);
3874
4311
  });
3875
4312
  return {
3876
- stageStyle,
3877
- ...useMenu(),
3878
- stageContainer
4313
+ stageWrap,
4314
+ stageContainer,
4315
+ stageRect,
4316
+ zoom,
4317
+ ...useMenu()
3879
4318
  };
3880
4319
  }
3881
4320
  });
3882
- const _hoisted_1$1 = { class: "m-editor-stage" };
3883
4321
  function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3884
4322
  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
- ]);
4323
+ const _component_scroll_viewer = resolveComponent("scroll-viewer");
4324
+ return openBlock(), createBlock(_component_scroll_viewer, {
4325
+ class: "m-editor-stage",
4326
+ ref: "stageWrap",
4327
+ width: _ctx.stageRect?.width,
4328
+ height: _ctx.stageRect?.height,
4329
+ zoom: _ctx.zoom
4330
+ }, {
4331
+ default: withCtx(() => [
4332
+ createElementVNode("div", {
4333
+ class: "m-editor-stage-container",
4334
+ ref: "stageContainer",
4335
+ onContextmenu: _cache[0] || (_cache[0] = (...args) => _ctx.contextmenuHandler && _ctx.contextmenuHandler(...args)),
4336
+ style: normalizeStyle(`transform: scale(${_ctx.zoom})`)
4337
+ }, null, 36),
4338
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
4339
+ createVNode(_component_viewer_menu, {
4340
+ ref: "menu",
4341
+ style: normalizeStyle(_ctx.menuStyle)
4342
+ }, null, 8, ["style"])
4343
+ ]))
4344
+ ]),
4345
+ _: 1
4346
+ }, 8, ["width", "height", "zoom"]);
3899
4347
  }
3900
4348
  var MagicStage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2]]);
3901
4349
 
@@ -3919,32 +4367,48 @@ const _sfc_main$1 = defineComponent({
3919
4367
  },
3920
4368
  setup() {
3921
4369
  const services = inject("services");
4370
+ const workspace = ref();
3922
4371
  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);
4372
+ let keycon;
4373
+ const mouseenterHandler = () => {
4374
+ workspace.value?.focus();
4375
+ };
4376
+ const mouseleaveHandler = () => {
4377
+ workspace.value?.blur();
4378
+ };
4379
+ onMounted(() => {
4380
+ workspace.value?.addEventListener("mouseenter", mouseenterHandler);
4381
+ workspace.value?.addEventListener("mouseleave", mouseleaveHandler);
4382
+ keycon = new KeyController(workspace.value);
4383
+ keycon.keyup("delete", () => {
4384
+ node.value && services?.editorService.remove(node.value);
4385
+ }).keyup(["ctrl", "c"], () => {
4386
+ node.value && services?.editorService.copy(node.value);
4387
+ }).keyup(["ctrl", "v"], () => {
4388
+ node.value && services?.editorService.paste();
4389
+ }).keyup(["ctrl", "x"], () => {
4390
+ if (node.value && services) {
4391
+ services.editorService.copy(node.value);
4392
+ services.editorService.remove(node.value);
4393
+ }
3927
4394
  });
3928
4395
  });
4396
+ onUnmounted(() => {
4397
+ workspace.value?.removeEventListener("mouseenter", mouseenterHandler);
4398
+ workspace.value?.removeEventListener("mouseleave", mouseleaveHandler);
4399
+ keycon.destroy();
4400
+ });
3929
4401
  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
- }
4402
+ workspace,
4403
+ page: computed(() => services?.editorService.get("page"))
3944
4404
  };
3945
4405
  }
3946
4406
  });
3947
- const _hoisted_1 = { class: "m-editor-workspace" };
4407
+ const _hoisted_1 = {
4408
+ class: "m-editor-workspace",
4409
+ tabindex: "1",
4410
+ ref: "workspace"
4411
+ };
3948
4412
  function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3949
4413
  const _component_magic_stage = resolveComponent("magic-stage");
3950
4414
  const _component_page_bar = resolveComponent("page-bar");
@@ -3953,17 +4417,9 @@ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3953
4417
  key: _ctx.page?.id,
3954
4418
  "runtime-url": _ctx.runtimeUrl,
3955
4419
  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
4420
  "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"])),
4421
+ "can-select": _ctx.canSelect
4422
+ }, null, 8, ["runtime-url", "render", "moveable-options", "can-select"])),
3967
4423
  renderSlot(_ctx.$slots, "workspace-content"),
3968
4424
  createVNode(_component_page_bar, null, {
3969
4425
  "page-bar-title": withCtx(({ page }) => [
@@ -3974,7 +4430,7 @@ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3974
4430
  ]),
3975
4431
  _: 3
3976
4432
  })
3977
- ]);
4433
+ ], 512);
3978
4434
  }
3979
4435
  var Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
3980
4436
 
@@ -3994,15 +4450,24 @@ class ComponentList extends BaseService {
3994
4450
  }
3995
4451
  var componentListService = new ComponentList();
3996
4452
 
4453
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4454
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
3997
4455
  const state = reactive({
3998
4456
  uiSelectMode: false,
3999
4457
  showSrc: false,
4000
4458
  zoom: 1,
4001
- stageStyle: {},
4459
+ stageContainerRect: {
4460
+ width: 0,
4461
+ height: 0
4462
+ },
4463
+ stageRect: {
4464
+ width: 375,
4465
+ height: 817
4466
+ },
4002
4467
  columnWidth: {
4003
- left: 310,
4004
- center: globalThis.document.body.clientWidth - 310 - 400,
4005
- right: 400
4468
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
4469
+ center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4470
+ right: DEFAULT_RIGHT_COLUMN_WIDTH
4006
4471
  },
4007
4472
  showGuides: true,
4008
4473
  showRule: true
@@ -4022,6 +4487,10 @@ class Ui extends BaseService {
4022
4487
  this.setColumnWidth(value);
4023
4488
  return;
4024
4489
  }
4490
+ if (name === "stageRect") {
4491
+ this.setStageRect(value);
4492
+ return;
4493
+ }
4025
4494
  if (name === "showGuides") {
4026
4495
  mask?.showGuides(value);
4027
4496
  }
@@ -4029,6 +4498,9 @@ class Ui extends BaseService {
4029
4498
  mask?.showRule(value);
4030
4499
  }
4031
4500
  state[name] = value;
4501
+ if (name === "stageContainerRect") {
4502
+ state.zoom = this.calcZoom();
4503
+ }
4032
4504
  }
4033
4505
  get(name) {
4034
4506
  return state[name];
@@ -4051,6 +4523,23 @@ class Ui extends BaseService {
4051
4523
  }
4052
4524
  state.columnWidth = columnWidth;
4053
4525
  }
4526
+ setStageRect(value) {
4527
+ state.stageRect = {
4528
+ ...state.stageRect,
4529
+ ...value
4530
+ };
4531
+ state.zoom = this.calcZoom();
4532
+ }
4533
+ calcZoom() {
4534
+ const { stageRect, stageContainerRect } = state;
4535
+ const { height, width } = stageContainerRect;
4536
+ if (!width || !height)
4537
+ return 1;
4538
+ if (width > stageRect.width && height > stageRect.height) {
4539
+ return 1;
4540
+ }
4541
+ return Math.min((width - 100) / stageRect.width || 1, (height - 100) / stageRect.height || 1);
4542
+ }
4054
4543
  }
4055
4544
  var uiService = new Ui();
4056
4545
 
@@ -4105,7 +4594,7 @@ const _sfc_main = defineComponent({
4105
4594
  canSelect: {
4106
4595
  type: Function
4107
4596
  },
4108
- stageStyle: {
4597
+ stageRect: {
4109
4598
  type: [String, Object]
4110
4599
  }
4111
4600
  },
@@ -4143,7 +4632,7 @@ const _sfc_main = defineComponent({
4143
4632
  watch(() => props.defaultSelected, (defaultSelected) => defaultSelected && editorService.select(defaultSelected), {
4144
4633
  immediate: true
4145
4634
  });
4146
- watch(() => props.stageStyle, (stageStyle) => uiService.set("stageStyle", stageStyle), {
4635
+ watch(() => props.stageRect, (stageRect) => stageRect && uiService.set("stageRect", stageRect), {
4147
4636
  immediate: true
4148
4637
  });
4149
4638
  onUnmounted(() => editorService.destroy());
@@ -4229,5 +4718,5 @@ var index = {
4229
4718
  }
4230
4719
  };
4231
4720
 
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 };
4721
+ 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
4722
  //# sourceMappingURL=tmagic-editor.es.js.map