@tmagic/editor 1.3.16 → 1.4.0-beta.2

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 (129) hide show
  1. package/dist/style.css +25 -9
  2. package/dist/tmagic-editor.js +1048 -632
  3. package/dist/tmagic-editor.umd.cjs +1065 -647
  4. package/package.json +23 -21
  5. package/src/components/CodeBlockEditor.vue +82 -59
  6. package/src/components/FloatingBox.vue +71 -25
  7. package/src/components/SplitView.vue +46 -35
  8. package/src/fields/Code.vue +12 -10
  9. package/src/fields/CodeLink.vue +9 -9
  10. package/src/fields/CodeSelect.vue +7 -5
  11. package/src/fields/CodeSelectCol.vue +1 -1
  12. package/src/fields/DataSourceFieldSelect.vue +118 -27
  13. package/src/fields/DataSourceFields.vue +10 -3
  14. package/src/fields/DataSourceInput.vue +7 -7
  15. package/src/fields/DataSourceMethodSelect.vue +1 -1
  16. package/src/fields/DataSourceMethods.vue +3 -3
  17. package/src/fields/DataSourceMocks.vue +3 -3
  18. package/src/fields/DataSourceSelect.vue +6 -18
  19. package/src/fields/EventSelect.vue +1 -1
  20. package/src/fields/KeyValue.vue +8 -8
  21. package/src/fields/PageFragmentSelect.vue +1 -1
  22. package/src/fields/UISelect.vue +5 -5
  23. package/src/hooks/index.ts +2 -0
  24. package/src/hooks/use-code-block-edit.ts +1 -2
  25. package/src/hooks/use-editor-content-height.ts +20 -0
  26. package/src/hooks/use-float-box.ts +8 -8
  27. package/src/hooks/use-window-rect.ts +20 -0
  28. package/src/index.ts +2 -2
  29. package/src/layouts/Framework.vue +33 -34
  30. package/src/layouts/NavMenu.vue +21 -2
  31. package/src/layouts/PropsPanel.vue +35 -0
  32. package/src/layouts/sidebar/Sidebar.vue +18 -8
  33. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +0 -1
  34. package/src/layouts/workspace/viewer/NodeListMenu.vue +1 -0
  35. package/src/services/BaseService.ts +5 -2
  36. package/src/services/codeBlock.ts +14 -8
  37. package/src/services/dataSource.ts +39 -26
  38. package/src/services/editor.ts +46 -25
  39. package/src/services/events.ts +4 -4
  40. package/src/services/props.ts +44 -35
  41. package/src/services/stageOverlay.ts +16 -9
  42. package/src/services/storage.ts +14 -8
  43. package/src/services/ui.ts +26 -19
  44. package/src/theme/code-block.scss +0 -5
  45. package/src/theme/code-editor.scss +6 -0
  46. package/src/theme/floating-box.scss +4 -2
  47. package/src/theme/props-panel.scss +14 -0
  48. package/src/theme/sidebar.scss +6 -3
  49. package/src/type.ts +87 -37
  50. package/src/utils/operator.ts +37 -39
  51. package/src/utils/props.ts +174 -37
  52. package/types/components/CodeBlockEditor.vue.d.ts +46 -25
  53. package/types/components/CodeParams.vue.d.ts +5 -5
  54. package/types/components/ContentMenu.vue.d.ts +12 -12
  55. package/types/components/FloatingBox.vue.d.ts +42 -55
  56. package/types/components/Icon.vue.d.ts +3 -3
  57. package/types/components/Resizer.vue.d.ts +3 -3
  58. package/types/components/ScrollBar.vue.d.ts +3 -3
  59. package/types/components/ScrollViewer.vue.d.ts +12 -12
  60. package/types/components/SearchInput.vue.d.ts +1 -1
  61. package/types/components/SplitView.vue.d.ts +13 -11
  62. package/types/components/ToolButton.vue.d.ts +13 -13
  63. package/types/components/Tree.vue.d.ts +24 -14
  64. package/types/components/TreeNode.vue.d.ts +22 -12
  65. package/types/fields/Code.vue.d.ts +14 -14
  66. package/types/fields/CodeLink.vue.d.ts +6 -10
  67. package/types/fields/CodeSelect.vue.d.ts +14 -14
  68. package/types/fields/CodeSelectCol.vue.d.ts +11 -11
  69. package/types/fields/DataSourceFieldSelect.vue.d.ts +11 -11
  70. package/types/fields/DataSourceFields.vue.d.ts +11 -11
  71. package/types/fields/DataSourceInput.vue.d.ts +14 -18
  72. package/types/fields/DataSourceMethodSelect.vue.d.ts +11 -11
  73. package/types/fields/DataSourceMethods.vue.d.ts +11 -11
  74. package/types/fields/DataSourceMocks.vue.d.ts +11 -11
  75. package/types/fields/DataSourceSelect.vue.d.ts +13 -26
  76. package/types/fields/EventSelect.vue.d.ts +3 -3
  77. package/types/fields/KeyValue.vue.d.ts +14 -18
  78. package/types/fields/PageFragmentSelect.vue.d.ts +11 -11
  79. package/types/fields/UISelect.vue.d.ts +8 -4
  80. package/types/hooks/index.d.ts +2 -0
  81. package/types/hooks/use-code-block-edit.d.ts +66 -90
  82. package/types/hooks/use-data-source-method.d.ts +66 -90
  83. package/types/hooks/use-editor-content-height.d.ts +3 -0
  84. package/types/hooks/use-node-status.d.ts +6 -1
  85. package/types/hooks/use-window-rect.d.ts +6 -0
  86. package/types/icons/AppManageIcon.vue.d.ts +1 -1
  87. package/types/icons/CenterIcon.vue.d.ts +1 -1
  88. package/types/icons/CodeIcon.vue.d.ts +1 -1
  89. package/types/icons/FolderMinusIcon.vue.d.ts +1 -1
  90. package/types/icons/PinIcon.vue.d.ts +1 -1
  91. package/types/icons/PinnedIcon.vue.d.ts +1 -1
  92. package/types/layouts/AddPageBox.vue.d.ts +3 -3
  93. package/types/layouts/CodeEditor.vue.d.ts +12 -12
  94. package/types/layouts/Framework.vue.d.ts +9 -9
  95. package/types/layouts/NavMenu.vue.d.ts +11 -11
  96. package/types/layouts/PropsPanel.vue.d.ts +193 -243
  97. package/types/layouts/page-bar/AddButton.vue.d.ts +3 -3
  98. package/types/layouts/page-bar/PageBar.vue.d.ts +8 -8
  99. package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +8 -8
  100. package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +3 -3
  101. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
  102. package/types/layouts/sidebar/Sidebar.vue.d.ts +13 -13
  103. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +10 -10
  104. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +9 -9
  105. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -3
  106. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +3 -3
  107. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +9 -9
  108. package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +11 -11
  109. package/types/layouts/sidebar/layer/LayerNodeTool.vue.d.ts +3 -3
  110. package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +9 -9
  111. package/types/layouts/sidebar/layer/use-click.d.ts +42 -76
  112. package/types/layouts/sidebar/layer/use-node-status.d.ts +6 -1
  113. package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -1
  114. package/types/layouts/workspace/Workspace.vue.d.ts +12 -12
  115. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -1
  116. package/types/layouts/workspace/viewer/Stage.vue.d.ts +11 -11
  117. package/types/layouts/workspace/viewer/StageOverlay.vue.d.ts +1 -1
  118. package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +12 -12
  119. package/types/services/BaseService.d.ts +5 -2
  120. package/types/services/codeBlock.d.ts +8 -0
  121. package/types/services/dataSource.d.ts +9 -2
  122. package/types/services/editor.d.ts +8 -1
  123. package/types/services/props.d.ts +15 -22
  124. package/types/services/stageOverlay.d.ts +9 -2
  125. package/types/services/storage.d.ts +8 -0
  126. package/types/services/ui.d.ts +20 -8
  127. package/types/type.d.ts +56 -32
  128. package/types/utils/operator.d.ts +1 -1
  129. package/types/utils/props.d.ts +2 -13
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.16",
2
+ "version": "1.4.0-beta.2",
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.3.16",
46
- "@tmagic/dep": "1.3.16",
47
- "@tmagic/design": "1.3.16",
48
- "@tmagic/form": "1.3.16",
49
- "@tmagic/schema": "1.3.16",
50
- "@tmagic/stage": "1.3.16",
51
- "@tmagic/table": "1.3.16",
52
- "@tmagic/utils": "1.3.16",
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",
53
53
  "buffer": "^6.0.3",
