@tmagic/editor 1.1.0-beta.9 → 1.1.0

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 +971 -794
  3. package/dist/tmagic-editor.mjs.map +1 -1
  4. package/dist/tmagic-editor.umd.js +974 -794
  5. package/dist/tmagic-editor.umd.js.map +1 -1
  6. package/package.json +10 -10
  7. package/src/Editor.vue +15 -5
  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 -90
  21. package/src/layouts/workspace/ViewerMenu.vue +3 -3
  22. package/src/layouts/workspace/Workspace.vue +133 -138
  23. package/src/services/componentList.ts +5 -0
  24. package/src/services/editor.ts +56 -19
  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 +26 -10
  31. package/src/utils/index.ts +1 -0
  32. package/src/utils/operator.ts +3 -3
  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 +7 -7
  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 +1 -0
  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 +23 -10
  55. package/types/utils/index.d.ts +1 -0
  56. package/types/utils/operator.d.ts +1 -1
  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,10 +1049,10 @@
1048
1049
  top
1049
1050
  };
1050
1051
  };
1051
- const getAddParent = (addNode) => {
1052
+ const getAddParent = (node) => {
1052
1053
  const curNode = editorService.get("node");
1053
1054
  let parentNode;
1054
- if (!Array.isArray(addNode) && utils.isPage(addNode)) {
1055
+ if (utils.isPage(node)) {
1055
1056
  parentNode = editorService.get("root");
1056
1057
  } else if (curNode.items) {
1057
1058
  parentNode = curNode;
@@ -1087,6 +1088,7 @@
1087
1088
  "sort",
1088
1089
  "copy",
1089
1090
  "paste",
1091
+ "doPaste",
1090
1092
  "duAlignCenter",
1091
1093
  "alignCenter",
1092
1094
  "moveLayer",
@@ -1223,20 +1225,27 @@
1223
1225
  if ((parent?.type === schema.NodeType.ROOT || curNode.type === schema.NodeType.ROOT) && node.type !== schema.NodeType.PAGE) {
1224
1226
  throw new Error("app\u4E0B\u4E0D\u80FD\u6DFB\u52A0\u7EC4\u4EF6");
1225
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
+ }
1226
1234
  const layout = await this.getLayout(vue.toRaw(parent), node);
1227
1235
  node.style = getInitPositionStyle(node.style, layout);
1228
- 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
+ });
1229
1242
  node.style = fixNodePosition(node, parent, stage);
1230
- await stage?.update({ config: lodashEs.cloneDeep(node), root: lodashEs.cloneDeep(root) });
1231
- parent?.items?.push(node);
1243
+ await stage?.update({ config: lodashEs.cloneDeep(node), parentId: parent.id, root: lodashEs.cloneDeep(root) });
1232
1244
  this.addModifiedNodeId(node.id);
1233
1245
  return node;
1234
1246
  }
1235
1247
  async add(addNode, parent) {
1236
1248
  const stage = this.get("stage");
1237
- const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(addNode);
1238
- if (!parentNode)
1239
- throw new Error("\u672A\u627E\u5230\u7236\u5143\u7D20");
1240
1249
  const addNodes = [];
1241
1250
  if (!Array.isArray(addNode)) {
1242
1251
  const { type, inputEvent, ...config } = addNode;
@@ -1246,7 +1255,12 @@
1246
1255
  } else {
1247
1256
  addNodes.push(...addNode);
1248
1257
  }
1249
- 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
+ }));
1250
1264
  if (newNodes.length > 1) {
1251
1265
  const newNodeIds = newNodes.map((node) => node.id);
1252
1266
  stage?.multiSelect(newNodeIds);
@@ -1261,7 +1275,7 @@
1261
1275
  }
1262
1276
  this.pushHistoryState();
1263
1277
  this.emit("add", newNodes);
1264
- return newNodes.length > 1 ? newNodes[0] : newNodes;
1278
+ return Array.isArray(addNode) ? newNodes : newNodes[0];
1265
1279
  }
1266
1280
  async doRemove(node) {
1267
1281
  const root = this.get("root");
@@ -1275,7 +1289,7 @@
1275
1289
  throw new Error("\u627E\u4E0D\u8981\u5220\u9664\u7684\u8282\u70B9");
1276
1290
  parent.items?.splice(index, 1);
1277
1291
  const stage = this.get("stage");
1278
- stage?.remove({ id: node.id, root: this.get("root") });
1292
+ stage?.remove({ id: node.id, parentId: parent.id, root: lodashEs.cloneDeep(root) });
1279
1293
  if (node.type === schema.NodeType.PAGE) {
1280
1294
  this.state.pageLength -= 1;
1281
1295
  if (root.items[0]) {
@@ -1301,7 +1315,7 @@
1301
1315
  const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
1302
1316
  await Promise.all(nodes.map((node) => this.doRemove(node)));
1303
1317
  this.pushHistoryState();
1304
- this.emit("remove");
1318
+ this.emit("remove", nodes);
1305
1319
  }
1306
1320
  async doUpdate(config) {
1307
1321
  if (!config?.id)
@@ -1339,7 +1353,11 @@
1339
1353
  const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
1340
1354
  nodes.splice(targetIndex, 1, newConfig);
1341
1355
  this.set("nodes", nodes);
1342
- 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
+ });
1343
1361
  if (newConfig.type === schema.NodeType.PAGE) {
1344
1362
  this.set("page", newConfig);
1345
1363
  }
@@ -1351,7 +1369,7 @@
1351
1369
  const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
1352
1370
  this.pushHistoryState();
1353
1371
  this.emit("update", newNodes);
1354
- return newNodes.length > 1 ? newNodes[0] : newNodes;
1372
+ return Array.isArray(config) ? newNodes : newNodes[0];
1355
1373
  }
1356
1374
  async sort(id1, id2) {
1357
1375
  const node = this.get("node");
@@ -1363,7 +1381,11 @@
1363
1381
  parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
1364
1382
  await this.update(parent);
1365
1383
  await this.select(node);
1366
- 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
+ });
1367
1389
  this.addModifiedNodeId(parent.id);
1368
1390
  this.pushHistoryState();
1369
1391
  }
@@ -1376,9 +1398,13 @@
1376
1398
  const config = await storageService.getItem(COPY_STORAGE_KEY);
1377
1399
  if (!Array.isArray(config))
1378
1400
  return;
1379
- const pasteConfigs = await beforePaste(position, config);
1401
+ const pasteConfigs = await this.doPaste(config, position);
1380
1402
  return this.add(pasteConfigs);
1381
1403
  }
1404
+ async doPaste(config, position = {}) {
1405
+ const pasteConfigs = await beforePaste(position, lodashEs.cloneDeep(config));
1406
+ return pasteConfigs;
1407
+ }
1382
1408
  async doAlignCenter(config) {
1383
1409
  const parent = this.getParentById(config.id);
1384
1410
  if (!parent)
@@ -1423,10 +1449,14 @@
1423
1449
  } else {
1424
1450
  brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
1425
1451
  }
1452
+ const grandparent = this.getParentById(parent.id);
1426
1453
  this.get("stage")?.update({
1427
1454
  config: lodashEs.cloneDeep(vue.toRaw(parent)),
1455
+ parentId: grandparent?.id,
1428
1456
  root: lodashEs.cloneDeep(this.get("root"))
1429
1457
  });
1458
+ this.addModifiedNodeId(parent.id);
1459
+ this.pushHistoryState();
1430
1460
  }
1431
1461
  async moveToContainer(config, targetId) {
1432
1462
  const { node, parent } = this.getNodeInfo(config.id, false);
@@ -1436,7 +1466,7 @@
1436
1466
  const root = lodashEs.cloneDeep(this.get("root"));
1437
1467
  const index = getNodeIndex(node, parent);
1438
1468
  parent.items?.splice(index, 1);
1439
- await stage.remove({ id: node.id, root });
1469
+ await stage.remove({ id: node.id, parentId: parent.id, root });
1440
1470
  const layout = await this.getLayout(target);
1441
1471
  const newConfig = lodashEs.mergeWith(lodashEs.cloneDeep(node), config, (objValue, srcValue) => {
1442
1472
  if (Array.isArray(srcValue)) {
@@ -1446,7 +1476,8 @@
1446
1476
  newConfig.style = getInitPositionStyle(newConfig.style, layout);
1447
1477
  target.items.push(newConfig);
1448
1478
  await stage.select(targetId);
1449
- 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 });
1450
1481
  await this.select(newConfig);
1451
1482
  stage.select(newConfig.id);
1452
1483
  this.addModifiedNodeId(target.id);
@@ -1493,6 +1524,10 @@
1493
1524
  this.set("nodes", []);
1494
1525
  this.set("page", null);
1495
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());
1496
1531
  }
1497
1532
  resetModifiedNodeId() {
1498
1533
  this.get("modifiedNodeIds").clear();
@@ -1562,8 +1597,8 @@
1562
1597
  }
1563
1598
  const editorService = new Editor$1();
1564
1599
 
