@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
@@ -37,7 +37,7 @@
37
37
  window.globalThis = window;
38
38
  }
39
39
 
40
- const _sfc_main$n = vue.defineComponent({
40
+ const _sfc_main$o = vue.defineComponent({
41
41
  name: "m-fields-vs-code",
42
42
  props: ["model", "name", "config", "prop"],
43
43
  emits: ["change"],
@@ -63,7 +63,7 @@
63
63
  return target;
64
64
  };
65
65
 
66
- function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
66
+ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
67
67
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
68
68
  return vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
69
69
  style: vue.normalizeStyle(`height: ${_ctx.height}`),
@@ -72,9 +72,9 @@
72
72
  onSave: _ctx.save
73
73
  }, null, 8, ["style", "init-values", "language", "onSave"]);
74
74
  }
75
- const Code = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$g]]);
75
+ const Code = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render$b]]);
76
76
 
77
- const _sfc_main$m = vue.defineComponent({
77
+ const _sfc_main$n = vue.defineComponent({
78
78
  name: "m-fields-code-link",
79
79
  props: {
80
80
  config: {
@@ -130,7 +130,7 @@
130
130
  }
131
131
  });
132
132
 
133
- function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
133
+ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
134
134
  const _component_m_fields_link = vue.resolveComponent("m-fields-link");
135
135
  return vue.openBlock(), vue.createBlock(_component_m_fields_link, {
136
136
  config: _ctx.formConfig,
@@ -139,10 +139,10 @@
139
139
  onChange: _ctx.changeHandler
140
140
  }, null, 8, ["config", "model", "onChange"]);
141
141
  }
142
- const CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$f]]);
142
+ const CodeLink = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$a]]);
143
143
 
144
- const _hoisted_1$d = /* @__PURE__ */ vue.createTextVNode("\u53D6\u6D88");
145
- const _sfc_main$l = /* @__PURE__ */ vue.defineComponent({
144
+ const _hoisted_1$b = /* @__PURE__ */ vue.createTextVNode("\u53D6\u6D88");
145
+ const _sfc_main$m = /* @__PURE__ */ vue.defineComponent({
146
146
  __name: "UISelect",
147
147
  props: {
148
148
  config: null,
@@ -207,7 +207,7 @@
207
207
  style: { "padding": "0" }
208
208
  }, {
209
209
  default: vue.withCtx(() => [
210
- _hoisted_1$d
210
+ _hoisted_1$b
211
211
  ]),
212
212
  _: 1
213
213
  }, 8, ["icon"])
@@ -217,19 +217,21 @@
217
217
  onClick: startSelect,
218
218
  style: { "display": "flex" }
219
219
  }, [
220
- vue.createVNode(_component_el_tooltip, { content: "\u6E05\u9664" }, {
220
+ vue.unref(val) ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
221
+ key: 0,
222
+ content: "\u6E05\u9664"
223
+ }, {
221
224
  default: vue.withCtx(() => [
222
- vue.unref(val) ? (vue.openBlock(), vue.createBlock(_component_el_button, {
223
- key: 0,
225
+ vue.createVNode(_component_el_button, {
224
226
  style: { "padding": "0" },
225
227
  type: "danger",
226
228
  icon: vue.unref(iconsVue.Close),
227
229
  text: "",
228
230
  onClick: vue.withModifiers(deleteHandler, ["stop"])
229
- }, null, 8, ["icon", "onClick"])) : vue.createCommentVNode("", true)
231
+ }, null, 8, ["icon", "onClick"])
230
232
  ]),
231
233
  _: 1
232
- }),
234
+ })) : vue.createCommentVNode("", true),
233
235
  vue.createVNode(_component_el_tooltip, {
234
236
  content: vue.unref(val) ? vue.unref(toName) + "_" + vue.unref(val) : "\u70B9\u51FB\u6B64\u5904\u9009\u62E9"
235
237
  }, {
@@ -268,7 +270,7 @@
268
270
  }
269
271
  return value;
270
272
  };
271
- const _sfc_main$k = vue.defineComponent({
273
+ const _sfc_main$l = vue.defineComponent({
272
274
  name: "magic-code-editor",
273
275
  props: {
274
276
  initValues: {
@@ -376,14 +378,14 @@
376
378
  }
377
379
  });
378
380
 
379
- const _hoisted_1$c = {
381
+ const _hoisted_1$a = {
380
382
  ref: "codeEditor",
381
383
  class: "magic-code-editor"
382
384
  };
383
- function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
384
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, null, 512);
385
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
386
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, null, 512);
385
387
  }
386
- const CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$e]]);
388
+ const CodeEditor = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$9]]);
387
389
 
388
390
  let $TMAGIC_EDITOR = {};
389
391
  const setConfig = (option) => {
@@ -691,6 +693,9 @@
691
693
  }
692
694
  storage2.setItem(`${options2.namespace || namespace2}:${key2}`, item2);
693
695
  }
696
+ destroy() {
697
+ this.removeAllListeners();
698
+ }
694
699
  getValueAndProtocol(value) {
695
700
  let protocol2 = "";
696
701
  if (value === null) {
@@ -711,6 +716,12 @@
711
716
  }
712
717
  const storageService = new WebStorage();
713
718
 
719
+ var ColumnLayout = /* @__PURE__ */ ((ColumnLayout2) => {
720
+ ColumnLayout2["LEFT"] = "left";
721
+ ColumnLayout2["CENTER"] = "center";
722
+ ColumnLayout2["RIGHT"] = "right";
723
+ return ColumnLayout2;
724
+ })(ColumnLayout || {});
714
725
  var LayerOffset = /* @__PURE__ */ ((LayerOffset2) => {
715
726
  LayerOffset2["TOP"] = "top";
716
727
  LayerOffset2["BOTTOM"] = "bottom";
@@ -895,6 +906,7 @@
895
906
  "getPropsValue",
896
907
  "createId",
897
908
  "setNewItemId",
909
+ "fillConfig",
898
910
  "getDefaultPropsValue"
899
911
  ]);
900
912
  }
@@ -904,14 +916,17 @@
904
916
  });
905
917
  this.emit("props-configs-change");
906
918
  }