54
54
  "color": "^3.1.3",
55
55
  "emmet-monaco-es": "^5.3.0",
@@ -57,16 +57,16 @@
57
57
  "gesto": "^1.19.1",
58
58
  "keycon": "^1.4.0",
59
59
  "lodash-es": "^4.17.21",
60
- "monaco-editor": "^0.41.0",
60
+ "monaco-editor": "^0.47.0",
61
61
  "moveable": "^0.51.1",
62
62
  "serialize-javascript": "^6.0.0",
63
- "vue": "^3.3.8"
63
+ "vue": "^3.4.21"
64
64
  },
65
65
  "peerDependencies": {
66
- "@tmagic/design": "1.3.16",
67
- "@tmagic/form": "1.3.16",
68
- "monaco-editor": "^0.41.0",
69
- "vue": "^3.3.8"
66
+ "@tmagic/design": "1.4.0-beta.2",
67
+ "@tmagic/form": "1.4.0-beta.2",
68
+ "monaco-editor": "^0.47.0",
69
+ "vue": "^3.4.21"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/events": "^3.0.0",
@@ -74,18 +74,20 @@
74
74
  "@types/node": "^18.19.0",
75
75
  "@types/serialize-javascript": "^5.0.1",
76
76
  "@vitejs/plugin-vue": "^4.5.2",
77
- "@vue/compiler-sfc": "^3.3.8",
78
- "@vue/test-utils": "^2.3.2",
77
+ "@vue/compiler-sfc": "^3.4.21",
78
+ "@vue/test-utils": "^2.4.4",
79
79
  "rimraf": "^3.0.2",
80
80
  "sass": "^1.35.1",
81
81
  "tsc-alias": "^1.8.5",
82
- "typescript": "^5.0.4",
83
- "vite": "^5.0.7",
84
- "vue-tsc": "^1.8.25"
82
+ "type-fest": "^4.10.3",
83
+ "typescript": "^5.4.2",
84
+ "vite": "^5.1.6",
85
+ "vue-tsc": "^2.0.6"
85
86
  },
