@tmagic/editor 1.3.5 → 1.3.7

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 (142) hide show
  1. package/LICENSE +5432 -0
  2. package/dist/style.css +88 -62
  3. package/dist/tmagic-editor.js +2448 -2016
  4. package/dist/tmagic-editor.js.map +1 -1
  5. package/dist/tmagic-editor.umd.cjs +2453 -2019
  6. package/dist/tmagic-editor.umd.cjs.map +1 -1
  7. package/package.json +23 -23
  8. package/src/Editor.vue +15 -7
  9. package/src/components/CodeBlockEditor.vue +2 -2
  10. package/src/components/ContentMenu.vue +5 -5
  11. package/src/components/FloatingBox.vue +117 -0
  12. package/src/components/ScrollBar.vue +2 -2
  13. package/src/components/ScrollViewer.vue +2 -2
  14. package/src/components/SplitView.vue +2 -2
  15. package/src/components/Tree.vue +5 -0
  16. package/src/components/TreeNode.vue +10 -4
  17. package/src/editorProps.ts +20 -3
  18. package/src/fields/PageFragmentSelect.vue +55 -0
  19. package/src/hooks/use-filter.ts +55 -0
  20. package/src/hooks/use-getso.ts +2 -2
  21. package/src/hooks/use-node-status.ts +48 -0
  22. package/src/hooks/use-stage.ts +19 -1
  23. package/src/index.ts +3 -0
  24. package/src/initService.ts +43 -17
  25. package/src/layouts/AddPageBox.vue +16 -4
  26. package/src/layouts/CodeEditor.vue +2 -2
  27. package/src/layouts/Framework.vue +17 -3
  28. package/src/layouts/PropsPanel.vue +2 -2
  29. package/src/layouts/page-bar/AddButton.vue +48 -0
  30. package/src/layouts/page-bar/PageBar.vue +158 -0
  31. package/src/layouts/{workspace → page-bar}/PageBarScrollContainer.vue +61 -35
  32. package/src/layouts/page-bar/SwitchTypeButton.vue +45 -0
  33. package/src/layouts/sidebar/Sidebar.vue +9 -2
  34. package/src/layouts/sidebar/code-block/CodeBlockList.vue +55 -65
  35. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +2 -1
  36. package/src/layouts/sidebar/data-source/DataSourceList.vue +63 -59
  37. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
  38. package/src/layouts/sidebar/layer/LayerMenu.vue +39 -27
  39. package/src/layouts/sidebar/layer/LayerPanel.vue +31 -8
  40. package/src/layouts/sidebar/layer/use-click.ts +5 -3
  41. package/src/layouts/sidebar/layer/use-keybinding.ts +8 -8
  42. package/src/layouts/sidebar/layer/use-node-status.ts +10 -13
  43. package/src/layouts/workspace/Workspace.vue +6 -7
  44. package/src/layouts/workspace/viewer/NodeListMenu.vue +68 -129
  45. package/src/layouts/workspace/viewer/Stage.vue +14 -6
  46. package/src/layouts/workspace/viewer/ViewerMenu.vue +94 -86
  47. package/src/services/BaseService.ts +63 -26
  48. package/src/services/codeBlock.ts +7 -1
  49. package/src/services/dep.ts +12 -8
  50. package/src/services/editor.ts +131 -64
  51. package/src/services/history.ts +6 -2
  52. package/src/services/keybinding.ts +48 -13
  53. package/src/services/props.ts +70 -12
  54. package/src/services/storage.ts +23 -13
  55. package/src/services/ui.ts +4 -1
  56. package/src/theme/code-block.scss +0 -16
  57. package/src/theme/floating-box.scss +30 -0
  58. package/src/theme/layer-panel.scss +19 -0
  59. package/src/theme/page-bar.scss +18 -1
  60. package/src/theme/stage.scss +24 -0
  61. package/src/theme/theme.scss +1 -1
  62. package/src/theme/tree.scss +12 -1
  63. package/src/type.ts +28 -10
  64. package/src/utils/compose.ts +25 -6
  65. package/src/utils/content-menu.ts +6 -7
  66. package/src/utils/editor.ts +34 -18
  67. package/src/utils/operator.ts +5 -6
  68. package/types/components/CodeBlockEditor.vue.d.ts +6 -2
  69. package/types/components/CodeParams.vue.d.ts +3 -1
  70. package/types/components/ContentMenu.vue.d.ts +13 -5
  71. package/types/components/FloatingBox.vue.d.ts +78 -0
  72. package/types/components/Resizer.vue.d.ts +6 -1
  73. package/types/components/ScrollBar.vue.d.ts +3 -1
  74. package/types/components/ScrollViewer.vue.d.ts +3 -3
  75. package/types/components/SearchInput.vue.d.ts +3 -1
  76. package/types/components/SplitView.vue.d.ts +8 -4
  77. package/types/components/ToolButton.vue.d.ts +3 -3
  78. package/types/components/Tree.vue.d.ts +27 -8
  79. package/types/components/TreeNode.vue.d.ts +24 -7
  80. package/types/editorProps.d.ts +16 -1
  81. package/types/fields/Code.vue.d.ts +6 -2
  82. package/types/fields/CodeLink.vue.d.ts +5 -3
  83. package/types/fields/CodeSelect.vue.d.ts +3 -1
  84. package/types/fields/CodeSelectCol.vue.d.ts +3 -1
  85. package/types/fields/DataSourceFieldSelect.vue.d.ts +3 -1
  86. package/types/fields/DataSourceFields.vue.d.ts +5 -3
  87. package/types/fields/DataSourceInput.vue.d.ts +8 -4
  88. package/types/fields/DataSourceMethodSelect.vue.d.ts +3 -1
  89. package/types/fields/DataSourceMethods.vue.d.ts +5 -3
  90. package/types/fields/DataSourceMocks.vue.d.ts +5 -3
  91. package/types/fields/DataSourceSelect.vue.d.ts +5 -3
  92. package/types/fields/EventSelect.vue.d.ts +3 -1
  93. package/types/fields/KeyValue.vue.d.ts +2 -2
  94. package/types/fields/PageFragmentSelect.vue.d.ts +31 -0
  95. package/types/fields/UISelect.vue.d.ts +3 -1
  96. package/types/hooks/use-code-block-edit.d.ts +14 -5
  97. package/types/hooks/use-data-source-method.d.ts +14 -5
  98. package/types/hooks/use-filter.d.ts +7 -0
  99. package/types/hooks/use-node-status.d.ts +6 -0
  100. package/types/index.d.ts +1 -0
  101. package/types/layouts/AddPageBox.vue.d.ts +14 -1
  102. package/types/layouts/CodeEditor.vue.d.ts +4 -1
  103. package/types/layouts/Framework.vue.d.ts +14 -1
  104. package/types/layouts/PropsPanel.vue.d.ts +19 -13
  105. package/types/layouts/{workspace/viewer/NodeListMenuTitle.vue.d.ts → page-bar/AddButton.vue.d.ts} +3 -2
  106. package/types/layouts/page-bar/PageBar.vue.d.ts +28 -0
  107. package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +24 -0
  108. package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +20 -0
  109. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
  110. package/types/layouts/sidebar/Sidebar.vue.d.ts +7 -5
  111. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +9 -3
  112. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -1
  113. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  114. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +8 -2
  115. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -1
  116. package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +26 -3
  117. package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +3 -1
  118. package/types/layouts/sidebar/layer/use-click.d.ts +37 -6
  119. package/types/layouts/sidebar/layer/use-keybinding.d.ts +1 -1
  120. package/types/layouts/sidebar/layer/use-node-status.d.ts +3 -4
  121. package/types/layouts/workspace/Workspace.vue.d.ts +3 -1
  122. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -14
  123. package/types/layouts/workspace/viewer/Stage.vue.d.ts +2 -0
  124. package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +9 -1
  125. package/types/services/BaseService.d.ts +4 -1
  126. package/types/services/dataSource.d.ts +1 -0
  127. package/types/services/dep.d.ts +6 -5
  128. package/types/services/editor.d.ts +12 -5
  129. package/types/services/history.d.ts +3 -2
  130. package/types/services/keybinding.d.ts +21 -1
  131. package/types/services/props.d.ts +25 -1
  132. package/types/services/storage.d.ts +7 -7
  133. package/types/type.d.ts +32 -17
  134. package/types/utils/compose.d.ts +1 -1
  135. package/types/utils/editor.d.ts +14 -8
  136. package/src/layouts/sidebar/layer/use-filter.ts +0 -59
  137. package/src/layouts/workspace/PageBar.vue +0 -87
  138. package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +0 -68
  139. package/src/theme/dep-list.scss +0 -59
  140. package/types/layouts/sidebar/layer/use-filter.d.ts +0 -7
  141. package/types/layouts/workspace/PageBar.vue.d.ts +0 -15
  142. package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +0 -9
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.5",
2
+ "version": "1.3.7",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -23,13 +23,8 @@
23
23
  "./*": "./*"