907
- setPropsConfig(type, config) {
908
- this.state.propsConfigMap[type] = fillConfig(Array.isArray(config) ? config : [config]);
919
+ async fillConfig(config) {
920
+ return fillConfig(config);
921
+ }
922
+ async setPropsConfig(type, config) {
923
+ this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
909
924
  }
910
925
  async getPropsConfig(type) {
911
926
  if (type === "area") {
912
927
  return await this.getPropsConfig("button");
913
928
  }
914
- return lodashEs.cloneDeep(this.state.propsConfigMap[type] || DEFAULT_CONFIG);
929
+ return lodashEs.cloneDeep(this.state.propsConfigMap[type] || await this.fillConfig([]));
915
930
  }
916
931
  setPropsValues(values) {
917
932
  Object.keys(values).forEach((type) => {
@@ -945,25 +960,14 @@
945
960
  ...lodashEs.mergeWith({}, lodashEs.cloneDeep(this.state.propsValueMap[type] || {}), data)
946
961
  };
947
962
  }
948
- guid(digit = 8) {
949
- return "x".repeat(digit).replace(/[xy]/g, (c) => {
950
- const r = Math.random() * 16 | 0;
951
- const v = c == "x" ? r : r & 3 | 8;
952
- return v.toString(16);
953
- });
954
- }
955
963
  async createId(type) {
956
964
  return `${type}_${this.guid()}`;
957
965
  }
958
- async setNewItemId(config, parent) {
959
- const oldId = config.id;
966
+ async setNewItemId(config) {
960
967
  config.id = await this.createId(config.type || "component");
961
- if (utils.isPop(config) && parent?.type === schema.NodeType.PAGE) {
962
- updatePopId(oldId, config.id, parent);
963
- }
964
968
  if (config.items && Array.isArray(config.items)) {
965
969
  for (const item of config.items) {
966
- await this.setNewItemId(item, config);
970
+ await this.setNewItemId(item);
967
971
  }
968
972
  }
969
973
  return config;
@@ -981,22 +985,19 @@
981
985
  name: type
982
986
  };
983
987
  }
988
+ destroy() {
989
+ this.state.propsConfigMap = {};
990
+ this.state.propsValueMap = {};
991
+ this.removeAllListeners();
992
+ }
993
+ guid(digit = 8) {
994
+ return "x".repeat(digit).replace(/[xy]/g, (c) => {
995
+ const r = Math.random() * 16 | 0;
996
+ const v = c === "x" ? r : r & 3 | 8;
997
+ return v.toString(16);
998
+ });
999
+ }
984
1000
  }
985
- const updatePopId = (oldId, popId, pageConfig) => {
986
- pageConfig.items?.forEach((config) => {
987
- if (config.pop === oldId) {
988
- config.pop = popId;
989
- return;
990
- }
991
- if (config.popId === oldId) {
992
- config.popId = popId;
993
- return;
994
- }
995
- if (Array.isArray(config.items)) {
996
- updatePopId(oldId, popId, config);
997
- }
998
- });
999
- };
1000
1001
  const propsService = new Props();
1001
1002
 
1002
1003
  const beforePaste = async (position, config) => {
@@ -1016,7 +1017,7 @@
1016
1017
  if (pastePosition.top && configItem.style?.top) {
1017
1018
  pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
1018
1019
  }
1019
- const pasteConfig = await propsService.setNewItemId(configItem, editorService.get("root"));
1020
+ const pasteConfig = await propsService.setNewItemId(configItem);
1020
1021
  if (pasteConfig.style) {
1021
1022
  const { left, top } = pasteConfig.style;
1022
1023
  if (typeof left === "number" || !!left && !isNaN(Number(left))) {
@@ -1048,48 +1049,10 @@
1048
1049
  top
1049
1050
  };
1050
1051
  };
1051
- const beforeRemove = async (node) => {
1052
- if (!node?.id)
1053
- return;
1054
- const stage = editorService.get("stage");
1055
- const root = editorService.get("root");
1056
- if (!root)
1057
- throw new Error("\u6CA1\u6709root");
1058
- const { parent, node: curNode } = editorService.getNodeInfo(node.id, false);
1059
- if (!parent || !curNode)
1060
- throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1061
- const index = getNodeIndex(curNode, parent);
1062
- if (typeof index !== "number" || index === -1)
1063
- throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1064
- parent.items?.splice(index, 1);
1065
- stage?.remove({ id: node.id, root: lodashEs.cloneDeep(root) });
1066
- if (node.type === schema.NodeType.PAGE) {
1067
- editorService.state.pageLength -= 1;
1068
- if (root.items[0]) {
1069
- await editorService.select(root.items[0]);
1070
- stage?.select(root.items[0].id);
1071
- } else {
1072
- editorService.set("node", null);
1073
- editorService.set("nodes", []);
1074
- editorService.set("parent", null);
1075
- editorService.set("page", null);
1076
- editorService.set("stage", null);
1077
- editorService.set("highlightNode", null);
1078
- editorService.resetModifiedNodeId();
1079
- historyService.reset();
1080
- editorService.emit("remove", node);
1081
- return;
1082
- }
1083
- } else {
1084
- await editorService.select(parent);
1085
- stage?.select(parent.id);
1086
- }
1087
- return parent;
1088
- };
1089
- const getAddParent = (addNode) => {
1052
+ const getAddParent = (node) => {
1090
1053
  const curNode = editorService.get("node");
1091
1054
  let parentNode;
1092
- if (!Array.isArray(addNode) && utils.isPage(addNode)) {
1055
+ if (utils.isPage(node)) {
1093
1056
  parentNode = editorService.get("root");
1094
1057
  } else if (curNode.items) {
1095
1058
  parentNode = curNode;
@@ -1118,11 +1081,15 @@
1118
1081
  "select",
1119
1082
  "doAdd",
1120
1083
  "add",
1084
+ "doRemove",
1121
1085
  "remove",
1086
+ "doUpdate",
1122
1087
  "update",
1123
1088
  "sort",
1124
1089
  "copy",
1125
1090
  "paste",
1091
+ "doPaste",
1092
+ "duAlignCenter",
1126
1093
  "alignCenter",
1127
1094
  "moveLayer",
1128
1095
  "moveToContainer",
@@ -1258,20 +1225,27 @@
1258
1225
  if ((parent?.type === schema.NodeType.ROOT || curNode.type === schema.NodeType.ROOT) && node.type !== schema.NodeType.PAGE) {
1259
1226
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
1260
1227
  }
1228
+ if (parent.id !== curNode.id) {
1229
+ const index = parent.items.indexOf(curNode);
1230
+ parent?.items?.splice(index + 1, 0, node);
1231
+ } else {
1232
+ parent?.items?.push(node);
1233
+ }
1261
1234
  const layout = await this.getLayout(vue.toRaw(parent), node);
1262
1235
  node.style = getInitPositionStyle(node.style, layout);
1263
- await stage?.add({ config: lodashEs.cloneDeep(node), parent: lodashEs.cloneDeep(parent), root: lodashEs.cloneDeep(root) });
1236
+ await stage?.add({
1237
+ config: lodashEs.cloneDeep(node),
1238
+ parent: lodashEs.cloneDeep(parent),
1239
+ parentId: parent.id,
1240
+ root: lodashEs.cloneDeep(root)
1241
+ });
1264
1242
  node.style = fixNodePosition(node, parent, stage);
1265
- await stage?.update({ config: lodashEs.cloneDeep(node), root: lodashEs.cloneDeep(root) });
1266
- parent?.items?.push(node);
1243
+ await stage?.update({ config: lodashEs.cloneDeep(node), parentId: parent.id, root: lodashEs.cloneDeep(root) });
1267
1244
  this.addModifiedNodeId(node.id);
1268
1245
  return node;
1269
1246
  }
1270
1247
  async add(addNode, parent) {
1271
1248
  const stage = this.get("stage");
1272
- const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(addNode);
1273
- if (!parentNode)
1274
- throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
1275
1249
  const addNodes = [];
1276
1250
  if (!Array.isArray(addNode)) {
1277
1251
  const { type, inputEvent, ...config } = addNode;
@@ -1281,7 +1255,12 @@
1281
1255
  } else {
1282
1256
  addNodes.push(...addNode);
1283
1257
  }
1284
- const newNodes = await Promise.all(addNodes.map((node) => this.doAdd(node, parentNode)));
1258
+ const newNodes = await Promise.all(addNodes.map((node) => {
1259
+ const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(node);
1260
+ if (!parentNode)
1261
+ throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
1262
+ return this.doAdd(node, parentNode);
1263
+ }));
1285
1264
  if (newNodes.length > 1) {
1286
1265
  const newNodeIds = newNodes.map((node) => node.id);
1287
1266
  stage?.multiSelect(newNodeIds);
@@ -1296,33 +1275,49 @@
1296
1275
  }
1297
1276
  this.pushHistoryState();
1298
1277
  this.emit("add", newNodes);
1299
- return newNodes.length > 1 ? newNodes[0] : newNodes;
1278
+ return Array.isArray(addNode) ? newNodes : newNodes[0];
1300
1279
  }
1301
- async remove(nodeOrNodeList) {
1302
- if (Array.isArray(nodeOrNodeList)) {
1303
- const nodes = nodeOrNodeList;
1304
- return this.multiRemove(nodes);
1280
+ async doRemove(node) {
1281
+ const root = this.get("root");
1282
+ if (!root)
1283
+ throw new Error("\u6CA1\u6709root");
1284
+ const { parent, node: curNode } = this.getNodeInfo(node.id);
1285
+ if (!parent || !curNode)
1286
+ throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1287
+ const index = getNodeIndex(curNode, parent);
1288
+ if (typeof index !== "number" || index === -1)
1289
+ throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1290
+ parent.items?.splice(index, 1);
1291
+ const stage = this.get("stage");
1292
+ stage?.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
1293
+ if (node.type === schema.NodeType.PAGE) {
1294
+ this.state.pageLength -= 1;
1295
+ if (root.items[0]) {
1296
+ await this.select(root.items[0]);
1297
+ stage?.select(root.items[0].id);
1298
+ } else {
1299
+ this.set("nodes", [root]);
1300
+ this.set("parent", null);
1301
+ this.set("page", null);
1302
+ this.set("stage", null);
1303
+ this.set("highlightNode", null);
1304
+ this.resetModifiedNodeId();
1305
+ historyService.reset();
1306
+ return;
1307
+ }
1308
+ } else {
1309
+ await this.select(parent);
1310
+ stage?.select(parent.id);
1305
1311
  }
1306
- const node = nodeOrNodeList;
1307
- const removeParent = await beforeRemove(node);
1308
- if (!removeParent)
1309
- return node;
1310
- this.addModifiedNodeId(removeParent.id);
1311
- this.pushHistoryState();
1312
- this.emit("remove", node);
1313
- return node;
1312
+ this.addModifiedNodeId(parent.id);
1314
1313
  }
1315
- async multiRemove(nodes) {
1316
- await Promise.all(nodes.map(async (removeNode) => {
1317
- await beforeRemove(removeNode);
1318
- }));
1319
- const nodeIds = nodes.map((node) => node.id);
1320
- this.addModifiedNodeId(nodeIds.join("-"));
1314
+ async remove(nodeOrNodeList) {
1315
+ const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
1316
+ await Promise.all(nodes.map((node) => this.doRemove(node)));
1321
1317
  this.pushHistoryState();
1322
- this.emit("multiRemove", nodes);
1323
- return nodes;
1318
+ this.emit("remove", nodes);
1324
1319
  }
1325
- async update(config) {
1320
+ async doUpdate(config) {
1326
1321
  if (!config?.id)
1327
1322
  throw new Error("\u6CA1\u6709\u914D\u7F6E\u6216\u8005\u914D\u7F6E\u7F3A\u5C11id\u503C");
1328
1323
  const info = this.getNodeInfo(config.id, false);
@@ -1358,15 +1353,24 @@
1358
1353
  const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
1359
1354
  nodes.splice(targetIndex, 1, newConfig);
1360
1355
  this.set("nodes", nodes);
1361
- this.get("stage")?.update({ config: lodashEs.cloneDeep(newConfig), root: lodashEs.cloneDeep(this.get("root")) });
1356
+ this.get("stage")?.update({
1357
+ config: lodashEs.cloneDeep(newConfig),
1358
+ parentId: parent.id,
1359
+ root: lodashEs.cloneDeep(this.get("root"))
1360
+ });
1362
1361
  if (newConfig.type === schema.NodeType.PAGE) {
1363
1362
  this.set("page", newConfig);
1364
1363
  }
1365
1364
  this.addModifiedNodeId(newConfig.id);
1366
- this.pushHistoryState();
1367
- this.emit("update", newConfig);
1368
1365
  return newConfig;
1369
1366
  }
1367
+ async update(config) {
1368
+ const nodes = Array.isArray(config) ? config : [config];
1369
+ const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
1370
+ this.pushHistoryState();
1371
+ this.emit("update", newNodes);
1372
+ return Array.isArray(config) ? newNodes : newNodes[0];
1373
+ }
1370
1374
  async sort(id1, id2) {
1371
1375
  const node = this.get("node");
1372
1376
  const parent = lodashEs.cloneDeep(vue.toRaw(this.get("parent")));
@@ -1377,7 +1381,11 @@
1377
1381
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
1378
1382
  await this.update(parent);
1379
1383
  await this.select(node);
1380
- this.get("stage")?.update({ config: lodashEs.cloneDeep(node), root: lodashEs.cloneDeep(this.get("root")) });
1384
+ this.get("stage")?.update({
1385
+ config: lodashEs.cloneDeep(node),
1386
+ parentId: parent.id,
1387
+ root: lodashEs.cloneDeep(this.get("root"))
1388
+ });
1381
1389
  this.addModifiedNodeId(parent.id);
1382
1390
  this.pushHistoryState();
1383
1391
  }
@@ -1390,18 +1398,24 @@
1390
1398
  const config = await storageService.getItem(COPY_STORAGE_KEY);
1391
1399
  if (!Array.isArray(config))
1392
1400
  return;
1393
- const pasteConfigs = await beforePaste(position, config);
1401
+ const pasteConfigs = await this.doPaste(config, position);
1394
1402
  return this.add(pasteConfigs);
1395
1403
  }
1396
- async alignCenter(config) {
1397
- const parent = this.get("parent");
1398
- const node = this.get("node");
1399
- const layout = await this.getLayout(vue.toRaw(parent), vue.toRaw(node));
1404
+ async doPaste(config, position = {}) {
1405
+ const pasteConfigs = await beforePaste(position, lodashEs.cloneDeep(config));
1406
+ return pasteConfigs;
1407
+ }
1408
+ async doAlignCenter(config) {
1409
+ const parent = this.getParentById(config.id);
1410
+ if (!parent)
1411
+ throw new Error("\u627E\u4E0D\u5230\u7236\u8282\u70B9");
1412
+ const node = lodashEs.cloneDeep(vue.toRaw(config));
1413
+ const layout = await this.getLayout(parent, node);
1400
1414
  if (layout === Layout.RELATIVE) {
1401
- return;
1415
+ return config;
1402
1416
  }
1403
1417
  if (!node.style)
1404
- return;
1418
+ return config;
1405
1419
  const stage = this.get("stage");
1406
1420
  const doc = stage?.renderer.contentWindow?.document;
1407
1421
  if (doc) {
@@ -1413,14 +1427,15 @@
1413
1427
  } else if (parent.style && utils.isNumber(parent.style?.width) && utils.isNumber(node.style?.width)) {
1414
1428
  node.style.left = (parent.style.width - node.style.width) / 2;
1415
1429
  }
1416
- await this.update(node);
1417
- this.get("stage")?.update({
1418
- config: lodashEs.cloneDeep(vue.toRaw(node)),
1419
- root: lodashEs.cloneDeep(this.get("root"))
1420
- });
1421
- this.addModifiedNodeId(config.id);
1422
- this.pushHistoryState();
1423
- return config;
1430
+ return node;
1431
+ }
1432
+ async alignCenter(config) {
1433
+ const nodes = Array.isArray(config) ? config : [config];
1434
+ const stage = this.get("stage");
1435
+ const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
1436
+ const newNode = await this.update(newNodes);
1437
+ await stage?.multiSelect(newNodes.map((node) => node.id));
1438
+ return newNode;
1424
1439
  }
1425
1440
  async moveLayer(offset) {
1426
1441
  const parent = this.get("parent");
@@ -1434,10 +1449,14 @@
1434
1449
  } else {
1435
1450
  brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
1436
1451
  }
1452
+ const grandparent = this.getParentById(parent.id);
1437
1453
  this.get("stage")?.update({
1438
1454
  config: lodashEs.cloneDeep(vue.toRaw(parent)),
1455
+ parentId: grandparent?.id,
1439
1456
  root: lodashEs.cloneDeep(this.get("root"))
1440
1457
  });
1458
+ this.addModifiedNodeId(parent.id);
1459
+ this.pushHistoryState();
1441
1460
  }
1442
1461
  async moveToContainer(config, targetId) {
1443
1462
  const { node, parent } = this.getNodeInfo(config.id, false);
@@ -1447,7 +1466,7 @@
1447
1466
  const root = lodashEs.cloneDeep(this.get("root"));
1448
1467
  const index = getNodeIndex(node, parent);
1449
1468
  parent.items?.splice(index, 1);
1450
- await stage.remove({ id: node.id, root });
1469
+ await stage.remove({ id: node.id, parentId: parent.id, root });
1451
1470
  const layout = await this.getLayout(target);
1452
1471
  const newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), config, (objValue, srcValue) => {
1453
1472
  if (Array.isArray(srcValue)) {
@@ -1457,7 +1476,8 @@
1457
1476
  newConfig.style = getInitPositionStyle(newConfig.style, layout);
1458
1477
  target.items.push(newConfig);
1459
1478
  await stage.select(targetId);
1460
- await stage.update({ config: lodashEs.cloneDeep(target), root });
1479
+ const targetParent = this.getParentById(target.id);
1480
+ await stage.update({ config: lodashEs.cloneDeep(target), parentId: targetParent?.id, root });
1461
1481
  await this.select(newConfig);
1462
1482
  stage.select(newConfig.id);
1463
1483
  this.addModifiedNodeId(target.id);
@@ -1504,6 +1524,10 @@
1504
1524
  this.set("nodes", []);
1505
1525
  this.set("page", null);
1506
1526
  this.set("parent", null);
1527
+ this.set("stage", null);
1528
+ this.set("highlightNode", null);
1529
+ this.set("modifiedNodeIds", /* @__PURE__ */ new Map());
1530
+ this.set("pageLength", /* @__PURE__ */ new Map());
1507
1531
  }
1508
1532
  resetModifiedNodeId() {
1509
1533
  this.get("modifiedNodeIds").clear();
@@ -1573,8 +1597,8 @@
1573
1597
  }
1574
1598
  const editorService = new Editor$1();
1575
1599
 
1576
- const eventMap = vue.reactive({});
1577
- const methodMap = vue.reactive({});
1600
+ let eventMap = vue.reactive({});
1601
+ let methodMap = vue.reactive({});
1578
1602
  class Events extends BaseService {
1579
1603
  constructor() {
1580
1604
  super([]);
@@ -1614,6 +1638,11 @@
1614
1638
  getMethod(type) {
1615
1639
  return lodashEs.cloneDeep(methodMap[type] || core.DEFAULT_METHODS);
1616
1640
  }
1641
+ destroy() {
1642
+ eventMap = vue.reactive({});
1643
+ methodMap = vue.reactive({});
1644
+ this.removeAllListeners();
1645
+ }
1617
1646
  }
1618
1647
  const eventsService = new Events();
1619
1648
 
@@ -1820,7 +1849,6 @@
1820
1849
  ]
1821
1850
  }
1822
1851
  ];
1823
- const DEFAULT_CONFIG = fillConfig([]);
1824
1852
 
1825
1853
  const log = (...args) => {
1826
1854
  if (process.env.NODE_ENV === "development") {
@@ -1848,7 +1876,194 @@
1848
1876
  }
1849
1877
  };
1850
1878
 
1851
- const _sfc_main$j = vue.defineComponent({
1879
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
1880
+ const MIN_LEFT_COLUMN_WIDTH = 45;
1881
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
1882
+ const MIN_RIGHT_COLUMN_WIDTH = 1;
1883
+ const COLUMN_WIDTH_STORAGE_KEY = "$MagicEditorColumnWidthData";
1884
+ const defaultColumnWidth = {
1885
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
1886
+ center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
1887
+ right: DEFAULT_RIGHT_COLUMN_WIDTH
1888
+ };
1889
+ const state = vue.reactive({
1890
+ uiSelectMode: false,
1891
+ showSrc: false,
1892
+ zoom: 1,
1893
+ stageContainerRect: {
1894
+ width: 0,
1895
+ height: 0
1896
+ },
1897
+ stageRect: {
1898
+ width: 375,
1899
+ height: 817
1900
+ },
1901
+ columnWidth: defaultColumnWidth,
1902
+ showGuides: true,
1903
+ showRule: true,
1904
+ propsPanelSize: "small"
1905
+ });
1906
+ class Ui extends BaseService {
1907
+ constructor() {
1908
+ super([]);
1909
+ globalThis.addEventListener("resize", () => {
1910
+ this.setColumnWidth({
1911
+ center: "auto"
1912
+ });
1913
+ });
1914
+ }
1915
+ set(name, value) {
1916
+ const mask = editorService.get("stage")?.mask;
1917
+ if (name === "columnWidth") {
1918
+ this.setColumnWidth(value);
1919
+ return;
1920
+ }
1921
+ if (name === "stageRect") {
1922
+ this.setStageRect(value);
1923
+ return;
1924
+ }
1925
+ if (name === "showGuides") {
1926
+ mask?.showGuides(value);
1927
+ }
1928
+ if (name === "showRule") {
1929
+ mask?.showRule(value);
1930
+ }
1931
+ state[name] = value;
1932
+ }
1933
+ get(name) {
1934
+ return state[name];
1935
+ }
1936
+ initColumnWidth() {
1937
+ const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
1938
+ if (columnWidthCacheData) {
1939
+ try {
1940
+ const columnWidthCache = JSON.parse(columnWidthCacheData);
1941
+ this.setColumnWidth(columnWidthCache);
1942
+ } catch (e) {
1943
+ console.error(e);
1944
+ }
1945
+ }
1946
+ }
1947
+ zoom(zoom) {
1948
+ this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
1949
+ if (this.get("zoom") < 0.1)
1950
+ this.set("zoom", 0.1);
1951
+ }
1952
+ calcZoom() {
1953
+ const { stageRect, stageContainerRect } = state;
1954
+ const { height, width } = stageContainerRect;
1955
+ if (!width || !height)
1956
+ return 1;
1957
+ const stageWidth = stageRect.width + 30;
1958
+ const stageHeight = stageRect.height + 30;
1959
+ if (width > stageWidth && height > stageHeight) {
1960
+ return 1;
1961
+ }
1962
+ return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
1963
+ }
1964
+ destroy() {
1965
+ this.removeAllListeners();
1966
+ }
1967
+ setColumnWidth({ left, center, right }) {
1968
+ const columnWidth = {
1969
+ ...vue.toRaw(this.get("columnWidth"))
1970
+ };
1971
+ if (left) {
1972
+ columnWidth.left = Math.max(left, MIN_LEFT_COLUMN_WIDTH);
1973
+ }
1974
+ if (right) {
1975
+ columnWidth.right = Math.max(right, MIN_RIGHT_COLUMN_WIDTH);
1976
+ }
1977
+ if (!center || center === "auto") {
1978
+ const bodyWidth = globalThis.document.body.clientWidth;
1979
+ columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
1980
+ if (columnWidth.center <= 0) {
1981
+ columnWidth.left = defaultColumnWidth.left;
1982
+ columnWidth.center = defaultColumnWidth.center;
1983
+ columnWidth.right = defaultColumnWidth.right;
1984
+ }
1985
+ } else {
1986
+ columnWidth.center = center;
1987
+ }
1988
+ globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
1989
+ state.columnWidth = columnWidth;
1990
+ }
1991
+ setStageRect(value) {
1992
+ state.stageRect = {
1993
+ ...state.stageRect,
1994
+ ...value
1995
+ };
1996
+ state.zoom = this.calcZoom();
1997
+ }
1998
+ }
1999
+ const uiService = new Ui();
2000
+
2001
+ const root = vue.computed(() => editorService.get("root"));
2002
+ const page = vue.computed(() => editorService.get("page"));
2003
+ const zoom = vue.computed(() => uiService.get("zoom") || 1);
2004
+ const uiSelectMode = vue.computed(() => uiService.get("uiSelectMode"));
2005
+ const getGuideLineKey = (key) => `${key}_${root.value?.id}_${page.value?.id}`;
2006
+ const useStage = (stageOptions) => {
2007
+ const stage = new StageCore__default.default({
2008
+ render: stageOptions.render,
2009
+ runtimeUrl: stageOptions.runtimeUrl,
2010
+ zoom: zoom.value,
2011
+ autoScrollIntoView: stageOptions.autoScrollIntoView,
2012
+ isContainer: stageOptions.isContainer,
2013
+ containerHighlightClassName: stageOptions.containerHighlightClassName,
2014
+ containerHighlightDuration: stageOptions.containerHighlightDuration,
2015
+ containerHighlightType: stageOptions.containerHighlightType,
2016
+ canSelect: (el, event, stop) => {
2017
+ const elCanSelect = stageOptions.canSelect(el);
2018
+ if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
2019
+ document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
2020
+ return stop();
2021
+ }
2022
+ return elCanSelect;
2023
+ },
2024
+ moveableOptions: stageOptions.moveableOptions,
2025
+ updateDragEl: stageOptions.updateDragEl
2026
+ });
2027
+ stage.mask.setGuides([
2028
+ getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
2029
+ getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
2030
+ ]);
2031
+ stage.on("select", (el) => {
2032
+ editorService.select(el.id);
2033
+ });
2034
+ stage.on("highlight", (el) => {
2035
+ editorService.highlight(el.id);
2036
+ });
2037
+ stage.on("multiSelect", (els) => {
2038
+ editorService.multiSelect(els.map((el) => el.id));
2039
+ });
2040
+ stage.on("update", (ev) => {
2041
+ if (ev.parentEl) {
2042
+ for (const data of ev.data) {
2043
+ editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
2044
+ }
2045
+ return;
2046
+ }
2047
+ editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
2048
+ });
2049
+ stage.on("sort", (ev) => {
2050
+ editorService.sort(ev.src, ev.dist);
2051
+ });
2052
+ stage.on("changeGuides", (e) => {
2053
+ uiService.set("showGuides", true);
2054
+ if (!root.value || !page.value)
2055
+ return;
2056
+ const storageKey = getGuideLineKey(e.type === StageCore.GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY);
2057
+ if (e.guides.length) {
2058
+ globalThis.localStorage.setItem(storageKey, JSON.stringify(e.guides));
2059
+ } else {
2060
+ globalThis.localStorage.removeItem(storageKey);
2061
+ }
2062
+ });
2063
+ return stage;
2064
+ };
2065
+
2066
+ const _sfc_main$k = vue.defineComponent({
1852
2067
  components: { Plus: iconsVue.Plus },
1853
2068
  setup() {
1854
2069
  const services = vue.inject("services");
@@ -1866,13 +2081,13 @@
1866
2081
  }
1867
2082
  });
1868
2083
 
1869
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
2084
+ const _hoisted_1$9 = { class: "m-editor-empty-panel" };
1870
2085
  const _hoisted_2$4 = { class: "m-editor-empty-content" };
1871
- const _hoisted_3$1 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1872
- function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
2086
+ const _hoisted_3 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
2087
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
1873
2088
  const _component_plus = vue.resolveComponent("plus");
1874
2089
  const _component_el_icon = vue.resolveComponent("el-icon");
1875
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, [
2090
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
1876
2091
  vue.createElementVNode("div", _hoisted_2$4, [
1877
2092
  vue.createElementVNode("div", {
1878
2093
  class: "m-editor-empty-button",
@@ -1886,14 +2101,14 @@
1886
2101
  _: 1
1887
2102
  })
1888
2103
  ]),
1889
- _hoisted_3$1
2104
+ _hoisted_3
1890
2105
  ])
1891
2106
  ])
1892
2107
  ]);
1893
2108
  }
1894
- const AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$d]]);
2109
+ const AddPageBox = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$8]]);
1895
2110
 