86
87
  "scripts": {
87
88
  "build": "npm run build:type && vite build",
88
89
  "build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
89
- "clear:type": "rimraf ./types"
90
+ "clear:type": "rimraf ./types",
91
+ "type:check": "vue-tsc --noEmit"
90
92
  }
91
93
  }
@@ -1,26 +1,39 @@
1
1
  <template>
2
- <component
3
- :is="slideType === 'box' ? MFormBox : MFormDrawer"
4
- class="m-editor-code-block-editor"
5
- ref="fomDrawer"
6
- label-width="80px"
7
- :close-on-press-escape="false"
8
- :title="content.name"
9
- :width="size"
10
- :config="functionConfig"
11
- :values="content"
12
- :disabled="disabled"
2
+ <!-- 代码块编辑区 -->
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"
13
9
  :before-close="beforeClose"
14
- @change="changeHandler"
15
- @submit="submitForm"
16
- @error="errorHandler"
17
- @open="openHandler"
18
- @closed="closedHandler"
19
10
  >
20
- <template #left>
21
- <TMagicButton type="primary" link @click="difVisible = true">查看修改</TMagicButton>
11
+ <template #body>
12
+ <div ref="floatingBoxBody" style="height: 100%"></div>
22
13
  </template>
23
- </component>
14
+ </FloatingBox>
15
+
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
+ </template>
35
+ </MFormBox>
36
+ </Teleport>
24
37
 
25
38
  <TMagicDialog v-model="difVisible" title="查看修改" fullscreen>
26
39
  <div style="display: flex; margin-bottom: 10px">
@@ -34,8 +47,8 @@
34
47
  type="diff"
35
48
  language="json"
36
49
  :initValues="content.content"
37
- :modifiedValues="fomDrawer?.form?.values.content"
38
- :style="`height: ${height - 200}px`"
50
+ :modifiedValues="formBox?.form?.values.content"
51
+ :style="`height: ${windowRect.height - 150}px`"
39
52
  ></CodeEditor>
40
53
 
41
54
  <template #footer>
@@ -48,12 +61,15 @@
48
61
  </template>
49
62
 
50
63
  <script lang="ts" setup>
51
- import { computed, inject, onBeforeUnmount, ref } from 'vue';
64
+ import { computed, inject, nextTick, ref } from 'vue';
52
65
 
53
66
  import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
