@tmagic/editor 1.2.0 → 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 (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
@@ -78,7 +78,7 @@
78
78
  </TMagicScrollbar>
79
79
 
80
80
  <!-- 代码块编辑区 -->
81
- <code-block-editor v-if="isShowCodeBlockEditor">
81
+ <code-block-editor v-if="isShowCodeBlockEditor" :paramsColConfig="paramsColConfig">
82
82
  <template #code-block-edit-panel-header="{ id }">
83
83
  <slot name="code-block-edit-panel-header" :id="id"></slot>
84
84
  </template>
@@ -92,17 +92,18 @@ import { Close, Edit, Link, View } from '@element-plus/icons-vue';
92
92
  import { cloneDeep, forIn, isEmpty } from 'lodash-es';
93
93
 
94
94
  import { TMagicButton, TMagicInput, tMagicMessage, TMagicScrollbar, TMagicTooltip, TMagicTree } from '@tmagic/design';
95
+ import { ColumnConfig } from '@tmagic/form';
95
96
  import { CodeBlockContent, Id } from '@tmagic/schema';
96
- import StageCore from '@tmagic/stage';
97
97
 
98
98
  import Icon from '../../../components/Icon.vue';
99
99
  import type { CodeRelation, Services } from '../../../type';
100
- import { CodeDeleteErrorType, CodeDslItem, CodeEditorMode, ListState } from '../../../type';
100
+ import { CodeDeleteErrorType, CodeDslItem, ListState } from '../../../type';
101
101
 
102
102
  import codeBlockEditor from './CodeBlockEditor.vue';
103
103
 
104
104
  const props = defineProps<{
105
105
  customError?: (id: Id, errorType: CodeDeleteErrorType) => any;
106
+ paramsColConfig?: ColumnConfig;
106
107
  }>();
107
108
 
108
109
  const services = inject<Services>('services');
@@ -169,7 +170,6 @@ const createCodeBlock = async () => {
169
170
  content: `({app, params}) => {\n // place your code here\n}`,
170
171
  params: [],
171
172
  };
172
- await codeBlockService.setMode(CodeEditorMode.EDITOR);
173
173
  const id = await codeBlockService.getUniqueId();
174
174
  await codeBlockService.setCodeDslById(id, codeConfig);
175
175
  codeBlockService.setCodeEditorContent(true, id);
@@ -177,7 +177,6 @@ const createCodeBlock = async () => {
177
177
 
178
178
  // 编辑代码块
179
179
  const editCode = async (key: Id) => {
180
- await services?.codeBlockService.setMode(CodeEditorMode.EDITOR);
181
180
  services?.codeBlockService.setCodeEditorContent(true, key);
182
181
  };
183
182
 
@@ -228,7 +227,7 @@ const getCompName = (compId: Id): string => {
228
227
 
229
228
  // 选中组件
230
229
  const selectComp = (compId: Id) => {
231
- const stage = services?.editorService.get<StageCore | null>('stage');
230
+ const stage = services?.editorService.get('stage');
232
231
  services?.editorService.select(compId);
233
232
  stage?.select(compId);
234
233
  };
@@ -11,8 +11,7 @@
11
11
  import { computed, inject } from 'vue';
12
12
 
13
13
  import { TMagicButton } from '@tmagic/design';
14
- import type { MApp, MNode } from '@tmagic/schema';
15
- import type StageCore from '@tmagic/stage';
14
+ import type { MNode } from '@tmagic/schema';
16
15
  import { getNodePath } from '@tmagic/utils';
17
16
 
18
17
  import type { Services } from '../../type';
@@ -20,13 +19,13 @@ import type { Services } from '../../type';
20
19
  const services = inject<Services>('services');
21
20
  const editorService = services?.editorService;
22
21
 
23
- const node = computed(() => editorService?.get<MNode>('node'));
24
- const nodes = computed(() => editorService?.get<MNode[]>('nodes') || []);
25
- const root = computed(() => editorService?.get<MApp>('root'));
22
+ const node = computed(() => editorService?.get('node'));
23
+ const nodes = computed(() => editorService?.get('nodes') || []);
24
+ const root = computed(() => editorService?.get('root'));
26
25
  const path = computed(() => getNodePath(node.value?.id || '', root.value?.items || []));
27
26
 
28
27
  const select = async (node: MNode) => {
29
28
  await editorService?.select(node);
30
- editorService?.get<StageCore>('stage')?.select(node.id);
29
+ editorService?.get('stage')?.select(node.id);
31
30
  };
32
31
  </script>
@@ -51,7 +51,7 @@ import { computed, inject } from 'vue';
51
51
  import { CaretBottom, Delete, DocumentCopy } from '@element-plus/icons-vue';
52
52
 
53
53
  import { TMagicIcon, TMagicPopover, TMagicTooltip } from '@tmagic/design';
54
- import type { MApp, MPage } from '@tmagic/schema';
54
+ import type { MPage } from '@tmagic/schema';
55
55
 
56
56
  import ToolButton from '../../components/ToolButton.vue';
57
57
  import type { Services } from '../../type';
@@ -61,7 +61,7 @@ import PageBarScrollContainer from './PageBarScrollContainer.vue';
61
61
  const services = inject<Services>('services');
62
62
  const editorService = services?.editorService;
63
63
 
64
- const root = computed(() => editorService?.get<MApp>('root'));
64
+ const root = computed(() => editorService?.get('root'));
65
65
 
66
66
  const page = computed(() => editorService?.get('page'));
67
67
 
@@ -100,7 +100,7 @@ const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
100
100
  itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
101
101
  };
102
102
 
103
- const pageLength = computed(() => editorService?.get<number>('pageLength'));
103
+ const pageLength = computed(() => editorService?.get('pageLength'));
104
104
 
105
105
  watch(pageLength, (length = 0, preLength = 0) => {
106
106
  setTimeout(() => {
@@ -115,9 +115,11 @@ watch(pageLength, (length = 0, preLength = 0) => {
115
115
 
116
116
  const addPage = () => {
117
117
  if (!editorService) return;
118
+ const root = toRaw(editorService.get('root'));
119
+ if (!root) throw new Error('root 不能为空');
118
120
  const pageConfig = {
119
121
  type: NodeType.PAGE,
120
- name: generatePageNameByApp(toRaw(editorService.get('root'))),
122
+ name: generatePageNameByApp(root),
121
123
  };
122
124
  editorService.add(pageConfig);
123
125
  };
@@ -30,11 +30,11 @@
30
30
  import { computed, inject, markRaw, nextTick, onMounted, onUnmounted, ref, toRaw, watch, watchEffect } from 'vue';
31
31
  import { cloneDeep } from 'lodash-es';
32
32
 
33
- import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
33
+ import type { MContainer } from '@tmagic/schema';
34
34
  import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stage';
35
35
 
36
36
  import ScrollViewer from '../../components/ScrollViewer.vue';
37
- import { Layout, MenuButton, MenuComponent, Services, StageOptions, StageRect } from '../../type';
37
+ import { Layout, MenuButton, MenuComponent, Services, StageOptions } from '../../type';
38
38
  import { useStage } from '../../utils/stage';
39
39
 
40
40
  import ViewerMenu from './ViewerMenu.vue';
@@ -53,13 +53,14 @@ const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
53
53
  const stageContainer = ref<HTMLDivElement>();
54
54
  const menu = ref<InstanceType<typeof ViewerMenu>>();
55
55
 
56
- const isMultiSelect = computed(() => services?.editorService.get('nodes')?.length > 1);
57
- const stageRect = computed(() => services?.uiService.get<StageRect>('stageRect'));
58
- const stageContainerRect = computed(() => services?.uiService.get<StageRect>('stageContainerRect'));
59
- const root = computed(() => services?.editorService.get<MApp>('root'));
60
- const page = computed(() => services?.editorService.get<MPage>('page'));
61
- const zoom = computed(() => services?.uiService.get<number>('zoom') || 1);
62
- const node = computed(() => services?.editorService.get<MNode>('node'));
56
+ const nodes = computed(() => services?.editorService.get('nodes') || []);
57
+ const isMultiSelect = computed(() => nodes.value.length > 1);
58
+ const stageRect = computed(() => services?.uiService.get('stageRect'));
59
+ const stageContainerRect = computed(() => services?.uiService.get('stageContainerRect'));
60
+ const root = computed(() => services?.editorService.get('root'));
61
+ const page = computed(() => services?.editorService.get('page'));
62
+ const zoom = computed(() => services?.uiService.get('zoom') || 1);
63
+ const node = computed(() => services?.editorService.get('node'));
63
64
 
64
65
  watchEffect(() => {
65
66
  if (stage || !page.value) return;
@@ -142,7 +143,7 @@ const dropHandler = async (e: DragEvent) => {
142
143
  const doc = stage?.renderer.contentWindow?.document;
143
144
  const parentEl: HTMLElement | null | undefined = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
144
145
 
145
- let parent: MContainer | undefined = page.value;
146
+ let parent: MContainer | undefined | null = page.value;
146
147
  if (parentEl) {
147
148
  parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer;
148
149
  }
@@ -6,8 +6,7 @@
6
6
  import { computed, inject, markRaw, ref, watch } from 'vue';
7
7
  import { Bottom, CopyDocument, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
8
8
 
9
- import { MNode, NodeType } from '@tmagic/schema';
10
- import StageCore from '@tmagic/stage';
9
+ import { NodeType } from '@tmagic/schema';
11
10
  import { isPage } from '@tmagic/utils';
12
11
 
13
12
  import ContentMenu from '../../components/ContentMenu.vue';
@@ -26,10 +25,10 @@ const menu = ref<InstanceType<typeof ContentMenu>>();
26
25
  const canPaste = ref(false);
27
26
  const canCenter = ref(false);
28
27
 
29
- const node = computed(() => editorService?.get<MNode>('node'));
30
- const nodes = computed(() => editorService?.get<MNode[]>('nodes'));
28
+ const node = computed(() => editorService?.get('node'));
29
+ const nodes = computed(() => editorService?.get('nodes'));
31
30
  const parent = computed(() => editorService?.get('parent'));
32
- const stage = computed(() => editorService?.get<StageCore>('stage'));
31
+ const stage = computed(() => editorService?.get('stage'));
33
32
 
34
33
  const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
35
34
  {
@@ -129,7 +128,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
129
128
  type: 'button',
130
129
  text: '清空参考线',
131
130
  handler: () => {
132
- editorService?.get<StageCore>('stage').clearGuides();
131
+ editorService?.get('stage')?.clearGuides();
133
132
  },
134
133
  },
135
134
  ...props.stageContentMenu,
@@ -19,7 +19,6 @@
19
19
  import { computed, inject, onMounted, onUnmounted, ref } from 'vue';
20
20
  import KeyController from 'keycon';
21
21
 
22
- import type { MNode, MPage } from '@tmagic/schema';
23
22
  import { isPage } from '@tmagic/utils';
24
23
 
25
24
  import type { MenuButton, MenuComponent, Services } from '../../type';
@@ -34,8 +33,8 @@ defineProps<{
34
33
 
35
34
  const services = inject<Services>('services');
36
35
  const workspace = ref<HTMLDivElement>();
37
- const nodes = computed(() => services?.editorService.get<MNode[]>('nodes'));
38
- const page = computed(() => services?.editorService.get<MPage>('page'));
36
+ const nodes = computed(() => services?.editorService.get('nodes'));
37
+ const page = computed(() => services?.editorService.get('page'));
39
38
 
40
39
  const mouseenterHandler = () => {
41
40
  workspace.value?.focus();
@@ -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.
@@ -19,11 +19,11 @@
19
19
  import { reactive } from 'vue';
20
20
  import { cloneDeep, forIn, isEmpty, keys, omit, pick } from 'lodash-es';
21
21
 
22
- import { CodeBlockContent, CodeBlockDSL, HookType, Id, MApp, MNode } from '@tmagic/schema';
22
+ import { CodeBlockContent, CodeBlockDSL, HookType, Id, MNode } from '@tmagic/schema';
23
23
 
24
24
  import editorService from '../services/editor';
25
25
  import type { CodeRelation, CodeState, HookData } from '../type';
26
- import { CODE_DRAFT_STORAGE_KEY, CodeEditorMode } from '../type';
26
+ import { CODE_DRAFT_STORAGE_KEY } from '../type';
27
27
  import { info } from '../utils/logger';
28
28
 
29
29
  import BaseService from './BaseService';
@@ -34,7 +34,6 @@ class CodeBlock extends BaseService {
34
34
  codeDsl: null,
35
35
  id: '',
36
36
  editable: true,
37
- mode: CodeEditorMode.EDITOR,
38
37
  combineIds: [],
39
38
  undeletableList: [],
40
39
  relations: {},
@@ -50,7 +49,6 @@ class CodeBlock extends BaseService {
50
49
  'setCodeDslById',
51
50
  'setCodeEditorShowStatus',
52
51
  'setEditStatus',
53
- 'setMode',
54
52
  'setCombineIds',
55
53
  'setUndeleteableList',
56
54
  'deleteCodeDslByIds',
@@ -214,23 +212,6 @@ class CodeBlock extends BaseService {
214
212
  return this.state.id;
215
213
  }
216
214
 
217
- /**
218
- * 获取当前模式
219
- * @returns {CodeEditorMode}
220
- */
221
- public getMode(): CodeEditorMode {
222
- return this.state.mode;
223
- }
224
-
225
- /**
226
- * 设置当前模式
227
- * @param {CodeEditorMode} mode 模式
228
- * @returns {void}
229
- */
230
- public async setMode(mode: CodeEditorMode): Promise<void> {
231
- this.state.mode = mode;
232
- }
233
-
234
215
  /**
235
216
  * 设置当前选中组件已关联绑定的代码块id数组
236
217
  * @param {string[]} ids 代码块id数组
@@ -253,7 +234,7 @@ class CodeBlock extends BaseService {
253
234
  * @returns {CodeRelation | null}
254
235
  */
255
236
  public refreshCombineInfo(): CodeRelation | null {
256
- const root = editorService.get<MApp | null>('root');
237
+ const root = editorService.get('root');
257
238
  if (!root) return null;
258
239
  const relations = {};
259
240
  this.recurseMNode(root, relations);
@@ -349,7 +330,6 @@ class CodeBlock extends BaseService {
349
330
  this.state.codeDsl = null;
350
331
  this.state.id = '';
351
332
  this.state.editable = true;
352
- this.state.mode = CodeEditorMode.EDITOR;
353
333
  this.state.combineIds = [];
354
334
  this.state.undeletableList = [];
355
335
  }
@@ -386,6 +366,7 @@ class CodeBlock extends BaseService {
386
366
  */
387
367
  private recurseMNode(node: MNode, relations: CodeRelation): void {
388
368
  forIn(node, (value, key) => {
369
+ let unConfirmedValue: MNode = { id: node.id };
389
370
  if (value?.hookType === HookType.CODE && !isEmpty(value.hookData)) {
390
371
  value.hookData.forEach((relationItem: HookData) => {
391
372
  // continue
@@ -399,6 +380,16 @@ class CodeBlock extends BaseService {
399
380
  }
400
381
  codeItem[node.id].push(key);
401
382
  });
383
+ // continue
384
+ return;
385
+ }
386
+ if (typeof value === 'object') {
387
+ // 检查value内部是否有嵌套
388
+ unConfirmedValue = {
389
+ ...unConfirmedValue,
390
+ ...value,
391
+ };
392
+ this.recurseMNode(unConfirmedValue, relations);
402
393
  }
403
394
  });
404
395
  if (!isEmpty(node.items)) {
@@ -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.