1896
- const _sfc_main$i = vue.defineComponent({
2111
+ const _sfc_main$j = vue.defineComponent({
1897
2112
  name: "m-editor-resize",
1898
2113
  props: {
1899
2114
  type: {
@@ -1936,18 +2151,18 @@
1936
2151
  }
1937
2152
  });
1938
2153
 
1939
- const _hoisted_1$a = {
2154
+ const _hoisted_1$8 = {
1940
2155
  ref: "target",
1941
2156
  class: "m-editor-resizer"
1942
2157
  };
1943
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
1944
- return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$a, [
2158
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2159
+ return vue.openBlock(), vue.createElementBlock("span", _hoisted_1$8, [
1945
2160
  vue.renderSlot(_ctx.$slots, "default")
1946
2161
  ], 512);
1947
2162
  }
1948
- const Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$c]]);
2163
+ const Resizer = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$7]]);
1949
2164
 
1950
- const _sfc_main$h = vue.defineComponent({
2165
+ const _sfc_main$i = vue.defineComponent({
1951
2166
  components: {
1952
2167
  AddPageBox,
1953
2168
  Resizer
@@ -1977,17 +2192,17 @@
1977
2192
  }
1978
2193
  });
1979
2194
 
1980
- const _hoisted_1$9 = { class: "m-editor" };
2195
+ const _hoisted_1$7 = { class: "m-editor" };
1981
2196
  const _hoisted_2$3 = {
1982
2197
  key: 1,
1983
2198
  class: "m-editor-content"
1984
2199
  };
1985
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2200
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
1986
2201
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
1987
2202
  const _component_resizer = vue.resolveComponent("resizer");
1988
2203
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
1989
2204
  const _component_add_page_box = vue.resolveComponent("add-page-box");
1990
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
2205
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$7, [
1991
2206
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
1992
2207
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
1993
2208
  key: 0,
@@ -2028,211 +2243,112 @@
2028
2243
  ]))
2029
2244
  ]);
2030
2245
  }
2031
- const Framework = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$b]]);
2246
+ const Framework = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$6]]);
2032
2247
 
2033
- const _sfc_main$g = vue.defineComponent({
2034
- name: "m-icon",
2035
- components: { Edit: iconsVue.Edit },
2248
+ const _hoisted_1$6 = ["src"];
2249
+ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
2250
+ __name: "Icon",
2036
2251
  props: {
2037
- icon: {
2038
- type: [String, Object]
2039
- }
2252
+ icon: null
2040
2253
  },
2041
- setup() {
2042
- return {
2043
- toRaw: vue.toRaw
2044
- };
2045
- }
2046
- });
2047
-
2048
- const _hoisted_1$8 = ["src"];
2049
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2050
- const _component_edit = vue.resolveComponent("edit");
2051
- const _component_el_icon = vue.resolveComponent("el-icon");
2052
- return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
2053
- default: vue.withCtx(() => [
2054
- vue.createVNode(_component_edit)
2055
- ]),
2056
- _: 1
2057
- })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 1 }, {
2058
- default: vue.withCtx(() => [
2059
- vue.createElementVNode("img", { src: _ctx.icon }, null, 8, _hoisted_1$8)
2060
- ]),
2061
- _: 1
2062
- })) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2063
- key: 2,
2064
- class: vue.normalizeClass(_ctx.icon)
2065
- }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
2066
- default: vue.withCtx(() => [
2067
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.toRaw(_ctx.icon))))
2068
- ]),
2069
- _: 1
2070
- }));
2071
- }
2072
- const MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$a]]);
2254
+ setup(__props) {
2255
+ return (_ctx, _cache) => {
2256
+ const _component_el_icon = vue.resolveComponent("el-icon");
2257
+ return !__props.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
2258
+ default: vue.withCtx(() => [
2259
+ vue.createVNode(vue.unref(iconsVue.Edit))
2260
+ ]),
2261
+ _: 1
2262
+ })) : typeof __props.icon === "string" && __props.icon.startsWith("http") ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 1 }, {
2263
+ default: vue.withCtx(() => [
2264
+ vue.createElementVNode("img", { src: __props.icon }, null, 8, _hoisted_1$6)
2265
+ ]),
2266
+ _: 1
2267
+ })) : typeof __props.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2268
+ key: 2,
2269
+ class: vue.normalizeClass(__props.icon)
2270
+ }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
2271
+ default: vue.withCtx(() => [
2272
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.toRaw(__props.icon))))
2273
+ ]),
2274
+ _: 1
2275
+ }));
2276
+ };
2277
+ }
2278
+ });
2073
2279
 
