@tmagic/editor 1.1.0-beta.8 → 1.1.1

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 (59) hide show
  1. package/dist/style.css +46 -0
  2. package/dist/tmagic-editor.mjs +1052 -873
  3. package/dist/tmagic-editor.mjs.map +1 -1
  4. package/dist/tmagic-editor.umd.js +1054 -872
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/package.json +10 -10
  7. package/src/Editor.vue +31 -9
  8. package/src/components/ContentMenu.vue +4 -4
  9. package/src/components/Icon.vue +6 -20
  10. package/src/components/ScrollBar.vue +147 -0
  11. package/src/components/ScrollViewer.vue +89 -44
  12. package/src/components/ToolButton.vue +40 -138
  13. package/src/fields/UISelect.vue +2 -2
  14. package/src/index.ts +2 -0
  15. package/src/layouts/NavMenu.vue +156 -23
  16. package/src/layouts/PropsPanel.vue +49 -51
  17. package/src/layouts/sidebar/LayerMenu.vue +3 -3
  18. package/src/layouts/sidebar/LayerPanel.vue +39 -8
  19. package/src/layouts/workspace/PageBar.vue +1 -1
  20. package/src/layouts/workspace/Stage.vue +8 -86
  21. package/src/layouts/workspace/ViewerMenu.vue +6 -6
  22. package/src/layouts/workspace/Workspace.vue +133 -138
  23. package/src/services/componentList.ts +5 -0
  24. package/src/services/editor.ts +148 -76
  25. package/src/services/events.ts +8 -2
  26. package/src/services/props.ts +31 -52
  27. package/src/services/storage.ts +4 -0
  28. package/src/services/ui.ts +32 -30
  29. package/src/theme/nav-menu.scss +6 -0
  30. package/src/type.ts +28 -11
  31. package/src/utils/index.ts +1 -0
  32. package/src/utils/operator.ts +6 -60
  33. package/src/utils/props.ts +0 -3
  34. package/src/utils/scroll-viewer.ts +90 -158
  35. package/src/utils/stage.ts +91 -0
  36. package/types/Editor.vue.d.ts +17 -8
  37. package/types/components/ContentMenu.vue.d.ts +8 -8
  38. package/types/components/Icon.vue.d.ts +62 -12
  39. package/types/components/ScrollBar.vue.d.ts +83 -0
  40. package/types/components/ScrollViewer.vue.d.ts +131 -19
  41. package/types/components/ToolButton.vue.d.ts +56 -59
  42. package/types/index.d.ts +2 -0
  43. package/types/layouts/NavMenu.vue.d.ts +92 -23
  44. package/types/layouts/PropsPanel.vue.d.ts +25 -208
  45. package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
  46. package/types/layouts/sidebar/LayerPanel.vue.d.ts +17 -15
  47. package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
  48. package/types/services/componentList.d.ts +1 -0
  49. package/types/services/editor.d.ts +7 -9
  50. package/types/services/events.d.ts +1 -0
  51. package/types/services/props.d.ts +41 -9
  52. package/types/services/storage.d.ts +1 -0
  53. package/types/services/ui.d.ts +3 -1
  54. package/types/type.d.ts +25 -11
  55. package/types/utils/index.d.ts +1 -0
  56. package/types/utils/operator.d.ts +1 -7
  57. package/types/utils/props.d.ts +0 -1
  58. package/types/utils/scroll-viewer.d.ts +16 -18
  59. package/types/utils/stage.d.ts +3 -0
@@ -1,9 +1,9 @@
1
- import { defineComponent, computed, resolveComponent, openBlock, createBlock, normalizeStyle, ref, watchEffect, inject, createElementBlock, createVNode, unref, withCtx, withModifiers, createCommentVNode, createTextVNode, toDisplayString, watch, onMounted, onUnmounted, reactive, toRaw, createElementVNode, renderSlot, Fragment, normalizeClass, resolveDynamicComponent, markRaw, renderList, normalizeProps, mergeProps, getCurrentInstance, Teleport, nextTick, toHandlers, createSlots, provide } from 'vue';
1
+ import { defineComponent, computed, resolveComponent, openBlock, createBlock, normalizeStyle, ref, watchEffect, inject, createElementBlock, createVNode, unref, withCtx, withModifiers, createCommentVNode, createTextVNode, toDisplayString, watch, onMounted, onUnmounted, reactive, toRaw, createElementVNode, renderSlot, Fragment, normalizeClass, resolveDynamicComponent, renderList, normalizeProps, mergeProps, markRaw, getCurrentInstance, Teleport, nextTick, toHandlers, createSlots, provide } from 'vue';
2
2
  import serialize from 'serialize-javascript';
3
- import { Delete, Close, Plus, Edit, Grid, ScaleToOriginal, ZoomOut, ZoomIn, Right, Back, ArrowDown, Files, DocumentCopy, Coin, ArrowLeftBold, ArrowRightBold, CaretBottom, Top, Bottom } from '@element-plus/icons-vue';
3
+ import { Delete, Close, Plus, Edit, ArrowDown, Grid, Memo, FullScreen, ScaleToOriginal, ZoomOut, ZoomIn, Right, Back, Files, DocumentCopy, Coin, ArrowLeftBold, ArrowRightBold, CaretBottom, Top, Bottom } from '@element-plus/icons-vue';
4
4
  import { throttle, cloneDeep, mergeWith, isEmpty, uniq } from 'lodash-es';
5
5
  import * as monaco from 'monaco-editor';
6
- import StageCore, { GuidesType, getOffset, calcValueByFontsize, CONTAINER_HIGHLIGHT_CLASS } from '@tmagic/stage';
6
+ import StageCore, { GuidesType, getOffset, calcValueByFontsize, CONTAINER_HIGHLIGHT_CLASS, ContainerHighlightType } from '@tmagic/stage';
7
7
  import { NodeType } from '@tmagic/schema';
8
8
  import { isPop, getNodePath, isNumber, isPage, toLine, removeClassNameByClassName } from '@tmagic/utils';
9
9
  import { EventEmitter } from 'events';
@@ -19,7 +19,7 @@ if (typeof globalThis === "undefined") {
19
19
  window.globalThis = window;
20
20
  }
21
21
 
22
- const _sfc_main$n = defineComponent({
22
+ const _sfc_main$o = defineComponent({
23
23
  name: "m-fields-vs-code",
24
24
  props: ["model", "name", "config", "prop"],
25
25
  emits: ["change"],
@@ -45,7 +45,7 @@ const _export_sfc = (sfc, props) => {
45
45
  return target;
46
46
  };
47
47
 
48
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
48
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
49
49
  const _component_magic_code_editor = resolveComponent("magic-code-editor");
50
50
  return openBlock(), createBlock(_component_magic_code_editor, {
51
51
  style: normalizeStyle(`height: ${_ctx.height}`),
@@ -54,9 +54,9 @@ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
54
54
  onSave: _ctx.save
55
55
  }, null, 8, ["style", "init-values", "language", "onSave"]);
56
56
  }
57
- const Code = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$g]]);
57
+ const Code = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render$b]]);
58
58
 
59
- const _sfc_main$m = defineComponent({
59
+ const _sfc_main$n = defineComponent({
60
60
  name: "m-fields-code-link",
61
61
  props: {
62
62
  config: {
@@ -112,7 +112,7 @@ const _sfc_main$m = defineComponent({
112
112
  }
113
113
  });
114
114
 
115
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
115
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
116
116
  const _component_m_fields_link = resolveComponent("m-fields-link");
117
117
  return openBlock(), createBlock(_component_m_fields_link, {
118
118
  config: _ctx.formConfig,
@@ -121,10 +121,10 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
121
121
  onChange: _ctx.changeHandler
122
122
  }, null, 8, ["config", "model", "onChange"]);
123
123
  }
124
- const CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$f]]);
124
+ const CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$a]]);
125
125
 
