@tmagic/editor 1.0.4 → 1.1.0-beta.1
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 +237 -98
- package/dist/tmagic-editor.es.js.map +1 -1
- package/dist/tmagic-editor.umd.js +269 -129
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/dist/types/src/Editor.vue.d.ts +28 -1
- package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -0
- package/dist/types/src/services/editor.d.ts +6 -0
- package/dist/types/src/type.d.ts +3 -0
- package/dist/types/src/utils/editor.d.ts +8 -4
- package/package.json +8 -8
- package/src/Editor.vue +28 -6
- package/src/components/Icon.vue +1 -1
- package/src/components/ToolButton.vue +1 -1
- package/src/fields/UISelect.vue +1 -1
- package/src/layouts/AddPageBox.vue +1 -1
- package/src/layouts/PropsPanel.vue +12 -9
- package/src/layouts/sidebar/ComponentListPanel.vue +55 -2
- package/src/layouts/sidebar/LayerMenu.vue +1 -1
- package/src/layouts/sidebar/LayerPanel.vue +1 -1
- package/src/layouts/sidebar/Sidebar.vue +4 -4
- package/src/layouts/sidebar/TabPane.vue +7 -5
- package/src/layouts/workspace/PageBar.vue +1 -1
- package/src/layouts/workspace/Stage.vue +52 -11
- package/src/layouts/workspace/ViewerMenu.vue +1 -1
- package/src/services/editor.ts +74 -17
- package/src/type.ts +3 -0
- package/src/utils/editor.ts +45 -35
|
@@ -3,7 +3,7 @@ import { PropType } from 'vue';
|
|
|
3
3
|
import type { FormConfig } from '@tmagic/form';
|
|
4
4
|
import type { MApp, MNode } from '@tmagic/schema';
|
|
5
5
|
import type StageCore from '@tmagic/stage';
|
|
6
|
-
import
|
|
6
|
+
import { MoveableOptions } from '@tmagic/stage';
|
|
7
7
|
import type { ComponentGroup, MenuBarData, MenuItem, Services, SideBarData, StageRect } from './type';
|
|
8
8
|
declare const _default: DefineComponent<{
|
|
9
9
|
/** 页面初始值 */
|
|
@@ -72,6 +72,18 @@ declare const _default: DefineComponent<{
|
|
|
72
72
|
type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
|
|
73
73
|
default: (el: HTMLElement) => boolean;
|
|
74
74
|
};
|
|
75
|
+
isContainer: {
|
|
76
|
+
type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
|
|
77
|
+
default: (el: HTMLElement) => boolean;
|
|
78
|
+
};
|
|
79
|
+
containerHighlightClassName: {
|
|
80
|
+
type: StringConstructor;
|
|
81
|
+
default: string;
|
|
82
|
+
};
|
|
83
|
+
containerHighlightDuration: {
|
|
84
|
+
type: NumberConstructor;
|
|
85
|
+
default: number;
|
|
86
|
+
};
|
|
75
87
|
stageRect: {
|
|
76
88
|
type: PropType<StageRect>;
|
|
77
89
|
};
|
|
@@ -149,6 +161,18 @@ declare const _default: DefineComponent<{
|
|
|
149
161
|
type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
|
|
150
162
|
default: (el: HTMLElement) => boolean;
|
|
151
163
|
};
|
|
164
|
+
isContainer: {
|
|
165
|
+
type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
|
|
166
|
+
default: (el: HTMLElement) => boolean;
|
|
167
|
+
};
|
|
168
|
+
containerHighlightClassName: {
|
|
169
|
+
type: StringConstructor;
|
|
170
|
+
default: string;
|
|
171
|
+
};
|
|
172
|
+
containerHighlightDuration: {
|
|
173
|
+
type: NumberConstructor;
|
|
174
|
+
default: number;
|
|
175
|
+
};
|
|
152
176
|
stageRect: {
|
|
153
177
|
type: PropType<StageRect>;
|
|
154
178
|
};
|
|
@@ -174,5 +198,8 @@ declare const _default: DefineComponent<{
|
|
|
174
198
|
propsValues: Record<string, MNode>;
|
|
175
199
|
eventMethodList: Record<string, any>;
|
|
176
200
|
canSelect: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
201
|
+
isContainer: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
202
|
+
containerHighlightClassName: string;
|
|
203
|
+
containerHighlightDuration: number;
|
|
177
204
|
}>;
|
|
178
205
|
export default _default;
|
|
@@ -10,5 +10,7 @@ declare const _default: DefineComponent<{}, {
|
|
|
10
10
|
}[] | undefined>;
|
|
11
11
|
appendComponent({ text, type, data }: ComponentItem): void;
|
|
12
12
|
dragstartHandler({ text, type, data }: ComponentItem, e: DragEvent): void;
|
|
13
|
+
dragendHandler(): void;
|
|
14
|
+
dragHandler(e: DragEvent): void;
|
|
13
15
|
}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{}>>, {}>;
|
|
14
16
|
export default _default;
|
|
@@ -111,6 +111,12 @@ declare class Editor extends BaseService {
|
|
|
111
111
|
* @param offset 偏移量
|
|
112
112
|
*/
|
|
113
113
|
moveLayer(offset: number | LayerOffset): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* 移动到指定容器中
|
|
116
|
+
* @param config 需要移动的节点
|
|
117
|
+
* @param targetId 容器ID
|
|
118
|
+
*/
|
|
119
|
+
moveToContainer(config: MNode, targetId: Id): Promise<MNode | undefined>;
|
|
114
120
|
/**
|
|
115
121
|
* 撤销当前操作
|
|
116
122
|
* @returns 上一次数据
|
package/dist/types/src/type.d.ts
CHANGED
|
@@ -25,9 +25,12 @@ export interface Services {
|
|
|
25
25
|
export interface StageOptions {
|
|
26
26
|
runtimeUrl: string;
|
|
27
27
|
autoScrollIntoView: boolean;
|
|
28
|
+
containerHighlightClassName: string;
|
|
29
|
+
containerHighlightDuration: number;
|
|
28
30
|
render: () => HTMLDivElement;
|
|
29
31
|
moveableOptions: MoveableOptions | ((core?: StageCore) => MoveableOptions);
|
|
30
32
|
canSelect: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
33
|
+
isContainer: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
31
34
|
updateDragEl: (el: HTMLDivElement) => void;
|
|
32
35
|
}
|
|
33
36
|
export interface StoreState {
|
|
@@ -32,9 +32,13 @@ export declare const generatePageNameByApp: (app: MApp) => string;
|
|
|
32
32
|
*/
|
|
33
33
|
export declare const isFixed: (node: MNode) => boolean;
|
|
34
34
|
export declare const getNodeIndex: (node: MNode, parent: MContainer | MApp) => number;
|
|
35
|
-
export declare const
|
|
36
|
-
export declare const
|
|
35
|
+
export declare const getRelativeStyle: (style?: Record<string, any>) => Record<string, any>;
|
|
36
|
+
export declare const getInitPositionStyle: (style: Record<string, any> | undefined, layout: Layout, parentNode: MNode, stage: StageCore) => Record<string, any>;
|
|
37
37
|
export declare const setLayout: (node: MNode, layout: Layout) => MNode;
|
|
38
|
-
export declare const change2Fixed: (node: MNode, root: MApp) =>
|
|
39
|
-
|
|
38
|
+
export declare const change2Fixed: (node: MNode, root: MApp) => {
|
|
39
|
+
left: number;
|
|
40
|
+
top: number;
|
|
41
|
+
};
|
|
42
|
+
export declare const Fixed2Other: (node: MNode, root: MApp, getLayout: (parent: MNode, node?: MNode | undefined) => Promise<Layout>) => Promise<Record<string, any>>;
|
|
40
43
|
export declare const getGuideLineFromCache: (key: string) => number[];
|
|
44
|
+
export declare const fixNodeLeft: (config: MNode, parent: MContainer, doc?: Document | undefined) => any;
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.
|
|
2
|
+
"version": "1.1.0-beta.1",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"dist/*",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@babel/core": "^7.18.0",
|
|
45
|
-
"@element-plus/icons": "
|
|
46
|
-
"@tmagic/core": "1.0.
|
|
47
|
-
"@tmagic/form": "1.0.
|
|
48
|
-
"@tmagic/schema": "1.0.
|
|
49
|
-
"@tmagic/stage": "1.0.
|
|
50
|
-
"@tmagic/utils": "1.0.
|
|
45
|
+
"@element-plus/icons-vue": "^2.0.6",
|
|
46
|
+
"@tmagic/core": "1.1.0-beta.1",
|
|
47
|
+
"@tmagic/form": "1.1.0-beta.1",
|
|
48
|
+
"@tmagic/schema": "1.1.0-beta.1",
|
|
49
|
+
"@tmagic/stage": "1.1.0-beta.1",
|
|
50
|
+
"@tmagic/utils": "1.1.0-beta.1",
|
|
51
51
|
"buffer": "^6.0.3",
|
|
52
52
|
"color": "^3.1.3",
|
|
53
53
|
"element-plus": "^2.2.6",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"vue": "^3.2.0"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"@tmagic/form": "1.0.
|
|
63
|
+
"@tmagic/form": "1.1.0-beta.1",
|
|
64
64
|
"element-plus": "^2.2.6",
|
|
65
65
|
"monaco-editor": "^0.32.1",
|
|
66
66
|
"vue": "^3.2.0"
|
package/src/Editor.vue
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
<template #sidebar>
|
|
8
8
|
<slot name="sidebar" :editorService="editorService">
|
|
9
9
|
<sidebar :data="sidebar">
|
|
10
|
-
<template #layer-panel>
|
|
11
|
-
<slot name="layer-panel"></slot>
|
|
10
|
+
<template #layer-panel-header>
|
|
11
|
+
<slot name="layer-panel-header"></slot>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
|
-
<template #component-list-panel>
|
|
15
|
-
<slot name="component-list-panel"></slot>
|
|
14
|
+
<template #component-list-panel-header>
|
|
15
|
+
<slot name="component-list-panel-header"></slot>
|
|
16
16
|
</template>
|
|
17
17
|
</sidebar>
|
|
18
18
|
</slot>
|
|
@@ -30,7 +30,11 @@
|
|
|
30
30
|
|
|
31
31
|
<template #props-panel>
|
|
32
32
|
<slot name="props-panel">
|
|
33
|
-
<props-panel ref="propsPanel" @mounted="(instance) => $emit('props-panel-mounted', instance)"
|
|
33
|
+
<props-panel ref="propsPanel" @mounted="(instance) => $emit('props-panel-mounted', instance)">
|
|
34
|
+
<template #props-panel-header>
|
|
35
|
+
<slot name="props-panel-header"></slot>
|
|
36
|
+
</template>
|
|
37
|
+
</props-panel>
|
|
34
38
|
</slot>
|
|
35
39
|
</template>
|
|
36
40
|
|
|
@@ -45,7 +49,7 @@ import { EventOption } from '@tmagic/core';
|
|
|
45
49
|
import type { FormConfig } from '@tmagic/form';
|
|
46
50
|
import type { MApp, MNode } from '@tmagic/schema';
|
|
47
51
|
import type StageCore from '@tmagic/stage';
|
|
48
|
-
import
|
|
52
|
+
import { CONTAINER_HIGHLIGHT_CLASS, MoveableOptions } from '@tmagic/stage';
|
|
49
53
|
|
|
50
54
|
import Framework from '@editor/layouts/Framework.vue';
|
|
51
55
|
import NavMenu from '@editor/layouts/NavMenu.vue';
|
|
@@ -150,6 +154,21 @@ export default defineComponent({
|
|
|
150
154
|
default: (el: HTMLElement) => Boolean(el.id),
|
|
151
155
|
},
|
|
152
156
|
|
|
157
|
+
isContainer: {
|
|
158
|
+
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
159
|
+
default: (el: HTMLElement) => el.classList.contains('magic-ui-container'),
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
containerHighlightClassName: {
|
|
163
|
+
type: String,
|
|
164
|
+
default: CONTAINER_HIGHLIGHT_CLASS,
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
containerHighlightDuration: {
|
|
168
|
+
type: Number,
|
|
169
|
+
default: 800,
|
|
170
|
+
},
|
|
171
|
+
|
|
153
172
|
stageRect: {
|
|
154
173
|
type: [String, Object] as PropType<StageRect>,
|
|
155
174
|
},
|
|
@@ -265,6 +284,9 @@ export default defineComponent({
|
|
|
265
284
|
moveableOptions: props.moveableOptions,
|
|
266
285
|
canSelect: props.canSelect,
|
|
267
286
|
updateDragEl: props.updateDragEl,
|
|
287
|
+
isContainer: props.isContainer,
|
|
288
|
+
containerHighlightClassName: props.containerHighlightClassName,
|
|
289
|
+
containerHighlightDuration: props.containerHighlightDuration,
|
|
268
290
|
}),
|
|
269
291
|
);
|
|
270
292
|
|
package/src/components/Icon.vue
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
|
|
53
53
|
<script lang="ts">
|
|
54
54
|
import { computed, defineComponent, inject, markRaw, PropType } from 'vue';
|
|
55
|
-
import { ArrowDown, Back, Delete, Grid, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons';
|
|
55
|
+
import { ArrowDown, Back, Delete, Grid, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons-vue';
|
|
56
56
|
|
|
57
57
|
import { NodeType } from '@tmagic/schema';
|
|
58
58
|
|
package/src/fields/UISelect.vue
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<script lang="ts">
|
|
16
16
|
import { computed, defineComponent, inject, markRaw, ref } from 'vue';
|
|
17
|
-
import { Close, Delete, Pointer } from '@element-plus/icons';
|
|
17
|
+
import { Close, Delete, Pointer } from '@element-plus/icons-vue';
|
|
18
18
|
|
|
19
19
|
import { FormState } from '@tmagic/form';
|
|
20
20
|
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<m-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
<div class="`m-editor-props-panel">
|
|
3
|
+
<slot name="props-panel-header"></slot>
|
|
4
|
+
<m-form
|
|
5
|
+
:class="`m-editor-props-panel ${propsPanelSize}`"
|
|
6
|
+
:popper-class="`m-editor-props-panel-popper ${propsPanelSize}`"
|
|
7
|
+
ref="configForm"
|
|
8
|
+
:size="propsPanelSize"
|
|
9
|
+
:init-values="values"
|
|
10
|
+
:config="curFormConfig"
|
|
11
|
+
@change="submit"
|
|
12
|
+
></m-form>
|
|
13
|
+
</div>
|
|
11
14
|
</template>
|
|
12
15
|
|
|
13
16
|
<script lang="ts">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-scrollbar>
|
|
3
|
-
<slot name="component-list-panel"></slot>
|
|
3
|
+
<slot name="component-list-panel-header"></slot>
|
|
4
|
+
|
|
4
5
|
<el-collapse class="ui-component-panel" :model-value="collapseValue">
|
|
5
6
|
<el-input
|
|
6
7
|
prefix-icon="el-icon-search"
|
|
@@ -20,6 +21,8 @@
|
|
|
20
21
|
:key="item.type"
|
|
21
22
|
@click="appendComponent(item)"
|
|
22
23
|
@dragstart="dragstartHandler(item, $event)"
|
|
24
|
+
@dragend="dragendHandler"
|
|
25
|
+
@drag="dragHandler"
|
|
23
26
|
>
|
|
24
27
|
<m-icon :icon="item.icon"></m-icon>
|
|
25
28
|
|
|
@@ -37,8 +40,12 @@
|
|
|
37
40
|
import { computed, defineComponent, inject, ref } from 'vue';
|
|
38
41
|
import serialize from 'serialize-javascript';
|
|
39
42
|
|
|
43
|
+
import type StageCore from '@tmagic/stage';
|
|
44
|
+
import { GHOST_EL_ID_PREFIX } from '@tmagic/stage';
|
|
45
|
+
import { addClassName, removeClassNameByClassName } from '@tmagic/utils';
|
|
46
|
+
|
|
40
47
|
import MIcon from '@editor/components/Icon.vue';
|
|
41
|
-
import type { ComponentGroup, ComponentItem, Services } from '@editor/type';
|
|
48
|
+
import type { ComponentGroup, ComponentItem, Services, StageOptions } from '@editor/type';
|
|
42
49
|
|
|
43
50
|
export default defineComponent({
|
|
44
51
|
name: 'ui-component-panel',
|
|
@@ -48,6 +55,9 @@ export default defineComponent({
|
|
|
48
55
|
setup() {
|
|
49
56
|
const searchText = ref('');
|
|
50
57
|
const services = inject<Services>('services');
|
|
58
|
+
const stageOptions = inject<StageOptions>('stageOptions');
|
|
59
|
+
|
|
60
|
+
const stage = computed(() => services?.editorService.get<StageCore>('stage'));
|
|
51
61
|
const list = computed(() =>
|
|
52
62
|
services?.componentListService.getList().map((group: ComponentGroup) => ({
|
|
53
63
|
...group,
|
|
@@ -60,6 +70,10 @@ export default defineComponent({
|
|
|
60
70
|
.map((x, i) => i),
|
|
61
71
|
);
|
|
62
72
|
|
|
73
|
+
let timeout: NodeJS.Timeout | undefined;
|
|
74
|
+
let clientX: number;
|
|
75
|
+
let clientY: number;
|
|
76
|
+
|
|
63
77
|
return {
|
|
64
78
|
searchText,
|
|
65
79
|
collapseValue,
|
|
@@ -86,6 +100,45 @@ export default defineComponent({
|
|
|
86
100
|
);
|
|
87
101
|
}
|
|
88
102
|
},
|
|
103
|
+
|
|
104
|
+
dragendHandler() {
|
|
105
|
+
if (timeout) {
|
|
106
|
+
globalThis.clearTimeout(timeout);
|
|
107
|
+
timeout = undefined;
|
|
108
|
+
}
|
|
109
|
+
const doc = stage.value?.renderer.contentWindow?.document;
|
|
110
|
+
if (doc && stageOptions) {
|
|
111
|
+
removeClassNameByClassName(doc, stageOptions.containerHighlightClassName);
|
|
112
|
+
}
|
|
113
|
+
clientX = 0;
|
|
114
|
+
clientY = 0;
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
dragHandler(e: DragEvent) {
|
|
118
|
+
if (e.clientX !== clientX || e.clientY !== clientY) {
|
|
119
|
+
clientX = e.clientX;
|
|
120
|
+
clientY = e.clientY;
|
|
121
|
+
if (timeout) {
|
|
122
|
+
globalThis.clearTimeout(timeout);
|
|
123
|
+
timeout = undefined;
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (timeout) return;
|
|
129
|
+
|
|
130
|
+
timeout = globalThis.setTimeout(async () => {
|
|
131
|
+
if (!stageOptions || !stage.value) return;
|
|
132
|
+
const doc = stage.value.renderer.contentWindow?.document;
|
|
133
|
+
const els = stage.value.getElementsFromPoint(e);
|
|
134
|
+
for (const el of els) {
|
|
135
|
+
if (doc && !el.id.startsWith(GHOST_EL_ID_PREFIX) && (await stageOptions.isContainer(el))) {
|
|
136
|
+
addClassName(el, doc, stageOptions?.containerHighlightClassName);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}, stageOptions?.containerHighlightDuration);
|
|
141
|
+
},
|
|
89
142
|
};
|
|
90
143
|
},
|
|
91
144
|
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { computed, defineComponent, inject, markRaw, ref } from 'vue';
|
|
7
|
-
import { Delete, DocumentCopy, Files, Plus } from '@element-plus/icons';
|
|
7
|
+
import { Delete, DocumentCopy, Files, Plus } from '@element-plus/icons-vue';
|
|
8
8
|
|
|
9
9
|
import { NodeType } from '@tmagic/schema';
|
|
10
10
|
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
tab-position="left"
|
|
8
8
|
>
|
|
9
9
|
<tab-pane v-for="(item, index) in data.items" :key="index" :data="item">
|
|
10
|
-
<template #layer-panel v-if="item === 'layer'">
|
|
11
|
-
<slot name="layer-panel"></slot>
|
|
10
|
+
<template #layer-panel-header v-if="item === 'layer'">
|
|
11
|
+
<slot name="layer-panel-header"></slot>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
|
-
<template #component-list-panel v-if="item === 'component-list'">
|
|
15
|
-
<slot name="component-list-panel"></slot>
|
|
14
|
+
<template #component-list-panel-header v-if="item === 'component-list'">
|
|
15
|
+
<slot name="component-list-panel-header"></slot>
|
|
16
16
|
</template>
|
|
17
17
|
</tab-pane>
|
|
18
18
|
</el-tabs>
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
</template>
|
|
9
9
|
|
|
10
10
|
<component :is="config.component" v-bind="config.props || {}" v-on="config?.listeners || {}">
|
|
11
|
-
<template #
|
|
12
|
-
<slot name="
|
|
11
|
+
<template #component-list-panel-header v-if="data === 'component-list' || config.slots?.componentListPanelHeader">
|
|
12
|
+
<slot v-if="data === 'component-list'" name="component-list-panel-header"></slot>
|
|
13
|
+
<component v-else-if="config.slots?.componentListPanelHeader" :is="config.slots.componentListPanelHeader" />
|
|
13
14
|
</template>
|
|
14
15
|
|
|
15
|
-
<template #
|
|
16
|
-
<slot name="
|
|
16
|
+
<template #layer-panel-header v-if="data === 'layer' || config.slots?.layerPanelHeader">
|
|
17
|
+
<slot v-if="data === 'layer'" name="layer-panel-header"></slot>
|
|
18
|
+
<component v-else-if="config.slots?.layerPanelHeader" :is="config.slots.layerPanelHeader" />
|
|
17
19
|
</template>
|
|
18
20
|
|
|
19
21
|
<template #layer-node-content="{ data, node }" v-if="config.slots?.layerNodeContent">
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
|
|
26
28
|
<script lang="ts">
|
|
27
29
|
import { computed, defineComponent, PropType } from 'vue';
|
|
28
|
-
import { Coin, Files } from '@element-plus/icons';
|
|
30
|
+
import { Coin, Files } from '@element-plus/icons-vue';
|
|
29
31
|
|
|
30
32
|
import MIcon from '@editor/components/Icon.vue';
|
|
31
33
|
import { SideComponent, SideItem } from '@editor/type';
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
toRaw,
|
|
71
71
|
watch,
|
|
72
72
|
} from 'vue';
|
|
73
|
-
import { ArrowLeftBold, ArrowRightBold, CaretBottom, Delete, DocumentCopy, Plus } from '@element-plus/icons';
|
|
73
|
+
import { ArrowLeftBold, ArrowRightBold, CaretBottom, Delete, DocumentCopy, Plus } from '@element-plus/icons-vue';
|
|
74
74
|
|
|
75
75
|
import type { MApp, MPage } from '@tmagic/schema';
|
|
76
76
|
import { NodeType } from '@tmagic/schema';
|
|
@@ -35,8 +35,15 @@ import {
|
|
|
35
35
|
} from 'vue';
|
|
36
36
|
import { cloneDeep } from 'lodash-es';
|
|
37
37
|
|
|
38
|
-
import type { MApp, MNode, MPage } from '@tmagic/schema';
|
|
39
|
-
import StageCore, {
|
|
38
|
+
import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
39
|
+
import StageCore, {
|
|
40
|
+
calcValueByFontsize,
|
|
41
|
+
getOffset,
|
|
42
|
+
GuidesType,
|
|
43
|
+
Runtime,
|
|
44
|
+
SortEventData,
|
|
45
|
+
UpdateEventData,
|
|
46
|
+
} from '@tmagic/stage';
|
|
40
47
|
|
|
41
48
|
import ScrollViewer from '@editor/components/ScrollViewer.vue';
|
|
42
49
|
import {
|
|
@@ -90,6 +97,9 @@ export default defineComponent({
|
|
|
90
97
|
runtimeUrl: stageOptions.runtimeUrl,
|
|
91
98
|
zoom: zoom.value,
|
|
92
99
|
autoScrollIntoView: stageOptions.autoScrollIntoView,
|
|
100
|
+
isContainer: stageOptions.isContainer,
|
|
101
|
+
containerHighlightClassName: stageOptions.containerHighlightClassName,
|
|
102
|
+
containerHighlightDuration: stageOptions.containerHighlightDuration,
|
|
93
103
|
canSelect: (el, event, stop) => {
|
|
94
104
|
const elCanSelect = stageOptions.canSelect(el);
|
|
95
105
|
// 在组件联动过程中不能再往下选择,返回并触发 ui-select
|
|
@@ -122,6 +132,10 @@ export default defineComponent({
|
|
|
122
132
|
});
|
|
123
133
|
|
|
124
134
|
stage?.on('update', (ev: UpdateEventData) => {
|
|
135
|
+
if (ev.parentEl) {
|
|
136
|
+
services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
125
139
|
services?.editorService.update({ id: ev.el.id, style: ev.style });
|
|
126
140
|
});
|
|
127
141
|
|
|
@@ -207,23 +221,50 @@ export default defineComponent({
|
|
|
207
221
|
|
|
208
222
|
async dropHandler(e: DragEvent) {
|
|
209
223
|
e.preventDefault();
|
|
210
|
-
|
|
224
|
+
|
|
225
|
+
const doc = stage?.renderer.contentWindow?.document;
|
|
226
|
+
const parentEl: HTMLElement | null | undefined = doc?.querySelector(
|
|
227
|
+
`.${stageOptions?.containerHighlightClassName}`,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
let parent: MContainer | undefined = page.value;
|
|
231
|
+
if (parentEl) {
|
|
232
|
+
parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (e.dataTransfer && parent && stageContainer.value && stage) {
|
|
211
236
|
// eslint-disable-next-line no-eval
|
|
212
237
|
const config = eval(`(${e.dataTransfer.getData('data')})`);
|
|
213
|
-
const layout = await services?.editorService.getLayout(
|
|
238
|
+
const layout = await services?.editorService.getLayout(parent);
|
|
214
239
|
|
|
215
240
|
const containerRect = stageContainer.value.getBoundingClientRect();
|
|
216
241
|
const { scrollTop, scrollLeft } = stage.mask;
|
|
242
|
+
const { style = {} } = config;
|
|
243
|
+
|
|
244
|
+
let top = 0;
|
|
245
|
+
let left = 0;
|
|
246
|
+
let position = 'relative';
|
|
247
|
+
|
|
217
248
|
if (layout === Layout.ABSOLUTE) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
249
|
+
position = 'absolute';
|
|
250
|
+
top = e.clientY - containerRect.top + scrollTop;
|
|
251
|
+
left = e.clientX - containerRect.left + scrollLeft;
|
|
252
|
+
|
|
253
|
+
if (parentEl && doc) {
|
|
254
|
+
const { left: parentLeft, top: parentTop } = getOffset(parentEl);
|
|
255
|
+
left = left - calcValueByFontsize(doc, parentLeft);
|
|
256
|
+
top = top - calcValueByFontsize(doc, parentTop);
|
|
257
|
+
}
|
|
224
258
|
}
|
|
225
259
|
|
|
226
|
-
|
|
260
|
+
config.style = {
|
|
261
|
+
...style,
|
|
262
|
+
position,
|
|
263
|
+
top,
|
|
264
|
+
left,
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
services?.editorService.add(config, parent);
|
|
227
268
|
}
|
|
228
269
|
},
|
|
229
270
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { computed, defineComponent, inject, markRaw, onMounted, reactive, ref, watch } from 'vue';
|
|
7
|
-
import { Bottom, Delete, DocumentCopy, Top } from '@element-plus/icons';
|
|
7
|
+
import { Bottom, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
|
|
8
8
|
|
|
9
9
|
import { NodeType } from '@tmagic/schema';
|
|
10
10
|
import type StageCore from '@tmagic/stage';
|