@tmagic/editor 1.7.14-beta.3 → 1.8.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +11 -2
  2. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +8 -2
  3. package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +10 -2
  4. package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +3 -1
  5. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +10 -2
  6. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +16 -3
  7. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +10 -2
  8. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +14 -2
  9. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +10 -2
  10. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +10 -2
  11. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/es/layouts/sidebar/layer/use-node-status.js +37 -3
  13. package/dist/es/services/editor.js +58 -27
  14. package/dist/es/style.css +15 -14
  15. package/dist/es/utils/editor.js +1 -1
  16. package/dist/style.css +15 -14
  17. package/dist/tmagic-editor.umd.cjs +199 -52
  18. package/package.json +7 -7
  19. package/src/fields/DataSourceFieldSelect/Index.vue +8 -1
  20. package/src/fields/StyleSetter/Index.vue +6 -0
  21. package/src/fields/StyleSetter/components/Border.vue +15 -1
  22. package/src/fields/StyleSetter/components/Box.vue +2 -0
  23. package/src/fields/StyleSetter/pro/Background.vue +15 -1
  24. package/src/fields/StyleSetter/pro/Border.vue +24 -2
  25. package/src/fields/StyleSetter/pro/Font.vue +15 -1
  26. package/src/fields/StyleSetter/pro/Layout.vue +17 -1
  27. package/src/fields/StyleSetter/pro/Position.vue +15 -1
  28. package/src/fields/StyleSetter/pro/Transform.vue +15 -1
  29. package/src/layouts/props-panel/FormPanel.vue +1 -1
  30. package/src/layouts/sidebar/layer/use-node-status.ts +55 -6
  31. package/src/services/editor.ts +74 -43
  32. package/src/theme/props-panel.scss +20 -20
  33. package/src/type.ts +10 -0
  34. package/src/utils/editor.ts +4 -1
  35. package/types/index.d.ts +31 -22
@@ -35,7 +35,8 @@
35
35
  <TMagicButton
36
36
  :type="showDataSourceFieldSelect ? 'primary' : 'default'"
37
37
  :size="size"
38
- @click="showDataSourceFieldSelect = !showDataSourceFieldSelect"
38
+ :disabled="disabled || mForm?.isCompare"
39
+ @click="onToggleDataSourceFieldSelectHandler"
39
40
  ><MIcon :icon="Coin"></MIcon
40
41
  ></TMagicButton>
41
42
  </TMagicTooltip>
@@ -185,4 +186,10 @@ const onChangeHandler = (value: string[], eventData?: ContainerChangeEventData)
185
186
  emit('change', [dsId], eventData);
186
187
  }
187
188
  };
189
+
190
+ const onToggleDataSourceFieldSelectHandler = () => {
191
+ // 禁用或对比模式下禁止切换
192
+ if (props.disabled || mForm?.isCompare) return;
193
+ showDataSourceFieldSelect.value = !showDataSourceFieldSelect.value;
194
+ };
188
195
  </script>
@@ -7,9 +7,12 @@
7
7
  v-if="item.component"
8
8
  :is="item.component"
9
9
  :values="model[name]"
10
+ :last-values="lastValues?.[name]"
11
+ :is-compare="isCompare"
10
12
  :size="size"
11
13
  :disabled="disabled"
12
14
  @change="change"
15
+ @add-diff-count="onAddDiffCount"
13
16
  ></component>
14
17
  </TMagicCollapseItem>
15
18
  </template>
@@ -36,6 +39,7 @@ const props = defineProps<FieldProps<StyleSchema>>();
36
39
 
37
40
  const emit = defineEmits<{
38
41
  change: [v: any, eventData: ContainerChangeEventData];
42
+ addDiffCount: [];
39
43
  }>();
40
44
 
41
45
  const list = [
@@ -82,4 +86,6 @@ const change = (v: any, eventData: ContainerChangeEventData) => {
82
86
  });
83
87
  emit('change', v, eventData);
84
88
  };
89
+
90
+ const onAddDiffCount = () => emit('addDiffCount');
85
91
  </script>