2074
- const _hoisted_1$7 = {
2280
+ const _hoisted_1$5 = {
2075
2281
  key: 1,
2076
2282
  class: "menu-item-text"
2077
2283
  };
2078
- const _hoisted_2$2 = {
2079
- class: "menu-item-text",
2080
- style: { "margin": "0 5px" }
2081
- };
2082
- const _hoisted_3 = { class: "el-dropdown-link menubar-menu-button" };
2083
- const _sfc_main$f = /* @__PURE__ */ vue.defineComponent({
2284
+ const _hoisted_2$2 = { class: "el-dropdown-link menubar-menu-button" };
2285
+ const _sfc_main$g = /* @__PURE__ */ vue.defineComponent({
2084
2286
  __name: "ToolButton",
2085
2287
  props: {
2086
- data: {
2087
- type: [Object, String],
2088
- require: true,
2089
- default: () => ({
2090
- type: "text",
2091
- display: false
2092
- })
2093
- },
2094
- eventType: {
2095
- type: String,
2096
- default: "click"
2097
- }
2288
+ data: { default: () => ({
2289
+ type: "text",
2290
+ display: false
2291
+ }) },
2292
+ eventType: { default: "click" }
2098
2293
  },
2099
2294
  setup(__props) {
2100
2295
  const props = __props;
2101
2296
  const services = vue.inject("services");
2102
- const uiService = services?.uiService;
2103
- const zoom = vue.computed(() => uiService?.get("zoom") ?? 1);
2104
- const showGuides = vue.computed(() => uiService?.get("showGuides") ?? true);
2105
- const showRule = vue.computed(() => uiService?.get("showRule") ?? true);
2106
- const zoomInHandler = () => uiService?.zoom(0.1);
2107
- const zoomOutHandler = () => uiService?.zoom(-0.1);
2108
- const item = vue.computed(() => {
2109
- if (typeof props.data !== "string") {
2110
- return props.data;
2111
- }
2112
- switch (props.data) {
2113
- case "/":
2114
- return {
2115
- type: "divider"
2116
- };
2117
- case "zoom":
2118
- return {
2119
- type: "zoom"
2120
- };
2121
- case "delete":
2122
- return {
2123
- type: "button",
2124
- icon: vue.markRaw(iconsVue.Delete),
2125
- tooltip: "\u522A\u9664",
2126
- disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2127
- handler: () => services?.editorService.remove(services?.editorService.get("node"))
2128
- };
2129
- case "undo":
2130
- return {
2131
- type: "button",
2132
- icon: vue.markRaw(iconsVue.Back),
2133
- tooltip: "\u540E\u9000",
2134
- disabled: () => !services?.historyService.state.canUndo,
2135
- handler: () => services?.editorService.undo()
2136
- };
2137
- case "redo":
2138
- return {
2139
- type: "button",
2140
- icon: vue.markRaw(iconsVue.Right),
2141
- tooltip: "\u524D\u8FDB",
2142
- disabled: () => !services?.historyService.state.canRedo,
2143
- handler: () => services?.editorService.redo()
2144
- };
2145
- case "zoom-in":
2146
- return {
2147
- type: "button",
2148
- icon: vue.markRaw(iconsVue.ZoomIn),
2149
- tooltip: "\u653E\u5927",
2150
- handler: zoomInHandler
2151
- };
2152
- case "zoom-out":
2153
- return {
2154
- type: "button",
2155
- icon: vue.markRaw(iconsVue.ZoomOut),
2156
- tooltip: "\u7E2E\u5C0F",
2157
- handler: zoomOutHandler
2158
- };
2159
- case "rule":
2160
- return {
2161
- type: "button",
2162
- icon: vue.markRaw(iconsVue.ScaleToOriginal),
2163
- tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2164
- handler: () => uiService?.set("showRule", !showRule.value)
2165
- };
2166
- case "guides":
2167
- return {
2168
- type: "button",
2169
- icon: vue.markRaw(iconsVue.Grid),
2170
- tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2171
- handler: () => uiService?.set("showGuides", !showGuides.value)
2172
- };
2173
- default:
2174
- return {
2175
- type: "text",
2176
- text: props.data
2177
- };
2178
- }
2179
- });
2180
2297
  const disabled = vue.computed(() => {
2181
- if (typeof item.value === "string")
2298
+ if (typeof props.data === "string")
2182
2299
  return false;
2183
- if (item.value.type === "component")
2300
+ if (props.data.type === "component")
2184
2301
  return false;
2185
- if (typeof item.value.disabled === "function") {
2186
- return item.value.disabled(services);
2302
+ if (typeof props.data.disabled === "function") {
2303
+ return props.data.disabled(services);
2187
2304
  }
2188
- return item.value.disabled;
2305
+ return props.data.disabled;
2189
2306
  });
2190
- const buttonHandler = (item2, event) => {
2191
- if (disabled.value)
2192
- return;
2193
- if (typeof item2.handler === "function" && services) {
2194
- item2.handler?.(services, event);
2195
- }
2196
- };
2197
2307
  const display = vue.computed(() => {
2198
- if (!item.value)
2308
+ if (!props.data)
2199
2309
  return false;
2200
- if (typeof item.value === "string")
2310
+ if (typeof props.data === "string")
2201
2311
  return true;
2202
- if (typeof item.value.display === "function") {
2203
- return item.value.display(services);
2312
+ if (typeof props.data.display === "function") {
2313
+ return props.data.display(services);
2204
2314
  }
2205
- return item.value.display ?? true;
2315
+ return props.data.display ?? true;
2206
2316
  });
2317
+ const buttonHandler = (item, event) => {
2318
+ if (disabled.value)
2319
+ return;
2320
+ if (typeof item.handler === "function" && services) {
2321
+ item.handler?.(services, event);
2322
+ }
2323
+ };
2207
2324
  const dropdownHandler = (command) => {
2208
2325
  if (command.item.handler) {
2209
2326
  command.item.handler(services);
2210
2327
  }
2211
2328
  };
2212
- const clickHandler = (item2, event) => {
2329
+ const clickHandler = (item, event) => {
2213
2330
  if (props.eventType !== "click")
2214
2331
  return;
2215
- if (item2.type === "button") {
2216
- buttonHandler(item2, event);
2332
+ if (item.type === "button") {
2333
+ buttonHandler(item, event);
2217
2334
  }
2218
2335
  };
2219
- const mousedownHandler = (item2, event) => {
2336
+ const mousedownHandler = (item, event) => {
2220
2337
  if (props.eventType !== "mousedown")
2221
2338
  return;
2222
- if (item2.type === "button") {
2223
- buttonHandler(item2, event);
2339
+ if (item.type === "button") {
2340
+ buttonHandler(item, event);
2224
2341
  }
2225
2342
  };
2226
- const mouseupHandler = (item2, event) => {
2343
+ const mouseupHandler = (item, event) => {
2227
2344
  if (props.eventType !== "mouseup")
2228
2345
  return;
2229
- if (item2.type === "button") {
2230
- buttonHandler(item2, event);
2346
+ if (item.type === "button") {
2347
+ buttonHandler(item, event);
2231
2348
  }
2232
2349
  };
2233
2350
  return (_ctx, _cache) => {
2234
2351
  const _component_el_divider = vue.resolveComponent("el-divider");
2235
- const _component_tool_button = vue.resolveComponent("tool-button", true);
2236
2352
  const _component_el_button = vue.resolveComponent("el-button");
2237
2353
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
2238
2354
  const _component_el_icon = vue.resolveComponent("el-icon");
@@ -2241,30 +2357,20 @@
2241
2357
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
2242
2358
  return vue.unref(display) ? (vue.openBlock(), vue.createElementBlock("div", {
2243
2359
  key: 0,
2244
- class: vue.normalizeClass(["menu-item", vue.unref(item).type]),
2245
- onClick: _cache[0] || (_cache[0] = ($event) => clickHandler(vue.unref(item), $event)),
2246
- onMousedown: _cache[1] || (_cache[1] = ($event) => mousedownHandler(vue.unref(item), $event)),
2247
- onMouseup: _cache[2] || (_cache[2] = ($event) => mouseupHandler(vue.unref(item), $event))
2360
+ class: vue.normalizeClass(["menu-item", `${__props.data.type} ${__props.data.className || ""}`]),
2361
+ onClick: _cache[0] || (_cache[0] = ($event) => clickHandler(__props.data, $event)),
2362
+ onMousedown: _cache[1] || (_cache[1] = ($event) => mousedownHandler(__props.data, $event)),
2363
+ onMouseup: _cache[2] || (_cache[2] = ($event) => mouseupHandler(__props.data, $event))
2248
2364
  }, [
2249
- vue.unref(item).type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2365
+ __props.data.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2250
2366
  key: 0,
2251
- direction: vue.unref(item).direction || "vertical"
2252
- }, null, 8, ["direction"])) : vue.unref(item).type === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$7, vue.toDisplayString(vue.unref(item).text), 1)) : vue.unref(item).type === "zoom" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
2253
- vue.createVNode(_component_tool_button, {
2254
- data: { type: "button", icon: vue.unref(iconsVue.ZoomOut), handler: zoomOutHandler, tooltip: "\u7F29\u5C0F" },
2255
- "event-type": __props.eventType
2256
- }, null, 8, ["data", "event-type"]),
2257
- vue.createElementVNode("span", _hoisted_2$2, vue.toDisplayString(parseInt(`${vue.unref(zoom) * 100}`, 10)) + "%", 1),
2258
- vue.createVNode(_component_tool_button, {
2259
- data: { type: "button", icon: vue.unref(iconsVue.ZoomIn), handler: zoomInHandler, tooltip: "\u653E\u5927" },
2260
- "event-type": __props.eventType
2261
- }, null, 8, ["data", "event-type"])
2262
- ], 64)) : vue.unref(item).type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
2263
- vue.unref(item).tooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
2367
+ direction: __props.data.direction || "vertical"
2368
+ }, null, 8, ["direction"])) : __props.data.type === "text" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, vue.toDisplayString(__props.data.text), 1)) : __props.data.type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
2369
+ __props.data.tooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, {
2264
2370
  key: 0,
2265
2371
  effect: "dark",
2266
2372
  placement: "bottom-start",
2267
- content: vue.unref(item).tooltip
2373
+ content: __props.data.tooltip
2268
2374
  }, {
2269
2375
  default: vue.withCtx(() => [
2270
2376
  vue.createVNode(_component_el_button, {
@@ -2273,11 +2379,11 @@
2273
2379
  disabled: vue.unref(disabled)
2274
2380
  }, {
2275
2381
  default: vue.withCtx(() => [
2276
- vue.unref(item).icon ? (vue.openBlock(), vue.createBlock(MIcon, {
2382
+ __props.data.icon ? (vue.openBlock(), vue.createBlock(_sfc_main$h, {
2277
2383
  key: 0,
2278
- icon: vue.unref(item).icon
2384
+ icon: __props.data.icon
2279
2385
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
2280
- vue.createElementVNode("span", null, vue.toDisplayString(vue.unref(item).text), 1)
2386
+ vue.createElementVNode("span", null, vue.toDisplayString(__props.data.text), 1)
2281
2387
  ]),
2282
2388
  _: 1
2283
2389
  }, 8, ["disabled"])
@@ -2290,27 +2396,27 @@
2290
2396
  disabled: vue.unref(disabled)
2291
2397
  }, {
2292
2398
  default: vue.withCtx(() => [
2293
- vue.unref(item).icon ? (vue.openBlock(), vue.createBlock(MIcon, {
2399
+ __props.data.icon ? (vue.openBlock(), vue.createBlock(_sfc_main$h, {
2294
2400
  key: 0,
2295
- icon: vue.unref(item).icon
2401
+ icon: __props.data.icon
2296
2402
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
2297
- vue.createElementVNode("span", null, vue.toDisplayString(vue.unref(item).text), 1)
2403
+ vue.createElementVNode("span", null, vue.toDisplayString(__props.data.text), 1)
2298
2404
  ]),
2299
2405
  _: 1
2300
2406
  }, 8, ["disabled"]))
2301
- ], 64)) : vue.unref(item).type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2302
- key: 4,
2407
+ ], 64)) : __props.data.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2408
+ key: 3,
2303
2409
  trigger: "click",
2304
2410
  disabled: vue.unref(disabled),
2305
2411
  onCommand: dropdownHandler
2306
2412
  }, {
2307
2413
  dropdown: vue.withCtx(() => [
2308
- vue.unref(item).items && vue.unref(item).items.length ? (vue.openBlock(), vue.createBlock(_component_el_dropdown_menu, { key: 0 }, {
2414
+ __props.data.items && __props.data.items.length ? (vue.openBlock(), vue.createBlock(_component_el_dropdown_menu, { key: 0 }, {
2309
2415
  default: vue.withCtx(() => [
2310
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(item).items, (subItem, index) => {
2416
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.data.items, (subItem, index) => {
2311
2417
  return vue.openBlock(), vue.createBlock(_component_el_dropdown_item, {
2312
2418
  key: index,
2313
- command: { item: vue.unref(item), subItem }
2419
+ command: { data: __props.data, subItem }
2314
2420
  }, {
2315
2421
  default: vue.withCtx(() => [
2316
2422
  vue.createTextVNode(vue.toDisplayString(subItem.text), 1)
@@ -2323,8 +2429,8 @@
2323
2429
  })) : vue.createCommentVNode("", true)
2324
2430
  ]),
2325
2431
  default: vue.withCtx(() => [
2326
- vue.createElementVNode("span", _hoisted_3, [
2327
- vue.createTextVNode(vue.toDisplayString(vue.unref(item).text), 1),
2432
+ vue.createElementVNode("span", _hoisted_2$2, [
2433
+ vue.createTextVNode(vue.toDisplayString(__props.data.text), 1),
2328
2434
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
2329
2435
  default: vue.withCtx(() => [
2330
2436
  vue.createVNode(vue.unref(iconsVue.ArrowDown))
@@ -2334,67 +2440,187 @@
2334
2440
  ])
2335
2441
  ]),
2336
2442
  _: 1
2337
- }, 8, ["disabled"])) : vue.unref(item).type === "component" ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(item).component), vue.normalizeProps(vue.mergeProps({ key: 5 }, vue.unref(item).props || {})), null, 16)) : vue.createCommentVNode("", true)
2443
+ }, 8, ["disabled"])) : __props.data.type === "component" ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(__props.data.component), vue.normalizeProps(vue.mergeProps({ key: 4 }, __props.data.props || {})), null, 16)) : vue.createCommentVNode("", true)
2338
2444
  ], 34)) : vue.createCommentVNode("", true);
2339
2445
  };
2340
2446
  }
2341
2447
  });
2342
2448
 
2343
- const _sfc_main$e = vue.defineComponent({
2344
- name: "nav-menu",
2345
- components: { ToolButton: _sfc_main$f },
2449
+ const _sfc_main$f = /* @__PURE__ */ vue.defineComponent({
2450
+ __name: "NavMenu",
2346
2451
  props: {
2347
- data: {
2348
- type: Object,
2349
- default: () => ({})
2350
- },
2351
- height: {
2352
- type: Number
2353
- }
2452
+ data: { default: () => ({}) },
2453
+ height: { default: 35 }
2354
2454
  },
2355
- setup(props) {
2455
+ setup(__props) {
2456
+ const props = __props;
2356
2457
  const services = vue.inject("services");
2357
- return {
2358
- keys: vue.computed(() => Object.keys(props.data)),
2359
- columnWidth: vue.computed(() => services?.uiService.get("columnWidth"))
2458
+ const uiService = services?.uiService;
2459
+ const columnWidth = vue.computed(() => services?.uiService.get("columnWidth"));
2460
+ const keys = Object.values(ColumnLayout);
2461
+ const showGuides = vue.computed(() => uiService?.get("showGuides") ?? true);
2462
+ const showRule = vue.computed(() => uiService?.get("showRule") ?? true);
2463
+ const zoom = vue.computed(() => uiService?.get("zoom") ?? 1);
2464
+ const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
2465
+ const ctrl = isMac ? "Command" : "Ctrl";
2466
+ const getConfig = (item) => {
2467
+ if (typeof item !== "string") {
2468
+ return [item];
2469
+ }
2470
+ const config = [];
2471
+ switch (item) {
2472
+ case "/":
2473
+ config.push({
2474
+ type: "divider",
2475
+ className: "divider"
2476
+ });
2477
+ break;
2478
+ case "zoom":
2479
+ config.push(...getConfig("zoom-out"), ...getConfig(`${parseInt(`${zoom.value * 100}`, 10)}%`), ...getConfig("zoom-in"), ...getConfig("scale-to-original"), ...getConfig("scale-to-fit"));
2480
+ break;
2481
+ case "delete":
2482
+ config.push({
2483
+ type: "button",
2484
+ className: "delete",
2485
+ icon: vue.markRaw(iconsVue.Delete),
2486
+ tooltip: `\u522A\u9664(Delete)`,
2487
+ disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2488
+ handler: () => services?.editorService.remove(services?.editorService.get("node"))
2489
+ });
2490
+ break;
2491
+ case "undo":
2492
+ config.push({
2493
+ type: "button",
2494
+ className: "undo",
2495
+ icon: vue.markRaw(iconsVue.Back),
2496
+ tooltip: `\u540E\u9000(${ctrl}+z)`,
2497
+ disabled: () => !services?.historyService.state.canUndo,
2498
+ handler: () => services?.editorService.undo()
2499
+ });
2500
+ break;
2501
+ case "redo":
2502
+ config.push({
2503
+ type: "button",
2504
+ className: "redo",
2505
+ icon: vue.markRaw(iconsVue.Right),
2506
+ tooltip: `\u524D\u8FDB(${ctrl}+Shift+z)`,
2507
+ disabled: () => !services?.historyService.state.canRedo,
2508
+ handler: () => services?.editorService.redo()
2509
+ });
2510
+ break;
2511
+ case "zoom-in":
2512
+ config.push({
2513
+ type: "button",
2514
+ className: "zoom-in",
2515
+ icon: vue.markRaw(iconsVue.ZoomIn),
2516
+ tooltip: `\u653E\u5927(${ctrl}+=)`,
2517
+ handler: () => uiService?.zoom(0.1)
2518
+ });
2519
+ break;
2520
+ case "zoom-out":
2521
+ config.push({
2522
+ type: "button",
2523
+ className: "zoom-out",
2524
+ icon: vue.markRaw(iconsVue.ZoomOut),
2525
+ tooltip: `\u7E2E\u5C0F(${ctrl}+-)`,
2526
+ handler: () => uiService?.zoom(-0.1)
2527
+ });
2528
+ break;
2529
+ case "scale-to-original":
2530
+ config.push({
2531
+ type: "button",
2532
+ className: "scale-to-original",
2533
+ icon: vue.markRaw(iconsVue.ScaleToOriginal),
2534
+ tooltip: `\u7F29\u653E\u5230\u5B9E\u9645\u5927\u5C0F(${ctrl}+1)`,
2535
+ handler: () => uiService?.set("zoom", 1)
2536
+ });
2537
+ break;
2538
+ case "scale-to-fit":
2539
+ config.push({
2540
+ type: "button",
2541
+ className: "scale-to-fit",
2542
+ icon: vue.markRaw(iconsVue.FullScreen),
2543
+ tooltip: `\u7F29\u653E\u4EE5\u9002\u5E94(${ctrl}+0)`,
2544
+ handler: () => uiService?.set("zoom", uiService.calcZoom())
2545
+ });
2546
+ break;
2547
+ case "rule":
2548
+ config.push({
2549
+ type: "button",
2550
+ className: "rule",
2551
+ icon: vue.markRaw(iconsVue.Memo),
2552
+ tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2553
+ handler: () => uiService?.set("showRule", !showRule.value)
2554
+ });
2555
+ break;
2556
+ case "guides":
2557
+ config.push({
2558
+ type: "button",
2559
+ className: "guides",
2560
+ icon: vue.markRaw(iconsVue.Grid),
2561
+ tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2562
+ handler: () => uiService?.set("showGuides", !showGuides.value)
2563
+ });
2564
+ break;
2565
+ default:
2566
+ config.push({
2567
+ type: "text",
2568
+ text: item
2569
+ });
2570
+ }
2571
+ return config;
2360
2572
  };
2361
- }
2362
- });
2363
-
2364
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
2365
- const _component_tool_button = vue.resolveComponent("tool-button");
2366
- return vue.openBlock(), vue.createElementBlock("div", {
2367
- class: "m-editor-nav-menu",
2368
- style: vue.normalizeStyle({ height: `${_ctx.height}px` })
2369
- }, [
2370
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.keys, (key) => {
2573
+ const buttons = vue.computed(() => {
2574
+ const data = {
2575
+ [ColumnLayout.LEFT]: [],
2576
+ [ColumnLayout.CENTER]: [],
2577
+ [ColumnLayout.RIGHT]: []
2578
+ };
2579
+ keys.forEach((key) => {
2580
+ const items = props.data[key] || [];
2581
+ items.forEach((item) => {
2582
+ data[key].push(...getConfig(item));
2583
+ });
2584
+ });
2585
+ return data;
2586
+ });
2587
+ return (_ctx, _cache) => {
2371
2588
  return vue.openBlock(), vue.createElementBlock("div", {
2372
- class: vue.normalizeClass(`menu-${key}`),
2373
- key,
2374
- style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.[key]}px`)
2589
+ class: "m-editor-nav-menu",
2590
+ style: vue.normalizeStyle({ height: `${__props.height}px` })
2375
2591
  }, [
2376
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.data[key], (item, index) => {
2377
- return vue.openBlock(), vue.createBlock(_component_tool_button, {
2378
- data: item,
2379
- key: index
2380
- }, null, 8, ["data"]);
2592
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(keys), (key) => {
2593
+ return vue.openBlock(), vue.createElementBlock("div", {
2594
+ class: vue.normalizeClass(`menu-${key}`),
2595
+ key,
2596
+ style: vue.normalizeStyle(`width: ${vue.unref(columnWidth)?.[key]}px`)
2597
+ }, [
2598
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(buttons)[key], (item, index) => {
2599
+ return vue.openBlock(), vue.createBlock(_sfc_main$g, {
2600
+ data: item,
2601
+ key: index
2602
+ }, null, 8, ["data"]);
2603
+ }), 128))
2604
+ ], 6);
2381
2605
  }), 128))
2382
- ], 6);
2383
- }), 128))
2384
- ], 4);
2385
- }
2386
- const NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$9]]);
2606
+ ], 4);
2607
+ };
2608
+ }
2609
+ });
2387
2610
 
2388
- const _sfc_main$d = vue.defineComponent({
2389
- name: "m-editor-props-panel",
2611
+ const _hoisted_1$4 = { class: "`m-editor-props-panel" };
2612
+ const _sfc_main$e = /* @__PURE__ */ vue.defineComponent({
2613
+ __name: "PropsPanel",
2390
2614
  emits: ["mounted"],
2391
- setup(props, { emit }) {
2615
+ setup(__props, { expose, emit }) {
2392
2616
  const internalInstance = vue.getCurrentInstance();
2393
2617
  const values = vue.ref({});
2394
2618
  const configForm = vue.ref();
2395
2619
  const curFormConfig = vue.ref([]);
2396
2620
  const services = vue.inject("services");
2397
2621
  const node = vue.computed(() => services?.editorService.get("node"));
2622
+ const propsPanelSize = vue.computed(() => services?.uiService.get("propsPanelSize") || "small");
2623
+ const stage = vue.computed(() => services?.editorService.get("stage"));
2398
2624
  const init = async () => {
2399
2625
  if (!node.value) {
2400
2626
  curFormConfig.value = [];
@@ -2409,51 +2635,49 @@
2409
2635
  vue.onMounted(() => {
2410
2636
  emit("mounted", internalInstance);
2411
2637
  });
2412
- return {
2413
- values,
2414
- configForm,
2415
- curFormConfig,
2416
- propsPanelSize: vue.computed(() => services?.uiService.get("propsPanelSize") || "small"),
2417
- async submit() {
2418
- try {
2419
- const values2 = await configForm.value?.submitForm();
2420
- services?.editorService.update(values2);
2421
- } catch (e) {
2422
- console.error(e);
2423
- elementPlus.ElMessage.closeAll();
2424
- elementPlus.ElMessage.error({
2425
- duration: 1e4,
2426
- showClose: true,
2427
- message: e.message,
2428
- dangerouslyUseHTMLString: true
2429
- });
2430
- }
2638
+ vue.watchEffect(() => {
2639
+ if (configForm.value && stage.value) {
2640
+ configForm.value.formState.stage = stage.value;
2641
+ }
2642
+ });
2643
+ const submit = async () => {
2644
+ try {
2645
+ const values2 = await configForm.value?.submitForm();
2646
+ services?.editorService.update(values2);
2647
+ } catch (e) {
2648
+ console.error(e);
2649
+ elementPlus.ElMessage.closeAll();
2650
+ elementPlus.ElMessage.error({
2651
+ duration: 1e4,
2652
+ showClose: true,
2653
+ message: e.message,
2654
+ dangerouslyUseHTMLString: true
2655
+ });
2431
2656
  }
2432
2657
  };
2658
+ expose({ submit });
2659
+ return (_ctx, _cache) => {
2660
+ const _component_m_form = vue.resolveComponent("m-form");
2661
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$4, [
2662
+ vue.renderSlot(_ctx.$slots, "props-panel-header"),
2663
+ vue.createVNode(_component_m_form, {
2664
+ ref_key: "configForm",
2665
+ ref: configForm,
2666
+ class: vue.normalizeClass(`m-editor-props-panel ${vue.unref(propsPanelSize)}`),
2667
+ "popper-class": `m-editor-props-panel-popper ${vue.unref(propsPanelSize)}`,
2668
+ size: vue.unref(propsPanelSize),
2669
+ "init-values": values.value,
2670
+ config: curFormConfig.value,
2671
+ onChange: submit
2672
+ }, null, 8, ["class", "popper-class", "size", "init-values", "config"])
2673
+ ]);
2674
+ };
2433
2675
  }
2434
2676
  });
2435
2677
 
2436
- const _hoisted_1$6 = { class: "`m-editor-props-panel" };
2437
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
2438
- const _component_m_form = vue.resolveComponent("m-form");
2439
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
2440
- vue.renderSlot(_ctx.$slots, "props-panel-header"),
2441
- vue.createVNode(_component_m_form, {
2442
- class: vue.normalizeClass(`m-editor-props-panel ${_ctx.propsPanelSize}`),
2443
- "popper-class": `m-editor-props-panel-popper ${_ctx.propsPanelSize}`,
2444
- ref: "configForm",
2445
- size: _ctx.propsPanelSize,
2446
- "init-values": _ctx.values,
2447
- config: _ctx.curFormConfig,
2448
- onChange: _ctx.submit
2449
- }, null, 8, ["class", "popper-class", "size", "init-values", "config", "onChange"])
2450
- ]);
2451
- }
2452
- const PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$8]]);
2453
-
2454
- const _sfc_main$c = vue.defineComponent({
2678
+ const _sfc_main$d = vue.defineComponent({
2455
2679
  name: "ui-component-panel",
2456
- components: { MIcon },
2680
+ components: { MIcon: _sfc_main$h },
2457
2681
  setup() {
2458
2682
  const searchText = vue.ref("");
2459
2683
  const services = vue.inject("services");
@@ -2518,9 +2742,9 @@
2518
2742
  }
2519
2743
  });
2520
2744
 
2521
- const _hoisted_1$5 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
2745
+ const _hoisted_1$3 = /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-s-grid" }, null, -1);
2522
2746
  const _hoisted_2$1 = ["onClick", "onDragstart"];
2523
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2747
+ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2524
2748
  const _component_el_input = vue.resolveComponent("el-input");
2525
2749
  const _component_m_icon = vue.resolveComponent("m-icon");
2526
2750
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -2551,7 +2775,7 @@
2551
2775
  name: index
2552
2776
  }, {
2553
2777
  title: vue.withCtx(() => [
2554
- _hoisted_1$5,
2778
+ _hoisted_1$3,
2555
2779
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
2556
2780
  ]),
2557
2781
  default: vue.withCtx(() => [
@@ -2592,9 +2816,9 @@
2592
2816
  _: 3
2593
2817
  });
2594
2818
  }
2595
- const ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$7]]);
2819
+ const ComponentListPanel = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$5]]);
2596
2820
 
2597
- const _sfc_main$b = /* @__PURE__ */ vue.defineComponent({
2821
+ const _sfc_main$c = /* @__PURE__ */ vue.defineComponent({
2598
2822
  __name: "ContentMenu",
2599
2823
  props: {
2600
2824
  menuData: { default: () => [] },
@@ -2683,7 +2907,7 @@
2683
2907
  }, [
2684
2908
  vue.createElementVNode("div", null, [
2685
2909
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.menuData, (item, index) => {
2686
- return vue.openBlock(), vue.createBlock(_sfc_main$f, {
2910
+ return vue.openBlock(), vue.createBlock(_sfc_main$g, {
2687
2911
  "event-type": "mouseup",
2688
2912
  data: item,
2689
2913
  key: index,
@@ -2707,8 +2931,8 @@
2707
2931
  }
2708
2932
  });
2709
2933
 
2710
- const _sfc_main$a = vue.defineComponent({
2711
- components: { ContentMenu: _sfc_main$b },
2934
+ const _sfc_main$b = vue.defineComponent({
2935
+ components: { ContentMenu: _sfc_main$c },
2712
2936
  setup() {
2713
2937
  const services = vue.inject("services");
2714
2938
  const menu = vue.ref();
@@ -2791,7 +3015,7 @@
2791
3015
  }
2792
3016
  });
2793
3017
 
2794
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3018
+ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
2795
3019
  const _component_content_menu = vue.resolveComponent("content-menu");
2796
3020
  return vue.openBlock(), vue.createBlock(_component_content_menu, {
2797
3021
  "menu-data": _ctx.menuData,
@@ -2799,7 +3023,7 @@
2799
3023
  style: { "overflow": "initial" }
2800
3024
  }, null, 8, ["menu-data"]);
2801
3025
  }
2802
- const LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$6]]);
3026
+ const LayerMenu = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$4]]);
2803
3027
 
2804
3028
  const throttleTime = 150;
2805
3029
  const select = async (data, editorService) => {
@@ -2850,20 +3074,38 @@
2850
3074
  }
2851
3075
  });
2852
3076
  const useStatus = (tree, editorService) => {
2853
- const highlightNode = vue.ref();
2854
3077
  const node = vue.ref();
2855
3078
  const page = vue.computed(() => editorService?.get("page"));
3079
+ const expandedKeys = /* @__PURE__ */ new Map();
3080
+ const expandNodes = () => {
3081
+ expandedKeys.forEach((key) => {
3082
+ if (!tree.value)
3083
+ return;
3084
+ tree.value.getNode(key)?.expand();
3085
+ });
3086
+ };
2856
3087
  vue.watchEffect(() => {
2857
3088
  if (!tree.value)
2858
3089
  return;
2859
- node.value = editorService?.get("node");
2860
- node.value && tree.value.setCurrentKey(node.value.id, true);
2861
- const parent = editorService?.get("parent");
3090
+ if (!editorService)
3091
+ return;
3092
+ node.value = editorService.get("node");
3093
+ if (!node.value)
3094
+ return;
3095
+ tree.value.setCurrentKey(node.value.id, true);
3096
+ const parent = editorService.get("parent");
2862
3097
  if (!parent?.id)
2863
3098
  return;
2864
3099
  const treeNode = tree.value.getNode(parent.id);
2865
3100
  treeNode?.updateChildren();
2866
- highlightNode.value = editorService?.get("highlightNode");
3101
+ setTimeout(() => {
3102
+ tree.value && Object.entries(tree.value.store.nodesMap).forEach(([id, node2]) => {
3103
+ if (node2.expanded && node2.data.items) {
3104
+ expandedKeys.set(id, id);
3105
+ }
3106
+ });
3107
+ expandNodes();
3108
+ });
2867
3109
  });
2868
3110
  return {
2869
3111
  values: vue.computed(() => page.value ? [page.value] : []),
@@ -2876,9 +3118,18 @@
2876
3118
  }
2877
3119
  resolve([]);
2878
3120
  },
2879
- highlightNode,
3121
+ highlightNode: vue.computed(() => editorService?.get("highlightNode")),
2880
3122
  clickNode: node,
2881
- expandedKeys: vue.computed(() => node.value ? [node.value.id] : [])
3123
+ expandedKeys: vue.computed(() => node.value ? [node.value.id] : []),
3124
+ handleCollapse: (data) => {
3125
+ expandedKeys.delete(data.id);
3126
+ },
3127
+ handleExpand: (data) => {
3128
+ const parent = editorService?.getParentById(data.id);
3129
+ if (!parent?.id)
3130
+ return;
3131
+ expandedKeys.set(parent.id, parent.id);
3132
+ }
2882
3133
  };
2883
3134
  };
2884
3135
  const useFilter = (tree) => ({
@@ -2899,7 +3150,7 @@
2899
3150
  tree.value?.filter(val);
2900
3151
  }
2901
3152
  });
2902
- const _sfc_main$9 = vue.defineComponent({
3153
+ const _sfc_main$a = vue.defineComponent({
2903
3154
  name: "magic-editor-layer-panel",
2904
3155
  components: { LayerMenu },
2905
3156
  setup() {
@@ -2947,8 +3198,8 @@
2947
3198
  }
2948
3199
  });
2949
3200
 
2950
- const _hoisted_1$4 = ["id", "onMouseenter"];
2951
- function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
3201
+ const _hoisted_1$2 = ["id", "onMouseenter"];
3202
+ function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
2952
3203
  const _component_el_input = vue.resolveComponent("el-input");
2953
3204
  const _component_el_tree = vue.resolveComponent("el-tree");
2954
3205
  const _component_layer_menu = vue.resolveComponent("layer-menu");
@@ -2969,6 +3220,7 @@
2969
3220
  key: 0,
2970
3221
  ref: "tree",
2971
3222
  "node-key": "id",
3223
+ "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684",
2972
3224
  draggable: "",
2973
3225
  "default-expanded-keys": _ctx.expandedKeys,
2974
3226
  load: _ctx.loadItems,
@@ -2983,7 +3235,8 @@
2983
3235
  onNodeClick: _ctx.clickHandler,
2984
3236
  onNodeContextmenu: _ctx.contextmenu,
2985
3237
  onNodeDragEnd: _ctx.handleDragEnd,
2986
- "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3238
+ onNodeCollapse: _ctx.handleCollapse,
3239
+ onNodeExpand: _ctx.handleExpand
2987
3240
  }, {
2988
3241
  default: vue.withCtx(({ node, data }) => [
2989
3242
  vue.createElementVNode("div", {
@@ -2999,10 +3252,10 @@
2999
3252
  }, () => [
3000
3253
  vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
3001
3254
  ])
3002
- ], 42, _hoisted_1$4)
3255
+ ], 42, _hoisted_1$2)
3003
3256
  ]),
3004
3257
  _: 3
3005
- }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd"])) : vue.createCommentVNode("", true),
3258
+ }, 8, ["default-expanded-keys", "load", "data", "filter-node-method", "allow-drop", "onNodeClick", "onNodeContextmenu", "onNodeDragEnd", "onNodeCollapse", "onNodeExpand"])) : vue.createCommentVNode("", true),
3006
3259
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
3007
3260
  vue.createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
3008
3261
  ]))
