@tmagic/editor 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/style.css +4 -0
- package/dist/tmagic-editor.js +305 -249
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +308 -253
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +9 -9
- package/src/Editor.vue +1 -1
- package/src/components/CodeDraftEditor.vue +2 -10
- package/src/components/FunctionEditor.vue +58 -13
- package/src/components/Layout.vue +1 -1
- package/src/fields/CodeSelect.vue +23 -7
- package/src/fields/UISelect.vue +2 -2
- package/src/index.ts +1 -1
- package/src/layouts/AddPageBox.vue +4 -1
- package/src/layouts/Framework.vue +10 -8
- package/src/layouts/NavMenu.vue +9 -6
- package/src/layouts/PropsPanel.vue +3 -7
- package/src/layouts/sidebar/ComponentListPanel.vue +1 -2
- package/src/layouts/sidebar/LayerPanel.vue +8 -9
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +10 -39
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -6
- package/src/layouts/workspace/Breadcrumb.vue +5 -6
- package/src/layouts/workspace/PageBar.vue +2 -2
- package/src/layouts/workspace/PageBarScrollContainer.vue +4 -2
- package/src/layouts/workspace/Stage.vue +11 -10
- package/src/layouts/workspace/ViewerMenu.vue +5 -6
- package/src/layouts/workspace/Workspace.vue +2 -3
- package/src/services/BaseService.ts +1 -1
- package/src/services/codeBlock.ts +15 -24
- package/src/services/componentList.ts +1 -1
- package/src/services/editor.ts +119 -79
- package/src/services/events.ts +1 -1
- package/src/services/history.ts +1 -1
- package/src/services/props.ts +1 -1
- package/src/services/ui.ts +8 -10
- package/src/theme/code-block.scss +4 -0
- package/src/type.ts +7 -13
- package/src/utils/config.ts +1 -1
- package/src/utils/editor.ts +8 -2
- package/src/utils/index.ts +1 -1
- package/src/utils/logger.ts +1 -1
- package/src/utils/operator.ts +12 -12
- package/src/utils/props.ts +1 -1
- package/src/utils/stage.ts +6 -6
- package/src/utils/undo-redo.ts +1 -1
- package/types/Editor.vue.d.ts +1 -1
- package/types/components/CodeDraftEditor.vue.d.ts +1 -2
- package/types/components/FunctionEditor.vue.d.ts +17 -0
- package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +23 -5
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +5 -0
- package/types/layouts/workspace/Workspace.vue.d.ts +2 -3
- package/types/services/codeBlock.d.ts +0 -12
- package/types/services/editor.d.ts +6 -6
- package/types/services/ui.d.ts +23 -24
- package/types/type.d.ts +5 -11
- package/types/utils/operator.d.ts +1 -1
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
</TMagicScrollbar>
|
|
79
79
|
|
|
80
80
|
<!-- 代码块编辑区 -->
|
|
81
|
-
<code-block-editor v-if="isShowCodeBlockEditor">
|
|
81
|
+
<code-block-editor v-if="isShowCodeBlockEditor" :paramsColConfig="paramsColConfig">
|
|
82
82
|
<template #code-block-edit-panel-header="{ id }">
|
|
83
83
|
<slot name="code-block-edit-panel-header" :id="id"></slot>
|
|
84
84
|
</template>
|
|
@@ -92,17 +92,18 @@ import { Close, Edit, Link, View } from '@element-plus/icons-vue';
|
|
|
92
92
|
import { cloneDeep, forIn, isEmpty } from 'lodash-es';
|
|
93
93
|
|
|
94
94
|
import { TMagicButton, TMagicInput, tMagicMessage, TMagicScrollbar, TMagicTooltip, TMagicTree } from '@tmagic/design';
|
|
95
|
+
import { ColumnConfig } from '@tmagic/form';
|
|
95
96
|
import { CodeBlockContent, Id } from '@tmagic/schema';
|
|
96
|
-
import StageCore from '@tmagic/stage';
|
|
97
97
|
|
|
98
98
|
import Icon from '../../../components/Icon.vue';
|
|
99
99
|
import type { CodeRelation, Services } from '../../../type';
|
|
100
|
-
import { CodeDeleteErrorType, CodeDslItem,
|
|
100
|
+
import { CodeDeleteErrorType, CodeDslItem, ListState } from '../../../type';
|
|
101
101
|
|
|
102
102
|
import codeBlockEditor from './CodeBlockEditor.vue';
|
|
103
103
|
|
|
104
104
|
const props = defineProps<{
|
|
105
105
|
customError?: (id: Id, errorType: CodeDeleteErrorType) => any;
|
|
106
|
+
paramsColConfig?: ColumnConfig;
|
|
106
107
|
}>();
|
|
107
108
|
|
|
108
109
|
const services = inject<Services>('services');
|
|
@@ -169,7 +170,6 @@ const createCodeBlock = async () => {
|
|
|
169
170
|
content: `({app, params}) => {\n // place your code here\n}`,
|
|
170
171
|
params: [],
|
|
171
172
|
};
|
|
172
|
-
await codeBlockService.setMode(CodeEditorMode.EDITOR);
|
|
173
173
|
const id = await codeBlockService.getUniqueId();
|
|
174
174
|
await codeBlockService.setCodeDslById(id, codeConfig);
|
|
175
175
|
codeBlockService.setCodeEditorContent(true, id);
|
|
@@ -177,7 +177,6 @@ const createCodeBlock = async () => {
|
|
|
177
177
|
|
|
178
178
|
// 编辑代码块
|
|
179
179
|
const editCode = async (key: Id) => {
|
|
180
|
-
await services?.codeBlockService.setMode(CodeEditorMode.EDITOR);
|
|
181
180
|
services?.codeBlockService.setCodeEditorContent(true, key);
|
|
182
181
|
};
|
|
183
182
|
|
|
@@ -228,7 +227,7 @@ const getCompName = (compId: Id): string => {
|
|
|
228
227
|
|
|
229
228
|
// 选中组件
|
|
230
229
|
const selectComp = (compId: Id) => {
|
|
231
|
-
const stage = services?.editorService.get
|
|
230
|
+
const stage = services?.editorService.get('stage');
|
|
232
231
|
services?.editorService.select(compId);
|
|
233
232
|
stage?.select(compId);
|
|
234
233
|
};
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
import { computed, inject } from 'vue';
|
|
12
12
|
|
|
13
13
|
import { TMagicButton } from '@tmagic/design';
|
|
14
|
-
import type {
|
|
15
|
-
import type StageCore from '@tmagic/stage';
|
|
14
|
+
import type { MNode } from '@tmagic/schema';
|
|
16
15
|
import { getNodePath } from '@tmagic/utils';
|
|
17
16
|
|
|
18
17
|
import type { Services } from '../../type';
|
|
@@ -20,13 +19,13 @@ import type { Services } from '../../type';
|
|
|
20
19
|
const services = inject<Services>('services');
|
|
21
20
|
const editorService = services?.editorService;
|
|
22
21
|
|
|
23
|
-
const node = computed(() => editorService?.get
|
|
24
|
-
const nodes = computed(() => editorService?.get
|
|
25
|
-
const root = computed(() => editorService?.get
|
|
22
|
+
const node = computed(() => editorService?.get('node'));
|
|
23
|
+
const nodes = computed(() => editorService?.get('nodes') || []);
|
|
24
|
+
const root = computed(() => editorService?.get('root'));
|
|
26
25
|
const path = computed(() => getNodePath(node.value?.id || '', root.value?.items || []));
|
|
27
26
|
|
|
28
27
|
const select = async (node: MNode) => {
|
|
29
28
|
await editorService?.select(node);
|
|
30
|
-
editorService?.get
|
|
29
|
+
editorService?.get('stage')?.select(node.id);
|
|
31
30
|
};
|
|
32
31
|
</script>
|
|
@@ -51,7 +51,7 @@ import { computed, inject } from 'vue';
|
|
|
51
51
|
import { CaretBottom, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
|
52
52
|
|
|
53
53
|
import { TMagicIcon, TMagicPopover, TMagicTooltip } from '@tmagic/design';
|
|
54
|
-
import type {
|
|
54
|
+
import type { MPage } from '@tmagic/schema';
|
|
55
55
|
|
|
56
56
|
import ToolButton from '../../components/ToolButton.vue';
|
|
57
57
|
import type { Services } from '../../type';
|
|
@@ -61,7 +61,7 @@ import PageBarScrollContainer from './PageBarScrollContainer.vue';
|
|
|
61
61
|
const services = inject<Services>('services');
|
|
62
62
|
const editorService = services?.editorService;
|
|
63
63
|
|
|
64
|
-
const root = computed(() => editorService?.get
|
|
64
|
+
const root = computed(() => editorService?.get('root'));
|
|
65
65
|
|
|
66
66
|
const page = computed(() => editorService?.get('page'));
|
|
67
67
|
|
|
@@ -100,7 +100,7 @@ const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
|
|
|
100
100
|
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
const pageLength = computed(() => editorService?.get
|
|
103
|
+
const pageLength = computed(() => editorService?.get('pageLength'));
|
|
104
104
|
|
|
105
105
|
watch(pageLength, (length = 0, preLength = 0) => {
|
|
106
106
|
setTimeout(() => {
|
|
@@ -115,9 +115,11 @@ watch(pageLength, (length = 0, preLength = 0) => {
|
|
|
115
115
|
|
|
116
116
|
const addPage = () => {
|
|
117
117
|
if (!editorService) return;
|
|
118
|
+
const root = toRaw(editorService.get('root'));
|
|
119
|
+
if (!root) throw new Error('root 不能为空');
|
|
118
120
|
const pageConfig = {
|
|
119
121
|
type: NodeType.PAGE,
|
|
120
|
-
name: generatePageNameByApp(
|
|
122
|
+
name: generatePageNameByApp(root),
|
|
121
123
|
};
|
|
122
124
|
editorService.add(pageConfig);
|
|
123
125
|
};
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
import { computed, inject, markRaw, nextTick, onMounted, onUnmounted, ref, toRaw, watch, watchEffect } from 'vue';
|
|
31
31
|
import { cloneDeep } from 'lodash-es';
|
|
32
32
|
|
|
33
|
-
import type {
|
|
33
|
+
import type { MContainer } from '@tmagic/schema';
|
|
34
34
|
import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stage';
|
|
35
35
|
|
|
36
36
|
import ScrollViewer from '../../components/ScrollViewer.vue';
|
|
37
|
-
import { Layout, MenuButton, MenuComponent, Services, StageOptions
|
|
37
|
+
import { Layout, MenuButton, MenuComponent, Services, StageOptions } from '../../type';
|
|
38
38
|
import { useStage } from '../../utils/stage';
|
|
39
39
|
|
|
40
40
|
import ViewerMenu from './ViewerMenu.vue';
|
|
@@ -53,13 +53,14 @@ const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
|
|
|
53
53
|
const stageContainer = ref<HTMLDivElement>();
|
|
54
54
|
const menu = ref<InstanceType<typeof ViewerMenu>>();
|
|
55
55
|
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
const
|
|
56
|
+
const nodes = computed(() => services?.editorService.get('nodes') || []);
|
|
57
|
+
const isMultiSelect = computed(() => nodes.value.length > 1);
|
|
58
|
+
const stageRect = computed(() => services?.uiService.get('stageRect'));
|
|
59
|
+
const stageContainerRect = computed(() => services?.uiService.get('stageContainerRect'));
|
|
60
|
+
const root = computed(() => services?.editorService.get('root'));
|
|
61
|
+
const page = computed(() => services?.editorService.get('page'));
|
|
62
|
+
const zoom = computed(() => services?.uiService.get('zoom') || 1);
|
|
63
|
+
const node = computed(() => services?.editorService.get('node'));
|
|
63
64
|
|
|
64
65
|
watchEffect(() => {
|
|
65
66
|
if (stage || !page.value) return;
|
|
@@ -142,7 +143,7 @@ const dropHandler = async (e: DragEvent) => {
|
|
|
142
143
|
const doc = stage?.renderer.contentWindow?.document;
|
|
143
144
|
const parentEl: HTMLElement | null | undefined = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
|
|
144
145
|
|
|
145
|
-
let parent: MContainer | undefined = page.value;
|
|
146
|
+
let parent: MContainer | undefined | null = page.value;
|
|
146
147
|
if (parentEl) {
|
|
147
148
|
parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer;
|
|
148
149
|
}
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
import { computed, inject, markRaw, ref, watch } from 'vue';
|
|
7
7
|
import { Bottom, CopyDocument, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import StageCore from '@tmagic/stage';
|
|
9
|
+
import { NodeType } from '@tmagic/schema';
|
|
11
10
|
import { isPage } from '@tmagic/utils';
|
|
12
11
|
|
|
13
12
|
import ContentMenu from '../../components/ContentMenu.vue';
|
|
@@ -26,10 +25,10 @@ const menu = ref<InstanceType<typeof ContentMenu>>();
|
|
|
26
25
|
const canPaste = ref(false);
|
|
27
26
|
const canCenter = ref(false);
|
|
28
27
|
|
|
29
|
-
const node = computed(() => editorService?.get
|
|
30
|
-
const nodes = computed(() => editorService?.get
|
|
28
|
+
const node = computed(() => editorService?.get('node'));
|
|
29
|
+
const nodes = computed(() => editorService?.get('nodes'));
|
|
31
30
|
const parent = computed(() => editorService?.get('parent'));
|
|
32
|
-
const stage = computed(() => editorService?.get
|
|
31
|
+
const stage = computed(() => editorService?.get('stage'));
|
|
33
32
|
|
|
34
33
|
const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
|
|
35
34
|
{
|
|
@@ -129,7 +128,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
|
|
|
129
128
|
type: 'button',
|
|
130
129
|
text: '清空参考线',
|
|
131
130
|
handler: () => {
|
|
132
|
-
editorService?.get
|
|
131
|
+
editorService?.get('stage')?.clearGuides();
|
|
133
132
|
},
|
|
134
133
|
},
|
|
135
134
|
...props.stageContentMenu,
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
import { computed, inject, onMounted, onUnmounted, ref } from 'vue';
|
|
20
20
|
import KeyController from 'keycon';
|
|
21
21
|
|
|
22
|
-
import type { MNode, MPage } from '@tmagic/schema';
|
|
23
22
|
import { isPage } from '@tmagic/utils';
|
|
24
23
|
|
|
25
24
|
import type { MenuButton, MenuComponent, Services } from '../../type';
|
|
@@ -34,8 +33,8 @@ defineProps<{
|
|
|
34
33
|
|
|
35
34
|
const services = inject<Services>('services');
|
|
36
35
|
const workspace = ref<HTMLDivElement>();
|
|
37
|
-
const nodes = computed(() => services?.editorService.get
|
|
38
|
-
const page = computed(() => services?.editorService.get
|
|
36
|
+
const nodes = computed(() => services?.editorService.get('nodes'));
|
|
37
|
+
const page = computed(() => services?.editorService.get('page'));
|
|
39
38
|
|
|
40
39
|
const mouseenterHandler = () => {
|
|
41
40
|
workspace.value?.focus();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
20
|
import { cloneDeep, forIn, isEmpty, keys, omit, pick } from 'lodash-es';
|
|
21
21
|
|
|
22
|
-
import { CodeBlockContent, CodeBlockDSL, HookType, Id,
|
|
22
|
+
import { CodeBlockContent, CodeBlockDSL, HookType, Id, MNode } from '@tmagic/schema';
|
|
23
23
|
|
|
24
24
|
import editorService from '../services/editor';
|
|
25
25
|
import type { CodeRelation, CodeState, HookData } from '../type';
|
|
26
|
-
import { CODE_DRAFT_STORAGE_KEY
|
|
26
|
+
import { CODE_DRAFT_STORAGE_KEY } from '../type';
|
|
27
27
|
import { info } from '../utils/logger';
|
|
28
28
|
|
|
29
29
|
import BaseService from './BaseService';
|
|
@@ -34,7 +34,6 @@ class CodeBlock extends BaseService {
|
|
|
34
34
|
codeDsl: null,
|
|
35
35
|
id: '',
|
|
36
36
|
editable: true,
|
|
37
|
-
mode: CodeEditorMode.EDITOR,
|
|
38
37
|
combineIds: [],
|
|
39
38
|
undeletableList: [],
|
|
40
39
|
relations: {},
|
|
@@ -50,7 +49,6 @@ class CodeBlock extends BaseService {
|
|
|
50
49
|
'setCodeDslById',
|
|
51
50
|
'setCodeEditorShowStatus',
|
|
52
51
|
'setEditStatus',
|
|
53
|
-
'setMode',
|
|
54
52
|
'setCombineIds',
|
|
55
53
|
'setUndeleteableList',
|
|
56
54
|
'deleteCodeDslByIds',
|
|
@@ -214,23 +212,6 @@ class CodeBlock extends BaseService {
|
|
|
214
212
|
return this.state.id;
|
|
215
213
|
}
|
|
216
214
|
|
|
217
|
-
/**
|
|
218
|
-
* 获取当前模式
|
|
219
|
-
* @returns {CodeEditorMode}
|
|
220
|
-
*/
|
|
221
|
-
public getMode(): CodeEditorMode {
|
|
222
|
-
return this.state.mode;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* 设置当前模式
|
|
227
|
-
* @param {CodeEditorMode} mode 模式
|
|
228
|
-
* @returns {void}
|
|
229
|
-
*/
|
|
230
|
-
public async setMode(mode: CodeEditorMode): Promise<void> {
|
|
231
|
-
this.state.mode = mode;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
215
|
/**
|
|
235
216
|
* 设置当前选中组件已关联绑定的代码块id数组
|
|
236
217
|
* @param {string[]} ids 代码块id数组
|
|
@@ -253,7 +234,7 @@ class CodeBlock extends BaseService {
|
|
|
253
234
|
* @returns {CodeRelation | null}
|
|
254
235
|
*/
|
|
255
236
|
public refreshCombineInfo(): CodeRelation | null {
|
|
256
|
-
const root = editorService.get
|
|
237
|
+
const root = editorService.get('root');
|
|
257
238
|
if (!root) return null;
|
|
258
239
|
const relations = {};
|
|
259
240
|
this.recurseMNode(root, relations);
|
|
@@ -349,7 +330,6 @@ class CodeBlock extends BaseService {
|
|
|
349
330
|
this.state.codeDsl = null;
|
|
350
331
|
this.state.id = '';
|
|
351
332
|
this.state.editable = true;
|
|
352
|
-
this.state.mode = CodeEditorMode.EDITOR;
|
|
353
333
|
this.state.combineIds = [];
|
|
354
334
|
this.state.undeletableList = [];
|
|
355
335
|
}
|
|
@@ -386,6 +366,7 @@ class CodeBlock extends BaseService {
|
|
|
386
366
|
*/
|
|
387
367
|
private recurseMNode(node: MNode, relations: CodeRelation): void {
|
|
388
368
|
forIn(node, (value, key) => {
|
|
369
|
+
let unConfirmedValue: MNode = { id: node.id };
|
|
389
370
|
if (value?.hookType === HookType.CODE && !isEmpty(value.hookData)) {
|
|
390
371
|
value.hookData.forEach((relationItem: HookData) => {
|
|
391
372
|
// continue
|
|
@@ -399,6 +380,16 @@ class CodeBlock extends BaseService {
|
|
|
399
380
|
}
|
|
400
381
|
codeItem[node.id].push(key);
|
|
401
382
|
});
|
|
383
|
+
// continue
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (typeof value === 'object') {
|
|
387
|
+
// 检查value内部是否有嵌套
|
|
388
|
+
unConfirmedValue = {
|
|
389
|
+
...unConfirmedValue,
|
|
390
|
+
...value,
|
|
391
|
+
};
|
|
392
|
+
this.recurseMNode(unConfirmedValue, relations);
|
|
402
393
|
}
|
|
403
394
|
});
|
|
404
395
|
if (!isEmpty(node.items)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|