@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.
Files changed (56) hide show
  1. package/dist/style.css +4 -0
  2. package/dist/tmagic-editor.js +305 -249
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +308 -253
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +9 -9
  7. package/src/Editor.vue +1 -1
  8. package/src/components/CodeDraftEditor.vue +2 -10
  9. package/src/components/FunctionEditor.vue +58 -13
  10. package/src/components/Layout.vue +1 -1
  11. package/src/fields/CodeSelect.vue +23 -7
  12. package/src/fields/UISelect.vue +2 -2
  13. package/src/index.ts +1 -1
  14. package/src/layouts/AddPageBox.vue +4 -1
  15. package/src/layouts/Framework.vue +10 -8
  16. package/src/layouts/NavMenu.vue +9 -6
  17. package/src/layouts/PropsPanel.vue +3 -7
  18. package/src/layouts/sidebar/ComponentListPanel.vue +1 -2
  19. package/src/layouts/sidebar/LayerPanel.vue +8 -9
  20. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +10 -39
  21. package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -6
  22. package/src/layouts/workspace/Breadcrumb.vue +5 -6
  23. package/src/layouts/workspace/PageBar.vue +2 -2
  24. package/src/layouts/workspace/PageBarScrollContainer.vue +4 -2
  25. package/src/layouts/workspace/Stage.vue +11 -10
  26. package/src/layouts/workspace/ViewerMenu.vue +5 -6
  27. package/src/layouts/workspace/Workspace.vue +2 -3
  28. package/src/services/BaseService.ts +1 -1
  29. package/src/services/codeBlock.ts +15 -24
  30. package/src/services/componentList.ts +1 -1
  31. package/src/services/editor.ts +119 -79
  32. package/src/services/events.ts +1 -1
  33. package/src/services/history.ts +1 -1
  34. package/src/services/props.ts +1 -1
  35. package/src/services/ui.ts +8 -10
  36. package/src/theme/code-block.scss +4 -0
  37. package/src/type.ts +7 -13
  38. package/src/utils/config.ts +1 -1
  39. package/src/utils/editor.ts +8 -2
  40. package/src/utils/index.ts +1 -1
  41. package/src/utils/logger.ts +1 -1
  42. package/src/utils/operator.ts +12 -12
  43. package/src/utils/props.ts +1 -1
  44. package/src/utils/stage.ts +6 -6
  45. package/src/utils/undo-redo.ts +1 -1
  46. package/types/Editor.vue.d.ts +1 -1
  47. package/types/components/CodeDraftEditor.vue.d.ts +1 -2
  48. package/types/components/FunctionEditor.vue.d.ts +17 -0
  49. package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +23 -5
  50. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +5 -0
  51. package/types/layouts/workspace/Workspace.vue.d.ts +2 -3
  52. package/types/services/codeBlock.d.ts +0 -12
  53. package/types/services/editor.d.ts +6 -6
  54. package/types/services/ui.d.ts +23 -24
  55. package/types/type.d.ts +5 -11
  56. package/types/utils/operator.d.ts +1 -1
@@ -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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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.
@@ -27,7 +27,7 @@ import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
27
27
  import codeBlockService from '../services/codeBlock';
28
28
  import historyService from '../services/history';
29
29
  import storageService, { Protocol } from '../services/storage';
30
- import type { AddMNode, EditorNodeInfo, PastePosition, StepValue, StoreState } from '../type';
30
+ import type { AddMNode, EditorNodeInfo, PastePosition, StepValue, StoreState, StoreStateKey } from '../type';
31
31
  import { LayerOffset, Layout } from '../type';
