@tmagic/editor 1.8.0-beta.13 → 1.8.0-beta.15

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 (127) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +15 -3
  2. package/dist/es/components/ContentMenu.vue_vue_type_script_setup_true_lang.js +31 -8
  3. package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +7 -2
  4. package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +15 -4
  5. package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +4 -1
  6. package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +80 -55
  7. package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +5 -1
  8. package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +4 -1
  9. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +10 -7
  10. package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +4 -1
  11. package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +4 -1
  12. package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +4 -1
  13. package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +4 -1
  14. package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +4 -1
  15. package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +4 -1
  16. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +8 -2
  17. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +99 -64
  18. package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +4 -1
  19. package/dist/es/fields/PageFragmentSelect.vue_vue_type_script_setup_true_lang.js +4 -1
  20. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +5 -4
  21. package/dist/es/fields/StyleSetter/components/BackgroundPosition.vue_vue_type_script_setup_true_lang.js +4 -1
  22. package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +1 -1
  23. package/dist/es/fields/StyleSetter/icons/align-items/Center.js +31 -0
  24. package/dist/es/fields/StyleSetter/icons/align-items/FlexEnd.js +31 -0
  25. package/dist/es/fields/StyleSetter/icons/align-items/FlexStart.js +31 -0
  26. package/dist/es/fields/StyleSetter/icons/align-items/SpaceAround.js +50 -0
  27. package/dist/es/fields/StyleSetter/icons/align-items/SpaceBetween.js +50 -0
  28. package/dist/es/fields/StyleSetter/icons/background-repeat/NoRepeat.js +6 -6
  29. package/dist/es/fields/StyleSetter/icons/background-repeat/Repeat.js +5 -2
  30. package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatX.js +28 -5
  31. package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatY.js +31 -5
  32. package/dist/es/fields/StyleSetter/icons/flex-direction/Column.js +10 -2
  33. package/dist/es/fields/StyleSetter/icons/flex-direction/ColumnReverse.js +10 -2
  34. package/dist/es/fields/StyleSetter/icons/flex-direction/Row.js +10 -2
  35. package/dist/es/fields/StyleSetter/icons/flex-direction/RowReverse.js +10 -2
  36. package/dist/es/fields/StyleSetter/icons/justify-content/Center.js +16 -2
  37. package/dist/es/fields/StyleSetter/icons/justify-content/FlexEnd.js +18 -2
  38. package/dist/es/fields/StyleSetter/icons/justify-content/FlexStart.js +18 -2
  39. package/dist/es/fields/StyleSetter/icons/justify-content/SpaceAround.js +36 -2
  40. package/dist/es/fields/StyleSetter/icons/justify-content/SpaceBetween.js +32 -2
  41. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +7 -6
  42. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +6 -3
  43. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +47 -25
  44. package/dist/es/fields/UISelect.vue_vue_type_script_setup_true_lang.js +4 -1
  45. package/dist/es/icons/DatasourceIcon.js +17 -0
  46. package/dist/es/index.js +2 -2
  47. package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +14 -10
  48. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +13 -4
  49. package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +3 -3
  50. package/dist/es/plugin.js +2 -1
  51. package/dist/es/services/editor.js +86 -24
  52. package/dist/es/services/history.js +16 -0
  53. package/dist/es/services/ui.js +5 -3
  54. package/dist/es/style.css +307 -40
  55. package/dist/es/utils/config.js +4 -1
  56. package/dist/es/utils/const.js +2 -2
  57. package/dist/es/utils/data-source/index.js +4 -2
  58. package/dist/es/utils/props.js +43 -29
  59. package/dist/es/utils/type-match-rules.js +12 -5
  60. package/dist/style.css +307 -40
  61. package/dist/themes/magic-admin.css +3004 -0
  62. package/dist/tmagic-editor.umd.cjs +1161 -476
  63. package/package.json +7 -7
  64. package/src/Editor.vue +22 -1
  65. package/src/components/ContentMenu.vue +44 -8
  66. package/src/components/FloatingBox.vue +8 -2
  67. package/src/editorProps.ts +4 -0
  68. package/src/fields/Code.vue +10 -2
  69. package/src/fields/CodeSelect.vue +54 -43
  70. package/src/fields/CodeSelectCol.vue +1 -0
  71. package/src/fields/DataSourceFieldSelect/Index.vue +14 -5
  72. package/src/fields/DisplayConds.vue +4 -1
  73. package/src/fields/EventSelect.vue +56 -32
  74. package/src/fields/StyleSetter/Index.vue +1 -4
  75. package/src/fields/StyleSetter/components/Border.vue +1 -1
  76. package/src/fields/StyleSetter/icons/align-items/Center.vue +19 -0
  77. package/src/fields/StyleSetter/icons/align-items/FlexEnd.vue +19 -0
  78. package/src/fields/StyleSetter/icons/align-items/FlexStart.vue +19 -0
  79. package/src/fields/StyleSetter/icons/align-items/SpaceAround.vue +34 -0
  80. package/src/fields/StyleSetter/icons/align-items/SpaceBetween.vue +34 -0
  81. package/src/fields/StyleSetter/icons/align-items/index.ts +5 -0
  82. package/src/fields/StyleSetter/icons/background-repeat/NoRepeat.vue +20 -4
  83. package/src/fields/StyleSetter/icons/background-repeat/Repeat.vue +10 -28
  84. package/src/fields/StyleSetter/icons/background-repeat/RepeatX.vue +4 -5
  85. package/src/fields/StyleSetter/icons/background-repeat/RepeatY.vue +4 -5
  86. package/src/fields/StyleSetter/icons/flex-direction/Column.vue +4 -3
  87. package/src/fields/StyleSetter/icons/flex-direction/ColumnReverse.vue +4 -3
  88. package/src/fields/StyleSetter/icons/flex-direction/Row.vue +4 -3
  89. package/src/fields/StyleSetter/icons/flex-direction/RowReverse.vue +4 -3
  90. package/src/fields/StyleSetter/icons/justify-content/Center.vue +5 -2
  91. package/src/fields/StyleSetter/icons/justify-content/FlexEnd.vue +15 -2
  92. package/src/fields/StyleSetter/icons/justify-content/FlexStart.vue +15 -2
  93. package/src/fields/StyleSetter/icons/justify-content/SpaceAround.vue +28 -3
  94. package/src/fields/StyleSetter/icons/justify-content/SpaceBetween.vue +28 -2
  95. package/src/fields/StyleSetter/pro/Background.vue +7 -2
  96. package/src/fields/StyleSetter/pro/Font.vue +3 -3
  97. package/src/fields/StyleSetter/pro/Layout.vue +98 -28
  98. package/src/icons/DatasourceIcon.vue +7 -0
  99. package/src/index.ts +3 -0
  100. package/src/layouts/Framework.vue +7 -1
  101. package/src/layouts/props-panel/PropsPanel.vue +38 -12
  102. package/src/layouts/sidebar/Sidebar.vue +3 -3
  103. package/src/plugin.ts +3 -2
  104. package/src/services/editor.ts +76 -11
  105. package/src/services/history.ts +22 -1
  106. package/src/services/ui.ts +20 -5
  107. package/src/theme/code-block.scss +37 -0
  108. package/src/theme/common/var.scss +1 -1
  109. package/src/theme/component-list-panel.scss +2 -2
  110. package/src/theme/data-source-field.scss +4 -0
  111. package/src/theme/display-conds.scss +11 -0
  112. package/src/theme/event.scss +58 -4
  113. package/src/theme/framework.scss +4 -1
  114. package/src/theme/history-list-panel.scss +9 -9
  115. package/src/theme/nav-menu.scss +5 -1
  116. package/src/theme/props-panel.scss +2 -1
  117. package/src/theme/style-setter/border.scss +14 -5
  118. package/src/theme/theme.scss +1 -0
  119. package/src/theme/themes/magic-admin/index.scss +214 -0
  120. package/src/theme/ui-select.scss +1 -1
  121. package/src/type.ts +33 -6
  122. package/src/utils/config.ts +9 -1
  123. package/src/utils/const.ts +3 -2
  124. package/src/utils/data-source/index.ts +3 -3
  125. package/src/utils/props.ts +22 -9
  126. package/src/utils/type-match-rules.ts +11 -5
  127. package/types/index.d.ts +114 -35