126
- const _hoisted_1$d = /* @__PURE__ */ createTextVNode("\u53D6\u6D88");
127
- const _sfc_main$l = /* @__PURE__ */ defineComponent({
126
+ const _hoisted_1$b = /* @__PURE__ */ createTextVNode("\u53D6\u6D88");
127
+ const _sfc_main$m = /* @__PURE__ */ defineComponent({
128
128
  __name: "UISelect",
129
129
  props: {
130
130
  config: null,
@@ -189,7 +189,7 @@ const _sfc_main$l = /* @__PURE__ */ defineComponent({
189
189
  style: { "padding": "0" }
190
190
  }, {
191
191
  default: withCtx(() => [
192
- _hoisted_1$d
192
+ _hoisted_1$b
193
193
  ]),
194
194
  _: 1
195
195
  }, 8, ["icon"])
@@ -199,19 +199,21 @@ const _sfc_main$l = /* @__PURE__ */ defineComponent({
199
199
  onClick: startSelect,
200
200
  style: { "display": "flex" }
201
201
  }, [
202
- createVNode(_component_el_tooltip, { content: "\u6E05\u9664" }, {
202
+ unref(val) ? (openBlock(), createBlock(_component_el_tooltip, {
203
+ key: 0,
204
+ content: "\u6E05\u9664"
205
+ }, {
203
206
  default: withCtx(() => [
204
- unref(val) ? (openBlock(), createBlock(_component_el_button, {
205
- key: 0,
207
+ createVNode(_component_el_button, {
206
208
  style: { "padding": "0" },
207
209
  type: "danger",
208
210
  icon: unref(Close),
209
211
  text: "",
210
212
  onClick: withModifiers(deleteHandler, ["stop"])
211
- }, null, 8, ["icon", "onClick"])) : createCommentVNode("", true)
213
+ }, null, 8, ["icon", "onClick"])
212
214
  ]),
213
215
  _: 1
214
- }),
216
+ })) : createCommentVNode("", true),
215
217
  createVNode(_component_el_tooltip, {
216
218
  content: unref(val) ? unref(toName) + "_" + unref(val) : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"
217
219
  }, {
@@ -250,7 +252,7 @@ const toString = (v, language) => {
250
252
  }
251
253
  return value;
252
254
  };
253
- const _sfc_main$k = defineComponent({
255
+ const _sfc_main$l = defineComponent({
254
256
  name: "magic-code-editor",
255
257
  props: {
256
258
  initValues: {
@@ -358,14 +360,14 @@ const _sfc_main$k = defineComponent({
358
360
  }
359
361
  });
360
362
 
361
- const _hoisted_1$c = {
363
+ const _hoisted_1$a = {
362
364
  ref: "codeEditor",
363
365
  class: "magic-code-editor"
364
366
  };
365
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
366
- return openBlock(), createElementBlock("div", _hoisted_1$c, null, 512);
367
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
368
+ return openBlock(), createElementBlock("div", _hoisted_1$a, null, 512);
367
369
  }
368
- const CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$e]]);
370
+ const CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$9]]);
369
371
 
370
372
  let $TMAGIC_EDITOR = {};
371
373
  const setConfig = (option) => {
@@ -673,6 +675,9 @@ class WebStorage extends BaseService {
673
675
  }
674
676
  storage2.setItem(`${options2.namespace || namespace2}:${key2}`, item2);
675
677
  }
678
+ destroy() {
679
+ this.removeAllListeners();
680
+ }
676
681
  getValueAndProtocol(value) {
677
682
  let protocol2 = "";
678
683
  if (value === null) {
@@ -693,6 +698,12 @@ class WebStorage extends BaseService {
693
698
  }
694
699
  const storageService = new WebStorage();
695
700
 
701
+ var ColumnLayout = /* @__PURE__ */ ((ColumnLayout2) => {
702
+ ColumnLayout2["LEFT"] = "left";
703
+ ColumnLayout2["CENTER"] = "center";
704
+ ColumnLayout2["RIGHT"] = "right";
705
+ return ColumnLayout2;
706
+ })(ColumnLayout || {});
696
707
  var LayerOffset = /* @__PURE__ */ ((LayerOffset2) => {
697
708
  LayerOffset2["TOP"] = "top";
698
709
  LayerOffset2["BOTTOM"] = "bottom";
@@ -877,6 +888,7 @@ class Props extends BaseService {
877
888
  "getPropsValue",
878
889
  "createId",
879
890
  "setNewItemId",
891
+ "fillConfig",
880
892
  "getDefaultPropsValue"
881
893
  ]);
882
894
  }
@@ -886,14 +898,17 @@ class Props extends BaseService {
886
898
  });
887
899
  this.emit("props-configs-change");
888
900
  }
889
- setPropsConfig(type, config) {
890
- this.state.propsConfigMap[type] = fillConfig(Array.isArray(config) ? config : [config]);
901
+ async fillConfig(config) {
902
+ return fillConfig(config);
903
+ }
904
+ async setPropsConfig(type, config) {
905
+ this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
891
906
  }
892
907
  async getPropsConfig(type) {
893
908
  if (type === "area") {
894
909
  return await this.getPropsConfig("button");
895
910
  }
896
- return cloneDeep(this.state.propsConfigMap[type] || DEFAULT_CONFIG);
911
+ return cloneDeep(this.state.propsConfigMap[type] || await this.fillConfig([]));
897
912
  }
898
913
  setPropsValues(values) {
899
914
  Object.keys(values).forEach((type) => {
@@ -927,25 +942,14 @@ class Props extends BaseService {
927
942
  ...mergeWith({}, cloneDeep(this.state.propsValueMap[type] || {}), data)
928
943
  };
929
944
  }
930
- guid(digit = 8) {
931
- return "x".repeat(digit).replace(/[xy]/g, (c) => {
932
- const r = Math.random() * 16 | 0;
933
- const v = c == "x" ? r : r & 3 | 8;
934
- return v.toString(16);
935
- });
936
- }
937
945
  async createId(type) {
938
946
  return `${type}_${this.guid()}`;
939
947
  }
940
- async setNewItemId(config, parent) {
941
- const oldId = config.id;
948
+ async setNewItemId(config) {
942
949
  config.id = await this.createId(config.type || "component");
943
- if (isPop(config) && parent?.type === NodeType.PAGE) {
944
- updatePopId(oldId, config.id, parent);
945
- }
946
950
  if (config.items && Array.isArray(config.items)) {
947
951
  for (const item of config.items) {
948
- await this.setNewItemId(item, config);
952
+ await this.setNewItemId(item);
949
953
  }
950
954
  }
951
955
  return config;
@@ -963,22 +967,19 @@ class Props extends BaseService {
963
967
  name: type
964
968
  };
965
969
  }
970
+ destroy() {
971
+ this.state.propsConfigMap = {};
972
+ this.state.propsValueMap = {};
973
+ this.removeAllListeners();
974
+ }
975
+ guid(digit = 8) {
976
+ return "x".repeat(digit).replace(/[xy]/g, (c) => {
977
+ const r = Math.random() * 16 | 0;
978
+ const v = c === "x" ? r : r & 3 | 8;
979
+ return v.toString(16);
980
+ });
981
+ }
966
982
  }
967
- const updatePopId = (oldId, popId, pageConfig) => {
968
- pageConfig.items?.forEach((config) => {
969
- if (config.pop === oldId) {
970
- config.pop = popId;
971
- return;
972
- }
973
- if (config.popId === oldId) {
974
- config.popId = popId;
975
- return;
976
- }
977
- if (Array.isArray(config.items)) {
978
- updatePopId(oldId, popId, config);
979
- }
980
- });
981
- };
982
983
  const propsService = new Props();
983
984
 
984
985
  const beforePaste = async (position, config) => {
@@ -998,7 +999,7 @@ const beforePaste = async (position, config) => {
998
999
  if (pastePosition.top && configItem.style?.top) {
999
1000
  pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
1000
1001
  }
1001
- const pasteConfig = await propsService.setNewItemId(configItem, editorService.get("root"));
1002
+ const pasteConfig = await propsService.setNewItemId(configItem);
1002
1003
  if (pasteConfig.style) {
1003
1004
  const { left, top } = pasteConfig.style;
1004
1005
  if (typeof left === "number" || !!left && !isNaN(Number(left))) {
@@ -1030,48 +1031,10 @@ const getPositionInContainer = (position = {}, id) => {
1030
1031
  top
1031
1032
  };
1032
1033
  };
1033
- const beforeRemove = async (node) => {
1034
- if (!node?.id)
1035
- return;
1036
- const stage = editorService.get("stage");
1037
- const root = editorService.get("root");
1038
- if (!root)
1039
- throw new Error("\u6CA1\u6709root");
1040
- const { parent, node: curNode } = editorService.getNodeInfo(node.id, false);
1041
- if (!parent || !curNode)
1042
- throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1043
- const index = getNodeIndex(curNode, parent);
1044
- if (typeof index !== "number" || index === -1)
1045
- throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1046
- parent.items?.splice(index, 1);
1047
- stage?.remove({ id: node.id, root: cloneDeep(root) });
1048
- if (node.type === NodeType.PAGE) {
1049
- editorService.state.pageLength -= 1;
1050
- if (root.items[0]) {
1051
- await editorService.select(root.items[0]);
1052
- stage?.select(root.items[0].id);
1053
- } else {
1054
- editorService.set("node", null);
1055
- editorService.set("nodes", []);
1056
- editorService.set("parent", null);
1057
- editorService.set("page", null);
1058
- editorService.set("stage", null);
1059
- editorService.set("highlightNode", null);
1060
- editorService.resetModifiedNodeId();
1061
- historyService.reset();
1062
- editorService.emit("remove", node);
1063
- return;
1064
- }
1065
- } else {
1066
- await editorService.select(parent);
1067
- stage?.select(parent.id);
1068
- }
1069
- return parent;
1070
- };
1071
- const getAddParent = (addNode) => {
1034
+ const getAddParent = (node) => {
1072
1035
  const curNode = editorService.get("node");
1073
1036
  let parentNode;
1074
- if (!Array.isArray(addNode) && isPage(addNode)) {
1037
+ if (isPage(node)) {
1075
1038
  parentNode = editorService.get("root");
1076
1039
  } else if (curNode.items) {
1077
1040
  parentNode = curNode;
@@ -1100,11 +1063,15 @@ class Editor$1 extends BaseService {
1100
1063
  "select",
1101
1064
  "doAdd",
1102
1065
  "add",
1066
+ "doRemove",
1103
1067
  "remove",
1068
+ "doUpdate",
1104
1069
  "update",
1105
1070
  "sort",
1106
1071
  "copy",
1107
1072
  "paste",
1073
+ "doPaste",
1074
+ "duAlignCenter",
1108
1075
  "alignCenter",
1109
1076
  "moveLayer",
1110
1077
  "moveToContainer",
@@ -1240,20 +1207,27 @@ class Editor$1 extends BaseService {
1240
1207
  if ((parent?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
1241
1208
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
1242
1209
  }
1210
+ if (parent.id !== curNode.id) {
1211
+ const index = parent.items.indexOf(curNode);
1212
+ parent?.items?.splice(index + 1, 0, node);
1213
+ } else {
1214
+ parent?.items?.push(node);
1215
+ }
1243
1216
  const layout = await this.getLayout(toRaw(parent), node);
1244
1217
  node.style = getInitPositionStyle(node.style, layout);
1245
- await stage?.add({ config: cloneDeep(node), parent: cloneDeep(parent), root: cloneDeep(root) });
1218
+ await stage?.add({
1219
+ config: cloneDeep(node),
1220
+ parent: cloneDeep(parent),
1221
+ parentId: parent.id,
1222
+ root: cloneDeep(root)
1223
+ });
1246
1224
  node.style = fixNodePosition(node, parent, stage);
1247
- await stage?.update({ config: cloneDeep(node), root: cloneDeep(root) });
1248
- parent?.items?.push(node);
1225
+ await stage?.update({ config: cloneDeep(node), parentId: parent.id, root: cloneDeep(root) });
1249
1226
  this.addModifiedNodeId(node.id);
1250
1227
  return node;
1251
1228
  }
1252
1229
  async add(addNode, parent) {
1253
1230
  const stage = this.get("stage");
1254
- const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(addNode);
1255
- if (!parentNode)
1256
- throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
1257
1231
  const addNodes = [];
1258
1232
  if (!Array.isArray(addNode)) {
1259
1233
  const { type, inputEvent, ...config } = addNode;
@@ -1263,7 +1237,12 @@ class Editor$1 extends BaseService {
1263
1237
  } else {
1264
1238
  addNodes.push(...addNode);
1265
1239
  }
1266
- const newNodes = await Promise.all(addNodes.map((node) => this.doAdd(node, parentNode)));
1240
+ const newNodes = await Promise.all(addNodes.map((node) => {
1241
+ const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(node);
1242
+ if (!parentNode)
1243
+ throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
1244
+ return this.doAdd(node, parentNode);
1245
+ }));
1267
1246
  if (newNodes.length > 1) {
1268
1247
  const newNodeIds = newNodes.map((node) => node.id);
1269
1248
  stage?.multiSelect(newNodeIds);
@@ -1278,33 +1257,49 @@ class Editor$1 extends BaseService {
1278
1257
  }
1279
1258
  this.pushHistoryState();
1280
1259
  this.emit("add", newNodes);
1281
- return newNodes.length > 1 ? newNodes[0] : newNodes;
1260
+ return Array.isArray(addNode) ? newNodes : newNodes[0];
1282
1261
  }
1283
- async remove(nodeOrNodeList) {
1284
- if (Array.isArray(nodeOrNodeList)) {
1285
- const nodes = nodeOrNodeList;
1286
- return this.multiRemove(nodes);
1262
+ async doRemove(node) {
1263
+ const root = this.get("root");
1264
+ if (!root)
1265
+ throw new Error("\u6CA1\u6709root");
1266
+ const { parent, node: curNode } = this.getNodeInfo(node.id);
1267
+ if (!parent || !curNode)
1268
+ throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1269
+ const index = getNodeIndex(curNode, parent);
1270
+ if (typeof index !== "number" || index === -1)
1271
+ throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1272
+ parent.items?.splice(index, 1);
1273
+ const stage = this.get("stage");
1274
+ stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
1275
+ if (node.type === NodeType.PAGE) {
1276
+ this.state.pageLength -= 1;
1277
+ if (root.items[0]) {
1278
+ await this.select(root.items[0]);
1279
+ stage?.select(root.items[0].id);
1280
+ } else {
1281
+ this.set("nodes", [root]);
1282
+ this.set("parent", null);
1283
+ this.set("page", null);
1284
+ this.set("stage", null);
1285
+ this.set("highlightNode", null);
1286
+ this.resetModifiedNodeId();
1287
+ historyService.reset();
1288
+ return;
1289
+ }
1290
+ } else {
1291
+ await this.select(parent);
1292
+ stage?.select(parent.id);
1287
1293
  }
1288
- const node = nodeOrNodeList;
1289
- const removeParent = await beforeRemove(node);
1290
- if (!removeParent)
1291
- return node;
1292
- this.addModifiedNodeId(removeParent.id);
1293
- this.pushHistoryState();
1294
- this.emit("remove", node);
1295
- return node;
1294
+ this.addModifiedNodeId(parent.id);
1296
1295
  }
1297
- async multiRemove(nodes) {
1298
- await Promise.all(nodes.map(async (removeNode) => {
1299
- await beforeRemove(removeNode);
1300
- }));
1301
- const nodeIds = nodes.map((node) => node.id);
1302
- this.addModifiedNodeId(nodeIds.join("-"));
1296
+ async remove(nodeOrNodeList) {
1297
+ const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
1298
+ await Promise.all(nodes.map((node) => this.doRemove(node)));
1303
1299
  this.pushHistoryState();
1304
- this.emit("multiRemove", nodes);
1305
- return nodes;
1300
+ this.emit("remove", nodes);
1306
1301
  }
1307
- async update(config) {
1302
+ async doUpdate(config) {
1308
1303
  if (!config?.id)
1309
1304
  throw new Error("\u6CA1\u6709\u914D\u7F6E\u6216\u8005\u914D\u7F6E\u7F3A\u5C11id\u503C");
1310
1305
  const info = this.getNodeInfo(config.id, false);
@@ -1340,15 +1335,24 @@ class Editor$1 extends BaseService {
1340
1335
  const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
1341
1336
  nodes.splice(targetIndex, 1, newConfig);
1342
1337
  this.set("nodes", nodes);
1343
- this.get("stage")?.update({ config: cloneDeep(newConfig), root: cloneDeep(this.get("root")) });
1338
+ this.get("stage")?.update({
1339
+ config: cloneDeep(newConfig),
1340
+ parentId: parent.id,
1341
+ root: cloneDeep(this.get("root"))
1342
+ });
1344
1343
  if (newConfig.type === NodeType.PAGE) {
1345
1344
  this.set("page", newConfig);
1346
1345
  }
1347
1346
  this.addModifiedNodeId(newConfig.id);
1348
- this.pushHistoryState();
1349
- this.emit("update", newConfig);
1350
1347
  return newConfig;
1351
1348
  }
1349
+ async update(config) {
1350
+ const nodes = Array.isArray(config) ? config : [config];
1351
+ const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
1352
+ this.pushHistoryState();
1353
+ this.emit("update", newNodes);
1354
+ return Array.isArray(config) ? newNodes : newNodes[0];
1355
+ }
1352
1356
  async sort(id1, id2) {
1353
1357
  const node = this.get("node");
1354
1358
  const parent = cloneDeep(toRaw(this.get("parent")));
@@ -1359,7 +1363,11 @@ class Editor$1 extends BaseService {
1359
1363
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
1360
1364
  await this.update(parent);
1361
1365
  await this.select(node);
1362
- this.get("stage")?.update({ config: cloneDeep(node), root: cloneDeep(this.get("root")) });
1366
+ this.get("stage")?.update({
1367
+ config: cloneDeep(node),
1368
+ parentId: parent.id,
1369
+ root: cloneDeep(this.get("root"))
1370
+ });
1363
1371
  this.addModifiedNodeId(parent.id);
1364
1372
  this.pushHistoryState();
1365
1373
  }
@@ -1372,18 +1380,24 @@ class Editor$1 extends BaseService {
1372
1380
  const config = await storageService.getItem(COPY_STORAGE_KEY);
1373
1381
  if (!Array.isArray(config))
1374
1382
  return;
1375
- const pasteConfigs = await beforePaste(position, config);
1383
+ const pasteConfigs = await this.doPaste(config, position);
1376
1384
  return this.add(pasteConfigs);
1377
1385
  }
1378
- async alignCenter(config) {
1379
- const parent = this.get("parent");
1380
- const node = this.get("node");
1381
- const layout = await this.getLayout(toRaw(parent), toRaw(node));
1386
+ async doPaste(config, position = {}) {
1387
+ const pasteConfigs = await beforePaste(position, cloneDeep(config));
1388
+ return pasteConfigs;
1389
+ }
1390
+ async doAlignCenter(config) {
1391
+ const parent = this.getParentById(config.id);
1392
+ if (!parent)
1393
+ throw new Error("\u627E\u4E0D\u5230\u7236\u8282\u70B9");
1394
+ const node = cloneDeep(toRaw(config));
1395
+ const layout = await this.getLayout(parent, node);
1382
1396
  if (layout === Layout.RELATIVE) {
1383
- return;
1397
+ return config;
1384
1398
  }
1385
1399
  if (!node.style)
1386
- return;
1400
+ return config;
1387
1401
  const stage = this.get("stage");
1388
1402
  const doc = stage?.renderer.contentWindow?.document;
1389
1403
  if (doc) {
@@ -1395,14 +1409,15 @@ class Editor$1 extends BaseService {
1395
1409
  } else if (parent.style && isNumber(parent.style?.width) && isNumber(node.style?.width)) {
1396
1410
  node.style.left = (parent.style.width - node.style.width) / 2;
1397
1411
  }
1398
- await this.update(node);
1399
- this.get("stage")?.update({
1400
- config: cloneDeep(toRaw(node)),
1401
- root: cloneDeep(this.get("root"))
1402
- });
1403
- this.addModifiedNodeId(config.id);
1404
- this.pushHistoryState();
1405
- return config;
1412
+ return node;
1413
+ }
1414
+ async alignCenter(config) {
1415
+ const nodes = Array.isArray(config) ? config : [config];
1416
+ const stage = this.get("stage");
1417
+ const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
1418
+ const newNode = await this.update(newNodes);
1419
+ await stage?.multiSelect(newNodes.map((node) => node.id));
1420
+ return newNode;
1406
1421
  }
1407
1422
  async moveLayer(offset) {
1408
1423
  const parent = this.get("parent");
@@ -1416,10 +1431,14 @@ class Editor$1 extends BaseService {
1416
1431
  } else {
1417
1432
  brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
1418
1433
  }
1434
+ const grandparent = this.getParentById(parent.id);
1419
1435
  this.get("stage")?.update({
1420
1436
  config: cloneDeep(toRaw(parent)),
1437
+ parentId: grandparent?.id,
1421
1438
  root: cloneDeep(this.get("root"))
1422
1439
  });
1440
+ this.addModifiedNodeId(parent.id);
1441
+ this.pushHistoryState();
1423
1442
  }
1424
1443
  async moveToContainer(config, targetId) {
1425
1444
  const { node, parent } = this.getNodeInfo(config.id, false);
@@ -1429,7 +1448,7 @@ class Editor$1 extends BaseService {
1429
1448
  const root = cloneDeep(this.get("root"));
1430
1449
  const index = getNodeIndex(node, parent);
1431
1450
  parent.items?.splice(index, 1);
1432
- await stage.remove({ id: node.id, root });
1451
+ await stage.remove({ id: node.id, parentId: parent.id, root });
1433
1452
  const layout = await this.getLayout(target);
1434
1453
  const newConfig = mergeWith(cloneDeep(node), config, (objValue, srcValue) => {
1435
1454
  if (Array.isArray(srcValue)) {
@@ -1439,7 +1458,8 @@ class Editor$1 extends BaseService {
1439
1458
  newConfig.style = getInitPositionStyle(newConfig.style, layout);
1440
1459
  target.items.push(newConfig);
1441
1460
  await stage.select(targetId);
1442
- await stage.update({ config: cloneDeep(target), root });
1461
+ const targetParent = this.getParentById(target.id);
1462
+ await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root });
1443
1463
  await this.select(newConfig);
1444
1464
  stage.select(newConfig.id);
1445
1465
  this.addModifiedNodeId(target.id);
@@ -1486,6 +1506,10 @@ class Editor$1 extends BaseService {
1486
1506
  this.set("nodes", []);
1487
1507
  this.set("page", null);
1488
1508
  this.set("parent", null);
1509
+ this.set("stage", null);
1510
+ this.set("highlightNode", null);
1511
+ this.set("modifiedNodeIds", /* @__PURE__ */ new Map());
1512
+ this.set("pageLength", /* @__PURE__ */ new Map());
1489
1513
  }
1490
1514
  resetModifiedNodeId() {
1491
1515
  this.get("modifiedNodeIds").clear();
@@ -1555,8 +1579,8 @@ class Editor$1 extends BaseService {
1555
1579
  }
1556
1580
  const editorService = new Editor$1();
1557
1581
 
1558
- const eventMap = reactive({});
1559
- const methodMap = reactive({});
1582
+ let eventMap = reactive({});
1583
+ let methodMap = reactive({});
1560
1584
  class Events extends BaseService {
1561
1585
  constructor() {
1562
1586
  super([]);
@@ -1596,6 +1620,11 @@ class Events extends BaseService {
1596
1620
  getMethod(type) {
1597
1621
  return cloneDeep(methodMap[type] || DEFAULT_METHODS);
1598
1622
  }
1623
+ destroy() {
1624
+ eventMap = reactive({});
1625
+ methodMap = reactive({});
1626
+ this.removeAllListeners();
1627
+ }
1599
1628
  }
1600
1629
  const eventsService = new Events();
1601
1630
 
@@ -1802,7 +1831,6 @@ const fillConfig = (config = []) => [
1802
1831
  ]
1803
1832
  }
1804
1833
  ];
1805
- const DEFAULT_CONFIG = fillConfig([]);
1806
1834
 
1807
1835
  const log = (...args) => {
1808
1836
  if (process.env.NODE_ENV === "development") {
@@ -1830,7 +1858,194 @@ const error = (...args) => {
1830
1858
  }
1831
1859
  };
1832
1860
 
1833
- const _sfc_main$j = defineComponent({
1861
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
1862
+ const MIN_LEFT_COLUMN_WIDTH = 45;
1863
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
1864
+ const MIN_RIGHT_COLUMN_WIDTH = 1;
1865
+ const COLUMN_WIDTH_STORAGE_KEY = "$MagicEditorColumnWidthData";
1866
+ const defaultColumnWidth = {
1867
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
1868
+ center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
1869
+ right: DEFAULT_RIGHT_COLUMN_WIDTH
1870
+ };
1871
+ const state = reactive({
1872
+ uiSelectMode: false,
1873
+ showSrc: false,
1874
+ zoom: 1,
1875
+ stageContainerRect: {
1876
+ width: 0,
1877
+ height: 0
1878
+ },
1879
+ stageRect: {
1880
+ width: 375,
1881
+ height: 817
1882
+ },
1883
+ columnWidth: defaultColumnWidth,
1884
+ showGuides: true,
1885
+ showRule: true,
1886
+ propsPanelSize: "small"
1887
+ });
1888
+ class Ui extends BaseService {
1889
+ constructor() {
1890
+ super([]);
1891
+ globalThis.addEventListener("resize", () => {
1892
+ this.setColumnWidth({
1893
+ center: "auto"
1894
+ });
1895
+ });
1896
+ }
1897
+ set(name, value) {
1898
+ const mask = editorService.get("stage")?.mask;
1899
+ if (name === "columnWidth") {
1900
+ this.setColumnWidth(value);
1901
+ return;
1902
+ }
1903
+ if (name === "stageRect") {
1904
+ this.setStageRect(value);
1905
+ return;
1906
+ }
1907
+ if (name === "showGuides") {
1908
+ mask?.showGuides(value);
1909
+ }
1910
+ if (name === "showRule") {
1911
+ mask?.showRule(value);
1912
+ }
1913
+ state[name] = value;
1914
+ }
1915
+ get(name) {
1916
+ return state[name];
1917
+ }
1918
+ initColumnWidth() {
1919
+ const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
1920
+ if (columnWidthCacheData) {
1921
+ try {
1922
+ const columnWidthCache = JSON.parse(columnWidthCacheData);
1923
+ this.setColumnWidth(columnWidthCache);
1924
+ } catch (e) {
1925
+ console.error(e);
1926
+ }
1927
+ }
1928
+ }
1929
+ zoom(zoom) {
1930
+ this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
1931
+ if (this.get("zoom") < 0.1)
1932
+ this.set("zoom", 0.1);
1933
+ }
1934
+ calcZoom() {
1935
+ const { stageRect, stageContainerRect } = state;
1936
+ const { height, width } = stageContainerRect;
1937
+ if (!width || !height)
1938
+ return 1;
1939
+ const stageWidth = stageRect.width + 30;
1940
+ const stageHeight = stageRect.height + 30;
1941
+ if (width > stageWidth && height > stageHeight) {
1942
+ return 1;
1943
+ }
1944
+ return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
1945
+ }
1946
+ destroy() {
1947
+ this.removeAllListeners();
1948
+ }
1949
+ setColumnWidth({ left, center, right }) {
1950
+ const columnWidth = {
1951
+ ...toRaw(this.get("columnWidth"))
1952
+ };
1953
+ if (left) {
1954
+ columnWidth.left = Math.max(left, MIN_LEFT_COLUMN_WIDTH);
1955
+ }
1956
+ if (right) {
1957
+ columnWidth.right = Math.max(right, MIN_RIGHT_COLUMN_WIDTH);
1958
+ }
1959
+ if (!center || center === "auto") {
1960
+ const bodyWidth = globalThis.document.body.clientWidth;
1961
+ columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
1962
+ if (columnWidth.center <= 0) {
1963
+ columnWidth.left = defaultColumnWidth.left;
1964
+ columnWidth.center = defaultColumnWidth.center;
1965
+ columnWidth.right = defaultColumnWidth.right;
1966
+ }
1967
+ } else {
1968
+ columnWidth.center = center;
1969
+ }
1970
+ globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
1971
+ state.columnWidth = columnWidth;
1972
+ }
1973
+ setStageRect(value) {
1974
+ state.stageRect = {
1975
+ ...state.stageRect,
1976
+ ...value
1977
+ };
1978
+ state.zoom = this.calcZoom();
1979
+ }
1980
+ }
1981
+ const uiService = new Ui();
1982
+
1983
+ const root = computed(() => editorService.get("root"));
1984
+ const page = computed(() => editorService.get("page"));
1985
+ const zoom = computed(() => uiService.get("zoom") || 1);
1986
+ const uiSelectMode = computed(() => uiService.get("uiSelectMode"));
1987
+ const getGuideLineKey = (key) => `${key}_${root.value?.id}_${page.value?.id}`;
1988
+ const useStage = (stageOptions) => {
1989
+ const stage = new StageCore({
1990
+ render: stageOptions.render,
1991
+ runtimeUrl: stageOptions.runtimeUrl,
1992
+ zoom: zoom.value,
1993
+ autoScrollIntoView: stageOptions.autoScrollIntoView,
1994
+ isContainer: stageOptions.isContainer,
1995
+ containerHighlightClassName: stageOptions.containerHighlightClassName,
1996
+ containerHighlightDuration: stageOptions.containerHighlightDuration,
1997
+ containerHighlightType: stageOptions.containerHighlightType,
1998
+ canSelect: (el, event, stop) => {
1999
+ const elCanSelect = stageOptions.canSelect(el);
2000
+ if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
2001
+ document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
2002
+ return stop();
2003
+ }
2004
+ return elCanSelect;
2005
+ },
2006
+ moveableOptions: stageOptions.moveableOptions,
2007
+ updateDragEl: stageOptions.updateDragEl
2008
+ });
2009
+ stage.mask.setGuides([
2010
+ getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
2011
+ getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
2012
+ ]);
2013
+ stage.on("select", (el) => {
2014
+ editorService.select(el.id);
2015
+ });
2016
+ stage.on("highlight", (el) => {
2017
+ editorService.highlight(el.id);
2018
+ });
2019
+ stage.on("multiSelect", (els) => {
2020
+ editorService.multiSelect(els.map((el) => el.id));
2021
+ });
2022
+ stage.on("update", (ev) => {
2023
+ if (ev.parentEl) {
2024
+ for (const data of ev.data) {
2025
+ editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
2026
+ }
2027
+ return;
2028
+ }
2029
+ editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
2030
+ });
2031
+ stage.on("sort", (ev) => {
2032
+ editorService.sort(ev.src, ev.dist);
2033
+ });
2034
+ stage.on("changeGuides", (e) => {
2035
+ uiService.set("showGuides", true);
2036
+ if (!root.value || !page.value)
2037
+ return;
2038
+ const storageKey = getGuideLineKey(e.type === GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY);
2039
+ if (e.guides.length) {
2040
+ globalThis.localStorage.setItem(storageKey, JSON.stringify(e.guides));
2041
+ } else {
2042
+ globalThis.localStorage.removeItem(storageKey);
2043
+ }
2044
+ });
2045
+ return stage;
2046
+ };
2047
+
2048
+ const _sfc_main$k = defineComponent({
1834
2049
  components: { Plus },
1835
2050
  setup() {
1836
2051
  const services = inject("services");
@@ -1848,13 +2063,13 @@ const _sfc_main$j = defineComponent({
1848
2063
  }
1849
2064
  });
1850
2065
 
1851
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
2066
+ const _hoisted_1$9 = { class: "m-editor-empty-panel" };
1852
2067
  const _hoisted_2$4 = { class: "m-editor-empty-content" };
1853
- const _hoisted_3$1 = /* @__PURE__ */ createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1854
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2068
+ const _hoisted_3 = /* @__PURE__ */ createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
2069
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
1855
2070
  const _component_plus = resolveComponent("plus");
1856
2071
  const _component_el_icon = resolveComponent("el-icon");
1857
- return openBlock(), createElementBlock("div", _hoisted_1$b, [
2072
+ return openBlock(), createElementBlock("div", _hoisted_1$9, [
1858
2073
  createElementVNode("div", _hoisted_2$4, [
1859
2074
  createElementVNode("div", {
1860
2075
  class: "m-editor-empty-button",
@@ -1868,14 +2083,14 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
1868
2083
  _: 1
1869
2084
  })
1870
2085
  ]),
1871
- _hoisted_3$1
2086
+ _hoisted_3
1872
2087
  ])
1873
2088
  ])
1874
2089
  ]);
1875
2090
  }
1876
- const AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$d]]);
2091
+ const AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$8]]);
1877
2092
 
1878
- const _sfc_main$i = defineComponent({
2093
+ const _sfc_main$j = defineComponent({
1879
2094
  name: "m-editor-resize",
1880
2095
  props: {
1881
2096
  type: {
@@ -1918,18 +2133,18 @@ const _sfc_main$i = defineComponent({
1918
2133
  }
1919
2134
  });
1920
2135
 
1921
- const _hoisted_1$a = {
2136
+ const _hoisted_1$8 = {
1922
2137
  ref: "target",
1923
2138
  class: "m-editor-resizer"
1924
2139
  };
1925
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
1926
- return openBlock(), createElementBlock("span", _hoisted_1$a, [
2140
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2141
+ return openBlock(), createElementBlock("span", _hoisted_1$8, [
1927
2142
  renderSlot(_ctx.$slots, "default")
1928
2143
  ], 512);
1929
2144
  }
1930
- const Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$c]]);
2145
+ const Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$7]]);
1931
2146
 
1932
- const _sfc_main$h = defineComponent({
2147
+ const _sfc_main$i = defineComponent({
1933
2148
  components: {
1934
2149
  AddPageBox,
1935
2150
  Resizer
@@ -1959,17 +2174,17 @@ const _sfc_main$h = defineComponent({
1959
2174
  }
1960
2175
  });
1961
2176
 
1962
- const _hoisted_1$9 = { class: "m-editor" };
2177
+ const _hoisted_1$7 = { class: "m-editor" };
1963
2178
  const _hoisted_2$3 = {
1964
2179
  key: 1,
1965
2180
  class: "m-editor-content"
1966
2181
  };
1967
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2182
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
1968
2183
  const _component_magic_code_editor = resolveComponent("magic-code-editor");
1969
2184
  const _component_resizer = resolveComponent("resizer");
1970
2185
  const _component_el_scrollbar = resolveComponent("el-scrollbar");
1971
2186
  const _component_add_page_box = resolveComponent("add-page-box");
1972
- return openBlock(), createElementBlock("div", _hoisted_1$9, [
2187
+ return openBlock(), createElementBlock("div", _hoisted_1$7, [
1973
2188
  renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
1974
2189
  _ctx.showSrc ? (openBlock(), createBlock(_component_magic_code_editor, {
1975
2190
  key: 0,
@@ -2010,211 +2225,112 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2010
2225
  ]))
2011
2226
  ]);
2012
2227
  }
2013
- const Framework = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$b]]);
2228
+ const Framework = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$6]]);
2014
2229
 
2015
- const _sfc_main$g = defineComponent({
2016
- name: "m-icon",
2017
- components: { Edit },
2230
+ const _hoisted_1$6 = ["src"];
2231
+ const _sfc_main$h = /* @__PURE__ */ defineComponent({
2232
+ __name: "Icon",
2018
2233
  props: {
2019
- icon: {
2020
- type: [String, Object]
2021
- }
2234
+ icon: null
2022
2235
  },
2023
- setup() {
2024
- return {
2025
- toRaw
2026
- };
2027
- }
2028
- });
2029
-
2030
- const _hoisted_1$8 = ["src"];
2031
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2032
- const _component_edit = resolveComponent("edit");
2033
- const _component_el_icon = resolveComponent("el-icon");
2034
- return !_ctx.icon ? (openBlock(), createBlock(_component_el_icon, { key: 0 }, {
2035
- default: withCtx(() => [
2036
- createVNode(_component_edit)
2037
- ]),
2038
- _: 1
2039
- })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (openBlock(), createBlock(_component_el_icon, { key: 1 }, {
2040
- default: withCtx(() => [
2041
- createElementVNode("img", { src: _ctx.icon }, null, 8, _hoisted_1$8)
2042
- ]),
2043
- _: 1
2044
- })) : typeof _ctx.icon === "string" ? (openBlock(), createElementBlock("i", {
2045
- key: 2,
2046
- class: normalizeClass(_ctx.icon)
2047
- }, null, 2)) : (openBlock(), createBlock(_component_el_icon, { key: 3 }, {
2048
- default: withCtx(() => [
2049
- (openBlock(), createBlock(resolveDynamicComponent(_ctx.toRaw(_ctx.icon))))
2050
- ]),
2051
- _: 1
2052
- }));
2053
- }
2054
- const MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$a]]);
2236
+ setup(__props) {
2237
+ return (_ctx, _cache) => {
2238
+ const _component_el_icon = resolveComponent("el-icon");
2239
+ return !__props.icon ? (openBlock(), createBlock(_component_el_icon, { key: 0 }, {
2240
+ default: withCtx(() => [
2241
+ createVNode(unref(Edit))
2242
+ ]),
2243
+ _: 1
2244
+ })) : typeof __props.icon === "string" && __props.icon.startsWith("http") ? (openBlock(), createBlock(_component_el_icon, { key: 1 }, {
2245
+ default: withCtx(() => [
2246
+ createElementVNode("img", { src: __props.icon }, null, 8, _hoisted_1$6)
2247
+ ]),
2248
+ _: 1
2249
+ })) : typeof __props.icon === "string" ? (openBlock(), createElementBlock("i", {
2250
+ key: 2,
2251
+ class: normalizeClass(__props.icon)
2252
+ }, null, 2)) : (openBlock(), createBlock(_component_el_icon, { key: 3 }, {
2253
+ default: withCtx(() => [
2254
+ (openBlock(), createBlock(resolveDynamicComponent(toRaw(__props.icon))))
2255
+ ]),
2256
+ _: 1
2257
+ }));
2258
+ };
2259
+ }
2260
+ });
2055
2261
 
2056
- const _hoisted_1$7 = {
2262
+ const _hoisted_1$5 = {
2057
2263
  key: 1,
2058
2264
  class: "menu-item-text"
2059
2265
  };
2060
- const _hoisted_2$2 = {
2061
- class: "menu-item-text",
2062
- style: { "margin": "0 5px" }
2063
- };
2064
- const _hoisted_3 = { class: "el-dropdown-link menubar-menu-button" };
2065
- const _sfc_main$f = /* @__PURE__ */ defineComponent({
2266
+ const _hoisted_2$2 = { class: "el-dropdown-link menubar-menu-button" };
2267
+ const _sfc_main$g = /* @__PURE__ */ defineComponent({
2066
2268
  __name: "ToolButton",
2067
2269
  props: {
2068
- data: {
2069
- type: [Object, String],
2070
- require: true,
2071
- default: () => ({
2072
- type: "text",
2073
- display: false
2074
- })
2075
- },
2076
- eventType: {
2077
- type: String,
2078
- default: "click"
2079
- }
2270
+ data: { default: () => ({
2271
+ type: "text",
2272
+ display: false
2273
+ }) },
2274
+ eventType: { default: "click" }
2080
2275
  },
2081
2276
  setup(__props) {
2082
2277
  const props = __props;
2083
2278
  const services = inject("services");
2084
- const uiService = services?.uiService;
2085
- const zoom = computed(() => uiService?.get("zoom") ?? 1);
2086
- const showGuides = computed(() => uiService?.get("showGuides") ?? true);
2087
- const showRule = computed(() => uiService?.get("showRule") ?? true);
2088
- const zoomInHandler = () => uiService?.zoom(0.1);
2089
- const zoomOutHandler = () => uiService?.zoom(-0.1);
2090
- const item = computed(() => {
2091
- if (typeof props.data !== "string") {
2092
- return props.data;
2093
- }
2094
- switch (props.data) {
2095
- case "/":
2096
- return {
2097
- type: "divider"
2098
- };
2099
- case "zoom":
2100
- return {
2101
- type: "zoom"
2102
- };
2103
- case "delete":
2104
- return {
2105
- type: "button",
2106
- icon: markRaw(Delete),
2107
- tooltip: "\u522A\u9664",
2108
- disabled: () => services?.editorService.get("node")?.type === NodeType.PAGE,
2109
- handler: () => services?.editorService.remove(services?.editorService.get("node"))
2110
- };
2111
- case "undo":
2112
- return {
2113
- type: "button",
2114
- icon: markRaw(Back),
2115
- tooltip: "\u540E\u9000",
2116
- disabled: () => !services?.historyService.state.canUndo,
2117
- handler: () => services?.editorService.undo()
2118
- };
2119
- case "redo":
2120
- return {
2121
- type: "button",
2122
- icon: markRaw(Right),
2123
- tooltip: "\u524D\u8FDB",
2124
- disabled: () => !services?.historyService.state.canRedo,
2125
- handler: () => services?.editorService.redo()
2126
- };
2127
- case "zoom-in":
2128
- return {
2129
- type: "button",
2130
- icon: markRaw(ZoomIn),
2131
- tooltip: "\u653E\u5927",
2132
- handler: zoomInHandler
2133
- };
2134
- case "zoom-out":
2135
- return {
2136
- type: "button",
2137
- icon: markRaw(ZoomOut),
2138
- tooltip: "\u7E2E\u5C0F",
2139
- handler: zoomOutHandler
2140
- };
2141
- case "rule":
2142
- return {
2143
- type: "button",
2144
- icon: markRaw(ScaleToOriginal),
2145
- tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2146
- handler: () => uiService?.set("showRule", !showRule.value)
2147
- };
2148
- case "guides":
2149
- return {
2150
- type: "button",
2151
- icon: markRaw(Grid),
2152
- tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2153
- handler: () => uiService?.set("showGuides", !showGuides.value)
2154
- };
2155
- default:
2156
- return {
2157
- type: "text",
2158
- text: props.data
2159
- };
2160
- }
2161
- });
2162
2279
  const disabled = computed(() => {
2163
- if (typeof item.value === "string")
2280
+ if (typeof props.data === "string")
2164
2281
  return false;
2165
- if (item.value.type === "component")
2282
+ if (props.data.type === "component")
2166
2283
  return false;
2167
- if (typeof item.value.disabled === "function") {
2168
- return item.value.disabled(services);
2284
+ if (typeof props.data.disabled === "function") {
2285
+ return props.data.disabled(services);
2169
2286
  }
2170
- return item.value.disabled;
2287
+ return props.data.disabled;
2171
2288
  });
2172
- const buttonHandler = (item2, event) => {
2173
- if (disabled.value)
2174
- return;
2175
- if (typeof item2.handler === "function" && services) {
2176
- item2.handler?.(services, event);
2177
- }
2178
- };
2179
2289
  const display = computed(() => {
2180
- if (!item.value)
2290
+ if (!props.data)
2181
2291
  return false;
2182
- if (typeof item.value === "string")
2292
+ if (typeof props.data === "string")
2183
2293
  return true;
2184
- if (typeof item.value.display === "function") {
2185
- return item.value.display(services);
2294
+ if (typeof props.data.display === "function") {
2295
+ return props.data.display(services);
2186
2296
  }
2187
- return item.value.display ?? true;
2297
+ return props.data.display ?? true;
2188
2298
  });
2299
+ const buttonHandler = (item, event) => {
2300
+ if (disabled.value)
2301
+ return;
2302
+ if (typeof item.handler === "function" && services) {
2303
+ item.handler?.(services, event);
2304
+ }
2305
+ };
2189
2306
  const dropdownHandler = (command) => {
2190
2307
  if (command.item.handler) {
2191
2308
  command.item.handler(services);
2192
2309
  }
2193
2310
  };
2194
- const clickHandler = (item2, event) => {
2311
+ const clickHandler = (item, event) => {
2195
2312
  if (props.eventType !== "click")
2196
2313
  return;
2197
- if (item2.type === "button") {
2198
- buttonHandler(item2, event);
2314
+ if (item.type === "button") {
2315
+ buttonHandler(item, event);
2199
2316
  }
2200
2317
  };
2201
- const mousedownHandler = (item2, event) => {
2318
+ const mousedownHandler = (item, event) => {
2202
2319
  if (props.eventType !== "mousedown")
2203
2320
  return;
2204
- if (item2.type === "button") {
2205
- buttonHandler(item2, event);
2321
+ if (item.type === "button") {
2322
+ buttonHandler(item, event);
2206
2323
  }
2207
2324
  };
2208
- const mouseupHandler = (item2, event) => {
2325
+ const mouseupHandler = (item, event) => {
2209
2326
  if (props.eventType !== "mouseup")
2210
2327
  return;
2211
- if (item2.type === "button") {
2212
- buttonHandler(item2, event);
2328
+ if (item.type === "button") {
2329
+ buttonHandler(item, event);
2213
2330
  }
2214
2331
  };
2215
2332
  return (_ctx, _cache) => {
2216
2333
  const _component_el_divider = resolveComponent("el-divider");
2217
- const _component_tool_button = resolveComponent("tool-button", true);
2218
2334
  const _component_el_button = resolveComponent("el-button");
2219
2335
  const _component_el_tooltip = resolveComponent("el-tooltip");
2220
2336
  const _component_el_icon = resolveComponent("el-icon");
@@ -2223,30 +2339,20 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2223
2339
  const _component_el_dropdown = resolveComponent("el-dropdown");
2224
2340
  return unref(display) ? (openBlock(), createElementBlock("div", {
2225
2341
  key: 0,
2226
- class: normalizeClass(["menu-item", unref(item).type]),
2227
- onClick: _cache[0] || (_cache[0] = ($event) => clickHandler(unref(item), $event)),
2228
- onMousedown: _cache[1] || (_cache[1] = ($event) => mousedownHandler(unref(item), $event)),
2229
- onMouseup: _cache[2] || (_cache[2] = ($event) => mouseupHandler(unref(item), $event))
2342
+ class: normalizeClass(["menu-item", `${__props.data.type} ${__props.data.className || ""}`]),
2343
+ onClick: _cache[0] || (_cache[0] = ($event) => clickHandler(__props.data, $event)),
2344
+ onMousedown: _cache[1] || (_cache[1] = ($event) => mousedownHandler(__props.data, $event)),
2345
+ onMouseup: _cache[2] || (_cache[2] = ($event) => mouseupHandler(__props.data, $event))
2230
2346
  }, [
2231
- unref(item).type === "divider" ? (openBlock(), createBlock(_component_el_divider, {
2347
+ __props.data.type === "divider" ? (openBlock(), createBlock(_component_el_divider, {
2232
2348
  key: 0,
2233
- direction: unref(item).direction || "vertical"
2234
- }, null, 8, ["direction"])) : unref(item).type === "text" ? (openBlock(), createElementBlock("div", _hoisted_1$7, toDisplayString(unref(item).text), 1)) : unref(item).type === "zoom" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2235
- createVNode(_component_tool_button, {
2236
- data: { type: "button", icon: unref(ZoomOut), handler: zoomOutHandler, tooltip: "\u7F29\u5C0F" },
2237
- "event-type": __props.eventType
2238
- }, null, 8, ["data", "event-type"]),
2239
- createElementVNode("span", _hoisted_2$2, toDisplayString(parseInt(`${unref(zoom) * 100}`, 10)) + "%", 1),
2240
- createVNode(_component_tool_button, {
2241
- data: { type: "button", icon: unref(ZoomIn), handler: zoomInHandler, tooltip: "\u653E\u5927" },
2242
- "event-type": __props.eventType
2243
- }, null, 8, ["data", "event-type"])
2244
- ], 64)) : unref(item).type === "button" ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [
2245
- unref(item).tooltip ? (openBlock(), createBlock(_component_el_tooltip, {
2349
+ direction: __props.data.direction || "vertical"
2350
+ }, null, 8, ["direction"])) : __props.data.type === "text" ? (openBlock(), createElementBlock("div", _hoisted_1$5, toDisplayString(__props.data.text), 1)) : __props.data.type === "button" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2351
+ __props.data.tooltip ? (openBlock(), createBlock(_component_el_tooltip, {
2246
2352
  key: 0,
2247
2353
  effect: "dark",
2248
2354
  placement: "bottom-start",
2249
- content: unref(item).tooltip
2355
+ content: __props.data.tooltip
2250
2356
  }, {
2251
2357
  default: withCtx(() => [
2252
2358
  createVNode(_component_el_button, {
@@ -2255,11 +2361,11 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2255
2361
  disabled: unref(disabled)
2256
2362
  }, {
2257
2363
  default: withCtx(() => [
2258
- unref(item).icon ? (openBlock(), createBlock(MIcon, {
2364
+ __props.data.icon ? (openBlock(), createBlock(_sfc_main$h, {
2259
2365
  key: 0,
2260
- icon: unref(item).icon
2366
+ icon: __props.data.icon
2261
2367
  }, null, 8, ["icon"])) : createCommentVNode("", true),
2262
- createElementVNode("span", null, toDisplayString(unref(item).text), 1)
2368
+ createElementVNode("span", null, toDisplayString(__props.data.text), 1)
2263
2369
  ]),
2264
2370
  _: 1
2265
2371
  }, 8, ["disabled"])
@@ -2272,27 +2378,27 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2272
2378
  disabled: unref(disabled)
2273
2379
  }, {
2274
2380
  default: withCtx(() => [
2275
- unref(item).icon ? (openBlock(), createBlock(MIcon, {
2381
+ __props.data.icon ? (openBlock(), createBlock(_sfc_main$h, {
2276
2382
  key: 0,
2277
- icon: unref(item).icon
2383
+ icon: __props.data.icon
2278
2384
  }, null, 8, ["icon"])) : createCommentVNode("", true),
2279
- createElementVNode("span", null, toDisplayString(unref(item).text), 1)
2385
+ createElementVNode("span", null, toDisplayString(__props.data.text), 1)
2280
2386
  ]),
2281
2387
  _: 1
2282
2388
  }, 8, ["disabled"]))
2283
- ], 64)) : unref(item).type === "dropdown" ? (openBlock(), createBlock(_component_el_dropdown, {
2284
- key: 4,
2389
+ ], 64)) : __props.data.type === "dropdown" ? (openBlock(), createBlock(_component_el_dropdown, {
2390
+ key: 3,
2285
2391
  trigger: "click",
2286
2392
  disabled: unref(disabled),
2287
2393
  onCommand: dropdownHandler
2288
2394
  }, {
2289
2395
  dropdown: withCtx(() => [
2290
- unref(item).items && unref(item).items.length ? (openBlock(), createBlock(_component_el_dropdown_menu, { key: 0 }, {
2396
+ __props.data.items && __props.data.items.length ? (openBlock(), createBlock(_component_el_dropdown_menu, { key: 0 }, {
2291
2397
  default: withCtx(() => [
2292
- (openBlock(true), createElementBlock(Fragment, null, renderList(unref(item).items, (subItem, index) => {
2398
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.data.items, (subItem, index) => {
2293
2399
  return openBlock(), createBlock(_component_el_dropdown_item, {
2294
2400
  key: index,
2295
- command: { item: unref(item), subItem }
2401
+ command: { data: __props.data, subItem }
2296
2402
  }, {
2297
2403
  default: withCtx(() => [
2298
2404
  createTextVNode(toDisplayString(subItem.text), 1)
@@ -2305,8 +2411,8 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2305
2411
  })) : createCommentVNode("", true)
2306
2412
  ]),
2307
2413
  default: withCtx(() => [
2308
- createElementVNode("span", _hoisted_3, [
2309
- createTextVNode(toDisplayString(unref(item).text), 1),
2414
+ createElementVNode("span", _hoisted_2$2, [
2415
+ createTextVNode(toDisplayString(__props.data.text), 1),
2310
2416
  createVNode(_component_el_icon, { class: "el-icon--right" }, {
2311
2417
  default: withCtx(() => [
2312
2418
  createVNode(unref(ArrowDown))
@@ -2316,67 +2422,187 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2316
2422
  ])
2317
2423
  ]),
2318
2424
  _: 1
2319
- }, 8, ["disabled"])) : unref(item).type === "component" ? (openBlock(), createBlock(resolveDynamicComponent(unref(item).component), normalizeProps(mergeProps({ key: 5 }, unref(item).props || {})), null, 16)) : createCommentVNode("", true)
2425
+ }, 8, ["disabled"])) : __props.data.type === "component" ? (openBlock(), createBlock(resolveDynamicComponent(__props.data.component), normalizeProps(mergeProps({ key: 4 }, __props.data.props || {})), null, 16)) : createCommentVNode("", true)
2320
2426
  ], 34)) : createCommentVNode("", true);
2321
2427
  };
2322
2428
  }
2323
2429
  });
2324
2430
 
2325
- const _sfc_main$e = defineComponent({
2326
- name: "nav-menu",
2327
- components: { ToolButton: _sfc_main$f },
2431
+ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2432
+ __name: "NavMenu",
2328
2433
  props: {
2329
- data: {
2330
- type: Object,
2331
- default: () => ({})
2332
- },
2333
- height: {
2334
- type: Number
2335
- }
2434
+ data: { default: () => ({}) },
2435
+ height: { default: 35 }
2336
2436
  },
2337
- setup(props) {
2437
+ setup(__props) {
2438
+ const props = __props;
2338
2439
  const services = inject("services");
2339
- return {
2340
- keys: computed(() => Object.keys(props.data)),
2341
- columnWidth: computed(() => services?.uiService.get("columnWidth"))
2440
+ const uiService = services?.uiService;
2441
+ const columnWidth = computed(() => services?.uiService.get("columnWidth"));
2442
+ const keys = Object.values(ColumnLayout);
2443
+ const showGuides = computed(() => uiService?.get("showGuides") ?? true);
2444
+ const showRule = computed(() => uiService?.get("showRule") ?? true);
2445
+ const zoom = computed(() => uiService?.get("zoom") ?? 1);
2446
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
2447
+ const ctrl = isMac ? "Command" : "Ctrl";
2448
+ const getConfig = (item) => {
2449
+ if (typeof item !== "string") {
2450
+ return [item];
2451
+ }
2452
+ const config = [];
2453
+ switch (item) {
2454
+ case "/":
2455
+ config.push({
2456
+ type: "divider",
2457
+ className: "divider"
2458
+ });
2459
+ break;
2460
+ case "zoom":
2461
+ config.push(...getConfig("zoom-out"), ...getConfig(`${parseInt(`${zoom.value * 100}`, 10)}%`), ...getConfig("zoom-in"), ...getConfig("scale-to-original"), ...getConfig("scale-to-fit"));
2462
+ break;
2463
+ case "delete":
2464
+ config.push({
2465
+ type: "button",
2466
+ className: "delete",
2467
+ icon: markRaw(Delete),
2468
+ tooltip: `\u522A\u9664(Delete)`,
2469
+ disabled: () => services?.editorService.get("node")?.type === NodeType.PAGE,
2470
+ handler: () => services?.editorService.remove(services?.editorService.get("node"))
2471
+ });
2472
+ break;
2473
+ case "undo":
2474
+ config.push({
2475
+ type: "button",
2476
+ className: "undo",
2477
+ icon: markRaw(Back),
2478
+ tooltip: `\u540E\u9000(${ctrl}+z)`,
2479
+ disabled: () => !services?.historyService.state.canUndo,
2480
+ handler: () => services?.editorService.undo()
2481
+ });
2482
+ break;
2483
+ case "redo":
2484
+ config.push({
2485
+ type: "button",
2486
+ className: "redo",
2487
+ icon: markRaw(Right),
2488
+ tooltip: `\u524D\u8FDB(${ctrl}+Shift+z)`,
2489
+ disabled: () => !services?.historyService.state.canRedo,
2490
+ handler: () => services?.editorService.redo()
2491
+ });
2492
+ break;
2493
+ case "zoom-in":
2494
+ config.push({
2495
+ type: "button",
2496
+ className: "zoom-in",
2497
+ icon: markRaw(ZoomIn),
2498
+ tooltip: `\u653E\u5927(${ctrl}+=)`,
2499
+ handler: () => uiService?.zoom(0.1)
2500
+ });
2501
+ break;
2502
+ case "zoom-out":
2503
+ config.push({
2504
+ type: "button",
2505
+ className: "zoom-out",
2506
+ icon: markRaw(ZoomOut),
2507
+ tooltip: `\u7E2E\u5C0F(${ctrl}+-)`,
2508
+ handler: () => uiService?.zoom(-0.1)
2509
+ });
2510
+ break;
2511
+ case "scale-to-original":
2512
+ config.push({
2513
+ type: "button",
2514
+ className: "scale-to-original",
2515
+ icon: markRaw(ScaleToOriginal),
2516
+ tooltip: `\u7F29\u653E\u5230\u5B9E\u9645\u5927\u5C0F(${ctrl}+1)`,
2517
+ handler: () => uiService?.set("zoom", 1)
2518
+ });
2519
+ break;
2520
+ case "scale-to-fit":
2521
+ config.push({
2522
+ type: "button",
2523
+ className: "scale-to-fit",
2524
+ icon: markRaw(FullScreen),
2525
+ tooltip: `\u7F29\u653E\u4EE5\u9002\u5E94(${ctrl}+0)`,
2526
+ handler: () => uiService?.set("zoom", uiService.calcZoom())
2527
+ });
2528
+ break;
2529
+ case "rule":
2530
+ config.push({
2531
+ type: "button",
2532
+ className: "rule",
2533
+ icon: markRaw(Memo),
2534
+ tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2535
+ handler: () => uiService?.set("showRule", !showRule.value)
2536
+ });
2537
+ break;
2538
+ case "guides":
2539
+ config.push({
2540
+ type: "button",
2541
+ className: "guides",
2542
+ icon: markRaw(Grid),
2543
+ tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2544
+ handler: () => uiService?.set("showGuides", !showGuides.value)
2545
+ });
2546
+ break;
2547
+ default:
2548
+ config.push({
2549
+ type: "text",
2550
+ text: item
2551
+ });
2552
+ }
2553
+ return config;
2342
2554
  };
2343
- }
2344
- });
2345
-
2346
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
2347
- const _component_tool_button = resolveComponent("tool-button");
2348
- return openBlock(), createElementBlock("div", {
2349
- class: "m-editor-nav-menu",
2350
- style: normalizeStyle({ height: `${_ctx.height}px` })
2351
- }, [
2352
- (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.keys, (key) => {
2555
+ const buttons = computed(() => {
2556
+ const data = {
2557
+ [ColumnLayout.LEFT]: [],
2558
+ [ColumnLayout.CENTER]: [],
2559
+ [ColumnLayout.RIGHT]: []
2560
+ };
2561
+ keys.forEach((key) => {
2562
+ const items = props.data[key] || [];
2563
+ items.forEach((item) => {
2564
+ data[key].push(...getConfig(item));
2565
+ });
2566
+ });
2567
+ return data;
2568
+ });
2569
+ return (_ctx, _cache) => {
2353
2570
  return openBlock(), createElementBlock("div", {
2354
- class: normalizeClass(`menu-${key}`),
2355
- key,
2356
- style: normalizeStyle(`width: ${_ctx.columnWidth?.[key]}px`)
2571
+ class: "m-editor-nav-menu",
2572
+ style: normalizeStyle({ height: `${__props.height}px` })
2357
2573
  }, [
2358
- (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.data[key], (item, index) => {
2359
- return openBlock(), createBlock(_component_tool_button, {
2360
- data: item,
2361
- key: index
2362
- }, null, 8, ["data"]);
2574
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(keys), (key) => {
2575
+ return openBlock(), createElementBlock("div", {
2576
+ class: normalizeClass(`menu-${key}`),
2577
+ key,
2578
+ style: normalizeStyle(`width: ${unref(columnWidth)?.[key]}px`)
2579
+ }, [
2580
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(buttons)[key], (item, index) => {
2581
+ return openBlock(), createBlock(_sfc_main$g, {
2582
+ data: item,
2583
+ key: index
2584
+ }, null, 8, ["data"]);
2585
+ }), 128))
2586
+ ], 6);
2363
2587
  }), 128))
2364
- ], 6);
2365
- }), 128))
2366
- ], 4);
2367
- }
2368
- const NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$9]]);
2588
+ ], 4);
2589
+ };
2590
+ }
2591
+ });
2369
2592
 
2370
- const _sfc_main$d = defineComponent({
2371
- name: "m-editor-props-panel",
2593
+ const _hoisted_1$4 = { class: "`m-editor-props-panel" };
2594
+ const _sfc_main$e = /* @__PURE__ */ defineComponent({
2595
+ __name: "PropsPanel",
2372
2596
  emits: ["mounted"],
2373
- setup(props, { emit }) {
2597
+ setup(__props, { expose, emit }) {
2374
2598
  const internalInstance = getCurrentInstance();
2375
2599
  const values = ref({});
2376
2600
  const configForm = ref();
2377
2601
  const curFormConfig = ref([]);
2378
2602
  const services = inject("services");
2379
2603
  const node = computed(() => services?.editorService.get("node"));
2604
+ const propsPanelSize = computed(() => services?.uiService.get("propsPanelSize") || "small");
2605
+ const stage = computed(() => services?.editorService.get("stage"));
2380
2606
  const init = async () => {
2381
2607
  if (!node.value) {
2382
2608
  curFormConfig.value = [];
@@ -2391,51 +2617,49 @@ const _sfc_main$d = defineComponent({
2391
2617
  onMounted(() => {
2392
2618
  emit("mounted", internalInstance);
2393
2619
  });
2394
- return {
2395
- values,
2396
- configForm,
2397
- curFormConfig,
2398
- propsPanelSize: computed(() => services?.uiService.get("propsPanelSize") || "small"),
2399
- async submit() {
2400
- try {
2401
- const values2 = await configForm.value?.submitForm();
2402
- services?.editorService.update(values2);
2403
- } catch (e) {
2404
- console.error(e);
2405
- ElMessage.closeAll();
2406
- ElMessage.error({
2407
- duration: 1e4,
2408
- showClose: true,
2409
- message: e.message,
2410
- dangerouslyUseHTMLString: true
2411
- });
2412
- }
2620
+ watchEffect(() => {
2621
+ if (configForm.value && stage.value) {
2622
+ configForm.value.formState.stage = stage.value;
2623
+ }
2624
+ });
2625
+ const submit = async () => {
2626
+ try {
2627
+ const values2 = await configForm.value?.submitForm();
2628
+ services?.editorService.update(values2);
2629
+ } catch (e) {
2630
+ console.error(e);
2631
+ ElMessage.closeAll();
2632
+ ElMessage.error({
2633
+ duration: 1e4,
2634
+ showClose: true,
2635
+ message: e.message,
2636
+ dangerouslyUseHTMLString: true
2637
+ });
2413
2638
  }
2414
2639
  };
2640
+ expose({ submit });
2641
+ return (_ctx, _cache) => {
2642
+ const _component_m_form = resolveComponent("m-form");
2643
+ return openBlock(), createElementBlock("div", _hoisted_1$4, [
2644
+ renderSlot(_ctx.$slots, "props-panel-header"),
2645
+ createVNode(_component_m_form, {
2646
+ ref_key: "configForm",
2647
+ ref: configForm,
2648
+ class: normalizeClass(`m-editor-props-panel ${unref(propsPanelSize)}`),
2649
+ "popper-class": `m-editor-props-panel-popper ${unref(propsPanelSize)}`,
2650
+ size: unref(propsPanelSize),
2651
+ "init-values": values.value,
2652
+ config: curFormConfig.value,
2653
+ onChange: submit
2654
+ }, null, 8, ["class", "popper-class", "size", "init-values", "config"])
2655
+ ]);
2656
+ };
2415
2657
  }
2416
2658
  });
2417
2659
 
2418
- const _hoisted_1$6 = { class: "`m-editor-props-panel" };
2419
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
2420
- const _component_m_form = resolveComponent("m-form");
2421
- return openBlock(), createElementBlock("div", _hoisted_1$6, [
2422
- renderSlot(_ctx.$slots, "props-panel-header"),
2423
- createVNode(_component_m_form, {
2424
- class: normalizeClass(`m-editor-props-panel ${_ctx.propsPanelSize}`),
2425
- "popper-class": `m-editor-props-panel-popper ${_ctx.propsPanelSize}`,
2426
- ref: "configForm",
2427
- size: _ctx.propsPanelSize,
2428
- "init-values": _ctx.values,
2429
- config: _ctx.curFormConfig,
2430
- onChange: _ctx.submit
2431
- }, null, 8, ["class", "popper-class", "size", "init-values", "config", "onChange"])
2432
- ]);
2433
- }
2434
- const PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$8]]);
2435
-
2436
- const _sfc_main$c = defineComponent({
2660
+ const _sfc_main$d = defineComponent({
2437
2661
  name: "ui-component-panel",
2438
- components: { MIcon },
2662
+ components: { MIcon: _sfc_main$h },
2439
2663
  setup() {
2440
2664
  const searchText = ref("");
2441
2665
  const services = inject("services");
@@ -2500,9 +2724,9 @@ const _sfc_main$c = defineComponent({
2500
2724
  }
2501
2725
  });
2502
2726
 
2503
- const _hoisted_1$5 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
2727
+ const _hoisted_1$3 = /* @__PURE__ */ createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
2504
2728
  const _hoisted_2$1 = ["onClick", "onDragstart"];
2505
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2729
+ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2506
2730
  const _component_el_input = resolveComponent("el-input");
2507
2731
  const _component_m_icon = resolveComponent("m-icon");
2508
2732
  const _component_el_tooltip = resolveComponent("el-tooltip");
@@ -2533,7 +2757,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2533
2757
  name: index
2534
2758
  }, {
2535
2759
  title: withCtx(() => [
2536
- _hoisted_1$5,
2760
+ _hoisted_1$3,
2537
2761
  createTextVNode(toDisplayString(group.title), 1)
2538
2762
  ]),
2539
2763
  default: withCtx(() => [
@@ -2574,9 +2798,9 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2574
2798
  _: 3
2575
2799
  });
2576
2800
  }
2577
- const ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$7]]);
2801
+ const ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$5]]);
2578
2802
 
2579
- const _sfc_main$b = /* @__PURE__ */ defineComponent({
2803
+ const _sfc_main$c = /* @__PURE__ */ defineComponent({
2580
2804
  __name: "ContentMenu",
2581
2805
  props: {
2582
2806
  menuData: { default: () => [] },
@@ -2665,7 +2889,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
2665
2889
  }, [
2666
2890
  createElementVNode("div", null, [
2667
2891
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.menuData, (item, index) => {
2668
- return openBlock(), createBlock(_sfc_main$f, {
2892
+ return openBlock(), createBlock(_sfc_main$g, {
2669
2893
  "event-type": "mouseup",
2670
2894
  data: item,
2671
2895
  key: index,
@@ -2689,8 +2913,8 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
2689
2913
  }
2690
2914
  });
2691
2915
 
2692
- const _sfc_main$a = defineComponent({
2693
- components: { ContentMenu: _sfc_main$b },
2916
+ const _sfc_main$b = defineComponent({
2917
+ components: { ContentMenu: _sfc_main$c },
2694
2918
  setup() {
2695
2919
  const services = inject("services");
2696
2920
  const menu = ref();
@@ -2773,7 +2997,7 @@ const _sfc_main$a = defineComponent({
2773
2997
  }
2774
2998
  });
2775
2999
 
2776
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3000
+ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
2777
3001
  const _component_content_menu = resolveComponent("content-menu");
2778
3002
  return openBlock(), createBlock(_component_content_menu, {
2779
3003
  "menu-data": _ctx.menuData,
@@ -2781,7 +3005,7 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
2781
3005
  style: { "overflow": "initial" }
2782
3006
  }, null, 8, ["menu-data"]);
2783
3007
  }
2784
- const LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$6]]);
3008
+ const LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$4]]);
2785
3009
 
2786
3010
  const throttleTime = 150;
2787
3011
  const select = async (data, editorService) => {
@@ -2832,20 +3056,38 @@ const useDrop = (tree, editorService) => ({
2832
3056
  }
2833
3057
  });
2834
3058
  const useStatus = (tree, editorService) => {
2835
- const highlightNode = ref();
2836
3059
  const node = ref();
2837
3060
  const page = computed(() => editorService?.get("page"));
3061
+ const expandedKeys = /* @__PURE__ */ new Map();
3062
+ const expandNodes = () => {
3063
+ expandedKeys.forEach((key) => {
3064
+ if (!tree.value)
3065
+ return;
3066
+ tree.value.getNode(key)?.expand();
3067
+ });
3068
+ };
2838
3069
  watchEffect(() => {
2839
3070
  if (!tree.value)
2840
3071
  return;
2841
- node.value = editorService?.get("node");
2842
- node.value && tree.value.setCurrentKey(node.value.id, true);
2843
- const parent = editorService?.get("parent");
3072
+ if (!editorService)
3073
+ return;
3074
+ node.value = editorService.get("node");
3075
+ if (!node.value)
3076
+ return;
3077
+ tree.value.setCurrentKey(node.value.id, true);
3078
+ const parent = editorService.get("parent");
2844
3079
  if (!parent?.id)
2845
3080
  return;
2846
3081
  const treeNode = tree.value.getNode(parent.id);
2847
3082
  treeNode?.updateChildren();
2848
- highlightNode.value = editorService?.get("highlightNode");
3083
+ setTimeout(() => {
3084
+ tree.value && Object.entries(tree.value.store.nodesMap).forEach(([id, node2]) => {
3085
+ if (node2.expanded && node2.data.items) {
3086
+ expandedKeys.set(id, id);
3087
+ }
3088
+ });
3089
+ expandNodes();
3090
+ });
2849
3091
  });
2850
3092
  return {
2851
3093
  values: computed(() => page.value ? [page.value] : []),
@@ -2858,9 +3100,18 @@ const useStatus = (tree, editorService) => {
2858
3100
  }
2859
3101
  resolve([]);
2860
3102
  },
2861
- highlightNode,
3103
+ highlightNode: computed(() => editorService?.get("highlightNode")),
2862
3104
  clickNode: node,
2863
- expandedKeys: computed(() => node.value ? [node.value.id] : [])
3105
+ expandedKeys: computed(() => node.value ? [node.value.id] : []),
3106
+ handleCollapse: (data) => {
3107
+ expandedKeys.delete(data.id);
3108
+ },
3109
+ handleExpand: (data) => {
3110
+ const parent = editorService?.getParentById(data.id);
3111
+ if (!parent?.id)
3112
+ return;
3113
+ expandedKeys.set(parent.id, parent.id);
3114
+ }
2864
3115
  };
2865
3116
  };
2866
3117
  const useFilter = (tree) => ({
@@ -2881,7 +3132,7 @@ const useFilter = (tree) => ({
2881
3132
  tree.value?.filter(val);
2882
3133
  }
2883
3134
  });
2884
- const _sfc_main$9 = defineComponent({
3135
+ const _sfc_main$a = defineComponent({
2885
3136
  name: "magic-editor-layer-panel",
2886
3137
  components: { LayerMenu },
2887
3138
  setup() {
@@ -2929,8 +3180,8 @@ const _sfc_main$9 = defineComponent({
2929
3180
  }
2930
3181
  });
2931
3182
 
2932
- const _hoisted_1$4 = ["id", "onMouseenter"];
2933
- function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3183
+ const _hoisted_1$2 = ["id", "onMouseenter"];
3184
+ function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
2934
3185
  const _component_el_input = resolveComponent("el-input");
2935
3186
  const _component_el_tree = resolveComponent("el-tree");
2936
3187
  const _component_layer_menu = resolveComponent("layer-menu");
@@ -2951,6 +3202,7 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2951
3202
  key: 0,
2952
3203
  ref: "tree",
2953
3204
  "node-key": "id",
3205
+ "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684",
2954
3206
  draggable: "",
2955
3207
  "default-expanded-keys": _ctx.expandedKeys,
2956
3208
  load: _ctx.loadItems,
@@ -2965,7 +3217,8 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2965
3217
  onNodeClick: _ctx.clickHandler,
2966
3218
  onNodeContextmenu: _ctx.contextmenu,
2967
3219
  onNodeDragEnd: _ctx.handleDragEnd,
2968
- "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3220
+ onNodeCollapse: _ctx.handleCollapse,
3221
+ onNodeExpand: _ctx.handleExpand
2969
3222
  }, {
2970
3223
  default: withCtx(({ node, data }) => [
2971
3224
  createElementVNode("div", {
@@ -2981,10 +3234,10 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2981
3234
  }, () => [
2982
3235
  createElementVNode("span", null, toDisplayString(`${data.name} (${data.id})`), 1)
2983
3236
  ])
2984
- ], 42, _hoisted_1$4)
3237
+ ], 42, _hoisted_1$2)
2985
3238
  ]),
2986
3239
  _: 3
2987
- }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : createCommentVNode("", true),
3240
+ }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd", "onNodeCollapse", "onNodeExpand"])) : createCommentVNode("", true),
2988
3241
  (openBlock(), createBlock(Teleport, { to: "body" }, [
2989
3242
  createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
2990
3243
  ]))
@@ -2992,10 +3245,10 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2992
3245
  _: 3
2993
3246
  });
2994
3247
  }
2995
- const LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$5]]);
3248
+ const LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$3]]);
2996
3249
 
2997
- const _sfc_main$8 = defineComponent({
2998
- components: { MIcon },
3250
+ const _sfc_main$9 = defineComponent({
3251
+ components: { MIcon: _sfc_main$h },
2999
3252
  props: {
3000
3253
  data: {
3001
3254
  type: [Object, String]
@@ -3032,11 +3285,11 @@ const _sfc_main$8 = defineComponent({
3032
3285
  }
3033
3286
  });
3034
3287
 
3035
- const _hoisted_1$3 = {
3288
+ const _hoisted_1$1 = {
3036
3289
  key: 1,
3037
3290
  class: "magic-editor-tab-panel-title"
3038
3291
  };
3039
- function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3292
+ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3040
3293
  const _component_m_icon = resolveComponent("m-icon");
3041
3294
  const _component_el_tab_pane = resolveComponent("el-tab-pane");
3042
3295
  return _ctx.config ? (openBlock(), createBlock(_component_el_tab_pane, {
@@ -3051,7 +3304,7 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3051
3304
  key: 0,
3052
3305
  icon: _ctx.config.icon
3053
3306
  }, null, 8, ["icon"])) : createCommentVNode("", true),
3054
- _ctx.config.text ? (openBlock(), createElementBlock("div", _hoisted_1$3, toDisplayString(_ctx.config.text), 1)) : createCommentVNode("", true)
3307
+ _ctx.config.text ? (openBlock(), createElementBlock("div", _hoisted_1$1, toDisplayString(_ctx.config.text), 1)) : createCommentVNode("", true)
3055
3308
  ]))
3056
3309
  ]),
3057
3310
  default: withCtx(() => [
@@ -3082,9 +3335,9 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3082
3335
  _: 3
3083
3336
  }, 8, ["name"])) : createCommentVNode("", true);
3084
3337
  }
3085
- const TabPane = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$4]]);
3338
+ const TabPane = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$2]]);
3086
3339
 
3087
- const _sfc_main$7 = defineComponent({
3340
+ const _sfc_main$8 = defineComponent({
3088
3341
  components: { TabPane },
3089
3342
  name: "m-sidebar",
3090
3343
  props: {
@@ -3104,7 +3357,7 @@ const _sfc_main$7 = defineComponent({
3104
3357
  }
3105
3358
  });
3106
3359
 
3107
- function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3360
+ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3108
3361
  const _component_tab_pane = resolveComponent("tab-pane");
3109
3362
  const _component_el_tabs = resolveComponent("el-tabs");
3110
3363
  return _ctx.data.type === "tabs" && _ctx.data.items.length ? (openBlock(), createBlock(_component_el_tabs, {
@@ -3139,9 +3392,9 @@ function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3139
3392
  _: 3
3140
3393
  }, 8, ["modelValue"])) : createCommentVNode("", true);
3141
3394
  }
3142
- const Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$3]]);
3395
+ const Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$1]]);
3143
3396
 
3144
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
3397
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
3145
3398
  __name: "PageBarScrollContainer",
3146
3399
  setup(__props) {
3147
3400
  const services = inject("services");
@@ -3268,9 +3521,9 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
3268
3521
  }
3269
3522
  });
3270
3523
 
3271
- const _hoisted_1$2 = ["onClick"];
3524
+ const _hoisted_1 = ["onClick"];
3272
3525
  const _hoisted_2 = { class: "m-editor-page-bar-title" };
3273
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3526
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
3274
3527
  __name: "PageBar",
3275
3528
  setup(__props) {
3276
3529
  const services = inject("services");
@@ -3294,7 +3547,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3294
3547
  const _component_el_tooltip = resolveComponent("el-tooltip");
3295
3548
  const _component_el_icon = resolveComponent("el-icon");
3296
3549
  const _component_el_popover = resolveComponent("el-popover");
3297
- return openBlock(), createBlock(_sfc_main$6, null, {
3550
+ return openBlock(), createBlock(_sfc_main$7, null, {
3298
3551
  default: withCtx(() => [
3299
3552
  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(root) && unref(root).items || [], (item) => {
3300
3553
  return openBlock(), createElementBlock("div", {
@@ -3310,7 +3563,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3310
3563
  content: item.name
3311
3564
  }, {
3312
3565
  default: withCtx(() => [
3313
- createElementVNode("span", null, toDisplayString(item.name), 1)
3566
+ createElementVNode("span", null, toDisplayString(item.name || item.id), 1)
3314
3567
  ]),
3315
3568
  _: 2
3316
3569
  }, 1032, ["content"])
@@ -3333,7 +3586,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3333
3586
  default: withCtx(() => [
3334
3587
  createElementVNode("div", null, [
3335
3588
  renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3336
- createVNode(_sfc_main$f, {
3589
+ createVNode(_sfc_main$g, {
3337
3590
  data: {
3338
3591
  type: "button",
3339
3592
  text: "\u590D\u5236",
@@ -3341,7 +3594,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3341
3594
  handler: () => copy(item)
3342
3595
  }
3343
3596
  }, null, 8, ["data"]),
3344
- createVNode(_sfc_main$f, {
3597
+ createVNode(_sfc_main$g, {
3345
3598
  data: {
3346
3599
  type: "button",
3347
3600
  text: "\u5220\u9664",
@@ -3354,7 +3607,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3354
3607
  ]),
3355
3608
  _: 2
3356
3609
  }, 1024)
3357
- ], 10, _hoisted_1$2);
3610
+ ], 10, _hoisted_1);
3358
3611
  }), 128))
3359
3612
  ]),
3360
3613
  _: 3
@@ -3363,190 +3616,245 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3363
3616
  }
3364
3617
  });
3365
3618
 
3366
- class ScrollViewer$1 {
3367
- enter = false;
3368
- targetEnter = false;
3369
- keydown = false;
3619
+ class ScrollViewer extends EventEmitter {
3370
3620
  container;
3371
3621
  target;
3372
3622
  zoom = 1;
3373
3623
  scrollLeft = 0;
3374
3624
  scrollTop = 0;
3375
- x = 0;
3376
- y = 0;
3377
- resizeObserver = new ResizeObserver((entries) => {
3378
- for (const { contentRect } of entries) {
3379
- const { width, height } = contentRect;
3380
- const targetRect = this.target.getBoundingClientRect();
3381
- const targetWidth = targetRect.width * this.zoom;
3382
- const targetMarginTop = Number(this.target.style.marginTop) || 0;
3383
- const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3384
- if (targetWidth < width) {
3385
- this.target._left = 0;
3386
- }
3387
- if (targetHeight < height) {
3388
- this.target._top = 0;
3389
- }
3390
- this.scroll();
3391
- }
3625
+ scrollHeight = 0;
3626
+ scrollWidth = 0;
3627
+ width = 0;
3628
+ height = 0;
3629
+ translateXCorrectionValue = 0;
3630
+ translateYCorrectionValue = 0;
3631
+ resizeObserver = new ResizeObserver(() => {
3632
+ this.setSize();
3633
+ this.setScrollSize();
3392
3634
  });
3393
3635
  constructor(options) {
3636
+ super();
3394
3637
  this.container = options.container;
3395
3638
  this.target = options.target;
3396
3639
  this.zoom = options.zoom;
3397
- globalThis.addEventListener("keydown", this.keydownHandler);
3398
- globalThis.addEventListener("keyup", this.keyupHandler);
3399
- this.container.addEventListener("mouseenter", this.mouseEnterHandler);
3400
- this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
3401
- this.target.addEventListener("mouseenter", this.targetMouseEnterHandler);
3402
- this.target.addEventListener("mouseleave", this.targetMouseLeaveHandler);
3403
- this.container.addEventListener("wheel", this.wheelHandler);
3640
+ this.container.addEventListener("wheel", this.wheelHandler, false);
3641
+ this.setSize();
3642
+ this.setScrollSize();
3404
3643
  this.resizeObserver.observe(this.container);
3405
3644
  }
3406
3645
  destroy() {
3407
3646
  this.resizeObserver.disconnect();
3408
- this.container.removeEventListener("mouseenter", this.mouseEnterHandler);
3409
- this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
3410
- this.target.removeEventListener("mouseenter", this.targetMouseEnterHandler);
3411
- this.target.removeEventListener("mouseleave", this.targetMouseLeaveHandler);
3412
- globalThis.removeEventListener("keydown", this.keydownHandler);
3413
- globalThis.removeEventListener("keyup", this.keyupHandler);
3647
+ this.container.removeEventListener("wheel", this.wheelHandler, false);
3648
+ this.removeAllListeners();
3414
3649
  }
3415
3650
  setZoom(zoom) {
3416
3651
  this.zoom = zoom;
3652
+ this.setScrollSize();
3417
3653
  }
3418
- scroll() {
3419
- const scrollLeft = this.target._left;
3420
- const scrollTop = this.target._top;
3421
- this.target.style.transform = `translate(${scrollLeft}px, ${scrollTop}px)`;
3422
- }
3423
- removeHandler() {
3424
- this.target.style.cursor = "";
3425
- this.target.removeEventListener("mousedown", this.mousedownHandler);
3426
- document.removeEventListener("mousemove", this.mousemoveHandler);
3427
- document.removeEventListener("mouseup", this.mouseupHandler);
3654
+ scrollTo({ left, top }) {
3655
+ if (typeof left !== "undefined") {
3656
+ this.scrollLeft = left;
3657
+ }
3658
+ if (typeof top !== "undefined") {
3659
+ this.scrollTop = top;
3660
+ }
3661
+ const translateX = -this.scrollLeft + this.translateXCorrectionValue;
3662
+ const translateY = -this.scrollTop + this.translateYCorrectionValue;
3663
+ this.target.style.transform = `translate(${translateX}px, ${translateY}px)`;
3428
3664
  }
3429
3665
  wheelHandler = (event) => {
3430
- if (this.targetEnter)
3431
- return;
3432
3666
  const { deltaX, deltaY, currentTarget } = event;
3433
3667
  if (currentTarget !== this.container)
3434
3668
  return;
3435
- this.setScrollOffset(deltaX, deltaY);
3436
- this.scroll();
3437
- this.scrollLeft = this.target._left;
3438
- this.scrollTop = this.target._top;
3439
- };
3440
- mouseEnterHandler = () => {
3441
- this.enter = true;
3442
- };
3443
- mouseLeaveHandler = () => {
3444
- this.enter = false;
3445
- };
3446
- targetMouseEnterHandler = () => {
3447
- this.targetEnter = true;
3448
- };
3449
- targetMouseLeaveHandler = () => {
3450
- this.targetEnter = false;
3451
- };
3452
- mousedownHandler = (event) => {
3453
- if (!this.keydown)
3454
- return;
3455
- event.stopImmediatePropagation();
3456
- event.stopPropagation();
3457
- this.target.style.cursor = "grabbing";
3458
- this.x = event.clientX;
3459
- this.y = event.clientY;
3460
- document.addEventListener("mousemove", this.mousemoveHandler);
3461
- document.addEventListener("mouseup", this.mouseupHandler);
3462
- };
3463
- mouseupHandler = () => {
3464
- this.x = 0;
3465
- this.y = 0;
3466
- this.scrollLeft = this.target._left;
3467
- this.scrollTop = this.target._top;
3468
- this.removeHandler();
3469
- };
3470
- mousemoveHandler = (event) => {
3471
- event.stopImmediatePropagation();
3472
- event.stopPropagation();
3473
- const deltaX = event.clientX - this.x;
3474
- const deltaY = event.clientY - this.y;
3475
- this.setScrollOffset(deltaX, deltaY);
3476
- this.scroll();
3477
- };
3478
- keydownHandler = (event) => {
3479
- if (event.code === Keys.ESCAPE && this.enter) {
3480
- event.preventDefault();
3481
- event.stopImmediatePropagation();
3482
- event.stopPropagation();
3669
+ let top;
3670
+ if (this.scrollHeight > this.height) {
3671
+ top = this.scrollTop + this.getPos(deltaY, this.scrollTop, this.scrollHeight, this.height);
3483
3672
  }
3484
- if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3485
- return;
3673
+ let left;
3674
+ if (this.scrollWidth > this.width) {
3675
+ left = this.scrollLeft + this.getPos(deltaX, this.scrollLeft, this.scrollWidth, this.width);
3486
3676
  }
3487
- this.keydown = true;
3488
- this.target.style.cursor = "grab";
3489
- this.container.addEventListener("mousedown", this.mousedownHandler);
3677
+ this.scrollTo({ left, top });
3678
+ this.emit("scroll", {
3679
+ scrollLeft: this.scrollLeft,
3680
+ scrollTop: this.scrollTop,
3681
+ scrollHeight: this.scrollHeight,
3682
+ scrollWidth: this.scrollWidth
3683
+ });
3490
3684
  };
3491
- keyupHandler = (event) => {
3492
- if (event.code !== Keys.ESCAPE || !this.keydown) {
3493
- return;
3685
+ getPos(delta, scrollPos, scrollSize, size) {
3686
+ let pos = 0;
3687
+ if (delta < 0) {
3688
+ if (scrollPos > 0) {
3689
+ pos = Math.max(delta, -scrollPos);
3690
+ }
3691
+ } else {
3692
+ const leftPos = scrollSize - size - scrollPos;
3693
+ if (leftPos > 0) {
3694
+ pos = Math.min(delta, leftPos);
3695
+ }
3494
3696
  }
3495
- event.preventDefault();
3496
- event.stopImmediatePropagation();
3497
- event.stopPropagation();
3498
- this.keydown = false;
3499
- event.preventDefault();
3500
- this.removeHandler();
3697
+ return pos;
3698
+ }
3699
+ setScrollSize = () => {
3700
+ const targetRect = this.target.getBoundingClientRect();
3701
+ this.scrollWidth = targetRect.width * this.zoom + 100;
3702
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
3703
+ this.scrollHeight = (targetRect.height + targetMarginTop) * this.zoom + 100;
3704
+ let left;
3705
+ let top;
3706
+ if (this.scrollWidth < this.width) {
3707
+ left = 0;
3708
+ this.translateXCorrectionValue = 0;
3709
+ } else {
3710
+ this.translateXCorrectionValue = (this.scrollWidth - this.width) / 2;
3711
+ }
3712
+ if (this.scrollHeight < this.height) {
3713
+ top = 0;
3714
+ this.translateYCorrectionValue = 0;
3715
+ } else {
3716
+ this.translateYCorrectionValue = (this.scrollHeight - this.height) / 2;
3717
+ }
3718
+ this.scrollTo({
3719
+ left,
3720
+ top
3721
+ });
3722
+ this.emit("scroll", {
3723
+ scrollLeft: this.scrollLeft,
3724
+ scrollTop: this.scrollTop,
3725
+ scrollHeight: this.scrollHeight,
3726
+ scrollWidth: this.scrollWidth
3727
+ });
3501
3728
  };
3502
- setScrollOffset(deltaX, deltaY) {
3729
+ setSize = () => {
3503
3730
  const { width, height } = this.container.getBoundingClientRect();
3504
- const targetRect = this.target.getBoundingClientRect();
3505
- const targetWidth = targetRect.width * this.zoom;
3506
- const targetHeight = targetRect.height * this.zoom;
3507
- let y = 0;
3508
- if (targetHeight > height) {
3509
- if (deltaY > 0) {
3510
- y = this.scrollTop + Math.min(targetHeight - height - this.scrollTop, deltaY);
3511
- } else {
3512
- y = this.scrollTop + Math.max(-(targetHeight - height + this.scrollTop), deltaY);
3731
+ this.width = width;
3732
+ this.height = height;
3733
+ };
3734
+ }
3735
+
3736
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3737
+ __name: "ScrollBar",
3738
+ props: {
3739
+ size: null,
3740
+ scrollSize: null,
3741
+ isHorizontal: { type: Boolean },
3742
+ pos: null
3743
+ },
3744
+ emits: ["scroll"],
3745
+ setup(__props, { emit }) {
3746
+ const props = __props;
3747
+ const bar = ref();
3748
+ const thumb = ref();
3749
+ const thumbSize = computed(() => props.size * (props.size / props.scrollSize));
3750
+ const thumbPos = computed(() => props.pos / props.scrollSize * props.size);
3751
+ const thumbStyle = computed(() => ({
3752
+ [props.isHorizontal ? "width" : "height"]: `${thumbSize.value}px`,
3753
+ transform: `translate${props.isHorizontal ? "X" : "Y"}(${thumbPos.value}px)`
3754
+ }));
3755
+ let gesto;
3756
+ onMounted(() => {
3757
+ if (!thumb.value)
3758
+ return;
3759
+ const thumbEl = thumb.value;
3760
+ gesto = new Gesto(thumbEl, {
3761
+ container: window
3762
+ });
3763
+ gesto.on("dragStart", (e) => {
3764
+ e.inputEvent.stopPropagation();
3765
+ e.inputEvent.preventDefault();
3766
+ }).on("drag", (e) => {
3767
+ scrollBy(getDelta(e));
3768
+ });
3769
+ bar.value?.addEventListener("wheel", wheelHandler, false);
3770
+ });
3771
+ onUnmounted(() => {
3772
+ if (gesto)
3773
+ gesto.off();
3774
+ bar.value?.removeEventListener("wheel", wheelHandler, false);
3775
+ });
3776
+ const wheelHandler = (e) => {
3777
+ const delta = props.isHorizontal ? e.deltaX : e.deltaY;
3778
+ if (delta) {
3779
+ e.preventDefault();
3513
3780
  }
3514
- }
3515
- let x = 0;
3516
- if (targetWidth > width) {
3517
- if (deltaX > 0) {
3518
- x = this.scrollLeft + Math.min(targetWidth - width - this.scrollLeft, deltaX);
3781
+ scrollBy(delta);
3782
+ };
3783
+ const getDelta = (e) => {
3784
+ const ratio = (props.isHorizontal ? e.deltaX : e.deltaY) / props.size;
3785
+ return props.scrollSize * ratio;
3786
+ };
3787
+ const scrollBy = (delta) => {
3788
+ if (delta < 0) {
3789
+ if (props.pos <= 0) {
3790
+ emit("scroll", 0);
3791
+ } else {
3792
+ emit("scroll", -Math.min(-delta, props.pos));
3793
+ }
3519
3794
  } else {
3520
- x = this.scrollLeft + Math.max(-(targetWidth - width + this.scrollLeft), deltaX);
3795
+ const leftPos = props.size - (thumbSize.value + thumbPos.value);
3796
+ if (leftPos <= 0) {
3797
+ emit("scroll", 0);
3798
+ } else {
3799
+ emit("scroll", Math.min(delta, leftPos));
3800
+ }
3521
3801
  }
3522
- }
3523
- this.target._left = x;
3524
- this.target._top = y;
3802
+ };
3803
+ return (_ctx, _cache) => {
3804
+ return openBlock(), createElementBlock("div", {
3805
+ ref_key: "bar",
3806
+ ref: bar,
3807
+ class: normalizeClass(["m-editor-scroll-bar", __props.isHorizontal ? "horizontal" : "vertical"])
3808
+ }, [
3809
+ createElementVNode("div", {
3810
+ ref_key: "thumb",
3811
+ ref: thumb,
3812
+ class: "m-editor-scroll-bar-thumb",
3813
+ style: normalizeStyle(unref(thumbStyle))
3814
+ }, null, 4)
3815
+ ], 2);
3816
+ };
3525
3817
  }
3526
- }
3818
+ });
3819
+
3820
+ const ScrollBar_vue_vue_type_style_index_0_lang = '';
3527
3821
 
3528
- const _sfc_main$4 = defineComponent({
3529
- name: "m-editor-scroll-viewer",
3822
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
3823
+ __name: "ScrollViewer",
3530
3824
  props: {
3531
- width: Number,
3532
- height: Number,
3533
- zoom: {
3534
- type: Number,
3535
- default: 1
3536
- }
3825
+ width: { default: 0 },
3826
+ height: { default: 0 },
3827
+ wrapWidth: { default: 0 },
3828
+ wrapHeight: { default: 0 },
3829
+ zoom: { default: 1 }
3537
3830
  },
3538
- setup(props) {
3831
+ setup(__props, { expose }) {
3832
+ const props = __props;
3539
3833
  const container = ref();
3540
3834
  const el = ref();
3835
+ const style = computed(() => `
3836
+ width: ${props.width}px;
3837
+ height: ${props.height}px;
3838
+ position: absolute;
3839
+ margin-top: 30px;
3840
+ `);
3841
+ const scrollWidth = ref(0);
3842
+ const scrollHeight = ref(0);
3541
3843
  let scrollViewer;
3542
3844
  onMounted(() => {
3543
3845
  if (!container.value || !el.value)
3544
3846
  return;
3545
- scrollViewer = new ScrollViewer$1({
3847
+ scrollViewer = new ScrollViewer({
3546
3848
  container: container.value,
3547
3849
  target: el.value,
3548
3850
  zoom: props.zoom
3549
3851
  });
3852
+ scrollViewer.on("scroll", (data) => {
3853
+ hOffset.value = data.scrollLeft;
3854
+ vOffset.value = data.scrollTop;
3855
+ scrollWidth.value = data.scrollWidth;
3856
+ scrollHeight.value = data.scrollHeight;
3857
+ });
3550
3858
  });
3551
3859
  onUnmounted(() => {
3552
3860
  scrollViewer.destroy();
@@ -3554,35 +3862,56 @@ const _sfc_main$4 = defineComponent({
3554
3862
  watch(() => props.zoom, () => {
3555
3863
  scrollViewer.setZoom(props.zoom);
3556
3864
  });
3557
- return {
3558
- container,
3559
- el,
3560
- style: computed(() => `
3561
- width: ${props.width}px;
3562
- height: ${props.height}px;
3563
- position: absolute;
3564
- margin-top: 30px;
3565
- `)
3865
+ const vOffset = ref(0);
3866
+ const vScrollHandler = (delta) => {
3867
+ vOffset.value += delta;
3868
+ scrollViewer.scrollTo({
3869
+ top: vOffset.value
3870
+ });
3871
+ };
3872
+ const hOffset = ref(0);
3873
+ const hScrollHandler = (delta) => {
3874
+ hOffset.value += delta;
3875
+ scrollViewer.scrollTo({
3876
+ left: hOffset.value
3877
+ });
3878
+ };
3879
+ expose({
3880
+ container
3881
+ });
3882
+ return (_ctx, _cache) => {
3883
+ return openBlock(), createElementBlock("div", {
3884
+ class: "m-editor-scroll-viewer-container",
3885
+ ref_key: "container",
3886
+ ref: container
3887
+ }, [
3888
+ createElementVNode("div", {
3889
+ ref_key: "el",
3890
+ ref: el,
3891
+ style: normalizeStyle(unref(style))
3892
+ }, [
3893
+ renderSlot(_ctx.$slots, "default")
3894
+ ], 4),
3895
+ scrollHeight.value > __props.wrapHeight ? (openBlock(), createBlock(_sfc_main$5, {
3896
+ key: 0,
3897
+ "scroll-size": scrollHeight.value,
3898
+ size: __props.wrapHeight,
3899
+ pos: vOffset.value,
3900
+ onScroll: vScrollHandler
3901
+ }, null, 8, ["scroll-size", "size", "pos"])) : createCommentVNode("", true),
3902
+ scrollWidth.value > __props.wrapWidth ? (openBlock(), createBlock(_sfc_main$5, {
3903
+ key: 1,
3904
+ "is-horizontal": true,
3905
+ "scroll-size": scrollWidth.value,
3906
+ pos: hOffset.value,
3907
+ size: __props.wrapWidth,
3908
+ onScroll: hScrollHandler
3909
+ }, null, 8, ["scroll-size", "pos", "size"])) : createCommentVNode("", true)
3910
+ ], 512);
3566
3911
  };
3567
3912
  }
3568
3913
  });
3569
3914
 
3570
- const _hoisted_1$1 = {
3571
- class: "m-editor-scroll-viewer-container",
3572
- ref: "container"
3573
- };
3574
- function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3575
- return openBlock(), createElementBlock("div", _hoisted_1$1, [
3576
- createElementVNode("div", {
3577
- ref: "el",
3578
- style: normalizeStyle(_ctx.style)
3579
- }, [
3580
- renderSlot(_ctx.$slots, "default")
3581
- ], 4)
3582
- ], 512);
3583
- }
3584
- const ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$2]]);
3585
-
3586
3915
  const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3587
3916
  __name: "ViewerMenu",
3588
3917
  props: {
@@ -3604,11 +3933,11 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3604
3933
  {
3605
3934
  type: "button",
3606
3935
  text: "\u6C34\u5E73\u5C45\u4E2D",
3607
- display: () => canCenter.value && !props.isMultiSelect,
3936
+ display: () => canCenter.value,
3608
3937
  handler: () => {
3609
- if (!node.value)
3938
+ if (!nodes.value)
3610
3939
  return;
3611
- editorService?.alignCenter(node.value);
3940
+ editorService?.alignCenter(nodes.value);
3612
3941
  }
3613
3942
  },
3614
3943
  {
@@ -3719,7 +4048,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3719
4048
  };
3720
4049
  expose({ show });
3721
4050
  return (_ctx, _cache) => {
3722
- return openBlock(), createBlock(_sfc_main$b, {
4051
+ return openBlock(), createBlock(_sfc_main$c, {
3723
4052
  "menu-data": menuData,
3724
4053
  ref_key: "menu",
3725
4054
  ref: menu
@@ -3740,12 +4069,11 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3740
4069
  const menu = ref();
3741
4070
  const isMultiSelect = computed(() => services?.editorService.get("nodes")?.length > 1);
3742
4071
  const stageRect = computed(() => services?.uiService.get("stageRect"));
3743
- const uiSelectMode = computed(() => services?.uiService.get("uiSelectMode"));
4072
+ const stageContainerRect = computed(() => services?.uiService.get("stageContainerRect"));
3744
4073
  const root = computed(() => services?.editorService.get("root"));
3745
4074
  const page = computed(() => services?.editorService.get("page"));
3746
4075
  const zoom = computed(() => services?.uiService.get("zoom") || 1);
3747
4076
  const node = computed(() => services?.editorService.get("node"));
3748
- const getGuideLineKey = (key) => `${key}_${root.value?.id}_${page.value?.id}`;
3749
4077
  watchEffect(() => {
3750
4078
  if (stage)
3751
4079
  return;
@@ -3753,61 +4081,9 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3753
4081
  return;
3754
4082
  if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value)
3755
4083
  return;
3756
- stage = new StageCore({
3757
- render: stageOptions.render,
3758
- runtimeUrl: stageOptions.runtimeUrl,
3759
- zoom: zoom.value,
3760
- autoScrollIntoView: stageOptions.autoScrollIntoView,
3761
- isContainer: stageOptions.isContainer,
3762
- containerHighlightClassName: stageOptions.containerHighlightClassName,
3763
- containerHighlightDuration: stageOptions.containerHighlightDuration,
3764
- canSelect: (el, event, stop) => {
3765
- const elCanSelect = stageOptions.canSelect(el);
3766
- if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
3767
- document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
3768
- return stop();
3769
- }
3770
- return elCanSelect;
3771
- },
3772
- moveableOptions: stageOptions.moveableOptions,
3773
- updateDragEl: stageOptions.updateDragEl
3774
- });
4084
+ stage = useStage(stageOptions);
3775
4085
  services?.editorService.set("stage", markRaw(stage));
3776
4086
  stage?.mount(stageContainer.value);
3777
- stage.mask.setGuides([
3778
- getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
3779
- getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
3780
- ]);
3781
- stage?.on("select", (el) => {
3782
- services?.editorService.select(el.id);
3783
- });
3784
- stage?.on("highlight", (el) => {
3785
- services?.editorService.highlight(el.id);
3786
- });
3787
- stage?.on("multiSelect", (els) => {
3788
- services?.editorService.multiSelect(els.map((el) => el.id));
3789
- });
3790
- stage?.on("update", (ev) => {
3791
- if (ev.parentEl) {
3792
- services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
3793
- return;
3794
- }
3795
- services?.editorService.update({ id: ev.el.id, style: ev.style });
3796
- });
3797
- stage?.on("sort", (ev) => {
3798
- services?.editorService.sort(ev.src, ev.dist);
3799
- });
3800
- stage?.on("changeGuides", (e2) => {
3801
- services?.uiService.set("showGuides", true);
3802
- if (!root.value || !page.value)
3803
- return;
3804
- const storageKey = getGuideLineKey(e2.type === GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY);
3805
- if (e2.guides.length) {
3806
- globalThis.localStorage.setItem(storageKey, JSON.stringify(e2.guides));
3807
- } else {
3808
- globalThis.localStorage.removeItem(storageKey);
3809
- }
3810
- });
3811
4087
  if (!node.value?.id)
3812
4088
  return;
3813
4089
  stage?.on("runtime-ready", (rt) => {
@@ -3893,12 +4169,14 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3893
4169
  }
3894
4170
  };
3895
4171
  return (_ctx, _cache) => {
3896
- return openBlock(), createBlock(ScrollViewer, {
4172
+ return openBlock(), createBlock(_sfc_main$4, {
3897
4173
  class: "m-editor-stage",
3898
4174
  ref_key: "stageWrap",
3899
4175
  ref: stageWrap,
3900
4176
  width: unref(stageRect)?.width,
3901
4177
  height: unref(stageRect)?.height,
4178
+ "wrap-width": unref(stageContainerRect)?.width,
4179
+ "wrap-height": unref(stageContainerRect)?.height,
3902
4180
  zoom: unref(zoom)
3903
4181
  }, {
3904
4182
  default: withCtx(() => [
@@ -3906,7 +4184,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3906
4184
  class: "m-editor-stage-container",
3907
4185
  ref_key: "stageContainer",
3908
4186
  ref: stageContainer,
3909
- style: normalizeStyle(`transform: scale(${unref(zoom)})`),
4187
+ style: normalizeStyle(`transform: scale(${unref(zoom)});`),
3910
4188
  onContextmenu: contextmenuHandler,
3911
4189
  onDrop: dropHandler,
3912
4190
  onDragover: dragoverHandler
@@ -3920,28 +4198,25 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3920
4198
  ]))
3921
4199
  ]),
3922
4200
  _: 1
3923
- }, 8, ["width", "height", "zoom"]);
4201
+ }, 8, ["width", "height", "wrap-width", "wrap-height", "zoom"]);
3924
4202
  };
3925
4203
  }
3926
4204
  });
3927
4205
 
3928
- const _sfc_main$1 = defineComponent({
3929
- name: "m-editor-workspace",
3930
- components: {
3931
- PageBar: _sfc_main$5,
3932
- MagicStage: _sfc_main$2
3933
- },
3934
- setup() {
4206
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
4207
+ __name: "Workspace",
4208
+ setup(__props) {
3935
4209
  const services = inject("services");
3936
4210
  const workspace = ref();
3937
4211
  const nodes = computed(() => services?.editorService.get("nodes"));
3938
- let keycon;
4212
+ const page = computed(() => services?.editorService.get("page"));
3939
4213
  const mouseenterHandler = () => {
3940
4214
  workspace.value?.focus();
3941
4215
  };
3942
4216
  const mouseleaveHandler = () => {
3943
4217
  workspace.value?.blur();
3944
4218
  };
4219
+ let keycon;
3945
4220
  onMounted(() => {
3946
4221
  workspace.value?.addEventListener("mouseenter", mouseenterHandler);
3947
4222
  workspace.value?.addEventListener("mouseleave", mouseleaveHandler);
@@ -4018,6 +4293,12 @@ const _sfc_main$1 = defineComponent({
4018
4293
  }).keydown([ctrl, "numpad-"], (e) => {
4019
4294
  e.inputEvent.preventDefault();
4020
4295
  services?.uiService.zoom(-0.1);
4296
+ }).keydown([ctrl, "0"], (e) => {
4297
+ e.inputEvent.preventDefault();
4298
+ services?.uiService.set("zoom", services.uiService.calcZoom());
4299
+ }).keydown([ctrl, "1"], (e) => {
4300
+ e.inputEvent.preventDefault();
4301
+ services?.uiService.set("zoom", 1);
4021
4302
  });
4022
4303
  });
4023
4304
  onUnmounted(() => {
@@ -4025,39 +4306,33 @@ const _sfc_main$1 = defineComponent({
4025
4306
  workspace.value?.removeEventListener("mouseleave", mouseleaveHandler);
4026
4307
  keycon.destroy();
4027
4308
  });
4028
- return {
4029
- workspace,
4030
- page: computed(() => services?.editorService.get("page"))
4309
+ return (_ctx, _cache) => {
4310
+ return openBlock(), createElementBlock("div", {
4311
+ class: "m-editor-workspace",
4312
+ tabindex: "1",
4313
+ ref_key: "workspace",
4314
+ ref: workspace
4315
+ }, [
4316
+ renderSlot(_ctx.$slots, "stage", {}, () => [
4317
+ (openBlock(), createBlock(_sfc_main$2, {
4318
+ key: unref(page)?.id
4319
+ }))
4320
+ ]),
4321
+ renderSlot(_ctx.$slots, "workspace-content"),
4322
+ createVNode(_sfc_main$6, null, {
4323
+ "page-bar-title": withCtx(({ page: page2 }) => [
4324
+ renderSlot(_ctx.$slots, "page-bar-title", { page: page2 })
4325
+ ]),
4326
+ "page-bar-popover": withCtx(({ page: page2 }) => [
4327
+ renderSlot(_ctx.$slots, "page-bar-popover", { page: page2 })
4328
+ ]),
4329
+ _: 3
4330
+ })
4331
+ ], 512);
4031
4332
  };
4032
4333
  }
4033
4334
  });
4034
4335
 
4035
- const _hoisted_1 = {
4036
- class: "m-editor-workspace",
4037
- tabindex: "1",
4038
- ref: "workspace"
4039
- };
4040
- function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
4041
- const _component_magic_stage = resolveComponent("magic-stage");
4042
- const _component_page_bar = resolveComponent("page-bar");
4043
- return openBlock(), createElementBlock("div", _hoisted_1, [
4044
- (openBlock(), createBlock(_component_magic_stage, {
4045
- key: _ctx.page?.id
4046
- })),
4047
- renderSlot(_ctx.$slots, "workspace-content"),
4048
- createVNode(_component_page_bar, null, {
4049
- "page-bar-title": withCtx(({ page }) => [
4050
- renderSlot(_ctx.$slots, "page-bar-title", { page })
4051
- ]),
4052
- "page-bar-popover": withCtx(({ page }) => [
4053
- renderSlot(_ctx.$slots, "page-bar-popover", { page })
4054
- ]),
4055
- _: 3
4056
- })
4057
- ], 512);
4058
- }
4059
- const Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
4060
-
4061
4336
  class ComponentList extends BaseService {
4062
4337
  state = reactive({
4063
4338
  list: []
@@ -4071,136 +4346,20 @@ class ComponentList extends BaseService {
4071
4346
  getList() {
4072
4347
  return this.state.list;
4073
4348
  }
4074
- }
4075
- const componentListService = new ComponentList();
4076
-
4077
- const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4078
- const MIN_LEFT_COLUMN_WIDTH = 45;
4079
- const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
4080
- const MIN_RIGHT_COLUMN_WIDTH = 1;
4081
- const COLUMN_WIDTH_STORAGE_KEY = "$MagicEditorColumnWidthData";
4082
- const defaultColumnWidth = {
4083
- left: DEFAULT_LEFT_COLUMN_WIDTH,
4084
- center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4085
- right: DEFAULT_RIGHT_COLUMN_WIDTH
4086
- };
4087
- const state = reactive({
4088
- uiSelectMode: false,
4089
- showSrc: false,
4090
- zoom: 1,
4091
- stageContainerRect: {
4092
- width: 0,
4093
- height: 0
4094
- },
4095
- stageRect: {
4096
- width: 375,
4097
- height: 817
4098
- },
4099
- columnWidth: defaultColumnWidth,
4100
- showGuides: true,
4101
- showRule: true,
4102
- propsPanelSize: "small"
4103
- });
4104
- class Ui extends BaseService {
4105
- constructor() {
4106
- super([]);
4107
- globalThis.addEventListener("resize", () => {
4108
- this.setColumnWidth({
4109
- center: "auto"
4110
- });
4111
- });
4112
- const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
4113
- if (columnWidthCacheData) {
4114
- try {
4115
- const columnWidthCache = JSON.parse(columnWidthCacheData);
4116
- this.setColumnWidth(columnWidthCache);
4117
- } catch (e) {
4118
- console.error(e);
4119
- }
4120
- }
4121
- }
4122
- set(name, value) {
4123
- const mask = editorService.get("stage")?.mask;
4124
- if (name === "columnWidth") {
4125
- this.setColumnWidth(value);
4126
- return;
4127
- }
4128
- if (name === "stageRect") {
4129
- this.setStageRect(value);
4130
- return;
4131
- }
4132
- if (name === "showGuides") {
4133
- mask?.showGuides(value);
4134
- }
4135
- if (name === "showRule") {
4136
- mask?.showRule(value);
4137
- }
4138
- state[name] = value;
4139
- if (name === "stageContainerRect") {
4140
- state.zoom = this.calcZoom();
4141
- }
4142
- }
4143
- get(name) {
4144
- return state[name];
4145
- }
4146
- zoom(zoom) {
4147
- this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
4148
- if (this.get("zoom") < 0.1)
4149
- this.set("zoom", 0.1);
4150
- }
4151
- setColumnWidth({ left, center, right }) {
4152
- const columnWidth = {
4153
- ...toRaw(this.get("columnWidth"))
4154
- };
4155
- if (left) {
4156
- columnWidth.left = Math.max(left, MIN_LEFT_COLUMN_WIDTH);
4157
- }
4158
- if (right) {
4159
- columnWidth.right = Math.max(right, MIN_RIGHT_COLUMN_WIDTH);
4160
- }
4161
- if (!center || center === "auto") {
4162
- const bodyWidth = globalThis.document.body.clientWidth;
4163
- columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
4164
- if (columnWidth.center <= 0) {
4165
- columnWidth.left = defaultColumnWidth.left;
4166
- columnWidth.center = defaultColumnWidth.center;
4167
- columnWidth.right = defaultColumnWidth.right;
4168
- }
4169
- } else {
4170
- columnWidth.center = center;
4171
- }
4172
- globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
4173
- state.columnWidth = columnWidth;
4174
- }
4175
- setStageRect(value) {
4176
- state.stageRect = {
4177
- ...state.stageRect,
4178
- ...value
4179
- };
4180
- state.zoom = this.calcZoom();
4181
- }
4182
- calcZoom() {
4183
- const { stageRect, stageContainerRect } = state;
4184
- const { height, width } = stageContainerRect;
4185
- if (!width || !height)
4186
- return 1;
4187
- const stageWidth = stageRect.width + 30;
4188
- const stageHeight = stageRect.height + 30;
4189
- if (width > stageWidth && height > stageHeight) {
4190
- return 1;
4191
- }
4192
- return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
4349
+ destroy() {
4350
+ this.state.list = [];
4351
+ this.removeAllListeners();
4193
4352
  }
4194
4353
  }
4195
- const uiService = new Ui();
4354
+ const componentListService = new ComponentList();
4196
4355
 
4197
4356
  const _sfc_main = defineComponent({
4198
4357
  name: "m-editor",
4199
4358
  components: {
4200
- NavMenu,
4359
+ NavMenu: _sfc_main$f,
4201
4360
  Sidebar,
4202
- Workspace,
4203
- PropsPanel,
4361
+ Workspace: _sfc_main$1,
4362
+ PropsPanel: _sfc_main$e,
4204
4363
  Framework
4205
4364
  },
4206
4365
  props: {
@@ -4267,6 +4426,10 @@ const _sfc_main = defineComponent({
4267
4426
  type: Number,
4268
4427
  default: 800
4269
4428
  },
4429
+ containerHighlightType: {
4430
+ type: String,
4431
+ default: ContainerHighlightType.DEFAULT
4432
+ },
4270
4433
  stageRect: {
4271
4434
  type: [String, Object]
4272
4435
  },
@@ -4280,9 +4443,14 @@ const _sfc_main = defineComponent({
4280
4443
  },
4281
4444
  emits: ["props-panel-mounted", "update:modelValue"],
4282
4445
  setup(props, { emit }) {
4283
- editorService.on("root-change", () => {
4284
- const node = editorService.get("node") || props.defaultSelected;
4285
- node && editorService.select(node);
4446
+ editorService.on("root-change", (value) => {
4447
+ const node = editorService.get("node");
4448
+ const nodeId = node?.id || props.defaultSelected;
4449
+ if (nodeId && node !== value) {
4450
+ editorService.select(nodeId);
4451
+ } else {
4452
+ editorService.set("nodes", [value]);
4453
+ }
4286
4454
  emit("update:modelValue", toRaw(editorService.get("root")));
4287
4455
  });
4288
4456
  watch(() => props.modelValue, (modelValue) => editorService.set("root", modelValue), {
@@ -4315,7 +4483,15 @@ const _sfc_main = defineComponent({
4315
4483
  watch(() => props.stageRect, (stageRect) => stageRect && uiService.set("stageRect", stageRect), {
4316
4484
  immediate: true
4317
4485
  });
4318
- onUnmounted(() => editorService.destroy());
4486
+ uiService.initColumnWidth();
4487
+ onUnmounted(() => {
4488
+ editorService.destroy();
4489
+ historyService.destroy();
4490
+ propsService.destroy();
4491
+ uiService.destroy();
4492
+ componentListService.destroy();
4493
+ storageService.destroy();
4494
+ });
4319
4495
  const services = {
4320
4496
  componentListService,
4321
4497
  eventsService,
@@ -4337,7 +4513,8 @@ const _sfc_main = defineComponent({
4337
4513
  updateDragEl: props.updateDragEl,
4338
4514
  isContainer: props.isContainer,
4339
4515
  containerHighlightClassName: props.containerHighlightClassName,
4340
- containerHighlightDuration: props.containerHighlightDuration
4516
+ containerHighlightDuration: props.containerHighlightDuration,
4517
+ containerHighlightType: props.containerHighlightType
4341
4518
  }));
4342
4519
  return services;
4343
4520
  }
@@ -4371,6 +4548,9 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
4371
4548
  workspace: withCtx(() => [
4372
4549
  renderSlot(_ctx.$slots, "workspace", { editorService: _ctx.editorService }, () => [
4373
4550
  createVNode(_component_workspace, null, {
4551
+ stage: withCtx(() => [
4552
+ renderSlot(_ctx.$slots, "stage")
4553
+ ]),
4374
4554
  "workspace-content": withCtx(() => [
4375
4555
  renderSlot(_ctx.$slots, "workspace-content", { editorService: _ctx.editorService })
4376
4556
  ]),
@@ -4387,14 +4567,13 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
4387
4567
  "props-panel": withCtx(() => [
4388
4568
  renderSlot(_ctx.$slots, "props-panel", {}, () => [
4389
4569
  createVNode(_component_props_panel, {
4390
- ref: "propsPanel",
4391
4570
  onMounted: _cache[0] || (_cache[0] = (instance) => _ctx.$emit("props-panel-mounted", instance))
4392
4571
  }, {
4393
4572
  "props-panel-header": withCtx(() => [
4394
4573
  renderSlot(_ctx.$slots, "props-panel-header")
4395
4574
  ]),
4396
4575
  _: 3
4397
- }, 512)
4576
+ })
4398
4577
  ])
4399
4578
  ]),
4400
4579
  empty: withCtx(() => [
@@ -4414,12 +4593,12 @@ const index = {
4414
4593
  app.config.globalProperties.$TMAGIC_EDITOR = option;
4415
4594
  setConfig(option);
4416
4595
  app.component(Editor.name, Editor);
4417
- app.component("m-fields-ui-select", _sfc_main$l);
4596
+ app.component("m-fields-ui-select", _sfc_main$m);
4418
4597
  app.component(CodeLink.name, CodeLink);
4419
4598
  app.component(Code.name, Code);
4420
4599
  app.component(CodeEditor.name, CodeEditor);
4421
4600
  }
4422
4601
  };
4423
4602
 
4424
- export { COPY_STORAGE_KEY, ComponentListPanel, DEFAULT_CONFIG, Fixed2Other, H_GUIDE_LINE_STORAGE_KEY, Keys, LayerOffset, LayerPanel, Layout, PropsPanel, CodeEditor as TMagicCodeEditor, Editor as TMagicEditor, _sfc_main$f as ToolButton, V_GUIDE_LINE_STORAGE_KEY, change2Fixed, debug, index as default, editorService, error, eventsService, fillConfig, fixNodeLeft, fixNodePosition, generatePageName, generatePageNameByApp, getConfig, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageList, getPageNameList, getRelativeStyle, historyService, info, isFixed, log, propsService, setConfig, setLayout, storageService, uiService, warn };
4603
+ export { COPY_STORAGE_KEY, ColumnLayout, ComponentListPanel, _sfc_main$c as ContentMenu, Fixed2Other, H_GUIDE_LINE_STORAGE_KEY, _sfc_main$h as Icon, Keys, LayerOffset, LayerPanel, Layout, _sfc_main$e as PropsPanel, CodeEditor as TMagicCodeEditor, Editor as TMagicEditor, _sfc_main$g as ToolButton, V_GUIDE_LINE_STORAGE_KEY, change2Fixed, debug, index as default, editorService, error, eventsService, fillConfig, fixNodeLeft, fixNodePosition, generatePageName, generatePageNameByApp, getConfig, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageList, getPageNameList, getRelativeStyle, historyService, info, isFixed, log, propsService, setConfig, setLayout, storageService, uiService, useStage, warn };
4425
4604
  //# sourceMappingURL=tmagic-editor.mjs.map