@tmagic/editor 1.1.0-beta.9 → 1.1.0
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 +46 -0
- package/dist/tmagic-editor.mjs +971 -794
- package/dist/tmagic-editor.mjs.map +1 -1
- package/dist/tmagic-editor.umd.js +974 -794
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/package.json +10 -10
- package/src/Editor.vue +15 -5
- package/src/components/ContentMenu.vue +4 -4
- package/src/components/Icon.vue +6 -20
- package/src/components/ScrollBar.vue +147 -0
- package/src/components/ScrollViewer.vue +89 -44
- package/src/components/ToolButton.vue +40 -138
- package/src/fields/UISelect.vue +2 -2
- package/src/index.ts +2 -0
- package/src/layouts/NavMenu.vue +156 -23
- package/src/layouts/PropsPanel.vue +49 -51
- package/src/layouts/sidebar/LayerMenu.vue +3 -3
- package/src/layouts/sidebar/LayerPanel.vue +39 -8
- package/src/layouts/workspace/PageBar.vue +1 -1
- package/src/layouts/workspace/Stage.vue +8 -90
- package/src/layouts/workspace/ViewerMenu.vue +3 -3
- package/src/layouts/workspace/Workspace.vue +133 -138
- package/src/services/componentList.ts +5 -0
- package/src/services/editor.ts +56 -19
- package/src/services/events.ts +8 -2
- package/src/services/props.ts +31 -52
- package/src/services/storage.ts +4 -0
- package/src/services/ui.ts +32 -30
- package/src/theme/nav-menu.scss +6 -0
- package/src/type.ts +26 -10
- package/src/utils/index.ts +1 -0
- package/src/utils/operator.ts +3 -3
- package/src/utils/props.ts +0 -3
- package/src/utils/scroll-viewer.ts +90 -158
- package/src/utils/stage.ts +91 -0
- package/types/Editor.vue.d.ts +7 -7
- package/types/components/ContentMenu.vue.d.ts +8 -8
- package/types/components/Icon.vue.d.ts +62 -12
- package/types/components/ScrollBar.vue.d.ts +83 -0
- package/types/components/ScrollViewer.vue.d.ts +131 -19
- package/types/components/ToolButton.vue.d.ts +56 -59
- package/types/index.d.ts +2 -0
- package/types/layouts/NavMenu.vue.d.ts +92 -23
- package/types/layouts/PropsPanel.vue.d.ts +25 -208
- package/types/layouts/sidebar/LayerMenu.vue.d.ts +7 -7
- package/types/layouts/sidebar/LayerPanel.vue.d.ts +17 -15
- package/types/layouts/workspace/Workspace.vue.d.ts +54 -4
- package/types/services/componentList.d.ts +1 -0
- package/types/services/editor.d.ts +1 -0
- package/types/services/events.d.ts +1 -0
- package/types/services/props.d.ts +41 -9
- package/types/services/storage.d.ts +1 -0
- package/types/services/ui.d.ts +3 -1
- package/types/type.d.ts +23 -10
- package/types/utils/index.d.ts +1 -0
- package/types/utils/operator.d.ts +1 -1
- package/types/utils/props.d.ts +0 -1
- package/types/utils/scroll-viewer.d.ts +16 -18
- package/types/utils/stage.d.ts +3 -0
package/src/services/editor.ts
CHANGED
|
@@ -71,6 +71,7 @@ class Editor extends BaseService {
|
|
|
71
71
|
'sort',
|
|
72
72
|
'copy',
|
|
73
73
|
'paste',
|
|
74
|
+
'doPaste',
|
|
74
75
|
'duAlignCenter',
|
|
75
76
|
'alignCenter',
|
|
76
77
|
'moveLayer',
|
|
@@ -296,17 +297,27 @@ class Editor extends BaseService {
|
|
|
296
297
|
throw new Error('app下不能添加组件');
|
|
297
298
|
}
|
|
298
299
|
|
|
300
|
+
if (parent.id !== curNode.id) {
|
|
301
|
+
const index = parent.items.indexOf(curNode);
|
|
302
|
+
parent?.items?.splice(index + 1, 0, node);
|
|
303
|
+
} else {
|
|
304
|
+
// 新增节点添加到配置中
|
|
305
|
+
parent?.items?.push(node);
|
|
306
|
+
}
|
|
307
|
+
|
|
299
308
|
const layout = await this.getLayout(toRaw(parent), node as MNode);
|
|
300
309
|
node.style = getInitPositionStyle(node.style, layout);
|
|
301
310
|
|
|
302
|
-
await stage?.add({
|
|
311
|
+
await stage?.add({
|
|
312
|
+
config: cloneDeep(node),
|
|
313
|
+
parent: cloneDeep(parent),
|
|
314
|
+
parentId: parent.id,
|
|
315
|
+
root: cloneDeep(root),
|
|
316
|
+
});
|
|
303
317
|
|
|
304
318
|
node.style = fixNodePosition(node, parent, stage);
|
|
305
319
|
|
|
306
|
-
await stage?.update({ config: cloneDeep(node), root: cloneDeep(root) });
|
|
307
|
-
|
|
308
|
-
// 新增节点添加到配置中
|
|
309
|
-
parent?.items?.push(node);
|
|
320
|
+
await stage?.update({ config: cloneDeep(node), parentId: parent.id, root: cloneDeep(root) });
|
|
310
321
|
|
|
311
322
|
this.addModifiedNodeId(node.id);
|
|
312
323
|
|
|
@@ -322,9 +333,6 @@ class Editor extends BaseService {
|
|
|
322
333
|
public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
|
|
323
334
|
const stage = this.get<StageCore | null>('stage');
|
|
324
335
|
|
|
325
|
-
const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(addNode);
|
|
326
|
-
if (!parentNode) throw new Error('未找到父元素');
|
|
327
|
-
|
|
328
336
|
// 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
|
|
329
337
|
const addNodes = [];
|
|
330
338
|
if (!Array.isArray(addNode)) {
|
|
@@ -337,7 +345,13 @@ class Editor extends BaseService {
|
|
|
337
345
|
addNodes.push(...addNode);
|
|
338
346
|
}
|
|
339
347
|
|
|
340
|
-
const newNodes = await Promise.all(
|
|
348
|
+
const newNodes = await Promise.all(
|
|
349
|
+
addNodes.map((node) => {
|
|
350
|
+
const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(node);
|
|
351
|
+
if (!parentNode) throw new Error('未找到父元素');
|
|
352
|
+
return this.doAdd(node, parentNode);
|
|
353
|
+
}),
|
|
354
|
+
);
|
|
341
355
|
|
|
342
356
|
if (newNodes.length > 1) {
|
|
343
357
|
const newNodeIds = newNodes.map((node) => node.id);
|
|
@@ -359,7 +373,7 @@ class Editor extends BaseService {
|
|
|
359
373
|
|
|
360
374
|
this.emit('add', newNodes);
|
|
361
375
|
|
|
362
|
-
return
|
|
376
|
+
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
363
377
|
}
|
|
364
378
|
|
|
365
379
|
public async doRemove(node: MNode): Promise<void> {
|
|
@@ -377,7 +391,7 @@ class Editor extends BaseService {
|
|
|
377
391
|
|
|
378
392
|
parent.items?.splice(index, 1);
|
|
379
393
|
const stage = this.get<StageCore | null>('stage');
|
|
380
|
-
stage?.remove({ id: node.id, root:
|
|
394
|
+
stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
381
395
|
|
|
382
396
|
if (node.type === NodeType.PAGE) {
|
|
383
397
|
this.state.pageLength -= 1;
|
|
@@ -417,7 +431,7 @@ class Editor extends BaseService {
|
|
|
417
431
|
// 更新历史记录
|
|
418
432
|
this.pushHistoryState();
|
|
419
433
|
|
|
420
|
-
this.emit('remove');
|
|
434
|
+
this.emit('remove', nodes);
|
|
421
435
|
}
|
|
422
436
|
|
|
423
437
|
public async doUpdate(config: MNode) {
|
|
@@ -466,7 +480,11 @@ class Editor extends BaseService {
|
|
|
466
480
|
nodes.splice(targetIndex, 1, newConfig);
|
|
467
481
|
this.set('nodes', nodes);
|
|
468
482
|
|
|
469
|
-
this.get<StageCore | null>('stage')?.update({
|
|
483
|
+
this.get<StageCore | null>('stage')?.update({
|
|
484
|
+
config: cloneDeep(newConfig),
|
|
485
|
+
parentId: parent.id,
|
|
486
|
+
root: cloneDeep(this.get('root')),
|
|
487
|
+
});
|
|
470
488
|
|
|
471
489
|
if (newConfig.type === NodeType.PAGE) {
|
|
472
490
|
this.set('page', newConfig);
|
|
@@ -491,7 +509,7 @@ class Editor extends BaseService {
|
|
|
491
509
|
|
|
492
510
|
this.emit('update', newNodes);
|
|
493
511
|
|
|
494
|
-
return
|
|
512
|
+
return Array.isArray(config) ? newNodes : newNodes[0];
|
|
495
513
|
}
|
|
496
514
|
|
|
497
515
|
/**
|
|
@@ -513,7 +531,11 @@ class Editor extends BaseService {
|
|
|
513
531
|
await this.update(parent);
|
|
514
532
|
await this.select(node);
|
|
515
533
|
|
|
516
|
-
this.get<StageCore | null>('stage')?.update({
|
|
534
|
+
this.get<StageCore | null>('stage')?.update({
|
|
535
|
+
config: cloneDeep(node),
|
|
536
|
+
parentId: parent.id,
|
|
537
|
+
root: cloneDeep(this.get('root')),
|
|
538
|
+
});
|
|
517
539
|
|
|
518
540
|
this.addModifiedNodeId(parent.id);
|
|
519
541
|
this.pushHistoryState();
|
|
@@ -540,11 +562,16 @@ class Editor extends BaseService {
|
|
|
540
562
|
|
|
541
563
|
if (!Array.isArray(config)) return;
|
|
542
564
|
|
|
543
|
-
const pasteConfigs = await
|
|
565
|
+
const pasteConfigs = await this.doPaste(config, position);
|
|
544
566
|
|
|
545
567
|
return this.add(pasteConfigs);
|
|
546
568
|
}
|
|
547
569
|
|
|
570
|
+
public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
|
|
571
|
+
const pasteConfigs = await beforePaste(position, cloneDeep(config));
|
|
572
|
+
return pasteConfigs;
|
|
573
|
+
}
|
|
574
|
+
|
|
548
575
|
public async doAlignCenter(config: MNode): Promise<MNode> {
|
|
549
576
|
const parent = this.getParentById(config.id);
|
|
550
577
|
|
|
@@ -598,7 +625,7 @@ class Editor extends BaseService {
|
|
|
598
625
|
*/
|
|
599
626
|
public async moveLayer(offset: number | LayerOffset): Promise<void> {
|
|
600
627
|
const parent = this.get<MContainer>('parent');
|
|
601
|
-
const node = this.get('node');
|
|
628
|
+
const node = this.get<MNode>('node');
|
|
602
629
|
const brothers: MNode[] = parent?.items || [];
|
|
603
630
|
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
604
631
|
|
|
@@ -610,10 +637,15 @@ class Editor extends BaseService {
|
|
|
610
637
|
brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
|
|
611
638
|
}
|
|
612
639
|
|
|
640
|
+
const grandparent = this.getParentById(parent.id);
|
|
613
641
|
this.get<StageCore | null>('stage')?.update({
|
|
614
642
|
config: cloneDeep(toRaw(parent)),
|
|
643
|
+
parentId: grandparent?.id,
|
|
615
644
|
root: cloneDeep(this.get<MApp>('root')),
|
|
616
645
|
});
|
|
646
|
+
|
|
647
|
+
this.addModifiedNodeId(parent.id);
|
|
648
|
+
this.pushHistoryState();
|
|
617
649
|
}
|
|
618
650
|
|
|
619
651
|
/**
|
|
@@ -632,7 +664,7 @@ class Editor extends BaseService {
|
|
|
632
664
|
const index = getNodeIndex(node, parent);
|
|
633
665
|
parent.items?.splice(index, 1);
|
|
634
666
|
|
|
635
|
-
await stage.remove({ id: node.id, root });
|
|
667
|
+
await stage.remove({ id: node.id, parentId: parent.id, root });
|
|
636
668
|
|
|
637
669
|
const layout = await this.getLayout(target);
|
|
638
670
|
|
|
@@ -647,7 +679,8 @@ class Editor extends BaseService {
|
|
|
647
679
|
|
|
648
680
|
await stage.select(targetId);
|
|
649
681
|
|
|
650
|
-
|
|
682
|
+
const targetParent = this.getParentById(target.id);
|
|
683
|
+
await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root });
|
|
651
684
|
|
|
652
685
|
await this.select(newConfig);
|
|
653
686
|
stage.select(newConfig.id);
|
|
@@ -708,6 +741,10 @@ class Editor extends BaseService {
|
|
|
708
741
|
this.set('nodes', []);
|
|
709
742
|
this.set('page', null);
|
|
710
743
|
this.set('parent', null);
|
|
744
|
+
this.set('stage', null);
|
|
745
|
+
this.set('highlightNode', null);
|
|
746
|
+
this.set('modifiedNodeIds', new Map());
|
|
747
|
+
this.set('pageLength', new Map());
|
|
711
748
|
}
|
|
712
749
|
|
|
713
750
|
public resetModifiedNodeId() {
|
package/src/services/events.ts
CHANGED
|
@@ -26,8 +26,8 @@ import type { ComponentGroup } from '../type';
|
|
|
26
26
|
|
|
27
27
|
import BaseService from './BaseService';
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
let eventMap: Record<string, EventOption[]> = reactive({});
|
|
30
|
+
let methodMap: Record<string, EventOption[]> = reactive({});
|
|
31
31
|
|
|
32
32
|
class Events extends BaseService {
|
|
33
33
|
constructor() {
|
|
@@ -75,6 +75,12 @@ class Events extends BaseService {
|
|
|
75
75
|
public getMethod(type: string) {
|
|
76
76
|
return cloneDeep(methodMap[type] || DEFAULT_METHODS);
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
public destroy() {
|
|
80
|
+
eventMap = reactive({});
|
|
81
|
+
methodMap = reactive({});
|
|
82
|
+
this.removeAllListeners();
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
export type EventsService = Events;
|
package/src/services/props.ts
CHANGED
|
@@ -20,12 +20,11 @@ import { reactive } from 'vue';
|
|
|
20
20
|
import { cloneDeep, mergeWith } from 'lodash-es';
|
|
21
21
|
|
|
22
22
|
import type { FormConfig } from '@tmagic/form';
|
|
23
|
-
import type {
|
|
24
|
-
import {
|
|
25
|
-
import { isPop, toLine } from '@tmagic/utils';
|
|
23
|
+
import type { MComponent, MNode } from '@tmagic/schema';
|
|
24
|
+
import { toLine } from '@tmagic/utils';
|
|
26
25
|
|
|
27
26
|
import type { PropsState } from '../type';
|
|
28
|
-
import {
|
|
27
|
+
import { fillConfig } from '../utils/props';
|
|
29
28
|
|
|
30
29
|
import BaseService from './BaseService';
|
|
31
30
|
|
|
@@ -43,6 +42,7 @@ class Props extends BaseService {
|
|
|
43
42
|
'getPropsValue',
|
|
44
43
|
'createId',
|
|
45
44
|
'setNewItemId',
|
|
45
|
+
'fillConfig',
|
|
46
46
|
'getDefaultPropsValue',
|
|
47
47
|
]);
|
|
48
48
|
}
|
|
@@ -54,13 +54,17 @@ class Props extends BaseService {
|
|
|
54
54
|
this.emit('props-configs-change');
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
public async fillConfig(config: FormConfig) {
|
|
58
|
+
return fillConfig(config);
|
|
59
|
+
}
|
|
60
|
+
|
|
57
61
|
/**
|
|
58
62
|
* 为指定类型组件设置组件属性表单配置
|
|
59
63
|
* @param type 组件类型
|
|
60
64
|
* @param config 组件属性表单配置
|
|
61
65
|
*/
|
|
62
|
-
public setPropsConfig(type: string, config: FormConfig) {
|
|
63
|
-
this.state.propsConfigMap[type] = fillConfig(Array.isArray(config) ? config : [config]);
|
|
66
|
+
public async setPropsConfig(type: string, config: FormConfig) {
|
|
67
|
+
this.state.propsConfigMap[type] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
/**
|
|
@@ -73,7 +77,7 @@ class Props extends BaseService {
|
|
|
73
77
|
return await this.getPropsConfig('button');
|
|
74
78
|
}
|
|
75
79
|
|
|
76
|
-
return cloneDeep(this.state.propsConfigMap[type] ||
|
|
80
|
+
return cloneDeep(this.state.propsConfigMap[type] || (await this.fillConfig([])));
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
public setPropsValues(values: Record<string, MNode>) {
|
|
@@ -125,19 +129,6 @@ class Props extends BaseService {
|
|
|
125
129
|
};
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
/**
|
|
129
|
-
* 生成指定位数的GUID,无【-】格式
|
|
130
|
-
* @param digit 位数,默认值8
|
|
131
|
-
* @returns
|
|
132
|
-
*/
|
|
133
|
-
guid(digit = 8): string {
|
|
134
|
-
return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
|
|
135
|
-
const r = (Math.random() * 16) | 0;
|
|
136
|
-
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
137
|
-
return v.toString(16);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
132
|
public async createId(type: string | number): Promise<string> {
|
|
142
133
|
return `${type}_${this.guid()}`;
|
|
143
134
|
}
|
|
@@ -147,19 +138,12 @@ class Props extends BaseService {
|
|
|
147
138
|
* @param {Object} config 组件配置
|
|
148
139
|
*/
|
|
149
140
|
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
150
|
-
public async setNewItemId(config: MNode
|
|
151
|
-
const oldId = config.id;
|
|
152
|
-
|
|
141
|
+
public async setNewItemId(config: MNode) {
|
|
153
142
|
config.id = await this.createId(config.type || 'component');
|
|
154
143
|
|
|
155
|
-
// 只有弹窗在页面下的一级子元素才有效
|
|
156
|
-
if (isPop(config) && parent?.type === NodeType.PAGE) {
|
|
157
|
-
updatePopId(oldId, config.id, parent);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
144
|
if (config.items && Array.isArray(config.items)) {
|
|
161
145
|
for (const item of config.items) {
|
|
162
|
-
await this.setNewItemId(item
|
|
146
|
+
await this.setNewItemId(item);
|
|
163
147
|
}
|
|
164
148
|
}
|
|
165
149
|
|
|
@@ -186,31 +170,26 @@ class Props extends BaseService {
|
|
|
186
170
|
name: type,
|
|
187
171
|
};
|
|
188
172
|
}
|
|
189
|
-
}
|
|
190
173
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
*/
|
|
197
|
-
const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
|
|
198
|
-
pageConfig.items?.forEach((config) => {
|
|
199
|
-
if (config.pop === oldId) {
|
|
200
|
-
config.pop = popId;
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (config.popId === oldId) {
|
|
205
|
-
config.popId = popId;
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
174
|
+
public destroy() {
|
|
175
|
+
this.state.propsConfigMap = {};
|
|
176
|
+
this.state.propsValueMap = {};
|
|
177
|
+
this.removeAllListeners();
|
|
178
|
+
}
|
|
208
179
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
180
|
+
/**
|
|
181
|
+
* 生成指定位数的GUID,无【-】格式
|
|
182
|
+
* @param digit 位数,默认值8
|
|
183
|
+
* @returns
|
|
184
|
+
*/
|
|
185
|
+
private guid(digit = 8): string {
|
|
186
|
+
return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
|
|
187
|
+
const r = (Math.random() * 16) | 0;
|
|
188
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
189
|
+
return v.toString(16);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
214
193
|
|
|
215
194
|
export type PropsService = Props;
|
|
216
195
|
|
package/src/services/storage.ts
CHANGED
|
@@ -107,6 +107,10 @@ export class WebStorage extends BaseService {
|
|
|
107
107
|
storage.setItem(`${options.namespace || namespace}:${key}`, item);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
public destroy() {
|
|
111
|
+
this.removeAllListeners();
|
|
112
|
+
}
|
|
113
|
+
|
|
110
114
|
private getValueAndProtocol(value: string | null) {
|
|
111
115
|
let protocol = '';
|
|
112
116
|
|
package/src/services/ui.ts
CHANGED
|
@@ -64,16 +64,6 @@ class Ui extends BaseService {
|
|
|
64
64
|
center: 'auto',
|
|
65
65
|
});
|
|
66
66
|
});
|
|
67
|
-
|
|
68
|
-
const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
|
|
69
|
-
if (columnWidthCacheData) {
|
|
70
|
-
try {
|
|
71
|
-
const columnWidthCache = JSON.parse(columnWidthCacheData);
|
|
72
|
-
this.setColumnWidth(columnWidthCache);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
console.error(e);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
67
|
}
|
|
78
68
|
|
|
79
69
|
public set<T = any>(name: keyof UiState, value: T) {
|
|
@@ -98,21 +88,49 @@ class Ui extends BaseService {
|
|
|
98
88
|
}
|
|
99
89
|
|
|
100
90
|
(state as any)[name] = value;
|
|
101
|
-
|
|
102
|
-
if (name === 'stageContainerRect') {
|
|
103
|
-
state.zoom = this.calcZoom();
|
|
104
|
-
}
|
|
105
91
|
}
|
|
106
92
|
|
|
107
93
|
public get<T>(name: keyof typeof state): T {
|
|
108
94
|
return (state as any)[name];
|
|
109
95
|
}
|
|
110
96
|
|
|
97
|
+
public initColumnWidth() {
|
|
98
|
+
const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
|
|
99
|
+
if (columnWidthCacheData) {
|
|
100
|
+
try {
|
|
101
|
+
const columnWidthCache = JSON.parse(columnWidthCacheData);
|
|
102
|
+
this.setColumnWidth(columnWidthCache);
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.error(e);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
111
109
|
public zoom(zoom: number) {
|
|
112
110
|
this.set('zoom', (this.get<number>('zoom') * 100 + zoom * 100) / 100);
|
|
113
111
|
if (this.get<number>('zoom') < 0.1) this.set('zoom', 0.1);
|
|
114
112
|
}
|
|
115
113
|
|
|
114
|
+
public calcZoom() {
|
|
115
|
+
const { stageRect, stageContainerRect } = state;
|
|
116
|
+
const { height, width } = stageContainerRect;
|
|
117
|
+
if (!width || !height) return 1;
|
|
118
|
+
|
|
119
|
+
// 30为标尺的大小
|
|
120
|
+
const stageWidth = stageRect.width + 30;
|
|
121
|
+
const stageHeight = stageRect.height + 30;
|
|
122
|
+
|
|
123
|
+
if (width > stageWidth && height > stageHeight) {
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
// 60/80是为了不要让画布太过去贴住四周(这样好看些)
|
|
127
|
+
return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public destroy() {
|
|
131
|
+
this.removeAllListeners();
|
|
132
|
+
}
|
|
133
|
+
|
|
116
134
|
private setColumnWidth({ left, center, right }: SetColumnWidth) {
|
|
117
135
|
const columnWidth = {
|
|
118
136
|
...toRaw(this.get<GetColumnWidth>('columnWidth')),
|
|
@@ -150,22 +168,6 @@ class Ui extends BaseService {
|
|
|
150
168
|
};
|
|
151
169
|
state.zoom = this.calcZoom();
|
|
152
170
|
}
|
|
153
|
-
|
|
154
|
-
private calcZoom() {
|
|
155
|
-
const { stageRect, stageContainerRect } = state;
|
|
156
|
-
const { height, width } = stageContainerRect;
|
|
157
|
-
if (!width || !height) return 1;
|
|
158
|
-
|
|
159
|
-
// 30为标尺的大小
|
|
160
|
-
const stageWidth = stageRect.width + 30;
|
|
161
|
-
const stageHeight = stageRect.height + 30;
|
|
162
|
-
|
|
163
|
-
if (width > stageWidth && height > stageHeight) {
|
|
164
|
-
return 1;
|
|
165
|
-
}
|
|
166
|
-
// 60/80是为了不要让画布太过去贴住四周(这样好看些)
|
|
167
|
-
return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
|
|
168
|
-
}
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
export type UiService = Ui;
|
package/src/theme/nav-menu.scss
CHANGED
package/src/type.ts
CHANGED
|
@@ -82,16 +82,22 @@ export interface ComponentGroupState {
|
|
|
82
82
|
list: ComponentGroup[];
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
export enum ColumnLayout {
|
|
86
|
+
LEFT = 'left',
|
|
87
|
+
CENTER = 'center',
|
|
88
|
+
RIGHT = 'right',
|
|
89
|
+
}
|
|
90
|
+
|
|
85
91
|
export interface SetColumnWidth {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
[ColumnLayout.LEFT]?: number;
|
|
93
|
+
[ColumnLayout.CENTER]?: number | 'auto';
|
|
94
|
+
[ColumnLayout.RIGHT]?: number;
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
export interface GetColumnWidth {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
98
|
+
[ColumnLayout.LEFT]: number;
|
|
99
|
+
[ColumnLayout.CENTER]: number;
|
|
100
|
+
[ColumnLayout.RIGHT]: number;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
export interface StageRect {
|
|
@@ -174,6 +180,7 @@ export interface MenuButton {
|
|
|
174
180
|
/** type为button/dropdown时点击运行的方法 */
|
|
175
181
|
handler?: (data: Services, event: MouseEvent) => Promise<any> | any;
|
|
176
182
|
/** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
|
|
183
|
+
className?: string;
|
|
177
184
|
items?: MenuButton[];
|
|
178
185
|
}
|
|
179
186
|
|
|
@@ -187,6 +194,7 @@ export interface MenuComponent {
|
|
|
187
194
|
listeners?: Record<string, Function>;
|
|
188
195
|
slots?: Record<string, any>;
|
|
189
196
|
/** 是否显示,默认为true */
|
|
197
|
+
className?: string;
|
|
190
198
|
display?: boolean | ((data?: Services) => Promise<boolean> | boolean);
|
|
191
199
|
}
|
|
192
200
|
|
|
@@ -209,16 +217,17 @@ export type MenuItem =
|
|
|
209
217
|
| 'guides'
|
|
210
218
|
| 'rule'
|
|
211
219
|
| MenuButton
|
|
212
|
-
| MenuComponent
|
|
220
|
+
| MenuComponent
|
|
221
|
+
| string;
|
|
213
222
|
|
|
214
223
|
/** 工具栏 */
|
|
215
224
|
export interface MenuBarData {
|
|
216
225
|
/** 顶部工具栏左边项 */
|
|
217
|
-
|
|
226
|
+
[ColumnLayout.LEFT]?: MenuItem[];
|
|
218
227
|
/** 顶部工具栏中间项 */
|
|
219
|
-
|
|
228
|
+
[ColumnLayout.CENTER]?: MenuItem[];
|
|
220
229
|
/** 顶部工具栏右边项 */
|
|
221
|
-
|
|
230
|
+
[ColumnLayout.RIGHT]?: MenuItem[];
|
|
222
231
|
}
|
|
223
232
|
|
|
224
233
|
export interface SideComponent extends MenuComponent {
|
|
@@ -287,3 +296,10 @@ export enum Keys {
|
|
|
287
296
|
|
|
288
297
|
export const H_GUIDE_LINE_STORAGE_KEY = '$MagicStageHorizontalGuidelinesData';
|
|
289
298
|
export const V_GUIDE_LINE_STORAGE_KEY = '$MagicStageVerticalGuidelinesData';
|
|
299
|
+
|
|
300
|
+
export interface ScrollViewerEvent {
|
|
301
|
+
scrollLeft: number;
|
|
302
|
+
scrollTop: number;
|
|
303
|
+
scrollHeight: number;
|
|
304
|
+
scrollWidth: number;
|
|
305
|
+
}
|
package/src/utils/index.ts
CHANGED
package/src/utils/operator.ts
CHANGED
|
@@ -42,7 +42,7 @@ export const beforePaste = async (position: PastePosition, config: MNode[]): Pro
|
|
|
42
42
|
pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const pasteConfig = await propsService.setNewItemId(configItem
|
|
45
|
+
const pasteConfig = await propsService.setNewItemId(configItem);
|
|
46
46
|
|
|
47
47
|
if (pasteConfig.style) {
|
|
48
48
|
const { left, top } = pasteConfig.style;
|
|
@@ -86,11 +86,11 @@ export const getPositionInContainer = (position: PastePosition = {}, id: Id) =>
|
|
|
86
86
|
};
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
-
export const getAddParent = (
|
|
89
|
+
export const getAddParent = (node: MNode) => {
|
|
90
90
|
const curNode = editorService.get<MContainer>('node');
|
|
91
91
|
|
|
92
92
|
let parentNode;
|
|
93
|
-
if (
|
|
93
|
+
if (isPage(node)) {
|
|
94
94
|
parentNode = editorService.get<MApp>('root');
|
|
95
95
|
} else if (curNode.items) {
|
|
96
96
|
parentNode = curNode;
|