@tmagic/editor 1.4.0-beta.1 → 1.4.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 (54) hide show
  1. package/dist/style.css +22 -26
  2. package/dist/tmagic-editor.js +977 -798
  3. package/dist/tmagic-editor.umd.cjs +981 -800
  4. package/package.json +11 -11
  5. package/src/components/CodeBlockEditor.vue +75 -101
  6. package/src/components/FloatingBox.vue +58 -38
  7. package/src/components/SplitView.vue +46 -35
  8. package/src/fields/DataSourceFieldSelect.vue +2 -1
  9. package/src/fields/DataSourceFields.vue +55 -30
  10. package/src/fields/DataSourceInput.vue +6 -2
  11. package/src/fields/DataSourceMocks.vue +35 -17
  12. package/src/hooks/index.ts +2 -0
  13. package/src/hooks/use-code-block-edit.ts +1 -1
  14. package/src/hooks/use-editor-content-height.ts +20 -0
  15. package/src/hooks/use-float-box.ts +21 -15
  16. package/src/hooks/use-next-float-box-position.ts +29 -0
  17. package/src/hooks/use-window-rect.ts +20 -0
  18. package/src/layouts/CodeEditor.vue +3 -6
  19. package/src/layouts/Framework.vue +33 -34
  20. package/src/layouts/PropsPanel.vue +37 -0
  21. package/src/layouts/sidebar/Sidebar.vue +17 -15
  22. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -3
  23. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +36 -22
  24. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -6
  25. package/src/layouts/workspace/viewer/NodeListMenu.vue +1 -0
  26. package/src/layouts/workspace/viewer/StageOverlay.vue +3 -1
  27. package/src/services/stageOverlay.ts +2 -2
  28. package/src/services/ui.ts +6 -0
  29. package/src/theme/code-block.scss +0 -19
  30. package/src/theme/component-list-panel.scss +0 -1
  31. package/src/theme/floating-box.scss +2 -2
  32. package/src/theme/icon.scss +7 -1
  33. package/src/theme/layer-panel.scss +0 -1
  34. package/src/theme/props-panel.scss +14 -0
  35. package/src/theme/sidebar.scss +0 -7
  36. package/src/type.ts +6 -6
  37. package/types/components/CodeBlockEditor.vue.d.ts +39 -25
  38. package/types/components/FloatingBox.vue.d.ts +42 -57
  39. package/types/components/SplitView.vue.d.ts +2 -0
  40. package/types/fields/DataSourceFields.vue.d.ts +84 -28
  41. package/types/fields/DataSourceMocks.vue.d.ts +80 -28
  42. package/types/hooks/index.d.ts +2 -0
  43. package/types/hooks/use-code-block-edit.d.ts +16 -11
  44. package/types/hooks/use-data-source-method.d.ts +16 -11
  45. package/types/hooks/use-editor-content-height.d.ts +3 -0
  46. package/types/hooks/use-next-float-box-position.d.ts +9 -0
  47. package/types/hooks/use-window-rect.d.ts +6 -0
  48. package/types/layouts/sidebar/Sidebar.vue.d.ts +1 -1
  49. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -3
  50. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +34 -22
  51. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +2 -15
  52. package/types/services/stageOverlay.d.ts +1 -1
  53. package/types/services/ui.d.ts +6 -0
  54. package/types/type.d.ts +6 -5
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.4.0-beta.1",
2
+ "version": "1.4.0",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -42,14 +42,14 @@
42
42
  "dependencies": {
43
43
  "@babel/core": "^7.18.0",
44
44
  "@element-plus/icons-vue": "^2.3.1",
45
- "@tmagic/core": "1.4.0-beta.1",
46
- "@tmagic/dep": "1.4.0-beta.1",
47
- "@tmagic/design": "1.4.0-beta.1",
48
- "@tmagic/form": "1.4.0-beta.1",
49
- "@tmagic/schema": "1.4.0-beta.1",
50
- "@tmagic/stage": "1.4.0-beta.1",
51
- "@tmagic/table": "1.4.0-beta.1",
52
- "@tmagic/utils": "1.4.0-beta.1",
45
+ "@tmagic/core": "1.4.0",
46
+ "@tmagic/dep": "1.4.0",
47
+ "@tmagic/design": "1.4.0",
48
+ "@tmagic/form": "1.4.0",
49
+ "@tmagic/schema": "1.4.0",
50
+ "@tmagic/stage": "1.4.0",
51
+ "@tmagic/table": "1.4.0",
52
+ "@tmagic/utils": "1.4.0",
53
53
  "buffer": "^6.0.3",
54
54
  "color": "^3.1.3",
55
55
  "emmet-monaco-es": "^5.3.0",
@@ -63,8 +63,8 @@
63
63
  "vue": "^3.4.21"
64
64
  },