@@ -30,7 +30,16 @@
30
30
  </div>
31
31
  </div>
32
32
  <div class="border-value-container">
33
- <MContainer :config="config" :model="model" :size="size" :disabled="disabled" @change="change"></MContainer>
33
+ <MContainer
34
+ :config="config"
35
+ :model="model"
36
+ :last-values="lastValues"
37
+ :is-compare="isCompare"
38
+ :size="size"
39
+ :disabled="disabled"
40
+ @change="change"
41
+ @add-diff-count="onAddDiffCount"
42
+ ></MContainer>
34
43
  </div>
35
44
  </div>
36
45
  </template>
@@ -86,11 +95,14 @@ const selectDirection = (d?: string) => (direction.value = d || '');
86
95
 
87
96
  const emit = defineEmits<{
88
97
  change: [v: StyleSchema, eventData: ContainerChangeEventData];
98
+ addDiffCount: [];
89
99
  }>();
90
100
 
91
101
  withDefaults(
92
102
  defineProps<{
93
103
  model: FormValue;
104
+ lastValues?: FormValue;
105
+ isCompare?: boolean;
94
106
  disabled?: boolean;
95
107
  size?: 'large' | 'default' | 'small';
96
108
  }>(),
@@ -104,4 +116,6 @@ const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
104
116
  });
105
117
  });
106
118
  };
119
+
120
+ const onAddDiffCount = () => emit('addDiffCount');
107
121
  </script>
@@ -64,6 +64,8 @@ withDefaults(
64
64
  disabled?: boolean;
65
65
  size?: 'large' | 'default' | 'small';
66
66
  model: FormValue;
67
+ lastValues?: FormValue;
68
+ isCompare?: boolean;
67
69
  }>(),
68
70
  {},
69
71
  );
@@ -1,5 +1,14 @@
1
1
  <template>
2
- <MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
2
+ <MContainer
3
+ :config="config"
4
+ :model="values"
5
+ :last-values="lastValues"
6
+ :is-compare="isCompare"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ @change="change"
10
+ @add-diff-count="onAddDiffCount"
11
+ ></MContainer>
3
12
  </template>
4
13
 
5
14
  <script lang="ts" setup>
