@tmagic/editor 1.2.0-beta.9 → 1.2.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.
Files changed (103) hide show
  1. package/dist/style.css +62 -34
  2. package/dist/{tmagic-editor.mjs → tmagic-editor.js} +1641 -1266
  3. package/dist/tmagic-editor.js.map +1 -0
  4. package/dist/{tmagic-editor.umd.js → tmagic-editor.umd.cjs} +1649 -1270
  5. package/dist/tmagic-editor.umd.cjs.map +1 -0
  6. package/package.json +16 -14
  7. package/src/Editor.vue +66 -40
  8. package/src/components/CodeDraftEditor.vue +137 -0
  9. package/src/components/ContentMenu.vue +1 -1
  10. package/src/components/FunctionEditor.vue +190 -0
  11. package/src/components/Icon.vue +1 -1
  12. package/src/{layouts → components}/Layout.vue +54 -15
  13. package/src/components/ScrollBar.vue +1 -1
  14. package/src/components/ScrollViewer.vue +10 -1
  15. package/src/components/ToolButton.vue +1 -1
  16. package/src/fields/Code.vue +1 -1
  17. package/src/fields/CodeLink.vue +1 -1
  18. package/src/fields/CodeSelect.vue +102 -99
  19. package/src/fields/UISelect.vue +3 -3
  20. package/src/index.ts +2 -1
  21. package/src/layouts/AddPageBox.vue +5 -2
  22. package/src/layouts/CodeEditor.vue +2 -3
  23. package/src/layouts/Framework.vue +12 -10
  24. package/src/layouts/NavMenu.vue +11 -8
  25. package/src/layouts/PropsPanel.vue +12 -9
  26. package/src/layouts/Resizer.vue +1 -1
  27. package/src/layouts/sidebar/ComponentListPanel.vue +2 -3
  28. package/src/layouts/sidebar/LayerMenu.vue +9 -7
  29. package/src/layouts/sidebar/LayerPanel.vue +130 -178
  30. package/src/layouts/sidebar/Sidebar.vue +110 -26
  31. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +33 -118
  32. package/src/layouts/sidebar/code-block/CodeBlockList.vue +93 -126
  33. package/src/layouts/workspace/Breadcrumb.vue +6 -7
  34. package/src/layouts/workspace/PageBar.vue +3 -3
  35. package/src/layouts/workspace/PageBarScrollContainer.vue +5 -3
  36. package/src/layouts/workspace/Stage.vue +36 -18
  37. package/src/layouts/workspace/ViewerMenu.vue +16 -15
  38. package/src/layouts/workspace/Workspace.vue +9 -6
  39. package/src/services/BaseService.ts +11 -2
  40. package/src/services/codeBlock.ts +136 -146
  41. package/src/services/componentList.ts +7 -2
  42. package/src/services/editor.ts +161 -85
  43. package/src/services/events.ts +7 -2
  44. package/src/services/history.ts +8 -17
  45. package/src/services/props.ts +8 -3
  46. package/src/services/storage.ts +1 -0
  47. package/src/services/ui.ts +20 -10
  48. package/src/theme/code-block.scss +46 -23
  49. package/src/theme/component-list-panel.scss +8 -5
  50. package/src/type.ts +84 -63
  51. package/src/utils/config.ts +1 -1
  52. package/src/utils/editor.ts +17 -3
  53. package/src/utils/index.ts +2 -1
  54. package/src/utils/logger.ts +1 -1
  55. package/src/utils/operator.ts +12 -12
  56. package/src/utils/props.ts +3 -3
  57. package/src/utils/scroll-viewer.ts +18 -2
  58. package/src/utils/stage.ts +10 -9
  59. package/src/utils/undo-redo.ts +1 -1
  60. package/types/Editor.vue.d.ts +48 -28
  61. package/types/components/CodeDraftEditor.vue.d.ts +55 -0
  62. package/types/components/ContentMenu.vue.d.ts +11 -87
  63. package/types/components/FunctionEditor.vue.d.ts +60 -0
  64. package/types/components/Icon.vue.d.ts +4 -50
  65. package/types/{layouts → components}/Layout.vue.d.ts +12 -1
  66. package/types/components/ScrollBar.vue.d.ts +7 -65
  67. package/types/components/ScrollViewer.vue.d.ts +45 -1
  68. package/types/components/ToolButton.vue.d.ts +12 -78
  69. package/types/fields/Code.vue.d.ts +11 -77
  70. package/types/fields/CodeLink.vue.d.ts +12 -82
  71. package/types/fields/CodeSelect.vue.d.ts +13 -77
  72. package/types/fields/UISelect.vue.d.ts +7 -65
  73. package/types/index.d.ts +1 -0
  74. package/types/layouts/AddPageBox.vue.d.ts +1 -43
  75. package/types/layouts/CodeEditor.vue.d.ts +22 -130
  76. package/types/layouts/NavMenu.vue.d.ts +9 -69
  77. package/types/layouts/sidebar/LayerMenu.vue.d.ts +16 -48
  78. package/types/layouts/sidebar/LayerPanel.vue.d.ts +24 -7
  79. package/types/layouts/sidebar/Sidebar.vue.d.ts +10 -5
  80. package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +24 -6
  81. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +11 -5
  82. package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -43
  83. package/types/layouts/workspace/Stage.vue.d.ts +15 -43
  84. package/types/layouts/workspace/ViewerMenu.vue.d.ts +11 -66
  85. package/types/layouts/workspace/Workspace.vue.d.ts +25 -8
  86. package/types/services/BaseService.d.ts +2 -1
  87. package/types/services/codeBlock.d.ts +56 -47
  88. package/types/services/componentList.d.ts +1 -0
  89. package/types/services/editor.d.ts +10 -11
  90. package/types/services/events.d.ts +1 -0
  91. package/types/services/history.d.ts +5 -15
  92. package/types/services/props.d.ts +3 -2
  93. package/types/services/ui.d.ts +24 -24
  94. package/types/type.d.ts +70 -59
  95. package/types/utils/editor.d.ts +1 -0
  96. package/types/utils/index.d.ts +1 -0
  97. package/types/utils/operator.d.ts +1 -1
  98. package/types/utils/props.d.ts +1 -1
  99. package/types/utils/scroll-viewer.d.ts +5 -0
  100. package/dist/tmagic-editor.mjs.map +0 -1
  101. package/dist/tmagic-editor.umd.js.map +0 -1
  102. package/src/layouts/sidebar/TabPane.vue +0 -118
  103. package/types/layouts/sidebar/TabPane.vue.d.ts +0 -82