65
65
  "peerDependencies": {
66
- "@tmagic/design": "1.4.0-beta.1",
67
- "@tmagic/form": "1.4.0-beta.1",
66
+ "@tmagic/design": "1.4.0",
67
+ "@tmagic/form": "1.4.0",
68
68
  "monaco-editor": "^0.47.0",
69
69
  "vue": "^3.4.21"
70
70
  },
@@ -1,81 +1,90 @@
1
1
  <template>
2
2
  <!-- 代码块编辑区 -->
3
- <FloatingBox v-model:visible="boxVisible" title="代码编辑" :position="boxPosition" :before-close="beforeClose">
3
+ <FloatingBox
4
+ v-model:visible="boxVisible"
5
+ v-model:width="width"
6
+ v-model:height="codeBlockEditorHeight"
7
+ :title="content.name ? `${disabled ? '查看' : '编辑'}${content.name}` : '新增代码'"
8
+ :position="boxPosition"
9
+ :before-close="beforeClose"
10
+ >
4
11
  <template #body>
5
- <div ref="floatingBoxBody"></div>
12
+ <MFormBox
13
+ class="m-editor-code-block-editor"
14
+ ref="formBox"
15
+ label-width="80px"
16
+ :close-on-press-escape="false"
17
+ :title="content.name"
18
+ :config="functionConfig"
19
+ :values="content"
20
+ :disabled="disabled"
21
+ style="height: 100%"
22
+ @change="changeHandler"
23
+ @submit="submitForm"
24
+ @error="errorHandler"
25
+ @closed="closedHandler"
26
+ >
27
+ <template #left>
28
+ <TMagicButton v-if="!disabled" type="primary" link @click="difVisible = true">查看修改</TMagicButton>
29
+ </template>
30
+ </MFormBox>
6
31
  </template>
7
32
  </FloatingBox>
8
33
 
9
- <Teleport :to="floatingBoxBody" :disabled="slideType === 'box'" v-if="editVisible">
10
- <MFormBox
11
- class="m-editor-code-block-editor"
12
- ref="fomDrawer"
13
- label-width="80px"
14
- :close-on-press-escape="false"
15
- :title="content.name"
16
- :width="size"
17
- :config="functionConfig"
18
- :values="content"
19
- :disabled="disabled"
20
- @change="changeHandler"
21
- @submit="submitForm"
22
- @error="errorHandler"
23
- @open="openHandler"
24
- @closed="closedHandler"
25
- >
26
- <template #left>
27
- <TMagicButton type="primary" link @click="difVisible = true">查看修改</TMagicButton>
34
+ <Teleport to="body">
35
+ <TMagicDialog title="查看修改" v-model="difVisible" fullscreen>
36
+ <div style="display: flex; margin-bottom: 10px">
37
+ <div style="flex: 1"><TMagicTag size="small" type="info">修改前</TMagicTag></div>
38
+ <div style="flex: 1"><TMagicTag size="small" type="success">修改后</TMagicTag></div>
39
+ </div>
40
+
41
+ <CodeEditor
42
+ v-if="difVisible"
43
+ ref="magicVsEditor"
44
+ type="diff"
45
+ language="json"
46
+ :initValues="content.content"
47
+ :modifiedValues="formBox?.form?.values.content"
48
+ :style="`height: ${windowRect.height - 150}px`"
49
+ ></CodeEditor>
50
+
51
+ <template #footer>
52
+ <span class="dialog-footer">
53
+ <TMagicButton size="small" @click="difVisible = false">取消</TMagicButton>
54
+ <TMagicButton size="small" type="primary" @click="diffChange">确定</TMagicButton>
55
+ </span>
28
56
  </template>