@@ -3010,10 +3263,10 @@
3010
3263
  _: 3
3011
3264
  });
3012
3265
  }
3013
- const LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$5]]);
3266
+ const LayerPanel = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$3]]);
3014
3267
 
3015
- const _sfc_main$8 = vue.defineComponent({
3016
- components: { MIcon },
3268
+ const _sfc_main$9 = vue.defineComponent({
3269
+ components: { MIcon: _sfc_main$h },
3017
3270
  props: {
3018
3271
  data: {
3019
3272
  type: [Object, String]
@@ -3050,11 +3303,11 @@
3050
3303
  }
3051
3304
  });
3052
3305
 
3053
- const _hoisted_1$3 = {
3306
+ const _hoisted_1$1 = {
3054
3307
  key: 1,
3055
3308
  class: "magic-editor-tab-panel-title"
3056
3309
  };
3057
- function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3310
+ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3058
3311
  const _component_m_icon = vue.resolveComponent("m-icon");
3059
3312
  const _component_el_tab_pane = vue.resolveComponent("el-tab-pane");
3060
3313
  return _ctx.config ? (vue.openBlock(), vue.createBlock(_component_el_tab_pane, {
@@ -3069,7 +3322,7 @@
3069
3322
  key: 0,
3070
3323
  icon: _ctx.config.icon
3071
3324
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3072
- _ctx.config.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, vue.toDisplayString(_ctx.config.text), 1)) : vue.createCommentVNode("", true)
3325
+ _ctx.config.text ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, vue.toDisplayString(_ctx.config.text), 1)) : vue.createCommentVNode("", true)
3073
3326
  ]))
