@tmagic/editor 1.1.0-beta.8 → 1.1.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 +46 -0
- package/dist/tmagic-editor.mjs +1052 -873
- package/dist/tmagic-editor.mjs.map +1 -1
- package/dist/tmagic-editor.umd.js +1054 -872
- package/dist/tmagic-editor.umd.js.map +1 -1
- package/package.json +10 -10
- package/src/Editor.vue +31 -9
- 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 -86
- package/src/layouts/workspace/ViewerMenu.vue +6 -6
- package/src/layouts/workspace/Workspace.vue +133 -138
- package/src/services/componentList.ts +5 -0
- package/src/services/editor.ts +148 -76
- 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 +28 -11
- package/src/utils/index.ts +1 -0
- package/src/utils/operator.ts +6 -60
- 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 +17 -8
- 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 +7 -9
- 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 +25 -11
- package/types/utils/index.d.ts +1 -0
- package/types/utils/operator.d.ts +1 -7
- 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
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
isFixed,
|
|
39
39
|
setLayout,
|
|
40
40
|
} from '../utils/editor';
|
|
41
|
-
import { beforePaste,
|
|
41
|
+
import { beforePaste, getAddParent } from '../utils/operator';
|
|
42
42
|
|
|
43
43
|
import BaseService from './BaseService';
|
|
44
44
|
import propsService from './props';
|
|
@@ -64,11 +64,15 @@ class Editor extends BaseService {
|
|
|
64
64
|
'select',
|
|
65
65
|
'doAdd',
|
|
66
66
|
'add',
|
|
67
|
+
'doRemove',
|
|
67
68
|
'remove',
|
|
69
|
+
'doUpdate',
|
|
68
70
|
'update',
|
|
69
71
|
'sort',
|
|
70
72
|
'copy',
|
|
71
73
|
'paste',
|
|
74
|
+
'doPaste',
|
|
75
|
+
'duAlignCenter',
|
|
72
76
|
'alignCenter',
|
|
73
77
|
'moveLayer',
|
|
74
78
|
'moveToContainer',
|
|
@@ -293,17 +297,27 @@ class Editor extends BaseService {
|
|
|
293
297
|
throw new Error('app下不能添加组件');
|
|
294
298
|
}
|
|
295
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
|
+
|
|
296
308
|
const layout = await this.getLayout(toRaw(parent), node as MNode);
|
|
297
309
|
node.style = getInitPositionStyle(node.style, layout);
|
|
298
310
|
|
|
299
|
-
await stage?.add({
|
|
311
|
+
await stage?.add({
|
|
312
|
+
config: cloneDeep(node),
|
|
313
|
+
parent: cloneDeep(parent),
|
|
314
|
+
parentId: parent.id,
|
|
315
|
+
root: cloneDeep(root),
|
|
316
|
+
});
|
|
300
317
|
|
|
301
318
|
node.style = fixNodePosition(node, parent, stage);
|
|
302
319
|
|
|
303
|
-
await stage?.update({ config: cloneDeep(node), root: cloneDeep(root) });
|
|
304
|
-
|
|
305
|
-
// 新增节点添加到配置中
|
|
306
|
-
parent?.items?.push(node);
|
|
320
|
+
await stage?.update({ config: cloneDeep(node), parentId: parent.id, root: cloneDeep(root) });
|
|
307
321
|
|
|
308
322
|
this.addModifiedNodeId(node.id);
|
|
309
323
|
|
|
@@ -319,9 +333,6 @@ class Editor extends BaseService {
|
|
|
319
333
|
public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
|
|
320
334
|
const stage = this.get<StageCore | null>('stage');
|
|
321
335
|
|
|
322
|
-
const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(addNode);
|
|
323
|
-
if (!parentNode) throw new Error('未找到父元素');
|
|
324
|
-
|
|
325
336
|
// 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
|
|
326
337
|
const addNodes = [];
|
|
327
338
|
if (!Array.isArray(addNode)) {
|
|
@@ -334,7 +345,13 @@ class Editor extends BaseService {
|
|
|
334
345
|
addNodes.push(...addNode);
|
|
335
346
|
}
|
|
336
347
|
|
|
337
|
-
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
|
+
);
|
|
338
355
|
|
|
339
356
|
if (newNodes.length > 1) {
|
|
340
357
|
const newNodeIds = newNodes.map((node) => node.id);
|
|
@@ -356,7 +373,49 @@ class Editor extends BaseService {
|
|
|
356
373
|
|
|
357
374
|
this.emit('add', newNodes);
|
|
358
375
|
|
|
359
|
-
return
|
|
376
|
+
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
public async doRemove(node: MNode): Promise<void> {
|
|
380
|
+
const root = this.get<MApp | null>('root');
|
|
381
|
+
|
|
382
|
+
if (!root) throw new Error('没有root');
|
|
383
|
+
|
|
384
|
+
const { parent, node: curNode } = this.getNodeInfo(node.id);
|
|
385
|
+
|
|
386
|
+
if (!parent || !curNode) throw new Error('找不要删除的节点');
|
|
387
|
+
|
|
388
|
+
const index = getNodeIndex(curNode, parent);
|
|
389
|
+
|
|
390
|
+
if (typeof index !== 'number' || index === -1) throw new Error('找不要删除的节点');
|
|
391
|
+
|
|
392
|
+
parent.items?.splice(index, 1);
|
|
393
|
+
const stage = this.get<StageCore | null>('stage');
|
|
394
|
+
stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
395
|
+
|
|
396
|
+
if (node.type === NodeType.PAGE) {
|
|
397
|
+
this.state.pageLength -= 1;
|
|
398
|
+
|
|
399
|
+
if (root.items[0]) {
|
|
400
|
+
await this.select(root.items[0]);
|
|
401
|
+
stage?.select(root.items[0].id);
|
|
402
|
+
} else {
|
|
403
|
+
this.set('nodes', [root]);
|
|
404
|
+
this.set('parent', null);
|
|
405
|
+
this.set('page', null);
|
|
406
|
+
this.set('stage', null);
|
|
407
|
+
this.set('highlightNode', null);
|
|
408
|
+
this.resetModifiedNodeId();
|
|
409
|
+
historyService.reset();
|
|
410
|
+
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
} else {
|
|
414
|
+
await this.select(parent);
|
|
415
|
+
stage?.select(parent.id);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
this.addModifiedNodeId(parent.id);
|
|
360
419
|
}
|
|
361
420
|
|
|
362
421
|
/**
|
|
@@ -364,50 +423,18 @@ class Editor extends BaseService {
|
|
|
364
423
|
* @param {Object} node
|
|
365
424
|
* @return {Object} 删除的组件配置
|
|
366
425
|
*/
|
|
367
|
-
public async remove(nodeOrNodeList: MNode | MNode[]): Promise<
|
|
368
|
-
|
|
369
|
-
// 多选批量删除
|
|
370
|
-
const nodes = nodeOrNodeList;
|
|
371
|
-
return this.multiRemove(nodes);
|
|
372
|
-
}
|
|
373
|
-
const node = nodeOrNodeList;
|
|
374
|
-
const removeParent = await beforeRemove(node);
|
|
375
|
-
// 删除的是页面
|
|
376
|
-
if (!removeParent) return node;
|
|
377
|
-
// 更新历史记录
|
|
378
|
-
this.addModifiedNodeId(removeParent.id);
|
|
379
|
-
this.pushHistoryState();
|
|
426
|
+
public async remove(nodeOrNodeList: MNode | MNode[]): Promise<void> {
|
|
427
|
+
const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
|
|
380
428
|
|
|
381
|
-
this.
|
|
429
|
+
await Promise.all(nodes.map((node) => this.doRemove(node)));
|
|
382
430
|
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* 批量删除
|
|
388
|
-
* @param nodes 批量删除的节点
|
|
389
|
-
* @returns 批量删除的节点
|
|
390
|
-
*/
|
|
391
|
-
public async multiRemove(nodes: MNode[]): Promise<MNode[]> {
|
|
392
|
-
await Promise.all(
|
|
393
|
-
nodes.map(async (removeNode) => {
|
|
394
|
-
await beforeRemove(removeNode);
|
|
395
|
-
}),
|
|
396
|
-
);
|
|
397
|
-
const nodeIds = nodes.map((node) => node.id);
|
|
398
|
-
this.addModifiedNodeId(nodeIds.join('-'));
|
|
431
|
+
// 更新历史记录
|
|
399
432
|
this.pushHistoryState();
|
|
400
433
|
|
|
401
|
-
this.emit('
|
|
402
|
-
return nodes;
|
|
434
|
+
this.emit('remove', nodes);
|
|
403
435
|
}
|
|
404
436
|
|
|
405
|
-
|
|
406
|
-
* 更新节点
|
|
407
|
-
* @param config 新的节点配置,配置中需要有id信息
|
|
408
|
-
* @returns 更新后的节点配置
|
|
409
|
-
*/
|
|
410
|
-
public async update(config: MNode): Promise<MNode> {
|
|
437
|
+
public async doUpdate(config: MNode) {
|
|
411
438
|
if (!config?.id) throw new Error('没有配置或者配置缺少id值');
|
|
412
439
|
|
|
413
440
|
const info = this.getNodeInfo(config.id, false);
|
|
@@ -453,18 +480,36 @@ class Editor extends BaseService {
|
|
|
453
480
|
nodes.splice(targetIndex, 1, newConfig);
|
|
454
481
|
this.set('nodes', nodes);
|
|
455
482
|
|
|
456
|
-
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
|
+
});
|
|
457
488
|
|
|
458
489
|
if (newConfig.type === NodeType.PAGE) {
|
|
459
490
|
this.set('page', newConfig);
|
|
460
491
|
}
|
|
461
492
|
|
|
462
493
|
this.addModifiedNodeId(newConfig.id);
|
|
494
|
+
|
|
495
|
+
return newConfig;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* 更新节点
|
|
500
|
+
* @param config 新的节点配置,配置中需要有id信息
|
|
501
|
+
* @returns 更新后的节点配置
|
|
502
|
+
*/
|
|
503
|
+
public async update(config: MNode | MNode[]): Promise<MNode | MNode[]> {
|
|
504
|
+
const nodes = Array.isArray(config) ? config : [config];
|
|
505
|
+
|
|
506
|
+
const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
|
|
507
|
+
|
|
463
508
|
this.pushHistoryState();
|
|
464
509
|
|
|
465
|
-
this.emit('update',
|
|
510
|
+
this.emit('update', newNodes);
|
|
466
511
|
|
|
467
|
-
return
|
|
512
|
+
return Array.isArray(config) ? newNodes : newNodes[0];
|
|
468
513
|
}
|
|
469
514
|
|
|
470
515
|
/**
|
|
@@ -486,7 +531,11 @@ class Editor extends BaseService {
|
|
|
486
531
|
await this.update(parent);
|
|
487
532
|
await this.select(node);
|
|
488
533
|
|
|
489
|
-
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
|
+
});
|
|
490
539
|
|
|
491
540
|
this.addModifiedNodeId(parent.id);
|
|
492
541
|
this.pushHistoryState();
|
|
@@ -513,25 +562,28 @@ class Editor extends BaseService {
|
|
|
513
562
|
|
|
514
563
|
if (!Array.isArray(config)) return;
|
|
515
564
|
|
|
516
|
-
const pasteConfigs = await
|
|
565
|
+
const pasteConfigs = await this.doPaste(config, position);
|
|
517
566
|
|
|
518
567
|
return this.add(pasteConfigs);
|
|
519
568
|
}
|
|
520
569
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
public async
|
|
527
|
-
const parent = this.
|
|
528
|
-
|
|
529
|
-
|
|
570
|
+
public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
|
|
571
|
+
const pasteConfigs = await beforePaste(position, cloneDeep(config));
|
|
572
|
+
return pasteConfigs;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
public async doAlignCenter(config: MNode): Promise<MNode> {
|
|
576
|
+
const parent = this.getParentById(config.id);
|
|
577
|
+
|
|
578
|
+
if (!parent) throw new Error('找不到父节点');
|
|
579
|
+
|
|
580
|
+
const node = cloneDeep(toRaw(config));
|
|
581
|
+
const layout = await this.getLayout(parent, node);
|
|
530
582
|
if (layout === Layout.RELATIVE) {
|
|
531
|
-
return;
|
|
583
|
+
return config;
|
|
532
584
|
}
|
|
533
585
|
|
|
534
|
-
if (!node.style) return;
|
|
586
|
+
if (!node.style) return config;
|
|
535
587
|
|
|
536
588
|
const stage = this.get<StageCore>('stage');
|
|
537
589
|
const doc = stage?.renderer.contentWindow?.document;
|
|
@@ -546,15 +598,25 @@ class Editor extends BaseService {
|
|
|
546
598
|
node.style.left = (parent.style.width - node.style.width) / 2;
|
|
547
599
|
}
|
|
548
600
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
601
|
+
return node;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* 将指点节点设置居中
|
|
606
|
+
* @param config 组件节点配置
|
|
607
|
+
* @returns 当前组件节点配置
|
|
608
|
+
*/
|
|
609
|
+
public async alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]> {
|
|
610
|
+
const nodes = Array.isArray(config) ? config : [config];
|
|
611
|
+
const stage = this.get<StageCore | null>('stage');
|
|
612
|
+
|
|
613
|
+
const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
|
|
614
|
+
|
|
615
|
+
const newNode = await this.update(newNodes);
|
|
556
616
|
|
|
557
|
-
|
|
617
|
+
await stage?.multiSelect(newNodes.map((node) => node.id));
|
|
618
|
+
|
|
619
|
+
return newNode;
|
|
558
620
|
}
|
|
559
621
|
|
|
560
622
|
/**
|
|
@@ -563,7 +625,7 @@ class Editor extends BaseService {
|
|
|
563
625
|
*/
|
|
564
626
|
public async moveLayer(offset: number | LayerOffset): Promise<void> {
|
|
565
627
|
const parent = this.get<MContainer>('parent');
|
|
566
|
-
const node = this.get('node');
|
|
628
|
+
const node = this.get<MNode>('node');
|
|
567
629
|
const brothers: MNode[] = parent?.items || [];
|
|
568
630
|
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
569
631
|
|
|
@@ -575,10 +637,15 @@ class Editor extends BaseService {
|
|
|
575
637
|
brothers.splice(index + parseInt(`${offset}`, 10), 0, brothers.splice(index, 1)[0]);
|
|
576
638
|
}
|
|
577
639
|
|
|
640
|
+
const grandparent = this.getParentById(parent.id);
|
|
578
641
|
this.get<StageCore | null>('stage')?.update({
|
|
579
642
|
config: cloneDeep(toRaw(parent)),
|
|
643
|
+
parentId: grandparent?.id,
|
|
580
644
|
root: cloneDeep(this.get<MApp>('root')),
|
|
581
645
|
});
|
|
646
|
+
|
|
647
|
+
this.addModifiedNodeId(parent.id);
|
|
648
|
+
this.pushHistoryState();
|
|
582
649
|
}
|
|
583
650
|
|
|
584
651
|
/**
|
|
@@ -597,7 +664,7 @@ class Editor extends BaseService {
|
|
|
597
664
|
const index = getNodeIndex(node, parent);
|
|
598
665
|
parent.items?.splice(index, 1);
|
|
599
666
|
|
|
600
|
-
await stage.remove({ id: node.id, root });
|
|
667
|
+
await stage.remove({ id: node.id, parentId: parent.id, root });
|
|
601
668
|
|
|
602
669
|
const layout = await this.getLayout(target);
|
|
603
670
|
|
|
@@ -612,7 +679,8 @@ class Editor extends BaseService {
|
|
|
612
679
|
|
|
613
680
|
await stage.select(targetId);
|
|
614
681
|
|
|
615
|
-
|
|
682
|
+
const targetParent = this.getParentById(target.id);
|
|
683
|
+
await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root });
|
|
616
684
|
|
|
617
685
|
await this.select(newConfig);
|
|
618
686
|
stage.select(newConfig.id);
|
|
@@ -673,6 +741,10 @@ class Editor extends BaseService {
|
|
|
673
741
|
this.set('nodes', []);
|
|
674
742
|
this.set('page', null);
|
|
675
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());
|
|
676
748
|
}
|
|
677
749
|
|
|
678
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;
|