@@ -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.
@@ -91,7 +91,7 @@ class Props extends BaseService {
91
91
  * @param type 组件类型
92
92
  * @param value 组件初始值
93
93
  */
94
- public setPropsValue(type: string, value: MNode) {
94
+ public async setPropsValue(type: string, value: MNode) {
95
95
  this.state.propsValueMap[type] = value;
96
96
  }
97
97
 
@@ -171,10 +171,15 @@ class Props extends BaseService {
171
171
  };
172
172
  }
173
173
 
174
- public destroy() {
174
+ public resetState() {
175
175
  this.state.propsConfigMap = {};
176
176
  this.state.propsValueMap = {};
177
+ }
178
+
179
+ public destroy() {
180
+ this.resetState();
177
181
  this.removeAllListeners();
182
+ this.removeAllPlugins();
178
183
  }
179
184
 
180
185
  /**
@@ -109,6 +109,7 @@ export class WebStorage extends BaseService {
109
109
 
110
110
  public destroy() {
111
111
  this.removeAllListeners();
112
+ this.removeAllPlugins();
112
113
  }
113
114
 
114
115
  private getValueAndProtocol(value: string | null) {
@@ -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() {
@@ -97,8 +95,20 @@ class Ui extends BaseService {
97
95
  return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
98
96
  }
99
97
 
98
+ public resetState() {
99
+ this.set('showSrc', false);
100
+ this.set('uiSelectMode', false);
101
+ this.set('zoom', 1);
102
+ this.set('stageContainerRect', {
103
+ width: 0,
104
+ height: 0,
105
+ });
106
+ }
107
+
100
108
  public destroy() {
109
+ this.resetState();
101
110
  this.removeAllListeners();
111
+ this.removeAllPlugins();
102
112
  }
103
113
 
104
114
  private async setStageRect(value: StageRect) {
@@ -1,8 +1,13 @@
1
1
  .m-editor-code-block-list {
2
+ height: 100%;
2
3
  margin-top: 5px;
4
+
3
5
  .el-tree-node__content {
4
6
  height: auto;
5
7
  }
8
+ .el-tree-node__label {
9
+ width: 100%;
10
+ }
6
11
  .code-header-wrapper {
7
12
  display: flex;
8
13
  align-items: center;
@@ -32,9 +37,7 @@
32
37
  display: flex;
33
38
  align-items: center;
34
39
  .right-tool {
35
- position: absolute;
36
- right: 15px;
37
- padding-left: 5px;
40
+ width: fit-content !important;
38
41
  display: flex;
39
42
  align-items: center;
40
43
  .edit-icon {
@@ -47,7 +50,8 @@
47
50
  white-space: nowrap;
48
51
  text-overflow: ellipsis;
49
52
  padding: 10px 15px;
50
- margin-right: 60px;
53
+ width: 0 !important;
54
+ flex: 1;
51
55
  }
52
56
  }
53
57
  .code-comp-map-wrapper {
@@ -74,30 +78,34 @@
74
78
 
75
79
  .m-fields-code-select {
76
80
  width: 100%;
77
- .el-card__body {
78
- padding: 5px;
79
- }
80
- .tool-bar {
81
- display: flex;
82
- align-items: center;
83
- justify-content: end;
84
- height: 20px;
85
- .tool-item {
86
- display: flex;
87
- align-items: center;
88
- }
81
+ .edit-icon {
82
+ cursor: pointer;
83
+ margin-right: 5px;
89
84
  }
90
85
  }
86
+
87
+ .el-dialog.is-fullscreen.code-editor-dialog {
88
+ overflow: hidden;
89
+ }
90
+
91
91
  .code-editor-dialog {
92
- .el-dialog__body {
92
+ .tmagic-design-card {
93
+ .t-card__header {
94
+ display: block;
95
+ }
96
+ }
97
+
98
+ .el-dialog__body,
99
+ .t-dialog__body {
93
100
  height: 90%;
94
101
  padding-top: 10px;
95
102
  }
96
- .el-card {
103
+ .tmagic-design-card {
97
104
  height: 100%;
98
105
  background: #fff;
99
- .el-card__body {
100
- height: calc(100% - 80px);
106
+ .el-card__body,
107
+ .t-card__body {
108
+ height: 100%;
101
109
  background: #fff;
102
110
  }
103
111
  }
@@ -109,6 +117,9 @@
109
117
  .side-tree {
110
118
  height: 100%;
111
119
  overflow: auto;
120
+ .el-tree-node__label {
121
+ width: 100%;
122
+ }
112
123
 
113
124
  .list-container {
114
125
  width: 100%;
@@ -134,6 +145,7 @@
134
145
  display: flex;
135
146
  align-items: center;
136
147
  font-size: 16px;
148
+ margin-bottom: 10px;
137
149
  .code-name-label {
138
150
  margin-right: 10px;
139
151
  }
@@ -166,18 +178,29 @@
166
178
 
167
179
  .m-editor-wrapper {
168
180
  height: 100%;
181
+ &.fullScreen {
182
+ height: 100%;
183
+ width: 100%;
184
+ position: fixed;
185
+ top: 0;
186
+ left: 0;
187
+ z-index: 100;
188
+ }
169
189
  .m-editor-container {
170
- height: calc(100% - 70px);
190
+ height: calc(100% - 45px);
171
191
  }
172
192
  .m-editor-content-bottom {
173
- height: 40px;
193
+ height: 45px;
174
194
  width: 100%;
175
195
  display: flex;
176
196
  justify-content: end;
177
197
  background: #fff;
198
+ position: absolute;
199
+ right: 20px;
200
+ bottom: 0;
178
201
  > button {
179
202
  height: 30px;
180
- margin-top: 15px;
203
+ margin-top: 5px;
181
204
  }
182
205
  }
183
206
  }
@@ -1,4 +1,4 @@
1
- .ui-component-panel {
1
+ .ui-component-panel.tmagic-design-collapse {
2
2
  height: 100%;
3
3
  border-top: 0 !important;
4
4
  margin-top: 48px;
@@ -19,14 +19,15 @@
19
19
  }
20
20
  }
21
21
 
22
- .el-collapse-item {
22
+ .tmagic-design-collapse-item {
23
23
  > div:first-of-type {
24
24
  border-bottom: 1px solid $--border-color;
25
25
  margin-bottom: 10px;
26
26
  }
27
27
  }
28
28
 
29
- .el-collapse-item__header {
29
+ .el-collapse-item__header,
30
+ .t-collapse-panel__header {
30
31
  background: $--sidebar-content-background-color;
31
32
  color: $--font-color;
32
33
  height: 25px;
@@ -40,11 +41,13 @@
40
41
  }
41
42
  }
42
43
 
43
- .el-collapse-item__wrap {
44
+ .el-collapse-item__wrap,
45
+ .t-collapse-panel__body {
44
46
  background: $--sidebar-content-background-color;
45
47
  border-bottom: 0;
46
48
 
47
- .el-collapse-item__content {
49
+ .el-collapse-item__content,
50
+ .t-collapse-panel__content {
48
51
  padding: 10px;
49
52
  display: flex;
50
53
  flex-wrap: wrap;
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.
@@ -19,9 +19,14 @@
19
19
  import type { Component } from 'vue';
20
20
 
21
21
  import type { FormConfig } from '@tmagic/form';
22
- import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
22
+ import type { CodeBlockContent, CodeBlockDSL, Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
23
23
  import type StageCore from '@tmagic/stage';
24
- import type { ContainerHighlightType, MoveableOptions } from '@tmagic/stage';
24
+ import type {
25
+ ContainerHighlightType,
26
+ CustomizeMoveableOptionsCallbackConfig,
27
+ MoveableOptions,
28
+ UpdateDragEl,
29
+ } from '@tmagic/stage';
25
30
 
26
31
  import type { CodeBlockService } from './services/codeBlock';
27
32
  import type { ComponentListService } from './services/componentList';
@@ -31,6 +36,7 @@ import type { HistoryService } from './services/history';
31
36
  import type { PropsService } from './services/props';
32
37
  import type { StorageService } from './services/storage';
33
38
  import type { UiService } from './services/ui';
39
+ import type { UndoRedo } from './utils/undo-redo';
34
40
 
35
41
  export type BeforeAdd = (config: MNode, parent: MContainer) => Promise<MNode> | MNode;
36
42
  export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig;
@@ -56,11 +62,12 @@ export interface StageOptions {
56
62
  containerHighlightClassName: string;
57
63
  containerHighlightDuration: number;
58
64
  containerHighlightType: ContainerHighlightType;
59
- render: () => HTMLDivElement;
60
- moveableOptions: MoveableOptions | ((core?: StageCore) => MoveableOptions);
65
+ disabledDragStart?: boolean;
66
+ render: (stage: StageCore) => HTMLDivElement | Promise<HTMLDivElement>;
67
+ moveableOptions: MoveableOptions | ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions);
61
68
  canSelect: (el: HTMLElement) => boolean | Promise<boolean>;
62
69
  isContainer: (el: HTMLElement) => boolean | Promise<boolean>;
63
- updateDragEl: (el: HTMLDivElement) => void;
70
+ updateDragEl: UpdateDragEl;
64
71
  }
65
72
 
66
73
  export interface StoreState {
@@ -75,6 +82,8 @@ export interface StoreState {
75
82
  pageLength: number;
76
83
  }
77
84
 
85
+ export type StoreStateKey = keyof StoreState;
86
+
78
87
  export interface PropsState {
79
88
  propsConfigMap: Record<string, FormConfig>;
80
89
  propsValueMap: Record<string, MNode>;
@@ -131,9 +140,9 @@ export interface UiState {
131
140
  }
132
141
 
133
142
  export interface EditorNodeInfo {
134
- node?: MNode;
135
- parent?: MContainer;
136
- page?: MPage;
143
+ node: MNode | null;
144
+ parent: MContainer | null;
145
+ page: MPage | null;
137
146
  }
138
147
 
139
148
  export interface AddMNode {
@@ -164,18 +173,17 @@ export interface MenuButton {
164
173
  * 按钮类型
165
174
  * button: 只有文字不带边框的按钮
166
175
  * text: 纯文本
176
+ * divider: 分割线
167
177
  * dropdown: 下拉菜单
168
- * divider: 分隔线
169
- * zoom: 放大缩小
170
178
  */
171
- type: 'button' | 'dropdown' | 'text' | 'divider' | 'zoom';
179
+ type: 'button' | 'text' | 'divider' | 'dropdown';
172
180
  /** 当type为divider时有效,分割线方向, 默认vertical */
173
181
  direction?: 'horizontal' | 'vertical';
174
182
  /** 展示的文案 */
175
183
  text?: string;
176
184
  /** 鼠标悬浮是显示的气泡中的文案 */
177
185
  tooltip?: string;
178
- /** element-plus icon class */
186
+ /** Vue组件或url */
179
187
  icon?: string | Component<{}, {}, any>;
180
188
  /** 是否置灰,默认为false */
181
189
  disabled?: boolean | ((data?: Services) => boolean);
@@ -183,8 +191,8 @@ export interface MenuButton {
183
191
  display?: boolean | ((data?: Services) => boolean);
184
192
  /** type为button/dropdown时点击运行的方法 */
185
193
  handler?: (data: Services, event: MouseEvent) => Promise<any> | any;
186
- /** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
187
194
  className?: string;
195
+ /** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
188
196
  items?: MenuButton[];
189
197
  }
190
198
 
@@ -200,6 +208,7 @@ export interface MenuComponent {
200
208
  /** 是否显示,默认为true */
201
209
  className?: string;
202
210
  display?: boolean | ((data?: Services) => Promise<boolean> | boolean);
211
+ [key: string]: any;
203
212
  }
204
213
 
205
214
  /**
@@ -207,8 +216,13 @@ export interface MenuComponent {
207
216
  * 'delete': 删除按钮
208
217
  * 'undo': 撤销按钮
209
218
  * 'redo': 恢复按钮
219
+ * 'zoom': 'zoom-in', 'zoom-out', 'scale-to-original', 'scale-to-fit' 的集合
210
220
  * 'zoom-in': 放大按钮
211
221
  * 'zoom-out': 缩小按钮
222
+ * 'guides': 显示隐藏参考线
223
+ * 'rule': 显示隐藏标尺
224
+ * 'scale-to-original': 缩放到实际大小
225
+ * 'scale-to-fit': 缩放以适应
212
226
  */
213
227
  export type MenuItem =
214
228
  | '/'
@@ -220,6 +234,8 @@ export type MenuItem =
220
234
  | 'zoom-out'
221
235
  | 'guides'
222
236
  | 'rule'
237
+ | 'scale-to-original'
238
+ | 'scale-to-fit'
223
239
  | MenuButton
224
240
  | MenuComponent
225
241
  | string;
@@ -237,13 +253,14 @@ export interface MenuBarData {
237
253
  export interface SideComponent extends MenuComponent {
238
254
  /** 显示文案 */
239
255
  text: string;
240
- /** element-plus icon class */
256
+ /** vue组件或url */
241
257
  icon: Component<{}, {}, any>;
242
258
  }
243
259
 
244
260
  /**
245
261
  * component-list: 组件列表
246
262
  * layer: 已选组件树
263
+ * code-block: 代码块
247
264
  */
248
265
  export type SideItem = 'component-list' | 'layer' | 'code-block' | SideComponent;
249
266
 
@@ -262,8 +279,9 @@ export interface ComponentItem {
262
279
  text: string;
263
280
  /** 组件类型 */
264
281
  type: string;
265
- /** element-plus icon class */
266
- icon?: string | Component;
282
+ /** Vue组件或url */
283
+ icon?: string | Component<{}, {}, any>;
284
+ /** 新增组件时需要透传到组价节点上的数据 */
267
285
  data?: {
268
286
  [key: string]: any;
269
287
  };
@@ -308,72 +326,60 @@ export interface ScrollViewerEvent {
308
326
  scrollWidth: number;
309
327
  }
310
328
 
311
- export interface CodeBlockDSL {
312
- [id: string]: CodeBlockContent;
313
- }
314
-
315
- export interface CodeBlockContent {
316
- /** 代码块名称 */
317
- name: string;
318
- /** 代码块内容 */
319
- content: string;
320
- /** 代码块与组件的绑定关系 */
321
- comps?: CodeRelation;
322
- /** 扩展字段 */
323
- [propName: string]: any;
324
- }
325
-
326
329
  export type CodeState = {
327
330
  /** 是否展示代码块编辑区 */
328
331
  isShowCodeEditor: boolean;
329
332
  /** 代码块DSL数据源 */
330
333
  codeDsl: CodeBlockDSL | null;
331
334
  /** 当前选中的代码块id */
332
- id: string;
335
+ id: Id;
333
336
  /** 代码块是否可编辑 */
334
337
  editable: boolean;
335
- /** 代码编辑面板的展示模式 */
336
- mode: CodeEditorMode;
337
338
  /** list模式下左侧展示的代码列表 */
338
339
  combineIds: string[];
339
340
  /** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
340
- undeletableList: string[];
341
+ undeletableList: Id[];
342
+ /** 代码块和组件的绑定关系 */
343
+ relations: CodeRelation;
341
344
  };
342
345
 
343
- export type CodeRelation = {
344
- /** 组件id:['created'] */
345
- [compId: string | number]: string[];
346
+ export type HookData = {
347
+ /** 代码块id */
348
+ codeId: Id;
349
+ /** 参数 */
350
+ params?: object;
346
351
  };
347
352
 
348
- export enum CodeEditorMode {
349
- /** 左侧菜单,右侧代码 */
350
- LIST = 'list',
351
- /** 全屏代码 */
352
- EDITOR = 'editor',
353
- }
353
+ export type CodeRelation = {
354
+ [codeId: Id]: {
355
+ /** 组件id:['created'] */
356
+ [compId: Id]: string[];
357
+ };
358
+ };
354
359
 
355
- export interface CodeDslList {
360
+ export interface CodeDslItem {
356
361
  /** 代码块id */
357
- id: string;
362
+ id: Id;
358
363
  /** 代码块名称 */
359
364
  name: string;
360
365
  /** 代码块函数内容 */
361
366
  codeBlockContent?: CodeBlockContent;
362
367
  /** 是否展示代码绑定关系 */
363
368
  showRelation?: boolean;
369
+ /** 代码块对应绑定的组件信息 */
370
+ combineInfo?: CombineInfo[];
364
371
  }
365
372
 
366
- export interface ListState {
367
- /** 代码块列表 */
368
- codeList: CodeDslList[];
373
+ export interface CombineInfo {
374
+ /** 组件id */
375
+ compId: Id;
376
+ /** 组件名称 */
377
+ compName: string;
369
378
  }
370
379
 
371
- export interface ListRelationState extends ListState {
372
- /** 与代码块绑定的组件id信息 */
373
- bindComps: {
374
- /** 代码块id : 组件信息 */
375
- [id: string]: MNode[];
376
- };
380
+ export interface ListState {
381
+ /** 代码块列表 */
382
+ codeList: CodeDslItem[];
377
383
  }
378
384
 
379
385
  export enum CodeDeleteErrorType {
@@ -383,11 +389,26 @@ export enum CodeDeleteErrorType {
383
389
  BIND = 'bind',
384
390
  }
385
391
 
386
- export enum CodeSelectOp {
387
- /** 增加 */
388
- ADD = 'add',
389
- /** 删除 */
390
- DELETE = 'delete',
391
- /** 单选修改 */
392
- CHANGE = 'change',
392
+ // 代码块草稿localStorage key
393
+ export const CODE_DRAFT_STORAGE_KEY = 'magicCodeDraft';
394
+
395
+ export interface CodeParamStatement {
396
+ /** 参数名称 */
397
+ name: string;
398
+ /** 参数类型 */
399
+ type?: string;
400
+ [key: string]: any;
401
+ }
402
+
403
+ export interface StepValue {
404
+ data: MPage;
405
+ modifiedNodeIds: Map<Id, Id>;
406
+ nodeId: Id;
407
+ }
408
+
409
+ export interface HistoryState {
410
+ pageId?: Id;
411
+ pageSteps: Record<Id, UndoRedo<StepValue>>;
412
+ canRedo: boolean;
413
+ canUndo: boolean;
393
414
  }
@@ -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.
@@ -16,13 +16,14 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
+ import serialize from 'serialize-javascript';
20
+
19
21
  import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
20
22
  import { NodeType } from '@tmagic/schema';
21
23
  import type StageCore from '@tmagic/stage';
22
24
  import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
23
25
 
24
26
  import { Layout } from '../type';
25
-
26
27
  export const COPY_STORAGE_KEY = '$MagicEditorCopyData';
27
28
 
28
29
  /**
@@ -109,10 +110,16 @@ const getMiddleTop = (node: MNode, parentNode: MNode, stage: StageCore | null) =
109
110
 
110
111
  export const getInitPositionStyle = (style: Record<string, any> = {}, layout: Layout) => {
111
112
  if (layout === Layout.ABSOLUTE) {
112
- return {
113
+ const newStyle: Record<string, any> = {
113
114
  ...style,
114
115
  position: 'absolute',
115
116
  };
117
+
118
+ if (typeof newStyle.left === 'undefined' && typeof newStyle.right === 'undefined') {
119
+ newStyle.left = 0;
120
+ }
121
+
122
+ return newStyle;
116
123
  }
117
124
 
118
125
  if (layout === Layout.RELATIVE) {
@@ -237,3 +244,10 @@ export const fixNodePosition = (config: MNode, parent: MContainer, stage: StageC
237
244
  left: fixNodeLeft(config, parent, stage?.renderer.contentWindow?.document),
238
245
  };
239
246
  };
247
+
248
+ // 序列化配置
249
+ export const serializeConfig = (config: any) =>
250
+ serialize(config, {
251
+ space: 2,
252
+ unsafe: true,
253
+ }).replace(/"(\w+)":\s/g, '$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.
@@ -21,3 +21,4 @@ export * from './props';
21
21
  export * from './logger';
22
22
  export * from './editor';
23
23
  export * from './stage';
24
+ export * from './operator';
@@ -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.