3074
3327
  ]),
3075
3328
  default: vue.withCtx(() => [
@@ -3100,9 +3353,9 @@
3100
3353
  _: 3
3101
3354
  }, 8, ["name"])) : vue.createCommentVNode("", true);
3102
3355
  }
3103
- const TabPane = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$4]]);
3356
+ const TabPane = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$2]]);
3104
3357
 
3105
- const _sfc_main$7 = vue.defineComponent({
3358
+ const _sfc_main$8 = vue.defineComponent({
3106
3359
  components: { TabPane },
3107
3360
  name: "m-sidebar",
3108
3361
  props: {
@@ -3122,7 +3375,7 @@
3122
3375
  }
3123
3376
  });
3124
3377
 
3125
- function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3378
+ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3126
3379
  const _component_tab_pane = vue.resolveComponent("tab-pane");
3127
3380
  const _component_el_tabs = vue.resolveComponent("el-tabs");
3128
3381
  return _ctx.data.type === "tabs" && _ctx.data.items.length ? (vue.openBlock(), vue.createBlock(_component_el_tabs, {
@@ -3157,9 +3410,9 @@
3157
3410
  _: 3
3158
3411
  }, 8, ["modelValue"])) : vue.createCommentVNode("", true);
3159
3412
  }
3160
- const Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$3]]);
3413
+ const Sidebar = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$1]]);
3161
3414
 
3162
- const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
3415
+ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
3163
3416
  __name: "PageBarScrollContainer",
3164
3417
  setup(__props) {
3165
3418
  const services = vue.inject("services");
@@ -3286,9 +3539,9 @@
3286
3539
  }
3287
3540
  });
3288
3541
 
3289
- const _hoisted_1$2 = ["onClick"];
3542
+ const _hoisted_1 = ["onClick"];
3290
3543
  const _hoisted_2 = { class: "m-editor-page-bar-title" };
3291
- const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
3544
+ const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
3292
3545
  __name: "PageBar",
