@tmagic/editor 1.3.15 → 1.4.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/style.css +17 -3
- package/dist/tmagic-editor.js +875 -530
- package/dist/tmagic-editor.umd.cjs +891 -545
- package/package.json +23 -21
- package/src/Editor.vue +8 -0
- package/src/components/CodeBlockEditor.vue +50 -24
- package/src/components/FloatingBox.vue +53 -12
- package/src/fields/Code.vue +12 -10
- package/src/fields/CodeLink.vue +9 -9
- package/src/fields/CodeSelect.vue +7 -5
- package/src/fields/CodeSelectCol.vue +1 -1
- package/src/fields/DataSourceFieldSelect.vue +118 -27
- package/src/fields/DataSourceFields.vue +10 -3
- package/src/fields/DataSourceInput.vue +7 -7
- package/src/fields/DataSourceMethodSelect.vue +1 -1
- package/src/fields/DataSourceMethods.vue +3 -3
- package/src/fields/DataSourceMocks.vue +3 -3
- package/src/fields/DataSourceSelect.vue +6 -18
- package/src/fields/EventSelect.vue +1 -1
- package/src/fields/KeyValue.vue +8 -8
- package/src/fields/PageFragmentSelect.vue +1 -1
- package/src/fields/UISelect.vue +5 -5
- package/src/hooks/use-code-block-edit.ts +0 -1
- package/src/index.ts +3 -2
- package/src/layouts/NavMenu.vue +21 -2
- package/src/layouts/sidebar/Sidebar.vue +16 -1
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +0 -1
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +3 -0
- package/src/services/BaseService.ts +5 -2
- package/src/services/codeBlock.ts +14 -8
- package/src/services/dataSource.ts +39 -26
- package/src/services/editor.ts +46 -25
- package/src/services/events.ts +4 -4
- package/src/services/props.ts +44 -35
- package/src/services/stageOverlay.ts +14 -7
- package/src/services/storage.ts +14 -8
- package/src/services/ui.ts +20 -19
- package/src/theme/code-editor.scss +6 -0
- package/src/theme/component-list-panel.scss +79 -71
- package/src/theme/floating-box.scss +2 -0
- package/src/theme/layer-panel.scss +1 -0
- package/src/theme/sidebar.scss +6 -3
- package/src/type.ts +82 -37
- package/src/utils/operator.ts +37 -39
- package/src/utils/props.ts +174 -37
- package/types/components/CodeBlockEditor.vue.d.ts +4 -4
- package/types/components/CodeParams.vue.d.ts +5 -5
- package/types/components/ContentMenu.vue.d.ts +12 -12
- package/types/components/FloatingBox.vue.d.ts +14 -12
- package/types/components/Icon.vue.d.ts +3 -3
- package/types/components/Resizer.vue.d.ts +3 -3
- package/types/components/ScrollBar.vue.d.ts +3 -3
- package/types/components/ScrollViewer.vue.d.ts +12 -12
- package/types/components/SearchInput.vue.d.ts +1 -1
- package/types/components/SplitView.vue.d.ts +11 -11
- package/types/components/ToolButton.vue.d.ts +13 -13
- package/types/components/Tree.vue.d.ts +24 -14
- package/types/components/TreeNode.vue.d.ts +22 -12
- package/types/fields/Code.vue.d.ts +14 -14
- package/types/fields/CodeLink.vue.d.ts +6 -10
- package/types/fields/CodeSelect.vue.d.ts +14 -14
- package/types/fields/CodeSelectCol.vue.d.ts +11 -11
- package/types/fields/DataSourceFieldSelect.vue.d.ts +11 -11
- package/types/fields/DataSourceFields.vue.d.ts +11 -11
- package/types/fields/DataSourceInput.vue.d.ts +14 -18
- package/types/fields/DataSourceMethodSelect.vue.d.ts +11 -11
- package/types/fields/DataSourceMethods.vue.d.ts +11 -11
- package/types/fields/DataSourceMocks.vue.d.ts +11 -11
- package/types/fields/DataSourceSelect.vue.d.ts +13 -26
- package/types/fields/EventSelect.vue.d.ts +3 -3
- package/types/fields/KeyValue.vue.d.ts +14 -18
- package/types/fields/PageFragmentSelect.vue.d.ts +11 -11
- package/types/fields/UISelect.vue.d.ts +8 -4
- package/types/hooks/use-code-block-edit.d.ts +51 -89
- package/types/hooks/use-data-source-method.d.ts +51 -89
- package/types/hooks/use-node-status.d.ts +6 -1
- package/types/icons/AppManageIcon.vue.d.ts +1 -1
- package/types/icons/CenterIcon.vue.d.ts +1 -1
- package/types/icons/CodeIcon.vue.d.ts +1 -1
- package/types/icons/FolderMinusIcon.vue.d.ts +1 -1
- package/types/icons/PinIcon.vue.d.ts +1 -1
- package/types/icons/PinnedIcon.vue.d.ts +1 -1
- package/types/index.d.ts +1 -0
- package/types/layouts/AddPageBox.vue.d.ts +3 -3
- package/types/layouts/CodeEditor.vue.d.ts +12 -12
- package/types/layouts/Framework.vue.d.ts +9 -9
- package/types/layouts/NavMenu.vue.d.ts +11 -11
- package/types/layouts/PropsPanel.vue.d.ts +193 -243
- package/types/layouts/page-bar/AddButton.vue.d.ts +3 -3
- package/types/layouts/page-bar/PageBar.vue.d.ts +8 -8
- package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +8 -8
- package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +3 -3
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/Sidebar.vue.d.ts +12 -12
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +10 -10
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +9 -9
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -3
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +3 -3
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +9 -9
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +11 -11
- package/types/layouts/sidebar/layer/LayerNodeTool.vue.d.ts +3 -3
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +9 -9
- package/types/layouts/sidebar/layer/use-click.d.ts +42 -76
- package/types/layouts/sidebar/layer/use-node-status.d.ts +6 -1
- package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -1
- package/types/layouts/workspace/Workspace.vue.d.ts +12 -12
- package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -1
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +11 -11
- package/types/layouts/workspace/viewer/StageOverlay.vue.d.ts +1 -1
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +12 -12
- package/types/services/BaseService.d.ts +5 -2
- package/types/services/codeBlock.d.ts +8 -0
- package/types/services/dataSource.d.ts +9 -2
- package/types/services/editor.d.ts +8 -1
- package/types/services/props.d.ts +15 -22
- package/types/services/stageOverlay.d.ts +8 -1
- package/types/services/storage.d.ts +8 -0
- package/types/services/ui.d.ts +15 -9
- package/types/type.d.ts +51 -32
- package/types/utils/operator.d.ts +1 -1
- package/types/utils/props.d.ts +2 -13
package/src/services/editor.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { reactive, toRaw } from 'vue';
|
|
20
20
|
import { cloneDeep, get, isObject, mergeWith, uniq } from 'lodash-es';
|
|
21
|
+
import { Writable } from 'type-fest';
|
|
21
22
|
|
|
22
23
|
import { DepTargetType } from '@tmagic/dep';
|
|
23
24
|
import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
|
@@ -29,7 +30,15 @@ import propsService from '@editor/services//props';
|
|
|
29
30
|
import depService from '@editor/services/dep';
|
|
30
31
|
import historyService from '@editor/services/history';
|
|
31
32
|
import storageService, { Protocol } from '@editor/services/storage';
|
|
32
|
-
import type {
|
|
33
|
+
import type {
|
|
34
|
+
AddMNode,
|
|
35
|
+
AsyncHookPlugin,
|
|
36
|
+
EditorNodeInfo,
|
|
37
|
+
PastePosition,
|
|
38
|
+
StepValue,
|
|
39
|
+
StoreState,
|
|
40
|
+
StoreStateKey,
|
|
41
|
+
} from '@editor/type';
|
|
33
42
|
import { LayerOffset, Layout } from '@editor/type';
|
|
34
43
|
import {
|
|
35
44
|
change2Fixed,
|
|
@@ -46,6 +55,36 @@ import {
|
|
|
46
55
|
} from '@editor/utils/editor';
|
|
47
56
|
import { beforePaste, getAddParent } from '@editor/utils/operator';
|
|
48
57
|
|
|
58
|
+
const canUsePluginMethods = {
|
|
59
|
+
async: [
|
|
60
|
+
'getLayout',
|
|
61
|
+
'highlight',
|
|
62
|
+
'select',
|
|
63
|
+
'multiSelect',
|
|
64
|
+
'doAdd',
|
|
65
|
+
'add',
|
|
66
|
+
'doRemove',
|
|
67
|
+
'remove',
|
|
68
|
+
'doUpdate',
|
|
69
|
+
'update',
|
|
70
|
+
'sort',
|
|
71
|
+
'copy',
|
|
72
|
+
'paste',
|
|
73
|
+
'doPaste',
|
|
74
|
+
'doAlignCenter',
|
|
75
|
+
'alignCenter',
|
|
76
|
+
'moveLayer',
|
|
77
|
+
'moveToContainer',
|
|
78
|
+
'dragTo',
|
|
79
|
+
'undo',
|
|
80
|
+
'redo',
|
|
81
|
+
'move',
|
|
82
|
+
] as const,
|
|
83
|
+
sync: [],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
87
|
+
|
|
49
88
|
class Editor extends BaseService {
|
|
50
89
|
public state: StoreState = reactive({
|
|
51
90
|
root: null,
|
|
@@ -65,29 +104,7 @@ class Editor extends BaseService {
|
|
|
65
104
|
|
|
66
105
|
constructor() {
|
|
67
106
|
super(
|
|
68
|
-
|
|
69
|
-
{ name: 'getLayout', isAsync: true },
|
|
70
|
-
{ name: 'select', isAsync: true },
|
|
71
|
-
{ name: 'doAdd', isAsync: true },
|
|
72
|
-
{ name: 'add', isAsync: true },
|
|
73
|
-
{ name: 'doRemove', isAsync: true },
|
|
74
|
-
{ name: 'remove', isAsync: true },
|
|
75
|
-
{ name: 'doUpdate', isAsync: true },
|
|
76
|
-
{ name: 'update', isAsync: true },
|
|
77
|
-
{ name: 'sort', isAsync: true },
|
|
78
|
-
{ name: 'copy', isAsync: true },
|
|
79
|
-
{ name: 'paste', isAsync: true },
|
|
80
|
-
{ name: 'doPaste', isAsync: true },
|
|
81
|
-
{ name: 'doAlignCenter', isAsync: true },
|
|
82
|
-
{ name: 'alignCenter', isAsync: true },
|
|
83
|
-
{ name: 'moveLayer', isAsync: true },
|
|
84
|
-
{ name: 'moveToContainer', isAsync: true },
|
|
85
|
-
{ name: 'move', isAsync: true },
|
|
86
|
-
{ name: 'undo', isAsync: true },
|
|
87
|
-
{ name: 'redo', isAsync: true },
|
|
88
|
-
{ name: 'highlight', isAsync: true },
|
|
89
|
-
{ name: 'dragTo', isAsync: true },
|
|
90
|
-
],
|
|
107
|
+
canUsePluginMethods.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
91
108
|
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
|
92
109
|
['select', 'update', 'moveLayer'],
|
|
93
110
|
);
|
|
@@ -696,7 +713,7 @@ class Editor extends BaseService {
|
|
|
696
713
|
|
|
697
714
|
public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
|
|
698
715
|
propsService.clearRelateId();
|
|
699
|
-
const pasteConfigs =
|
|
716
|
+
const pasteConfigs = beforePaste(position, cloneDeep(config));
|
|
700
717
|
return pasteConfigs;
|
|
701
718
|
}
|
|
702
719
|
|
|
@@ -985,6 +1002,10 @@ class Editor extends BaseService {
|
|
|
985
1002
|
this.get('modifiedNodeIds').clear();
|
|
986
1003
|
}
|
|
987
1004
|
|
|
1005
|
+
public usePlugin(options: AsyncHookPlugin<AsyncMethodName, Editor>): void {
|
|
1006
|
+
super.usePlugin(options);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
988
1009
|
private addModifiedNodeId(id: Id) {
|
|
989
1010
|
if (!this.isHistoryStateChange) {
|
|
990
1011
|
this.get('modifiedNodeIds').set(id, id);
|
package/src/services/events.ts
CHANGED
|
@@ -55,11 +55,11 @@ class Events extends BaseService {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
public setEvent(type: string, events: EventOption[]) {
|
|
58
|
-
eventMap[type] = [...DEFAULT_EVENTS, ...events];
|
|
58
|
+
eventMap[toLine(type)] = [...DEFAULT_EVENTS, ...events];
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
public getEvent(type: string): EventOption[] {
|
|
62
|
-
return cloneDeep(eventMap[type] || DEFAULT_EVENTS);
|
|
62
|
+
return cloneDeep(eventMap[toLine(type)] || DEFAULT_EVENTS);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
public setMethods(methods: Record<string, EventOption[]>) {
|
|
@@ -69,11 +69,11 @@ class Events extends BaseService {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
public setMethod(type: string, method: EventOption[]) {
|
|
72
|
-
methodMap[type] = [...DEFAULT_METHODS, ...method];
|
|
72
|
+
methodMap[toLine(type)] = [...DEFAULT_METHODS, ...method];
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
public getMethod(type: string) {
|
|
76
|
-
return cloneDeep(methodMap[type] || DEFAULT_METHODS);
|
|
76
|
+
return cloneDeep(methodMap[toLine(type)] || DEFAULT_METHODS);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
public resetState() {
|
package/src/services/props.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
20
|
import { cloneDeep, mergeWith } from 'lodash-es';
|
|
21
|
+
import { Writable } from 'type-fest';
|
|
21
22
|
|
|
22
23
|
import { DepTargetType } from '@tmagic/dep';
|
|
23
24
|
import type { FormConfig } from '@tmagic/form';
|
|
@@ -26,11 +27,26 @@ import { getValueByKeyPath, guid, setValueByKeyPath, toLine } from '@tmagic/util
|
|
|
26
27
|
|
|
27
28
|
import depService from '@editor/services/dep';
|
|
28
29
|
import editorService from '@editor/services/editor';
|
|
29
|
-
import type { PropsState } from '@editor/type';
|
|
30
|
+
import type { AsyncHookPlugin, PropsState, SyncHookPlugin } from '@editor/type';
|
|
30
31
|
import { fillConfig } from '@editor/utils/props';
|
|
31
32
|
|
|
32
33
|
import BaseService from './BaseService';
|
|
33
34
|
|
|
35
|
+
const canUsePluginMethods = {
|
|
36
|
+
async: [
|
|
37
|
+
'setPropsConfig',
|
|
38
|
+
'getPropsConfig',
|
|
39
|
+
'setPropsValue',
|
|
40
|
+
'getPropsValue',
|
|
41
|
+
'fillConfig',
|
|
42
|
+
'getDefaultPropsValue',
|
|
43
|
+
] as const,
|
|
44
|
+
sync: ['createId', 'setNewItemId'] as const,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
48
|
+
type SyncMethodName = Writable<(typeof canUsePluginMethods)['sync']>;
|
|
49
|
+
|
|
34
50
|
class Props extends BaseService {
|
|
35
51
|
private state = reactive<PropsState>({
|
|
36
52
|
propsConfigMap: {},
|
|
@@ -40,14 +56,8 @@ class Props extends BaseService {
|
|
|
40
56
|
|
|
41
57
|
constructor() {
|
|
42
58
|
super([
|
|
43
|
-
{ name:
|
|
44
|
-
{ name:
|
|
45
|
-
{ name: 'setPropsValue', isAsync: true },
|
|
46
|
-
{ name: 'getPropsValue', isAsync: true },
|
|
47
|
-
{ name: 'createId', isAsync: false },
|
|
48
|
-
{ name: 'setNewItemId', isAsync: true },
|
|
49
|
-
{ name: 'fillConfig', isAsync: true },
|
|
50
|
-
{ name: 'getDefaultPropsValue', isAsync: true },
|
|
59
|
+
...canUsePluginMethods.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
60
|
+
...canUsePluginMethods.sync.map((methodName) => ({ name: methodName, isAsync: false })),
|
|
51
61
|
]);
|
|
52
62
|
}
|
|
53
63
|
|
|
@@ -58,17 +68,12 @@ class Props extends BaseService {
|
|
|
58
68
|
this.emit('props-configs-change');
|
|
59
69
|
}
|
|
60
70
|
|
|
61
|
-
public async fillConfig(config: FormConfig) {
|
|
62
|
-
return fillConfig(config);
|
|
71
|
+
public async fillConfig(config: FormConfig, labelWidth?: string) {
|
|
72
|
+
return fillConfig(config, typeof labelWidth !== 'function' ? labelWidth : '80px');
|
|
63
73
|
}
|
|
64
74
|
|
|
65
|
-
/**
|
|
66
|
-
* 为指定类型组件设置组件属性表单配置
|
|
67
|
-
* @param type 组件类型
|
|
68
|
-
* @param config 组件属性表单配置
|
|
69
|
-
*/
|
|
70
75
|
public async setPropsConfig(type: string, config: FormConfig) {
|
|
71
|
-
this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
76
|
+
this.state.propsConfigMap[toLine(type)] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
/**
|
|
@@ -81,7 +86,7 @@ class Props extends BaseService {
|
|
|
81
86
|
return await this.getPropsConfig('button');
|
|
82
87
|
}
|
|
83
88
|
|
|
84
|
-
return cloneDeep(this.state.propsConfigMap[type] || (await this.fillConfig([])));
|
|
89
|
+
return cloneDeep(this.state.propsConfigMap[toLine(type)] || (await this.fillConfig([])));
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
public setPropsValues(values: Record<string, Partial<MNode>>) {
|
|
@@ -96,7 +101,7 @@ class Props extends BaseService {
|
|
|
96
101
|
* @param value 组件初始值
|
|
97
102
|
*/
|
|
98
103
|
public async setPropsValue(type: string, value: Partial<MNode>) {
|
|
99
|
-
this.state.propsValueMap[type] = value;
|
|
104
|
+
this.state.propsValueMap[toLine(type)] = value;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
/**
|
|
@@ -104,7 +109,9 @@ class Props extends BaseService {
|
|
|
104
109
|
* @param type 组件类型
|
|
105
110
|
* @returns 组件初始值
|
|
106
111
|
*/
|
|
107
|
-
public async getPropsValue(
|
|
112
|
+
public async getPropsValue(componentType: string, { inputEvent, ...defaultValue }: Record<string, any> = {}) {
|
|
113
|
+
const type = toLine(componentType);
|
|
114
|
+
|
|
108
115
|
if (type === 'area') {
|
|
109
116
|
const value = (await this.getPropsValue('button')) as MComponent;
|
|
110
117
|
value.className = 'action-area';
|
|
@@ -115,16 +122,14 @@ class Props extends BaseService {
|
|
|
115
122
|
return value;
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
),
|
|
127
|
-
]);
|
|
125
|
+
const id = this.createId(type);
|
|
126
|
+
const defaultPropsValue = this.getDefaultPropsValue(type);
|
|
127
|
+
const data = this.setNewItemId(
|
|
128
|
+
cloneDeep({
|
|
129
|
+
type,
|
|
130
|
+
...defaultValue,
|
|
131
|
+
} as any),
|
|
132
|
+
);
|
|
128
133
|
|
|
129
134
|
return {
|
|
130
135
|
id,
|
|
@@ -133,7 +138,7 @@ class Props extends BaseService {
|
|
|
133
138
|
};
|
|
134
139
|
}
|
|
135
140
|
|
|
136
|
-
public
|
|
141
|
+
public createId(type: string | number): string {
|
|
137
142
|
return `${type}_${guid()}`;
|
|
138
143
|
}
|
|
139
144
|
|
|
@@ -144,16 +149,16 @@ class Props extends BaseService {
|
|
|
144
149
|
* @param {Boolean} force 是否强制设置新的ID
|
|
145
150
|
*/
|
|
146
151
|
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
147
|
-
public
|
|
152
|
+
public setNewItemId(config: MNode, force = true) {
|
|
148
153
|
if (force || editorService.getNodeById(config.id)) {
|
|
149
|
-
const newId =
|
|
154
|
+
const newId = this.createId(config.type || 'component');
|
|
150
155
|
this.setRelateId(config.id, newId);
|
|
151
156
|
config.id = newId;
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
if (config.items && Array.isArray(config.items)) {
|
|
155
160
|
for (const item of config.items) {
|
|
156
|
-
|
|
161
|
+
this.setNewItemId(item);
|
|
157
162
|
}
|
|
158
163
|
}
|
|
159
164
|
|
|
@@ -165,7 +170,7 @@ class Props extends BaseService {
|
|
|
165
170
|
* @param type 组件类型
|
|
166
171
|
* @returns Object
|
|
167
172
|
*/
|
|
168
|
-
public
|
|
173
|
+
public getDefaultPropsValue(type: string) {
|
|
169
174
|
return ['page', 'container'].includes(type)
|
|
170
175
|
? {
|
|
171
176
|
type,
|
|
@@ -227,6 +232,10 @@ class Props extends BaseService {
|
|
|
227
232
|
this.removeAllPlugins();
|
|
228
233
|
}
|
|
229
234
|
|
|
235
|
+
public usePlugin(options: AsyncHookPlugin<AsyncMethodName, Props> & SyncHookPlugin<SyncMethodName, Props>): void {
|
|
236
|
+
super.usePlugin(options);
|
|
237
|
+
}
|
|
238
|
+
|
|
230
239
|
/**
|
|
231
240
|
* 获取setNewItemId前后映射关系
|
|
232
241
|
* @param oldId 原组件ID
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { reactive } from 'vue';
|
|
2
|
+
import type { Writable } from 'type-fest';
|
|
2
3
|
|
|
3
4
|
import StageCore from '@tmagic/stage';
|
|
4
5
|
|
|
5
6
|
import { useStage } from '@editor/hooks/use-stage';
|
|
6
7
|
import BaseService from '@editor/services//BaseService';
|
|
7
8
|
import editorService from '@editor/services//editor';
|
|
8
|
-
import type { StageOptions, StageOverlayState } from '@editor/type';
|
|
9
|
+
import type { StageOptions, StageOverlayState, SyncHookPlugin } from '@editor/type';
|
|
10
|
+
|
|
11
|
+
const canUsePluginMethods = {
|
|
12
|
+
async: [],
|
|
13
|
+
sync: ['openOverlay', 'closeOverlay', 'updateOverlay', 'createStage'] as const,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type SyncMethodName = Writable<(typeof canUsePluginMethods)['sync']>;
|
|
9
17
|
|
|
10
18
|
class StageOverlay extends BaseService {
|
|
11
19
|
private state: StageOverlayState = reactive({
|
|
@@ -20,12 +28,7 @@ class StageOverlay extends BaseService {
|
|
|
20
28
|
});
|
|
21
29
|
|
|
22
30
|
constructor() {
|
|
23
|
-
super(
|
|
24
|
-
{ name: 'openOverlay', isAsync: false },
|
|
25
|
-
{ name: 'closeOverlay', isAsync: false },
|
|
26
|
-
{ name: 'updateOverlay', isAsync: false },
|
|
27
|
-
{ name: 'createStage', isAsync: false },
|
|
28
|
-
]);
|
|
31
|
+
super(canUsePluginMethods.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
29
32
|
|
|
30
33
|
this.get('wrapDiv').classList.add('tmagic-editor-sub-stage-wrap');
|
|
31
34
|
}
|
|
@@ -111,6 +114,10 @@ class StageOverlay extends BaseService {
|
|
|
111
114
|
});
|
|
112
115
|
}
|
|
113
116
|
|
|
117
|
+
public usePlugin(options: SyncHookPlugin<SyncMethodName, StageOverlay>): void {
|
|
118
|
+
super.usePlugin(options);
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
private createContentEl() {
|
|
115
122
|
const sourceEl = this.get('sourceEl');
|
|
116
123
|
if (!sourceEl) return;
|
package/src/services/storage.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import serialize from 'serialize-javascript';
|
|
2
|
+
import type { Writable } from 'type-fest';
|
|
2
3
|
|
|
4
|
+
import type { SyncHookPlugin } from '@editor/type';
|
|
3
5
|
import { getConfig } from '@editor/utils/config';
|
|
4
6
|
|
|
5
7
|
import BaseService from './BaseService';
|
|
@@ -17,6 +19,13 @@ export enum Protocol {
|
|
|
17
19
|
BOOLEAN = 'boolean',
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
const canUsePluginMethods = {
|
|
23
|
+
async: [],
|
|
24
|
+
sync: ['getStorage', 'getNamespace', 'clear', 'getItem', 'removeItem', 'setItem'] as const,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type SyncMethodName = Writable<(typeof canUsePluginMethods)['sync']>;
|
|
28
|
+
|
|
20
29
|
/**
|
|
21
30
|
* 数据存储服务
|
|
22
31
|
*/
|
|
@@ -25,14 +34,7 @@ export class WebStorage extends BaseService {
|
|
|
25
34
|
private namespace = 'tmagic';
|
|
26
35
|
|
|
27
36
|
constructor() {
|
|
28
|
-
super(
|
|
29
|
-
{ name: 'getStorage', isAsync: false },
|
|
30
|
-
{ name: 'getNamespace', isAsync: false },
|
|
31
|
-
{ name: 'clear', isAsync: false },
|
|
32
|
-
{ name: 'getItem', isAsync: false },
|
|
33
|
-
{ name: 'removeItem', isAsync: false },
|
|
34
|
-
{ name: 'setItem', isAsync: false },
|
|
35
|
-
]);
|
|
37
|
+
super(canUsePluginMethods.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
/**
|
|
@@ -123,6 +125,10 @@ export class WebStorage extends BaseService {
|
|
|
123
125
|
this.removeAllPlugins();
|
|
124
126
|
}
|
|
125
127
|
|
|
128
|
+
public usePlugin(options: SyncHookPlugin<SyncMethodName, WebStorage>): void {
|
|
129
|
+
super.usePlugin(options);
|
|
130
|
+
}
|
|
131
|
+
|
|
126
132
|
private getValueAndProtocol(value: string | null) {
|
|
127
133
|
let protocol = '';
|
|
128
134
|
|
package/src/services/ui.ts
CHANGED
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
|
+
import type { Writable } from 'type-fest';
|
|
20
21
|
|
|
21
22
|
import { convertToNumber } from '@tmagic/utils';
|
|
22
23
|
|
|
23
24
|
import editorService from '@editor/services/editor';
|
|
24
|
-
import type { StageRect, UiState } from '@editor/type';
|
|
25
|
+
import type { AsyncHookPlugin, StageRect, UiState } from '@editor/type';
|
|
25
26
|
|
|
26
27
|
import BaseService from './BaseService';
|
|
27
28
|
|
|
@@ -46,16 +47,25 @@ const state = reactive<UiState>({
|
|
|
46
47
|
showRule: true,
|
|
47
48
|
propsPanelSize: 'small',
|
|
48
49
|
showAddPageButton: true,
|
|
49
|
-
floatBox: new Map(),
|
|
50
50
|
hideSlideBar: false,
|
|
51
|
+
navMenuRect: {
|
|
52
|
+
left: 0,
|
|
53
|
+
top: 0,
|
|
54
|
+
width: 0,
|
|
55
|
+
height: 0,
|
|
56
|
+
},
|
|
51
57
|
});
|
|
52
58
|
|
|
59
|
+
const canUsePluginMethods = {
|
|
60
|
+
async: ['zoom', 'calcZoom'] as const,
|
|
61
|
+
sync: [] as const,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
65
|
+
|
|
53
66
|
class Ui extends BaseService {
|
|
54
67
|
constructor() {
|
|
55
|
-
super(
|
|
56
|
-
{ name: 'zoom', isAsync: true },
|
|
57
|
-
{ name: 'calcZoom', isAsync: true },
|
|
58
|
-
]);
|
|
68
|
+
super(canUsePluginMethods.async.map((methodName) => ({ name: methodName, isAsync: true })));
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
public set<K extends keyof UiState, T extends UiState[K]>(name: K, value: T) {
|
|
@@ -105,19 +115,6 @@ class Ui extends BaseService {
|
|
|
105
115
|
return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
|
|
106
116
|
}
|
|
107
117
|
|
|
108
|
-
public async setFloatBox(keys: string[]) {
|
|
109
|
-
const map = state.floatBox;
|
|
110
|
-
for (const key of keys) {
|
|
111
|
-
if (map.get(key)) continue;
|
|
112
|
-
map.set(key, {
|
|
113
|
-
status: false,
|
|
114
|
-
zIndex: 99,
|
|
115
|
-
top: 0,
|
|
116
|
-
left: 0,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
118
|
public resetState() {
|
|
122
119
|
this.set('showSrc', false);
|
|
123
120
|
this.set('uiSelectMode', false);
|
|
@@ -134,6 +131,10 @@ class Ui extends BaseService {
|
|
|
134
131
|
this.removeAllPlugins();
|
|
135
132
|
}
|
|
136
133
|
|
|
134
|
+
public usePlugin(options: AsyncHookPlugin<AsyncMethodName, Ui>): void {
|
|
135
|
+
super.usePlugin(options);
|
|
136
|
+
}
|
|
137
|
+
|
|
137
138
|
private async setStageRect(value: StageRect) {
|
|
138
139
|
state.stageRect = {
|
|
139
140
|
...state.stageRect,
|
|
@@ -1,88 +1,96 @@
|
|
|
1
|
-
.ui-component-panel
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
.ui-component-panel {
|
|
2
|
+
&.tmagic-design-collapse {
|
|
3
|
+
height: 100%;
|
|
4
|
+
border-top: 0 !important;
|
|
5
|
+
margin-top: 48px;
|
|
6
|
+
background-color: $--sidebar-content-background-color;
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
.tmagic-design-collapse-item {
|
|
9
|
+
> div:first-of-type {
|
|
10
|
+
border-bottom: 1px solid $--border-color;
|
|
11
|
+
margin-bottom: 10px;
|
|
12
|
+
}
|
|
11
13
|
}
|
|
12
|
-
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
.el-collapse-item__header,
|
|
16
|
+
.t-collapse-panel__header {
|
|
17
|
+
background: $--sidebar-content-background-color;
|
|
18
|
+
color: $--font-color;
|
|
19
|
+
height: 25px;
|
|
20
|
+
line-height: 25px;
|
|
21
|
+
padding-left: 10px;
|
|
22
|
+
font-size: 12px;
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
i {
|
|
25
|
+
margin-right: 5px;
|
|
26
|
+
font-size: 14px;
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.el-collapse-item__wrap,
|
|
30
|
-
.t-collapse-panel__body {
|
|
31
|
-
background: $--sidebar-content-background-color;
|
|
32
|
-
border-bottom: 0;
|
|
33
29
|
|
|
34
|
-
.el-collapse-
|
|
35
|
-
.t-collapse-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
flex-wrap: wrap;
|
|
39
|
-
}
|
|
30
|
+
.el-collapse-item__wrap,
|
|
31
|
+
.t-collapse-panel__body {
|
|
32
|
+
background: $--sidebar-content-background-color;
|
|
33
|
+
border-bottom: 0;
|
|
40
34
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
color: $--font-color;
|
|
48
|
-
flex-direction: column;
|
|
49
|
-
width: 42px;
|
|
50
|
-
cursor: pointer;
|
|
35
|
+
.el-collapse-item__content,
|
|
36
|
+
.t-collapse-panel__content {
|
|
37
|
+
padding: 10px;
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-wrap: wrap;
|
|
40
|
+
}
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
font-size: 20px;
|
|
54
|
-
background: #fff;
|
|
55
|
-
height: 40px;
|
|
56
|
-
width: 40px;
|
|
57
|
-
line-height: 40px;
|
|
58
|
-
border-radius: 5px;
|
|
59
|
-
color: #909090;
|
|
60
|
-
border: 1px solid $--border-color;
|
|
42
|
+
.component-item {
|
|
61
43
|
display: flex;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
margin
|
|
44
|
+
overflow: hidden;
|
|
45
|
+
text-overflow: ellipsis;
|
|
46
|
+
margin: 5px 10px;
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
color: $--font-color;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
width: 42px;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
|
|
53
|
+
i {
|
|
54
|
+
font-size: 20px;
|
|
55
|
+
background: #fff;
|
|
56
|
+
height: 40px;
|
|
57
|
+
width: 40px;
|
|
58
|
+
line-height: 40px;
|
|
59
|
+
border-radius: 5px;
|
|
60
|
+
color: #909090;
|
|
61
|
+
border: 1px solid $--border-color;
|
|
62
|
+
display: flex;
|
|
63
|
+
justify-content: space-evenly;
|
|
64
|
+
align-items: center;
|
|
65
|
+
margin-bottom: 5px;
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
&:hover {
|
|
68
|
+
background: #2882e0;
|
|
69
|
+
color: #fff;
|
|
70
|
+
border-color: #4e8be1;
|
|
71
|
+
}
|
|
70
72
|
}
|
|
71
|
-
}
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
span {
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
text-align: center;
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
.el-tooltip {
|
|
80
|
+
width: 50px;
|
|
81
|
+
height: 30px;
|
|
82
|
+
line-height: 15px;
|
|
83
|
+
display: block;
|
|
84
|
+
white-space: normal;
|
|
85
|
+
margin: 0;
|
|
86
|
+
}
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
}
|
|
90
|
+
|
|
91
|
+
.t-collapse {
|
|
92
|
+
margin-top: 0;
|
|
93
|
+
padding-top: 48px;
|
|
94
|
+
position: relative;
|
|
95
|
+
}
|
|
88
96
|
}
|