54
- import { ColumnConfig, FormConfig, FormState, MFormBox, MFormDrawer } from '@tmagic/form';
67
+ import { ColumnConfig, FormConfig, FormState, MFormBox } from '@tmagic/form';
55
68
  import type { CodeBlockContent } from '@tmagic/schema';
56
69
 
70
+ import FloatingBox from '@editor/components/FloatingBox.vue';
71
+ import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
72
+ import { useWindowRect } from '@editor/hooks/use-window-rect';
57
73
  import CodeEditor from '@editor/layouts/CodeEditor.vue';
58
74
  import type { Services, SlideType } from '@editor/type';
59
75
  import { getConfig } from '@editor/utils/config';
@@ -62,6 +78,9 @@ defineOptions({
62
78
  name: 'MEditorCodeBlockEditor',
63
79
  });
64
80
 
81
+ const width = defineModel<number>('width', { default: 670 });
82
+ const boxVisible = defineModel<boolean>('visible', { default: false });
83
+
65
84
  const props = defineProps<{
66
85
  content: CodeBlockContent;
67
86
  disabled?: boolean;
@@ -76,38 +95,23 @@ const emit = defineEmits<{
76
95
 
77
96
  const services = inject<Services>('services');
78
97
 
79
- const difVisible = ref(false);
80
- const height = ref(globalThis.innerHeight);
81
-
82
- const windowReizehandler = () => {
83
- height.value = globalThis.innerHeight;
84
- };
85
-
86
- globalThis.addEventListener('resize', windowReizehandler);
98
+ const { height: codeBlockEditorHeight } = useEditorContentHeight();
87
99
 
88
- onBeforeUnmount(() => {
89
- globalThis.removeEventListener('resize', windowReizehandler);
90
- });
100
+ const difVisible = ref(false);
101
+ const { rect: windowRect } = useWindowRect();
91
102
 
92
103
  const magicVsEditor = ref<InstanceType<typeof CodeEditor>>();
93
104
 
94
105
  const diffChange = () => {
95
- if (!magicVsEditor.value || !fomDrawer.value?.form) {
106
+ if (!magicVsEditor.value || !formBox.value?.form) {
96
107
  return;
97
108
  }
98
109
 
99
- fomDrawer.value.form.values.content = magicVsEditor.value.getEditorValue();
110
+ formBox.value.form.values.content = magicVsEditor.value.getEditorValue();
100
111
 
101
112
  difVisible.value = false;
102
113
  };
103
114
 
104
- const columnWidth = computed(() => services?.uiService.get('columnWidth'));
105
- const size = computed(() =>
106
- columnWidth.value ? columnWidth.value.center + columnWidth.value.right - (props.isDataSource ? 100 : 0) : 600,
107
- );
108
-
109
- const codeEditorHeight = ref('600px');
110
-
111
115
  const defaultParamColConfig: ColumnConfig = {
112
116
  type: 'row',
113
117
  label: '参数类型',
@@ -191,7 +195,7 @@ const functionConfig = computed<FormConfig>(() => [
191
195
  name: 'content',
192
196
  type: 'vs-code',
193
197
  options: inject('codeOptions', {}),
194
- height: codeEditorHeight.value,
198
+ height: '500px',
195
199
  onChange: (formState: FormState | undefined, code: string) => {
196
200
  try {
197
201
  // 检测js代码是否存在语法错误
@@ -208,6 +212,7 @@ const functionConfig = computed<FormConfig>(() => [
208
212
  ]);
209
213
 
210
214
  const submitForm = (values: CodeBlockContent) => {
215
+ changedValue.value = undefined;
211
216
  emit('submit', values);
212
217
  };
213
218
 
@@ -215,16 +220,7 @@ const errorHandler = (error: any) => {
215
220
  tMagicMessage.error(error.message);
216
221
  };
217
222
 
218
- const fomDrawer = ref<InstanceType<typeof MFormDrawer>>();
219
-
220
- const openHandler = () => {
221
- setTimeout(() => {
222
- if (fomDrawer.value) {
223
- const height = fomDrawer.value?.bodyHeight - 348 - (props.isDataSource ? 50 : 0);
224
- codeEditorHeight.value = `${height > 100 ? height : 600}px`;
225
- }
226
- });
227
- };
223
+ const formBox = ref<InstanceType<typeof MFormBox>>();
228
224
 
229
225
  const changedValue = ref<CodeBlockContent>();
230
226
  const changeHandler = (values: CodeBlockContent) => {
@@ -233,6 +229,7 @@ const changeHandler = (values: CodeBlockContent) => {
233
229
 
234
230
  const beforeClose = (done: (cancel?: boolean) => void) => {
235
231
  if (!changedValue.value) {
232
+ editVisible.value = false;
236
233
  done();
237
234
  return;
238
235
  }
@@ -245,10 +242,14 @@ const beforeClose = (done: (cancel?: boolean) => void) => {
245
242
  })
246
243
  .then(() => {
247
244
  changedValue.value && submitForm(changedValue.value);
245
+ editVisible.value = false;
248
246
  done();
249
247
  })
250
248
  .catch((action: string) => {
251
- done(action === 'close');
249
+ if (action === 'cancel') {
250
+ editVisible.value = false;
251
+ }
252
+ done(action === 'cancel');
252
253
  });
253
254
  };
254
255
 
@@ -256,13 +257,35 @@ const closedHandler = () => {
256
257
  changedValue.value = undefined;
257
258
  };
258
259
 
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
+ });
271
+
259
272
  defineExpose({
260
- show() {
261
- fomDrawer.value?.show();
273
+ async show() {
274
+ if (props.slideType !== 'box') {
275
+ boxVisible.value = true;
276
+ await nextTick();
277
+ }
278
+
279
+ editVisible.value = true;
262
280
  },
263
281
 
264
- hide() {
265
- fomDrawer.value?.hide();
282
+ async hide() {
283
+ editVisible.value = false;
284
+
285
+ if (props.slideType !== 'box') {
286
+ await nextTick();
287
+ boxVisible.value = false;
288
+ }
266
289
  },
267
290
  });
268
291
  </script>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <Teleport to="body" v-if="visible">
3
- <div ref="target" class="m-editor-float-box" :style="style">
4
- <div ref="dragTarget" class="m-editor-float-box-title">
3
+ <div ref="target" class="m-editor-float-box" :style="{ ...style, zIndex: curZIndex }" @mousedown="nextZIndex">
4
+ <div ref="titleEl" class="m-editor-float-box-title">
5
5
  <slot name="title">
6
6
  <span>{{ title }}</span>
7
7
  </slot>
@@ -9,7 +9,7 @@
9
9
  <TMagicButton link size="small" :icon="Close" @click="closeHandler"></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>
@@ -21,37 +21,53 @@ import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';
21
21
  import { Close } from '@element-plus/icons-vue';
22
22
  import VanillaMoveable from 'moveable';
23
23
 
24
- import { TMagicButton } from '@tmagic/design';
24
+ import { TMagicButton, useZIndex } from '@tmagic/design';
25
25
 
26
26
  interface Position {
27
27
  left: number;
28
28
  top: number;
29
29
  }
30
30
 
31
- interface Rect {
32
- width: number | string;
33
- height: number | string;
34
- }
35
-
36
- const props = withDefaults(defineProps<{ visible: boolean; position?: Position; rect?: Rect; title?: string }>(), {
37
- visible: false,
38
- title: '',
39
- position: () => ({ left: 0, top: 0 }),
40
- rect: () => ({ width: 'auto', height: 'auto' }),
41
- });
31
+ const width = defineModel<number>('width', { default: 0 });
32
+ const height = defineModel<number>('height', { default: 0 });
33
+ const visible = defineModel<boolean>('visible', { default: false });
42
34
 
43
- const emit = defineEmits<{
44
- 'update:visible': [boolean];
45
- }>();
35
+ const props = withDefaults(
36
+ defineProps<{
37
+ position?: Position;
38
+ title?: string;
39
+ beforeClose?: (done: (cancel?: boolean) => void) => void;
40
+ }>(),
41
+ {
42
+ title: '',
43
+ position: () => ({ left: 0, top: 0 }),
44
+ },
45
+ );
46
46
 
47
47
  const target = ref<HTMLDivElement>();
48
- const dragTarget = ref<HTMLDivElement>();
48
+ const titleEl = ref<HTMLDivElement>();
49
+
50
+ const zIndex = useZIndex();
51
+ const curZIndex = ref<number>(zIndex.nextZIndex());
52
+
53
+ const titleHeight = ref(0);
54
+ const bodyHeight = computed(() => {
55
+ if (height.value) {
56
+ return height.value - titleHeight.value;
57
+ }
58
+
59
+ if (target.value) {
60
+ return target.value.clientHeight - titleHeight.value;
61
+ }
62
+
63
+ return 'auto';
64
+ });
49
65
 
50
66
  const style = computed(() => ({
51
67
  left: `${props.position.left}px`,
52
68
  top: `${props.position.top}px`,
53
- width: typeof props.rect.width === 'string' ? props.rect.width : `${props.rect.width}px`,
54
- height: typeof props.rect.height === 'string' ? props.rect.height : `${props.rect.height}px`,
69
+ width: width.value ? `${width.value}px` : 'auto',
70
+ height: height.value ? `${height.value}px` : 'auto',
55
71
  }));
56
72
 
57
73
  let moveable: VanillaMoveable | null = null;
@@ -66,10 +82,11 @@ const initMoveable = () => {
66
82
  keepRatio: false,
67
83
  origin: false,
68
84
  snappable: true,
69
- dragTarget: dragTarget.value,
85
+ dragTarget: titleEl.value,
70
86
  dragTargetSelf: false,
71
87
  linePadding: 10,
72
88
  controlPadding: 10,
89
+ bounds: { left: 0, top: 0, right: 0, bottom: 0, position: 'css' },
73
90
  });
74
91
 
75
92
  moveable.on('drag', (e) => {
@@ -77,6 +94,8 @@ const initMoveable = () => {
77
94
  });
78
95
 
79
96
  moveable.on('resize', (e) => {
97
+ width.value = e.width;
98
+ height.value = e.height;
80
99
  e.target.style.width = `${e.width}px`;
81
100
  e.target.style.height = `${e.height}px`;
82
101
  e.target.style.transform = e.drag.transform;
@@ -89,11 +108,22 @@ const destroyMoveable = () => {
89
108
  };
90
109
 
91
110
  watch(
92
- () => props.visible,
111
+ visible,
93
112
  async (visible) => {
94
113
  if (visible) {
95
114
  await nextTick();
96
- initMoveable();
115
+
116
+ const targetRect = target.value?.getBoundingClientRect();
117
+ if (targetRect) {
118
+ width.value = targetRect.width;
119
+ height.value = targetRect.height;
120
+ initMoveable();
121
+ }
122
+
123
+ if (titleEl.value) {
124
+ const titleRect = titleEl.value.getBoundingClientRect();
125
+ titleHeight.value = titleRect.height;
126
+ }
97
127
  } else {
98
128
  destroyMoveable();
99
129
  }
@@ -107,11 +137,27 @@ onBeforeUnmount(() => {
107
137
  destroyMoveable();
108
138
  });
109
139
 
140
+ const hide = (cancel?: boolean) => {
141
+ if (cancel !== false) {
142
+ visible.value = false;
143
+ }
144
+ };
145
+
110
146
  const closeHandler = () => {
111
- emit('update:visible', false);
147
+ if (typeof props.beforeClose === 'function') {
148
+ props.beforeClose(hide);
149
+ } else {
150
+ hide();
151
+ }
152
+ };
153
+
154
+ const nextZIndex = () => {
155
+ curZIndex.value = zIndex.nextZIndex();
112
156
  };
113
157
 
114
158
  defineExpose({
159
+ bodyHeight,
115
160
  target,
161
+ titleEl,
116
162
  });
117
163
  </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,
@@ -13,12 +13,12 @@
13
13
  </template>
14
14
 
15
15
  <script lang="ts" setup>
16
- import type { FieldProps } from '@tmagic/form';
16
+ import type { FieldProps, FormItem } from '@tmagic/form';
17
17
 
18
18
  import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';
19
19
 
20
20
  defineOptions({
21
- name: 'MEditorCode',
21
+ name: 'MFieldsVsCode',
22
22
  });
23
23
 
24
24
  const emit = defineEmits<{
@@ -27,14 +27,16 @@ const emit = defineEmits<{
27
27
 
28
28
  const props = withDefaults(
29
29
  defineProps<
30
- FieldProps<{
31
- language?: string;
32
- options?: {
33
- [key: string]: any;
34
- };
35
- height?: string;
36
- parse?: boolean;
37
- }>
30
+ FieldProps<
31
+ {
32
+ language?: string;
33
+ options?: {
34
+ [key: string]: any;
35
+ };
36
+ height?: string;
37
+ parse?: boolean;
38
+ } & FormItem
39
+ >
38
40
  >(),
39
41
  {
40
42
  disabled: false,