@tmagic/editor 1.3.0-alpha.7 → 1.3.0-alpha.8

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.3.0-alpha.7",
2
+ "version": "1.3.0-alpha.8",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -46,27 +46,27 @@
46
46
  "dependencies": {
47
47
  "@babel/core": "^7.18.0",
48
48
  "@element-plus/icons-vue": "^2.0.9",
49
- "@tmagic/core": "1.3.0-alpha.7",
50
- "@tmagic/design": "1.3.0-alpha.7",
51
- "@tmagic/form": "1.3.0-alpha.7",
52
- "@tmagic/schema": "1.3.0-alpha.7",
53
- "@tmagic/stage": "1.3.0-alpha.7",
54
- "@tmagic/table": "1.3.0-alpha.7",
55
- "@tmagic/utils": "1.3.0-alpha.7",
49
+ "@tmagic/core": "1.3.0-alpha.8",
50
+ "@tmagic/design": "1.3.0-alpha.8",
51
+ "@tmagic/form": "1.3.0-alpha.8",
52
+ "@tmagic/schema": "1.3.0-alpha.8",
53
+ "@tmagic/stage": "1.3.0-alpha.8",
54
+ "@tmagic/table": "1.3.0-alpha.8",
55
+ "@tmagic/utils": "1.3.0-alpha.8",
56
56
  "buffer": "^6.0.3",
57
57
  "color": "^3.1.3",
58
58
  "events": "^3.3.0",
59
59
  "gesto": "^1.7.0",
60
60
  "keycon": "^1.1.2",
61
61
  "lodash-es": "^4.17.21",
62
- "monaco-editor": "^0.34.0",
62
+ "monaco-editor": "^0.39.0",
63
63
  "serialize-javascript": "^6.0.0",
64
64
  "vue": "^3.3.4"
65
65
  },
66
66
  "peerDependencies": {
67
- "@tmagic/design": "1.3.0-alpha.7",
68
- "@tmagic/form": "1.3.0-alpha.7",
69
- "monaco-editor": "^0.34.0",
67
+ "@tmagic/design": "1.3.0-alpha.8",
68
+ "@tmagic/form": "1.3.0-alpha.8",
69
+ "monaco-editor": "^0.39.0",
70
70
  "vue": "^3.3.4"
71
71
  },
72
72
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div ref="el" class="m-editor-layout">
3
- <template v-if="hasLeft">
3
+ <template v-if="hasLeft && $slots.left">
4
4
  <div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
5
5
  <slot name="left"></slot>
6
6
  </div>
@@ -11,7 +11,7 @@
11
11
  <slot name="center"></slot>
12
12
  </div>
13
13
 
14
- <template v-if="hasRight">
14
+ <template v-if="hasRight && $slots.right">
15
15
  <Resizer @change="changeRight"></Resizer>
16
16
  <div class="m-editor-layout-right" :class="rightClass" :style="`width: ${right}px`">
17
17
  <slot name="right"></slot>
@@ -30,13 +30,15 @@
30
30
  </div>
31
31
  </template>
32
32
  </component>
33
- <div :class="`el-input el-input--${size}`" @mouseup="mouseupHandler" v-else>
34
- <div :class="`el-input__wrapper ${isFocused ? ' is-focus' : ''}`">
33
+ <div :class="`tmagic-data-source-input-text el-input el-input--${size}`" @mouseup="mouseupHandler" v-else>
34
+ <div :class="`tmagic-data-source-input-text-wrapper el-input__wrapper ${isFocused ? ' is-focus' : ''}`">
35
35
  <div class="el-input__inner">
36
36
  <template v-for="(item, index) in displayState">
37
37
  <span :key="index" v-if="item.type === 'text'" style="margin-right: 2px">{{ item.value }}</span>
38
38
  <TMagicTag :key="index" :size="size" v-if="item.type === 'var'">{{ item.value }}</TMagicTag>
39
39
  </template>
40
+
41
+ <Icon class="tmagic-data-source-input-icon" :icon="Coin" />
40
42
  </div>
41
43
  </div>
42
44
  </div>