@@ -6,13 +6,8 @@ import SplitView_default from "../components/SplitView.js";
6
6
  import PageBar_default from "./page-bar/PageBar.js";
7
7
  import AddPageBox_default from "./AddPageBox.js";
8
8
  import CodeEditor_default from "./CodeEditor.js";
9
- import { computed, createCommentVNode, createElementBlock, createSlots, createVNode, defineComponent, inject, onBeforeUnmount, onMounted, openBlock, renderSlot, unref, useTemplateRef, vShow, watch, withCtx, withDirectives } from "vue";
9
+ import { computed, createCommentVNode, createElementBlock, createSlots, createVNode, defineComponent, inject, normalizeClass, onBeforeUnmount, onMounted, openBlock, renderSlot, unref, useTemplateRef, vShow, watch, withCtx, withDirectives } from "vue";
10
10
  //#region packages/editor/src/layouts/Framework.vue?vue&type=script&setup=true&lang.ts
11
- var _hoisted_1 = {
12
- class: "m-editor",
13
- ref: "content",
14
- style: { "min-width": "900px" }
15
- };
16
11
  var Framework_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
17
12
  name: "MEditorFramework",
18
13
  __name: "Framework",
@@ -20,7 +15,8 @@ var Framework_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
20
15
  disabledPageFragment: { type: Boolean },
