@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.
- package/LICENSE +5432 -0
- package/dist/style.css +88 -62
- package/dist/tmagic-editor.js +2448 -2016
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +2453 -2019
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +23 -23
- package/src/Editor.vue +15 -7
- package/src/components/CodeBlockEditor.vue +2 -2
- package/src/components/ContentMenu.vue +5 -5
- package/src/components/FloatingBox.vue +117 -0
- package/src/components/ScrollBar.vue +2 -2
- package/src/components/ScrollViewer.vue +2 -2
- package/src/components/SplitView.vue +2 -2
- package/src/components/Tree.vue +5 -0
- package/src/components/TreeNode.vue +10 -4
- package/src/editorProps.ts +20 -3
- package/src/fields/PageFragmentSelect.vue +55 -0
- package/src/hooks/use-filter.ts +55 -0
- package/src/hooks/use-getso.ts +2 -2
- package/src/hooks/use-node-status.ts +48 -0
- package/src/hooks/use-stage.ts +19 -1
- package/src/index.ts +3 -0
- package/src/initService.ts +43 -17
- package/src/layouts/AddPageBox.vue +16 -4
- package/src/layouts/CodeEditor.vue +2 -2
- package/src/layouts/Framework.vue +17 -3
- package/src/layouts/PropsPanel.vue +2 -2
- package/src/layouts/page-bar/AddButton.vue +48 -0
- package/src/layouts/page-bar/PageBar.vue +158 -0
- package/src/layouts/{workspace → page-bar}/PageBarScrollContainer.vue +61 -35
- package/src/layouts/page-bar/SwitchTypeButton.vue +45 -0
- package/src/layouts/sidebar/Sidebar.vue +9 -2
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +55 -65
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +2 -1
- package/src/layouts/sidebar/data-source/DataSourceList.vue +63 -59
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
- package/src/layouts/sidebar/layer/LayerMenu.vue +39 -27
- package/src/layouts/sidebar/layer/LayerPanel.vue +31 -8
- package/src/layouts/sidebar/layer/use-click.ts +5 -3
- package/src/layouts/sidebar/layer/use-keybinding.ts +8 -8
- package/src/layouts/sidebar/layer/use-node-status.ts +10 -13
- package/src/layouts/workspace/Workspace.vue +6 -7
- package/src/layouts/workspace/viewer/NodeListMenu.vue +68 -129
- package/src/layouts/workspace/viewer/Stage.vue +14 -6
- package/src/layouts/workspace/viewer/ViewerMenu.vue +94 -86
- package/src/services/BaseService.ts +63 -26
- package/src/services/codeBlock.ts +7 -1
- package/src/services/dep.ts +12 -8
- package/src/services/editor.ts +131 -64
- package/src/services/history.ts +6 -2
- package/src/services/keybinding.ts +48 -13
- package/src/services/props.ts +70 -12
- package/src/services/storage.ts +23 -13
- package/src/services/ui.ts +4 -1
- package/src/theme/code-block.scss +0 -16
- package/src/theme/floating-box.scss +30 -0
- package/src/theme/layer-panel.scss +19 -0
- package/src/theme/page-bar.scss +18 -1
- package/src/theme/stage.scss +24 -0
- package/src/theme/theme.scss +1 -1
- package/src/theme/tree.scss +12 -1
- package/src/type.ts +28 -10
- package/src/utils/compose.ts +25 -6
- package/src/utils/content-menu.ts +6 -7
- package/src/utils/editor.ts +34 -18
- package/src/utils/operator.ts +5 -6
- package/types/components/CodeBlockEditor.vue.d.ts +6 -2
- package/types/components/CodeParams.vue.d.ts +3 -1
- package/types/components/ContentMenu.vue.d.ts +13 -5
- package/types/components/FloatingBox.vue.d.ts +78 -0
- package/types/components/Resizer.vue.d.ts +6 -1
- package/types/components/ScrollBar.vue.d.ts +3 -1
- package/types/components/ScrollViewer.vue.d.ts +3 -3
- package/types/components/SearchInput.vue.d.ts +3 -1
- package/types/components/SplitView.vue.d.ts +8 -4
- package/types/components/ToolButton.vue.d.ts +3 -3
- package/types/components/Tree.vue.d.ts +27 -8
- package/types/components/TreeNode.vue.d.ts +24 -7
- package/types/editorProps.d.ts +16 -1
- package/types/fields/Code.vue.d.ts +6 -2
- package/types/fields/CodeLink.vue.d.ts +5 -3
- package/types/fields/CodeSelect.vue.d.ts +3 -1
- package/types/fields/CodeSelectCol.vue.d.ts +3 -1
- package/types/fields/DataSourceFieldSelect.vue.d.ts +3 -1
- package/types/fields/DataSourceFields.vue.d.ts +5 -3
- package/types/fields/DataSourceInput.vue.d.ts +8 -4
- package/types/fields/DataSourceMethodSelect.vue.d.ts +3 -1
- package/types/fields/DataSourceMethods.vue.d.ts +5 -3
- package/types/fields/DataSourceMocks.vue.d.ts +5 -3
- package/types/fields/DataSourceSelect.vue.d.ts +5 -3
- package/types/fields/EventSelect.vue.d.ts +3 -1
- package/types/fields/KeyValue.vue.d.ts +2 -2
- package/types/fields/PageFragmentSelect.vue.d.ts +31 -0
- package/types/fields/UISelect.vue.d.ts +3 -1
- package/types/hooks/use-code-block-edit.d.ts +14 -5
- package/types/hooks/use-data-source-method.d.ts +14 -5
- package/types/hooks/use-filter.d.ts +7 -0
- package/types/hooks/use-node-status.d.ts +6 -0
- package/types/index.d.ts +1 -0
- package/types/layouts/AddPageBox.vue.d.ts +14 -1
- package/types/layouts/CodeEditor.vue.d.ts +4 -1
- package/types/layouts/Framework.vue.d.ts +14 -1
- package/types/layouts/PropsPanel.vue.d.ts +19 -13
- package/types/layouts/{workspace/viewer/NodeListMenuTitle.vue.d.ts → page-bar/AddButton.vue.d.ts} +3 -2
- package/types/layouts/page-bar/PageBar.vue.d.ts +28 -0
- package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +24 -0
- package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +20 -0
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/Sidebar.vue.d.ts +7 -5
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +9 -3
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +8 -2
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +26 -3
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +3 -1
- package/types/layouts/sidebar/layer/use-click.d.ts +37 -6
- package/types/layouts/sidebar/layer/use-keybinding.d.ts +1 -1
- package/types/layouts/sidebar/layer/use-node-status.d.ts +3 -4
- package/types/layouts/workspace/Workspace.vue.d.ts +3 -1
- package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -14
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +2 -0
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +9 -1
- package/types/services/BaseService.d.ts +4 -1
- package/types/services/dataSource.d.ts +1 -0
- package/types/services/dep.d.ts +6 -5
- package/types/services/editor.d.ts +12 -5
- package/types/services/history.d.ts +3 -2
- package/types/services/keybinding.d.ts +21 -1
- package/types/services/props.d.ts +25 -1
- package/types/services/storage.d.ts +7 -7
- package/types/type.d.ts +32 -17
- package/types/utils/compose.d.ts +1 -1
- package/types/utils/editor.d.ts +14 -8
- package/src/layouts/sidebar/layer/use-filter.ts +0 -59
- package/src/layouts/workspace/PageBar.vue +0 -87
- package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +0 -68
- package/src/theme/dep-list.scss +0 -59
- package/types/layouts/sidebar/layer/use-filter.d.ts +0 -7
- package/types/layouts/workspace/PageBar.vue.d.ts +0 -15
- package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +0 -9
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
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": ">=
|
|
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.
|
|
50
|
-
"@tmagic/core": "1.3.
|
|
51
|
-
"@tmagic/dep": "1.3.
|
|
52
|
-
"@tmagic/design": "1.3.
|
|
53
|
-
"@tmagic/form": "1.3.
|
|
54
|
-
"@tmagic/schema": "1.3.
|
|
55
|
-
"@tmagic/stage": "1.3.
|
|
56
|
-
"@tmagic/table": "1.3.
|
|
57
|
-
"@tmagic/utils": "1.3.
|
|
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.
|
|
71
|
-
"@tmagic/form": "1.3.
|
|
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": "^
|
|
73
|
+
"@types/node": "^18.19.0",
|
|
79
74
|
"@types/serialize-javascript": "^5.0.1",
|
|
80
|
-
"@vitejs/plugin-vue": "^4.2
|
|
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": "^
|
|
88
|
-
"vue-tsc": "^1.
|
|
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.
|
|
155
|
-
keybindingService.
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
|
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',
|
|
176
|
+
globalThis.addEventListener('mousedown', outsideClickHideHandler, true);
|
|
177
177
|
});
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
onBeforeUnmount(() => {
|
|
180
180
|
if (props.isSubMenu) return;
|
|
181
181
|
|
|
182
|
-
globalThis.removeEventListener('mousedown',
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
113
|
+
onBeforeUnmount(() => {
|
|
114
114
|
resizerObserver.disconnect();
|
|
115
115
|
});
|
|
116
116
|
|
package/src/components/Tree.vue
CHANGED
|
@@ -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="
|
|
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">
|
|
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="
|
|
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
|
|
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);
|
package/src/editorProps.ts
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
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
|
+
};
|
package/src/hooks/use-getso.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
+
};
|