1565
- const eventMap = vue.reactive({});
1566
- const methodMap = vue.reactive({});
1600
+ let eventMap = vue.reactive({});
1601
+ let methodMap = vue.reactive({});
1567
1602
  class Events extends BaseService {
1568
1603
  constructor() {
1569
1604
  super([]);
@@ -1603,6 +1638,11 @@
1603
1638
  getMethod(type) {
1604
1639
  return lodashEs.cloneDeep(methodMap[type] || core.DEFAULT_METHODS);
1605
1640
  }
1641
+ destroy() {
1642
+ eventMap = vue.reactive({});
1643
+ methodMap = vue.reactive({});
1644
+ this.removeAllListeners();
1645
+ }
1606
1646
  }
1607
1647
  const eventsService = new Events();
1608
1648
 
@@ -1809,7 +1849,6 @@
1809
1849
  ]
1810
1850
  }
1811
1851
  ];
1812
- const DEFAULT_CONFIG = fillConfig([]);
1813
1852
 
1814
1853
  const log = (...args) => {
1815
1854
  if (process.env.NODE_ENV === "development") {
@@ -1837,7 +1876,194 @@
1837
1876
  }
1838
1877
  };
1839
1878
 
1840
- 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({
1841
2067
  components: { Plus: iconsVue.Plus },
1842
2068
  setup() {
1843
2069
  const services = vue.inject("services");
@@ -1855,13 +2081,13 @@
1855
2081
  }
1856
2082
  });
1857
2083
 
1858
- const _hoisted_1$b = { class: "m-editor-empty-panel" };
2084
+ const _hoisted_1$9 = { class: "m-editor-empty-panel" };
1859
2085
  const _hoisted_2$4 = { class: "m-editor-empty-content" };
1860
- const _hoisted_3$1 = /* @__PURE__ */ vue.createElementVNode("p", null, "\u65B0\u589E\u9875\u9762", -1);
1861
- 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) {
1862
2088
  const _component_plus = vue.resolveComponent("plus");
1863
2089
  const _component_el_icon = vue.resolveComponent("el-icon");
1864
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, [
2090
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
1865
2091
  vue.createElementVNode("div", _hoisted_2$4, [
1866
2092
  vue.createElementVNode("div", {
1867
2093
  class: "m-editor-empty-button",
@@ -1875,14 +2101,14 @@
1875
2101
  _: 1
1876
2102
  })
1877
2103
  ]),
1878
- _hoisted_3$1
2104
+ _hoisted_3
1879
2105
  ])
1880
2106
  ])
1881
2107
  ]);
1882
2108
  }
1883
- 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]]);
1884
2110
 
1885
- const _sfc_main$i = vue.defineComponent({
2111
+ const _sfc_main$j = vue.defineComponent({
1886
2112
  name: "m-editor-resize",
1887
2113
  props: {
1888
2114
  type: {
@@ -1925,18 +2151,18 @@
1925
2151
  }
1926
2152
  });
1927
2153
 
1928
- const _hoisted_1$a = {
2154
+ const _hoisted_1$8 = {
1929
2155
  ref: "target",
1930
2156
  class: "m-editor-resizer"
1931
2157
  };
1932
- function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
1933
- 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, [
1934
2160
  vue.renderSlot(_ctx.$slots, "default")
1935
2161
  ], 512);
1936
2162
  }
1937
- 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]]);
1938
2164
 
1939
- const _sfc_main$h = vue.defineComponent({
2165
+ const _sfc_main$i = vue.defineComponent({
1940
2166
  components: {
1941
2167
  AddPageBox,
1942
2168
  Resizer
@@ -1966,17 +2192,17 @@
1966
2192
  }
1967
2193
  });
1968
2194
 
1969
- const _hoisted_1$9 = { class: "m-editor" };
2195
+ const _hoisted_1$7 = { class: "m-editor" };
1970
2196
  const _hoisted_2$3 = {
1971
2197
  key: 1,
1972
2198
  class: "m-editor-content"
1973
2199
  };
1974
- function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
2200
+ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
1975
2201
  const _component_magic_code_editor = vue.resolveComponent("magic-code-editor");
1976
2202
  const _component_resizer = vue.resolveComponent("resizer");
1977
2203
  const _component_el_scrollbar = vue.resolveComponent("el-scrollbar");
1978
2204
  const _component_add_page_box = vue.resolveComponent("add-page-box");
1979
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
2205
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$7, [
1980
2206
  vue.renderSlot(_ctx.$slots, "nav", { class: "m-editor-nav-menu" }),
1981
2207
  _ctx.showSrc ? (vue.openBlock(), vue.createBlock(_component_magic_code_editor, {
1982
2208
  key: 0,
@@ -2017,211 +2243,112 @@
2017
2243
  ]))
2018
2244
  ]);
2019
2245
  }
2020
- 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]]);
2021
2247
 
2022
- const _sfc_main$g = vue.defineComponent({
2023
- name: "m-icon",
2024
- components: { Edit: iconsVue.Edit },
2248
+ const _hoisted_1$6 = ["src"];
2249
+ const _sfc_main$h = /* @__PURE__ */ vue.defineComponent({
2250
+ __name: "Icon",
2025
2251
  props: {
2026
- icon: {
2027
- type: [String, Object]
2028
- }
2252
+ icon: null
2029
2253
  },
2030
- setup() {
2031
- return {
2032
- toRaw: vue.toRaw
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
+ }));
2033
2276
  };
2034
2277
  }
2035
2278
  });
2036
2279
 