21
16
  pageBarSortOptions: {},
22
17
  pageFilterFunction: { type: Function },
23
- hideSidebar: { type: Boolean }
18
+ hideSidebar: { type: Boolean },
19
+ theme: {}
24
20
  },
25
21
  setup(__props) {
26
22
  const props = __props;
@@ -42,7 +38,7 @@ var Framework_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
42
38
  watch(() => uiService.get("hideSlideBar"), (hideSlideBar) => {
43
39
  uiService.set("columnWidth", {
44
40
  ...columnWidth.value,
45
- left: hideSlideBar ? 0 : storageService.getItem("$MagicEditorLeftColumnWidthData", { protocol: Protocol.NUMBER }) || 310
41
+ left: hideSlideBar ? 0 : storageService.getItem("$MagicEditorLeftColumnWidthData", { protocol: Protocol.NUMBER }) || 345
46
42
  });
47
43
  });
48
44
  const columnWidthChange = (columnW) => {
@@ -75,7 +71,15 @@ var Framework_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
75
71
  }
76
72
  };
77
73
  return (_ctx, _cache) => {
78
- return openBlock(), createElementBlock("div", _hoisted_1, [
74
+ return openBlock(), createElementBlock("div", {
75
+ ref: "content",
76
+ class: normalizeClass([
77
+ "m-editor",
78
+ __props.theme ? `m-editor--${__props.theme}` : "",
79
+ __props.theme ? `m-theme--${__props.theme}` : ""
80
+ ]),
81
+ style: { "min-width": "900px" }
82
+ }, [
79
83
  renderSlot(_ctx.$slots, "header"),
80
84
  renderSlot(_ctx.$slots, "nav"),
81
85
  renderSlot(_ctx.$slots, "content-before"),
@@ -134,7 +138,7 @@ var Framework_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
134
138
  ]), [[vShow, !showSrc.value]]),
135
139
  renderSlot(_ctx.$slots, "content-after"),
136
140
  renderSlot(_ctx.$slots, "footer")
137
- ], 512);
141
+ ], 2);
138
142
  };
139
143
  }
140
144
  });
@@ -42,18 +42,27 @@ var PropsPanel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
42
42
  tabPosition: "right",
43
43
  items: styleTabConfig.items
44
44
  }];
45
+ let initSeq = 0;
46
+ let mounted = true;
45
47
  const init = async () => {
48
+ initSeq += 1;
49
+ const seq = initSeq;
46
50
  if (!node.value) {
51
+ if (seq !== initSeq || !mounted) return;
47
52
  curFormConfig.value = [];
48
53
  return;
49
54
  }
50
55
  const type = node.value.type || (node.value.items ? "container" : "text");
51
- curFormConfig.value = await propsService.getPropsConfig(type, { node: node.value });
56
+ const config = await propsService.getPropsConfig(type, { node: node.value });
57
+ if (seq !== initSeq || !mounted) return;
58
+ if (!node.value) return;
59
+ curFormConfig.value = config;
52
60
  values.value = node.value;
53
61
  };
54
62
  watchEffect(init);
55
63
  propsService.on("props-configs-change", init);
56
64
  onBeforeUnmount(() => {
65
+ mounted = false;
57
66
  propsService.off("props-configs-change", init);
58
67
  });
59
68
  const submit = async (v, eventData, error, source = "props") => {
@@ -63,14 +72,14 @@ var PropsPanel_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
63
72
  ...v,
64
73
  style: {}
65
74
  };
