@tmagic/editor 1.0.0-beta.11 → 1.0.0-beta.12

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.
@@ -7,6 +7,6 @@ declare const _default: DefineComponent<{}, {
7
7
  items: ComponentItem[];
8
8
  title: string;
9
9
  }[] | undefined>;
10
- appendComponent({ text, type, ...config }: ComponentItem): void;
10
+ appendComponent({ text, type, data }: ComponentItem): void;
11
11
  }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{}>>, {}>;
12
12
  export default _default;
@@ -1,4 +1,4 @@
1
- import type { DefineComponent, ComputedRef, ComponentOptionsMixin, VNodeProps, AllowedComponentProps, ComponentCustomProps, ExtractPropTypes, PropType } from 'vue';
1
+ import type { DefineComponent, Ref, ComputedRef, ComponentOptionsMixin, VNodeProps, AllowedComponentProps, ComponentCustomProps, ExtractPropTypes, PropType } from 'vue';
2
2
  import type { MPage } from '@tmagic/schema';
3
3
  import type { MoveableOptions } from '@tmagic/stage';
4
4
  import StageCore from '@tmagic/stage';
@@ -14,6 +14,7 @@ declare const _default: DefineComponent<{
14
14
  type: PropType<(el: HTMLElement) => boolean | Promise<boolean>>;
15
15
  };
16
16
  }, {
17
+ workspace: Ref<HTMLDivElement | undefined>;
17
18
  page: ComputedRef<MPage | undefined>;
18
19
  }, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, Record<string, any>, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<{
19
20
  runtimeUrl: StringConstructor;
@@ -29,7 +29,7 @@ declare class Props extends BaseService {
29
29
  * @param type 组件类型
30
30
  * @returns 组件初始值
31
31
  */
32
- getPropsValue(type: string): Promise<MComponent>;
32
+ getPropsValue(type: string, defaultValue?: {}): Promise<MComponent>;
33
33
  }
34
34
  export declare type PropsService = Props;
35
35
  declare const _default: Props;
@@ -169,7 +169,9 @@ export interface ComponentItem {
169
169
  type: string;
170
170
  /** element-plus icon class */
171
171
  icon?: string | Component;
172
- [key: string]: any;
172
+ data?: {
173
+ [key: string]: any;
174
+ };
173
175
  }
174
176
  export interface ComponentGroup {
175
177
  /** 显示文案 */
@@ -1,4 +1,5 @@
1
1
  import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
2
+ import type StageCore from '@tmagic/stage';
2
3
  import { Layout } from '../type';
3
4
  export declare const COPY_STORAGE_KEY = "$MagicEditorCopyData";
4
5
  export declare const generateId: (type: string | number) => string;
@@ -38,7 +39,7 @@ export declare const setNewItemId: (config: MNode, parent?: MPage | undefined) =
38
39
  export declare const isFixed: (node: MNode) => boolean;
39
40
  export declare const getNodeIndex: (node: MNode, parent: MContainer) => number;
40
41
  export declare const toRelative: (node: MNode) => MNode;
41
- export declare const initPosition: (node: MNode, layout: Layout) => MNode;
42
+ export declare const initPosition: (node: MNode, layout: Layout, parentNode: MNode, stage: StageCore) => MNode;
42
43
  export declare const setLayout: (node: MNode, layout: Layout) => MNode;
43
44
  export declare const change2Fixed: (node: MNode, root: MApp) => MNode;
44
45
  export declare const Fixed2Other: (node: MNode, root: MApp, getLayout: (node: MNode) => Promise<Layout>) => Promise<MNode>;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-beta.11",
2
+ "version": "1.0.0-beta.12",
3
3
  "name": "@tmagic/editor",
4
4
  "sideEffects": false,
5
5
  "main": "dist/tmagic-editor.umd.js",
@@ -26,16 +26,26 @@
26
26
  "type": "git",
27
27
  "url": "https://github.com/Tencent/tmagic-editor.git"
28
28
  },
29
+ "homepage": "https://tencent.github.io/tmagic-editor/docs/",
30
+ "keywords": [
31
+ "editor",
32
+ "drag",
33
+ "resize",
34
+ "vue",
35
+ "vue3",
36
+ "typescript"
37
+ ],
29
38
  "dependencies": {
30
39
  "@element-plus/icons": "0.0.11",
31
- "@tmagic/core": "^1.0.0-beta.11",
32
- "@tmagic/form": "^1.0.0-beta.11",
33
- "@tmagic/schema": "^1.0.0-beta.11",
34
- "@tmagic/stage": "^1.0.0-beta.11",
35
- "@tmagic/utils": "^1.0.0-beta.11",
40
+ "@tmagic/core": "^1.0.0-beta.12",
41
+ "@tmagic/form": "^1.0.0-beta.12",
42
+ "@tmagic/schema": "^1.0.0-beta.12",
43
+ "@tmagic/stage": "^1.0.0-beta.12",
44
+ "@tmagic/utils": "^1.0.0-beta.12",
36
45
  "color": "^3.1.3",
37
46
  "element-plus": "^2.1.7",
38
47
  "events": "^3.3.0",
48
+ "keycon": "^1.1.2",
39
49
  "lodash-es": "^4.17.21",
40
50
  "monaco-editor": "^0.32.1",
41
51
  "serialize-javascript": "^6.0.0",
@@ -56,5 +66,5 @@
56
66
  "vite-plugin-dts": "^0.9.6",
57
67
  "vue-tsc": "^0.0.24"
58
68
  },
59
- "gitHead": "db274d495f44030a788dee585f7fba53b6a3407e"
69
+ "gitHead": "ae00dd242d593ac8f57ffcd34e10e99399c7d00b"
60
70
  }
@@ -39,9 +39,9 @@ export default defineComponent({
39
39
  return;
40
40
  }
41
41
 
42
- values.value = node.value;
43
42
  const type = node.value.type || (node.value.items ? 'container' : 'text');
44
43
  curFormConfig.value = (await services?.propsService.getPropsConfig(type)) || [];
44
+ values.value = node.value;
45
45
  };
46
46
 
47
47
  watchEffect(init);
@@ -56,11 +56,11 @@ export default defineComponent({
56
56
  collapseValue,
57
57
  list,
58
58
 
59
- appendComponent({ text, type, ...config }: ComponentItem): void {
59
+ appendComponent({ text, type, data = {} }: ComponentItem): void {
60
60
  services?.editorService.add({
61
61
  name: text,
62
62
  type,
63
- ...config,
63
+ ...data,
64
64
  });
65
65
  },
66
66
  };
@@ -72,6 +72,7 @@ export default defineComponent({
72
72
  services?.editorService.add({
73
73
  name: config.text,
74
74
  type: config.type,
75
+ ...(config.data || {}),
75
76
  });
76
77
  },
77
78
 
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="m-editor-workspace">
2
+ <div class="m-editor-workspace" tabindex="1" ref="workspace">
3
3
  <magic-stage
4
4
  :key="page?.id"
5
5
  :runtime-url="runtimeUrl"
@@ -18,9 +18,10 @@
18
18
  </template>
19
19
 
20
20
  <script lang="ts">
21
- import { computed, defineComponent, inject, PropType } from 'vue';
21
+ import { computed, defineComponent, inject, onMounted, onUnmounted, PropType, ref } from 'vue';
22
+ import KeyController from 'keycon';
22
23
 
23
- import type { MPage } from '@tmagic/schema';
24
+ import type { MNode, MPage } from '@tmagic/schema';
24
25
  import type { MoveableOptions } from '@tmagic/stage';
25
26
  import StageCore from '@tmagic/stage';
26
27
 
@@ -55,8 +56,52 @@ export default defineComponent({
55
56
 
56
57
  setup() {
57
58
  const services = inject<Services>('services');
59
+ const workspace = ref<HTMLDivElement>();
60
+ const node = computed(() => services?.editorService.get<MNode>('node'));
61
+ let keycon: KeyController;
62
+
63
+ const mouseenterHandler = () => {
64
+ workspace.value?.focus();
65
+ };
66
+
67
+ const mouseleaveHandler = () => {
68
+ workspace.value?.blur();
69
+ };
70
+
71
+ onMounted(() => {
72
+ workspace.value?.addEventListener('mouseenter', mouseenterHandler);
73
+
74
+ workspace.value?.addEventListener('mouseleave', mouseleaveHandler);
75
+
76
+ keycon = new KeyController(workspace.value);
77
+
78
+ keycon
79
+ .keyup('delete', () => {
80
+ node.value && services?.editorService.remove(node.value);
81
+ })
82
+ .keyup(['ctrl', 'c'], () => {
83
+ node.value && services?.editorService.copy(node.value);
84
+ })
85
+ .keyup(['ctrl', 'v'], () => {
86
+ node.value && services?.editorService.paste();
87
+ })
88
+ .keyup(['ctrl', 'x'], () => {
89
+ if (node.value && services) {
90
+ services.editorService.copy(node.value);
91
+ services.editorService.remove(node.value);
92
+ }
93
+ });
94
+ });
95
+
96
+ onUnmounted(() => {
97
+ workspace.value?.removeEventListener('mouseenter', mouseenterHandler);
98
+ workspace.value?.removeEventListener('mouseleave', mouseleaveHandler);
99
+ keycon.destroy();
100
+ });
58
101
 
59
102
  return {
103
+ workspace,
104
+
60
105
  page: computed(() => services?.editorService.get<MPage>('page')),
61
106
  };
62
107
  },
@@ -22,7 +22,7 @@ import serialize from 'serialize-javascript';
22
22
 
23
23
  import type { Id, MApp, MComponent, MContainer, MNode, MPage } from '@tmagic/schema';
24
24
  import { NodeType } from '@tmagic/schema';
25
- import type StageCore from '@tmagic/stage';
25
+ import StageCore from '@tmagic/stage';
26
26
  import { getNodePath, isPop } from '@tmagic/utils';
27
27
 
28
28
  import historyService, { StepValue } from '@editor/services/history';
@@ -228,7 +228,12 @@ class Editor extends BaseService {
228
228
  if (!parentNode) throw new Error('未找到父元素');
229
229
 
230
230
  const layout = await this.getLayout(parentNode);
231
- const newNode = initPosition({ ...toRaw(await propsService.getPropsValue(type)), ...config }, layout);
231
+ const newNode = initPosition(
232
+ { ...toRaw(await propsService.getPropsValue(type, config)) },
233
+ layout,
234
+ parentNode,
235
+ this.get<StageCore>('stage'),
236
+ );
232
237
 
233
238
  if ((parentNode?.type === NodeType.ROOT || curNode.type === NodeType.ROOT) && newNode.type !== NodeType.PAGE) {
234
239
  throw new Error('app下不能添加组件');
@@ -87,7 +87,7 @@ class Props extends BaseService {
87
87
  * @param type 组件类型
88
88
  * @returns 组件初始值
89
89
  */
90
- public async getPropsValue(type: string) {
90
+ public async getPropsValue(type: string, defaultValue = {}) {
91
91
  if (type === 'area') {
92
92
  const value = (await this.getPropsValue('button')) as MComponent;
93
93
  value.className = 'action-area';
@@ -100,6 +100,7 @@ class Props extends BaseService {
100
100
 
101
101
  return cloneDeep({
102
102
  ...getDefaultPropsValue(type),
103
+ ...defaultValue,
103
104
  ...(this.state.propsValueMap[type] || {}),
104
105
  });
105
106
  }
package/src/type.ts CHANGED
@@ -220,7 +220,9 @@ export interface ComponentItem {
220
220
  type: string;
221
221
  /** element-plus icon class */
222
222
  icon?: string | Component;
223
- [key: string]: any;
223
+ data?: {
224
+ [key: string]: any;
225
+ };
224
226
  }
225
227
 
226
228
  export interface ComponentGroup {
@@ -20,7 +20,8 @@ import { random } from 'lodash-es';
20
20
 
21
21
  import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
22
22
  import { NodeType } from '@tmagic/schema';
23
- import { getNodePath, isPop } from '@tmagic/utils';
23
+ import type StageCore from '@tmagic/stage';
24
+ import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
24
25
 
25
26
  import { Layout } from '@editor/type';
26
27
 
@@ -105,7 +106,7 @@ const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
105
106
  export const setNewItemId = (config: MNode, parent?: MPage) => {
106
107
  const oldId = config.id;
107
108
 
108
- config.id = generateId(config.type);
109
+ config.id = generateId(config.type || 'component');
109
110
  config.name = `${config.name?.replace(/_(\d+)$/, '')}_${config.id}`;
110
111
 
111
112
  // 只有弹窗在页面下的一级子元素才有效
@@ -139,11 +140,29 @@ export const toRelative = (node: MNode) => {
139
140
  return node;
140
141
  };
141
142
 
142
- export const initPosition = (node: MNode, layout: Layout) => {
143
+ const setTop2Middle = (node: MNode, parentNode: MNode, stage: StageCore) => {
144
+ const style = node.style || {};
145
+ const height = style.height || 0;
146
+
147
+ if (!stage || style.top || !parentNode.style || !isNumber(height)) return style;
148
+
149
+ const { height: parentHeight } = parentNode.style;
150
+
151
+ if (isPage(parentNode)) {
152
+ const { scrollTop = 0, wrapperHeight } = stage.mask;
153
+ style.top = (wrapperHeight - height) / 2 + scrollTop;
154
+ } else {
155
+ style.top = (parentHeight - height) / 2;
156
+ }
157
+
158
+ return style;
159
+ };
160
+
161
+ export const initPosition = (node: MNode, layout: Layout, parentNode: MNode, stage: StageCore) => {
143
162
  if (layout === Layout.ABSOLUTE) {
144
163
  node.style = {
145
164
  position: 'absolute',
146
- ...(node.style || {}),
165
+ ...setTop2Middle(node, parentNode, stage),
147
166
  };
148
167
  return node;
149
168
  }
@@ -200,6 +219,8 @@ export const Fixed2Other = async (node: MNode, root: MApp, getLayout: (node: MNo
200
219
  const offset = {
201
220
  left: cur?.style?.left || 0,
202
221
  top: cur?.style?.top || 0,
222
+ right: '',
223
+ bottom: '',
203
224
  };
204
225
 
205
226
  path.forEach((value) => {
@@ -174,7 +174,7 @@ export const fillConfig = (config: FormConfig = []) => [
174
174
  type: 'select',
175
175
  options: (mForm: FormState, { model }: any) => {
176
176
  const node = editorService.getNodeById(model.to);
177
- if (!node) return [];
177
+ if (!node?.type) return [];
178
178
 
179
179
  return eventsService.getMethod(node.type).map((option) => ({
180
180
  text: option.label,