2037
- const _hoisted_1$8 = ["src"];
2038
- function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
2039
- const _component_edit = vue.resolveComponent("edit");
2040
- const _component_el_icon = vue.resolveComponent("el-icon");
2041
- return !_ctx.icon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0 }, {
2042
- default: vue.withCtx(() => [
2043
- vue.createVNode(_component_edit)
2044
- ]),
2045
- _: 1
2046
- })) : typeof _ctx.icon === "string" && _ctx.icon.startsWith("http") ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 1 }, {
2047
- default: vue.withCtx(() => [
2048
- vue.createElementVNode("img", { src: _ctx.icon }, null, 8, _hoisted_1$8)
2049
- ]),
2050
- _: 1
2051
- })) : typeof _ctx.icon === "string" ? (vue.openBlock(), vue.createElementBlock("i", {
2052
- key: 2,
2053
- class: vue.normalizeClass(_ctx.icon)
2054
- }, null, 2)) : (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 3 }, {
2055
- default: vue.withCtx(() => [
2056
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.toRaw(_ctx.icon))))
2057
- ]),
2058
- _: 1
2059
- }));
2060
- }
2061
- const MIcon = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$a]]);
2062
-
2063
- const _hoisted_1$7 = {
2280
+ const _hoisted_1$5 = {
2064
2281
  key: 1,
2065
2282
  class: "menu-item-text"
2066
2283
  };
2067
- const _hoisted_2$2 = {
2068
- class: "menu-item-text",
2069
- style: { "margin": "0 5px" }
2070
- };
2071
- const _hoisted_3 = { class: "el-dropdown-link menubar-menu-button" };
2072
- 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({
2073
2286
  __name: "ToolButton",
2074
2287
  props: {
2075
- data: {
2076
- type: [Object, String],
2077
- require: true,
2078
- default: () => ({
2079
- type: "text",
2080
- display: false
2081
- })
2082
- },
2083
- eventType: {
2084
- type: String,
2085
- default: "click"
2086
- }
2288
+ data: { default: () => ({
2289
+ type: "text",
2290
+ display: false
2291
+ }) },
2292
+ eventType: { default: "click" }
2087
2293
  },
2088
2294
  setup(__props) {
2089
2295
  const props = __props;
2090
2296
  const services = vue.inject("services");
2091
- const uiService = services?.uiService;
2092
- const zoom = vue.computed(() => uiService?.get("zoom") ?? 1);
2093
- const showGuides = vue.computed(() => uiService?.get("showGuides") ?? true);
2094
- const showRule = vue.computed(() => uiService?.get("showRule") ?? true);
2095
- const zoomInHandler = () => uiService?.zoom(0.1);
2096
- const zoomOutHandler = () => uiService?.zoom(-0.1);
2097
- const item = vue.computed(() => {
2098
- if (typeof props.data !== "string") {
2099
- return props.data;
2100
- }
2101
- switch (props.data) {
2102
- case "/":
2103
- return {
2104
- type: "divider"
2105
- };
2106
- case "zoom":
2107
- return {
2108
- type: "zoom"
2109
- };
2110
- case "delete":
2111
- return {
2112
- type: "button",
2113
- icon: vue.markRaw(iconsVue.Delete),
2114
- tooltip: "\u522A\u9664",
2115
- disabled: () => services?.editorService.get("node")?.type === schema.NodeType.PAGE,
2116
- handler: () => services?.editorService.remove(services?.editorService.get("node"))
2117
- };
2118
- case "undo":
2119
- return {
2120
- type: "button",
2121
- icon: vue.markRaw(iconsVue.Back),
2122
- tooltip: "\u540E\u9000",
2123
- disabled: () => !services?.historyService.state.canUndo,
2124
- handler: () => services?.editorService.undo()
2125
- };
2126
- case "redo":
2127
- return {
2128
- type: "button",
2129
- icon: vue.markRaw(iconsVue.Right),
2130
- tooltip: "\u524D\u8FDB",
2131
- disabled: () => !services?.historyService.state.canRedo,
2132
- handler: () => services?.editorService.redo()
2133
- };
2134
- case "zoom-in":
2135
- return {
2136
- type: "button",
2137
- icon: vue.markRaw(iconsVue.ZoomIn),
2138
- tooltip: "\u653E\u5927",
2139
- handler: zoomInHandler
2140
- };
2141
- case "zoom-out":
2142
- return {
2143
- type: "button",
2144
- icon: vue.markRaw(iconsVue.ZoomOut),
2145
- tooltip: "\u7E2E\u5C0F",
2146
- handler: zoomOutHandler
2147
- };
2148
- case "rule":
2149
- return {
2150
- type: "button",
2151
- icon: vue.markRaw(iconsVue.ScaleToOriginal),
2152
- tooltip: showRule.value ? "\u9690\u85CF\u6807\u5C3A" : "\u663E\u793A\u6807\u5C3A",
2153
- handler: () => uiService?.set("showRule", !showRule.value)
2154
- };
2155
- case "guides":
2156
- return {
2157
- type: "button",
2158
- icon: vue.markRaw(iconsVue.Grid),
2159
- tooltip: showGuides.value ? "\u9690\u85CF\u53C2\u8003\u7EBF" : "\u663E\u793A\u53C2\u8003\u7EBF",
2160
- handler: () => uiService?.set("showGuides", !showGuides.value)
2161
- };
2162
- default:
2163
- return {
2164
- type: "text",
2165
- text: props.data
2166
- };
2297
+ const disabled = vue.computed(() => {
2298
+ if (typeof props.data === "string")
2299
+ return false;
2300
+ if (props.data.type === "component")
2301
+ return false;
2302
+ if (typeof props.data.disabled === "function") {
2303
+ return props.data.disabled(services);
2167
2304
  }
2305
+ return props.data.disabled;
2168
2306
  });
2169
- const disabled = vue.computed(() => {
2170
- if (typeof item.value === "string")
2171
- return false;
2172
- if (item.value.type === "component")
2307
+ const display = vue.computed(() => {
2308
+ if (!props.data)
2173
2309
  return false;
2174
- if (typeof item.value.disabled === "function") {
2175
- return item.value.disabled(services);
2310
+ if (typeof props.data === "string")
2311
+ return true;
2312
+ if (typeof props.data.display === "function") {
2313
+ return props.data.display(services);
2176
2314
  }
2177
- return item.value.disabled;
2315
+ return props.data.display ?? true;
2178
2316
  });
2179
- const buttonHandler = (item2, event) => {
2317
+ const buttonHandler = (item, event) => {
2180
2318
  if (disabled.value)
2181
2319
  return;
2182
- if (typeof item2.handler === "function" && services) {
2183
- item2.handler?.(services, event);
2320
+ if (typeof item.handler === "function" && services) {
2321
+ item.handler?.(services, event);
2184
2322
  }
2185
2323
  };
2186
- const display = vue.computed(() => {
2187
- if (!item.value)
2188
- return false;
2189
- if (typeof item.value === "string")
2190
- return true;
2191
- if (typeof item.value.display === "function") {
2192
- return item.value.display(services);
2193
- }
2194
- return item.value.display ?? true;
2195
- });
2196
2324
  const dropdownHandler = (command) => {
2197
2325
  if (command.item.handler) {
2198
2326
  command.item.handler(services);
2199
2327
  }
2200
2328
  };
2201
- const clickHandler = (item2, event) => {
2329
+ const clickHandler = (item, event) => {
2202
2330
  if (props.eventType !== "click")
2203
2331
  return;
2204
- if (item2.type === "button") {
2205
- buttonHandler(item2, event);
2332
+ if (item.type === "button") {
2333
+ buttonHandler(item, event);
2206
2334
  }
2207
2335
  };
2208
- const mousedownHandler = (item2, event) => {
2336
+ const mousedownHandler = (item, event) => {
2209
2337
  if (props.eventType !== "mousedown")
2210
2338
  return;
2211
- if (item2.type === "button") {
2212
- buttonHandler(item2, event);
2339
+ if (item.type === "button") {
2340
+ buttonHandler(item, event);
2213
2341
  }
2214
2342
  };
2215
- const mouseupHandler = (item2, event) => {
2343
+ const mouseupHandler = (item, event) => {
2216
2344
  if (props.eventType !== "mouseup")
2217
2345
  return;
2218
- if (item2.type === "button") {
2219
- buttonHandler(item2, event);
2346
+ if (item.type === "button") {
2347
+ buttonHandler(item, event);
2220
2348
  }
2221
2349
  };
2222
2350
  return (_ctx, _cache) => {
2223
2351
  const _component_el_divider = vue.resolveComponent("el-divider");
2224
- const _component_tool_button = vue.resolveComponent("tool-button", true);
2225
2352
  const _component_el_button = vue.resolveComponent("el-button");
2226
2353
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
2227
2354
  const _component_el_icon = vue.resolveComponent("el-icon");
@@ -2230,30 +2357,20 @@
2230
2357
  const _component_el_dropdown = vue.resolveComponent("el-dropdown");
2231
2358
  return vue.unref(display) ? (vue.openBlock(), vue.createElementBlock("div", {
2232
2359
  key: 0,
2233
- class: vue.normalizeClass(["menu-item", vue.unref(item).type]),
2234
- onClick: _cache[0] || (_cache[0] = ($event) => clickHandler(vue.unref(item), $event)),
2235
- onMousedown: _cache[1] || (_cache[1] = ($event) => mousedownHandler(vue.unref(item), $event)),
2236
- 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))
2237
2364
  }, [
2238
- vue.unref(item).type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2365
+ __props.data.type === "divider" ? (vue.openBlock(), vue.createBlock(_component_el_divider, {
2239
2366
  key: 0,
2240
- direction: vue.unref(item).direction || "vertical"
2241
- }, 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 }, [
2242
- vue.createVNode(_component_tool_button, {
2243
- data: { type: "button", icon: vue.unref(iconsVue.ZoomOut), handler: zoomOutHandler, tooltip: "\u7F29\u5C0F" },
2244
- "event-type": __props.eventType
2245
- }, null, 8, ["data", "event-type"]),
2246
- vue.createElementVNode("span", _hoisted_2$2, vue.toDisplayString(parseInt(`${vue.unref(zoom) * 100}`, 10)) + "%", 1),
2247
- vue.createVNode(_component_tool_button, {
2248
- data: { type: "button", icon: vue.unref(iconsVue.ZoomIn), handler: zoomInHandler, tooltip: "\u653E\u5927" },
2249
- "event-type": __props.eventType
2250
- }, null, 8, ["data", "event-type"])
2251
- ], 64)) : vue.unref(item).type === "button" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
2252
- 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, {
2253
2370
  key: 0,
2254
2371
  effect: "dark",
2255
2372
  placement: "bottom-start",
2256
- content: vue.unref(item).tooltip
2373
+ content: __props.data.tooltip
2257
2374
  }, {
2258
2375
  default: vue.withCtx(() => [
2259
2376
  vue.createVNode(_component_el_button, {
@@ -2262,11 +2379,11 @@
2262
2379
  disabled: vue.unref(disabled)
2263
2380
  }, {
2264
2381
  default: vue.withCtx(() => [
2265
- vue.unref(item).icon ? (vue.openBlock(), vue.createBlock(MIcon, {
2382
+ __props.data.icon ? (vue.openBlock(), vue.createBlock(_sfc_main$h, {
2266
2383
  key: 0,
2267
- icon: vue.unref(item).icon
2384
+ icon: __props.data.icon
2268
2385
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
2269
- vue.createElementVNode("span", null, vue.toDisplayString(vue.unref(item).text), 1)
2386
+ vue.createElementVNode("span", null, vue.toDisplayString(__props.data.text), 1)
2270
2387
  ]),
2271
2388
  _: 1
2272
2389
  }, 8, ["disabled"])
@@ -2279,27 +2396,27 @@
2279
2396
  disabled: vue.unref(disabled)
2280
2397
  }, {
2281
2398
  default: vue.withCtx(() => [
2282
- vue.unref(item).icon ? (vue.openBlock(), vue.createBlock(MIcon, {
2399
+ __props.data.icon ? (vue.openBlock(), vue.createBlock(_sfc_main$h, {
2283
2400
  key: 0,
2284
- icon: vue.unref(item).icon
2401
+ icon: __props.data.icon
2285
2402
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
2286
- vue.createElementVNode("span", null, vue.toDisplayString(vue.unref(item).text), 1)
2403
+ vue.createElementVNode("span", null, vue.toDisplayString(__props.data.text), 1)
2287
2404
  ]),
2288
2405
  _: 1
2289
2406
  }, 8, ["disabled"]))
2290
- ], 64)) : vue.unref(item).type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2291
- key: 4,
2407
+ ], 64)) : __props.data.type === "dropdown" ? (vue.openBlock(), vue.createBlock(_component_el_dropdown, {
2408
+ key: 3,
2292
2409
  trigger: "click",
2293
2410
  disabled: vue.unref(disabled),
2294
2411
  onCommand: dropdownHandler
2295
2412
  }, {
2296
2413
  dropdown: vue.withCtx(() => [
2297
- 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 }, {
2298
2415
  default: vue.withCtx(() => [
2299
- (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) => {
2300
2417
  return vue.openBlock(), vue.createBlock(_component_el_dropdown_item, {
2301
2418
  key: index,
2302
- command: { item: vue.unref(item), subItem }
2419
+ command: { data: __props.data, subItem }
2303
2420
  }, {
2304
2421
  default: vue.withCtx(() => [
2305
2422
  vue.createTextVNode(vue.toDisplayString(subItem.text), 1)
@@ -2312,8 +2429,8 @@
2312
2429
  })) : vue.createCommentVNode("", true)
2313
2430
  ]),
2314
2431
  default: vue.withCtx(() => [
2315
- vue.createElementVNode("span", _hoisted_3, [
2316
- 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),
2317
2434
  vue.createVNode(_component_el_icon, { class: "el-icon--right" }, {
2318
2435
  default: vue.withCtx(() => [
2319
2436
  vue.createVNode(vue.unref(iconsVue.ArrowDown))
@@ -2323,67 +2440,187 @@
2323
2440
  ])
2324
2441
  ]),
2325
2442
  _: 1
2326
- }, 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)
2327
2444
  ], 34)) : vue.createCommentVNode("", true);
2328
2445
  };
2329
2446
  }
2330
2447
  });
2331
2448
 
2332
- const _sfc_main$e = vue.defineComponent({
2333
- name: "nav-menu",
2334
- components: { ToolButton: _sfc_main$f },
2449
+ const _sfc_main$f = /* @__PURE__ */ vue.defineComponent({
2450
+ __name: "NavMenu",
2335
2451
  props: {
2336
- data: {
2337
- type: Object,
2338
- default: () => ({})
2339
- },
2340
- height: {
2341
- type: Number
2342
- }
2452
+ data: { default: () => ({}) },
2453
+ height: { default: 35 }
2343
2454
  },
2344
- setup(props) {
2455
+ setup(__props) {
2456
+ const props = __props;
2345
2457
  const services = vue.inject("services");
2346
- return {
2347
- keys: vue.computed(() => Object.keys(props.data)),
2348
- 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;
2349
2572
  };
2350
- }
2351
- });
2352
-
2353
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
2354
- const _component_tool_button = vue.resolveComponent("tool-button");
2355
- return vue.openBlock(), vue.createElementBlock("div", {
2356
- class: "m-editor-nav-menu",
2357
- style: vue.normalizeStyle({ height: `${_ctx.height}px` })
2358
- }, [
2359
- (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) => {
2360
2588
  return vue.openBlock(), vue.createElementBlock("div", {
2361
- class: vue.normalizeClass(`menu-${key}`),
2362
- key,
2363
- style: vue.normalizeStyle(`width: ${_ctx.columnWidth?.[key]}px`)
2589
+ class: "m-editor-nav-menu",
2590
+ style: vue.normalizeStyle({ height: `${__props.height}px` })
2364
2591
  }, [
2365
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.data[key], (item, index) => {
2366
- return vue.openBlock(), vue.createBlock(_component_tool_button, {
2367
- data: item,
2368
- key: index
2369
- }, 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);
2370
2605
  }), 128))
2371
- ], 6);
2372
- }), 128))
2373
- ], 4);
2374
- }
2375
- const NavMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$9]]);
2606
+ ], 4);
2607
+ };
2608
+ }
2609
+ });
2376
2610
 
2377
- const _sfc_main$d = vue.defineComponent({
2378
- 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",
2379
2614
  emits: ["mounted"],
2380
- setup(props, { emit }) {
2615
+ setup(__props, { expose, emit }) {
2381
2616
  const internalInstance = vue.getCurrentInstance();
2382
2617
  const values = vue.ref({});
2383
2618
  const configForm = vue.ref();
2384
2619
  const curFormConfig = vue.ref([]);
2385
2620
  const services = vue.inject("services");
2386
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"));
2387
2624
  const init = async () => {
2388
2625
  if (!node.value) {
2389
2626
  curFormConfig.value = [];
@@ -2398,51 +2635,49 @@
2398
2635
  vue.onMounted(() => {
2399
2636
  emit("mounted", internalInstance);
2400
2637
  });
2401
- return {
2402
- values,
2403
- configForm,
2404
- curFormConfig,
2405
- propsPanelSize: vue.computed(() => services?.uiService.get("propsPanelSize") || "small"),
2406
- async submit() {
2407
- try {
2408
- const values2 = await configForm.value?.submitForm();
2409
- services?.editorService.update(values2);
2410
- } catch (e) {
2411
- console.error(e);
2412
- elementPlus.ElMessage.closeAll();
2413
- elementPlus.ElMessage.error({
2414
- duration: 1e4,
2415
- showClose: true,
2416
- message: e.message,
2417
- dangerouslyUseHTMLString: true
2418
- });
2419
- }
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
+ });
2420
2656
  }
2421
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
+ };
2422
2675
  }
2423
2676
  });
2424
2677
 
2425
- const _hoisted_1$6 = { class: "`m-editor-props-panel" };
2426
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
2427
- const _component_m_form = vue.resolveComponent("m-form");
2428
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
2429
- vue.renderSlot(_ctx.$slots, "props-panel-header"),
2430
- vue.createVNode(_component_m_form, {
2431
- class: vue.normalizeClass(`m-editor-props-panel ${_ctx.propsPanelSize}`),
2432
- "popper-class": `m-editor-props-panel-popper ${_ctx.propsPanelSize}`,
2433
- ref: "configForm",
2434
- size: _ctx.propsPanelSize,
2435
- "init-values": _ctx.values,
2436
- config: _ctx.curFormConfig,
2437
- onChange: _ctx.submit
2438
- }, null, 8, ["class", "popper-class", "size", "init-values", "config", "onChange"])
2439
- ]);
2440
- }
2441
- const PropsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$8]]);
2442
-
2443
- const _sfc_main$c = vue.defineComponent({
2678
+ const _sfc_main$d = vue.defineComponent({
2444
2679
  name: "ui-component-panel",
2445
- components: { MIcon },
2680
+ components: { MIcon: _sfc_main$h },
2446
2681
  setup() {
2447
2682
  const searchText = vue.ref("");
2448
2683
  const services = vue.inject("services");
@@ -2507,9 +2742,9 @@
2507
2742
  }
2508
2743
  });
2509
2744
 
2510
- 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);
2511
2746
  const _hoisted_2$1 = ["onClick", "onDragstart"];
2512
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2747
+ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
2513
2748
  const _component_el_input = vue.resolveComponent("el-input");
2514
2749
  const _component_m_icon = vue.resolveComponent("m-icon");
2515
2750
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
@@ -2540,7 +2775,7 @@
2540
2775
  name: index
2541
2776
  }, {
2542
2777
  title: vue.withCtx(() => [
2543
- _hoisted_1$5,
2778
+ _hoisted_1$3,
2544
2779
  vue.createTextVNode(vue.toDisplayString(group.title), 1)
2545
2780
  ]),
2546
2781
  default: vue.withCtx(() => [
@@ -2581,9 +2816,9 @@
2581
2816
  _: 3
2582
2817
  });
2583
2818
  }
2584
- 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]]);
2585
2820
 
2586
- const _sfc_main$b = /* @__PURE__ */ vue.defineComponent({
2821
+ const _sfc_main$c = /* @__PURE__ */ vue.defineComponent({
2587
2822
  __name: "ContentMenu",
2588
2823
  props: {
2589
2824
  menuData: { default: () => [] },
@@ -2672,7 +2907,7 @@
2672
2907
  }, [
2673
2908
  vue.createElementVNode("div", null, [
2674
2909
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.menuData, (item, index) => {
2675
- return vue.openBlock(), vue.createBlock(_sfc_main$f, {
2910
+ return vue.openBlock(), vue.createBlock(_sfc_main$g, {
2676
2911
  "event-type": "mouseup",
2677
2912
  data: item,
2678
2913
  key: index,
@@ -2696,8 +2931,8 @@
2696
2931
  }
2697
2932
  });
2698
2933
 
2699
- const _sfc_main$a = vue.defineComponent({
2700
- components: { ContentMenu: _sfc_main$b },
2934
+ const _sfc_main$b = vue.defineComponent({
2935
+ components: { ContentMenu: _sfc_main$c },
2701
2936
  setup() {
2702
2937
  const services = vue.inject("services");
2703
2938
  const menu = vue.ref();
@@ -2780,7 +3015,7 @@
2780
3015
  }
2781
3016
  });
2782
3017
 
2783
- function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
3018
+ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
2784
3019
  const _component_content_menu = vue.resolveComponent("content-menu");
2785
3020
  return vue.openBlock(), vue.createBlock(_component_content_menu, {
2786
3021
  "menu-data": _ctx.menuData,
@@ -2788,7 +3023,7 @@
2788
3023
  style: { "overflow": "initial" }
2789
3024
  }, null, 8, ["menu-data"]);
2790
3025
  }
2791
- 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]]);
2792
3027
 
2793
3028
  const throttleTime = 150;
2794
3029
  const select = async (data, editorService) => {
@@ -2839,20 +3074,38 @@
2839
3074
  }
2840
3075
  });
2841
3076
  const useStatus = (tree, editorService) => {
2842
- const highlightNode = vue.ref();
2843
3077
  const node = vue.ref();
2844
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
+ };
2845
3087
  vue.watchEffect(() => {
2846
3088
  if (!tree.value)
2847
3089
  return;
2848
- node.value = editorService?.get("node");
2849
- node.value && tree.value.setCurrentKey(node.value.id, true);
2850
- 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");
2851
3097
  if (!parent?.id)
2852
3098
  return;
2853
3099
  const treeNode = tree.value.getNode(parent.id);
2854
3100
  treeNode?.updateChildren();
2855
- 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
+ });
2856
3109
  });
2857
3110
  return {
2858
3111
  values: vue.computed(() => page.value ? [page.value] : []),
@@ -2865,9 +3118,18 @@
2865
3118
  }
2866
3119
  resolve([]);
2867
3120
  },
2868
- highlightNode,
3121
+ highlightNode: vue.computed(() => editorService?.get("highlightNode")),
2869
3122
  clickNode: node,
2870
- 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
+ }
2871
3133
  };
2872
3134
  };
2873
3135
  const useFilter = (tree) => ({
@@ -2888,7 +3150,7 @@
2888
3150
  tree.value?.filter(val);
2889
3151
  }
2890
3152
  });
2891
- const _sfc_main$9 = vue.defineComponent({
3153
+ const _sfc_main$a = vue.defineComponent({
2892
3154
  name: "magic-editor-layer-panel",
2893
3155
  components: { LayerMenu },
2894
3156
  setup() {
@@ -2936,8 +3198,8 @@
2936
3198
  }
2937
3199
  });
2938
3200
 
2939
- const _hoisted_1$4 = ["id", "onMouseenter"];
2940
- 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) {
2941
3203
  const _component_el_input = vue.resolveComponent("el-input");
2942
3204
  const _component_el_tree = vue.resolveComponent("el-tree");
2943
3205
  const _component_layer_menu = vue.resolveComponent("layer-menu");
@@ -2958,6 +3220,7 @@
2958
3220
  key: 0,
2959
3221
  ref: "tree",
2960
3222
  "node-key": "id",
3223
+ "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684",
2961
3224
  draggable: "",
2962
3225
  "default-expanded-keys": _ctx.expandedKeys,
2963
3226
  load: _ctx.loadItems,
@@ -2972,7 +3235,8 @@
2972
3235
  onNodeClick: _ctx.clickHandler,
2973
3236
  onNodeContextmenu: _ctx.contextmenu,
2974
3237
  onNodeDragEnd: _ctx.handleDragEnd,
2975
- "empty-text": "\u9875\u9762\u7A7A\u8361\u8361\u7684"
3238
+ onNodeCollapse: _ctx.handleCollapse,
3239
+ onNodeExpand: _ctx.handleExpand
2976
3240
  }, {
2977
3241
  default: vue.withCtx(({ node, data }) => [
2978
3242
  vue.createElementVNode("div", {
@@ -2988,10 +3252,10 @@
2988
3252
  }, () => [
2989
3253
  vue.createElementVNode("span", null, vue.toDisplayString(`${data.name} (${data.id})`), 1)
2990
3254
  ])
2991
- ], 42, _hoisted_1$4)
3255
+ ], 42, _hoisted_1$2)
2992
3256
  ]),
2993
3257
  _: 3
2994
- }, 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),
2995
3259
  (vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [
2996
3260
  vue.createVNode(_component_layer_menu, { ref: "menu" }, null, 512)
2997
3261
  ]))