29
- </MFormBox>
57
+ </TMagicDialog>
30
58
  </Teleport>
31
-
32
- <TMagicDialog v-model="difVisible" title="查看修改" fullscreen>
33
- <div style="display: flex; margin-bottom: 10px">
34
- <div style="flex: 1"><TMagicTag size="small" type="info">修改前</TMagicTag></div>
35
- <div style="flex: 1"><TMagicTag size="small" type="success">修改后</TMagicTag></div>
36
- </div>
37
-
38
- <CodeEditor
39
- v-if="difVisible"
40
- ref="magicVsEditor"
41
- type="diff"
42
- language="json"
43
- :initValues="content.content"
44
- :modifiedValues="fomDrawer?.form?.values.content"
45
- :style="`height: ${height - 200}px`"
46
- ></CodeEditor>
47
-
48
- <template #footer>
49
- <span class="dialog-footer">
50
- <TMagicButton size="small" @click="difVisible = false">取消</TMagicButton>
51
- <TMagicButton size="small" type="primary" @click="diffChange">确定</TMagicButton>
52
- </span>
53
- </template>
54
- </TMagicDialog>
55
59
  </template>
56
60
 
57
61
  <script lang="ts" setup>
58
- import { computed, inject, nextTick, onBeforeUnmount, ref } from 'vue';
62
+ import { computed, inject, Ref, ref } from 'vue';
59
63
 
60
64
  import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
61
- import { ColumnConfig, FormConfig, FormState, MFormBox, MFormDrawer } from '@tmagic/form';
65
+ import { ColumnConfig, FormConfig, FormState, MFormBox } from '@tmagic/form';
62
66
  import type { CodeBlockContent } from '@tmagic/schema';
63
67
 
64
68
  import FloatingBox from '@editor/components/FloatingBox.vue';
69
+ import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
70
+ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
71
+ import { useWindowRect } from '@editor/hooks/use-window-rect';
65
72
  import CodeEditor from '@editor/layouts/CodeEditor.vue';
66
- import type { Services, SlideType } from '@editor/type';
73
+ import type { Services } from '@editor/type';
67
74
  import { getConfig } from '@editor/utils/config';
68
75
 
69
76
  defineOptions({
70
77
  name: 'MEditorCodeBlockEditor',
71
78
  });
72
79
 
80
+ const width = defineModel<number>('width', { default: 670 });
81
+ const boxVisible = defineModel<boolean>('visible', { default: false });
82
+
73
83
  const props = defineProps<{
74
84
  content: CodeBlockContent;
75
85
  disabled?: boolean;
76
86
  isDataSource?: boolean;
77
87
  dataSourceType?: string;
78
- slideType?: SlideType;
79
88
  }>();
80
89
 
81
90
  const emit = defineEmits<{
@@ -84,38 +93,23 @@ const emit = defineEmits<{
84
93
 
85
94
  const services = inject<Services>('services');
86
95
 
87
- const difVisible = ref(false);
88
- const height = ref(globalThis.innerHeight);
89
-
90
- const windowReizehandler = () => {
91
- height.value = globalThis.innerHeight;
92
- };
96
+ const { height: codeBlockEditorHeight } = useEditorContentHeight();
93
97
 
94
- globalThis.addEventListener('resize', windowReizehandler);
95
-
96
- onBeforeUnmount(() => {
97
- globalThis.removeEventListener('resize', windowReizehandler);
98
- });
98
+ const difVisible = ref(false);
99
+ const { rect: windowRect } = useWindowRect();
99
100
 
100
101
  const magicVsEditor = ref<InstanceType<typeof CodeEditor>>();
101
102
 
102
103
  const diffChange = () => {
103
- if (!magicVsEditor.value || !fomDrawer.value?.form) {
104
+ if (!magicVsEditor.value || !formBox.value?.form) {
104
105
  return;
105
106
  }
106
107
 
107
- fomDrawer.value.form.values.content = magicVsEditor.value.getEditorValue();
108
+ formBox.value.form.values.content = magicVsEditor.value.getEditorValue();
108
109
 
109
110
  difVisible.value = false;
110
111
  };
111
112
 
112
- const columnWidth = computed(() => services?.uiService.get('columnWidth'));
113
- const size = computed(() =>
114
- columnWidth.value ? columnWidth.value.center + columnWidth.value.right - (props.isDataSource ? 100 : 0) : 600,
115
- );
116
-
117
- const codeEditorHeight = ref('600px');
118
-
119
113
  const defaultParamColConfig: ColumnConfig = {
120
114
  type: 'row',
121
115
  label: '参数类型',
@@ -199,7 +193,7 @@ const functionConfig = computed<FormConfig>(() => [
199
193
  name: 'content',
200
194
  type: 'vs-code',
201
195
  options: inject('codeOptions', {}),
202
- height: codeEditorHeight.value,
196
+ height: '500px',
203
197
  onChange: (formState: FormState | undefined, code: string) => {
204
198
  try {
205
199
  // 检测js代码是否存在语法错误
@@ -216,6 +210,7 @@ const functionConfig = computed<FormConfig>(() => [
216
210
  ]);
217
211
 
218
212
  const submitForm = (values: CodeBlockContent) => {
213
+ changedValue.value = undefined;
219
214
  emit('submit', values);
220
215
  };
221
216
 
@@ -223,16 +218,7 @@ const errorHandler = (error: any) => {
223
218
  tMagicMessage.error(error.message);
224
219
  };
225
220
 
226
- const fomDrawer = ref<InstanceType<typeof MFormDrawer>>();
227
-
228
- const openHandler = () => {
229
- setTimeout(() => {
230
- if (fomDrawer.value) {
231
- const height = fomDrawer.value?.bodyHeight - 348 - (props.isDataSource ? 50 : 0);
232
- codeEditorHeight.value = `${height > 100 ? height : 600}px`;
233
- }
234
- });
235
- };
221
+ const formBox = ref<InstanceType<typeof MFormBox>>();
236
222
 
237
223
  const changedValue = ref<CodeBlockContent>();
238
224
  const changeHandler = (values: CodeBlockContent) => {
@@ -256,6 +242,8 @@ const beforeClose = (done: (cancel?: boolean) => void) => {
256
242
  done();
257
243
  })
258
244
  .catch((action: string) => {
245
+ if (action === 'cancel') {
246
+ }
259
247
  done(action === 'cancel');
260
248
  });
261
249
  };
@@ -264,31 +252,17 @@ const closedHandler = () => {
264
252
  changedValue.value = undefined;
265
253
  };
266
254
 
267
- const boxVisible = ref<boolean>(false);
268
- const editVisible = ref<boolean>(false);
269
- const floatingBoxBody = ref<HTMLDivElement>();
270
-
271
- const boxPosition = computed(() => {
272
- const columnWidth = services?.uiService?.get('columnWidth');
273
- const navMenuRect = services?.uiService?.get('navMenuRect');
274
- return {
275
- left: columnWidth?.left ?? 0,
276
- top: (navMenuRect?.top ?? 0) + (navMenuRect?.height ?? 0),
277
- };
278
- });
255
+ const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
256
+ const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(services?.uiService, parentFloating);
279
257
 
280
258
  defineExpose({
281
259
  async show() {
282
- if (props.slideType !== 'box') {
283
- boxVisible.value = true;
284
- }
285
- await nextTick();
286
- editVisible.value = true;
287
- fomDrawer.value?.show();
260
+ calcBoxPosition();
261
+ boxVisible.value = true;
288
262
  },
289
263
 
290
- hide() {
291
- fomDrawer.value?.hide();
264
+ async hide() {
265
+ boxVisible.value = false;
292
266
  },
293
267
  });
294
268
  </script>
@@ -1,15 +1,15 @@
1
1
  <template>
2
2
  <Teleport to="body" v-if="visible">
3
3
  <div ref="target" class="m-editor-float-box" :style="{ ...style, zIndex: curZIndex }" @mousedown="nextZIndex">
4
- <div ref="dragTarget" class="m-editor-float-box-title">
4
+ <div ref="titleEl" class="m-editor-float-box-title">
5
5
  <slot name="title">
6
6
  <span>{{ title }}</span>
7
7
  </slot>
8
8
  <div>
9
- <TMagicButton link size="small" :icon="Close" @click="closeHandler"></TMagicButton>
9
+ <TMagicButton link size="small" @click="closeHandler"><MIcon :icon="Close"></MIcon></TMagicButton>
10
10
  </div>
11
11
  </div>
12
- <div class="m-editor-float-box-body">
12
+ <div class="m-editor-float-box-body" :style="{ height: `${bodyHeight}px` }">
13
13
  <slot name="body"></slot>
14
14
  </div>
15
15
  </div>
@@ -17,67 +17,71 @@
17
17
  </template>
18
18
 
19
19
  <script setup lang="ts">
20
- import { computed, nextTick, onBeforeUnmount, ref, watch, watchEffect } from 'vue';
20
+ import { computed, inject, nextTick, onBeforeUnmount, provide, ref, watch } from 'vue';
21
21
  import { Close } from '@element-plus/icons-vue';
22
22
  import VanillaMoveable from 'moveable';
23
23
 
24
24
  import { TMagicButton, useZIndex } from '@tmagic/design';
25
25
 
26
+ import MIcon from '@editor/components/Icon.vue';
27
+ import type { Services } from '@editor/type';
28
+
26
29
  interface Position {
27
30
  left: number;
28
31
  top: number;
29
32
  }
30
33
 
31
- interface Rect {
32
- width: number | string;
33
- height: number | string;
34
- }
34
+ const width = defineModel<number>('width', { default: 0 });
35
+ const height = defineModel<number>('height', { default: 0 });
36
+ const visible = defineModel<boolean>('visible', { default: false });
35
37
 
36
38
  const props = withDefaults(
37
39
  defineProps<{
38
- visible: boolean;
39
40
  position?: Position;
40
- rect?: Rect;
41
41
  title?: string;
42
42
  beforeClose?: (done: (cancel?: boolean) => void) => void;
43
43
  }>(),
44
44
  {
45
- visible: false,
46
45
  title: '',
47
46
  position: () => ({ left: 0, top: 0 }),
48
- rect: () => ({ width: 'auto', height: 'auto' }),
49
47
  },
50
48
  );
51
49
 
52
- const emit = defineEmits<{
53
- 'update:visible': [boolean];
54
- }>();
55
-
56
50
  const target = ref<HTMLDivElement>();
57
- const dragTarget = ref<HTMLDivElement>();
51
+ const titleEl = ref<HTMLDivElement>();
58
52
 
59
53
  const zIndex = useZIndex();
60
- const curZIndex = ref<number>(zIndex.nextZIndex());
54
+ const curZIndex = ref<number>(0);
61
55
 
62
- const rect = ref({
63
- width: props.rect.width,
64
- height: props.rect.height,
56
+ const titleHeight = ref(0);
57
+ const bodyHeight = computed(() => {
58
+ if (height.value) {
59
+ return height.value - titleHeight.value;
60
+ }
61
+
62
+ if (target.value) {
63
+ return target.value.clientHeight - titleHeight.value;
64
+ }
65
+
66
+ return 'auto';
65
67
  });
66
68
 
67
- watchEffect(() => {
68
- rect.value = {
69
- width: props.rect.width,
70
- height: props.rect.height,
69
+ const services = inject<Services>('services');
70
+ const frameworkWidth = computed(() => services?.uiService.get('frameworkRect').width || 0);
71
+ const style = computed(() => {
72
+ let { left } = props.position;
73
+ if (width.value) {
74
+ left = left + width.value > frameworkWidth.value ? frameworkWidth.value - width.value : left;
75
+ }
76
+
77
+ return {
78
+ left: `${left}px`,
79
+ top: `${props.position.top}px`,
80
+ width: width.value ? `${width.value}px` : 'auto',
81
+ height: height.value ? `${height.value}px` : 'auto',
71
82
  };
72
83
  });
73
84
 
74
- const style = computed(() => ({
75
- left: `${props.position.left}px`,
76
- top: `${props.position.top}px`,
77
- width: typeof rect.value.width === 'string' ? rect.value.width : `${rect.value.width}px`,
78
- height: typeof rect.value.height === 'string' ? rect.value.height : `${rect.value.height}px`,
79
- }));
80
-
81
85
  let moveable: VanillaMoveable | null = null;
82
86
 
83
87
  const initMoveable = () => {
@@ -90,7 +94,7 @@ const initMoveable = () => {
90
94
  keepRatio: false,
91
95
  origin: false,
92
96
  snappable: true,
93
- dragTarget: dragTarget.value,
97
+ dragTarget: titleEl.value,
94
98
  dragTargetSelf: false,
95
99
  linePadding: 10,
96
100
  controlPadding: 10,
@@ -102,8 +106,8 @@ const initMoveable = () => {
102
106
  });
103
107
 
104
108
  moveable.on('resize', (e) => {
105
- rect.value.width = e.width;
106
- rect.value.height = e.height;
109
+ width.value = e.width;
110
+ height.value = e.height;
107
111
  e.target.style.width = `${e.width}px`;
108
112
  e.target.style.height = `${e.height}px`;
109
113
  e.target.style.transform = e.drag.transform;
@@ -116,11 +120,23 @@ const destroyMoveable = () => {
116
120
  };
117
121
 
118
122
  watch(
119
- () => props.visible,
123
+ visible,
120
124
  async (visible) => {
121
125
  if (visible) {
122
126
  await nextTick();
123
- initMoveable();
127
+ curZIndex.value = zIndex.nextZIndex();
128
+
129
+ const targetRect = target.value?.getBoundingClientRect();
130
+ if (targetRect) {
131
+ width.value = targetRect.width;
132
+ height.value = targetRect.height;
133
+ initMoveable();
134
+ }
135
+
136
+ if (titleEl.value) {
137
+ const titleRect = titleEl.value.getBoundingClientRect();
138
+ titleHeight.value = titleRect.height;
139
+ }
124
140
  } else {
125
141
  destroyMoveable();
126
142
  }
@@ -136,7 +152,7 @@ onBeforeUnmount(() => {
136
152
 
137
153
  const hide = (cancel?: boolean) => {
138
154
  if (cancel !== false) {
139
- emit('update:visible', false);
155
+ visible.value = false;
140
156
  }
141
157
  };
142
158
 
@@ -152,7 +168,11 @@ const nextZIndex = () => {
152
168
  curZIndex.value = zIndex.nextZIndex();
153
169
  };
154
170
 
171
+ provide('parentFloating', target);
172
+
155
173
  defineExpose({
174
+ bodyHeight,
156
175
  target,
176
+ titleEl,
157
177
  });
158
178
  </script>
@@ -21,7 +21,7 @@
21
21
  </template>
22
22
 
23
23
  <script lang="ts" setup>
24
- import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
24
+ import { computed, onBeforeUnmount, onMounted, ref, watchEffect } from 'vue';
25
25
  import { OnDrag } from 'gesto';
26
26
 
27
27
  import Resizer from './Resizer.vue';
@@ -34,6 +34,7 @@ const emit = defineEmits(['update:left', 'change', 'update:right']);
34
34
 
35
35
  const props = withDefaults(
36
36
  defineProps<{
37
+ width?: number;
37
38
  left?: number;
38
39
  right?: number;
39
40
  minLeft?: number;
@@ -54,8 +55,11 @@ const el = ref<HTMLElement>();
54
55
 
55
56
  const hasLeft = computed(() => typeof props.left !== 'undefined');
56
57
  const hasRight = computed(() => typeof props.right !== 'undefined');
58
+ const center = ref(0);
59
+
60
+ let clientWidth = 0;
57
61
 
58
- const getCenterWidth = (clientWidth: number, l = 0, r = 0) => {
62
+ const getCenterWidth = (l = 0, r = 0) => {
59
63
  let right = r > 0 ? r : 0;
60
64
  let left = l > 0 ? l : 0;
61
65
  let center = clientWidth - left - right;
@@ -76,45 +80,51 @@ const getCenterWidth = (clientWidth: number, l = 0, r = 0) => {
76
80
  };
77
81
  };
78
82
 
79
- let clientWidth = 0;
80
- const resizerObserver = new ResizeObserver((entries) => {
81
- for (const { contentRect } of entries) {
82
- clientWidth = contentRect.width;
83
+ const widthChange = (width: number) => {
84
+ if (width <= 0) {
85
+ return;
86
+ }
83
87
 
84
- let left = props.left || 0;
85
- let right = props.right || 0;
88
+ clientWidth = width;
89
+ let left = props.left || 0;
90
+ let right = props.right || 0;
86
91
 
87
- if (left > clientWidth) {
88
- left = clientWidth / 3;
89
- }
92
+ if (left > clientWidth) {
93
+ left = clientWidth / 3;
94
+ }
90
95
 
91
- if (right > clientWidth) {
92
- right = clientWidth / 3;
93
- }
96
+ if (right > clientWidth) {
97
+ right = clientWidth / 3;
98
+ }
94
99
 
95
- const columnWidth = getCenterWidth(clientWidth, left, right);
100
+ const columnWidth = getCenterWidth(left, right);
96
101
 
97
- center.value = columnWidth.center;
102
+ center.value = columnWidth.center;
98
103
 
99
- emit('change', {
100
- left: columnWidth.left,
101
- center: center.value,
102
- right: columnWidth.right,
103
- });
104
- }
105
- });
104
+ emit('change', columnWidth);
105
+ };
106
106
 
107
- onMounted(() => {
108
- if (el.value) {
109
- resizerObserver.observe(el.value);
110
- }
111
- });
107
+ if (typeof props.width !== 'number') {
108
+ const resizerObserver = new ResizeObserver((entries) => {
109
+ for (const { contentRect } of entries) {
110
+ widthChange(contentRect.width);
111
+ }
112
+ });
112
113
 
113
- onBeforeUnmount(() => {
114
- resizerObserver.disconnect();
115
- });
114
+ onMounted(() => {
115
+ if (el.value) {
116
+ resizerObserver.observe(el.value);
117
+ }
118
+ });
116
119
 
117
- const center = ref(0);
120
+ onBeforeUnmount(() => {
121
+ resizerObserver.disconnect();
122
+ });
123
+ } else {
124
+ watchEffect(() => {
125
+ if (typeof props.width === 'number') widthChange(props.width);
126
+ });
127
+ }
118
128
 
119
129
  const changeLeft = ({ deltaX }: OnDrag) => {
120
130
  if (typeof props.left === 'undefined') return;
@@ -125,7 +135,7 @@ const changeLeft = ({ deltaX }: OnDrag) => {
125
135
  left = props.left;
126
136
  }
127
137
 
128
- const columnWidth = getCenterWidth(clientWidth, left, props.right || 0);
138
+ const columnWidth = getCenterWidth(left, props.right || 0);
129
139
 
130
140
  center.value = columnWidth.center;
131
141
 
@@ -145,7 +155,7 @@ const changeRight = ({ deltaX }: OnDrag) => {
145
155
  right = props.right;
146
156
  }
147
157
 
148
- const columnWidth = getCenterWidth(clientWidth, props.left, right);
158
+ const columnWidth = getCenterWidth(props.left, right);
149
159
 
150
160
  center.value = columnWidth.center;
151
161
 
@@ -158,7 +168,8 @@ const changeRight = ({ deltaX }: OnDrag) => {
158
168
 
159
169
  defineExpose({
160
170
  updateWidth() {
161
- const columnWidth = getCenterWidth(el.value?.clientWidth || clientWidth, props.left, props.right);
171
+ clientWidth = props.width ?? el.value?.clientWidth ?? clientWidth;
172
+ const columnWidth = getCenterWidth(props.left, props.right);
162
173
 
163
174
  emit('change', {
164
175
  left: columnWidth.left,
@@ -19,9 +19,9 @@
19
19
  style="margin-left: 5px"
20
20
  link
21
21
  :type="showDataSourceFieldSelect ? 'primary' : 'default'"
22
- :icon="Coin"
23
22
  :size="size"
24
23
  @click="showDataSourceFieldSelect = !showDataSourceFieldSelect"
24
+ ><MIcon :icon="Coin"></MIcon
25
25
  ></TMagicButton>
26
26
  </div>
27
27
  </template>
@@ -36,6 +36,7 @@ import { MCascader } from '@tmagic/form';
36
36
  import type { DataSchema, DataSourceFieldType } from '@tmagic/schema';
37
37
  import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX } from '@tmagic/utils';
38
38
 
39
+ import MIcon from '@editor/components/Icon.vue';
39
40
  import type { DataSourceFieldSelectConfig, Services } from '@editor/type';
40
41
 
41
42
  defineOptions({