24
24
  },
25
25
  "license": "Apache-2.0",
26
- "scripts": {
27
- "build": "npm run build:type && vite build",
28
- "build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
29
- "clear:type": "rimraf ./types"
30
- },
31
26
  "engines": {
32
- "node": ">=14"
27
+ "node": ">=18"
33
28
  },
34
29
  "repository": {
35
30
  "type": "git",
@@ -46,15 +41,15 @@
46
41
  ],
47
42
  "dependencies": {
48
43
  "@babel/core": "^7.18.0",
49
- "@element-plus/icons-vue": "^2.0.9",
50
- "@tmagic/core": "1.3.5",
51
- "@tmagic/dep": "1.3.5",
52
- "@tmagic/design": "1.3.5",
53
- "@tmagic/form": "1.3.5",
54
- "@tmagic/schema": "1.3.5",
55
- "@tmagic/stage": "1.3.5",
56
- "@tmagic/table": "1.3.5",
57
- "@tmagic/utils": "1.3.5",
44
+ "@element-plus/icons-vue": "^2.3.1",
45
+ "@tmagic/core": "1.3.7",
46
+ "@tmagic/dep": "1.3.7",
47
+ "@tmagic/design": "1.3.7",
48
+ "@tmagic/form": "1.3.7",
49
+ "@tmagic/schema": "1.3.7",
50
+ "@tmagic/stage": "1.3.7",
51
+ "@tmagic/table": "1.3.7",
52
+ "@tmagic/utils": "1.3.7",
58
53
  "buffer": "^6.0.3",
59
54
  "color": "^3.1.3",
60
55
  "events": "^3.3.0",
@@ -67,24 +62,29 @@
67
62
  "vue": "^3.3.8"
68
63
  },