32
32
  import {
33
33
  change2Fixed,
@@ -94,15 +94,26 @@ class Editor extends BaseService {
94
94
  * @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength'
95
95
  * @param value MNode
96
96
  */
97
- public set<T = MNode>(name: keyof StoreState, value: T) {
97
+ public set<K extends StoreStateKey, T extends StoreState[K]>(name: K, value: T) {
98
98
  const preValue = this.state[name];
99
- this.state[name] = value as any;
99
+ this.state[name] = value;
100
+
100
101
  // set nodes时将node设置为nodes第一个元素
101
- if (name === 'nodes') {
102
- this.set('node', (value as unknown as MNode[])[0]);
102
+ if (name === 'nodes' && Array.isArray(value)) {
103
+ this.set('node', value[0]);
103
104
  }
105
+
104
106
  if (name === 'root') {
105
- this.state.pageLength = (value as unknown as MApp)?.items?.length || 0;
107
+ if (Array.isArray(value)) {
108
+ throw new Error('root 不能为数组');
109
+ }
110
+
111
+ if (value && isObject(value) && !(value instanceof StageCore) && !(value instanceof Map)) {
112
+ this.state.pageLength = value.items?.length || 0;
113
+ } else {
114
+ this.state.pageLength = 0;
115
+ }
116
+
106
117
  this.emit('root-change', value, preValue);
107
118
  }
108
119
  }
@@ -112,8 +123,8 @@ class Editor extends BaseService {
112
123
  * @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength'
113
124
  * @returns MNode
114
125
  */
115
- public get<T = MNode>(name: keyof StoreState): T {
116
- return (this.state as any)[name];
126
+ public get<K extends StoreStateKey>(name: K): StoreState[K] {
127
+ return this.state[name];
117
128
  }
118
129
 
119
130
  /**
@@ -123,22 +134,29 @@ class Editor extends BaseService {
123
134
  * @returns {EditorNodeInfo}
124
135
  */
125
136
  public getNodeInfo(id: Id, raw = true): EditorNodeInfo {
126
- let root = this.get<MApp | null>('root');
137
+ let root = this.get('root');
127
138
  if (raw) {
128
139
  root = toRaw(root);
129
140
  }
130
- if (!root) return {};
141
+
142
+ const info: EditorNodeInfo = {
143
+ node: null,
144
+ parent: null,
145
+ page: null,
146
+ };
147
+
148
+ if (!root) return info;
131
149
 
132
150
  if (id === root.id) {
133
- return { node: root };
151
+ info.node = root;
152
+ return info;
134
153
  }
135
154
 
136
155
  const path = getNodePath(id, root.items);
137
156
 
138
- if (!path.length) return {};
157
+ if (!path.length) return info;
139
158
 
140
159
  path.unshift(root);
141
- const info: EditorNodeInfo = {};
142
160
 
143
161
  info.node = path[path.length - 1] as MComponent;
144
162
  info.parent = path[path.length - 2] as MContainer;
@@ -159,7 +177,7 @@ class Editor extends BaseService {
159
177
  * @param {boolean} raw 是否使用toRaw
160
178
  * @returns 组件节点配置
161
179
  */
162
- public getNodeById(id: Id, raw = true): MNode | undefined {
180
+ public getNodeById(id: Id, raw = true): MNode | null {
163
181
  const { node } = this.getNodeInfo(id, raw);
164
182
  return node;
165
183
  }
@@ -170,8 +188,7 @@ class Editor extends BaseService {
170
188
  * @param {boolean} raw 是否使用toRaw
171
189
  * @returns 指点组件的父节点配置
172
190
  */
173
- public getParentById(id: Id, raw = true): MContainer | undefined {
174
- if (!this.get<MApp | null>('root')) return;
191
+ public getParentById(id: Id, raw = true): MContainer | null {
175
192
  const { parent } = this.getNodeInfo(id, raw);
176
193
  return parent;
177
194
  }
@@ -201,9 +218,9 @@ class Editor extends BaseService {
201
218
  */
202
219
  public async select(config: MNode | Id): Promise<MNode> | never {
203
220
  const { node, page, parent } = this.selectedConfigExceptionHandler(config);
204
- this.set('nodes', [node]);
205
- this.set('page', page || null);
206
- this.set('parent', parent || null);
221
+ this.set('nodes', node ? [node] : []);
222
+ this.set('page', page);
223
+ this.set('parent', parent);
207
224
 
208
225
  if (page) {
209
226
  historyService.changePage(toRaw(page));
@@ -212,7 +229,7 @@ class Editor extends BaseService {
212
229
  }
213
230
 
214
231
  if (node?.id) {
215
- this.get<StageCore>('stage')
232
+ this.get('stage')
216
233
  ?.renderer.runtime?.getApp?.()
217
234
  ?.emit(
218
235
  'editor:select',
@@ -221,7 +238,7 @@ class Editor extends BaseService {
221
238
  page,
222
239
  parent,
223
240
  },
224
- getNodePath(node.id, this.get<MApp>('root').items),
241
+ getNodePath(node.id, this.get('root')?.items),
225
242
  );
226
243
  }
227
244
 
@@ -230,7 +247,7 @@ class Editor extends BaseService {
230
247
  return node!;
231
248
  }
232
249
 
233
- public async selectNextNode(): Promise<MNode> | never {
250
+ public async selectNextNode(): Promise<MNode | null> | never {
234
251
  const node = toRaw(this.get('node'));
235
252
 
236
253
  if (!node || isPage(node) || node.type === NodeType.ROOT) return node;
@@ -244,21 +261,24 @@ class Editor extends BaseService {
244
261
  const nextNode = parent.items[index + 1] || parent.items[0];
245
262
 
246
263
  await this.select(nextNode);
247
- this.get<StageCore>('stage')?.select(nextNode.id);
264
+ this.get('stage')?.select(nextNode.id);
248
265
 
249
266
  return nextNode;
250
267
  }
251
268
 
252
269
  public async selectNextPage(): Promise<MNode> | never {
253
- const root = toRaw(this.get<MApp>('root'));
270
+ const root = toRaw(this.get('root'));
254
271
  const page = toRaw(this.get('page'));
255
272
 
273
+ if (!page) throw new Error('page不能为空');
274
+ if (!root) throw new Error('root不能为空');
275
+
256
276
  const index = getNodeIndex(page, root);
257
277
 
258
278
  const nextPage = root.items[index + 1] || root.items[0];
259
279
 
260
280
  await this.select(nextPage);
261
- this.get<StageCore>('stage')?.select(nextPage.id);
281
+ this.get('stage')?.select(nextPage.id);
262
282
 
263
283
  return nextPage;
264
284
  }
@@ -292,20 +312,25 @@ class Editor extends BaseService {
292
312
  }
293
313
 
294
314
  public async doAdd(node: MNode, parent: MContainer): Promise<MNode> {
295
- const root = this.get<MApp>('root');
296
- const curNode = this.get<MNode>('node');
297
- const stage = this.get<StageCore | null>('stage');
315
+ const root = this.get('root');
316
+
317
+ if (!root) throw new Error('root为空');
318
+
319
+ const curNode = this.get('node');
320
+ const stage = this.get('stage');
321
+
322
+ if (!curNode) throw new Error('当前选中节点为空');
298
323
 
299
- if ((parent?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
324
+ if ((parent.type === NodeType.ROOT || curNode?.type === NodeType.ROOT) && node.type !== NodeType.PAGE) {
300
325
  throw new Error('app下不能添加组件');
301
326
  }
302
327
 
303
328
  if (parent.id !== curNode.id && node.type !== NodeType.PAGE) {
304
329
  const index = parent.items.indexOf(curNode);
305
- parent?.items?.splice(index + 1, 0, node);
330
+ parent.items?.splice(index + 1, 0, node);
306
331
  } else {
307
332
  // 新增节点添加到配置中
308
- parent?.items?.push(node);
333
+ parent.items?.push(node);
309
334
  }
310
335
 
311
336
  const layout = await this.getLayout(toRaw(parent), node as MNode);
@@ -337,7 +362,7 @@ class Editor extends BaseService {
337
362
  * @returns 添加后的节点
338
363
  */
339
364
  public async add(addNode: AddMNode | MNode[], parent?: MContainer | null): Promise<MNode | MNode[]> {
340
- const stage = this.get<StageCore | null>('stage');
365
+ const stage = this.get('stage');
341
366
 
342
367
  // 新增多个组件只存在于粘贴多个组件,粘贴的是一个完整的config,所以不再需要getPropsValue
343
368
  const addNodes = [];
@@ -353,8 +378,9 @@ class Editor extends BaseService {
353
378
 
354
379
  const newNodes = await Promise.all(
355
380
  addNodes.map((node) => {
356
- if (isPage(node)) {
357
- return this.doAdd(node, this.get('root'));
381
+ const root = this.get('root');
382
+ if (isPage(node) && root) {
383
+ return this.doAdd(node, root);
358
384
  }
359
385
  const parentNode = parent && typeof parent !== 'function' ? parent : getAddParent(node);
360
386
  if (!parentNode) throw new Error('未找到父元素');
@@ -388,9 +414,8 @@ class Editor extends BaseService {
388
414
  }
389
415
 
390
416
  public async doRemove(node: MNode): Promise<void> {
391
- const root = this.get<MApp | null>('root');
392
-
393
- if (!root) throw new Error('没有root');
417
+ const root = this.get('root');
418
+ if (!root) throw new Error('root不能为空');
394
419
 
395
420
  const { parent, node: curNode } = this.getNodeInfo(node.id);
396
421
 
@@ -401,7 +426,7 @@ class Editor extends BaseService {
401
426
  if (typeof index !== 'number' || index === -1) throw new Error('找不要删除的节点');
402
427
 
403
428
  parent.items?.splice(index, 1);
404
- const stage = this.get<StageCore | null>('stage');
429
+ const stage = this.get('stage');
405
430
  stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
406
431
 
407
432
  if (node.type === NodeType.PAGE) {
@@ -450,6 +475,9 @@ class Editor extends BaseService {
450
475
  }
451
476
 
452
477
  public async doUpdate(config: MNode) {
478
+ const root = this.get('root');
479
+ if (!root) throw new Error('root为空');
480
+
453
481
  if (!config?.id) throw new Error('没有配置或者配置缺少id值');
454
482
 
455
483
  const info = this.getNodeInfo(config.id, false);
@@ -458,7 +486,7 @@ class Editor extends BaseService {
458
486
 
459
487
  const node = cloneDeep(toRaw(info.node));
460
488
 
461
- let newConfig = await this.toggleFixedPosition(toRaw(config), node, this.get<MApp>('root'));
489
+ let newConfig = await this.toggleFixedPosition(toRaw(config), node, root);
462
490
 
463
491
  newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => {
464
492
  if (isObject(srcValue) && Array.isArray(objValue)) {
@@ -473,7 +501,7 @@ class Editor extends BaseService {
473
501
  if (!newConfig.type) throw new Error('配置缺少type值');
474
502
 
475
503
  if (newConfig.type === NodeType.ROOT) {
476
- this.set('root', newConfig);
504
+ this.set('root', newConfig as MApp);
477
505
  return newConfig;
478
506
  }
479
507
 
@@ -494,19 +522,19 @@ class Editor extends BaseService {
494
522
  parentNodeItems[index] = newConfig;
495
523
 
496
524
  // 将update后的配置更新到nodes中
497
- const nodes = this.get<MNode[]>('nodes') || [];
525
+ const nodes = this.get('nodes');
498
526
  const targetIndex = nodes.findIndex((nodeItem: MNode) => `${nodeItem.id}` === `${newConfig.id}`);
499
527
  nodes.splice(targetIndex, 1, newConfig);
500
528
  this.set('nodes', [...nodes]);
501
529
 
502
- this.get<StageCore | null>('stage')?.update({
530
+ this.get('stage')?.update({
503
531
  config: cloneDeep(newConfig),
504
532
  parentId: parent.id,
505
- root: cloneDeep(this.get('root')),
533
+ root: cloneDeep(root),
506
534
  });
507
535
 
508
536
  if (newConfig.type === NodeType.PAGE) {
509
- this.set('page', newConfig);
537
+ this.set('page', newConfig as MPage);
510
538
  }
511
539
 
512
540
  this.addModifiedNodeId(newConfig.id);
@@ -538,8 +566,15 @@ class Editor extends BaseService {
538
566
  * @returns void
539
567
  */
540
568
  public async sort(id1: Id, id2: Id): Promise<void> {
541
- const node = this.get<MNode>('node');
542
- const parent = cloneDeep(toRaw(this.get<MContainer>('parent')));
569
+ const root = this.get('root');
570
+ if (!root) throw new Error('root为空');
571
+
572
+ const node = this.get('node');
573
+ if (!node) throw new Error('当前节点为空');
574
+
575
+ const parent = cloneDeep(toRaw(this.get('parent')));
576
+ if (!parent) throw new Error('父节点为空');
577
+
543
578
  const index2 = parent.items.findIndex((node: MNode) => `${node.id}` === `${id2}`);
544
579
  // 在 id1 的兄弟组件中若无 id2 则直接 return
545
580
  if (index2 < 0) return;
@@ -550,10 +585,10 @@ class Editor extends BaseService {
550
585
  await this.update(parent);
551
586
  await this.select(node);
552
587
 
553
- this.get<StageCore | null>('stage')?.update({
588
+ this.get('stage')?.update({
554
589
  config: cloneDeep(node),
555
590
  parentId: parent.id,
556
- root: cloneDeep(this.get('root')),
591
+ root: cloneDeep(root),
557
592
  });
558
593
 
559
594
  this.addModifiedNodeId(parent.id);
@@ -581,14 +616,14 @@ class Editor extends BaseService {
581
616
 
582
617
  if (!Array.isArray(config)) return;
583
618
 
584
- const node = this.get<MNode>('node');
619
+ const node = this.get('node');
585
620
 
586
- let parent: MContainer | undefined = undefined;
621
+ let parent: MContainer | null = null;
587
622
  // 粘贴的组件为当前选中组件的副本时,则添加到当前选中组件的父组件中
588
- if (config.length === 1 && config[0].id === node.id) {
589
- parent = this.get<MContainer>('parent');
590
- if (parent.type === NodeType.ROOT) {
591
- parent = this.get<MPage>('page');
623
+ if (config.length === 1 && config[0].id === node?.id) {
624
+ parent = this.get('parent');
625
+ if (parent?.type === NodeType.ROOT) {
626
+ parent = this.get('page');
592
627
  }
593
628
  }
594
629
 
@@ -615,7 +650,7 @@ class Editor extends BaseService {
615
650
 
616
651
  if (!node.style) return config;
617
652
 
618
- const stage = this.get<StageCore>('stage');
653
+ const stage = this.get('stage');
619
654
  const doc = stage?.renderer.contentWindow?.document;
620
655
 
621
656
  if (doc) {
@@ -638,7 +673,7 @@ class Editor extends BaseService {
638
673
  */
639
674
  public async alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]> {
640
675
  const nodes = Array.isArray(config) ? config : [config];
641
- const stage = this.get<StageCore | null>('stage');
676
+ const stage = this.get('stage');
642
677
 
643
678
  const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
644
679
 
@@ -658,9 +693,16 @@ class Editor extends BaseService {
658
693
  * @param offset 偏移量
659
694
  */
660
695
  public async moveLayer(offset: number | LayerOffset): Promise<void> {
661
- const parent = this.get<MContainer>('parent');
662
- const node = this.get<MNode>('node');
663
- const brothers: MNode[] = parent?.items || [];
696
+ const root = this.get('root');
697
+ if (!root) throw new Error('root为空');
698
+
699
+ const parent = this.get('parent');
700
+ if (!parent) throw new Error('父节点为空');
701
+
702
+ const node = this.get('node');
703
+ if (!node) throw new Error('当前节点为空');
704
+
705
+ const brothers: MNode[] = parent.items || [];
664
706
  const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
665
707
 
666
708
  // 流式布局与绝对定位布局操作的相反的
@@ -678,10 +720,10 @@ class Editor extends BaseService {
678
720
  }
679
721
 
680
722
  const grandparent = this.getParentById(parent.id);
681
- this.get<StageCore | null>('stage')?.update({
723
+ this.get('stage')?.update({
682
724
  config: cloneDeep(toRaw(parent)),
683
725
  parentId: grandparent?.id,
684
- root: cloneDeep(this.get<MApp>('root')),
726
+ root: cloneDeep(root),
685
727
  });
686
728
 
687
729
  this.addModifiedNodeId(parent.id);
@@ -694,13 +736,12 @@ class Editor extends BaseService {
694
736
  * @param targetId 容器ID
695
737
  */
696
738
  public async moveToContainer(config: MNode, targetId: Id): Promise<MNode | undefined> {
739
+ const root = cloneDeep(this.get('root'));
697
740
  const { node, parent } = this.getNodeInfo(config.id, false);
698
741
  const target = this.getNodeById(targetId, false) as MContainer;
699
742
 
700
- const stage = this.get<StageCore | null>('stage');
701
-
702
- if (node && parent && stage) {
703
- const root = cloneDeep(this.get<MApp>('root'));
743
+ const stage = this.get('stage');
744
+ if (root && node && parent && stage) {
704
745
  const index = getNodeIndex(node, parent);
705
746
  parent.items?.splice(index, 1);
706
747
 
@@ -783,7 +824,7 @@ class Editor extends BaseService {
783
824
  this.set('stage', null);
784
825
  this.set('highlightNode', null);
785
826
  this.set('modifiedNodeIds', new Map());
786
- this.set('pageLength', new Map());
827
+ this.set('pageLength', 0);
787
828
  }
788
829
 
789
830
  public destroy() {
@@ -793,7 +834,7 @@ class Editor extends BaseService {
793
834
  }
794
835
 
795
836
  public resetModifiedNodeId() {
796
- this.get<Map<Id, Id>>('modifiedNodeIds').clear();
837
+ this.get('modifiedNodeIds').clear();
797
838
  }
798
839
 
799
840
  /**
@@ -801,15 +842,13 @@ class Editor extends BaseService {
801
842
  * @returns {CodeBlockDSL | null}
802
843
  */
803
844
  public async getCodeDsl(): Promise<CodeBlockDSL | null> {
804
- const root = this.get<MApp | null>('root');
805
- if (!root) return null;
806
- return root.codeBlocks || null;
845
+ const root = this.get('root');
846
+ return root?.codeBlocks || null;
807
847
  }
808
848
 
809
849
  public getCodeDslSync(): CodeBlockDSL | null {
810
- const root = this.get<MApp | null>('root');
811
- if (!root) return null;
812
- return root.codeBlocks || null;
850
+ const root = this.get('root');
851
+ return root?.codeBlocks || null;
813
852
  }
814
853
 
815
854
  /**
@@ -824,16 +863,17 @@ class Editor extends BaseService {
824
863
 
825
864
  private addModifiedNodeId(id: Id) {
826
865
  if (!this.isHistoryStateChange) {
827
- this.get<Map<Id, Id>>('modifiedNodeIds').set(id, id);
866
+ this.get('modifiedNodeIds').set(id, id);
828
867
  }
829
868
  }
830
869
 
831
870
  private pushHistoryState() {
832
871
  const curNode = cloneDeep(toRaw(this.get('node')));
833
- if (!this.isHistoryStateChange) {
872
+ const page = this.get('page');
873
+ if (!this.isHistoryStateChange && curNode && page) {
834
874
  historyService.push({
835
- data: cloneDeep(toRaw(this.get('page'))),
836
- modifiedNodeIds: this.get<Map<Id, Id>>('modifiedNodeIds'),
875
+ data: cloneDeep(toRaw(page)),
876
+ modifiedNodeIds: this.get('modifiedNodeIds'),
837
877
  nodeId: curNode.id,
838
878
  });
839
879
  }
@@ -849,7 +889,7 @@ class Editor extends BaseService {
849
889
  setTimeout(async () => {
850
890
  if (!value.nodeId) return;
851
891
  await this.select(value.nodeId);
852
- this.get<StageCore | null>('stage')?.select(value.nodeId);
892
+ this.get('stage')?.select(value.nodeId);
853
893
  }, 0);
854
894
  }
855
895
 
@@ -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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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.
@@ -18,8 +18,6 @@
18
18
 
19
19
  import { reactive } from 'vue';
20
20
 
21
- import type StageCore from '@tmagic/stage';
22
-
23
21
  import editorService from '../services/editor';
24
22
  import type { StageRect, UiState } from '../type';
25
23
 
@@ -53,8 +51,8 @@ class Ui extends BaseService {
53
51
  super(['zoom', 'calcZoom']);
54
52
  }
55
53
 
56
- public set<T = any>(name: keyof UiState, value: T) {
57
- const mask = editorService.get<StageCore>('stage')?.mask;
54
+ public set<K extends keyof UiState, T extends UiState[K]>(name: K, value: T) {
55
+ const mask = editorService.get('stage')?.mask;
58
56
 
59
57
  if (name === 'stageRect') {
60
58
  this.setStageRect(value as unknown as StageRect);
@@ -69,16 +67,16 @@ class Ui extends BaseService {
69
67
  mask?.showRule(value as unknown as boolean);
70
68
  }
71
69
 
72
- (state as any)[name] = value;
70
+ state[name] = value;
73
71
  }
74
72
 
75
- public get<T>(name: keyof typeof state): T {
76
- return (state as any)[name];
73
+ public get<K extends keyof UiState>(name: K) {
74
+ return state[name];
77
75
  }
78
76
 
79
77
  public async zoom(zoom: number) {
80
- this.set('zoom', (this.get<number>('zoom') * 100 + zoom * 100) / 100);
81
- if (this.get<number>('zoom') < 0.1) this.set('zoom', 0.1);
78
+ this.set('zoom', (this.get('zoom') * 100 + zoom * 100) / 100);
79
+ if (this.get('zoom') < 0.1) this.set('zoom', 0.1);
82
80
  }
83
81
 
84
82
  public async calcZoom() {
@@ -78,6 +78,10 @@
78
78
 
79
79
  .m-fields-code-select {
80
80
  width: 100%;
81
+ .edit-icon {
82
+ cursor: pointer;
83
+ margin-right: 5px;
84
+ }
81
85
  }
82
86
 
83
87
  .el-dialog.is-fullscreen.code-editor-dialog {
package/src/type.ts CHANGED
@@ -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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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.
@@ -82,6 +82,8 @@ export interface StoreState {
82
82
  pageLength: number;
83
83
  }
84
84
 
85
+ export type StoreStateKey = keyof StoreState;
86
+
85
87
  export interface PropsState {
86
88
  propsConfigMap: Record<string, FormConfig>;
87
89
  propsValueMap: Record<string, MNode>;
@@ -138,9 +140,9 @@ export interface UiState {
138
140
  }
139
141
 
140
142
  export interface EditorNodeInfo {
141
- node?: MNode;
142
- parent?: MContainer;
143
- page?: MPage;
143
+ node: MNode | null;
144
+ parent: MContainer | null;
145
+ page: MPage | null;
144
146
  }
145
147
 
146
148
  export interface AddMNode {
@@ -333,8 +335,6 @@ export type CodeState = {
333
335
  id: Id;
334
336
  /** 代码块是否可编辑 */
335
337
  editable: boolean;
336
- /** 代码编辑面板的展示模式 */
337
- mode: CodeEditorMode;
338
338
  /** list模式下左侧展示的代码列表 */
339
339
  combineIds: string[];
340
340
  /** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
@@ -357,13 +357,6 @@ export type CodeRelation = {
357
357
  };
358
358
  };
359
359
 
360
- export enum CodeEditorMode {
361
- /** 左侧菜单,右侧代码 */
362
- LIST = 'list',
363
- /** 全屏代码 */
364
- EDITOR = 'editor',
365
- }
366
-
367
360
  export interface CodeDslItem {
368
361
  /** 代码块id */
369
362
  id: Id;
@@ -404,6 +397,7 @@ export interface CodeParamStatement {
404
397
  name: string;
405
398
  /** 参数类型 */
406
399
  type?: string;
400
+ [key: string]: any;
407
401
  }
408
402
 
409
403
  export interface StepValue {
@@ -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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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) 2021 THL A29 Limited, a Tencent company. All rights reserved.
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.
@@ -110,10 +110,16 @@ const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) =
110
110
 
111
111
  export const getInitPositionStyle = (style: Record<string, any> = {}, layout: Layout) => {
112
112
  if (layout === Layout.ABSOLUTE) {
113
- return {
113
+ const newStyle: Record<string, any> = {
114
114
  ...style,
115
115
  position: 'absolute',
116
116
  };
117
+
118
+ if (typeof newStyle.left === 'undefined' && typeof newStyle.right === 'undefined') {
119
+ newStyle.left = 0;
120
+ }
121
+
122
+ return newStyle;
117
123
  }
118
124
 
119
125
  if (layout === Layout.RELATIVE) {