@@ -2999,10 +3263,10 @@
2999
3263
  _: 3
3000
3264
  });
3001
3265
  }
3002
- 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]]);
3003
3267
 
3004
- const _sfc_main$8 = vue.defineComponent({
3005
- components: { MIcon },
3268
+ const _sfc_main$9 = vue.defineComponent({
3269
+ components: { MIcon: _sfc_main$h },
3006
3270
  props: {
3007
3271
  data: {
3008
3272
  type: [Object, String]
@@ -3039,11 +3303,11 @@
3039
3303
  }
3040
3304
  });
3041
3305
 
3042
- const _hoisted_1$3 = {
3306
+ const _hoisted_1$1 = {
3043
3307
  key: 1,
3044
3308
  class: "magic-editor-tab-panel-title"
3045
3309
  };
3046
- function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
3310
+ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3047
3311
  const _component_m_icon = vue.resolveComponent("m-icon");
3048
3312
  const _component_el_tab_pane = vue.resolveComponent("el-tab-pane");
3049
3313
  return _ctx.config ? (vue.openBlock(), vue.createBlock(_component_el_tab_pane, {
@@ -3058,7 +3322,7 @@
3058
3322
  key: 0,
3059
3323
  icon: _ctx.config.icon
3060
3324
  }, null, 8, ["icon"])) : vue.createCommentVNode("", true),
3061
- _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)
3062
3326
  ]))
