@tmagic/editor 1.1.0-beta.4 → 1.1.0-beta.7

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 (100) hide show
  1. package/dist/{tmagic-editor.es.js → tmagic-editor.mjs} +1361 -1144
  2. package/dist/tmagic-editor.mjs.map +1 -0
  3. package/dist/tmagic-editor.umd.js +1375 -1158
  4. package/dist/tmagic-editor.umd.js.map +1 -1
  5. package/package.json +21 -19
  6. package/src/Editor.vue +14 -12
  7. package/src/components/ContentMenu.vue +87 -99
  8. package/src/components/ScrollViewer.vue +1 -1
  9. package/src/components/ToolButton.vue +150 -167
  10. package/src/fields/UISelect.vue +49 -70
  11. package/src/index.ts +2 -1
  12. package/src/layouts/AddPageBox.vue +2 -2
  13. package/src/layouts/Framework.vue +1 -1
  14. package/src/layouts/NavMenu.vue +2 -2
  15. package/src/layouts/PropsPanel.vue +1 -1
  16. package/src/layouts/Resizer.vue +1 -1
  17. package/src/layouts/sidebar/ComponentListPanel.vue +2 -2
  18. package/src/layouts/sidebar/LayerMenu.vue +2 -2
  19. package/src/layouts/sidebar/LayerPanel.vue +13 -4
  20. package/src/layouts/sidebar/Sidebar.vue +1 -1
  21. package/src/layouts/sidebar/TabPane.vue +2 -2
  22. package/src/layouts/workspace/PageBar.vue +63 -192
  23. package/src/layouts/workspace/PageBarScrollContainer.vue +111 -0
  24. package/src/layouts/workspace/Stage.vue +195 -222
  25. package/src/layouts/workspace/ViewerMenu.vue +142 -146
  26. package/src/layouts/workspace/Workspace.vue +11 -11
  27. package/src/services/BaseService.ts +1 -1
  28. package/src/services/componentList.ts +3 -3
  29. package/src/services/editor.ts +117 -135
  30. package/src/services/events.ts +1 -1
  31. package/src/services/history.ts +1 -1
  32. package/src/services/props.ts +62 -10
  33. package/src/services/storage.ts +133 -0
  34. package/src/services/ui.ts +2 -2
  35. package/src/type.ts +22 -6
  36. package/src/utils/config.ts +1 -1
  37. package/src/utils/editor.ts +1 -1
  38. package/src/utils/operator.ts +210 -0
  39. package/src/utils/props.ts +2 -24
  40. package/src/utils/scroll-viewer.ts +1 -1
  41. package/tsconfig.build.json +13 -0
  42. package/{dist/types/src → types}/Editor.vue.d.ts +7 -8
  43. package/types/components/ContentMenu.vue.d.ts +116 -0
  44. package/types/components/Icon.vue.d.ts +13 -0
  45. package/types/components/ScrollViewer.vue.d.ts +22 -0
  46. package/types/components/ToolButton.vue.d.ts +109 -0
  47. package/types/fields/Code.vue.d.ts +23 -0
  48. package/{dist/types/src → types}/fields/CodeLink.vue.d.ts +4 -6
  49. package/types/fields/UISelect.vue.d.ts +83 -0
  50. package/{dist/types/src → types}/index.d.ts +4 -1
  51. package/types/layouts/AddPageBox.vue.d.ts +4 -0
  52. package/{dist/types/src → types}/layouts/CodeEditor.vue.d.ts +11 -13
  53. package/types/layouts/Framework.vue.d.ts +22 -0
  54. package/types/layouts/NavMenu.vue.d.ts +25 -0
  55. package/types/layouts/PropsPanel.vue.d.ts +245 -0
  56. package/types/layouts/Resizer.vue.d.ts +12 -0
  57. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +14 -0
  58. package/types/layouts/sidebar/LayerMenu.vue.d.ts +100 -0
  59. package/types/layouts/sidebar/LayerPanel.vue.d.ts +1099 -0
  60. package/{dist/types/src → types}/layouts/sidebar/Sidebar.vue.d.ts +3 -5
  61. package/types/layouts/sidebar/TabPane.vue.d.ts +14 -0
  62. package/types/layouts/workspace/PageBar.vue.d.ts +54 -0
  63. package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +48 -0
  64. package/types/layouts/workspace/Stage.vue.d.ts +46 -0
  65. package/types/layouts/workspace/ViewerMenu.vue.d.ts +88 -0
  66. package/types/layouts/workspace/Workspace.vue.d.ts +6 -0
  67. package/{dist/types/src → types}/services/BaseService.d.ts +0 -0
  68. package/types/services/componentList.d.ts +14 -0
  69. package/{dist/types/src → types}/services/editor.d.ts +26 -11
  70. package/{dist/types/src → types}/services/events.d.ts +0 -0
  71. package/{dist/types/src → types}/services/history.d.ts +0 -0
  72. package/{dist/types/src → types}/services/props.d.ts +25 -1
  73. package/types/services/storage.d.ts +56 -0
  74. package/{dist/types/src → types}/services/ui.d.ts +1 -1
  75. package/{dist/types/src → types}/type.d.ts +15 -0
  76. package/{dist/types/src → types}/utils/compose.d.ts +1 -1
  77. package/{dist/types/src → types}/utils/config.d.ts +0 -0
  78. package/{dist/types/src → types}/utils/editor.d.ts +2 -2
  79. package/{dist/types/src → types}/utils/index.d.ts +0 -0
  80. package/{dist/types/src → types}/utils/logger.d.ts +0 -0
  81. package/types/utils/operator.d.ts +44 -0
  82. package/{dist/types/src → types}/utils/polyfills.d.ts +0 -0
  83. package/{dist/types/src → types}/utils/props.d.ts +2 -22
  84. package/{dist/types/src → types}/utils/scroll-viewer.d.ts +0 -0
  85. package/{dist/types/src → types}/utils/undo-redo.d.ts +0 -0
  86. package/dist/tmagic-editor.es.js.map +0 -1
  87. package/dist/types/src/components/Icon.vue.d.ts +0 -14
  88. package/dist/types/src/components/ScrollViewer.vue.d.ts +0 -24
  89. package/dist/types/src/fields/Code.vue.d.ts +0 -25
  90. package/dist/types/src/layouts/AddPageBox.vue.d.ts +0 -5
  91. package/dist/types/src/layouts/Framework.vue.d.ts +0 -24
  92. package/dist/types/src/layouts/NavMenu.vue.d.ts +0 -27
  93. package/dist/types/src/layouts/PropsPanel.vue.d.ts +0 -13
  94. package/dist/types/src/layouts/Resizer.vue.d.ts +0 -14
  95. package/dist/types/src/layouts/sidebar/ComponentListPanel.vue.d.ts +0 -16
  96. package/dist/types/src/layouts/sidebar/TabPane.vue.d.ts +0 -16
  97. package/dist/types/src/layouts/workspace/Workspace.vue.d.ts +0 -8
  98. package/dist/types/src/shims-vue.d.ts +0 -6
  99. package/dist/types/src/vite-env.d.ts +0 -1
  100. package/src/vite-env.d.ts +0 -1
