@tmagic/editor 1.1.3 → 1.1.5

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.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.3",
2
+ "version": "1.1.5",
3
3
  "name": "@tmagic/editor",
4
4
  "sideEffects": [
5
5
  "dist/*",
@@ -45,11 +45,11 @@
45
45
  "dependencies": {
46
46
  "@babel/core": "^7.18.0",
47
47
  "@element-plus/icons-vue": "^2.0.9",
48
- "@tmagic/core": "1.1.3",
49
- "@tmagic/form": "1.1.3",
50
- "@tmagic/schema": "1.1.3",
51
- "@tmagic/stage": "1.1.3",
52
- "@tmagic/utils": "1.1.3",
48
+ "@tmagic/core": "1.1.5",
49
+ "@tmagic/form": "1.1.5",
50
+ "@tmagic/schema": "1.1.5",
51
+ "@tmagic/stage": "1.1.5",
52
+ "@tmagic/utils": "1.1.5",
53
53
  "buffer": "^6.0.3",
54
54
  "color": "^3.1.3",
55
55
  "element-plus": "^2.2.6",
@@ -62,7 +62,7 @@
62
62
  "vue": "^3.2.37"
63
63
  },
64
64
  "peerDependencies": {
65
- "@tmagic/form": "1.1.3",
65
+ "@tmagic/form": "1.1.5",
66
66
  "element-plus": "^2.2.6",
67
67
  "monaco-editor": "^0.34.0",
68
68
  "vue": "^3.2.37"
@@ -72,13 +72,13 @@
72
72
  "@types/lodash-es": "^4.17.4",
73
73
  "@types/node": "^15.12.4",
74
74
  "@types/serialize-javascript": "^5.0.1",
75
- "@vitejs/plugin-vue": "^3.0.1",
75
+ "@vitejs/plugin-vue": "^3.1.0",
76
76
  "@vue/compiler-sfc": "^3.2.37",
77
77
  "@vue/test-utils": "^2.0.0",
78
78
  "rimraf": "^3.0.2",
79
79
  "sass": "^1.35.1",
80
80
  "typescript": "^4.7.4",
81
- "vite": "^3.0.4",
81
+ "vite": "^3.1.3",
82
82
  "vue-tsc": "^0.39.4"
83
83
  }
84
84
  }
package/src/Editor.vue CHANGED
@@ -277,8 +277,6 @@ export default defineComponent({
277
277
  },
278
278
  );
279
279
 
280
- uiService.initColumnWidth();
281
-
282
280
  onUnmounted(() => {
283
281
  editorService.destroy();
284
282
  historyService.destroy();
@@ -7,29 +7,25 @@
7
7
  ></magic-code-editor>
8
8
  </template>
9
9
 
10
- <script lang="ts">
11
- import { computed, defineComponent } from 'vue';
10
+ <script lang="ts" setup>
11
+ import { computed } from 'vue';
12
12
 
13
- export default defineComponent({
14
- name: 'm-fields-vs-code',
13
+ const emit = defineEmits(['change']);
15
14
 
16
- props: ['model', 'name', 'config', 'prop'],
15
+ const props = defineProps<{
16
+ model: any;
17
+ name: string;
18
+ config: {
19
+ language?: string;
20
+ };
21
+ prop: string;
22
+ }>();
17
23
 
18
- emits: ['change'],
24
+ const language = computed(() => props.config.language || 'javascript');
25
+ const height = computed(() => `${document.body.clientHeight - 168}px`);
19
26
 
20
- setup(props, { emit }) {
21
- const language = computed(() => props.config.language || 'javascript');
22
- const height = computed(() => `${document.body.clientHeight - 168}px`);
23
-
24
- return {
25
- height,
26
- language,
27
-
28
- save(v: string) {
29
- props.model[props.name] = v;
30
- emit('change', v);
31
- },
32
- };
33
- },
34
- });
27
+ const save = (v: string) => {
28
+ props.model[props.name] = v;
29
+ emit('change', v);
30
+ };
35
31
  </script>
@@ -2,80 +2,66 @@
2
2
  <m-fields-link :config="formConfig" :model="modelValue" name="form" @change="changeHandler"></m-fields-link>
3
3
  </template>
4
4
 
5
- <script lang="ts">
6
- import { computed, defineComponent, PropType, ref, watchEffect } from 'vue';
5
+ <script lang="ts" setup>
6
+ import { computed, reactive, watch } from 'vue';
7
7
  import serialize from 'serialize-javascript';
8
8
 
9
- interface CodeLinkConfig {
10
- type: 'code-link';
9
+ const props = defineProps<{
10
+ config: {
11
+ type: 'code-link';
12
+ name: string;
13
+ text?: string;
14
+ formTitle?: string;
15
+ };
16
+ model: any;
11
17
  name: string;
12
- text?: string;
13
- formTitle?: string;
14
- }
18
+ prop: string;
19
+ }>();
15
20
 
16
- export default defineComponent({
17
- name: 'm-fields-code-link',
21
+ const emit = defineEmits(['change']);
18
22
 
19
- props: {
20
- config: {
21
- type: Object as PropType<CodeLinkConfig>,
23
+ const formConfig = computed(() => ({
24
+ ...props.config,
25
+ text: '',
26
+ type: 'link',
27
+ form: [
28
+ {
29
+ name: props.name,
30
+ type: 'vs-code',
22
31
  },
32
+ ],
33
+ }));
23
34
 
24
- model: {
25
- type: Object,
26
- },
27
-
28
- name: {
29
- type: String,
30
- },
31
-
32
- prop: {
33
- type: String,
34
- },
35
+ const modelValue = reactive<{ form: Record<string, string> }>({
36
+ form: {
37
+ [props.name]: '',
35
38
  },
39
+ });
36
40
 
37
- emits: ['change'],
38
-
39
- setup(props, { emit }) {
40
- const modelValue = ref<{ form: Record<string, any> }>({
41
- form: {},
42
- });
43
-
44
- watchEffect(() => {
45
- if (!props.model || !props.name) return;
46
- modelValue.value.form[props.name] = serialize(props.model[props.name], {
41
+ watch(
42
+ () => props.model[props.name],
43
+ (value) => {
44
+ modelValue.form = {
45
+ [props.name]: serialize(value, {
47
46
  space: 2,
48
47
  unsafe: true,
49
- }).replace(/"(\w+)":\s/g, '$1: ');
50
- });
51
-
52
- return {
53
- modelValue,
54
-
55
- formConfig: computed(() => ({
56
- ...props.config,
57
- text: '',
58
- type: 'link',
59
- form: [
60
- {
61
- name: props.name,
62
- type: 'vs-code',
63
- },
64
- ],
65
- })),
66
-
67
- changeHandler(v: Record<string, any>) {
68
- if (!props.name || !props.model) return;
69
-
70
- try {
71
- // eslint-disable-next-line no-eval
72
- props.model[props.name] = eval(`${v[props.name]}`);
73
- emit('change', props.model[props.name]);
74
- } catch (e) {
75
- console.error(e);
76
- }
77
- },
48
+ }).replace(/"(\w+)":\s/g, '$1: '),
78
49
  };
79
50
  },
80
- });
51
+ {
52
+ immediate: true,
53
+ },
54
+ );
55
+
56
+ const changeHandler = (v: Record<string, any>) => {
57
+ if (!props.name || !props.model) return;
58
+
59
+ try {
60
+ // eslint-disable-next-line no-eval
61
+ props.model[props.name] = eval(`(${v[props.name]})`);
62
+ emit('change', props.model[props.name]);
63
+ } catch (e) {
64
+ console.error(e);
65
+ }
66
+ };
81
67
  </script>
package/src/index.ts CHANGED
@@ -59,8 +59,8 @@ export default {
59
59
 
60
60
  app.component(Editor.name, Editor);
61
61
  app.component('m-fields-ui-select', uiSelect);
62
- app.component(CodeLink.name, CodeLink);
63
- app.component(Code.name, Code);
62
+ app.component('m-fields-code-link', CodeLink);
63
+ app.component('m-fields-vs-code', Code);
64
64
  app.component(CodeEditor.name, CodeEditor);
65
65
  },
66
66
  };
@@ -10,77 +10,107 @@
10
10
  @save="saveCode"
11
11
  ></magic-code-editor>
12
12
 
13
- <div class="m-editor-content" v-else>
14
- <div class="m-editor-framework-left" :style="`width: ${columnWidth?.left}px`">
13
+ <layout
14
+ v-else
15
+ class="m-editor-content"
16
+ left-class="m-editor-framework-left"
17
+ center-class="m-editor-framework-center"
18
+ right-class="m-editor-framework-right"
19
+ v-model:left="columnWidth.left"
20
+ v-model:right="columnWidth.right"
21
+ :min-left="45"
22
+ :min-right="1"
23
+ @change="columnWidthChange"
24
+ >
25
+ <template #left>
15
26
  <slot name="sidebar"></slot>
16
- </div>
17
-
18
- <resizer type="left"></resizer>
19
-
20
- <template v-if="pageLength > 0">
21
- <div class="m-editor-framework-center" :style="`width: ${columnWidth?.center}px`">
22
- <slot name="workspace"></slot>
23
- </div>
24
-
25
- <resizer type="right"></resizer>
27
+ </template>
26
28
 
27
- <div class="m-editor-framework-right" :style="`width: ${columnWidth?.right}px`">
28
- <el-scrollbar>
29
- <slot name="props-panel"></slot>
30
- </el-scrollbar>
31
- </div>
29
+ <template #center>
30
+ <slot v-if="pageLength > 0" name="workspace"></slot>
31
+ <slot v-else name="empty">
32
+ <add-page-box></add-page-box>
33
+ </slot>
32
34
  </template>
33
35
 
34
- <slot v-else name="empty">
35
- <add-page-box></add-page-box>
36
- </slot>
37
- </div>
36
+ <template v-if="pageLength > 0" #right>
37
+ <el-scrollbar>
38
+ <slot name="props-panel"></slot>
39
+ </el-scrollbar>
40
+ </template>
41
+ </layout>
38
42
  </div>
39
43
  </template>
40
44
 
41
- <script lang="ts">
42
- import { computed, defineComponent, inject } from 'vue';
45
+ <script lang="ts" setup>
46
+ import { computed, inject, ref, watchEffect } from 'vue';
43
47
 
44
48
  import type { MApp } from '@tmagic/schema';
45
49
 
46
50
  import { GetColumnWidth, Services } from '../type';
47
51
 
48
52
  import AddPageBox from './AddPageBox.vue';
49
- import Resizer from './Resizer.vue';
53
+ import Layout from './Layout.vue';
50
54
 
51
- export default defineComponent({
52
- components: {
53
- AddPageBox,
54
- Resizer,
55
- },
55
+ const DEFAULT_LEFT_COLUMN_WIDTH = 310;
56
+ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
56
57
 
57
- props: {
58
- codeOptions: {
59
- type: Object,
60
- default: () => ({}),
61
- },
58
+ withDefaults(
59
+ defineProps<{
60
+ codeOptions?: Record<string, any>;
61
+ }>(),
62
+ {
63
+ codeOptions: () => ({}),
62
64
  },
65
+ );
63
66
 
64
- setup() {
65
- const { editorService, uiService } = inject<Services>('services') || {};
66
-
67
- const root = computed(() => editorService?.get<MApp>('root'));
68
-
69
- return {
70
- root,
71
- pageLength: computed(() => editorService?.get<number>('pageLength') || 0),
72
- showSrc: computed(() => uiService?.get<boolean>('showSrc')),
73
- columnWidth: computed(() => uiService?.get<GetColumnWidth>('columnWidth')),
74
-
75
- saveCode(value: string) {
76
- try {
77
- // eslint-disable-next-line no-eval
78
- editorService?.set('root', eval(value));
79
- } catch (e: any) {
80
- console.error(e);
81
- }
82
- },
83
- };
84
- },
67
+ const { editorService, uiService } = inject<Services>('services') || {};
68
+
69
+ const root = computed(() => editorService?.get<MApp>('root'));
70
+
71
+ const pageLength = computed(() => editorService?.get<number>('pageLength') || 0);
72
+ const showSrc = computed(() => uiService?.get<boolean>('showSrc'));
73
+ const columnWidth = ref<Partial<GetColumnWidth>>({
74
+ left: DEFAULT_LEFT_COLUMN_WIDTH,
75
+ center: 0,
76
+ right: 0,
77
+ });
78
+ uiService?.set('columnWidth', columnWidth.value);
79
+
80
+ watchEffect(() => {
81
+ if (pageLength.value <= 0) {
82
+ columnWidth.value.right = undefined;
83
+ columnWidth.value.center = globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH;
84
+ } else {
85
+ columnWidth.value.right = columnWidth.value.right || DEFAULT_RIGHT_COLUMN_WIDTH;
86
+ columnWidth.value.center =
87
+ globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH;
88
+ }
85
89
  });
90
+
91
+ const saveCode = (value: string) => {
92
+ try {
93
+ // eslint-disable-next-line no-eval
94
+ editorService?.set('root', eval(value));
95
+ } catch (e: any) {
96
+ console.error(e);
97
+ }
98
+ };
99
+
100
+ const COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorColumnWidthData';
101
+
102
+ const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
103
+ if (columnWidthCacheData) {
104
+ try {
105
+ const columnWidthCache = JSON.parse(columnWidthCacheData);
106
+ columnWidth.value = columnWidthCache;
107
+ } catch (e) {
108
+ console.error(e);
109
+ }
110
+ }
111
+
112
+ const columnWidthChange = (columnWidth: GetColumnWidth) => {
113
+ uiService?.set('columnWidth', columnWidth);
114
+ globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
115
+ };
86
116
  </script>
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div ref="el">
3
+ <template v-if="typeof props.left !== 'undefined'">
4
+ <div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
5
+ <slot name="left"></slot>
6
+ </div>
7
+ <Resizer @change="changeLeft"></Resizer>
8
+ </template>
9
+
10
+ <div class="m-editor-layout-center" :class="centerClass" :style="`width: ${center}px`">
11
+ <slot name="center"></slot>
12
+ </div>
13
+
14
+ <template v-if="typeof props.right !== 'undefined'">
15
+ <Resizer @change="changeRight"></Resizer>
16
+ <div class="m-editor-layout-right" :class="rightClass" :style="`width: ${right}px`">
17
+ <slot name="right"></slot>
18
+ </div>
19
+ </template>
20
+ </div>
21
+ </template>
22
+
23
+ <script lang="ts" setup>
24
+ import { onMounted, onUnmounted, ref } from 'vue';
25
+
26
+ import Resizer from './Resizer.vue';
27
+
28
+ const emit = defineEmits(['update:left', 'change', 'update:right']);
29
+
30
+ const props = withDefaults(
31
+ defineProps<{
32
+ left?: number;
33
+ right?: number;
34
+ minLeft?: number;
35
+ minRight?: number;
36
+ leftClass?: string;
37
+ rightClass?: string;
38
+ centerClass?: string;
39
+ }>(),
40
+ {
41
+ minLeft: 1,
42
+ minRight: 1,
43
+ },
44
+ );
45
+
46
+ const el = ref<HTMLElement>();
47
+
48
+ let clientWidth = 0;
49
+ const resizerObserver = new ResizeObserver((entries) => {
50
+ for (const { contentRect } of entries) {
51
+ clientWidth = contentRect.width;
52
+
53
+ center.value = clientWidth - (props.left || 0) - (props.right || 0);
54
+
55
+ emit('change', {
56
+ left: props.left,
57
+ center: center.value,
58
+ right: props.right,
59
+ });
60
+ }
61
+ });
62
+
63
+ onMounted(() => {
64
+ if (el.value) {
65
+ resizerObserver.observe(el.value);
66
+ }
67
+ });
68
+
69
+ onUnmounted(() => {
70
+ resizerObserver.disconnect();
71
+ });
72
+
73
+ const center = ref(0);
74
+
75
+ const changeLeft = (deltaX: number) => {
76
+ if (typeof props.left === 'undefined') return;
77
+ const left = Math.max(props.left + deltaX, props.minLeft) || 0;
78
+ emit('update:left', left);
79
+ center.value = clientWidth - left - (props.right || 0);
80
+
81
+ emit('change', {
82
+ left,
83
+ center: center.value,
84
+ right: props.right,
85
+ });
86
+ };
87
+
88
+ const changeRight = (deltaX: number) => {
89
+ if (typeof props.right === 'undefined') return;
90
+ const right = Math.max(props.right - deltaX, props.minRight) || 0;
91
+ emit('update:right', right);
92
+ center.value = clientWidth - (props.left || 0) - right;
93
+
94
+ emit('change', {
95
+ left: props.left,
96
+ center: center.value,
97
+ right,
98
+ });
99
+ };
100
+ </script>
@@ -123,7 +123,7 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
123
123
  className: 'scale-to-fit',
124
124
  icon: markRaw(FullScreen),
125
125
  tooltip: `缩放以适应(${ctrl}+0)`,
126
- handler: () => uiService?.set('zoom', uiService.calcZoom()),
126
+ handler: async () => uiService?.set('zoom', await uiService.calcZoom()),
127
127
  });
128
128
  break;
129
129
  case 'rule':
@@ -4,58 +4,29 @@
4
4
  </span>
5
5
  </template>
6
6
 
7
- <script lang="ts">
8
- import { defineComponent, inject, onMounted, onUnmounted, ref, toRaw } from 'vue';
7
+ <script lang="ts" setup>
8
+ import { onMounted, onUnmounted, ref } from 'vue';
9
9
  import Gesto from 'gesto';
10
10
 
11
- import { Services } from '../type';
11
+ const emit = defineEmits(['change']);
12
12
 
13
- export default defineComponent({
14
- name: 'm-editor-resize',
13
+ const target = ref<HTMLSpanElement>();
15
14
 
16
- props: {
17
- type: {
18
- type: String,
19
- },
20
- },
15
+ let getso: Gesto;
21
16
 
22
- setup(props) {
23
- const services = inject<Services>('services');
17
+ onMounted(() => {
18
+ if (!target.value) return;
19
+ getso = new Gesto(target.value, {
20
+ container: window,
21
+ pinchOutside: true,
22
+ }).on('drag', (e) => {
23
+ if (!target.value) return;
24
24
 
25
- const target = ref<HTMLSpanElement>();
26
-
27
- let getso: Gesto;
28
-
29
- onMounted(() => {
30
- if (!target.value) return;
31
- getso = new Gesto(target.value, {
32
- container: window,
33
- pinchOutside: true,
34
- }).on('drag', (e) => {
35
- if (!target.value || !services) return;
36
-
37
- let { left, right } = {
38
- ...toRaw(services.uiService.get('columnWidth')),
39
- };
40
- if (props.type === 'left') {
41
- left += e.deltaX;
42
- } else if (props.type === 'right') {
43
- right -= e.deltaX;
44
- }
45
- services.uiService.set('columnWidth', {
46
- left,
47
- right,
48
- });
49
- });
50
- });
51
-
52
- onUnmounted(() => {
53
- getso?.unset();
54
- });
25
+ emit('change', e.deltaX);
26
+ });
27
+ });
55
28
 
56
- return {
57
- target,
58
- };
59
- },
29
+ onUnmounted(() => {
30
+ getso?.unset();
60
31
  });
61
32
  </script>
@@ -15,8 +15,8 @@
15
15
  <el-collapse-item v-if="group.items && group.items.length" :key="index" :name="index">
16
16
  <template #title><i class="el-icon-s-grid"></i>{{ group.title }}</template>
17
17
  <div
18
- class="component-item"
19
18
  v-for="item in group.items"
19
+ class="component-item"
20
20
  draggable="true"
21
21
  :key="item.type"
22
22
  @click="appendComponent(item)"