69
64
  "peerDependencies": {
70
- "@tmagic/design": "1.3.5",
71
- "@tmagic/form": "1.3.5",
65
+ "@tmagic/design": "1.3.7",
66
+ "@tmagic/form": "1.3.7",
72
67
  "monaco-editor": "^0.41.0",
73
68
  "vue": "^3.3.8"
74
69
  },
75
70
  "devDependencies": {
76
71
  "@types/events": "^3.0.0",
77
72
  "@types/lodash-es": "^4.17.4",
78
- "@types/node": "^15.12.4",
73
+ "@types/node": "^18.19.0",
79
74
  "@types/serialize-javascript": "^5.0.1",
80
- "@vitejs/plugin-vue": "^4.2.3",
75
+ "@vitejs/plugin-vue": "^4.5.2",
81
76
  "@vue/compiler-sfc": "^3.3.8",
82
77
  "@vue/test-utils": "^2.3.2",
83
78
  "rimraf": "^3.0.2",
84
79
  "sass": "^1.35.1",
85
80
  "tsc-alias": "^1.8.5",
86
81
  "typescript": "^5.0.4",
87
- "vite": "^4.4.4",
88
- "vue-tsc": "^1.6.5"
82
+ "vite": "^5.0.7",
83
+ "vue-tsc": "^1.8.25"
84
+ },
85
+ "scripts": {
86
+ "build": "npm run build:type && vite build",
87
+ "build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
88
+ "clear:type": "rimraf ./types"
89
89
  }
90
- }
90
+ }
package/src/Editor.vue CHANGED
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Framework>
2
+ <Framework :disabled-page-fragment="disabledPageFragment">
3
3
  <template #header>
4
4
  <slot name="header"></slot>
5
5
  </template>
@@ -16,7 +16,7 @@
16
16
 
17
17
  <template #sidebar>
18
18
  <slot name="sidebar" :editorService="editorService">
19
- <Sidebar :data="sidebar" :layer-content-menu="layerContentMenu">
19
+ <Sidebar :data="sidebar" :layer-content-menu="layerContentMenu" :custom-content-menu="customContentMenu">
20
20
  <template #layer-panel-header>
21
21
  <slot name="layer-panel-header"></slot>