66
- if (v.style) {
75
+ if (v.style) if (eventData) {
67
76
  Object.entries(v.style).forEach(([key, value]) => {
68
77
  if (value !== "" && newValue.style) newValue.style[key] = value;
69
78
  });
70
- eventData?.changeRecords?.forEach((record) => {
79
+ eventData.changeRecords?.forEach((record) => {
71
80
  if (record.propPath?.startsWith("style") && record.value === "") setValueByKeyPath(record.propPath, record.value, newValue);
72
81
  });
73
- }
82
+ } else newValue.style = { ...v.style };
74
83
  const historySource = eventData ? "props" : "code";
75
84
  editorService.update(newValue, {
76
85
  changeRecords: eventData?.changeRecords,
@@ -9,7 +9,7 @@ import DataSourceListPanel_default from "./data-source/DataSourceListPanel.js";
9
9
  import LayerPanel_default from "./layer/LayerPanel.js";
10
10
  import ComponentListPanel_default from "./ComponentListPanel.js";
11
11
  import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, toHandlers, unref, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
12
- import { Close, Coin, EditPen, Goods, List } from "@element-plus/icons-vue";
12
+ import { Box, Close, Coin, EditPen, Finished } from "@element-plus/icons-vue";
13
13
  //#region packages/editor/src/layouts/sidebar/Sidebar.vue?vue&type=script&setup=true&lang.ts
14
14
  var _hoisted_1 = {
15
15
  key: 0,
@@ -82,7 +82,7 @@ var Sidebar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
82
82
  [SideItemKey.COMPONENT_LIST]: {
83
83
  $key: SideItemKey.COMPONENT_LIST,
84
84
  type: "component",
85
- icon: Goods,
85
+ icon: Box,
86
86
  text: "组件",
87
87
  component: ComponentListPanel_default,
88
88
  slots: {}
@@ -90,7 +90,7 @@ var Sidebar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
90
90
  layer: {
91
91
  $key: SideItemKey.LAYER,
92
92
  type: "component",
93
- icon: List,
93
+ icon: Finished,
94
94
  text: "已选组件",
95
95
  props: {
96
96
  layerContentMenu: props.layerContentMenu,
package/dist/es/plugin.js CHANGED
@@ -28,7 +28,8 @@ import designPlugin from "@tmagic/design";
28
28
  var defaultInstallOpt = {
29
29
  parseDSL: (dsl) => eval(dsl),
30
30
  customCreateMonacoEditor: (monaco, codeEditorEl, options) => monaco.editor.create(codeEditorEl, options),
31
- customCreateMonacoDiffEditor: (monaco, codeEditorEl, options) => monaco.editor.createDiffEditor(codeEditorEl, options)
31
+ customCreateMonacoDiffEditor: (monaco, codeEditorEl, options) => monaco.editor.createDiffEditor(codeEditorEl, options),
32
+ flat: false
32
33
  };
33
34
  var plugin_default = { install: (app, opt) => {
34
35
  const option = Object.assign(defaultInstallOpt, opt || {});
@@ -347,7 +347,14 @@ var Editor = class extends BaseService {
347
347
  data: newNodes.map((node) => ({
348
348
  node,
349
349
  page: this.getPageOfNode(node.id)
350
- }))
350
+ })),
351
+ historySource,
352
+ doNotPushHistory
353
+ });
354
+ const addedPages = newNodes.filter((node) => isPage(node) || isPageFragment(node));
355
+ if (addedPages.length) history_default.notifyPageStructureChange({
356
+ add: addedPages,
357
+ remove: []
351
358
  });
352
359
  return Array.isArray(addNode) ? newNodes : newNodes[0];
353
360
  }
@@ -448,7 +455,14 @@ var Editor = class extends BaseService {
448
455
  this.emit("remove", nodes);
449
456
  this.emit("change", {
450
457
  type: "remove",
451
- data: changeItems
458
+ data: changeItems,
459
+ historySource,
460
+ doNotPushHistory
461
+ });
462
+ const removedPages = nodes.filter((node) => isPage(node) || isPageFragment(node));
463
+ if (removedPages.length) history_default.notifyPageStructureChange({
464
+ add: [],
465
+ remove: removedPages
452
466
  });
453
467
  }
454
468
  async doUpdate(config, { changeRecords = [], historySource } = {}) {
@@ -541,7 +555,9 @@ var Editor = class extends BaseService {
541
555
  data: updateData.map((node) => ({
542
556
  node,
543
557
  page: this.getPageOfNode(node.newNode.id)
544
- }))
558
+ })),
559
+ historySource,
560
+ doNotPushHistory
545
561
  });
546
562
  return Array.isArray(config) ? updateData.map((item) => item.newNode) : updateData[0].newNode;
547
563
  }
@@ -714,7 +730,9 @@ var Editor = class extends BaseService {
714
730
  node,
715
731
  page: this.getPageOfNode(node.id)
716
732
  }],