@@ -13,12 +22,15 @@ import { BackgroundNoRepeat, BackgroundRepeat, BackgroundRepeatX, BackgroundRepe
13
22
 
14
23
  defineProps<{
15
24
  values: Partial<StyleSchema>;
25
+ lastValues?: Partial<StyleSchema>;
26
+ isCompare?: boolean;
16
27
  disabled?: boolean;
17
28
  size?: 'large' | 'default' | 'small';
18
29
  }>();
19
30
 
20
31
  const emit = defineEmits<{
21
32
  change: [v: StyleSchema, eventData: ContainerChangeEventData];
33
+ addDiffCount: [];
22
34
  }>();
23
35
 
24
36
  const config = defineFormItem({
@@ -79,4 +91,6 @@ const config = defineFormItem({
79
91
  const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
80
92
  emit('change', value, eventData);
81
93
  };
94
+
95
+ const onAddDiffCount = () => emit('addDiffCount');
82
96
  </script>
@@ -1,6 +1,23 @@
1
1
  <template>
2
- <MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
3
- <Border :model="values" :size="size" :disabled="disabled" @change="change"></Border>
2
+ <MContainer
3
+ :config="config"
4
+ :model="values"
5
+ :last-values="lastValues"
6
+ :is-compare="isCompare"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ @change="change"
10
+ @add-diff-count="onAddDiffCount"
11
+ ></MContainer>
12
+ <Border
13
+ :model="values"
14
+ :last-values="lastValues"
15
+ :is-compare="isCompare"
16
+ :size="size"
17
+ :disabled="disabled"
18
+ @change="change"
19
+ @add-diff-count="onAddDiffCount"
20
+ ></Border>
4
21
  </template>
5
22
 
6
23
  <script lang="ts" setup>
@@ -11,12 +28,15 @@ import Border from '../components/Border.vue';
11
28
 
12
29
  defineProps<{
13
30
  values: Partial<StyleSchema>;
31
+ lastValues?: Partial<StyleSchema>;
32
+ isCompare?: boolean;
14
33
  disabled?: boolean;
15
34
  size?: 'large' | 'default' | 'small';
16
35
  }>();
17
36
 
18
37
  const emit = defineEmits<{
19
38
  change: [v: StyleSchema, eventData: ContainerChangeEventData];
39
+ addDiffCount: [];
20
40
  }>();
21
41
 
22
42
  const config = defineFormItem({
@@ -36,4 +56,6 @@ const config = defineFormItem({
36
56
  const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
37
57
  emit('change', value, eventData);
38
58
  };
59
+
60
+ const onAddDiffCount = () => emit('addDiffCount');
39
61
  </script>
@@ -1,5 +1,14 @@
1
1
  <template>
2
- <MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
2
+ <MContainer
3
+ :config="config"
4
+ :model="values"
5
+ :last-values="lastValues"
6
+ :is-compare="isCompare"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ @change="change"
10
+ @add-diff-count="onAddDiffCount"
11
+ ></MContainer>
3
12
  </template>
4
13
 
5
14
  <script lang="ts" setup>
@@ -12,12 +21,15 @@ import { AlignCenter, AlignLeft, AlignRight } from '../icons/text-align';
12
21
 
13
22
  defineProps<{
14
23
  values: Partial<StyleSchema>;
24
+ lastValues?: Partial<StyleSchema>;
25
+ isCompare?: boolean;
15
26
  disabled?: boolean;
16
27
  size?: 'large' | 'default' | 'small';
17
28
  }>();
18
29
 
19
30
  const emit = defineEmits<{
20
31
  change: [v: StyleSchema, eventData: ContainerChangeEventData];
32
+ addDiffCount: [];
21
33
  }>();
22
34
 
23
35
  const config = defineFormItem({
@@ -91,4 +103,6 @@ const config = defineFormItem({
91
103
  const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
92
104
  emit('change', value, eventData);
93
105
  };
106
+
107
+ const onAddDiffCount = () => emit('addDiffCount');
94
108
  </script>
@@ -1,8 +1,19 @@
1
1
  <template>
2
- <MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
2
+ <MContainer
3
+ :config="config"
4
+ :model="values"
5
+ :last-values="lastValues"
6
+ :is-compare="isCompare"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ @change="change"
10
+ @add-diff-count="onAddDiffCount"
11
+ ></MContainer>
3
12
  <Box
4
13
  v-show="!['fixed', 'absolute'].includes(values.position)"
5
14
  :model="values"
15
+ :last-values="lastValues"
16
+ :is-compare="isCompare"
6
17
  :size="size"
7
18
  :disabled="disabled"
8
19
  @change="change"
@@ -34,12 +45,15 @@ import {
34
45
 
35
46
  defineProps<{
36
47
  values: Partial<StyleSchema>;
48
+ lastValues?: Partial<StyleSchema>;
49
+ isCompare?: boolean;
37
50
  disabled?: boolean;
38
51
  size?: 'large' | 'default' | 'small';
39
52
  }>();
40
53
 
41
54
  const emit = defineEmits<{
42
55
  change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
56
+ addDiffCount: [];
43
57
  }>();
44
58
 
45
59
  const config = defineFormItem({
@@ -185,4 +199,6 @@ const config = defineFormItem({
185
199
  const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
186
200
  emit('change', value, eventData);
187
201
  };
202
+
203
+ const onAddDiffCount = () => emit('addDiffCount');
188
204
  </script>
@@ -1,5 +1,14 @@
1
1
  <template>
2
- <MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
2
+ <MContainer
3
+ :config="config"
4
+ :model="values"
5
+ :last-values="lastValues"
6
+ :is-compare="isCompare"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ @change="change"
10
+ @add-diff-count="onAddDiffCount"
11
+ ></MContainer>
3
12
  </template>
4
13
 
5
14
  <script lang="ts" setup>
@@ -8,12 +17,15 @@ import type { StyleSchema } from '@tmagic/schema';
8
17
 
9
18
  const props = defineProps<{
10
19
  values: Partial<StyleSchema>;
20
+ lastValues?: Partial<StyleSchema>;
21
+ isCompare?: boolean;
11
22
  disabled?: boolean;
12
23
  size?: 'large' | 'default' | 'small';
13
24
  }>();
14
25
 
15
26
  const emit = defineEmits<{
16
27
  change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
28
+ addDiffCount: [];
17
29
  }>();
18
30
 
19
31
  const positionText: Record<string, string> = {
@@ -100,4 +112,6 @@ const config = defineFormItem({
100
112
  const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
101
113
  emit('change', value, eventData);
102
114
  };
115
+
116
+ const onAddDiffCount = () => emit('addDiffCount');
103
117
  </script>
@@ -1,5 +1,14 @@
1
1
  <template>
2
- <MContainer :config="config" :model="values" :size="size" :disabled="disabled" @change="change"></MContainer>
2
+ <MContainer
3
+ :config="config"
4
+ :model="values"
5
+ :last-values="lastValues"
6
+ :is-compare="isCompare"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ @change="change"
10
+ @add-diff-count="onAddDiffCount"
11
+ ></MContainer>
3
12
  </template>
4
13
 
5
14
  <script lang="ts" setup>
@@ -8,12 +17,15 @@ import type { StyleSchema } from '@tmagic/schema';
8
17
 
9
18
  defineProps<{
10
19
  values: Partial<StyleSchema>;
20
+ lastValues?: Partial<StyleSchema>;
21
+ isCompare?: boolean;
11
22
  disabled?: boolean;
12
23
  size?: 'large' | 'default' | 'small';
13
24
  }>();
14
25
 
15
26
  const emit = defineEmits<{
16
27
  change: [v: StyleSchema, eventData: ContainerChangeEventData];
28
+ addDiffCount: [];
17
29
  }>();
18
30
 
19
31
  const config = defineFormItem({
@@ -51,4 +63,6 @@ const config = defineFormItem({
51
63
  const change = (value: StyleSchema, eventData: ContainerChangeEventData) => {
52
64
  emit('change', value, eventData);
53
65
  };
66
+
67
+ const onAddDiffCount = () => emit('addDiffCount');
54
68
  </script>
@@ -5,7 +5,7 @@
5
5
  <TMagicScrollbar>
6
6
  <MForm
7
7
  ref="configForm"
8
- :class="propsPanelSize"
8
+ :class="[propsPanelSize, 'm-editor-props-form-panel-form']"
9
9
  :popper-class="`m-editor-props-panel-popper ${propsPanelSize}`"
10
10
  :label-width="labelWidth"
11
11
  :label-position="labelPosition"
@@ -1,6 +1,6 @@
1
1
  import { computed, onBeforeUnmount, ref, watch } from 'vue';
2
2
 
3
- import type { Id, MNode, MPage, MPageFragment } from '@tmagic/core';
3
+ import type { Id, MApp, MNode, MPage, MPageFragment } from '@tmagic/core';
4
4
  import { getNodePath, isPage, isPageFragment, traverseNode } from '@tmagic/utils';
5
5
 
6
6
  import type { LayerNodeStatus, Services } from '@editor/type';
@@ -45,22 +45,70 @@ export const useNodeStatus = ({ editorService }: Services) => {
45
45
  page.value ? nodeStatusMaps.value.get(page.value.id) : new Map<Id, LayerNodeStatus>(),
46
46
  );
47
47
 
48
- // 切换页面或者新增页面,重新生成节点状态
48
+ // 切换页面 / 新增页面 / 整体替换 dsl 后 page 引用变化时,重新生成节点状态。
49
+ //
50
+ // 注意这里 watch 的是 page 引用而不是 page.id:
51
+ // 历史版本恢复 / 外部 modelValue 整体覆盖等场景,新旧 dsl 的 page.id 通常完全
52
+ // 一致,但 page 对象引用是新的、items 也是新的。仅监听 id 会漏掉这类「同 id
53
+ // 不同内容」的替换,导致 nodeStatusMaps 残留旧节点 status,组件树渲染滞留在
54
+ // 旧版本。监听引用可以覆盖普通切页(不同 id)和整体替换(同 id 新引用)两种
55
+ // 情况;同时配合下方 root-change 时清空缓存,避免拿到污染的 initial status。
49
56
  watch(
50
- () => page.value?.id,
51
- (pageId) => {
52
- if (!pageId) {
57
+ page,
58
+ (newPage) => {
59
+ if (!newPage?.id) {
53
60
  return;
54
61
  }
55
62
 
56
63
  // 生成节点状态
57
- nodeStatusMaps.value.set(pageId, createPageNodeStatus(page.value!, nodeStatusMaps.value.get(pageId)));
64
+ nodeStatusMaps.value.set(newPage.id, createPageNodeStatus(newPage, nodeStatusMaps.value.get(newPage.id)));
58
65
  },
59
66
  {
60
67
  immediate: true,
61
68
  },
62
69
  );
63
70
 
71
+ /**
72
+ * root 整体被替换时(外部 modelValue 变化、历史版本恢复、套件编辑模式进入/退出等):
73
+ * - 仅 watch page 引用还不够,因为 root-change 同步触发时 page 还是旧引用,
74
+ * 等 initService 的异步 IIFE 跑完 editorService.select(...) 后 page 才会
75
+ * 被替换为新 dsl 中的 page;此时上面的 page watch 才会触发重建。
76
+ * - 但若直接同步清空 nodeStatusMaps,会让 nodeStatusMap (computed) 立刻变
77
+ * undefined。上层 LayerPanel 用 `v-if="page && nodeStatusMap"` 渲染组件树,
78
+ * 会瞬间销毁整个面板;若紧接着的异步 select 链路(套件退出等场景)发生
79
+ * 竞态、page 引用未变 / 解析失败,watch(page) 不触发重建,组件树就再也回
80
+ * 不来。
81
+ * - 此外「污染」问题本质来自 createPageNodeStatus 用旧 status 作为新节点
82
+ * initial 值:只要新 root 的 page 是新引用,watch(page) 会触发重建,重建
83
+ * 时基于新 page.items 生成的 map 只会包含新节点 id;旧节点 id 即便残留在
84
+ * initialLayerNodeStatus 中也不会被写入新 map。真正的风险只有「同一 page
85
+ * id 下,新旧 dsl 都存在同一节点 id 但其实是不同节点」这种极端情况——这
86
+ * 在常规业务中不会发生(id 是 uuid)。
87
+ *
88
+ * 综合:root-change 时仅清理「在新 root 中已不存在的 page id」对应缓存,
89
+ * 保留仍然有效的 page status 不动;既避免 v-if 闪断,也不会保留无关 page 的
90
+ * 死缓存。同 page id 的重建交给下方 watch(page) 触发。
91
+ */
92
+ const rootChangeHandler = (value: MApp | null) => {
93
+ if (!value) {
94
+ nodeStatusMaps.value = new Map();
95
+ return;
96
+ }
97
+
98
+ const validPageIds = new Set<Id>();
99
+ (value.items || []).forEach((p) => {
100
+ if (p?.id !== undefined) validPageIds.add(p.id);
101
+ });
102
+
103
+ for (const cachedPageId of Array.from(nodeStatusMaps.value.keys())) {
104
+ if (!validPageIds.has(cachedPageId)) {
105
+ nodeStatusMaps.value.delete(cachedPageId);
106
+ }
107
+ }
108
+ };
109
+
110
+ editorService.on('root-change', rootChangeHandler);
111
+
64
112
  // 选中状态变化,更新节点状态
65
113
  watch(
66
114
  nodes,
@@ -111,6 +159,7 @@ export const useNodeStatus = ({ editorService }: Services) => {
111
159
  editorService.on('remove', removeHandler);
112
160
 
113
161
  onBeforeUnmount(() => {
162
+ editorService.off('root-change', rootChangeHandler);
114
163
  editorService.off('remove', removeHandler);
115
164
  editorService.off('add', addHandler);
116
165
  });