22
22
  </template>
@@ -25,6 +25,10 @@
25
25
  <slot name="layer-node-content" :data="data"></slot>
26
26
  </template>
27
27
 
28
+ <template #layer-node-label="{ data }">
29
+ <slot name="layer-node-label" :data="data"></slot>
30
+ </template>
31
+
28
32
  <template #layer-node-tool="{ data }">
29
33
  <slot name="layer-node-tool" :data="data"></slot>
30
34
  </template>
@@ -54,11 +58,9 @@
54
58
 
55
59
  <template #workspace>
56
60
  <slot name="workspace" :editorService="editorService">
57
- <Workspace :stage-content-menu="stageContentMenu">
61
+ <Workspace :stage-content-menu="stageContentMenu" :custom-content-menu="customContentMenu">
58
62
  <template #stage><slot name="stage"></slot></template>
59
63
  <template #workspace-content><slot name="workspace-content" :editorService="editorService"></slot></template>
60
- <template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
61
- <template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
62
64
  </Workspace>
63
65
  </slot>
64
66
  </template>
@@ -85,6 +87,9 @@
85
87
  <template #footer>
86
88
  <slot name="footer"></slot>
87
89
  </template>
90
+
91
+ <template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
92
+ <template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
88
93
  </Framework>
89
94
  </template>
90
95
 
@@ -151,8 +156,8 @@ const services: Services = {
151
156
 
152
157
  initServiceEvents(props, emit, services);
153
158
  initServiceState(props, services);
154
- keybindingService.registe(keybindingConfig);
155
- keybindingService.registeEl('global');
159
+ keybindingService.register(keybindingConfig);
160
+ keybindingService.registerEl('global');
156
161
 
157
162
  provide('services', services);
158
163
 
@@ -171,6 +176,9 @@ provide(
171
176
  containerHighlightDuration: props.containerHighlightDuration,
172
177
  containerHighlightType: props.containerHighlightType,
173
178
  disabledDragStart: props.disabledDragStart,
179
+ renderType: props.renderType,
180
+ guidesOptions: props.guidesOptions,
181
+ disabledMultiSelect: props.disabledMultiSelect,
174
182
  }),
175
183
  );
176
184
 
@@ -48,7 +48,7 @@
48
48
  </template>
49
49
 
50
50
  <script lang="ts" setup>
51
- import { computed, inject, onUnmounted, ref } from 'vue';
51
+ import { computed, inject, onBeforeUnmount, ref } from 'vue';
52
52
 
53
53
  import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
54
54
  import { ColumnConfig, FormConfig, FormState, MFormBox, MFormDrawer } from '@tmagic/form';
