@tmagic/editor 1.7.14-beta.0 → 1.7.14-beta.2
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/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +8 -8
- package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +11 -11
- package/dist/es/layouts/NavMenuColumn.js +5 -0
- package/dist/es/layouts/NavMenuColumn.vue_vue_type_script_setup_true_lang.js +201 -0
- package/dist/es/services/storage.js +5 -5
- package/dist/es/style.css +51 -0
- package/dist/es/utils/keybinding-config.js +19 -19
- package/dist/style.css +51 -0
- package/dist/tmagic-editor.umd.cjs +267 -63
- package/package.json +8 -8
- package/src/components/ToolButton.vue +7 -1
- package/src/fields/StyleSetter/Index.vue +5 -1
- package/src/layouts/CodeEditor.vue +18 -10
- package/src/layouts/NavMenu.vue +9 -4
- package/src/layouts/NavMenuColumn.vue +252 -0
- package/src/theme/nav-menu.scss +61 -0
- package/src/type.ts +42 -0
- package/src/utils/undo-redo.ts +2 -0
- package/types/index.d.ts +420 -425
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
v-if="display"
|
|
4
|
+
ref="rootEl"
|
|
4
5
|
class="menu-item"
|
|
5
6
|
:class="`${data.type} ${data.className || ''}`"
|
|
6
7
|
@click="clickHandler(data, $event)"
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
</template>
|
|
57
58
|
|
|
58
59
|
<script lang="ts" setup>
|
|
59
|
-
import { computed } from 'vue';
|
|
60
|
+
import { computed, useTemplateRef } from 'vue';
|
|
60
61
|
import { ArrowDown } from '@element-plus/icons-vue';
|
|
61
62
|
|
|
62
63
|
import {
|
|
@@ -93,6 +94,9 @@ const props = withDefaults(
|
|
|
93
94
|
);
|
|
94
95
|
const services = useServices();
|
|
95
96
|
|
|
97
|
+
const rootElRef = useTemplateRef<HTMLDivElement>('rootEl');
|
|
98
|
+
const getElRef = () => rootElRef;
|
|
99
|
+
|
|
96
100
|
const disabled = computed(() => {
|
|
97
101
|
if (typeof props.data === 'string') return false;
|
|
98
102
|
if (props.data.type === 'component') return false;
|
|
@@ -145,4 +149,6 @@ const mouseupHandler = (item: MenuButton | MenuComponent, event: MouseEvent) =>
|
|
|
145
149
|
buttonHandler(item, event);
|
|
146
150
|
}
|
|
147
151
|
};
|
|
152
|
+
|
|
153
|
+
defineExpose({ getElRef });
|
|
148
154
|
</script>
|
|
@@ -74,7 +74,11 @@ const collapseValue = shallowRef(
|
|
|
74
74
|
|
|
75
75
|
const change = (v: any, eventData: ContainerChangeEventData) => {
|
|
76
76
|
eventData.changeRecords?.forEach((record) => {
|
|
77
|
-
|
|
77
|
+
if (props.prop) {
|
|
78
|
+
record.propPath = `${props.prop}.${record.propPath}`;
|
|
79
|
+
} else if (props.name) {
|
|
80
|
+
record.propPath = `${props.name}.${record.propPath}`;
|
|
81
|
+
}
|
|
78
82
|
});
|
|
79
83
|
emit('change', v, eventData);
|
|
80
84
|
};
|
|
@@ -214,24 +214,32 @@ const setEditorValue = (v: string | any, m: string | any) => {
|
|
|
214
214
|
if (props.type === 'diff') {
|
|
215
215
|
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
|
|
216
216
|
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
|
|
217
|
-
|
|
217
|
+
// 保存视图状态(光标、选区、滚动、折叠等)
|
|
218
|
+
const viewState = vsDiffEditor?.saveViewState();
|
|
218
219
|
const result = vsDiffEditor?.setModel({
|
|
219
220
|
original: originalModel,
|
|
220
221
|
modified: modifiedModel,
|
|
221
222
|
});
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
223
|
+
// setAutoHeight 内部会在 nextTick 中将 scrollTop 重置为 0,这里也放到 nextTick 中
|
|
224
|
+
// 利用 Vue nextTick 队列的 FIFO 特性,保证恢复在重置之后执行
|
|
225
|
+
if (viewState) {
|
|
226
|
+
nextTick(() => {
|
|
227
|
+
vsDiffEditor?.restoreViewState(viewState);
|
|
228
|
+
vsDiffEditor?.focus();
|
|
229
|
+
});
|
|
225
230
|
}
|
|
226
231
|
return result;
|
|
227
232
|
}
|
|
228
|
-
//
|
|
229
|
-
const
|
|
233
|
+
// 保存视图状态(光标、选区、滚动、折叠等)
|
|
234
|
+
const viewState = vsEditor?.saveViewState();
|
|
230
235
|
const result = vsEditor?.setValue(values.value);
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
// setAutoHeight 内部会在 nextTick 中将 scrollTop 重置为 0,这里也放到 nextTick 中
|
|
237
|
+
// 利用 Vue nextTick 队列的 FIFO 特性,保证恢复在重置之后执行
|
|
238
|
+
if (viewState) {
|
|
239
|
+
nextTick(() => {
|
|
240
|
+
vsEditor?.restoreViewState(viewState);
|
|
241
|
+
vsEditor?.focus();
|
|
242
|
+
});
|
|
235
243
|
}
|
|
236
244
|
return result;
|
|
237
245
|
};
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-nav-menu" :style="{ height: `${height}px` }" ref="navMenu">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
<NavMenuColumn
|
|
4
|
+
v-for="key in keys"
|
|
5
|
+
:key="key"
|
|
6
|
+
:column-key="key"
|
|
7
|
+
:items="buttons[key]"
|
|
8
|
+
:width="columnWidth?.[key]"
|
|
9
|
+
></NavMenuColumn>
|
|
6
10
|
</div>
|
|
7
11
|
</template>
|
|
8
12
|
|
|
@@ -12,10 +16,11 @@ import { Back, Delete, FullScreen, Grid, Memo, Right, ScaleToOriginal, ZoomIn, Z
|
|
|
12
16
|
|
|
13
17
|
import { NodeType } from '@tmagic/core';
|
|
14
18
|
|
|
15
|
-
import ToolButton from '@editor/components/ToolButton.vue';
|
|
16
19
|
import { useServices } from '@editor/hooks/use-services';
|
|
17
20
|
import { ColumnLayout, MenuBarData, MenuButton, MenuComponent, MenuItem } from '@editor/type';
|
|
18
21
|
|
|
22
|
+
import NavMenuColumn from './NavMenuColumn.vue';
|
|
23
|
+
|
|
19
24
|
defineOptions({
|
|
20
25
|
name: 'MEditorNavMenu',
|
|
21
26
|
});
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="`menu-${columnKey} m-editor-nav-menu-column`"
|
|
4
|
+
:style="width != null ? `width: ${width}px` : ''"
|
|
5
|
+
ref="columnEl"
|
|
6
|
+
>
|
|
7
|
+
<ToolButton
|
|
8
|
+
v-for="(item, index) in items"
|
|
9
|
+
:data="item"
|
|
10
|
+
:key="`item-${index}`"
|
|
11
|
+
:class="{ 'm-editor-nav-menu-slot-hidden': hiddenIndexSet.has(index) }"
|
|
12
|
+
:ref="(comp: any) => setItemRef(comp, index)"
|
|
13
|
+
></ToolButton>
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
class="m-editor-nav-menu-more-wrapper"
|
|
17
|
+
:class="{ 'm-editor-nav-menu-more-wrapper-hidden': !hasOverflow }"
|
|
18
|
+
ref="moreWrapperEl"
|
|
19
|
+
>
|
|
20
|
+
<TMagicPopover
|
|
21
|
+
placement="bottom-end"
|
|
22
|
+
popper-class="m-editor-nav-menu-popover"
|
|
23
|
+
:width="popoverWidth"
|
|
24
|
+
:visible="popoverVisible"
|
|
25
|
+
>
|
|
26
|
+
<div class="m-editor-nav-menu-overflow-list">
|
|
27
|
+
<ToolButton v-for="(item, index) in overflowItems" :data="item" :key="`o-${index}`"></ToolButton>
|
|
28
|
+
</div>
|
|
29
|
+
<template #reference>
|
|
30
|
+
<div class="menu-item button m-editor-nav-menu-more" ref="referenceEl" @click="togglePopover">
|
|
31
|
+
<TMagicButton
|
|
32
|
+
size="small"
|
|
33
|
+
text
|
|
34
|
+
:icon="popoverVisible ? ArrowUp : ArrowDown"
|
|
35
|
+
:bg="popoverVisible"
|
|
36
|
+
:type="popoverVisible ? 'primary' : ''"
|
|
37
|
+
></TMagicButton>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
</TMagicPopover>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script lang="ts" setup>
|
|
46
|
+
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
|
47
|
+
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
|
|
48
|
+
|
|
49
|
+
import { TMagicButton, TMagicPopover } from '@tmagic/design';
|
|
50
|
+
|
|
51
|
+
import ToolButton from '@editor/components/ToolButton.vue';
|
|
52
|
+
import { MenuButton, MenuComponent } from '@editor/type';
|
|
53
|
+
|
|
54
|
+
defineOptions({
|
|
55
|
+
name: 'MEditorNavMenuColumn',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const props = withDefaults(
|
|
59
|
+
defineProps<{
|
|
60
|
+
columnKey: string;
|
|
61
|
+
items: (MenuButton | MenuComponent)[];
|
|
62
|
+
width?: number;
|
|
63
|
+
/** 子元素之间的间距,需与 SCSS gap 保持一致 */
|
|
64
|
+
gap?: number;
|
|
65
|
+
/** Popover 内容宽度 */
|
|
66
|
+
popoverWidth?: number;
|
|
67
|
+
}>(),
|
|
68
|
+
{
|
|
69
|
+
items: () => [],
|
|
70
|
+
gap: 3,
|
|
71
|
+
popoverWidth: 180,
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const columnEl = useTemplateRef<HTMLDivElement>('columnEl');
|
|
76
|
+
const moreWrapperEl = useTemplateRef<HTMLDivElement>('moreWrapperEl');
|
|
77
|
+
|
|
78
|
+
const popoverVisible = ref(false);
|
|
79
|
+
const togglePopover = () => {
|
|
80
|
+
popoverVisible.value = !popoverVisible.value;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const itemInstances = ref<(InstanceType<typeof ToolButton> | null)[]>([]);
|
|
84
|
+
let slotsRO: ResizeObserver | undefined;
|
|
85
|
+
const observedEls = new Set<HTMLElement>();
|
|
86
|
+
|
|
87
|
+
const setItemRef = (inst: InstanceType<typeof ToolButton> | null, index: number) => {
|
|
88
|
+
itemInstances.value[index] = inst ?? null;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const itemEls = computed<(HTMLElement | null)[]>(() =>
|
|
92
|
+
itemInstances.value.map((inst) => inst?.getElRef?.().value ?? null),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const reobserveSlots = () => {
|
|
96
|
+
if (!slotsRO) return;
|
|
97
|
+
for (const el of observedEls) slotsRO.unobserve(el);
|
|
98
|
+
observedEls.clear();
|
|
99
|
+
for (const el of itemEls.value) {
|
|
100
|
+
if (el) {
|
|
101
|
+
slotsRO.observe(el);
|
|
102
|
+
observedEls.add(el);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const cachedWidths = ref<Map<number, number>>(new Map());
|
|
108
|
+
const moreWidth = ref(0);
|
|
109
|
+
const containerWidth = ref(0);
|
|
110
|
+
const hiddenIndexSet = ref<Set<number>>(new Set());
|
|
111
|
+
|
|
112
|
+
const hasOverflow = computed(() => hiddenIndexSet.value.size > 0);
|
|
113
|
+
const overflowItems = computed(() => props.items.filter((_, index) => hiddenIndexSet.value.has(index)));
|
|
114
|
+
|
|
115
|
+
const measureAndCompute = () => {
|
|
116
|
+
if (!columnEl.value) return;
|
|
117
|
+
|
|
118
|
+
containerWidth.value = columnEl.value.clientWidth;
|
|
119
|
+
|
|
120
|
+
const els = itemEls.value;
|
|
121
|
+
for (let i = 0; i < props.items.length; i++) {
|
|
122
|
+
const el = els[i];
|
|
123
|
+
if (!el) {
|
|
124
|
+
cachedWidths.value.delete(i);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const w = el.getBoundingClientRect().width;
|
|
128
|
+
if (w > 0) {
|
|
129
|
+
cachedWidths.value.set(i, w);
|
|
130
|
+
} else {
|
|
131
|
+
cachedWidths.value.delete(i);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (moreWrapperEl.value) {
|
|
136
|
+
const w = moreWrapperEl.value.getBoundingClientRect().width;
|
|
137
|
+
if (w > 0) moreWidth.value = w;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const total = props.items.length;
|
|
141
|
+
if (total === 0 || containerWidth.value <= 0) {
|
|
142
|
+
if (hiddenIndexSet.value.size > 0) hiddenIndexSet.value = new Set();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let fullSum = 0;
|
|
147
|
+
let positive = 0;
|
|
148
|
+
for (let i = 0; i < total; i++) {
|
|
149
|
+
const w = cachedWidths.value.get(i) ?? 0;
|
|
150
|
+
if (w > 0) {
|
|
151
|
+
fullSum += w;
|
|
152
|
+
positive += 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
fullSum += props.gap * Math.max(0, positive - 1);
|
|
156
|
+
|
|
157
|
+
// more 按钮位置始终保留,参与"是否放得下"的判断,避免出现时再次挤压
|
|
158
|
+
const effectiveMoreWidth = moreWidth.value > 0 ? moreWidth.value : 32;
|
|
159
|
+
const reservedMore = effectiveMoreWidth + (positive > 0 ? props.gap : 0);
|
|
160
|
+
|
|
161
|
+
let nextHidden: Set<number> | null = null;
|
|
162
|
+
if (fullSum + reservedMore <= containerWidth.value + 0.5) {
|
|
163
|
+
if (hiddenIndexSet.value.size > 0) nextHidden = new Set();
|
|
164
|
+
} else {
|
|
165
|
+
const newHidden = new Set<number>();
|
|
166
|
+
let used = effectiveMoreWidth;
|
|
167
|
+
let cutoff = -1;
|
|
168
|
+
for (let i = 0; i < total; i++) {
|
|
169
|
+
const w = cachedWidths.value.get(i) ?? 0;
|
|
170
|
+
if (w === 0) continue;
|
|
171
|
+
const need = props.gap + w;
|
|
172
|
+
if (used + need > containerWidth.value) {
|
|
173
|
+
cutoff = i;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
used += need;
|
|
177
|
+
}
|
|
178
|
+
if (cutoff >= 0) {
|
|
179
|
+
for (let j = cutoff; j < total; j++) newHidden.add(j);
|
|
180
|
+
}
|
|
181
|
+
nextHidden = newHidden;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (nextHidden) {
|
|
185
|
+
const same =
|
|
186
|
+
nextHidden.size === hiddenIndexSet.value.size && [...nextHidden].every((v) => hiddenIndexSet.value.has(v));
|
|
187
|
+
if (!same) hiddenIndexSet.value = nextHidden;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
let raf = 0;
|
|
192
|
+
const scheduleMeasure = () => {
|
|
193
|
+
if (raf) cancelAnimationFrame(raf);
|
|
194
|
+
raf = requestAnimationFrame(() => {
|
|
195
|
+
raf = 0;
|
|
196
|
+
measureAndCompute();
|
|
197
|
+
if (hasOverflow.value && moreWidth.value === 0) {
|
|
198
|
+
raf = requestAnimationFrame(() => {
|
|
199
|
+
raf = 0;
|
|
200
|
+
measureAndCompute();
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
watch(hasOverflow, (value) => {
|
|
207
|
+
if (!value) popoverVisible.value = false;
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
watch(
|
|
211
|
+
() => props.items,
|
|
212
|
+
() => {
|
|
213
|
+
cachedWidths.value = new Map();
|
|
214
|
+
hiddenIndexSet.value = new Set();
|
|
215
|
+
},
|
|
216
|
+
{ deep: true },
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
watch(itemEls, () => {
|
|
220
|
+
cachedWidths.value = new Map();
|
|
221
|
+
reobserveSlots();
|
|
222
|
+
scheduleMeasure();
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
watch(
|
|
226
|
+
() => props.width,
|
|
227
|
+
() => scheduleMeasure(),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
let ro: ResizeObserver | undefined;
|
|
231
|
+
|
|
232
|
+
onMounted(() => {
|
|
233
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
234
|
+
if (columnEl.value) {
|
|
235
|
+
ro = new ResizeObserver(() => scheduleMeasure());
|
|
236
|
+
ro.observe(columnEl.value);
|
|
237
|
+
}
|
|
238
|
+
slotsRO = new ResizeObserver(() => scheduleMeasure());
|
|
239
|
+
reobserveSlots();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
scheduleMeasure();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
onBeforeUnmount(() => {
|
|
246
|
+
if (raf) cancelAnimationFrame(raf);
|
|
247
|
+
ro?.disconnect();
|
|
248
|
+
slotsRO?.disconnect();
|
|
249
|
+
slotsRO = undefined;
|
|
250
|
+
observedEls.clear();
|
|
251
|
+
});
|
|
252
|
+
</script>
|
package/src/theme/nav-menu.scss
CHANGED
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
z-index: 1;
|
|
24
24
|
align-items: center;
|
|
25
|
+
flex-wrap: nowrap;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
position: relative;
|
|
28
|
+
min-width: 0;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
.menu-center {
|
|
@@ -32,8 +36,33 @@
|
|
|
32
36
|
justify-content: flex-end;
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
.m-editor-nav-menu-slot-hidden {
|
|
40
|
+
position: absolute;
|
|
41
|
+
left: -99999px;
|
|
42
|
+
top: 0;
|
|
43
|
+
visibility: hidden;
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.m-editor-nav-menu-more-wrapper {
|
|
48
|
+
flex: 0 0 auto;
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
height: 100%;
|
|
52
|
+
|
|
53
|
+
&.m-editor-nav-menu-more-wrapper-hidden {
|
|
54
|
+
visibility: hidden;
|
|
55
|
+
pointer-events: none;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.m-editor-nav-menu-more {
|
|
60
|
+
flex: 0 0 auto;
|
|
61
|
+
}
|
|
62
|
+
|
|
35
63
|
.menu-item {
|
|
36
64
|
flex-direction: row;
|
|
65
|
+
flex: 0 0 auto;
|
|
37
66
|
-webkit-box-align: center;
|
|
38
67
|
align-items: center;
|
|
39
68
|
vertical-align: middle;
|
|
@@ -47,6 +76,7 @@
|
|
|
47
76
|
transition: all 0.3s ease 0s;
|
|
48
77
|
border-bottom: 2px solid transparent;
|
|
49
78
|
margin: 0;
|
|
79
|
+
white-space: nowrap;
|
|
50
80
|
|
|
51
81
|
.is-disabled {
|
|
52
82
|
opacity: 0.5;
|
|
@@ -70,6 +100,7 @@
|
|
|
70
100
|
|
|
71
101
|
.menu-item-text {
|
|
72
102
|
color: $nav-color;
|
|
103
|
+
white-space: nowrap;
|
|
73
104
|
}
|
|
74
105
|
|
|
75
106
|
&.rule {
|
|
@@ -84,3 +115,33 @@
|
|
|
84
115
|
}
|
|
85
116
|
}
|
|
86
117
|
}
|
|
118
|
+
|
|
119
|
+
.m-editor-nav-menu-popover {
|
|
120
|
+
.m-editor-nav-menu-overflow-list {
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-direction: column;
|
|
123
|
+
gap: 4px;
|
|
124
|
+
padding: 4px 0;
|
|
125
|
+
|
|
126
|
+
.menu-item {
|
|
127
|
+
display: flex;
|
|
128
|
+
align-items: center;
|
|
129
|
+
padding: 4px 8px;
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
border-radius: 4px;
|
|
132
|
+
|
|
133
|
+
&:hover {
|
|
134
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
&.divider {
|
|
138
|
+
padding: 0;
|
|
139
|
+
cursor: default;
|
|
140
|
+
|
|
141
|
+
&:hover {
|
|
142
|
+
background-color: transparent;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
package/src/type.ts
CHANGED
|
@@ -143,6 +143,7 @@ export interface EditorInstallOptions {
|
|
|
143
143
|
[key: string]: any;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
// #region Services
|
|
146
147
|
export interface Services {
|
|
147
148
|
editorService: EditorService;
|
|
148
149
|
historyService: HistoryService;
|
|
@@ -157,6 +158,7 @@ export interface Services {
|
|
|
157
158
|
keybindingService: KeybindingService;
|
|
158
159
|
stageOverlayService: StageOverlayService;
|
|
159
160
|
}
|
|
161
|
+
// #endregion Services
|
|
160
162
|
|
|
161
163
|
export interface StageOptions {
|
|
162
164
|
runtimeUrl?: string;
|
|
@@ -236,11 +238,13 @@ export interface ComponentGroupState {
|
|
|
236
238
|
list: ComponentGroup[];
|
|
237
239
|
}
|
|
238
240
|
|
|
241
|
+
// #region ColumnLayout
|
|
239
242
|
export enum ColumnLayout {
|
|
240
243
|
LEFT = 'left',
|
|
241
244
|
CENTER = 'center',
|
|
242
245
|
RIGHT = 'right',
|
|
243
246
|
}
|
|
247
|
+
// #endregion ColumnLayout
|
|
244
248
|
|
|
245
249
|
export interface SetColumnWidth {
|
|
246
250
|
[ColumnLayout.LEFT]?: number;
|
|
@@ -309,11 +313,13 @@ export interface UiState {
|
|
|
309
313
|
};
|
|
310
314
|
}
|
|
311
315
|
|
|
316
|
+
// #region EditorNodeInfo
|
|
312
317
|
export interface EditorNodeInfo {
|
|
313
318
|
node: MNode | null;
|
|
314
319
|
parent: MContainer | null;
|
|
315
320
|
page: MPage | MPageFragment | null;
|
|
316
321
|
}
|
|
322
|
+
// #endregion EditorNodeInfo
|
|
317
323
|
|
|
318
324
|
export interface AddMNode {
|
|
319
325
|
type: string;
|
|
@@ -322,6 +328,7 @@ export interface AddMNode {
|
|
|
322
328
|
[key: string]: any;
|
|
323
329
|
}
|
|
324
330
|
|
|
331
|
+
// #region PastePosition
|
|
325
332
|
export interface PastePosition {
|
|
326
333
|
left?: number;
|
|
327
334
|
top?: number;
|
|
@@ -334,7 +341,9 @@ export interface PastePosition {
|
|
|
334
341
|
*/
|
|
335
342
|
offsetY?: number;
|
|
336
343
|
}
|
|
344
|
+
// #endregion PastePosition
|
|
337
345
|
|
|
346
|
+
// #region MenuButton
|
|
338
347
|
/**
|
|
339
348
|
* 菜单按钮
|
|
340
349
|
*/
|
|
@@ -367,7 +376,9 @@ export interface MenuButton {
|
|
|
367
376
|
/** 唯一标识,用于高亮 */
|
|
368
377
|
id?: string | number;
|
|
369
378
|
}
|
|
379
|
+
// #endregion MenuButton
|
|
370
380
|
|
|
381
|
+
// #region MenuComponent
|
|
371
382
|
export interface MenuComponent {
|
|
372
383
|
type: 'component';
|
|
373
384
|
/** Vue3组件 */
|
|
@@ -382,6 +393,7 @@ export interface MenuComponent {
|
|
|
382
393
|
display?: boolean | ((data: Services) => Promise<boolean> | boolean);
|
|
383
394
|
[key: string]: any;
|
|
384
395
|
}
|
|
396
|
+
// #endregion MenuComponent
|
|
385
397
|
|
|
386
398
|
/**
|
|
387
399
|
* '/': 分隔符
|
|
@@ -396,6 +408,7 @@ export interface MenuComponent {
|
|
|
396
408
|
* 'scale-to-original': 缩放到实际大小
|
|
397
409
|
* 'scale-to-fit': 缩放以适应
|
|
398
410
|
*/
|
|
411
|
+
// #region MenuItem
|
|
399
412
|
export type MenuItem =
|
|
400
413
|
| '/'
|
|
401
414
|
| 'delete'
|
|
@@ -411,7 +424,9 @@ export type MenuItem =
|
|
|
411
424
|
| MenuButton
|
|
412
425
|
| MenuComponent
|
|
413
426
|
| string;
|
|
427
|
+
// #endregion MenuItem
|
|
414
428
|
|
|
429
|
+
// #region MenuBarData
|
|
415
430
|
/** 工具栏 */
|
|
416
431
|
export interface MenuBarData {
|
|
417
432
|
/** 顶部工具栏左边项 */
|
|
@@ -421,7 +436,9 @@ export interface MenuBarData {
|
|
|
421
436
|
/** 顶部工具栏右边项 */
|
|
422
437
|
[ColumnLayout.RIGHT]?: MenuItem[];
|
|
423
438
|
}
|
|
439
|
+
// #endregion MenuBarData
|
|
424
440
|
|
|
441
|
+
// #region SideComponent
|
|
425
442
|
export interface SideComponent extends MenuComponent {
|
|
426
443
|
/** 显示文案 */
|
|
427
444
|
text: string;
|
|
@@ -444,21 +461,27 @@ export interface SideComponent extends MenuComponent {
|
|
|
444
461
|
props?: Record<string, any>;
|
|
445
462
|
};
|
|
446
463
|
}
|
|
464
|
+
// #endregion SideComponent
|
|
447
465
|
|
|
466
|
+
// #region SideItemKey
|
|
448
467
|
export enum SideItemKey {
|
|
449
468
|
COMPONENT_LIST = 'component-list',
|
|
450
469
|
LAYER = 'layer',
|
|
451
470
|
CODE_BLOCK = 'code-block',
|
|
452
471
|
DATA_SOURCE = 'data-source',
|
|
453
472
|
}
|
|
473
|
+
// #endregion SideItemKey
|
|
454
474
|
|
|
475
|
+
// #region SideItem
|
|
455
476
|
/**
|
|
456
477
|
* component-list: 组件列表
|
|
457
478
|
* layer: 已选组件树
|
|
458
479
|
* code-block: 代码块
|
|
459
480
|
*/
|
|
460
481
|
export type SideItem = `${SideItemKey}` | SideComponent;
|
|
482
|
+
// #endregion SideItem
|
|
461
483
|
|
|
484
|
+
// #region SideBarData
|
|
462
485
|
/** 工具栏 */
|
|
463
486
|
export interface SideBarData {
|
|
464
487
|
/** 容器类型 */
|
|
@@ -468,7 +491,9 @@ export interface SideBarData {
|
|
|
468
491
|
/** panel列表 */
|
|
469
492
|
items: SideItem[];
|
|
470
493
|
}
|
|
494
|
+
// #endregion SideBarData
|
|
471
495
|
|
|
496
|
+
// #region ComponentItem
|
|
472
497
|
export interface ComponentItem {
|
|
473
498
|
/** 显示文案 */
|
|
474
499
|
text: string;
|
|
@@ -483,19 +508,23 @@ export interface ComponentItem {
|
|
|
483
508
|
[key: string]: any;
|
|
484
509
|
};
|
|
485
510
|
}
|
|
511
|
+
// #endregion ComponentItem
|
|
486
512
|
|
|
513
|
+
// #region ComponentGroup
|
|
487
514
|
export interface ComponentGroup {
|
|
488
515
|
/** 显示文案 */
|
|
489
516
|
title: string;
|
|
490
517
|
/** 组内列表 */
|
|
491
518
|
items: ComponentItem[];
|
|
492
519
|
}
|
|
520
|
+
// #endregion ComponentGroup
|
|
493
521
|
|
|
494
522
|
export enum LayerOffset {
|
|
495
523
|
TOP = 'top',
|
|
496
524
|
BOTTOM = 'bottom',
|
|
497
525
|
}
|
|
498
526
|
|
|
527
|
+
// #region Layout
|
|
499
528
|
/** 容器布局 */
|
|
500
529
|
export enum Layout {
|
|
501
530
|
FLEX = 'flex',
|
|
@@ -503,6 +532,7 @@ export enum Layout {
|
|
|
503
532
|
RELATIVE = 'relative',
|
|
504
533
|
ABSOLUTE = 'absolute',
|
|
505
534
|
}
|
|
535
|
+
// #endregion Layout
|
|
506
536
|
|
|
507
537
|
export enum Keys {
|
|
508
538
|
ESCAPE = 'Space',
|
|
@@ -575,8 +605,11 @@ export interface CodeParamStatement {
|
|
|
575
605
|
[key: string]: any;
|
|
576
606
|
}
|
|
577
607
|
|
|
608
|
+
// #region HistoryOpType
|
|
578
609
|
export type HistoryOpType = 'add' | 'remove' | 'update';
|
|
610
|
+
// #endregion HistoryOpType
|
|
579
611
|
|
|
612
|
+
// #region StepValue
|
|
580
613
|
export interface StepValue {
|
|
581
614
|
/** 页面信息 */
|
|
582
615
|
data: { name: string; id: Id };
|
|
@@ -597,6 +630,7 @@ export interface StepValue {
|
|
|
597
630
|
/** opType 'update': 变更前后的节点快照 */
|
|
598
631
|
updatedItems?: { oldNode: MNode; newNode: MNode }[];
|
|
599
632
|
}
|
|
633
|
+
// #endregion StepValue
|
|
600
634
|
|
|
601
635
|
export interface HistoryState {
|
|
602
636
|
pageId?: Id;
|
|
@@ -660,6 +694,7 @@ export interface KeyBindingCacheItem {
|
|
|
660
694
|
bound: boolean;
|
|
661
695
|
}
|
|
662
696
|
|
|
697
|
+
// #region DatasourceTypeOption
|
|
663
698
|
/** 可新增的数据源类型选项 */
|
|
664
699
|
export interface DatasourceTypeOption {
|
|
665
700
|
/** 数据源类型 */
|
|
@@ -667,6 +702,7 @@ export interface DatasourceTypeOption {
|
|
|
667
702
|
/** 数据源名称 */
|
|
668
703
|
text: string;
|
|
669
704
|
}
|
|
705
|
+
// #endregion DatasourceTypeOption
|
|
670
706
|
|
|
671
707
|
/** 组件树节点状态 */
|
|
672
708
|
export interface LayerNodeStatus {
|
|
@@ -688,12 +724,14 @@ export enum DragType {
|
|
|
688
724
|
LAYER_TREE = 'layer-tree',
|
|
689
725
|
}
|
|
690
726
|
|
|
727
|
+
// #region TreeNodeData
|
|
691
728
|
export interface TreeNodeData {
|
|
692
729
|
id: Id;
|
|
693
730
|
name?: string;
|
|
694
731
|
items?: TreeNodeData[];
|
|
695
732
|
[key: string]: any;
|
|
696
733
|
}
|
|
734
|
+
// #endregion TreeNodeData
|
|
697
735
|
|
|
698
736
|
/** 判断组件树节点是否可展开(即是否要展示为拥有子节点的形态)的函数 */
|
|
699
737
|
export type IsExpandableFunction = (_data: TreeNodeData, _nodeStatusMap: Map<Id, LayerNodeStatus>) => boolean;
|
|
@@ -775,9 +813,12 @@ export interface EventBus extends EventEmitter {
|
|
|
775
813
|
emit<Name extends keyof EventBusEvent, Param extends EventBusEvent[Name]>(eventName: Name, ...args: Param): boolean;
|
|
776
814
|
}
|
|
777
815
|
|
|
816
|
+
// #region PropsFormConfigFunction
|
|
778
817
|
export type PropsFormConfigFunction = (data: { editorService: EditorService }) => FormConfig;
|
|
818
|
+
// #endregion PropsFormConfigFunction
|
|
779
819
|
export type PropsFormValueFunction = (data: { editorService: EditorService }) => Partial<MNode>;
|
|
780
820
|
|
|
821
|
+
// #region PageBarSortOptions
|
|
781
822
|
export type PartSortableOptions = Omit<Options, 'onStart' | 'onUpdate'>;
|
|
782
823
|
export interface PageBarSortOptions extends PartSortableOptions {
|
|
783
824
|
/** 在onUpdate之后调用 */
|
|
@@ -785,6 +826,7 @@ export interface PageBarSortOptions extends PartSortableOptions {
|
|
|
785
826
|
/** 在onStart之前调用 */
|
|
786
827
|
beforeStart?: (event: SortableEvent, sortable: Sortable) => void | Promise<void>;
|
|
787
828
|
}
|
|
829
|
+
// #endregion PageBarSortOptions
|
|
788
830
|
|
|
789
831
|
export type CustomContentMenuFunction = (
|
|
790
832
|
menus: (MenuButton | MenuComponent)[],
|