@@ -90,7 +92,7 @@ const dataSources = computed(() => dataSourceService?.get('dataSources') || []);
90
92
  const setDisplayState = () => {
91
93
  displayState.value = [];
92
94
 
93
- const matches = state.value.matchAll(/\{\{([\s\S]+?)\}\}/g);
95
+ const matches = state.value.matchAll(/\$\{([\s\S]+?)\}/g);
94
96
  let index = 0;
95
97
  for (const match of matches) {
96
98
  if (typeof match.index === 'undefined') break;
@@ -195,7 +197,7 @@ const getSelectionStart = () => {
195
197
  * @param leftCurlyBracketIndex {字符索引
196
198
  */
197
199
  const curCharIsLeftCurlyBracket = (leftCurlyBracketIndex: number) =>
198
- leftCurlyBracketIndex > -1 && leftCurlyBracketIndex === getSelectionStart() - 1;
200
+ leftCurlyBracketIndex > 0 && leftCurlyBracketIndex === getSelectionStart() - 1;
199
201
 
200
202
  /**
201
203
  * 当前输入的是.
@@ -213,7 +215,7 @@ const dsQuerySearch = (queryString: string, leftCurlyBracketIndex: number, cb: (
213
215
  if (curCharIsLeftCurlyBracket(leftCurlyBracketIndex)) {
214
216
  // 当前输入的是{
215
217
  result = dataSources.value;
216
- } else if (leftCurlyBracketIndex > -1) {
218
+ } else if (leftCurlyBracketIndex > 0) {
217
219
  // 当前输入的是{xx
218
220
  const queryName = queryString.substring(leftCurlyBracketIndex + 1).toLowerCase();
219
221
  result = dataSources.value.filter((ds) => ds.title?.toLowerCase().includes(queryName) || ds.id.includes(queryName));
@@ -299,7 +301,7 @@ const querySearch = (queryString: string, cb: (data: { value: string }[]) => voi
299
301
  const curQueryString = queryString.substring(0, selectionStart);
300
302
 
301
303
  const fieldKeyStringLastIndex = curQueryString.lastIndexOf('.');
302
- const dsKeyStringLastIndex = curQueryString.lastIndexOf('{');
304
+ const dsKeyStringLastIndex = curQueryString.lastIndexOf('${') + 1;
303
305
 
304
306
  const isFieldTip = fieldKeyStringLastIndex > dsKeyStringLastIndex;
305
307
 
@@ -321,7 +323,7 @@ const selectHandler = async ({ value, type }: { value: string; type: 'dataSource
321
323
  let startText = inputText.substring(0, selectionStart);
322
324
 
323
325
  const dotIndex = startText.lastIndexOf('.');
324
- const leftCurlyBracketIndex = startText.lastIndexOf('{');
326
+ const leftCurlyBracketIndex = startText.lastIndexOf('${') + 1;
325
327
 
326
328
  const endText = inputText.substring(selectionStart);
327
329
 
@@ -336,7 +338,6 @@ const selectHandler = async ({ value, type }: { value: string; type: 'dataSource
336
338
  if (!isRightCurlyBracket(selectionStart + 1)) {
337
339
  suggestText = `${suggestText}}`;
338
340
  }
339
- suggestText = `{${suggestText}}`;
340
341
  } else if (!curCharIsDot(dotIndex)) {
341
342
  startText = startText.substring(0, dotIndex + 1);
342
343
  }
@@ -345,10 +346,10 @@ const selectHandler = async ({ value, type }: { value: string; type: 'dataSource
345
346
 
346
347
  await nextTick();
347
348
 
348
- // 由于选择数据源时会在后面补全}}, 所以光标要前移2位
349
+ // 由于选择数据源时会在后面补全}, 所以光标要前移2位
349
350
  let newSelectionStart = 0;
350
351
  if (isDataSource) {
351
- newSelectionStart = leftCurlyBracketIndex + suggestText.length - 1;
352
+ newSelectionStart = leftCurlyBracketIndex + suggestText.length;
352
353
  } else {
353
354
  newSelectionStart = dotIndex + suggestText.length + 1;
354
355
  }
package/src/index.ts CHANGED
@@ -62,6 +62,7 @@ export { default as ContentMenu } from './components/ContentMenu.vue';
62
62
  export { default as Icon } from './components/Icon.vue';
63
63
  export { default as LayoutContainer } from './components/SplitView.vue';
64
64
  export { default as SplitView } from './components/SplitView.vue';
65
+ export { default as Resizer } from './components/Resizer.vue';
65
66
 
66
67
  const defaultInstallOpt: InstallOptions = {
67
68
  // eslint-disable-next-line no-eval
@@ -33,7 +33,7 @@
33
33
  </slot>
34
34
  </template>
35
35
 
36
- <template v-if="pageLength > 0 && nodes.length === 1" #right>
36
+ <template v-if="pageLength > 0" #right>
37
37
  <TMagicScrollbar>
38
38
  <slot name="props-panel"></slot>
39
39
  </TMagicScrollbar>
@@ -68,7 +68,6 @@ const codeOptions = inject('codeOptions', {});
68
68
  const { editorService, uiService } = inject<Services>('services') || {};
69
69
 
70
70
  const root = computed(() => editorService?.get('root'));
71
- const nodes = computed(() => editorService?.get('nodes') || []);
72
71
 
73
72
  const pageLength = computed(() => editorService?.get('pageLength') || 0);
74
73
  const showSrc = computed(() => uiService?.get('showSrc'));
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="m-editor-props-panel">
2
+ <div class="m-editor-props-panel" v-if="nodes.length === 1">
3
3
  <slot name="props-panel-header"></slot>
4
4
  <MForm
5
5
  ref="configForm"
@@ -35,6 +35,7 @@ const configForm = ref<InstanceType<typeof MForm>>();
35
35
  const curFormConfig = ref<any>([]);
36
36
  const services = inject<Services>('services');
37
37
  const node = computed(() => services?.editorService.get('node'));
38
+ const nodes = computed(() => services?.editorService.get('nodes') || []);
38
39
  const propsPanelSize = computed(() => services?.uiService.get('propsPanelSize') || 'small');
39
40
  const stage = computed(() => services?.editorService.get('stage'));
40
41
 
@@ -22,6 +22,7 @@ const props = defineProps<{
22
22
  const services = inject<Services>('services');
23
23
  const menu = ref<InstanceType<typeof ContentMenu>>();
24
24
  const node = computed(() => services?.editorService.get('node'));
25
+ const nodes = computed(() => services?.editorService.get('nodes'));
25
26
  const isRoot = computed(() => node.value?.type === NodeType.ROOT);
26
27
  const isPage = computed(() => node.value?.type === NodeType.PAGE);
27
28
  const componentList = computed(() => services?.componentListService.getList() || []);
@@ -82,7 +83,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
82
83
  type: 'button',
83
84
  text: '新增',
84
85
  icon: markRaw(Plus),
85
- display: () => node.value?.items,
86
+ display: () => node.value?.items && nodes.value?.length === 1,
86
87
  items: getSubMenuData.value,
87
88
  },
88
89
  {
@@ -91,7 +92,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
91
92
  icon: markRaw(CopyDocument),
92
93
  display: () => !isRoot.value,
93
94
  handler: () => {
94
- node.value && services?.editorService.copy(node.value);
95
+ node.value && services?.editorService.copy(nodes.value || []);
95
96
  },
96
97
  },
97
98
  {
@@ -100,7 +101,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
100
101
  icon: markRaw(Delete),
101
102
  display: () => !isRoot.value && !isPage.value,
102
103
  handler: () => {
103
- node.value && services?.editorService.remove(node.value);
104
+ node.value && services?.editorService.remove(nodes.value || []);
104
105
  },
105
106
  },
106
107
  ...props.layerContentMenu,
@@ -350,7 +350,11 @@ const clickHandler = (data: MNode): void => {
350
350
  // 右键菜单
351
351
  const contextmenu = async (event: MouseEvent, data: MNode): Promise<void> => {
352
352
  event.preventDefault();
353
- await select(data);
353
+
354
+ if (nodes.value.length < 2) {
355
+ await select(data);
356
+ }
357
+
354
358
  menu.value?.show(event);
355
359
  };
356
360
  </script>
@@ -0,0 +1,18 @@
1
+ .tmagic-data-source-input-text {
2
+ .el-input__wrapper.tmagic-data-source-input-text-wrapper {
3
+ overflow: hidden;
4
+ padding-right: 30px;
5
+ }
6
+
7
+ .el-input__inner {
8
+ display: flex;
9
+ align-items: center;
10
+ overflow: hidden;
11
+ white-space: nowrap;
12
+ }
13
+
14
+ .tmagic-data-source-input-icon {
15
+ position: absolute;
16
+ right: 7px;
17
+ }
18
+ }
@@ -19,4 +19,5 @@
19
19
  @import "./dep-list.scss";
20
20
  @import "./data-source.scss";
21
21
  @import "./data-source-fields.scss";
22
+ @import "./data-source-input.scss";
22
23
  @import "./key-value.scss";
@@ -105,6 +105,40 @@ export const fillConfig = (config: FormConfig = []) => [
105
105
  },
106
106
  ],
107
107
  },
108
+ {
109
+ type: 'fieldset',
110
+ legend: '边框',
111
+ items: [
112
+ {
113
+ name: 'borderWidth',
114
+ text: '宽度',
115
+ defaultValue: '0',
116
+ },
117
+ {
118
+ name: 'borderColor',
119
+ text: '颜色',
120
+ type: 'colorPicker',
121
+ },
122
+ {
123
+ name: 'borderStyle',
124
+ text: '样式',
125
+ type: 'select',
126
+ defaultValue: 'none',
127
+ options: [
128
+ { text: 'none', value: 'none' },
129
+ { text: 'hidden', value: 'hidden' },
130
+ { text: 'dotted', value: 'dotted' },
131
+ { text: 'dashed', value: 'dashed' },
132
+ { text: 'solid', value: 'solid' },
133
+ { text: 'double', value: 'double' },
134
+ { text: 'groove', value: 'groove' },
135
+ { text: 'ridge', value: 'ridge' },
136
+ { text: 'inset', value: 'inset' },
137
+ { text: 'outset', value: 'outset' },
138
+ ],
139
+ },
140
+ ],
141
+ },
108
142
  {
109
143
  type: 'fieldset',
110
144
  legend: '背景',
package/types/index.d.ts CHANGED
@@ -30,6 +30,7 @@ export { default as ContentMenu } from './components/ContentMenu.vue';
30
30
  export { default as Icon } from './components/Icon.vue';
31
31
  export { default as LayoutContainer } from './components/SplitView.vue';
32
32
  export { default as SplitView } from './components/SplitView.vue';
33
+ export { default as Resizer } from './components/Resizer.vue';
33
34
  declare const _default: {
34
35
  install: (app: App, opt?: Partial<InstallOptions>) => void;
35
36
  };