717
- offset
733
+ offset,
734
+ historySource,
735
+ doNotPushHistory
718
736
  });
719
737
  }
720
738
  /**
@@ -852,7 +870,9 @@ var Editor = class extends BaseService {
852
870
  page: this.getPageOfNode(node.id)
853
871
  })),
854
872
  targetIndex,
855
- targetParent
873
+ targetParent,
874
+ historySource,
875
+ doNotPushHistory
856
876
  });
857
877
  }
858
878
  /**
@@ -1228,24 +1248,35 @@ var Editor = class extends BaseService {
1228
1248
  const prevMap = new Map(prevPages.map((p) => [`${p.id}`, p]));
1229
1249
  const nextMap = new Map(nextPages.map((p) => [`${p.id}`, p]));
1230
1250
  const indexInItems = (root, id) => (root.items ?? []).findIndex((item) => `${item.id}` === `${id}`);
1251
+ const addedPages = [];
1252
+ const removedPages = [];
1231
1253
  nextPages.forEach((nextPage) => {
1232
1254
  const prevPage = prevMap.get(`${nextPage.id}`);
1233
- if (!prevPage) this.pushPageDiffStep("add", nextPage, {
1234
- newSchema: cloneDeep$1(toRaw(nextPage)),
1235
- parentId: nextRoot.id,
1236
- index: indexInItems(nextRoot, nextPage.id)
1237
- }, source);
1238
- else if (!isEqual(toRaw(prevPage), toRaw(nextPage))) this.pushPageDiffStep("update", nextPage, {
1255
+ if (!prevPage) {
1256
+ this.pushPageDiffStep("add", nextPage, {
1257
+ newSchema: cloneDeep$1(toRaw(nextPage)),
1258
+ parentId: nextRoot.id,
1259
+ index: indexInItems(nextRoot, nextPage.id)
1260
+ }, source);
1261
+ addedPages.push(nextPage);
1262
+ } else if (!isEqual(toRaw(prevPage), toRaw(nextPage))) this.pushPageDiffStep("update", nextPage, {
1239
1263
  oldSchema: cloneDeep$1(toRaw(prevPage)),
1240
1264
  newSchema: cloneDeep$1(toRaw(nextPage))
1241
1265
  }, source);
1242
1266
  });
1243
1267
  prevPages.forEach((prevPage) => {
1244
- if (!nextMap.has(`${prevPage.id}`)) this.pushPageDiffStep("remove", prevPage, {
1245
- oldSchema: cloneDeep$1(toRaw(prevPage)),
1246
- parentId: preRoot.id,
1247
- index: indexInItems(preRoot, prevPage.id)
1248
- }, source);
1268
+ if (!nextMap.has(`${prevPage.id}`)) {
1269
+ this.pushPageDiffStep("remove", prevPage, {
1270
+ oldSchema: cloneDeep$1(toRaw(prevPage)),
1271
+ parentId: preRoot.id,
1272
+ index: indexInItems(preRoot, prevPage.id)
1273
+ }, source);
1274
+ removedPages.push(prevPage);
1275
+ }
1276
+ });
1277
+ if (addedPages.length || removedPages.length) history_default.notifyPageStructureChange({
1278
+ add: addedPages,
1279
+ remove: removedPages
1249
1280
  });
1250
1281
  }
1251
1282
  /**
@@ -1301,10 +1332,12 @@ var Editor = class extends BaseService {
1301
1332
  /**
1302
1333
  * 应用历史操作(撤销 / 重做)
1303
1334
  *
1304
- * 所有 DSL 修改都走 `editor.add / remove / update`,并通过 `doNotPushHistory` 阻止再次入栈、
1305
- * `doNotSelect / doNotSwitchPage` 让选区由方法末尾的统一逻辑兜底。
1335
+ * 删除 / 更新类修改走 `editor.remove / update`,并通过 `doNotPushHistory` 阻止再次入栈、
1336
+ * `doNotSelect / doNotSwitchPage` 让选区由方法末尾的统一逻辑兜底;
1337
+ * 「重新插回节点」(撤销 remove / 重做 add)需按 step 记录的 parentId / index 精确还原,
1338
+ * 不走 this.add,由手工 splice + stage.add 完成后补发等价的 add / change 事件(见 emitHistoryInsertEvents)。
1306
1339
  *
1307
- * 注意:这些公开方法会发出 add / remove / update 事件,业务侧若需要区分"用户操作"与"撤销重做触发",
1340
+ * 注意:这些路径都会发出 add / remove / update / change 事件,业务侧若需要区分"用户操作"与"撤销重做触发",
1308
1341
  * 请监听 `history-change` 事件配合判断。
1309
1342
  *
1310
1343
  * @param step 操作记录
@@ -1318,7 +1351,8 @@ var Editor = class extends BaseService {
1318
1351
  const commonOpts = {
1319
1352
  doNotSelect: true,
1320
1353
  doNotSwitchPage: true,
1321
- doNotPushHistory: true
1354
+ doNotPushHistory: true,
1355
+ historySource: step.source
1322
1356
  };
1323
1357
  switch (step.opType) {
1324
1358
  case "add": {
@@ -1330,12 +1364,15 @@ var Editor = class extends BaseService {
1330
1364
  }
1331
1365
  else {
1332
1366
  const sorted = [...items].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
1367
+ const addedNodes = [];
1333
1368
  for (const { newSchema, parentId, index } of sorted) {
1334
1369
  if (!newSchema || parentId === void 0) continue;
1335
1370
  const parent = this.getNodeById(parentId, false);
1336
1371
  if (parent?.items) {
1337
- if (typeof index === "number" && index >= 0 && index < parent.items.length) parent.items.splice(index, 0, cloneDeep$1(newSchema));
1338
- else parent.items.push(cloneDeep$1(newSchema));
1372
+ const addedNode = cloneDeep$1(newSchema);
1373
+ if (typeof index === "number" && index >= 0 && index < parent.items.length) parent.items.splice(index, 0, addedNode);
1374
+ else parent.items.push(addedNode);
1375
+ addedNodes.push(addedNode);
1339
1376
  await stage?.add({
1340
1377
  config: cloneDeep$1(newSchema),
1341
1378
  parent: cloneDeep$1(parent),
@@ -1344,6 +1381,7 @@ var Editor = class extends BaseService {
1344
1381
  });
1345
1382
  }
1346
1383
  }
1384
+ this.emitHistoryInsertEvents(addedNodes, step.source);
1347
1385
  }
1348
1386
  break;
1349
1387
  }
@@ -1351,11 +1389,14 @@ var Editor = class extends BaseService {
1351
1389
  const items = step.diff ?? [];
1352
1390
  if (reverse) {
1353
1391
  const sorted = [...items].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
1392
+ const addedNodes = [];
1354
1393
  for (const { oldSchema, parentId, index } of sorted) {
1355
1394
  if (!oldSchema || parentId === void 0) continue;
1356
1395
  const parent = this.getNodeById(parentId, false);
1357
1396
  if (parent?.items) {
1358
- parent.items.splice(index ?? parent.items.length, 0, cloneDeep$1(oldSchema));
1397
+ const addedNode = cloneDeep$1(oldSchema);
1398
+ parent.items.splice(index ?? parent.items.length, 0, addedNode);
1399
+ addedNodes.push(addedNode);
1359
1400
  await stage?.add({
1360
1401
  config: cloneDeep$1(oldSchema),
1361
1402
  parent: cloneDeep$1(parent),
@@ -1364,6 +1405,7 @@ var Editor = class extends BaseService {
1364
1405
  });
1365
1406
  }
1366
1407
  }
1408
+ this.emitHistoryInsertEvents(addedNodes, step.source);
1367
1409
  } else for (const { oldSchema } of items) {
1368
1410
  if (!oldSchema) continue;
1369
1411
  const existing = this.getNodeById(oldSchema.id, false);
@@ -1390,7 +1432,10 @@ var Editor = class extends BaseService {
1390
1432
  }
1391
1433
  return cloneDeep$1(reverse ? oldNode : newNode);
1392
1434
  });
1393
- if (configs.length) await this.update(configs, { doNotPushHistory: true });
1435
+ if (configs.length) await this.update(configs, {
1436
+ doNotPushHistory: true,
1437
+ historySource: step.source
1438
+ });
1394
1439
  break;
1395
1440
  }
1396
1441
  }
@@ -1414,6 +1459,23 @@ var Editor = class extends BaseService {
1414
1459
  selectedConfigExceptionHandler(config) {
1415
1460
  return resolveSelectedNode(config, (id) => this.getNodeInfo(id), this.state.root?.id);
1416
1461
  }
1462
+ /**
1463
+ * 撤销 remove / 重做 add 通过手工 splice 按 step 记录的 parentId / index 精确还原节点(不走 this.add,原因见调用处注释),
1464
+ * 这里补齐与 this.add 等价的 add / change 事件,保证撤销/重做路径的事件行为与正向操作一致。
1465
+ */
1466
+ emitHistoryInsertEvents(nodes, source) {
1467
+ if (!nodes.length) return;
1468
+ this.emit("add", nodes);
1469
+ this.emit("change", {
1470
+ type: "add",
1471
+ data: nodes.map((node) => ({
1472
+ node,
1473
+ page: this.getPageOfNode(node.id)
1474
+ })),
1475
+ historySource: source,
1476
+ doNotPushHistory: true
1477
+ });
1478
+ }
1417
1479
  };