3063
3327
  ]),
3064
3328
  default: vue.withCtx(() => [
@@ -3089,9 +3353,9 @@
3089
3353
  _: 3
3090
3354
  }, 8, ["name"])) : vue.createCommentVNode("", true);
3091
3355
  }
3092
- 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]]);
3093
3357
 
3094
- const _sfc_main$7 = vue.defineComponent({
3358
+ const _sfc_main$8 = vue.defineComponent({
3095
3359
  components: { TabPane },
3096
3360
  name: "m-sidebar",
3097
3361
  props: {
@@ -3111,7 +3375,7 @@
3111
3375
  }
3112
3376
  });
3113
3377
 
3114
- function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
3378
+ function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
3115
3379
  const _component_tab_pane = vue.resolveComponent("tab-pane");
3116
3380
  const _component_el_tabs = vue.resolveComponent("el-tabs");
3117
3381
  return _ctx.data.type === "tabs" && _ctx.data.items.length ? (vue.openBlock(), vue.createBlock(_component_el_tabs, {
@@ -3146,9 +3410,9 @@
3146
3410
  _: 3
3147
3411
  }, 8, ["modelValue"])) : vue.createCommentVNode("", true);
3148
3412
  }
3149
- 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]]);
3150
3414
 
3151
- const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
3415
+ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
3152
3416
  __name: "PageBarScrollContainer",
3153
3417
  setup(__props) {
3154
3418
  const services = vue.inject("services");
@@ -3275,9 +3539,9 @@
3275
3539
  }
3276
3540
  });
3277
3541
 
3278
- const _hoisted_1$2 = ["onClick"];
3542
+ const _hoisted_1 = ["onClick"];
3279
3543
  const _hoisted_2 = { class: "m-editor-page-bar-title" };
3280
- const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
3544
+ const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
3281
3545
  __name: "PageBar",