@@ -85,7 +85,7 @@ const windowReizehandler = () => {
85
85
 
86
86
  globalThis.addEventListener('resize', windowReizehandler);
87
87
 
88
- onUnmounted(() => {
88
+ onBeforeUnmount(() => {
89
89
  globalThis.removeEventListener('resize', windowReizehandler);
90
90
  });
91
91
 
@@ -36,7 +36,7 @@
36
36
  </template>
37
37
 
38
38
  <script lang="ts" setup>
39
- import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue';
39
+ import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
40
40
 
41
41
  import { MenuButton, MenuComponent } from '@editor/type';
42
42
 
@@ -99,7 +99,7 @@ const clickHandler = () => {
99
99
  hide();
100
100
  };
101
101
 
102
- const outsideClickhideHandler = (e: MouseEvent) => {
102
+ const outsideClickHideHandler = (e: MouseEvent) => {
103
103
  if (!props.autoHide) return;
104
104
 
105
105
  const target = e.target as HTMLElement | undefined;
@@ -173,13 +173,13 @@ const mouseenterHandler = () => {
173
173
  onMounted(() => {
174
174
  if (props.isSubMenu) return;
175
175
 
176
- globalThis.addEventListener('mousedown', outsideClickhideHandler, true);
176
+ globalThis.addEventListener('mousedown', outsideClickHideHandler, true);
177
177
  });
178
178
 
179
- onUnmounted(() => {
179
+ onBeforeUnmount(() => {
180
180
  if (props.isSubMenu) return;
181
181
 
182
- globalThis.removeEventListener('mousedown', outsideClickhideHandler, true);
182
+ globalThis.removeEventListener('mousedown', outsideClickHideHandler, true);
183
183
  });
184
184
 
185
185
  defineExpose({
@@ -0,0 +1,117 @@
1
+ <template>
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">
5
+ <slot name="title">
6
+ <span>{{ title }}</span>
7
+ </slot>
8
+ <div>
9
+ <TMagicButton text size="small" :icon="Close" @click="closeHandler"></TMagicButton>
10
+ </div>
11
+ </div>
12
+ <div class="m-editor-float-box-body">
13
+ <slot name="body"></slot>
14
+ </div>
15
+ </div>
16
+ </Teleport>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';
21
+ import { Close } from '@element-plus/icons-vue';
22
+ import VanillaMoveable from 'moveable';
23
+
24
+ import { TMagicButton } from '@tmagic/design';
25
+
26
+ interface Position {
27
+ left: number;
28
+ top: number;
29
+ }
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
+ });
42
+
43
+ const emit = defineEmits<{
44
+ 'update:visible': [boolean];
45
+ }>();
46
+
47
+ const target = ref<HTMLDivElement>();
48
+ const dragTarget = ref<HTMLDivElement>();
49
+
50
+ const style = computed(() => ({
51
+ left: `${props.position.left}px`,
52
+ 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`,
55
+ }));
56
+
57
+ let moveable: VanillaMoveable | null = null;
58
+
59
+ const initMoveable = () => {
60
+ moveable = new VanillaMoveable(globalThis.document.body, {
61
+ className: 'm-editor-floating-box-moveable',
62
+ target: target.value,
63
+ draggable: true,
64
+ resizable: true,
65
+ edge: true,
66
+ keepRatio: false,
67
+ origin: false,
68
+ snappable: true,
69
+ dragTarget: dragTarget.value,
70
+ dragTargetSelf: false,
71
+ linePadding: 10,
72
+ controlPadding: 10,
73
+ });
74
+
75
+ moveable.on('drag', (e) => {
76
+ e.target.style.transform = e.transform;
77
+ });
78
+
79
+ moveable.on('resize', (e) => {
80
+ e.target.style.width = `${e.width}px`;
81
+ e.target.style.height = `${e.height}px`;
82
+ e.target.style.transform = e.drag.transform;
83
+ });
84
+ };
85
+
86
+ const destroyMoveable = () => {
87
+ moveable?.destroy();
88
+ moveable = null;
89
+ };
90
+
91
+ watch(
92
+ () => props.visible,
93
+ async (visible) => {
94
+ if (visible) {
95
+ await nextTick();
96
+ initMoveable();
97
+ } else {
98
+ destroyMoveable();
99
+ }
100
+ },
101
+ {
102
+ immediate: true,
103
+ },
104
+ );
105
+
106
+ onBeforeUnmount(() => {
107
+ destroyMoveable();
108
+ });
109
+
110
+ const closeHandler = () => {
111
+ emit('update:visible', false);
112
+ };
113
+
114
+ defineExpose({
115
+ target,
116
+ });
117
+ </script>
@@ -5,7 +5,7 @@
5
5
  </template>
6
6
 
7
7
  <script lang="ts" setup>
8
- import { computed, onMounted, onUnmounted, ref } from 'vue';
8
+ import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
9
9
  import Gesto from 'gesto';
10
10
 
11
11
  defineOptions({
@@ -53,7 +53,7 @@ onMounted(() => {
53
53
  bar.value?.addEventListener('wheel', wheelHandler, false);
54
54
  });
55
55
 
56
- onUnmounted(() => {
56
+ onBeforeUnmount(() => {
57
57
  if (gesto) gesto.off();
58
58
  bar.value?.removeEventListener('wheel', wheelHandler, false);
59
59
  });
@@ -23,7 +23,7 @@
23
23
  </template>
24
24
 
25
25
  <script lang="ts" setup>
26
- import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
26
+ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
27
27
 
28
28
  import { isNumber } from '@tmagic/utils';
29
29
 
@@ -94,7 +94,7 @@ onMounted(() => {
94
94
  });
95
95
  });
96
96
 
97
- onUnmounted(() => {
97
+ onBeforeUnmount(() => {
98
98
  scrollViewer.destroy();
99
99
  });
100
100
 
@@ -21,7 +21,7 @@
21
21
  </template>
22
22
 
23
23
  <script lang="ts" setup>
24
- import { computed, onMounted, onUnmounted, ref } from 'vue';
24
+ import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
25
25
  import { OnDrag } from 'gesto';
26
26
 
27
27
  import Resizer from './Resizer.vue';
@@ -110,7 +110,7 @@ onMounted(() => {
110
110
  }
111
111
  });
112
112
 
113
- onUnmounted(() => {
113
+ onBeforeUnmount(() => {
114
114
  resizerObserver.disconnect();
115
115
  });
116
116
 
@@ -6,6 +6,10 @@
6
6
  <slot name="tree-node-content" :data="nodeData"> </slot>
7
7
  </template>
8
8
 
9
+ <template #tree-node-label="{ data: nodeData }">
10
+ <slot name="tree-node-label" :data="nodeData"> </slot>
11
+ </template>
12
+
9
13
  <template #tree-node-tool="{ data: nodeData }">
10
14
  <slot name="tree-node-tool" :data="nodeData"> </slot>
11
15
  </template>
@@ -28,6 +32,7 @@ import TreeNode from './TreeNode.vue';
28
32
 
29
33
  defineSlots<{
30
34
  'tree-node-content'(props: { data: TreeNodeData }): any;
35
+ 'tree-node-label'(props: { data: TreeNodeData }): any;
31
36
  'tree-node-tool'(props: { data: TreeNodeData }): any;
32
37
  }>();
33
38
 
@@ -18,14 +18,16 @@
18
18
  >
19
19
  <MIcon
20
20
  class="expand-icon"
21
- :style="hasChilren ? '' : 'color: transparent; cursor: default'"
21
+ :style="hasChildren ? '' : 'color: transparent; cursor: default'"
22
22
  :icon="expanded ? ArrowDown : ArrowRight"
23
23
  @click="expandHandler"
24
24
  ></MIcon>
25
25
 
26
26
  <div class="tree-node-content" @click="nodeClickHandler">
27
27
  <slot name="tree-node-content" :data="data">
28
- <div class="tree-node-label">{{ `${data.name} (${data.id})` }}</div>
28
+ <div class="tree-node-label">
29
+ <slot name="tree-node-label" :data="data">{{ `${data.name} (${data.id})` }}</slot>
30
+ </div>
29
31
  <div class="tree-node-tool">
30
32
  <slot name="tree-node-tool" :data="data"></slot>
31
33
  </div>
@@ -33,7 +35,7 @@
33
35
  </div>
34
36
  </div>
35
37
 
36
- <div v-if="hasChilren && expanded" class="m-editor-tree-node-children">
38
+ <div v-if="hasChildren && expanded" class="m-editor-tree-node-children">
37
39
  <TreeNode
38
40
  v-for="item in data.items"
39
41
  :key="item.id"
@@ -44,6 +46,9 @@
44
46
  <template #tree-node-content="{ data: nodeData }">
45
47
  <slot name="tree-node-content" :data="nodeData"> </slot>
46
48
  </template>
49
+ <template #tree-node-label="{ data: nodeData }">
50
+ <slot name="tree-node-label" :data="nodeData"> </slot>
51
+ </template>
47
52
  <template #tree-node-tool="{ data: nodeData }">
48
53
  <slot name="tree-node-tool" :data="nodeData"> </slot>
49
54
  </template>
@@ -63,6 +68,7 @@ import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
63
68
  import { updateStatus } from '@editor/utils/tree';
64
69
 
65
70
  defineSlots<{
71
+ 'tree-node-label'(props: { data: TreeNodeData }): any;
66
72
  'tree-node-tool'(props: { data: TreeNodeData }): any;
67
73
  'tree-node-content'(props: { data: TreeNodeData }): any;
68
74
  }>();
@@ -108,7 +114,7 @@ const selected = computed(() => nodeStatus.value.selected);
108
114
  const visible = computed(() => nodeStatus.value.visible);
109
115
  const draggable = computed(() => nodeStatus.value.draggable);
110
116
 
111
- const hasChilren = computed(() => props.data.items && props.data.items.length > 0);
117
+ const hasChildren = computed(() => props.data.items?.some((item) => props.nodeStatusMap.get(item.id)?.visible));
112
118
 
113
119
  const handleDragStart = (event: DragEvent) => {
114
120
  treeEmit?.('node-dragstart', event, props.data);
@@ -1,12 +1,15 @@
1
1
  import type { EventOption } from '@tmagic/core';
2
+ import type { CustomTargetOptions } from '@tmagic/dep';
2
3
  import type { FormConfig, FormState } from '@tmagic/form';
3
4
  import type { DataSourceSchema, Id, MApp, MNode } from '@tmagic/schema';
4
5
  import StageCore, {
5
6
  CONTAINER_HIGHLIGHT_CLASS_NAME,
6
7
  ContainerHighlightType,
7
- CustomizeMoveableOptionsCallbackConfig,
8
- MoveableOptions,
9
- UpdateDragEl,
8
+ type CustomizeMoveableOptionsCallbackConfig,
9
+ type GuidesOptions,
10
+ type MoveableOptions,
11
+ RenderType,
12
+ type UpdateDragEl,
10
13
  } from '@tmagic/stage';
11
14
 
12
15
  import type {
@@ -38,6 +41,8 @@ export interface EditorProps {
38
41
  render?: (stage: StageCore) => HTMLDivElement | Promise<HTMLDivElement>;
39
42
  /** 中间工作区域中画布通过iframe渲染时的页面url */
40
43
  runtimeUrl?: string;
44
+ /** 是用iframe渲染还是直接渲染 */
45
+ renderType?: RenderType;
41
46
  /** 选中时是否自动滚动到可视区域 */
42
47
  autoScrollIntoView?: boolean;
43
48
  /** 组件的属性配置表单的dsl */
@@ -65,6 +70,15 @@ export interface EditorProps {
65
70
  updateDragEl?: UpdateDragEl;
66
71
  disabledDragStart?: boolean;
67
72
  extendFormState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
73
+ /** 自定义依赖收集器,复制组件时会将关联依赖一并复制 */
74
+ collectorOptions?: CustomTargetOptions;
75
+ /** 标尺配置 */
76
+ guidesOptions?: Partial<GuidesOptions>;
77
+ /** 禁止多选 */
78
+ disabledMultiSelect?: boolean;
79
+ /** 禁用页面片 */
80
+ disabledPageFragment?: boolean;
81
+ customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[];
68
82
  }
69
83
 
70
84
  export const defaultEditorProps = {
@@ -84,4 +98,7 @@ export const defaultEditorProps = {
84
98
  containerHighlightDuration: 800,
85
99
  containerHighlightType: ContainerHighlightType.DEFAULT,
86
100
  codeOptions: () => ({}),
101
+ renderType: RenderType.IFRAME,
102
+ disabledMultiSelect: false,
103
+ disabledPageFragment: false,
87
104
  };
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div class="m-fields-page-fragment-select">
3
+ <div class="page-fragment-select-container">
4
+ <!-- 页面片下拉框 -->
5
+ <m-form-container
6
+ class="select"
7
+ :config="selectConfig"
8
+ :model="model"
9
+ :size="size"
10
+ @change="changeHandler"
11
+ ></m-form-container>
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script lang="ts" setup>
17
+ import { computed, inject } from 'vue';
18
+
19
+ import { FieldProps } from '@tmagic/form';
20
+ import { NodeType } from '@tmagic/schema';
21
+
22
+ import type { PageFragmentSelectConfig, Services } from '@editor/type';
23
+
24
+ defineOptions({
25
+ name: 'MEditorPageFragmentSelect',
26
+ });
27
+
28
+ const services = inject<Services>('services');
29
+ const emit = defineEmits(['change']);
30
+
31
+ const props = withDefaults(defineProps<FieldProps<PageFragmentSelectConfig>>(), {
32
+ disabled: false,
33
+ });
34
+ const pageList = computed(() =>
35
+ services?.editorService.get('root')?.items.filter((item) => item.type === NodeType.PAGE_FRAGMENT),
36
+ );
37
+
38
+ const selectConfig = {
39
+ type: 'select',
40
+ name: props.name,
41
+ options: () => {
42
+ if (pageList.value) {
43
+ return pageList.value.map((item) => ({
44
+ text: `${item.name}(${item.id})`,
45
+ label: `${item.name}(${item.id})`,
46
+ value: item.id,
47
+ }));
48
+ }
49
+ return [];
50
+ },
51
+ };
52
+ const changeHandler = async () => {
53
+ emit('change', props.model[props.name]);
54
+ };
55
+ </script>
@@ -0,0 +1,55 @@
1
+ import { type Ref, ref } from 'vue';
2
+
3
+ import type { Id, MNode } from '@tmagic/schema';
4
+
5
+ import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
6
+ import { traverseNode } from '@editor/utils';
7
+ import { updateStatus } from '@editor/utils/tree';
8
+
9
+ export const useFilter = (
10
+ nodeData: Ref<TreeNodeData[]>,
11
+ nodeStatusMap: Ref<Map<Id, LayerNodeStatus> | undefined>,
12
+ filterNodeMethod: (value: string, data: MNode) => boolean,
13
+ ) => {
14
+ // tree方法:对树节点进行筛选时执行的方法
15
+ const filterIsMatch = (value: string | string[], data: MNode): boolean => {
16
+ const string = !Array.isArray(value) ? [value] : value;
17
+
18
+ if (!string.length) {
19
+ return true;
20
+ }
21
+
22
+ return string.some((v) => filterNodeMethod(v, data));
23
+ };
24
+
25
+ const filter = (text: string | string[]) => {
26
+ if (!nodeData.value.length) return;
27
+
28
+ nodeData.value.forEach((node) => {
29
+ traverseNode(node, (node: MNode, parents: MNode[]) => {
30
+ if (!nodeStatusMap.value) return;
31
+
32
+ const visible = filterIsMatch(text, node);
33
+ if (visible && parents.length) {
34
+ parents.forEach((parent) => {
35
+ updateStatus(nodeStatusMap.value!, parent.id, {
36
+ visible,
37
+ expand: true,
38
+ });
39
+ });
40
+ }
41
+
42
+ updateStatus(nodeStatusMap.value, node.id, {
43
+ visible,
44
+ });
45
+ });
46
+ });
47
+ };
48
+
49
+ return {
50
+ filterText: ref(''),
51
+ filterTextChangeHandler(text: string | string[]) {
52
+ filter(text);
53
+ },
54
+ };
55
+ };
@@ -1,4 +1,4 @@
1
- import { onMounted, onUnmounted, type Ref, ref } from 'vue';
1
+ import { onBeforeUnmount, onMounted, type Ref, ref } from 'vue';
2
2
  import Gesto, { type OnDrag } from 'gesto';
3
3
 
4
4
  export const useGetSo = (target: Ref<HTMLElement | undefined>, emit: (evt: 'change', e: OnDrag<Gesto>) => void) => {
@@ -24,7 +24,7 @@ export const useGetSo = (target: Ref<HTMLElement | undefined>, emit: (evt: 'chan
24
24
  });
25
25
  });
26
26
 
27
- onUnmounted(() => {
27
+ onBeforeUnmount(() => {
28
28
  getso?.unset();
29
29
  isDraging.value = false;
30
30
  });
@@ -0,0 +1,48 @@
1
+ import { ComputedRef, ref, watch } from 'vue';
2
+
3
+ import type { Id, MNode } from '@tmagic/schema';
4
+
5
+ import { LayerNodeStatus, TreeNodeData } from '@editor/type';
6
+ import { traverseNode } from '@editor/utils';
7
+
8
+ const createPageNodeStatus = (nodeData: TreeNodeData[], initalLayerNodeStatus?: Map<Id, LayerNodeStatus>) => {
9
+ const map = new Map<Id, LayerNodeStatus>();
10
+
11
+ nodeData.forEach((node: MNode) =>
12
+ traverseNode(node, (node) => {
13
+ map.set(
14
+ node.id,
15
+ initalLayerNodeStatus?.get(node.id) || {
16
+ visible: true,
17
+ expand: false,
18
+ selected: false,
19
+ draggable: false,
20
+ },
21
+ );
22
+ }),
23
+ );
24
+
25
+ return map;
26
+ };
27
+
28
+ export const useNodeStatus = (nodeData: ComputedRef<TreeNodeData[]>) => {
29
+ /** 所有页面的节点状态 */
30
+ const nodeStatusMap = ref(new Map<Id, LayerNodeStatus>());
31
+
32
+ // 切换页面或者新增页面,重新生成节点状态
33
+ watch(
34
+ nodeData,
35
+ (nodeData) => {
36
+ // 生成节点状态
37
+ nodeStatusMap.value = createPageNodeStatus(nodeData, nodeStatusMap.value);
38
+ },
39
+ {
40
+ immediate: true,
41
+ deep: true,
42
+ },
43
+ );
44
+
45
+ return {
46
+ nodeStatusMap,
47
+ };
48
+ };