1418
1480
  var editor_default = new Editor();
1419
1481
  //#endregion
@@ -244,6 +244,22 @@ var History = class extends BaseService {
244
244
  });
245
245
  }
246
246
  /**
247
+ * 派发「页面 / 页面片结构变更」事件(`page-structure-change`)。
248
+ *
249
+ * 常规 `editorService.add` / `remove` 页面节点不会写入 `page` 历史栈(见 editor.add / remove 中
250
+ * 对 isPage / isPageFragment 的分支),因此不会产生任何 historyService 事件。该方法用于在这些
251
+ * 场景(以及 setRoot 整体替换 DSL 增删页面)下,向外统一通知页面结构的增删变化,供业务方感知。
252
+ *
253
+ * 一次操作涉及多个页面时,调用方应把本次增删的页面**合并为一个 change 一次性传入**,
254
+ * 使一次操作只派发一个事件;`add` / `remove` 分别为本次新增与删除的页面列表(其一可为空数组)。
255
+ *
256
+ * @param change 本次结构变更:{ add: 新增的页面列表, remove: 删除的页面列表 }
257
+ */
258
+ notifyPageStructureChange(change) {
259
+ if (!change.add.length && !change.remove.length) return;
260
+ this.emit("page-structure-change", change);
261
+ }
262
+ /**
247
263
  * 把当前内存中的全部历史栈(页面 / 代码块 / 数据源 / 扩展类型)序列化后写入本地 IndexedDB。
248
264
  *
249
265
  * - 每个 UndoRedo 栈连同其游标、容量一并保存,恢复后可继续 undo/redo;
@@ -19,11 +19,11 @@ var state = shallowReactive({
19
19
  height: 817
20
20
  },
21
21
  columnWidth: {
22
- left: storage_default.getItem("$MagicEditorLeftColumnWidthData", { protocol: Protocol.NUMBER }) || 310,
22
+ left: 0,
23
23
  center: 0,
24
- right: storage_default.getItem("$MagicEditorRightColumnWidthData", { protocol: Protocol.NUMBER }) || 480
24
+ right: 0
25
25
  },
26
- minLeftColumnWidth: 200,
26
+ minLeftColumnWidth: 345,
27
27
  minCenterColumnWidth: 400,
28
28
  minRightColumnWidth: 300,
29
29
  showGuides: true,
@@ -48,6 +48,8 @@ var state = shallowReactive({
48
48
  top: 0
49
49
  }
50
50
  });
51
+ state.columnWidth.left = Math.max(storage_default.getItem("$MagicEditorLeftColumnWidthData", { protocol: Protocol.NUMBER }) || 345, state.minLeftColumnWidth);
52
+ state.columnWidth.right = Math.max(storage_default.getItem("$MagicEditorRightColumnWidthData", { protocol: Protocol.NUMBER }) || 480, state.minRightColumnWidth);
51
53
  var canUsePluginMethods = {
52
54
  async: ["zoom", "calcZoom"],
53
55
  sync: []