@@ -2,163 +2,159 @@
2
2
  <content-menu :menu-data="menuData" ref="menu"></content-menu>
3
3
  </template>
4
4
 
5
- <script lang="ts">
6
- import { computed, defineComponent, inject, markRaw, onMounted, reactive, ref, watch } from 'vue';
5
+ <script lang="ts" setup>
6
+ import { computed, inject, markRaw, onMounted, reactive, ref, watch } from 'vue';
7
7
  import { Bottom, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
8
8
 
9
- import { NodeType } from '@tmagic/schema';
10
- import type StageCore from '@tmagic/stage';
9
+ import { MNode, NodeType } from '@tmagic/schema';
10
+ import StageCore from '@tmagic/stage';
11
+ import { isPage } from '@tmagic/utils';
11
12
 
12
- import ContentMenu from '@editor/components/ContentMenu.vue';
13
- import { LayerOffset, Layout, MenuItem, Services } from '@editor/type';
14
- import { COPY_STORAGE_KEY } from '@editor/utils/editor';
13
+ import ContentMenu from '../../components/ContentMenu.vue';
14
+ import storageService from '../../services/storage';
15
+ import { LayerOffset, Layout, MenuItem, Services } from '../../type';
16
+ import { COPY_STORAGE_KEY } from '../../utils/editor';
15
17
 
16
- export default defineComponent({
17
- components: { ContentMenu },
18
+ const props = withDefaults(defineProps<{ isMultiSelect?: boolean }>(), { isMultiSelect: false });
18
19
 
19
- setup() {
20
- const services = inject<Services>('services');
21
- const editorService = services?.editorService;
22
- const menu = ref<InstanceType<typeof ContentMenu>>();
23
- const canPaste = ref(false);
24
- const canCenter = ref(false);
20
+ const services = inject<Services>('services');
21
+ const editorService = services?.editorService;
22
+ const menu = ref<InstanceType<typeof ContentMenu>>();
23
+ const canPaste = ref(false);
24
+ const canCenter = ref(false);
25
25
 
26
- const node = computed(() => editorService?.get('node'));
27
- const parent = computed(() => editorService?.get('parent'));
28
- const isPage = computed(() => node.value?.type === NodeType.PAGE);
26
+ const node = computed(() => editorService?.get<MNode>('node'));
27
+ const nodes = computed(() => editorService?.get<MNode[]>('nodes'));
28
+ const parent = computed(() => editorService?.get('parent'));
29
+ const stage = computed(() => editorService?.get<StageCore>('stage'));
29
30
 
30
- const stageContentMenu = inject<MenuItem[]>('stageContentMenu', []);
31
+ const stageContentMenu = inject<MenuItem[]>('stageContentMenu', []);
31
32
 
32
- onMounted(() => {
33
- const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY);
34
- canPaste.value = data !== 'undefined' && !!data;
35
- });
36
-
37
- watch(
38
- parent,
39
- async () => {
40
- if (!parent.value || !editorService) return (canCenter.value = false);
41
- const layout = await editorService.getLayout(parent.value);
42
- canCenter.value =
43
- [Layout.ABSOLUTE, Layout.FIXED].includes(layout) &&
44
- ![NodeType.ROOT, NodeType.PAGE, 'pop'].includes(`${node.value?.type}`);
45
- },
46
- { immediate: true },
47
- );
33
+ const menuData = reactive<MenuItem[]>([
34
+ {
35
+ type: 'button',
36
+ text: '水平居中',
37
+ display: () => canCenter.value && !props.isMultiSelect,
38
+ handler: () => {
39
+ if (!node.value) return;
40
+ editorService?.alignCenter(node.value);
41
+ },
42
+ },
43
+ {
44
+ type: 'button',
45
+ text: '复制',
46
+ icon: markRaw(DocumentCopy),
47
+ handler: () => {
48
+ nodes.value && editorService?.copy(nodes.value);
49
+ canPaste.value = true;
50
+ },
51
+ },
52
+ {
53
+ type: 'button',
54
+ text: '粘贴',
55
+ display: () => canPaste.value,
56
+ handler: () => {
57
+ const rect = menu.value?.$el.getBoundingClientRect();
58
+ const parentRect = stage.value?.container?.getBoundingClientRect();
59
+ const initialLeft = (rect?.left || 0) - (parentRect?.left || 0);
60
+ const initialTop = (rect?.top || 0) - (parentRect?.top || 0);
48
61
 
49
- return {
50
- menu,
51
- menuData: reactive<MenuItem[]>([
52
- {
53
- type: 'button',
54
- text: '水平居中',
55
- display: () => canCenter.value,
56
- handler: () => {
57
- node.value && editorService?.alignCenter(node.value);
58
- },
59
- },
60
- {
61
- type: 'button',
62
- text: '复制',
63
- icon: markRaw(DocumentCopy),
64
- handler: () => {
65
- node.value && editorService?.copy(node.value);
66
- canPaste.value = true;
67
- },
68
- },
69
- {
70
- type: 'button',
71
- text: '粘贴',
72
- display: () => canPaste.value,
73
- handler: () => {
74
- const stage = editorService?.get<StageCore>('stage');
62
+ if (!nodes.value || nodes.value.length === 0) return;
63
+ editorService?.paste({ left: initialLeft, top: initialTop });
64
+ },
65
+ },
66
+ {
67
+ type: 'divider',
68
+ direction: 'horizontal',
69
+ display: () => {
70
+ if (!node.value) return false;
71
+ return !isPage(node.value);
72
+ },
73
+ },
74
+ {
75
+ type: 'button',
76
+ text: '上移一层',
77
+ icon: markRaw(Top),
78
+ display: () => !isPage(node.value) && !props.isMultiSelect,
79
+ handler: () => {
80
+ editorService?.moveLayer(1);
81
+ },
82
+ },
83
+ {
84
+ type: 'button',
85
+ text: '下移一层',
86
+ icon: markRaw(Bottom),
87
+ display: () => !isPage(node.value) && !props.isMultiSelect,
88
+ handler: () => {
89
+ editorService?.moveLayer(-1);
90
+ },
91
+ },
92
+ {
93
+ type: 'button',
94
+ text: '置顶',
95
+ display: () => !isPage(node.value) && !props.isMultiSelect,
96
+ handler: () => {
97
+ editorService?.moveLayer(LayerOffset.TOP);
98
+ },
99
+ },
100
+ {
101
+ type: 'button',
102
+ text: '置底',
103
+ display: () => !isPage(node.value) && !props.isMultiSelect,
104
+ handler: () => {
105
+ editorService?.moveLayer(LayerOffset.BOTTOM);
106
+ },
107
+ },
108
+ {
109
+ type: 'divider',
110
+ direction: 'horizontal',
111
+ display: () => !isPage(node.value) && !props.isMultiSelect,
112
+ },
113
+ {
114
+ type: 'button',
115
+ text: '删除',
116
+ icon: Delete,
117
+ display: () => !isPage(node.value),
118
+ handler: () => {
119
+ nodes.value && editorService?.remove(nodes.value);
120
+ },
121
+ },
122
+ {
123
+ type: 'divider',
124
+ direction: 'horizontal',
125
+ },
126
+ {
127
+ type: 'button',
128
+ text: '清空参考线',
129
+ handler: () => {
130
+ editorService?.get<StageCore>('stage').clearGuides();
131
+ },
132
+ },
133
+ ...stageContentMenu,
134
+ ]);
75
135
 
76
- const rect = menu.value?.$el.getBoundingClientRect();
77
- const parentRect = stage?.container?.getBoundingClientRect();
78
- let left = (rect?.left || 0) - (parentRect?.left || 0);
79
- let top = (rect?.top || 0) - (parentRect?.top || 0);
136
+ onMounted(async () => {
137
+ const data = await storageService.getItem(COPY_STORAGE_KEY);
138
+ canPaste.value = data !== 'undefined' && !!data;
139
+ });
80
140
 
81
- if (node.value?.items && stage) {
82
- const parentEl = stage.renderer.contentWindow?.document.getElementById(`${node.value.id}`);
83
- const parentElRect = parentEl?.getBoundingClientRect();
84
- left = left - (parentElRect?.left || 0);
85
- top = top - (parentElRect?.top || 0);
86
- }
141
+ watch(
142
+ parent,
143
+ async () => {
144
+ if (!parent.value || !editorService) return (canCenter.value = false);
145
+ const layout = await editorService.getLayout(parent.value);
146
+ const isLayoutConform = [Layout.ABSOLUTE, Layout.FIXED].includes(layout);
147
+ const isTypeConform = nodes.value?.every(
148
+ (selectedNode) => ![NodeType.ROOT, NodeType.PAGE, 'pop'].includes(`${selectedNode?.type}`),
149
+ );
150
+ canCenter.value = isLayoutConform && !!isTypeConform;
151
+ },
152
+ { immediate: true },
153
+ );
87
154
 
88
- editorService?.paste({ left, top });
89
- },
90
- },
91
- {
92
- type: 'divider',
93
- direction: 'horizontal',
94
- display: () => !isPage.value,
95
- },
96
- {
97
- type: 'button',
98
- text: '上移一层',
99
- icon: markRaw(Top),
100
- display: () => !isPage.value,
101
- handler: () => {
102
- editorService?.moveLayer(1);
103
- },
104
- },
105
- {
106
- type: 'button',
107
- text: '下移一层',
108
- icon: markRaw(Bottom),
109
- display: () => !isPage.value,
110
- handler: () => {
111
- editorService?.moveLayer(-1);
112
- },
113
- },
114
- {
115
- type: 'button',
116
- text: '置顶',
117
- display: () => !isPage.value,
118
- handler: () => {
119
- editorService?.moveLayer(LayerOffset.TOP);
120
- },
121
- },
122
- {
123
- type: 'button',
124
- text: '置底',
125
- display: () => !isPage.value,
126
- handler: () => {
127
- editorService?.moveLayer(LayerOffset.BOTTOM);
128
- },
129
- },
130
- {
131
- type: 'divider',
132
- direction: 'horizontal',
133
- display: () => !isPage.value,
134
- },
135
- {
136
- type: 'button',
137
- text: '删除',
138
- icon: Delete,
139
- display: () => !isPage.value,
140
- handler: () => {
141
- node.value && editorService?.remove(node.value);
142
- },
143
- },
144
- {
145
- type: 'divider',
146
- direction: 'horizontal',
147
- },
148
- {
149
- type: 'button',
150
- text: '清空参考线',
151
- handler: () => {
152
- editorService?.get<StageCore>('stage').clearGuides();
153
- },
154
- },
155
- ...stageContentMenu,
156
- ]),
155
+ const show = (e: MouseEvent) => {
156
+ menu.value?.show(e);
157
+ };
157
158
 
158
- show(e: MouseEvent) {
159
- menu.value?.show(e);
160
- },
161
- };
162
- },
163
- });
159
+ defineExpose({ show });
164
160
  </script>
@@ -18,7 +18,7 @@ import KeyController from 'keycon';
18
18
  import type { MNode, MPage } from '@tmagic/schema';
19
19
  import { isPage } from '@tmagic/utils';
20
20
 
21
- import type { Services } from '@editor/type';
21
+ import type { Services } from '../../type';
22
22
 
23
23
  import PageBar from './PageBar.vue';
24
24
  import MagicStage from './Stage.vue';
@@ -34,7 +34,7 @@ export default defineComponent({
34
34
  setup() {
35
35
  const services = inject<Services>('services');
36
36
  const workspace = ref<HTMLDivElement>();
37
- const node = computed(() => services?.editorService.get<MNode>('node'));
37
+ const nodes = computed(() => services?.editorService.get<MNode[]>('nodes'));
38
38
  let keycon: KeyController;
39
39
 
40
40
  const mouseenterHandler = () => {
@@ -58,27 +58,27 @@ export default defineComponent({
58
58
  keycon
59
59
  .keyup('delete', (e) => {
60
60
  e.inputEvent.preventDefault();
61
- if (!node.value || isPage(node.value)) return;
62
- services?.editorService.remove(node.value);
61
+ if (!nodes.value || isPage(nodes.value[0])) return;
62
+ services?.editorService.remove(nodes.value);
63
63
  })
64
64
  .keyup('backspace', (e) => {
65
65
  e.inputEvent.preventDefault();
66
- if (!node.value || isPage(node.value)) return;
67
- services?.editorService.remove(node.value);
66
+ if (!nodes.value || isPage(nodes.value[0])) return;
67
+ services?.editorService.remove(nodes.value);
68
68
  })
69
69
  .keydown([ctrl, 'c'], (e) => {
70
70
  e.inputEvent.preventDefault();
71
- node.value && services?.editorService.copy(node.value);
71
+ nodes.value && services?.editorService.copy(nodes.value);
72
72
  })
73
73
  .keydown([ctrl, 'v'], (e) => {
74
74
  e.inputEvent.preventDefault();
75
- node.value && services?.editorService.paste();
75
+ nodes.value && services?.editorService.paste();
76
76
  })
77
77
  .keydown([ctrl, 'x'], (e) => {
78
78
  e.inputEvent.preventDefault();
79
- if (!node.value || isPage(node.value)) return;
80
- services?.editorService.copy(node.value);
81
- services?.editorService.remove(node.value);
79
+ if (!nodes.value || isPage(nodes.value[0])) return;
80
+ services?.editorService.copy(nodes.value);
81
+ services?.editorService.remove(nodes.value);
82
82
  })
83
83
  .keydown([ctrl, 'z'], (e) => {
84
84
  e.inputEvent.preventDefault();
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { EventEmitter } from 'events';
20
20
 
21
- import { compose } from '@editor/utils/compose';
21
+ import { compose } from '../utils/compose';
22
22
 
23
23
  const methodName = (prefix: string, name: string) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
24
24
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { reactive } from 'vue';
20
20
 
21
- import type { ComponentGroup, ComponentGroupState } from '@editor/type';
21
+ import type { ComponentGroup, ComponentGroupState } from '../type';
22
22
 
23
23
  import BaseService from './BaseService';
24
24
 
@@ -34,11 +34,11 @@ class ComponentList extends BaseService {
34
34
  /**
35
35
  * @param componentGroupList 组件列表配置
36
36
  */
37
- public setList(componentGroupList: ComponentGroup[]) {
37
+ public setList(componentGroupList: ComponentGroup[]): void {
38
38
  this.state.list = componentGroupList;
39
39
  }
40
40
 
41
- public getList() {
41
+ public getList(): ComponentGroup[] {
42
42
  return this.state.list;
43
43
  }
44
44
  }