3282
3546
  setup(__props) {
3283
3547
  const services = vue.inject("services");
@@ -3301,7 +3565,7 @@
3301
3565
  const _component_el_tooltip = vue.resolveComponent("el-tooltip");
3302
3566
  const _component_el_icon = vue.resolveComponent("el-icon");
3303
3567
  const _component_el_popover = vue.resolveComponent("el-popover");
3304
- return vue.openBlock(), vue.createBlock(_sfc_main$6, null, {
3568
+ return vue.openBlock(), vue.createBlock(_sfc_main$7, null, {
3305
3569
  default: vue.withCtx(() => [
3306
3570
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(root) && vue.unref(root).items || [], (item) => {
3307
3571
  return vue.openBlock(), vue.createElementBlock("div", {
@@ -3317,7 +3581,7 @@
3317
3581
  content: item.name
3318
3582
  }, {
3319
3583
  default: vue.withCtx(() => [
3320
- vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1)
3584
+ vue.createElementVNode("span", null, vue.toDisplayString(item.name || item.id), 1)
3321
3585
  ]),
3322
3586
  _: 2
3323
3587
  }, 1032, ["content"])
@@ -3340,7 +3604,7 @@
3340
3604
  default: vue.withCtx(() => [
3341
3605
  vue.createElementVNode("div", null, [
3342
3606
  vue.renderSlot(_ctx.$slots, "page-bar-popover", { page: item }, () => [
3343
- vue.createVNode(_sfc_main$f, {
3607
+ vue.createVNode(_sfc_main$g, {
3344
3608
  data: {
3345
3609
  type: "button",
3346
3610
  text: "\u590D\u5236",
@@ -3348,7 +3612,7 @@
3348
3612
  handler: () => copy(item)
3349
3613
  }
3350
3614
  }, null, 8, ["data"]),
3351
- vue.createVNode(_sfc_main$f, {
3615
+ vue.createVNode(_sfc_main$g, {
3352
3616
  data: {
3353
3617
  type: "button",
3354
3618
  text: "\u5220\u9664",
@@ -3361,7 +3625,7 @@
3361
3625
  ]),
3362
3626
  _: 2
3363
3627
  }, 1024)
3364
- ], 10, _hoisted_1$2);
3628
+ ], 10, _hoisted_1);
3365
3629
  }), 128))
3366
3630
  ]),
3367
3631
  _: 3
@@ -3370,190 +3634,245 @@
3370
3634
  }
3371
3635
  });
3372
3636
 
3373
- class ScrollViewer$1 {
3374
- enter = false;
3375
- targetEnter = false;
3376
- keydown = false;
3637
+ class ScrollViewer extends events.EventEmitter {
3377
3638
  container;
3378
3639
  target;
3379
3640
  zoom = 1;
3380
3641
  scrollLeft = 0;
3381
3642
  scrollTop = 0;
3382
- x = 0;
3383
- y = 0;
3384
- resizeObserver = new ResizeObserver((entries) => {
3385
- for (const { contentRect } of entries) {
3386
- const { width, height } = contentRect;
3387
- const targetRect = this.target.getBoundingClientRect();
3388
- const targetWidth = targetRect.width * this.zoom;
3389
- const targetMarginTop = Number(this.target.style.marginTop) || 0;
3390
- const targetHeight = (targetRect.height + targetMarginTop) * this.zoom;
3391
- if (targetWidth < width) {
3392
- this.target._left = 0;
3393
- }
3394
- if (targetHeight < height) {
3395
- this.target._top = 0;
3396
- }
3397
- this.scroll();
3398
- }
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();
3399
3652
  });
3400
3653
  constructor(options) {
3654
+ super();
3401
3655
  this.container = options.container;
3402
3656
  this.target = options.target;
3403
3657
  this.zoom = options.zoom;
3404
- globalThis.addEventListener("keydown", this.keydownHandler);
3405
- globalThis.addEventListener("keyup", this.keyupHandler);
3406
- this.container.addEventListener("mouseenter", this.mouseEnterHandler);
3407
- this.container.addEventListener("mouseleave", this.mouseLeaveHandler);
3408
- this.target.addEventListener("mouseenter", this.targetMouseEnterHandler);
3409
- this.target.addEventListener("mouseleave", this.targetMouseLeaveHandler);
3410
- this.container.addEventListener("wheel", this.wheelHandler);
3658
+ this.container.addEventListener("wheel", this.wheelHandler, false);
3659
+ this.setSize();
3660
+ this.setScrollSize();
3411
3661
  this.resizeObserver.observe(this.container);
3412
3662
  }
3413
3663
  destroy() {
3414
3664
  this.resizeObserver.disconnect();
3415
- this.container.removeEventListener("mouseenter", this.mouseEnterHandler);
3416
- this.container.removeEventListener("mouseleave", this.mouseLeaveHandler);
3417
- this.target.removeEventListener("mouseenter", this.targetMouseEnterHandler);
3418
- this.target.removeEventListener("mouseleave", this.targetMouseLeaveHandler);
3419
- globalThis.removeEventListener("keydown", this.keydownHandler);
3420
- globalThis.removeEventListener("keyup", this.keyupHandler);
3665
+ this.container.removeEventListener("wheel", this.wheelHandler, false);
3666
+ this.removeAllListeners();
3421
3667
  }
3422
3668
  setZoom(zoom) {
3423
3669
  this.zoom = zoom;
3670
+ this.setScrollSize();
3424
3671
  }
3425
- scroll() {
3426
- const scrollLeft = this.target._left;
3427
- const scrollTop = this.target._top;
3428
- this.target.style.transform = `translate(${scrollLeft}px, ${scrollTop}px)`;
3429
- }
3430
- removeHandler() {
3431
- this.target.style.cursor = "";
3432
- this.target.removeEventListener("mousedown", this.mousedownHandler);
3433
- document.removeEventListener("mousemove", this.mousemoveHandler);
3434
- 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)`;
3435
3682
  }
3436
3683
  wheelHandler = (event) => {
3437
- if (this.targetEnter)
3438
- return;
3439
3684
  const { deltaX, deltaY, currentTarget } = event;
3440
3685
  if (currentTarget !== this.container)
3441
3686
  return;
3442
- this.setScrollOffset(deltaX, deltaY);
3443
- this.scroll();
3444
- this.scrollLeft = this.target._left;
3445
- this.scrollTop = this.target._top;
3446
- };
3447
- mouseEnterHandler = () => {
3448
- this.enter = true;
3449
- };
3450
- mouseLeaveHandler = () => {
3451
- this.enter = false;
3452
- };
3453
- targetMouseEnterHandler = () => {
3454
- this.targetEnter = true;
3455
- };
3456
- targetMouseLeaveHandler = () => {
3457
- this.targetEnter = false;
3458
- };
3459
- mousedownHandler = (event) => {
3460
- if (!this.keydown)
3461
- return;
3462
- event.stopImmediatePropagation();
3463
- event.stopPropagation();
3464
- this.target.style.cursor = "grabbing";
3465
- this.x = event.clientX;
3466
- this.y = event.clientY;
3467
- document.addEventListener("mousemove", this.mousemoveHandler);
3468
- document.addEventListener("mouseup", this.mouseupHandler);
3469
- };
3470
- mouseupHandler = () => {
3471
- this.x = 0;
3472
- this.y = 0;
3473
- this.scrollLeft = this.target._left;
3474
- this.scrollTop = this.target._top;
3475
- this.removeHandler();
3476
- };
3477
- mousemoveHandler = (event) => {
3478
- event.stopImmediatePropagation();
3479
- event.stopPropagation();
3480
- const deltaX = event.clientX - this.x;
3481
- const deltaY = event.clientY - this.y;
3482
- this.setScrollOffset(deltaX, deltaY);
3483
- this.scroll();
3484
- };
3485
- keydownHandler = (event) => {
3486
- if (event.code === Keys.ESCAPE && this.enter) {
3487
- event.preventDefault();
3488
- event.stopImmediatePropagation();
3489
- event.stopPropagation();
3687
+ let top;
3688
+ if (this.scrollHeight > this.height) {
3689
+ top = this.scrollTop + this.getPos(deltaY, this.scrollTop, this.scrollHeight, this.height);
3490
3690
  }
3491
- if (event.code !== Keys.ESCAPE || !this.enter || this.keydown) {
3492
- return;
3691
+ let left;
3692
+ if (this.scrollWidth > this.width) {
3693
+ left = this.scrollLeft + this.getPos(deltaX, this.scrollLeft, this.scrollWidth, this.width);
3493
3694
  }
3494
- this.keydown = true;
3495
- this.target.style.cursor = "grab";
3496
- 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
+ });
3497
3702
  };
3498
- keyupHandler = (event) => {
3499
- if (event.code !== Keys.ESCAPE || !this.keydown) {
3500
- 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
+ }
3714
+ }
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;
3501
3729
  }
3502
- event.preventDefault();
3503
- event.stopImmediatePropagation();
3504
- event.stopPropagation();
3505
- this.keydown = false;
3506
- event.preventDefault();
3507
- this.removeHandler();
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
+ });
3508
3746
  };
3509
- setScrollOffset(deltaX, deltaY) {
3747
+ setSize = () => {
3510
3748
  const { width, height } = this.container.getBoundingClientRect();
3511
- const targetRect = this.target.getBoundingClientRect();
3512
- const targetWidth = targetRect.width * this.zoom;
3513
- const targetHeight = targetRect.height * this.zoom;
3514
- let y = 0;
3515
- if (targetHeight > height) {
3516
- if (deltaY > 0) {
3517
- y = this.scrollTop + Math.min(targetHeight - height - this.scrollTop, deltaY);
3518
- } else {
3519
- 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();
3520
3798
  }
3521
- }
3522
- let x = 0;
3523
- if (targetWidth > width) {
3524
- if (deltaX > 0) {
3525
- 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
+ }
3526
3812
  } else {
3527
- 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
+ }
3528
3819
  }
3529
- }
3530
- this.target._left = x;
3531
- 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
+ };
3532
3835
  }
3533
- }
3836
+ });
3534
3837
 
3535
- const _sfc_main$4 = vue.defineComponent({
3536
- name: "m-editor-scroll-viewer",
3838
+ const ScrollBar_vue_vue_type_style_index_0_lang = '';
3839
+
3840
+ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
3841
+ __name: "ScrollViewer",
3537
3842
  props: {
3538
- width: Number,
3539
- height: Number,
3540
- zoom: {
3541
- type: Number,
3542
- default: 1
3543
- }
3843
+ width: { default: 0 },
3844
+ height: { default: 0 },
3845
+ wrapWidth: { default: 0 },
3846
+ wrapHeight: { default: 0 },
3847
+ zoom: { default: 1 }
3544
3848
  },
3545
- setup(props) {
3849
+ setup(__props, { expose }) {
3850
+ const props = __props;
3546
3851
  const container = vue.ref();
3547
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);
3548
3861
  let scrollViewer;
3549
3862
  vue.onMounted(() => {
3550
3863
  if (!container.value || !el.value)
3551
3864
  return;
3552
- scrollViewer = new ScrollViewer$1({
3865
+ scrollViewer = new ScrollViewer({
3553
3866
  container: container.value,
3554
3867
  target: el.value,
3555
3868
  zoom: props.zoom
3556
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
+ });
3557
3876
  });
3558
3877
  vue.onUnmounted(() => {
3559
3878
  scrollViewer.destroy();
@@ -3561,35 +3880,56 @@
3561
3880
  vue.watch(() => props.zoom, () => {
3562
3881
  scrollViewer.setZoom(props.zoom);
3563
3882
  });
3564
- return {
3565
- container,
3566
- el,
3567
- style: vue.computed(() => `
3568
- width: ${props.width}px;
3569
- height: ${props.height}px;
3570
- position: absolute;
3571
- margin-top: 30px;
3572
- `)
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);
3573
3929
  };
3574
3930
  }
3575
3931
  });
3576
3932
 
3577
- const _hoisted_1$1 = {
3578
- class: "m-editor-scroll-viewer-container",
3579
- ref: "container"
3580
- };
3581
- function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
3582
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
3583
- vue.createElementVNode("div", {
3584
- ref: "el",
3585
- style: vue.normalizeStyle(_ctx.style)
3586
- }, [
3587
- vue.renderSlot(_ctx.$slots, "default")
3588
- ], 4)
3589
- ], 512);
3590
- }
3591
- const ScrollViewer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$2]]);
3592
-
3593
3933
  const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
3594
3934
  __name: "ViewerMenu",
3595
3935
  props: {
@@ -3726,7 +4066,7 @@
3726
4066
  };
3727
4067
  expose({ show });
3728
4068
  return (_ctx, _cache) => {
3729
- return vue.openBlock(), vue.createBlock(_sfc_main$b, {
4069
+ return vue.openBlock(), vue.createBlock(_sfc_main$c, {
3730
4070
  "menu-data": menuData,
3731
4071
  ref_key: "menu",
3732
4072
  ref: menu
@@ -3747,12 +4087,11 @@
3747
4087
  const menu = vue.ref();
3748
4088
  const isMultiSelect = vue.computed(() => services?.editorService.get("nodes")?.length > 1);
3749
4089
  const stageRect = vue.computed(() => services?.uiService.get("stageRect"));
3750
- const uiSelectMode = vue.computed(() => services?.uiService.get("uiSelectMode"));
4090
+ const stageContainerRect = vue.computed(() => services?.uiService.get("stageContainerRect"));
3751
4091
  const root = vue.computed(() => services?.editorService.get("root"));
3752
4092
  const page = vue.computed(() => services?.editorService.get("page"));
3753
4093
  const zoom = vue.computed(() => services?.uiService.get("zoom") || 1);
3754
4094
  const node = vue.computed(() => services?.editorService.get("node"));
3755
- const getGuideLineKey = (key) => `${key}_${root.value?.id}_${page.value?.id}`;
3756
4095
  vue.watchEffect(() => {
3757
4096
  if (stage)
3758
4097
  return;
@@ -3760,64 +4099,9 @@
3760
4099
  return;
3761
4100
  if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value)
3762
4101
  return;
3763
- stage = new StageCore__default.default({
3764
- render: stageOptions.render,
3765
- runtimeUrl: stageOptions.runtimeUrl,
3766
- zoom: zoom.value,
3767
- autoScrollIntoView: stageOptions.autoScrollIntoView,
3768
- isContainer: stageOptions.isContainer,
3769
- containerHighlightClassName: stageOptions.containerHighlightClassName,
3770
- containerHighlightDuration: stageOptions.containerHighlightDuration,
3771
- containerHighlightType: stageOptions.containerHighlightType,
3772
- canSelect: (el, event, stop) => {
3773
- const elCanSelect = stageOptions.canSelect(el);
3774
- if (uiSelectMode.value && elCanSelect && event.type === "mousedown") {
3775
- document.dispatchEvent(new CustomEvent("ui-select", { detail: el }));
3776
- return stop();
3777
- }
3778
- return elCanSelect;
3779
- },
3780
- moveableOptions: stageOptions.moveableOptions,
3781
- updateDragEl: stageOptions.updateDragEl
3782
- });
4102
+ stage = useStage(stageOptions);
3783
4103
  services?.editorService.set("stage", vue.markRaw(stage));
3784
4104
  stage?.mount(stageContainer.value);
3785
- stage.mask.setGuides([
3786
- getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
3787
- getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY))
3788
- ]);
3789
- stage?.on("select", (el) => {
3790
- services?.editorService.select(el.id);
3791
- });
3792
- stage?.on("highlight", (el) => {
3793
- services?.editorService.highlight(el.id);
3794
- });
3795
- stage?.on("multiSelect", (els) => {
3796
- services?.editorService.multiSelect(els.map((el) => el.id));
3797
- });
3798
- stage?.on("update", (ev) => {
3799
- if (ev.parentEl) {
3800
- for (const data of ev.data) {
3801
- services?.editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
3802
- }
3803
- return;
3804
- }
3805
- services?.editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
3806
- });
3807
- stage?.on("sort", (ev) => {
3808
- services?.editorService.sort(ev.src, ev.dist);
3809
- });
3810
- stage?.on("changeGuides", (e2) => {
3811
- services?.uiService.set("showGuides", true);
3812
- if (!root.value || !page.value)
3813
- return;
3814
- const storageKey = getGuideLineKey(e2.type === StageCore.GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY);
3815
- if (e2.guides.length) {
3816
- globalThis.localStorage.setItem(storageKey, JSON.stringify(e2.guides));
3817
- } else {
3818
- globalThis.localStorage.removeItem(storageKey);
3819
- }
3820
- });
3821
4105
  if (!node.value?.id)
3822
4106
  return;
3823
4107
  stage?.on("runtime-ready", (rt) => {
@@ -3903,12 +4187,14 @@
3903
4187
  }
3904
4188
  };
3905
4189
  return (_ctx, _cache) => {
3906
- return vue.openBlock(), vue.createBlock(ScrollViewer, {
4190
+ return vue.openBlock(), vue.createBlock(_sfc_main$4, {
3907
4191
  class: "m-editor-stage",
3908
4192
  ref_key: "stageWrap",
3909
4193
  ref: stageWrap,
3910
4194
  width: vue.unref(stageRect)?.width,
3911
4195
  height: vue.unref(stageRect)?.height,
4196
+ "wrap-width": vue.unref(stageContainerRect)?.width,
4197
+ "wrap-height": vue.unref(stageContainerRect)?.height,
3912
4198
  zoom: vue.unref(zoom)
3913
4199
  }, {
3914
4200
  default: vue.withCtx(() => [
@@ -3916,7 +4202,7 @@
3916
4202
  class: "m-editor-stage-container",
3917
4203
  ref_key: "stageContainer",
3918
4204
  ref: stageContainer,
3919
- style: vue.normalizeStyle(`transform: scale(${vue.unref(zoom)})`),
4205
+ style: vue.normalizeStyle(`transform: scale(${vue.unref(zoom)});`),
3920
4206
  onContextmenu: contextmenuHandler,
3921
4207
  onDrop: dropHandler,
3922
4208
  onDragover: dragoverHandler
@@ -3930,28 +4216,25 @@
3930
4216
  ]))
3931
4217
  ]),
3932
4218
  _: 1
3933
- }, 8, ["width", "height", "zoom"]);
4219
+ }, 8, ["width", "height", "wrap-width", "wrap-height", "zoom"]);
3934
4220
  };
3935
4221
  }
3936
4222
  });
3937
4223
 
3938
- const _sfc_main$1 = vue.defineComponent({
3939
- name: "m-editor-workspace",
3940
- components: {
3941
- PageBar: _sfc_main$5,
3942
- MagicStage: _sfc_main$2
3943
- },
3944
- setup() {
4224
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
4225
+ __name: "Workspace",
4226
+ setup(__props) {
3945
4227
  const services = vue.inject("services");
3946
4228
  const workspace = vue.ref();
3947
4229
  const nodes = vue.computed(() => services?.editorService.get("nodes"));
3948
- let keycon;
4230
+ const page = vue.computed(() => services?.editorService.get("page"));
3949
4231
  const mouseenterHandler = () => {
3950
4232
  workspace.value?.focus();
3951
4233
  };
3952
4234
  const mouseleaveHandler = () => {
3953
4235
  workspace.value?.blur();
3954
4236
  };
4237
+ let keycon;
3955
4238
  vue.onMounted(() => {
3956
4239
  workspace.value?.addEventListener("mouseenter", mouseenterHandler);
3957
4240
  workspace.value?.addEventListener("mouseleave", mouseleaveHandler);
@@ -4028,6 +4311,12 @@
4028
4311
  }).keydown([ctrl, "numpad-"], (e) => {
4029
4312
  e.inputEvent.preventDefault();
4030
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);
4031
4320
  });
4032
4321
  });
4033
4322
  vue.onUnmounted(() => {
@@ -4035,39 +4324,33 @@
4035
4324
  workspace.value?.removeEventListener("mouseleave", mouseleaveHandler);
4036
4325
  keycon.destroy();
4037
4326
  });
4038
- return {
4039
- workspace,
4040
- 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);
4041
4350
  };
4042
4351
  }
4043
4352
  });
4044
4353
 
4045
- const _hoisted_1 = {
4046
- class: "m-editor-workspace",
4047
- tabindex: "1",
4048
- ref: "workspace"
4049
- };
4050
- function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
4051
- const _component_magic_stage = vue.resolveComponent("magic-stage");
4052
- const _component_page_bar = vue.resolveComponent("page-bar");
4053
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
4054
- (vue.openBlock(), vue.createBlock(_component_magic_stage, {
4055
- key: _ctx.page?.id
4056
- })),
4057
- vue.renderSlot(_ctx.$slots, "workspace-content"),
4058
- vue.createVNode(_component_page_bar, null, {
4059
- "page-bar-title": vue.withCtx(({ page }) => [
4060
- vue.renderSlot(_ctx.$slots, "page-bar-title", { page })
4061
- ]),
4062
- "page-bar-popover": vue.withCtx(({ page }) => [
4063
- vue.renderSlot(_ctx.$slots, "page-bar-popover", { page })
4064
- ]),
4065
- _: 3
4066
- })
4067
- ], 512);
4068
- }
4069
- const Workspace = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
4070
-
4071
4354
  class ComponentList extends BaseService {
4072
4355
  state = vue.reactive({
4073
4356
  list: []
@@ -4081,136 +4364,20 @@
4081
4364
  getList() {
4082
4365
  return this.state.list;
4083
4366
  }
4084
- }
4085
- const componentListService = new ComponentList();
4086
-
4087
- const DEFAULT_LEFT_COLUMN_WIDTH = 310;
4088
- const MIN_LEFT_COLUMN_WIDTH = 45;
4089
- const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
4090
- const MIN_RIGHT_COLUMN_WIDTH = 1;
4091
- const COLUMN_WIDTH_STORAGE_KEY = "$MagicEditorColumnWidthData";
4092
- const defaultColumnWidth = {
4093
- left: DEFAULT_LEFT_COLUMN_WIDTH,
4094
- center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
4095
- right: DEFAULT_RIGHT_COLUMN_WIDTH
4096
- };
4097
- const state = vue.reactive({
4098
- uiSelectMode: false,
4099
- showSrc: false,
4100
- zoom: 1,
4101
- stageContainerRect: {
4102
- width: 0,
4103
- height: 0
4104
- },
4105
- stageRect: {
4106
- width: 375,
4107
- height: 817
4108
- },
4109
- columnWidth: defaultColumnWidth,
4110
- showGuides: true,
4111
- showRule: true,
4112
- propsPanelSize: "small"
4113
- });
4114
- class Ui extends BaseService {
4115
- constructor() {
4116
- super([]);
4117
- globalThis.addEventListener("resize", () => {
4118
- this.setColumnWidth({
4119
- center: "auto"
4120
- });
4121
- });
4122
- const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
4123
- if (columnWidthCacheData) {
4124
- try {
4125
- const columnWidthCache = JSON.parse(columnWidthCacheData);
4126
- this.setColumnWidth(columnWidthCache);
4127
- } catch (e) {
4128
- console.error(e);
4129
- }
4130
- }
4131
- }
4132
- set(name, value) {
4133
- const mask = editorService.get("stage")?.mask;
4134
- if (name === "columnWidth") {
4135
- this.setColumnWidth(value);
4136
- return;
4137
- }
4138
- if (name === "stageRect") {
4139
- this.setStageRect(value);
4140
- return;
4141
- }
4142
- if (name === "showGuides") {
4143
- mask?.showGuides(value);
4144
- }
4145
- if (name === "showRule") {
4146
- mask?.showRule(value);
4147
- }
4148
- state[name] = value;
4149
- if (name === "stageContainerRect") {
4150
- state.zoom = this.calcZoom();
4151
- }
4152
- }
4153
- get(name) {
4154
- return state[name];
4155
- }
4156
- zoom(zoom) {
4157
- this.set("zoom", (this.get("zoom") * 100 + zoom * 100) / 100);
4158
- if (this.get("zoom") < 0.1)
4159
- this.set("zoom", 0.1);
4160
- }
4161
- setColumnWidth({ left, center, right }) {
4162
- const columnWidth = {
4163
- ...vue.toRaw(this.get("columnWidth"))
4164
- };
4165
- if (left) {
4166
- columnWidth.left = Math.max(left, MIN_LEFT_COLUMN_WIDTH);
4167
- }
4168
- if (right) {
4169
- columnWidth.right = Math.max(right, MIN_RIGHT_COLUMN_WIDTH);
4170
- }
4171
- if (!center || center === "auto") {
4172
- const bodyWidth = globalThis.document.body.clientWidth;
4173
- columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
4174
- if (columnWidth.center <= 0) {
4175
- columnWidth.left = defaultColumnWidth.left;
4176
- columnWidth.center = defaultColumnWidth.center;
4177
- columnWidth.right = defaultColumnWidth.right;
4178
- }
4179
- } else {
4180
- columnWidth.center = center;
4181
- }
4182
- globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
4183
- state.columnWidth = columnWidth;
4184
- }
4185
- setStageRect(value) {
4186
- state.stageRect = {
4187
- ...state.stageRect,
4188
- ...value
4189
- };
4190
- state.zoom = this.calcZoom();
4191
- }
4192
- calcZoom() {
4193
- const { stageRect, stageContainerRect } = state;
4194
- const { height, width } = stageContainerRect;
4195
- if (!width || !height)
4196
- return 1;
4197
- const stageWidth = stageRect.width + 30;
4198
- const stageHeight = stageRect.height + 30;
4199
- if (width > stageWidth && height > stageHeight) {
4200
- return 1;
4201
- }
4202
- return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
4367
+ destroy() {
4368
+ this.state.list = [];
4369
+ this.removeAllListeners();
4203
4370
  }
4204
4371
  }
4205
- const uiService = new Ui();
4372
+ const componentListService = new ComponentList();
4206
4373
 
4207
4374
  const _sfc_main = vue.defineComponent({
4208
4375
  name: "m-editor",
4209
4376
  components: {
4210
- NavMenu,
4377
+ NavMenu: _sfc_main$f,
4211
4378
  Sidebar,
4212
- Workspace,
4213
- PropsPanel,
4379
+ Workspace: _sfc_main$1,
4380
+ PropsPanel: _sfc_main$e,
4214
4381
  Framework
4215
4382
  },
4216
4383
  props: {
@@ -4329,7 +4496,15 @@
4329
4496
  vue.watch(() => props.stageRect, (stageRect) => stageRect && uiService.set("stageRect", stageRect), {
4330
4497
  immediate: true
4331
4498
  });
4332
- vue.onUnmounted(() => editorService.destroy());
4499
+ uiService.initColumnWidth();
4500
+ vue.onUnmounted(() => {
4501
+ editorService.destroy();
4502
+ historyService.destroy();
4503
+ propsService.destroy();
4504
+ uiService.destroy();
4505
+ componentListService.destroy();
4506
+ storageService.destroy();
4507
+ });
4333
4508
  const services = {
4334
4509
  componentListService,
4335
4510
  eventsService,
@@ -4386,6 +4561,9 @@
4386
4561
  workspace: vue.withCtx(() => [
4387
4562
  vue.renderSlot(_ctx.$slots, "workspace", { editorService: _ctx.editorService }, () => [
4388
4563
  vue.createVNode(_component_workspace, null, {
4564
+ stage: vue.withCtx(() => [
4565
+ vue.renderSlot(_ctx.$slots, "stage")
4566
+ ]),
4389
4567
  "workspace-content": vue.withCtx(() => [
4390
4568
  vue.renderSlot(_ctx.$slots, "workspace-content", { editorService: _ctx.editorService })
4391
4569
  ]),
@@ -4402,14 +4580,13 @@
4402
4580
  "props-panel": vue.withCtx(() => [
4403
4581
  vue.renderSlot(_ctx.$slots, "props-panel", {}, () => [
4404
4582
  vue.createVNode(_component_props_panel, {
4405
- ref: "propsPanel",
4406
4583
  onMounted: _cache[0] || (_cache[0] = (instance) => _ctx.$emit("props-panel-mounted", instance))
4407
4584
  }, {
4408
4585
  "props-panel-header": vue.withCtx(() => [
4409
4586
  vue.renderSlot(_ctx.$slots, "props-panel-header")
4410
4587
  ]),
4411
4588
  _: 3
4412
- }, 512)
4589
+ })
4413
4590
  ])
4414
4591
  ]),
4415
4592
  empty: vue.withCtx(() => [
@@ -4429,7 +4606,7 @@
4429
4606
  app.config.globalProperties.$TMAGIC_EDITOR = option;
4430
4607
  setConfig(option);
4431
4608
  app.component(Editor.name, Editor);
4432
- app.component("m-fields-ui-select", _sfc_main$l);
4609
+ app.component("m-fields-ui-select", _sfc_main$m);
4433
4610
  app.component(CodeLink.name, CodeLink);
4434
4611
  app.component(Code.name, Code);
4435
4612
  app.component(CodeEditor.name, CodeEditor);
@@ -4437,18 +4614,20 @@
4437
4614
  };
4438
4615
 
4439
4616
  exports.COPY_STORAGE_KEY = COPY_STORAGE_KEY;
4617
+ exports.ColumnLayout = ColumnLayout;
4440
4618
  exports.ComponentListPanel = ComponentListPanel;
4441
- exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
4619
+ exports.ContentMenu = _sfc_main$c;
4442
4620
  exports.Fixed2Other = Fixed2Other;
4443
4621
  exports.H_GUIDE_LINE_STORAGE_KEY = H_GUIDE_LINE_STORAGE_KEY;
4622
+ exports.Icon = _sfc_main$h;
4444
4623
  exports.Keys = Keys;
4445
4624
  exports.LayerOffset = LayerOffset;
4446
4625
  exports.LayerPanel = LayerPanel;
4447
4626
  exports.Layout = Layout;
4448
- exports.PropsPanel = PropsPanel;
4627
+ exports.PropsPanel = _sfc_main$e;
4449
4628
  exports.TMagicCodeEditor = CodeEditor;
4450
4629
  exports.TMagicEditor = Editor;
4451
- exports.ToolButton = _sfc_main$f;
4630
+ exports.ToolButton = _sfc_main$g;
4452
4631
  exports.V_GUIDE_LINE_STORAGE_KEY = V_GUIDE_LINE_STORAGE_KEY;
4453
4632
  exports.change2Fixed = change2Fixed;
4454
4633
  exports.debug = debug;
@@ -4477,6 +4656,7 @@
4477
4656
  exports.setLayout = setLayout;
4478
4657
  exports.storageService = storageService;
4479
4658
  exports.uiService = uiService;
4659
+ exports.useStage = useStage;
4480
4660
  exports.warn = warn;
4481
4661
 
4482
4662
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });