@tmagic/editor 1.0.0-rc.4 → 1.0.0-rc.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/dist/tmagic-editor.es.js +90 -32
- package/dist/tmagic-editor.es.js.map +1 -1
- package/dist/tmagic-editor.umd.js +91 -33
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/dist/types/src/Editor.vue.d.ts +19 -1
- package/dist/types/src/fields/Code.vue.d.ts +4 -4
- package/dist/types/src/fields/CodeLink.vue.d.ts +1 -3
- package/dist/types/src/layouts/PropsPanel.vue.d.ts +2 -4
- package/dist/types/src/services/history.d.ts +1 -18
- package/package.json +11 -20
- package/src/Editor.vue +14 -1
- package/src/components/ContentMenu.vue +58 -25
- package/src/layouts/sidebar/LayerMenu.vue +3 -0
- package/src/layouts/workspace/ViewerMenu.vue +3 -0
- package/src/services/editor.ts +3 -4
- package/src/services/props.ts +64 -9
- package/src/utils/editor.ts +7 -52
- package/src/utils/props.ts +17 -3
- package/LICENSE +0 -5432
- package/coverage/clover.xml +0 -1593
- package/coverage/coverage-final.json +0 -36
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -206
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov-report/src/Editor.vue.html +0 -814
- package/coverage/lcov-report/src/components/ContentMenu.vue.html +0 -406
- package/coverage/lcov-report/src/components/Icon.vue.html +0 -172
- package/coverage/lcov-report/src/components/ScrollViewer.vue.html +0 -283
- package/coverage/lcov-report/src/components/ToolButton.vue.html +0 -772
- package/coverage/lcov-report/src/components/index.html +0 -161
- package/coverage/lcov-report/src/index.html +0 -131
- package/coverage/lcov-report/src/layouts/AddPageBox.vue.html +0 -214
- package/coverage/lcov-report/src/layouts/Framework.vue.html +0 -343
- package/coverage/lcov-report/src/layouts/NavMenu.vue.html +0 -208
- package/coverage/lcov-report/src/layouts/PropsPanel.vue.html +0 -319
- package/coverage/lcov-report/src/layouts/Resizer.vue.html +0 -268
- package/coverage/lcov-report/src/layouts/index.html +0 -176
- package/coverage/lcov-report/src/layouts/sidebar/ComponentListPanel.vue.html +0 -358
- package/coverage/lcov-report/src/layouts/sidebar/LayerMenu.vue.html +0 -421
- package/coverage/lcov-report/src/layouts/sidebar/LayerPanel.vue.html +0 -775
- package/coverage/lcov-report/src/layouts/sidebar/Sidebar.vue.html +0 -226
- package/coverage/lcov-report/src/layouts/sidebar/TabPane.vue.html +0 -289
- package/coverage/lcov-report/src/layouts/sidebar/index.html +0 -176
- package/coverage/lcov-report/src/layouts/workspace/PageBar.vue.html +0 -718
- package/coverage/lcov-report/src/layouts/workspace/Stage.vue.html +0 -766
- package/coverage/lcov-report/src/layouts/workspace/ViewerMenu.vue.html +0 -568
- package/coverage/lcov-report/src/layouts/workspace/Workspace.vue.html +0 -649
- package/coverage/lcov-report/src/layouts/workspace/index.html +0 -161
- package/coverage/lcov-report/src/services/BaseService.ts.html +0 -643
- package/coverage/lcov-report/src/services/componentList.ts.html +0 -229
- package/coverage/lcov-report/src/services/editor.ts.html +0 -2167
- package/coverage/lcov-report/src/services/events.ts.html +0 -331
- package/coverage/lcov-report/src/services/history.ts.html +0 -478
- package/coverage/lcov-report/src/services/index.html +0 -206
- package/coverage/lcov-report/src/services/props.ts.html +0 -415
- package/coverage/lcov-report/src/services/ui.ts.html +0 -580
- package/coverage/lcov-report/src/type.ts.html +0 -850
- package/coverage/lcov-report/src/utils/compose.ts.html +0 -184
- package/coverage/lcov-report/src/utils/config.ts.html +0 -172
- package/coverage/lcov-report/src/utils/editor.ts.html +0 -838
- package/coverage/lcov-report/src/utils/index.html +0 -221
- package/coverage/lcov-report/src/utils/index.ts.html +0 -151
- package/coverage/lcov-report/src/utils/logger.ts.html +0 -226
- package/coverage/lcov-report/src/utils/props.ts.html +0 -796
- package/coverage/lcov-report/src/utils/scroll-viewer.ts.html +0 -733
- package/coverage/lcov-report/src/utils/undo-redo.ts.html +0 -313
- package/coverage/lcov.info +0 -3846
- package/dist/types/src/components/ToolButton.vue.d.ts +0 -46
- package/dist/types/src/fields/UISelect.vue.d.ts +0 -35
- package/dist/types/src/layouts/workspace/PageBar.vue.d.ts +0 -18
|
@@ -3,7 +3,7 @@ import type { FormConfig } from '@tmagic/form';
|
|
|
3
3
|
import type { MApp, MNode } from '@tmagic/schema';
|
|
4
4
|
import type StageCore from '@tmagic/stage';
|
|
5
5
|
import type { MoveableOptions } from '@tmagic/stage';
|
|
6
|
-
import type { ComponentGroup, MenuBarData, Services, SideBarData, StageRect } from './type';
|
|
6
|
+
import type { ComponentGroup, MenuBarData, MenuItem, Services, SideBarData, StageRect } from './type';
|
|
7
7
|
declare const _default: DefineComponent<{
|
|
8
8
|
/** 页面初始值 */
|
|
9
9
|
modelValue: {
|
|
@@ -20,6 +20,14 @@ declare const _default: DefineComponent<{
|
|
|
20
20
|
sidebar: {
|
|
21
21
|
type: PropType<SideBarData>;
|
|
22
22
|
};
|
|
23
|
+
layerContentMenu: {
|
|
24
|
+
type: PropType<MenuItem[]>;
|
|
25
|
+
default: () => never[];
|
|
26
|
+
};
|
|
27
|
+
stageContentMenu: {
|
|
28
|
+
type: PropType<MenuItem[]>;
|
|
29
|
+
default: () => never[];
|
|
30
|
+
};
|
|
23
31
|
/** 顶部工具栏配置 */
|
|
24
32
|
menu: {
|
|
25
33
|
type: PropType<MenuBarData>;
|
|
@@ -85,6 +93,14 @@ declare const _default: DefineComponent<{
|
|
|
85
93
|
sidebar: {
|
|
86
94
|
type: PropType<SideBarData>;
|
|
87
95
|
};
|
|
96
|
+
layerContentMenu: {
|
|
97
|
+
type: PropType<MenuItem[]>;
|
|
98
|
+
default: () => never[];
|
|
99
|
+
};
|
|
100
|
+
stageContentMenu: {
|
|
101
|
+
type: PropType<MenuItem[]>;
|
|
102
|
+
default: () => never[];
|
|
103
|
+
};
|
|
88
104
|
/** 顶部工具栏配置 */
|
|
89
105
|
menu: {
|
|
90
106
|
type: PropType<MenuBarData>;
|
|
@@ -139,6 +155,8 @@ declare const _default: DefineComponent<{
|
|
|
139
155
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
140
156
|
}, {
|
|
141
157
|
menu: MenuBarData;
|
|
158
|
+
layerContentMenu: MenuItem[];
|
|
159
|
+
stageContentMenu: MenuItem[];
|
|
142
160
|
autoScrollIntoView: boolean;
|
|
143
161
|
codeOptions: Record<string, any>;
|
|
144
162
|
modelValue: MApp;
|
|
@@ -16,9 +16,9 @@ declare const _default: DefineComponent<Readonly<{
|
|
|
16
16
|
}>>> & {
|
|
17
17
|
onChange?: ((...args: any[]) => any) | undefined;
|
|
18
18
|
}, {
|
|
19
|
-
name
|
|
20
|
-
config
|
|
21
|
-
model
|
|
22
|
-
prop
|
|
19
|
+
readonly name?: any;
|
|
20
|
+
readonly config?: any;
|
|
21
|
+
readonly model?: any;
|
|
22
|
+
readonly prop?: any;
|
|
23
23
|
}>;
|
|
24
24
|
export default _default;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { DefineComponent, Ref, ComputedRef, ComponentOptionsMixin, VNodeProps, AllowedComponentProps, ComponentCustomProps, ExtractPropTypes } from 'vue';
|
|
2
|
+
import type { FormValue } from '@tmagic/form';
|
|
2
3
|
declare const _default: DefineComponent<{}, {
|
|
3
|
-
values: Ref<
|
|
4
|
-
[x: string]: any;
|
|
5
|
-
[x: number]: any;
|
|
6
|
-
}>;
|
|
4
|
+
values: Ref<FormValue>;
|
|
7
5
|
configForm: Ref<any>;
|
|
8
6
|
curFormConfig: any;
|
|
9
7
|
propsPanelSize: ComputedRef<unknown>;
|
|
@@ -15,24 +15,7 @@ export interface HistoryState {
|
|
|
15
15
|
declare class History extends BaseService {
|
|
16
16
|
state: {
|
|
17
17
|
pageId?: Id | undefined;
|
|
18
|
-
pageSteps:
|
|
19
|
-
[x: string]: {
|
|
20
|
-
pushElement: (element: StepValue) => void;
|
|
21
|
-
canUndo: () => boolean;
|
|
22
|
-
undo: () => StepValue | null;
|
|
23
|
-
canRedo: () => boolean;
|
|
24
|
-
redo: () => StepValue | null;
|
|
25
|
-
getCurrentElement: () => StepValue | null;
|
|
26
|
-
};
|
|
27
|
-
[x: number]: {
|
|
28
|
-
pushElement: (element: StepValue) => void;
|
|
29
|
-
canUndo: () => boolean;
|
|
30
|
-
undo: () => StepValue | null;
|
|
31
|
-
canRedo: () => boolean;
|
|
32
|
-
redo: () => StepValue | null;
|
|
33
|
-
getCurrentElement: () => StepValue | null;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
18
|
+
pageSteps: Record<Id, UndoRedo<StepValue>>;
|
|
36
19
|
canRedo: boolean;
|
|
37
20
|
canUndo: boolean;
|
|
38
21
|
};
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.0-rc.
|
|
2
|
+
"version": "1.0.0-rc.7",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"dist/*",
|
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
24
|
"scripts": {
|
|
25
|
-
"build": "vite build"
|
|
26
|
-
"test": "jest --maxWorkers=8",
|
|
27
|
-
"test:coverage": "jest --maxWorkers=16 --coverage"
|
|
25
|
+
"build": "vite build"
|
|
28
26
|
},
|
|
29
27
|
"engines": {
|
|
30
28
|
"node": ">=14"
|
|
@@ -45,11 +43,11 @@
|
|
|
45
43
|
"dependencies": {
|
|
46
44
|
"@babel/core": "^7.18.0",
|
|
47
45
|
"@element-plus/icons": "0.0.11",
|
|
48
|
-
"@tmagic/core": "
|
|
49
|
-
"@tmagic/form": "
|
|
50
|
-
"@tmagic/schema": "
|
|
51
|
-
"@tmagic/stage": "
|
|
52
|
-
"@tmagic/utils": "
|
|
46
|
+
"@tmagic/core": "1.0.0-rc.7",
|
|
47
|
+
"@tmagic/form": "1.0.0-rc.7",
|
|
48
|
+
"@tmagic/schema": "1.0.0-rc.7",
|
|
49
|
+
"@tmagic/stage": "1.0.0-rc.7",
|
|
50
|
+
"@tmagic/utils": "1.0.0-rc.7",
|
|
53
51
|
"buffer": "^6.0.3",
|
|
54
52
|
"color": "^3.1.3",
|
|
55
53
|
"element-plus": "^2.2.0",
|
|
@@ -62,31 +60,24 @@
|
|
|
62
60
|
"vue": "^3.2.0"
|
|
63
61
|
},
|
|
64
62
|
"peerDependencies": {
|
|
65
|
-
"@tmagic/form": "
|
|
63
|
+
"@tmagic/form": "1.0.0-rc.7",
|
|
66
64
|
"element-plus": "^2.2.0",
|
|
65
|
+
"monaco-editor": "^0.32.1",
|
|
67
66
|
"vue": "^3.2.0"
|
|
68
67
|
},
|
|
69
68
|
"devDependencies": {
|
|
70
69
|
"@types/events": "^3.0.0",
|
|
71
|
-
"@types/jest": "^27.5.1",
|
|
72
70
|
"@types/lodash-es": "^4.17.4",
|
|
73
71
|
"@types/node": "^15.12.4",
|
|
74
72
|
"@types/serialize-javascript": "^5.0.1",
|
|
75
73
|
"@vitejs/plugin-vue": "^1.2.3",
|
|
76
74
|
"@vitejs/plugin-vue-jsx": "^1.1.6",
|
|
77
75
|
"@vue/compiler-sfc": "^3.2.0",
|
|
78
|
-
"@vue/test-utils": "^2.0.0
|
|
79
|
-
"@vue/vue3-jest": "^27.0.0-alpha.4",
|
|
80
|
-
"babel-jest": "^27.0.6",
|
|
81
|
-
"jest": "^27.5.1",
|
|
82
|
-
"jest-serializer-vue": "^2.0.2",
|
|
83
|
-
"jest-transform-stub": "^2.0.0",
|
|
76
|
+
"@vue/test-utils": "^2.0.0",
|
|
84
77
|
"sass": "^1.35.1",
|
|
85
|
-
"ts-jest": "^27.1.4",
|
|
86
78
|
"typescript": "^4.3.4",
|
|
87
79
|
"vite": "^2.3.7",
|
|
88
80
|
"vite-plugin-dts": "^0.9.6",
|
|
89
81
|
"vue-tsc": "^0.0.24"
|
|
90
|
-
}
|
|
91
|
-
"gitHead": "28d5ad4573a27fa240f5e7d0902d3368e8d936b6"
|
|
82
|
+
}
|
|
92
83
|
}
|
package/src/Editor.vue
CHANGED
|
@@ -56,7 +56,7 @@ import eventsService from '@editor/services/events';
|
|
|
56
56
|
import historyService from '@editor/services/history';
|
|
57
57
|
import propsService from '@editor/services/props';
|
|
58
58
|
import uiService from '@editor/services/ui';
|
|
59
|
-
import type { ComponentGroup, MenuBarData, Services, SideBarData, StageRect } from '@editor/type';
|
|
59
|
+
import type { ComponentGroup, MenuBarData, MenuItem, Services, SideBarData, StageRect } from '@editor/type';
|
|
60
60
|
|
|
61
61
|
export default defineComponent({
|
|
62
62
|
name: 'm-editor',
|
|
@@ -88,6 +88,16 @@ export default defineComponent({
|
|
|
88
88
|
type: Object as PropType<SideBarData>,
|
|
89
89
|
},
|
|
90
90
|
|
|
91
|
+
layerContentMenu: {
|
|
92
|
+
type: Array as PropType<MenuItem[]>,
|
|
93
|
+
default: () => [],
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
stageContentMenu: {
|
|
97
|
+
type: Array as PropType<MenuItem[]>,
|
|
98
|
+
default: () => [],
|
|
99
|
+
},
|
|
100
|
+
|
|
91
101
|
/** 顶部工具栏配置 */
|
|
92
102
|
menu: {
|
|
93
103
|
type: Object as PropType<MenuBarData>,
|
|
@@ -237,6 +247,9 @@ export default defineComponent({
|
|
|
237
247
|
|
|
238
248
|
provide('services', services);
|
|
239
249
|
|
|
250
|
+
provide('layerContentMenu', props.layerContentMenu);
|
|
251
|
+
provide('stageContentMenu', props.stageContentMenu);
|
|
252
|
+
|
|
240
253
|
return services;
|
|
241
254
|
},
|
|
242
255
|
});
|
|
@@ -11,13 +11,19 @@
|
|
|
11
11
|
></tool-button>
|
|
12
12
|
</div>
|
|
13
13
|
<teleport to="body">
|
|
14
|
-
<content-menu
|
|
14
|
+
<content-menu
|
|
15
|
+
class="sub-menu"
|
|
16
|
+
ref="subMenu"
|
|
17
|
+
:menu-data="subMenuData"
|
|
18
|
+
:is-sub-menu="true"
|
|
19
|
+
@hide="hide"
|
|
20
|
+
></content-menu>
|
|
15
21
|
</teleport>
|
|
16
22
|
</div>
|
|
17
23
|
</template>
|
|
18
24
|
|
|
19
25
|
<script lang="ts">
|
|
20
|
-
import { defineComponent, nextTick, onMounted, PropType, ref } from 'vue';
|
|
26
|
+
import { defineComponent, nextTick, onMounted, onUnmounted, PropType, ref } from 'vue';
|
|
21
27
|
|
|
22
28
|
import { MenuButton, MenuItem } from '@editor/type';
|
|
23
29
|
|
|
@@ -31,9 +37,16 @@ export default defineComponent({
|
|
|
31
37
|
type: Array as PropType<MenuItem[]>,
|
|
32
38
|
default: () => [],
|
|
33
39
|
},
|
|
40
|
+
|
|
41
|
+
isSubMenu: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
default: false,
|
|
44
|
+
},
|
|
34
45
|
},
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
emits: ['hide', 'show'],
|
|
48
|
+
|
|
49
|
+
setup(props, { emit }) {
|
|
37
50
|
const menu = ref<HTMLDivElement>();
|
|
38
51
|
const subMenu = ref<any>();
|
|
39
52
|
const visible = ref(false);
|
|
@@ -44,20 +57,35 @@ export default defineComponent({
|
|
|
44
57
|
});
|
|
45
58
|
|
|
46
59
|
const hide = () => {
|
|
60
|
+
if (!visible.value) return;
|
|
61
|
+
|
|
47
62
|
visible.value = false;
|
|
63
|
+
subMenu.value?.hide();
|
|
64
|
+
|
|
65
|
+
emit('hide');
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const hideHandler = (e: MouseEvent) => {
|
|
69
|
+
const target = e.target as HTMLElement | undefined;
|
|
70
|
+
if (!visible.value || !target) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (menu.value?.contains(target) || subMenu.value?.$el?.contains(target)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
hide();
|
|
48
77
|
};
|
|
49
78
|
|
|
50
79
|
onMounted(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
);
|
|
80
|
+
if (props.isSubMenu) return;
|
|
81
|
+
|
|
82
|
+
globalThis.addEventListener('mousedown', hideHandler, true);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
onUnmounted(() => {
|
|
86
|
+
if (props.isSubMenu) return;
|
|
87
|
+
|
|
88
|
+
globalThis.removeEventListener('mousedown', hideHandler, true);
|
|
61
89
|
});
|
|
62
90
|
|
|
63
91
|
return {
|
|
@@ -70,21 +98,26 @@ export default defineComponent({
|
|
|
70
98
|
hide,
|
|
71
99
|
|
|
72
100
|
show(e: MouseEvent) {
|
|
73
|
-
|
|
101
|
+
// 加settimeout是以为,如果菜单中的按钮监听的是mouseup,那么菜单显示出来时鼠标如果正好在菜单上就会马上触发按钮的mouseup
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
visible.value = true;
|
|
104
|
+
|
|
105
|
+
nextTick(() => {
|
|
106
|
+
const menuHeight = menu.value?.clientHeight || 0;
|
|
74
107
|
|
|
75
|
-
|
|
76
|
-
|
|
108
|
+
let top = e.clientY;
|
|
109
|
+
if (menuHeight + e.clientY > document.body.clientHeight) {
|
|
110
|
+
top = document.body.clientHeight - menuHeight;
|
|
111
|
+
}
|
|
77
112
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
113
|
+
menuStyle.value = {
|
|
114
|
+
top: `${top}px`,
|
|
115
|
+
left: `${e.clientX}px`,
|
|
116
|
+
};
|
|
82
117
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
87
|
-
});
|
|
118
|
+
emit('show');
|
|
119
|
+
});
|
|
120
|
+
}, 300);
|
|
88
121
|
},
|
|
89
122
|
|
|
90
123
|
showSubMenu(item: MenuItem) {
|
|
@@ -22,6 +22,8 @@ export default defineComponent({
|
|
|
22
22
|
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
23
23
|
const componentList = computed(() => services?.componentListService.getList() || []);
|
|
24
24
|
|
|
25
|
+
const layerContentMenu = inject<MenuItem[]>('layerContentMenu', []);
|
|
26
|
+
|
|
25
27
|
const createMenuItems = (group: ComponentGroup): MenuButton[] =>
|
|
26
28
|
group.items.map((component) => ({
|
|
27
29
|
text: component.text,
|
|
@@ -101,6 +103,7 @@ export default defineComponent({
|
|
|
101
103
|
node.value && services?.editorService.remove(node.value);
|
|
102
104
|
},
|
|
103
105
|
},
|
|
106
|
+
...layerContentMenu,
|
|
104
107
|
]),
|
|
105
108
|
|
|
106
109
|
show(e: MouseEvent) {
|
|
@@ -27,6 +27,8 @@ export default defineComponent({
|
|
|
27
27
|
const parent = computed(() => editorService?.get('parent'));
|
|
28
28
|
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
29
29
|
|
|
30
|
+
const stageContentMenu = inject<MenuItem[]>('stageContentMenu', []);
|
|
31
|
+
|
|
30
32
|
onMounted(() => {
|
|
31
33
|
const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
|
|
32
34
|
canPaste.value = data !== 'undefined' && !!data;
|
|
@@ -150,6 +152,7 @@ export default defineComponent({
|
|
|
150
152
|
editorService?.get<StageCore>('stage').clearGuides();
|
|
151
153
|
},
|
|
152
154
|
},
|
|
155
|
+
...stageContentMenu,
|
|
153
156
|
]),
|
|
154
157
|
|
|
155
158
|
show(e: MouseEvent) {
|
package/src/services/editor.ts
CHANGED
|
@@ -38,7 +38,6 @@ import {
|
|
|
38
38
|
initPosition,
|
|
39
39
|
isFixed,
|
|
40
40
|
setLayout,
|
|
41
|
-
setNewItemId,
|
|
42
41
|
} from '@editor/utils/editor';
|
|
43
42
|
import { log } from '@editor/utils/logger';
|
|
44
43
|
|
|
@@ -495,7 +494,7 @@ class Editor extends BaseService {
|
|
|
495
494
|
return;
|
|
496
495
|
}
|
|
497
496
|
|
|
498
|
-
setNewItemId(config, this.get('root'));
|
|
497
|
+
await propsService.setNewItemId(config, this.get('root'));
|
|
499
498
|
if (config.style) {
|
|
500
499
|
config.style = {
|
|
501
500
|
...config.style,
|
|
@@ -556,9 +555,9 @@ class Editor extends BaseService {
|
|
|
556
555
|
const brothers: MNode[] = parent?.items || [];
|
|
557
556
|
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
558
557
|
|
|
559
|
-
if (offset === LayerOffset.
|
|
558
|
+
if (offset === LayerOffset.TOP) {
|
|
560
559
|
brothers.splice(brothers.length - 1, 0, brothers.splice(index, 1)[0]);
|
|
561
|
-
} else if (offset === LayerOffset.
|
|
560
|
+
} else if (offset === LayerOffset.BOTTOM) {
|
|
562
561
|
brothers.splice(0, 0, brothers.splice(index, 1)[0]);
|
|
563
562
|
} else {
|
|
564
563
|
brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
|
package/src/services/props.ts
CHANGED
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
|
-
import { cloneDeep, mergeWith } from 'lodash-es';
|
|
20
|
+
import { cloneDeep, mergeWith, random } from 'lodash-es';
|
|
21
21
|
|
|
22
22
|
import type { FormConfig } from '@tmagic/form';
|
|
23
|
-
import type { MComponent, MNode } from '@tmagic/schema';
|
|
24
|
-
import {
|
|
23
|
+
import type { Id, MComponent, MNode, MPage } from '@tmagic/schema';
|
|
24
|
+
import { NodeType } from '@tmagic/schema';
|
|
25
|
+
import { isPop, toLine } from '@tmagic/utils';
|
|
25
26
|
|
|
26
27
|
import type { PropsState } from '@editor/type';
|
|
27
28
|
import { DEFAULT_CONFIG, fillConfig, getDefaultPropsValue } from '@editor/utils/props';
|
|
@@ -35,7 +36,7 @@ class Props extends BaseService {
|
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
constructor() {
|
|
38
|
-
super(['setPropsConfig', 'getPropsConfig', 'setPropsValue', 'getPropsValue']);
|
|
39
|
+
super(['setPropsConfig', 'getPropsConfig', 'setPropsValue', 'getPropsValue', 'createId', 'setNewItemId']);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
public setPropsConfigs(configs: Record<string, FormConfig>) {
|
|
@@ -87,7 +88,7 @@ class Props extends BaseService {
|
|
|
87
88
|
* @param type 组件类型
|
|
88
89
|
* @returns 组件初始值
|
|
89
90
|
*/
|
|
90
|
-
public async getPropsValue(type: string, defaultValue = {}) {
|
|
91
|
+
public async getPropsValue(type: string, defaultValue: Record<string, any> = {}) {
|
|
91
92
|
if (type === 'area') {
|
|
92
93
|
const value = (await this.getPropsValue('button')) as MComponent;
|
|
93
94
|
value.className = 'action-area';
|
|
@@ -98,13 +99,67 @@ class Props extends BaseService {
|
|
|
98
99
|
return value;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
const data = cloneDeep(defaultValue as any);
|
|
103
|
+
|
|
104
|
+
await this.setNewItemId(data);
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
...getDefaultPropsValue(type, await this.createId(type)),
|
|
108
|
+
...mergeWith(cloneDeep(this.state.propsValueMap[type] || {}), data),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public async createId(type: string | number): Promise<string> {
|
|
113
|
+
return `${type}_${random(10000, false)}`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 将组件与组件的子元素配置中的id都设置成一个新的ID
|
|
118
|
+
* @param {Object} config 组件配置
|
|
119
|
+
*/
|
|
120
|
+
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
121
|
+
public async setNewItemId(config: MNode, parent?: MPage) {
|
|
122
|
+
const oldId = config.id;
|
|
123
|
+
|
|
124
|
+
config.id = await this.createId(config.type || 'component');
|
|
125
|
+
|
|
126
|
+
// 只有弹窗在页面下的一级子元素才有效
|
|
127
|
+
if (isPop(config) && parent?.type === NodeType.PAGE) {
|
|
128
|
+
updatePopId(oldId, config.id, parent);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (config.items && Array.isArray(config.items)) {
|
|
132
|
+
for (const item of config.items) {
|
|
133
|
+
await this.setNewItemId(item, config as MPage);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
105
136
|
}
|
|
106
137
|
}
|
|
107
138
|
|
|
139
|
+
/**
|
|
140
|
+
* 复制页面时,需要把组件下关联的弹窗id换测复制出来的弹窗的id
|
|
141
|
+
* @param {number} oldId 复制的源弹窗id
|
|
142
|
+
* @param {number} popId 新的弹窗id
|
|
143
|
+
* @param {Object} pageConfig 页面配置
|
|
144
|
+
*/
|
|
145
|
+
const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
|
|
146
|
+
pageConfig.items?.forEach((config) => {
|
|
147
|
+
if (config.pop === oldId) {
|
|
148
|
+
config.pop = popId;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (config.popId === oldId) {
|
|
153
|
+
config.popId = popId;
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (Array.isArray(config.items)) {
|
|
158
|
+
updatePopId(oldId, popId, config as MPage);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
108
163
|
export type PropsService = Props;
|
|
109
164
|
|
|
110
165
|
export default new Props();
|
package/src/utils/editor.ts
CHANGED
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
19
|
+
import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
22
20
|
import { NodeType } from '@tmagic/schema';
|
|
23
21
|
import type StageCore from '@tmagic/stage';
|
|
24
22
|
import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
|
|
@@ -27,8 +25,6 @@ import { Layout } from '@editor/type';
|
|
|
27
25
|
|
|
28
26
|
export const COPY_STORAGE_KEY = '$MagicEditorCopyData';
|
|
29
27
|
|
|
30
|
-
export const generateId = (type: string | number): string => `${type}_${random(10000, false)}`;
|
|
31
|
-
|
|
32
28
|
/**
|
|
33
29
|
* 获取所有页面配置
|
|
34
30
|
* @param app DSL跟节点
|
|
@@ -74,51 +70,6 @@ export const generatePageName = (pageNameList: string[]): string => {
|
|
|
74
70
|
*/
|
|
75
71
|
export const generatePageNameByApp = (app: MApp): string => generatePageName(getPageNameList(getPageList(app)));
|
|
76
72
|
|
|
77
|
-
/**
|
|
78
|
-
* 复制页面时,需要把组件下关联的弹窗id换测复制出来的弹窗的id
|
|
79
|
-
* @param {number} oldId 复制的源弹窗id
|
|
80
|
-
* @param {number} popId 新的弹窗id
|
|
81
|
-
* @param {Object} pageConfig 页面配置
|
|
82
|
-
*/
|
|
83
|
-
const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
|
|
84
|
-
pageConfig.items?.forEach((config) => {
|
|
85
|
-
if (config.pop === oldId) {
|
|
86
|
-
config.pop = popId;
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (config.popId === oldId) {
|
|
91
|
-
config.popId = popId;
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (Array.isArray(config.items)) {
|
|
96
|
-
updatePopId(oldId, popId, config as MPage);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* 将组件与组件的子元素配置中的id都设置成一个新的ID
|
|
103
|
-
* @param {Object} config 组件配置
|
|
104
|
-
*/
|
|
105
|
-
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
106
|
-
export const setNewItemId = (config: MNode, parent?: MPage) => {
|
|
107
|
-
const oldId = config.id;
|
|
108
|
-
|
|
109
|
-
config.id = generateId(config.type || 'component');
|
|
110
|
-
config.name = `${config.name?.replace(/_(\d+)$/, '')}_${config.id}`;
|
|
111
|
-
|
|
112
|
-
// 只有弹窗在页面下的一级子元素才有效
|
|
113
|
-
if (isPop(config) && parent?.type === NodeType.PAGE) {
|
|
114
|
-
updatePopId(oldId, config.id, parent);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (config.items && Array.isArray(config.items)) {
|
|
118
|
-
config.items.forEach((item) => setNewItemId(item, config as MPage));
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
73
|
/**
|
|
123
74
|
* @param {Object} node
|
|
124
75
|
* @returns {boolean}
|
|
@@ -142,9 +93,13 @@ export const toRelative = (node: MNode) => {
|
|
|
142
93
|
|
|
143
94
|
const setTop2Middle = (node: MNode, parentNode: MNode, stage: StageCore) => {
|
|
144
95
|
const style = node.style || {};
|
|
145
|
-
|
|
96
|
+
let height = style.height || 0;
|
|
146
97
|
|
|
147
|
-
if (!stage || typeof style.top !== 'undefined' || !parentNode.style
|
|
98
|
+
if (!stage || typeof style.top !== 'undefined' || !parentNode.style) return style;
|
|
99
|
+
|
|
100
|
+
if (!isNumber(height)) {
|
|
101
|
+
height = 0;
|
|
102
|
+
}
|
|
148
103
|
|
|
149
104
|
const { height: parentHeight } = parentNode.style;
|
|
150
105
|
|
package/src/utils/props.ts
CHANGED
|
@@ -20,7 +20,6 @@ import { FormConfig, FormState } from '@tmagic/form';
|
|
|
20
20
|
|
|
21
21
|
import editorService from '@editor/services/editor';
|
|
22
22
|
import eventsService from '@editor/services/events';
|
|
23
|
-
import { generateId } from '@editor/utils/editor';
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* 统一为组件属性表单加上事件、高级、样式配置
|
|
@@ -161,6 +160,21 @@ export const fillConfig = (config: FormConfig = []) => [
|
|
|
161
160
|
},
|
|
162
161
|
],
|
|
163
162
|
},
|
|
163
|
+
{
|
|
164
|
+
type: 'fieldset',
|
|
165
|
+
legend: '变形',
|
|
166
|
+
name: 'transform',
|
|
167
|
+
items: [
|
|
168
|
+
{
|
|
169
|
+
name: 'rotate',
|
|
170
|
+
text: '旋转角度',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'scale',
|
|
174
|
+
text: '缩放',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
164
178
|
],
|
|
165
179
|
},
|
|
166
180
|
],
|
|
@@ -229,9 +243,9 @@ export const DEFAULT_CONFIG: FormConfig = fillConfig([]);
|
|
|
229
243
|
* @param type 组件类型
|
|
230
244
|
* @returns Object
|
|
231
245
|
*/
|
|
232
|
-
export const getDefaultPropsValue = (type: string) => ({
|
|
246
|
+
export const getDefaultPropsValue = (type: string, id: string) => ({
|
|
233
247
|
type,
|
|
234
|
-
id
|
|
248
|
+
id,
|
|
235
249
|
style: {},
|
|
236
250
|
name: type,
|
|
237
251
|
});
|