3293
3546
  setup(__props) {
3294
3547
  const services = vue.inject("services");
@@ -3312,7 +3565,7 @@
3312
3565
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
3313
3566
  const _component_el_icon = vue.resolveComponent("el-icon");
3314
3567
  const _component_el_popover = vue.resolveComponent("el-popover");
3315
- return vue.openBlock(), vue.createBlock(_sfc_main$6, null, {
3568
+ return vue.openBlock(), vue.createBlock(_sfc_main$7, null, {
3316
3569
  default: vue.withCtx(() => [
3317
3570
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(root) && vue.unref(root).items || [], (item) => {
3318
3571
  return vue.openBlock(), vue.createElementBlock("div", {
@@ -3328,7 +3581,7 @@
3328
3581
  content: item.name
3329
3582
  }, {
3330
3583
  default: vue.withCtx(() => [
3331
- vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1)
3584
+ vue.createElementVNode("span", null, vue.toDisplayString(item.name || item.id), 1)
3332
3585
  ]),
3333
3586
  _: 2
3334
3587
  }, 1032, ["content"])
@@ -3351,7 +3604,7 @@
3351
3604
  default: vue.withCtx(() => [
3352
3605
  vue.createElementVNode("div", null, [
3353
3606
  vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3354
- vue.createVNode(_sfc_main$f, {
3607
+ vue.createVNode(_sfc_main$g, {
3355
3608
  data: {
3356
3609
  type: "button",
3357
3610
  text: "\u590D\u5236",
@@ -3359,7 +3612,7 @@
3359
3612
  handler: () => copy(item)
3360
3613
  }
3361
3614
  }, null, 8, ["data"]),
3362
- vue.createVNode(_sfc_main$f, {
3615
+ vue.createVNode(_sfc_main$g, {
3363
3616
  data: {
3364
3617
  type: "button",
3365
3618
  text: "\u5220\u9664",
@@ -3372,7 +3625,7 @@
3372
3625
  ]),
3373
3626
  _: 2
3374
3627
  }, 1024)
3375
- ], 10, _hoisted_1$2);
3628
+ ], 10, _hoisted_1);
3376
3629
  }), 128))
3377
3630
  ]),
3378
3631
  _: 3
@@ -3381,190 +3634,245 @@
3381
3634
  }
3382
3635
  });
3383
3636
 
3384
- class ScrollViewer$1 {
3385
- enter = false;
3386
- targetEnter = false;
3387
- keydown = false;
3637
+ class ScrollViewer extends events.EventEmitter {
3388
3638
  container;
3389
3639
  target;
3390
3640
  zoom = 1;
3391
3641
  scrollLeft = 0;
3392
3642
  scrollTop = 0;
3393
- x = 0;
3394
- y = 0;
3395
- resizeObserver = new ResizeObserver((entries) => {
3396
- for (const { contentRect } of entries) {
3397
- const { width, height } = contentRect;
3398
- const targetRect = this.target.getBoundingClientRect();
3399
- const targetWidth = targetRect.width * this.zoom;
3400
- const targetMarginTop = Number(this.target.style.marginTop) || 0;
3401
- const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3402
- if (targetWidth < width) {
3403
- this.target._left = 0;
3404
- }
3405
- if (targetHeight < height) {
3406
- this.target._top = 0;
3407
- }
3408
- this.scroll();
3409
- }
3643
+ scrollHeight = 0;
3644
+ scrollWidth = 0;
3645
+ width = 0;
3646
+ height = 0;
3647
+ translateXCorrectionValue = 0;
3648
+ translateYCorrectionValue = 0;
3649
+ resizeObserver = new ResizeObserver(() => {
3650
+ this.setSize();
3651
+ this.setScrollSize();
3410
3652
  });
3411
3653
  constructor(options) {
3654
+ super();
3412
3655
  this.container = options.container;
3413
3656
  this.target = options.target;
3414
3657
  this.zoom = options.zoom;
3415
- globalThis.addEventListener("keydown", this.keydownHandler);
3416
- globalThis.addEventListener("keyup", this.keyupHandler);
3417
- this.container.addEventListener("mouseenter", this.mouseEnterHandler);
3418
- this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
3419
- this.target.addEventListener("mouseenter", this.targetMouseEnterHandler);
3420
- this.target.addEventListener("mouseleave", this.targetMouseLeaveHandler);
3421
- this.container.addEventListener("wheel", this.wheelHandler);
3658
+ this.container.addEventListener("wheel", this.wheelHandler, false);
3659
+ this.setSize();
3660
+ this.setScrollSize();
3422
3661
  this.resizeObserver.observe(this.container);
3423
3662
  }
3424
3663
  destroy() {
3425
3664
  this.resizeObserver.disconnect();
3426
- this.container.removeEventListener("mouseenter", this.mouseEnterHandler);
3427
- this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
3428
- this.target.removeEventListener("mouseenter", this.targetMouseEnterHandler);
3429
- this.target.removeEventListener("mouseleave", this.targetMouseLeaveHandler);
3430
- globalThis.removeEventListener("keydown", this.keydownHandler);
3431
- globalThis.removeEventListener("keyup", this.keyupHandler);
3665
+ this.container.removeEventListener("wheel", this.wheelHandler, false);
3666
+ this.removeAllListeners();
3432
3667
  }
3433
3668
  setZoom(zoom) {
3434
3669
  this.zoom = zoom;
3670
+ this.setScrollSize();
3435
3671
  }
3436
- scroll() {
3437
- const scrollLeft = this.target._left;
3438
- const scrollTop = this.target._top;
3439
- this.target.style.transform = `translate(${scrollLeft}px, ${scrollTop}px)`;
3440
- }
3441
- removeHandler() {
3442
- this.target.style.cursor = "";
3443
- this.target.removeEventListener("mousedown", this.mousedownHandler);
3444
- document.removeEventListener("mousemove", this.mousemoveHandler);
3445
- document.removeEventListener("mouseup", this.mouseupHandler);
3672
+ scrollTo({ left, top }) {
3673
+ if (typeof left !== "undefined") {
3674
+ this.scrollLeft = left;
3675
+ }
3676
+ if (typeof top !== "undefined") {
3677
+ this.scrollTop = top;
3678
+ }
3679
+ const translateX = -this.scrollLeft + this.translateXCorrectionValue;
3680
+ const translateY = -this.scrollTop + this.translateYCorrectionValue;
3681
+ this.target.style.transform = `translate(${translateX}px, ${translateY}px)`;
3446
3682
  }
3447
3683
  wheelHandler = (event) => {
3448
- if (this.targetEnter)
3449
- return;
3450
3684
  const { deltaX, deltaY, currentTarget } = event;
3451
3685
  if (currentTarget !== this.container)
3452
3686
  return;
3453
- this.setScrollOffset(deltaX, deltaY);
3454
- this.scroll();
3455
- this.scrollLeft = this.target._left;
3456
- this.scrollTop = this.target._top;
3457
- };
3458
- mouseEnterHandler = () => {
3459
- this.enter = true;
3460
- };
3461
- mouseLeaveHandler = () => {
3462
- this.enter = false;
3463
- };
3464
- targetMouseEnterHandler = () => {
3465
- this.targetEnter = true;
3466
- };
3467
- targetMouseLeaveHandler = () => {
3468
- this.targetEnter = false;
3469
- };
3470
- mousedownHandler = (event) => {
3471
- if (!this.keydown)
3472
- return;
3473
- event.stopImmediatePropagation();
3474
- event.stopPropagation();
3475
- this.target.style.cursor = "grabbing";
3476
- this.x = event.clientX;
3477
- this.y = event.clientY;
3478
- document.addEventListener("mousemove", this.mousemoveHandler);
3479
- document.addEventListener("mouseup", this.mouseupHandler);
3480
- };
3481
- mouseupHandler = () => {
3482
- this.x = 0;
3483
- this.y = 0;
3484
- this.scrollLeft = this.target._left;
3485
- this.scrollTop = this.target._top;
3486
- this.removeHandler();
3487
- };
3488
- mousemoveHandler = (event) => {
3489
- event.stopImmediatePropagation();
3490
- event.stopPropagation();
3491
- const deltaX = event.clientX - this.x;
3492
- const deltaY = event.clientY - this.y;
3493
- this.setScrollOffset(deltaX, deltaY);
3494
- this.scroll();
3495
- };
3496
- keydownHandler = (event) => {
3497
- if (event.code === Keys.ESCAPE && this.enter) {
3498
- event.preventDefault();
3499
- event.stopImmediatePropagation();
3500
- event.stopPropagation();
3687
+ let top;
3688
+ if (this.scrollHeight > this.height) {
3689
+ top = this.scrollTop + this.getPos(deltaY, this.scrollTop, this.scrollHeight, this.height);
3501
3690
  }
3502
- if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3503
- return;
3691
+ let left;
3692
+ if (this.scrollWidth > this.width) {
3693
+ left = this.scrollLeft + this.getPos(deltaX, this.scrollLeft, this.scrollWidth, this.width);
3504
3694
  }
3505
- this.keydown = true;
3506
- this.target.style.cursor = "grab";
3507
- this.container.addEventListener("mousedown", this.mousedownHandler);
3695
+ this.scrollTo({ left, top });
3696
+ this.emit("scroll", {
3697
+ scrollLeft: this.scrollLeft,
3698
+ scrollTop: this.scrollTop,
3699
+ scrollHeight: this.scrollHeight,
3700
+ scrollWidth: this.scrollWidth
3701
+ });
3508
3702
  };
3509
- keyupHandler = (event) => {
3510
- if (event.code !== Keys.ESCAPE || !this.keydown) {
3511
- return;
3703
+ getPos(delta, scrollPos, scrollSize, size) {
3704
+ let pos = 0;
3705
+ if (delta < 0) {
3706
+ if (scrollPos > 0) {
3707
+ pos = Math.max(delta, -scrollPos);
3708
+ }
3709
+ } else {
3710
+ const leftPos = scrollSize - size - scrollPos;
3711
+ if (leftPos > 0) {
3712
+ pos = Math.min(delta, leftPos);
3713
+ }
3512
3714
  }
3513
- event.preventDefault();
3514
- event.stopImmediatePropagation();
3515
- event.stopPropagation();
3516
- this.keydown = false;
3517
- event.preventDefault();
3518
- this.removeHandler();
3715
+ return pos;
3716
+ }
3717
+ setScrollSize = () => {
3718
+ const targetRect = this.target.getBoundingClientRect();
3719
+ this.scrollWidth = targetRect.width * this.zoom + 100;
3720
+ const targetMarginTop = Number(this.target.style.marginTop) || 0;
3721
+ this.scrollHeight = (targetRect.height + targetMarginTop) * this.zoom + 100;
3722
+ let left;
3723
+ let top;
3724
+ if (this.scrollWidth < this.width) {
3725
+ left = 0;
3726
+ this.translateXCorrectionValue = 0;
3727
+ } else {
3728
+ this.translateXCorrectionValue = (this.scrollWidth - this.width) / 2;
3729
+ }
3730
+ if (this.scrollHeight < this.height) {
3731
+ top = 0;
3732
+ this.translateYCorrectionValue = 0;
3733
+ } else {
3734
+ this.translateYCorrectionValue = (this.scrollHeight - this.height) / 2;
3735
+ }
3736
+ this.scrollTo({
3737
+ left,
3738
+ top
3739
+ });
3740
+ this.emit("scroll", {
3741
+ scrollLeft: this.scrollLeft,
3742
+ scrollTop: this.scrollTop,
3743
+ scrollHeight: this.scrollHeight,
3744
+ scrollWidth: this.scrollWidth
3745
+ });
3519
3746
  };
3520
- setScrollOffset(deltaX, deltaY) {
3747
+ setSize = () => {
3521
3748
  const { width, height } = this.container.getBoundingClientRect();
3522
- const targetRect = this.target.getBoundingClientRect();
3523
- const targetWidth = targetRect.width * this.zoom;
3524
- const targetHeight = targetRect.height * this.zoom;
3525
- let y = 0;
3526
- if (targetHeight > height) {
3527
- if (deltaY > 0) {
3528
- y = this.scrollTop + Math.min(targetHeight - height - this.scrollTop, deltaY);
3529
- } else {
3530
- y = this.scrollTop + Math.max(-(targetHeight - height + this.scrollTop), deltaY);
3749
+ this.width = width;
3750
+ this.height = height;
3751
+ };
3752
+ }
3753
+
3754
+ const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
3755
+ __name: "ScrollBar",
3756
+ props: {
3757
+ size: null,
3758
+ scrollSize: null,
3759
+ isHorizontal: { type: Boolean },
3760
+ pos: null
3761
+ },
3762
+ emits: ["scroll"],
3763
+ setup(__props, { emit }) {
3764
+ const props = __props;
3765
+ const bar = vue.ref();
3766
+ const thumb = vue.ref();
3767
+ const thumbSize = vue.computed(() => props.size * (props.size / props.scrollSize));
3768
+ const thumbPos = vue.computed(() => props.pos / props.scrollSize * props.size);
3769
+ const thumbStyle = vue.computed(() => ({
3770
+ [props.isHorizontal ? "width" : "height"]: `${thumbSize.value}px`,
3771
+ transform: `translate${props.isHorizontal ? "X" : "Y"}(${thumbPos.value}px)`
3772
+ }));
3773
+ let gesto;
3774
+ vue.onMounted(() => {
3775
+ if (!thumb.value)
3776
+ return;
3777
+ const thumbEl = thumb.value;
3778
+ gesto = new Gesto__default.default(thumbEl, {
3779
+ container: window
3780
+ });
3781
+ gesto.on("dragStart", (e) => {
3782
+ e.inputEvent.stopPropagation();
3783
+ e.inputEvent.preventDefault();
3784
+ }).on("drag", (e) => {
3785
+ scrollBy(getDelta(e));
3786
+ });
3787
+ bar.value?.addEventListener("wheel", wheelHandler, false);
3788
+ });
3789
+ vue.onUnmounted(() => {
3790
+ if (gesto)
3791
+ gesto.off();
3792
+ bar.value?.removeEventListener("wheel", wheelHandler, false);
3793
+ });
3794
+ const wheelHandler = (e) => {
3795
+ const delta = props.isHorizontal ? e.deltaX : e.deltaY;
3796
+ if (delta) {
3797
+ e.preventDefault();
3531
3798
  }
3532
- }
3533
- let x = 0;
3534
- if (targetWidth > width) {
3535
- if (deltaX > 0) {
3536
- x = this.scrollLeft + Math.min(targetWidth - width - this.scrollLeft, deltaX);
3799
+ scrollBy(delta);
3800
+ };
3801
+ const getDelta = (e) => {
3802
+ const ratio = (props.isHorizontal ? e.deltaX : e.deltaY) / props.size;
3803
+ return props.scrollSize * ratio;
3804
+ };
3805
+ const scrollBy = (delta) => {
3806
+ if (delta < 0) {
3807
+ if (props.pos <= 0) {
3808
+ emit("scroll", 0);
3809
+ } else {
3810
+ emit("scroll", -Math.min(-delta, props.pos));
3811
+ }
3537
3812
  } else {
3538
- x = this.scrollLeft + Math.max(-(targetWidth - width + this.scrollLeft), deltaX);
3813
+ const leftPos = props.size - (thumbSize.value + thumbPos.value);
3814
+ if (leftPos <= 0) {
3815
+ emit("scroll", 0);
3816
+ } else {
3817
+ emit("scroll", Math.min(delta, leftPos));
3818
+ }
3539
3819
  }
3540
- }
3541
- this.target._left = x;
3542
- this.target._top = y;
3820
+ };
3821
+ return (_ctx, _cache) => {
3822
+ return vue.openBlock(), vue.createElementBlock("div", {
3823
+ ref_key: "bar",
3824
+ ref: bar,
3825
+ class: vue.normalizeClass(["m-editor-scroll-bar", __props.isHorizontal ? "horizontal" : "vertical"])
3826
+ }, [
3827
+ vue.createElementVNode("div", {
3828
+ ref_key: "thumb",
3829
+ ref: thumb,
3830
+ class: "m-editor-scroll-bar-thumb",
3831
+ style: vue.normalizeStyle(vue.unref(thumbStyle))
3832
+ }, null, 4)
3833
+ ], 2);
3834
+ };
3543
3835
  }
3544
- }
3836
+ });
3837
+
3838
+ const ScrollBar_vue_vue_type_style_index_0_lang = '';
3545
3839
 
3546
- const _sfc_main$4 = vue.defineComponent({
3547
- name: "m-editor-scroll-viewer",
3840
+ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
3841
+ __name: "ScrollViewer",
3548
3842
  props: {
3549
- width: Number,
3550
- height: Number,
3551
- zoom: {
3552
- type: Number,
3553
- default: 1
3554
- }
3843
+ width: { default: 0 },
3844
+ height: { default: 0 },
3845
+ wrapWidth: { default: 0 },
3846
+ wrapHeight: { default: 0 },
3847
+ zoom: { default: 1 }
3555
3848
  },
3556
- setup(props) {
3849
+ setup(__props, { expose }) {
3850
+ const props = __props;
3557
3851
  const container = vue.ref();
3558
3852
  const el = vue.ref();
3853
+ const style = vue.computed(() => `
3854
+ width: ${props.width}px;
3855
+ height: ${props.height}px;
3856
+ position: absolute;
3857
+ margin-top: 30px;
3858
+ `);
3859
+ const scrollWidth = vue.ref(0);
3860
+ const scrollHeight = vue.ref(0);
3559
3861
  let scrollViewer;
3560
3862
  vue.onMounted(() => {
3561
3863
  if (!container.value || !el.value)
3562
3864
  return;
3563
- scrollViewer = new ScrollViewer$1({
3865
+ scrollViewer = new ScrollViewer({
3564
3866
  container: container.value,
3565
3867
  target: el.value,
3566
3868
  zoom: props.zoom
3567
3869
  });
3870
+ scrollViewer.on("scroll", (data) => {
3871
+ hOffset.value = data.scrollLeft;
3872
+ vOffset.value = data.scrollTop;
3873
+ scrollWidth.value = data.scrollWidth;
3874
+ scrollHeight.value = data.scrollHeight;
3875
+ });
3568
3876
  });
3569
3877
  vue.onUnmounted(() => {
3570
3878
  scrollViewer.destroy();
@@ -3572,35 +3880,56 @@
3572
3880
  vue.watch(() => props.zoom, () => {
3573
3881
  scrollViewer.setZoom(props.zoom);
3574
3882
  });
3575
- return {
3576
- container,
3577
- el,
3578
- style: vue.computed(() => `
3579
- width: ${props.width}px;
3580
- height: ${props.height}px;
3581
- position: absolute;
3582
- margin-top: 30px;
3583
- `)
3883
+ const vOffset = vue.ref(0);
3884
+ const vScrollHandler = (delta) => {
3885
+ vOffset.value += delta;
3886
+ scrollViewer.scrollTo({
3887
+ top: vOffset.value
3888
+ });
3889
+ };
3890
+ const hOffset = vue.ref(0);
3891
+ const hScrollHandler = (delta) => {
3892
+ hOffset.value += delta;
3893
+ scrollViewer.scrollTo({
3894
+ left: hOffset.value
3895
+ });
3896
+ };
3897
+ expose({
3898
+ container
3899
+ });
3900
+ return (_ctx, _cache) => {
3901
+ return vue.openBlock(), vue.createElementBlock("div", {
3902
+ class: "m-editor-scroll-viewer-container",
3903
+ ref_key: "container",
3904
+ ref: container
3905
+ }, [
3906
+ vue.createElementVNode("div", {
3907
+ ref_key: "el",
3908
+ ref: el,
3909
+ style: vue.normalizeStyle(vue.unref(style))
3910
+ }, [
3911
+ vue.renderSlot(_ctx.$slots, "default")
3912
+ ], 4),
3913
+ scrollHeight.value > __props.wrapHeight ? (vue.openBlock(), vue.createBlock(_sfc_main$5, {
3914
+ key: 0,
3915
+ "scroll-size": scrollHeight.value,
3916
+ size: __props.wrapHeight,
3917
+ pos: vOffset.value,
3918
+ onScroll: vScrollHandler
3919
+ }, null, 8, ["scroll-size", "size", "pos"])) : vue.createCommentVNode("", true),
3920
+ scrollWidth.value > __props.wrapWidth ? (vue.openBlock(), vue.createBlock(_sfc_main$5, {
3921
+ key: 1,
3922
+ "is-horizontal": true,
3923
+ "scroll-size": scrollWidth.value,
3924
+ pos: hOffset.value,
3925
+ size: __props.wrapWidth,
3926
+ onScroll: hScrollHandler
3927
+ }, null, 8, ["scroll-size", "pos", "size"])) : vue.createCommentVNode("", true)
3928
+ ], 512);
3584
3929
  };
3585
3930
  }
3586
3931
  });
3587
3932
 
3588
- const _hoisted_1$1 = {
3589
- class: "m-editor-scroll-viewer-container",
3590
- ref: "container"
3591
- };
3592
- function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3593
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
3594
- vue.createElementVNode("div", {
3595
- ref: "el",
3596
- style: vue.normalizeStyle(_ctx.style)
3597
- }, [
3598
- vue.renderSlot(_ctx.$slots, "default")
3599
- ], 4)
3600
- ], 512);
3601
- }
3602
- const ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$2]]);
3603
-
3604
3933
  const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
3605
3934
  __name: "ViewerMenu",
3606
3935
  props: {
@@ -3622,11 +3951,11 @@
3622
3951
  {
3623
3952
  type: "button",
3624
3953
  text: "\u6C34\u5E73\u5C45\u4E2D",
3625
- display: () => canCenter.value && !props.isMultiSelect,
3954
+ display: () => canCenter.value,
3626
3955
  handler: () => {
3627
- if (!node.value)
3956
+ if (!nodes.value)
3628
3957
  return;
3629
- editorService?.alignCenter(node.value);
3958
+ editorService?.alignCenter(nodes.value);
3630
3959
  }
3631
3960
  },
3632
3961
  {
@@ -3737,7 +4066,7 @@
3737
4066
  };
3738
4067
  expose({ show });
3739
4068
  return (_ctx, _cache) => {
3740
- return vue.openBlock(), vue.createBlock(_sfc_main$b, {
4069
+ return vue.openBlock(), vue.createBlock(_sfc_main$c, {
3741
4070
  "menu-data": menuData,
3742
4071
  ref_key: "menu",
3743
4072
  ref: menu
@@ -3758,12 +4087,11 @@
3758
4087
  const menu = vue.ref();
3759
4088
  const isMultiSelect = vue.computed(() => services?.editorService.get("nodes")?.length > 1);
3760
4089
  const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
3761
- const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4090
+ const stageContainerRect = vue.computed(() => services?.uiService.get("stageContainerRect"));
3762
4091
  const root = vue.computed(() => services?.editorService.get("root"));
3763
4092
  const page = vue.computed(() => services?.editorService.get("page"));
3764
4093
  const zoom = vue.computed(() => services?.uiService.get("zoom") || 1);
3765
4094
  const node = vue.computed(() => services?.editorService.get("node"));
3766
- const getGuideLineKey = (key) => `${key}_${root.value?.id}_${page.value?.id}`;
3767
4095
  vue.watchEffect(() => {
3768
4096
  if (stage)
3769
4097
  return;
@@ -3771,61 +4099,9 @@
3771
4099
  return;
3772
4100
  if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value)
3773
4101
  return;
3774
- stage = new StageCore__default.default({
3775
- render: stageOptions.render,
3776
- runtimeUrl: stageOptions.runtimeUrl,
3777
- zoom: zoom.value,
3778
- autoScrollIntoView: stageOptions.autoScrollIntoView,
3779
- isContainer: stageOptions.isContainer,
3780
- containerHighlightClassName: stageOptions.containerHighlightClassName,
3781
- containerHighlightDuration: stageOptions.containerHighlightDuration,
3782
- canSelect: (el, event, stop) => {
3783
- const elCanSelect = stageOptions.canSelect(el);
3784
- if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
3785
- document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
3786
- return stop();
3787
- }
3788
- return elCanSelect;
3789
- },
3790
- moveableOptions: stageOptions.moveableOptions,
3791
- updateDragEl: stageOptions.updateDragEl
3792
- });
4102
+ stage = useStage(stageOptions);
3793
4103
  services?.editorService.set("stage", vue.markRaw(stage));
3794
4104
  stage?.mount(stageContainer.value);
3795
- stage.mask.setGuides([
3796
- getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
3797
- getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
3798
- ]);
3799
- stage?.on("select", (el) => {
3800
- services?.editorService.select(el.id);
3801
- });
3802
- stage?.on("highlight", (el) => {
3803
- services?.editorService.highlight(el.id);
3804
- });
3805
- stage?.on("multiSelect", (els) => {
3806
- services?.editorService.multiSelect(els.map((el) => el.id));
3807
- });
3808
- stage?.on("update", (ev) => {
3809
- if (ev.parentEl) {
3810
- services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
3811
- return;
3812
- }
3813
- services?.editorService.update({ id: ev.el.id, style: ev.style });
3814
- });
3815
- stage?.on("sort", (ev) => {
3816
- services?.editorService.sort(ev.src, ev.dist);
3817
- });
3818
- stage?.on("changeGuides", (e2) => {
3819
- services?.uiService.set("showGuides", true);
3820
- if (!root.value || !page.value)
3821
- return;
3822
- const storageKey = getGuideLineKey(e2.type === StageCore.GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY);
3823
- if (e2.guides.length) {
3824
- globalThis.localStorage.setItem(storageKey, JSON.stringify(e2.guides));
3825
- } else {
3826
- globalThis.localStorage.removeItem(storageKey);
3827
- }
3828
- });
3829
4105
  if (!node.value?.id)
3830
4106
  return;
3831
4107
  stage?.on("runtime-ready", (rt) => {
@@ -3911,12 +4187,14 @@
3911
4187
  }
3912
4188
  };
3913
4189
  return (_ctx, _cache) => {
3914
- return vue.openBlock(), vue.createBlock(ScrollViewer, {
4190
+ return vue.openBlock(), vue.createBlock(_sfc_main$4, {
3915
4191
  class: "m-editor-stage",
3916
4192
  ref_key: "stageWrap",
3917
4193
  ref: stageWrap,
3918
4194
  width: vue.unref(stageRect)?.width,
3919
4195
  height: vue.unref(stageRect)?.height,
4196
+ "wrap-width": vue.unref(stageContainerRect)?.width,
4197
+ "wrap-height": vue.unref(stageContainerRect)?.height,
3920
4198
  zoom: vue.unref(zoom)
3921
4199
  }, {
3922
4200
  default: vue.withCtx(() => [
@@ -3924,7 +4202,7 @@
3924
4202
  class: "m-editor-stage-container",
3925
4203
  ref_key: "stageContainer",
3926
4204
  ref: stageContainer,
3927
- style: vue.normalizeStyle(`transform: scale(${vue.unref(zoom)})`),
4205
+ style: vue.normalizeStyle(`transform: scale(${vue.unref(zoom)});`),
3928
4206
  onContextmenu: contextmenuHandler,
3929
4207
  onDrop: dropHandler,
3930
4208
  onDragover: dragoverHandler
@@ -3938,28 +4216,25 @@
3938
4216
  ]))
3939
4217
  ]),
3940
4218
  _: 1
3941
- }, 8, ["width", "height", "zoom"]);
4219
+ }, 8, ["width", "height", "wrap-width", "wrap-height", "zoom"]);
3942
4220
  };
3943
4221
  }
3944
4222
  });
3945
4223
 
3946
- const _sfc_main$1 = vue.defineComponent({
3947
- name: "m-editor-workspace",
3948
- components: {
3949
- PageBar: _sfc_main$5,
3950
- MagicStage: _sfc_main$2
3951
- },
3952
- setup() {
4224
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
4225
+ __name: "Workspace",
4226
+ setup(__props) {
3953
4227
  const services = vue.inject("services");
3954
4228
  const workspace = vue.ref();
3955
4229
  const nodes = vue.computed(() => services?.editorService.get("nodes"));
3956
- let keycon;
4230
+ const page = vue.computed(() => services?.editorService.get("page"));
3957
4231
  const mouseenterHandler = () => {
3958
4232
  workspace.value?.focus();
3959
4233
  };
3960
4234
  const mouseleaveHandler = () => {
3961
4235
  workspace.value?.blur();
3962
4236
  };
4237
+ let keycon;
3963
4238
  vue.onMounted(() => {
3964
4239
  workspace.value?.addEventListener("mouseenter", mouseenterHandler);
3965
4240
  workspace.value?.addEventListener("mouseleave", mouseleaveHandler);
@@ -4036,6 +4311,12 @@
4036
4311
  }).keydown([ctrl, "numpad-"], (e) => {
4037
4312
  e.inputEvent.preventDefault();
4038
4313
  services?.uiService.zoom(-0.1);
4314
+ }).keydown([ctrl, "0"], (e) => {
4315
+ e.inputEvent.preventDefault();
4316
+ services?.uiService.set("zoom", services.uiService.calcZoom());
4317
+ }).keydown([ctrl, "1"], (e) => {
4318
+ e.inputEvent.preventDefault();
4319
+ services?.uiService.set("zoom", 1);
4039
4320
  });
4040
4321
  });
4041
4322
  vue.onUnmounted(() => {
@@ -4043,39 +4324,33 @@
4043
4324
  workspace.value?.removeEventListener("mouseleave", mouseleaveHandler);
4044
4325
  keycon.destroy();
4045
4326
  });
4046
- return {
4047
- workspace,
4048
- page: vue.computed(() => services?.editorService.get("page"))
4327
+ return (_ctx, _cache) => {
4328
+ return vue.openBlock(), vue.createElementBlock("div", {
4329
+ class: "m-editor-workspace",
4330
+ tabindex: "1",
4331
+ ref_key: "workspace",
4332
+ ref: workspace
4333
+ }, [
4334
+ vue.renderSlot(_ctx.$slots, "stage", {}, () => [
4335
+ (vue.openBlock(), vue.createBlock(_sfc_main$2, {
4336
+ key: vue.unref(page)?.id
4337
+ }))
4338
+ ]),
4339
+ vue.renderSlot(_ctx.$slots, "workspace-content"),
4340
+ vue.createVNode(_sfc_main$6, null, {
4341
+ "page-bar-title": vue.withCtx(({ page: page2 }) => [
4342
+ vue.renderSlot(_ctx.$slots, "page-bar-title", { page: page2 })
4343
+ ]),
4344
+ "page-bar-popover": vue.withCtx(({ page: page2 }) => [
4345
+ vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: page2 })
4346
+ ]),
4347
+ _: 3
4348
+ })
4349
+ ], 512);
4049
4350
  };
4050
4351
  }
4051
4352
  });
4052
4353
 
4053
- const _hoisted_1 = {
4054
- class: "m-editor-workspace",
4055
- tabindex: "1",
4056
- ref: "workspace"
4057
- };
4058
- function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
4059
- const _component_magic_stage = vue.resolveComponent("magic-stage");
4060
- const _component_page_bar = vue.resolveComponent("page-bar");
4061
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
4062
- (vue.openBlock(), vue.createBlock(_component_magic_stage, {
4063
- key: _ctx.page?.id
4064
- })),
4065
- vue.renderSlot(_ctx.$slots, "workspace-content"),
4066
- vue.createVNode(_component_page_bar, null, {
4067
- "page-bar-title": vue.withCtx(({ page }) => [
4068
- vue.renderSlot(_ctx.$slots, "page-bar-title", { page })
4069
- ]),
4070
- "page-bar-popover": vue.withCtx(({ page }) => [
4071
- vue.renderSlot(_ctx.$slots, "page-bar-popover", { page })
4072
- ]),
4073
- _: 3
4074
- })
4075
- ], 512);
4076
- }
4077
- const Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
4078
-
4079
4354
  class ComponentList extends BaseService {
4080
4355
  state = vue.reactive({
4081
4356
  list: []
@@ -4089,136 +4364,20 @@
4089
4364
  getList() {
4090
4365
  return this.state.list;
4091
4366
  }
4092
- }
4093
- const componentListService = new ComponentList();
4094
-
4095
- const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4096
- const MIN_LEFT_COLUMN_WIDTH = 45;
4097
- const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
4098
- const MIN_RIGHT_COLUMN_WIDTH = 1;
4099
- const COLUMN_WIDTH_STORAGE_KEY = "$MagicEditorColumnWidthData";
4100
- const defaultColumnWidth = {
4101
- left: DEFAULT_LEFT_COLUMN_WIDTH,
4102
- center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4103
- right: DEFAULT_RIGHT_COLUMN_WIDTH
4104
- };
4105
- const state = vue.reactive({
4106
- uiSelectMode: false,
4107
- showSrc: false,
4108
- zoom: 1,
4109
- stageContainerRect: {
4110
- width: 0,
4111
- height: 0
4112
- },
4113
- stageRect: {
4114
- width: 375,
4115
- height: 817
4116
- },
4117
- columnWidth: defaultColumnWidth,
4118
- showGuides: true,
4119
- showRule: true,
4120
- propsPanelSize: "small"
4121
- });
4122
- class Ui extends BaseService {
4123
- constructor() {
4124
- super([]);
4125
- globalThis.addEventListener("resize", () => {
4126
- this.setColumnWidth({
4127
- center: "auto"
4128
- });
4129
- });
4130
- const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
4131
- if (columnWidthCacheData) {
4132
- try {
4133
- const columnWidthCache = JSON.parse(columnWidthCacheData);
4134
- this.setColumnWidth(columnWidthCache);
4135
- } catch (e) {
4136
- console.error(e);
4137
- }
4138
- }
4139
- }
4140
- set(name, value) {
4141
- const mask = editorService.get("stage")?.mask;
4142
- if (name === "columnWidth") {
4143
- this.setColumnWidth(value);
4144
- return;
4145
- }
4146
- if (name === "stageRect") {
4147
- this.setStageRect(value);
4148
- return;
4149
- }
4150
- if (name === "showGuides") {
4151
- mask?.showGuides(value);
4152
- }
4153
- if (name === "showRule") {
4154
- mask?.showRule(value);
4155
- }
4156
- state[name] = value;
4157
- if (name === "stageContainerRect") {
4158
- state.zoom = this.calcZoom();
4159
- }
4160
- }
4161
- get(name) {
4162
- return state[name];
4163
- }
4164
- zoom(zoom) {
4165
- this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
4166
- if (this.get("zoom") < 0.1)
4167
- this.set("zoom", 0.1);
4168
- }
4169
- setColumnWidth({ left, center, right }) {
4170
- const columnWidth = {
4171
- ...vue.toRaw(this.get("columnWidth"))
4172
- };
4173
- if (left) {
4174
- columnWidth.left = Math.max(left, MIN_LEFT_COLUMN_WIDTH);
4175
- }
4176
- if (right) {
4177
- columnWidth.right = Math.max(right, MIN_RIGHT_COLUMN_WIDTH);
4178
- }
4179
- if (!center || center === "auto") {
4180
- const bodyWidth = globalThis.document.body.clientWidth;
4181
- columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
4182
- if (columnWidth.center <= 0) {
4183
- columnWidth.left = defaultColumnWidth.left;
4184
- columnWidth.center = defaultColumnWidth.center;
4185
- columnWidth.right = defaultColumnWidth.right;
4186
- }
4187
- } else {
4188
- columnWidth.center = center;
4189
- }
4190
- globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
4191
- state.columnWidth = columnWidth;
4192
- }
4193
- setStageRect(value) {
4194
- state.stageRect = {
4195
- ...state.stageRect,
4196
- ...value
4197
- };
4198
- state.zoom = this.calcZoom();
4199
- }
4200
- calcZoom() {
4201
- const { stageRect, stageContainerRect } = state;
4202
- const { height, width } = stageContainerRect;
4203
- if (!width || !height)
4204
- return 1;
4205
- const stageWidth = stageRect.width + 30;
4206
- const stageHeight = stageRect.height + 30;
4207
- if (width > stageWidth && height > stageHeight) {
4208
- return 1;
4209
- }
4210
- return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
4367
+ destroy() {
4368
+ this.state.list = [];
4369
+ this.removeAllListeners();
4211
4370
  }
4212
4371
  }
4213
- const uiService = new Ui();
4372
+ const componentListService = new ComponentList();
4214
4373
 
4215
4374
  const _sfc_main = vue.defineComponent({
4216
4375
  name: "m-editor",
4217
4376
  components: {
4218
- NavMenu,
4377
+ NavMenu: _sfc_main$f,
4219
4378
  Sidebar,
4220
- Workspace,
4221
- PropsPanel,
4379
+ Workspace: _sfc_main$1,
4380
+ PropsPanel: _sfc_main$e,
4222
4381
  Framework
4223
4382
  },
4224
4383
  props: {
@@ -4285,6 +4444,10 @@
4285
4444
  type: Number,
4286
4445
  default: 800
4287
4446
  },
4447
+ containerHighlightType: {
4448
+ type: String,
4449
+ default: StageCore.ContainerHighlightType.DEFAULT
4450
+ },
4288
4451
  stageRect: {
4289
4452
  type: [String, Object]
4290
4453
  },
@@ -4298,9 +4461,14 @@
4298
4461
  },
4299
4462
  emits: ["props-panel-mounted", "update:modelValue"],
4300
4463
  setup(props, { emit }) {
4301
- editorService.on("root-change", () => {
4302
- const node = editorService.get("node") || props.defaultSelected;
4303
- node && editorService.select(node);
4464
+ editorService.on("root-change", (value) => {
4465
+ const node = editorService.get("node");
4466
+ const nodeId = node?.id || props.defaultSelected;
4467
+ if (nodeId && node !== value) {
4468
+ editorService.select(nodeId);
4469
+ } else {
4470
+ editorService.set("nodes", [value]);
4471
+ }
4304
4472
  emit("update:modelValue", vue.toRaw(editorService.get("root")));
4305
4473
  });
4306
4474
  vue.watch(() => props.modelValue, (modelValue) => editorService.set("root", modelValue), {
@@ -4333,7 +4501,15 @@
4333
4501
  vue.watch(() => props.stageRect, (stageRect) => stageRect && uiService.set("stageRect", stageRect), {
4334
4502
  immediate: true
4335
4503
  });
4336
- vue.onUnmounted(() => editorService.destroy());
4504
+ uiService.initColumnWidth();
4505
+ vue.onUnmounted(() => {
4506
+ editorService.destroy();
4507
+ historyService.destroy();
4508
+ propsService.destroy();
4509
+ uiService.destroy();
4510
+ componentListService.destroy();
4511
+ storageService.destroy();
4512
+ });
4337
4513
  const services = {
4338
4514
  componentListService,
4339
4515
  eventsService,
@@ -4355,7 +4531,8 @@
4355
4531
  updateDragEl: props.updateDragEl,
4356
4532
  isContainer: props.isContainer,
4357
4533
  containerHighlightClassName: props.containerHighlightClassName,
4358
- containerHighlightDuration: props.containerHighlightDuration
4534
+ containerHighlightDuration: props.containerHighlightDuration,
4535
+ containerHighlightType: props.containerHighlightType
4359
4536
  }));
4360
4537
  return services;
4361
4538
  }
@@ -4389,6 +4566,9 @@
4389
4566
  workspace: vue.withCtx(() => [
4390
4567
  vue.renderSlot(_ctx.$slots, "workspace", { editorService: _ctx.editorService }, () => [
4391
4568
  vue.createVNode(_component_workspace, null, {
4569
+ stage: vue.withCtx(() => [
4570
+ vue.renderSlot(_ctx.$slots, "stage")
4571
+ ]),
4392
4572
  "workspace-content": vue.withCtx(() => [
4393
4573
  vue.renderSlot(_ctx.$slots, "workspace-content", { editorService: _ctx.editorService })
4394
4574
  ]),
@@ -4405,14 +4585,13 @@
4405
4585
  "props-panel": vue.withCtx(() => [
4406
4586
  vue.renderSlot(_ctx.$slots, "props-panel", {}, () => [
4407
4587
  vue.createVNode(_component_props_panel, {
4408
- ref: "propsPanel",
4409
4588
  onMounted: _cache[0] || (_cache[0] = (instance) => _ctx.$emit("props-panel-mounted", instance))
4410
4589
  }, {
4411
4590
  "props-panel-header": vue.withCtx(() => [
4412
4591
  vue.renderSlot(_ctx.$slots, "props-panel-header")
4413
4592
  ]),
4414
4593
  _: 3
4415
- }, 512)
4594
+ })
4416
4595
  ])
4417
4596
  ]),
4418
4597
  empty: vue.withCtx(() => [
@@ -4432,7 +4611,7 @@
4432
4611
  app.config.globalProperties.$TMAGIC_EDITOR = option;
4433
4612
  setConfig(option);
4434
4613
  app.component(Editor.name, Editor);
4435
- app.component("m-fields-ui-select", _sfc_main$l);
4614
+ app.component("m-fields-ui-select", _sfc_main$m);
4436
4615
  app.component(CodeLink.name, CodeLink);
4437
4616
  app.component(Code.name, Code);
4438
4617
  app.component(CodeEditor.name, CodeEditor);
@@ -4440,18 +4619,20 @@
4440
4619
  };
4441
4620
 
4442
4621
  exports.COPY_STORAGE_KEY = COPY_STORAGE_KEY;
4622
+ exports.ColumnLayout = ColumnLayout;
4443
4623
  exports.ComponentListPanel = ComponentListPanel;
4444
- exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
4624
+ exports.ContentMenu = _sfc_main$c;
4445
4625
  exports.Fixed2Other = Fixed2Other;
4446
4626
  exports.H_GUIDE_LINE_STORAGE_KEY = H_GUIDE_LINE_STORAGE_KEY;
4627
+ exports.Icon = _sfc_main$h;
4447
4628
  exports.Keys = Keys;
4448
4629
  exports.LayerOffset = LayerOffset;
4449
4630
  exports.LayerPanel = LayerPanel;
4450
4631
  exports.Layout = Layout;
4451
- exports.PropsPanel = PropsPanel;
4632
+ exports.PropsPanel = _sfc_main$e;
4452
4633
  exports.TMagicCodeEditor = CodeEditor;
4453
4634
  exports.TMagicEditor = Editor;
4454
- exports.ToolButton = _sfc_main$f;
4635
+ exports.ToolButton = _sfc_main$g;
4455
4636
  exports.V_GUIDE_LINE_STORAGE_KEY = V_GUIDE_LINE_STORAGE_KEY;
4456
4637
  exports.change2Fixed = change2Fixed;
4457
4638
  exports.debug = debug;
@@ -4480,6 +4661,7 @@
4480
4661
  exports.setLayout = setLayout;
4481
4662
  exports.storageService = storageService;
4482
4663
  exports.uiService = uiService;
4664
+ exports.useStage = useStage;
4483
4665
  exports.warn = warn;
4484
4666
 
4485
4667
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });