@tmagic/editor 1.4.0-beta.2 → 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 (36) hide show
  1. package/dist/style.css +8 -20
  2. package/dist/tmagic-editor.js +829 -742
  3. package/dist/tmagic-editor.umd.cjs +832 -745
  4. package/package.json +11 -11
  5. package/src/components/CodeBlockEditor.vue +50 -73
  6. package/src/components/FloatingBox.vue +24 -9
  7. package/src/fields/DataSourceFieldSelect.vue +2 -1
  8. package/src/fields/DataSourceFields.vue +55 -30
  9. package/src/fields/DataSourceInput.vue +6 -2
  10. package/src/fields/DataSourceMocks.vue +35 -17
  11. package/src/hooks/use-editor-content-height.ts +1 -1
  12. package/src/hooks/use-float-box.ts +14 -8
  13. package/src/hooks/use-next-float-box-position.ts +29 -0
  14. package/src/layouts/CodeEditor.vue +3 -6
  15. package/src/layouts/PropsPanel.vue +4 -2
  16. package/src/layouts/sidebar/Sidebar.vue +7 -10
  17. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -3
  18. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +36 -22
  19. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -6
  20. package/src/layouts/workspace/viewer/StageOverlay.vue +3 -1
  21. package/src/theme/code-block.scss +0 -14
  22. package/src/theme/component-list-panel.scss +0 -1
  23. package/src/theme/icon.scss +7 -1
  24. package/src/theme/layer-panel.scss +0 -1
  25. package/src/theme/sidebar.scss +0 -7
  26. package/src/type.ts +0 -6
  27. package/types/components/CodeBlockEditor.vue.d.ts +0 -7
  28. package/types/fields/DataSourceFields.vue.d.ts +84 -28
  29. package/types/fields/DataSourceMocks.vue.d.ts +80 -28
  30. package/types/hooks/use-code-block-edit.d.ts +0 -9
  31. package/types/hooks/use-data-source-method.d.ts +0 -9
  32. package/types/hooks/use-next-float-box-position.d.ts +9 -0
  33. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -3
  34. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +34 -22
  35. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +2 -15
  36. package/types/type.d.ts +0 -5
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.4.0-beta.2",
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.2",
46
- "@tmagic/dep": "1.4.0-beta.2",
47
- "@tmagic/design": "1.4.0-beta.2",
48
- "@tmagic/form": "1.4.0-beta.2",
49
- "@tmagic/schema": "1.4.0-beta.2",
50
- "@tmagic/stage": "1.4.0-beta.2",
51
- "@tmagic/table": "1.4.0-beta.2",
52
- "@tmagic/utils": "1.4.0-beta.2",
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.2",
67
- "@tmagic/form": "1.4.0-beta.2",
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
  },
@@ -9,59 +9,57 @@
9
9
  :before-close="beforeClose"
10
10
  >
11
11
  <template #body>
12
- <div ref="floatingBoxBody" style="height: 100%"></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>
13
31
  </template>
14
32
  </FloatingBox>
15
33
 
16
- <Teleport :to="floatingBoxBody" :disabled="slideType === 'box'" v-if="editVisible">
17
- <MFormBox
18
- class="m-editor-code-block-editor"
19
- ref="formBox"
20
- label-width="80px"
21
- :close-on-press-escape="false"
22
- :title="content.name"
23
- :config="functionConfig"
24
- :values="content"
25
- :disabled="disabled"
26
- :height="floatingBoxBody?.clientHeight"
27
- @change="changeHandler"
28
- @submit="submitForm"
29
- @error="errorHandler"
30
- @closed="closedHandler"
31
- >
32
- <template #left>
33
- <TMagicButton v-if="!disabled" 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>
34
56
  </template>
35
- </MFormBox>
57
+ </TMagicDialog>
36
58
  </Teleport>
37
-
38
- <TMagicDialog v-model="difVisible" title="查看修改" fullscreen>
39
- <div style="display: flex; margin-bottom: 10px">
40
- <div style="flex: 1"><TMagicTag size="small" type="info">修改前</TMagicTag></div>
41
- <div style="flex: 1"><TMagicTag size="small" type="success">修改后</TMagicTag></div>
42
- </div>
43
-
44
- <CodeEditor
45
- v-if="difVisible"
46
- ref="magicVsEditor"
47
- type="diff"
48
- language="json"
49
- :initValues="content.content"
50
- :modifiedValues="formBox?.form?.values.content"
51
- :style="`height: ${windowRect.height - 150}px`"
52
- ></CodeEditor>
53
-
54
- <template #footer>
55
- <span class="dialog-footer">
56
- <TMagicButton size="small" @click="difVisible = false">取消</TMagicButton>
57
- <TMagicButton size="small" type="primary" @click="diffChange">确定</TMagicButton>
58
- </span>
59
- </template>
60
- </TMagicDialog>
61
59
  </template>
62
60
 
63
61
  <script lang="ts" setup>
64
- import { computed, inject, nextTick, ref } from 'vue';
62
+ import { computed, inject, Ref, ref } from 'vue';
65
63
 
66
64
  import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
67
65
  import { ColumnConfig, FormConfig, FormState, MFormBox } from '@tmagic/form';
@@ -69,9 +67,10 @@ import type { CodeBlockContent } from '@tmagic/schema';
69
67
 
70
68
  import FloatingBox from '@editor/components/FloatingBox.vue';
71
69
  import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
70
+ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
72
71
  import { useWindowRect } from '@editor/hooks/use-window-rect';
73
72
  import CodeEditor from '@editor/layouts/CodeEditor.vue';
74
- import type { Services, SlideType } from '@editor/type';
73
+ import type { Services } from '@editor/type';
75
74
  import { getConfig } from '@editor/utils/config';
76
75
 
77
76
  defineOptions({
@@ -86,7 +85,6 @@ const props = defineProps<{
86
85
  disabled?: boolean;
87
86
  isDataSource?: boolean;
88
87
  dataSourceType?: string;
89
- slideType?: SlideType;
90
88
  }>();
91
89
 
92
90
  const emit = defineEmits<{
@@ -229,7 +227,6 @@ const changeHandler = (values: CodeBlockContent) => {
229
227
 
230
228
  const beforeClose = (done: (cancel?: boolean) => void) => {
231
229
  if (!changedValue.value) {
232
- editVisible.value = false;
233
230
  done();
234
231
  return;
235
232
  }
@@ -242,12 +239,10 @@ const beforeClose = (done: (cancel?: boolean) => void) => {
242
239
  })
243
240
  .then(() => {
244
241
  changedValue.value && submitForm(changedValue.value);
245
- editVisible.value = false;
246
242
  done();
247
243
  })
248
244
  .catch((action: string) => {
249
245
  if (action === 'cancel') {
250
- editVisible.value = false;
251
246
  }
252
247
  done(action === 'cancel');
253
248
  });
@@ -257,35 +252,17 @@ const closedHandler = () => {
257
252
  changedValue.value = undefined;
258
253
  };
259
254
 
260
- const editVisible = ref<boolean>(false);
261
- const floatingBoxBody = ref<HTMLDivElement>();
262
-
263
- const boxPosition = computed(() => {
264
- const columnWidth = services?.uiService?.get('columnWidth');
265
- const navMenuRect = services?.uiService?.get('navMenuRect');
266
- return {
267
- left: columnWidth?.left ?? 0,
268
- top: (navMenuRect?.top ?? 0) + (navMenuRect?.height ?? 0),
269
- };
270
- });
255
+ const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
256
+ const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(services?.uiService, parentFloating);
271
257
 
272
258
  defineExpose({
273
259
  async show() {
274
- if (props.slideType !== 'box') {
275
- boxVisible.value = true;
276
- await nextTick();
277
- }
278
-
279
- editVisible.value = true;
260
+ calcBoxPosition();
261
+ boxVisible.value = true;
280
262
  },
281
263
 
282
264
  async hide() {
283
- editVisible.value = false;
284
-
285
- if (props.slideType !== 'box') {
286
- await nextTick();
287
- boxVisible.value = false;
288
- }
265
+ boxVisible.value = false;
289
266
  },
290
267
  });
291
268
  </script>
@@ -6,7 +6,7 @@
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
12
  <div class="m-editor-float-box-body" :style="{ height: `${bodyHeight}px` }">
@@ -17,12 +17,15 @@
17
17
  </template>
18
18
 
19
19
  <script setup lang="ts">
20
- import { computed, nextTick, onBeforeUnmount, ref, watch } 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;
@@ -48,7 +51,7 @@ const target = ref<HTMLDivElement>();
48
51
  const titleEl = ref<HTMLDivElement>();
49
52
 
50
53
  const zIndex = useZIndex();
51
- const curZIndex = ref<number>(zIndex.nextZIndex());
54
+ const curZIndex = ref<number>(0);
52
55
 
53
56
  const titleHeight = ref(0);
54
57
  const bodyHeight = computed(() => {
@@ -63,12 +66,21 @@ const bodyHeight = computed(() => {
63
66
  return 'auto';
64
67
  });
65
68
 
66
- const style = computed(() => ({
67
- left: `${props.position.left}px`,
68
- top: `${props.position.top}px`,
69
- width: width.value ? `${width.value}px` : 'auto',
70
- height: height.value ? `${height.value}px` : 'auto',
71
- }));
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',
82
+ };
83
+ });
72
84
 
73
85
  let moveable: VanillaMoveable | null = null;
74
86
 
@@ -112,6 +124,7 @@ watch(
112
124
  async (visible) => {
113
125
  if (visible) {
114
126
  await nextTick();
127
+ curZIndex.value = zIndex.nextZIndex();
115
128
 
116
129
  const targetRect = target.value?.getBoundingClientRect();
117
130
  if (targetRect) {
@@ -155,6 +168,8 @@ const nextZIndex = () => {
155
168
  curZIndex.value = zIndex.nextZIndex();
156
169
  };
157
170
 
171
+ provide('parentFloating', target);
172
+
158
173
  defineExpose({
159
174
  bodyHeight,
160
175
  target,
@@ -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({
@@ -7,39 +7,57 @@
7
7
  <TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
8
8
  </div>
9
9
 
10
- <MFormDrawer
11
- ref="addDialog"
12
- label-width="80px"
10
+ <FloatingBox
11
+ v-model:visible="addDialogVisible"
12
+ v-model:width="width"
13
+ v-model:height="editorHeight"
13
14
  :title="fieldTitle"
14
- :config="dataSourceFieldsConfig"
15
- :values="fieldValues"
16
- :parentValues="model[name]"
17
- :disabled="disabled"
18
- :width="width"
19
- @submit="fieldChange"
20
- ></MFormDrawer>
21
-
22
- <MFormDrawer
23
- ref="addFromJsonDialog"
15
+ :position="boxPosition"
16
+ >
17
+ <template #body>
18
+ <MFormBox
19
+ label-width="80px"
20
+ :title="fieldTitle"
21
+ :config="dataSourceFieldsConfig"
22
+ :values="fieldValues"
23
+ :parentValues="model[name]"
24
+ :disabled="disabled"
25
+ @submit="fieldChange"
26
+ ></MFormBox>
27
+ </template>
28
+ </FloatingBox>
29
+
30
+ <FloatingBox
31
+ v-model:visible="addFromJsonDialogVisible"
32
+ v-model:width="width"
33
+ v-model:height="editorHeight"
24
34
  title="快速添加数据定义"
25
- :config="jsonFromConfig"
26
- :values="jsonFromValues"
27
- :disabled="disabled"
28
- :width="width"
29
- @submit="addFromJsonFromChange"
30
- ></MFormDrawer>
35
+ :position="boxPosition"
36
+ >
37
+ <template #body>
38
+ <MFormBox
39
+ :config="jsonFromConfig"
40
+ :values="jsonFromValues"
41
+ :disabled="disabled"
42
+ @submit="addFromJsonFromChange"
43
+ ></MFormBox>
44
+ </template>
45
+ </FloatingBox>
31
46
  </div>
32
47
  </template>
33
48
 
34
49
  <script setup lang="ts">
35
- import { computed, inject, ref } from 'vue';
50
+ import { inject, Ref, ref } from 'vue';
36
51
 
37
52
  import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
38
- import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
53
+ import { type FieldProps, type FormConfig, type FormState, MFormBox } from '@tmagic/form';
39
54
  import type { DataSchema } from '@tmagic/schema';
40
55
  import { type ColumnConfig, MagicTable } from '@tmagic/table';
41
56
  import { getDefaultValueFromFields } from '@tmagic/utils';
42
57
 
58
+ import FloatingBox from '@editor/components/FloatingBox.vue';
59
+ import { useEditorContentHeight } from '@editor/hooks';
60
+ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
43
61
  import type { Services } from '@editor/type';
44
62
 
45
63
  defineOptions({
@@ -61,17 +79,16 @@ const emit = defineEmits(['change']);
61
79
 
62
80
  const services = inject<Services>('services');
63
81
 
64
- const addDialog = ref<InstanceType<typeof MFormDrawer>>();
65
-
66
82
  const fieldValues = ref<Record<string, any>>({});
67
83
  const fieldTitle = ref('');
68
84
 
69
- const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
85
+ const width = defineModel<number>('width', { default: 670 });
70
86
 
71
87
  const newHandler = () => {
72
88
  fieldValues.value = {};
73
89
  fieldTitle.value = '新增属性';
74
- addDialog.value?.show();
90
+ calcBoxPosition();
91
+ addDialogVisible.value = true;
75
92
  };
76
93
 
77
94
  const fieldChange = ({ index, ...value }: Record<string, any>) => {
@@ -81,7 +98,7 @@ const fieldChange = ({ index, ...value }: Record<string, any>) => {
81
98
  props.model[props.name].push(value);
82
99
  }
83
100
 
84
- addDialog.value?.hide();
101
+ addDialogVisible.value = false;
85
102
 
86
103
  emit('change', props.model[props.name]);
87
104
  };
@@ -122,7 +139,8 @@ const fieldColumns: ColumnConfig[] = [
122
139
  index,
123
140
  };
124
141
  fieldTitle.value = `编辑${row.title}`;
125
- addDialog.value?.show();
142
+ calcBoxPosition();
143
+ addDialogVisible.value = true;
126
144
  },
127
145
  },
128
146
  {
@@ -220,7 +238,6 @@ const dataSourceFieldsConfig: FormConfig = [
220
238
  },
221
239
  ];
222
240
 
223
- const addFromJsonDialog = ref<InstanceType<typeof MFormDrawer>>();
224
241
  const jsonFromConfig: FormConfig = [
225
242
  {
226
243
  name: 'data',
@@ -238,7 +255,8 @@ const jsonFromValues = ref({
238
255
 
239
256
  const newFromJsonHandler = () => {
240
257
  jsonFromValues.value.data = getDefaultValueFromFields(props.model[props.name]);
241
- addFromJsonDialog.value?.show();
258
+ calcBoxPosition();
259
+ addFromJsonDialogVisible.value = true;
242
260
  };
243
261
 
244
262
  const getValueType = (value: any) => {
@@ -288,11 +306,18 @@ const addFromJsonFromChange = ({ data }: { data: string }) => {
288
306
 
289
307
  props.model[props.name] = getFieldsConfig(value, props.model[props.name]);
290
308
 
291
- addFromJsonDialog.value?.hide();
309
+ addFromJsonDialogVisible.value = false;
292
310
 
293
311
  emit('change', props.model[props.name]);
294
312
  } catch (e: any) {
295
313
  tMagicMessage.error(e.message);
296
314
  }
297
315
  };
316
+
317
+ const addDialogVisible = defineModel<boolean>('visible', { default: false });
318
+ const addFromJsonDialogVisible = defineModel<boolean>('visible1', { default: false });
319
+ const { height: editorHeight } = useEditorContentHeight();
320
+
321
+ const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
322
+ const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(services?.uiService, parentFloating);
298
323
  </script>
@@ -29,9 +29,13 @@
29
29
  </div>
30
30
  </template>
31
31
  </component>
32
- <div :class="`tmagic-data-source-input-text el-input el-input--${size}`" @mouseup="mouseupHandler" v-else>
32
+ <div
33
+ :class="`tmagic-data-source-input-text el-input t-input t-size-${size?.[0]} el-input--${size}`"
34
+ @mouseup="mouseupHandler"
35
+ v-else
36
+ >
33
37
  <div :class="`tmagic-data-source-input-text-wrapper el-input__wrapper ${isFocused ? ' is-focus' : ''}`">
34
- <div class="el-input__inner">
38
+ <div class="el-input__inner t-input__inner">
35
39
  <template v-for="(item, index) in displayState">
36
40
  <span :key="index" v-if="item.type === 'text'" style="margin-right: 2px">{{ item.value }}</span>
37
41
  <TMagicTag :key="index" :size="size" v-if="item.type === 'var'">{{ item.value }}</TMagicTag>
@@ -6,32 +6,44 @@
6
6
  <TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
7
7
  </div>
8
8
 
9
- <MFormDrawer
10
- ref="addDialog"
11
- label-width="120px"
9
+ <FloatingBox
10
+ v-model:visible="addDialogVisible"
11
+ v-model:width="width"
12
+ v-model:height="editorHeight"
12
13
  :title="drawerTitle"
13
- :config="formConfig"
14
- :values="formValues"
15
- :parentValues="model[name]"
16
- :disabled="disabled"
17
- :width="width"
18
- @submit="formChangeHandler"
19
- ></MFormDrawer>
14
+ :position="boxPosition"
15
+ >
16
+ <template #body>
17
+ <MFormBox
18
+ ref="addDialog"
19
+ label-width="120px"
20
+ :config="formConfig"
21
+ :values="formValues"
22
+ :parentValues="model[name]"
23
+ :disabled="disabled"
24
+ @submit="formChangeHandler"
25
+ ></MFormBox>
26
+ </template>
27
+ </FloatingBox>
20
28
  </div>
21
29
  </template>
22
30
 
23
31
  <script setup lang="ts">
24
- import { computed, inject, ref } from 'vue';
32
+ import { inject, Ref, ref } from 'vue';
25
33
 
26
34
  import { TMagicButton, tMagicMessageBox, TMagicSwitch } from '@tmagic/design';
27
- import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
35
+ import { type FieldProps, type FormConfig, type FormState, MFormBox } from '@tmagic/form';
28
36
  import type { MockSchema } from '@tmagic/schema';
29
37
  import { type ColumnConfig, MagicTable } from '@tmagic/table';
30
38
  import { getDefaultValueFromFields } from '@tmagic/utils';
31
39
 
40
+ import FloatingBox from '@editor/components/FloatingBox.vue';
41
+ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
32
42
  import CodeEditor from '@editor/layouts/CodeEditor.vue';
33
43
  import { Services } from '@editor/type';
34
44
 
45
+ import { useEditorContentHeight } from '..';
46
+
35
47
  defineOptions({
36
48
  name: 'MFieldsDataSourceMocks',
37
49
  });
@@ -50,9 +62,8 @@ const props = withDefaults(
50
62
  const emit = defineEmits(['change']);
51
63
 
52
64
  const services = inject<Services>('services');
53
- const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
65
+ const width = defineModel<number>('width', { default: 670 });
54
66
 
55
- const addDialog = ref<InstanceType<typeof MFormDrawer>>();
56
67
  const drawerTitle = ref('');
57
68
  const formValues = ref<Record<string, any>>({});
58
69
 
@@ -182,7 +193,8 @@ const columns: ColumnConfig[] = [
182
193
  index,
183
194
  };
184
195
  drawerTitle.value = `编辑${row.title}`;
185
- addDialog.value?.show();
196
+ calcBoxPosition();
197
+ addDialogVisible.value = true;
186
198
  },
187
199
  },
188
200
  {
@@ -206,7 +218,8 @@ const newHandler = () => {
206
218
  enable: isFirstRow,
207
219
  };
208
220
  drawerTitle.value = '新增Mock';
209
- addDialog.value?.show();
221
+ calcBoxPosition();
222
+ addDialogVisible.value = true;
210
223
  };
211
224
 
212
225
  const formChangeHandler = ({ index, ...value }: Record<string, any>) => {
@@ -216,7 +229,7 @@ const formChangeHandler = ({ index, ...value }: Record<string, any>) => {
216
229
  props.model[props.name].push(value);
217
230
  }
218
231
 
219
- addDialog.value?.hide();
232
+ addDialogVisible.value = false;
220
233
 
221
234
  emit('change', props.model[props.name]);
222
235
  };
@@ -234,4 +247,9 @@ const toggleValue = (row: MockSchema, key: 'enable' | 'useInEditor', value: bool
234
247
  index,
235
248
  });
236
249
  };
250
+
251
+ const addDialogVisible = defineModel<boolean>('visible', { default: false });
252
+ const { height: editorHeight } = useEditorContentHeight();
253
+ const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
254
+ const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(services?.uiService, parentFloating);
237
255
  </script>
@@ -10,7 +10,7 @@ export const useEditorContentHeight = () => {
10
10
 
11
11
  const height = ref(0);
12
12
  watchEffect(() => {
13
- if (height.value > 0) return;
13
+ if (height.value > 0 && height.value === editorContentHeight.value) return;
14
14
  height.value = editorContentHeight.value;
15
15
  });
16
16
 
@@ -1,4 +1,6 @@
1
- import { computed, ComputedRef, ref, watch } from 'vue';
1
+ import { computed, ComputedRef, inject, ref, watch } from 'vue';
2
+
3
+ import type { Services } from '@editor/type';
2
4
 
3
5
  interface State {
4
6
  status: boolean;
@@ -7,6 +9,8 @@ interface State {
7
9
  }
8
10
 
9
11
  export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
12
+ const services = inject<Services>('services');
13
+
10
14
  const floatBoxStates = ref<{
11
15
  [key in (typeof slideKeys.value)[number]]: State;
12
16
  }>(
@@ -30,9 +34,10 @@ export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
30
34
 
31
35
  const dragstartHandler = () => (isDragging.value = true);
32
36
  const dragendHandler = (key: string, e: DragEvent) => {
37
+ const navMenuRect = services?.uiService?.get('navMenuRect');
33
38
  floatBoxStates.value[key] = {
34
39
  left: e.clientX,
35
- top: e.clientY,
40
+ top: (navMenuRect?.top ?? 0) + (navMenuRect?.height ?? 0),
36
41
  status: true,
37
42
  };
38
43
  isDragging.value = false;
@@ -47,12 +52,13 @@ export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
47
52
  () => slideKeys.value,
48
53
  (slideKeys) => {
49
54
  slideKeys.forEach((key) => {
50
- if (floatBoxStates.value[key]) return;
51
- floatBoxStates.value[key] = {
52
- status: false,
53
- top: 0,
54
- left: 0,
55
- };
55
+ if (!floatBoxStates.value[key]) {
56
+ floatBoxStates.value[key] = {
57
+ status: false,
58
+ top: 0,
59
+ left: 0,
60
+ };
61
+ }
56
62
  });
57
63
  },
58
64
  {