starfish-editor-custom 1.0.0
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/auto-imports.d.ts +10 -0
- package/babel.config.js +8 -0
- package/components.d.ts +46 -0
- package/dist/ConditionModule.js +892 -0
- package/dist/ConditionSelect.js +483 -0
- package/dist/CustomDialog.js +105 -0
- package/dist/formStyle.js +245 -0
- package/dist/globalFormList.js +59 -0
- package/dist/jsonCode.js +74 -0
- package/dist/jsonEditor.js +71 -0
- package/dist/main.js +3319 -0
- package/dist/starfish-editor.es.js +30 -0
- package/dist/style.css +1 -0
- package/dist/types/editor/src/common/ConditionSelect/ConditionGroup.vue.d.ts +61 -0
- package/dist/types/editor/src/common/ConditionSelect/ConditionModule.vue.d.ts +43 -0
- package/dist/types/editor/src/common/ConditionSelect/ConditionTanc.vue.d.ts +48 -0
- package/dist/types/editor/src/common/ConditionSelect.vue.d.ts +72 -0
- package/dist/types/editor/src/common/CustomDialog.vue.d.ts +25 -0
- package/dist/types/editor/src/common/Loading.vue.d.ts +3 -0
- package/dist/types/editor/src/common/formJson.d.ts +80 -0
- package/dist/types/editor/src/common/jsonCode.vue.d.ts +110 -0
- package/dist/types/editor/src/components/ComponentList.vue.d.ts +32 -0
- package/dist/types/editor/src/components/FormPreview.vue.d.ts +25 -0
- package/dist/types/editor/src/components/Nav.vue.d.ts +9 -0
- package/dist/types/editor/src/components/PropsPanel.vue.d.ts +53 -0
- package/dist/types/editor/src/components/Shape.vue.d.ts +40 -0
- package/dist/types/editor/src/components/Workspace.vue.d.ts +22 -0
- package/dist/types/editor/src/components/globalFormList.vue.d.ts +6 -0
- package/dist/types/editor/src/components/jsonEditor.vue.d.ts +6 -0
- package/dist/types/editor/src/controller/action.d.ts +18 -0
- package/dist/types/editor/src/controller/form.d.ts +24 -0
- package/dist/types/editor/src/controller/history.d.ts +12 -0
- package/dist/types/editor/src/controller/shortcut.d.ts +20 -0
- package/dist/types/editor/src/controller/ui.d.ts +10 -0
- package/dist/types/editor/src/layouts/ControlEditSize.vue.d.ts +17 -0
- package/dist/types/editor/src/layouts/Framework.vue.d.ts +33 -0
- package/dist/types/editor/src/layouts/Resizer.vue.d.ts +13 -0
- package/dist/types/editor/src/layouts/ShortcutKey.vue.d.ts +8 -0
- package/dist/types/editor/src/main.d.ts +5 -0
- package/dist/types/editor/src/shims-vue.d.ts +23 -0
- package/dist/types/editor/src/starfish-editor.vue.d.ts +109 -0
- package/dist/types/editor/src/type.d.ts +224 -0
- package/dist/types/editor/src/utils/_.d.ts +33 -0
- package/dist/types/editor/src/utils/formKeycon.d.ts +18 -0
- package/dist/types/editor/src/utils/shortcutKey.d.ts +3 -0
- package/dist/types/editor/src/utils/vm.d.ts +3 -0
- package/dist/types/starfish-editor.d.ts +3 -0
- package/package.json +55 -0
- package/src/common/ConditionSelect/ConditionGroup.vue +167 -0
- package/src/common/ConditionSelect/ConditionModule.vue +118 -0
- package/src/common/ConditionSelect/ConditionTanc.vue +319 -0
- package/src/common/ConditionSelect.vue +268 -0
- package/src/common/CustomDialog.vue +77 -0
- package/src/common/Loading.vue +10 -0
- package/src/common/formJson.ts +143 -0
- package/src/common/formStyle.vue +170 -0
- package/src/common/jsonCode.vue +45 -0
- package/src/components/ComponentList.vue +156 -0
- package/src/components/FormPreview.vue +197 -0
- package/src/components/Nav.vue +128 -0
- package/src/components/NavList.vue +560 -0
- package/src/components/PropsPanel.vue +376 -0
- package/src/components/Shape.vue +178 -0
- package/src/components/Workspace.vue +258 -0
- package/src/components/globalFormList.vue +30 -0
- package/src/components/jsonEditor.vue +41 -0
- package/src/controller/action.ts +37 -0
- package/src/controller/form.ts +207 -0
- package/src/controller/history.ts +57 -0
- package/src/controller/shortcut.ts +81 -0
- package/src/controller/ui.ts +91 -0
- package/src/layouts/ControlEditSize.vue +52 -0
- package/src/layouts/Framework.vue +76 -0
- package/src/layouts/Resizer.vue +54 -0
- package/src/layouts/ShortcutKey.vue +61 -0
- package/src/main.ts +56 -0
- package/src/shims-vue.d.ts +23 -0
- package/src/starfish-editor.vue +176 -0
- package/src/styles/common/normalize.css +455 -0
- package/src/styles/component-list.scss +64 -0
- package/src/styles/condition-select.scss +176 -0
- package/src/styles/control_edit_size.scss +36 -0
- package/src/styles/custom-dialog.scss +110 -0
- package/src/styles/form-preview.scss +47 -0
- package/src/styles/framework.scss +150 -0
- package/src/styles/iconfont/iconfont.css +247 -0
- package/src/styles/iconfont/iconfont.js +1 -0
- package/src/styles/iconfont/iconfont.json +415 -0
- package/src/styles/iconfont/iconfont.ttf +0 -0
- package/src/styles/iconfont/iconfont.woff +0 -0
- package/src/styles/iconfont/iconfont.woff2 +0 -0
- package/src/styles/index.scss +18 -0
- package/src/styles/nav-list.scss +59 -0
- package/src/styles/nav.scss +46 -0
- package/src/styles/props-panel.scss +115 -0
- package/src/styles/resizer.scss +15 -0
- package/src/styles/shape.scss +101 -0
- package/src/styles/shortcutkey.scss +44 -0
- package/src/styles/variables.scss +36 -0
- package/src/styles/work-space.scss +126 -0
- package/src/type.ts +240 -0
- package/src/utils/_.ts +349 -0
- package/src/utils/formKeycon.ts +42 -0
- package/src/utils/shortcutKey.ts +46 -0
- package/src/utils/vm.ts +3 -0
- package/stats.html +4949 -0
- package/tsconfig.json +19 -0
- package/vite.config.ts +111 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// import { createStore } from "vuex";
|
|
2
|
+
import { reactive } from "vue";
|
|
3
|
+
import { state as form } from "./form";
|
|
4
|
+
import { AllFormItem, ShortCutState } from "@/type";
|
|
5
|
+
|
|
6
|
+
const state = reactive<ShortCutState>({
|
|
7
|
+
form: form,
|
|
8
|
+
copyContent: {},
|
|
9
|
+
curList: [], // 当前操作在哪个选中区间中
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 快捷键对表单的处理
|
|
14
|
+
*/
|
|
15
|
+
class ShortCut {
|
|
16
|
+
copy(list: AllFormItem[]) {
|
|
17
|
+
if (state.form.currentIndex > -1) {
|
|
18
|
+
state.copyContent = list[state.form.currentIndex];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
paste(list: AllFormItem[]) {
|
|
22
|
+
if (state.copyContent) {
|
|
23
|
+
const pasteControl = window.VueContext.$Flex.deepClone(state.copyContent);
|
|
24
|
+
if(pasteControl.data){
|
|
25
|
+
pasteControl.data.fieldName = pasteControl.ControlType + "_" + window.VueContext.$Flex.generateMixed();
|
|
26
|
+
pasteControl.id = window.VueContext.$Flex.generateMixed();
|
|
27
|
+
list.push(pasteControl);
|
|
28
|
+
state.form.formUpdate = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
delete(list: AllFormItem[]) {
|
|
33
|
+
list.splice(state.form.currentIndex, 1);
|
|
34
|
+
state.form.curControl = {};
|
|
35
|
+
state.form.formUpdate = true;
|
|
36
|
+
state.form.currentIndex = -1;
|
|
37
|
+
state.form.currentId = "";
|
|
38
|
+
}
|
|
39
|
+
onTop(list: AllFormItem[]) {
|
|
40
|
+
if (state.form.currentIndex > 0) {
|
|
41
|
+
const temp = list.splice(state.form.currentIndex, 1);
|
|
42
|
+
state.form.currentIndex -= 1;
|
|
43
|
+
list.splice(state.form.currentIndex, 0, ...temp);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
onBottom(list: AllFormItem[]) {
|
|
47
|
+
if (state.form.currentIndex < list.length - 1) {
|
|
48
|
+
const temp = list.splice(state.form.currentIndex, 1);
|
|
49
|
+
state.form.currentIndex += 1;
|
|
50
|
+
list.splice(state.form.currentIndex, 0, ...temp);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
clear() {
|
|
54
|
+
state.form.allFormList.length = 0;
|
|
55
|
+
state.form.formUpdate = true;
|
|
56
|
+
}
|
|
57
|
+
moveTop() {
|
|
58
|
+
if (state.form.currentIndex > 0) {
|
|
59
|
+
state.form.currentIndex -= 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
moveBottom(list: AllFormItem[]) {
|
|
63
|
+
if (state.form.currentIndex < list.length - 1) {
|
|
64
|
+
state.form.currentIndex += 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
set(name: keyof ShortCutState, value: any) {
|
|
68
|
+
state[name] = value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get(name: keyof ShortCutState) {
|
|
72
|
+
return state[name];
|
|
73
|
+
}
|
|
74
|
+
commit(event: string) {
|
|
75
|
+
this[event](state.curList);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type shortCut = ShortCut;
|
|
80
|
+
|
|
81
|
+
export default new ShortCut();
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { reactive, toRaw } from "vue";
|
|
2
|
+
import { UiState, setColumnWidth, GetColumnWidth } from "@/type.ts";
|
|
3
|
+
|
|
4
|
+
const DEFAUTL_LEFT_COLUMN_WIDTH = 300;
|
|
5
|
+
const DEFAUTL_RIGHT_COLUMN_WIDTH = 400;
|
|
6
|
+
/**
|
|
7
|
+
* 编辑器各模块的宽度
|
|
8
|
+
*/
|
|
9
|
+
const defaultColumnWidth = {
|
|
10
|
+
left: DEFAUTL_LEFT_COLUMN_WIDTH,
|
|
11
|
+
center: window.document.body.clientWidth - DEFAUTL_LEFT_COLUMN_WIDTH - DEFAUTL_RIGHT_COLUMN_WIDTH,
|
|
12
|
+
right: DEFAUTL_RIGHT_COLUMN_WIDTH,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const DIALOG_WIDTH = 500;
|
|
16
|
+
/**
|
|
17
|
+
* 编辑器缩放比例
|
|
18
|
+
*/
|
|
19
|
+
const scale = 1;
|
|
20
|
+
|
|
21
|
+
const state = reactive<UiState>({
|
|
22
|
+
columnWidth: defaultColumnWidth,
|
|
23
|
+
dialogWidth: DIALOG_WIDTH,
|
|
24
|
+
scale,
|
|
25
|
+
isFullscreen: false,
|
|
26
|
+
pageType: 'PC',
|
|
27
|
+
rightClose: false,
|
|
28
|
+
leftClose: false
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Ui {
|
|
33
|
+
public get<T>(name: keyof typeof state): T {
|
|
34
|
+
return (state as any)[name];
|
|
35
|
+
}
|
|
36
|
+
public set<T>(name: keyof typeof state, value: T) {
|
|
37
|
+
if (name === "columnWidth") {
|
|
38
|
+
this.setColumnWidth(value as setColumnWidth);
|
|
39
|
+
} else if (name === "scale") {
|
|
40
|
+
this.setScale(Number(value));
|
|
41
|
+
}else if(name == 'isFullscreen'){
|
|
42
|
+
(state as any)[name] = value;
|
|
43
|
+
state.pageType = '';
|
|
44
|
+
}else if(name == 'pageType'){
|
|
45
|
+
(state as any)[name] = value;
|
|
46
|
+
state.isFullscreen = true;
|
|
47
|
+
}else{
|
|
48
|
+
(state as any)[name] = value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private setScale(size: number) {
|
|
53
|
+
const range = [0.2, 1.5];
|
|
54
|
+
if (size >= range[0] && size <= range[1]) {
|
|
55
|
+
state.scale = size;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private setColumnWidth({ left, center, right }: setColumnWidth) {
|
|
60
|
+
const columnWidth = {
|
|
61
|
+
...toRaw(this.get<GetColumnWidth>("columnWidth")),
|
|
62
|
+
};
|
|
63
|
+
if (left && left >= 0) {
|
|
64
|
+
columnWidth.left = left;
|
|
65
|
+
} else {
|
|
66
|
+
columnWidth.left = defaultColumnWidth.left;
|
|
67
|
+
}
|
|
68
|
+
if (right != undefined && right >= 0) {
|
|
69
|
+
columnWidth.right = right;
|
|
70
|
+
} else {
|
|
71
|
+
columnWidth.right = defaultColumnWidth.right;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!center || center == "auto") {
|
|
75
|
+
const bodyWidth = window.document.body.clientWidth;
|
|
76
|
+
columnWidth.center = bodyWidth - (columnWidth?.left || 0) - (columnWidth?.right || 0);
|
|
77
|
+
if (columnWidth.center <= 0) {
|
|
78
|
+
columnWidth.left = defaultColumnWidth.left;
|
|
79
|
+
columnWidth.center = defaultColumnWidth.center;
|
|
80
|
+
columnWidth.right = defaultColumnWidth.right;
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
columnWidth.center = center;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
state.columnWidth = columnWidth;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type UiControl = Ui;
|
|
91
|
+
export default new Ui();
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="controller_edit_size" ref="controllerSize">
|
|
3
|
+
<span @click="handleCanvasSize(0.1)"><i class="iconfontui icon-jiahao"></i></span>
|
|
4
|
+
<span>{{ parseInt(String(size * 100)) }}%</span>
|
|
5
|
+
<span @click="handleCanvasSize(-0.1)"><i class="iconfontui icon-jianhao"></i></span>
|
|
6
|
+
<span @mouseover="handleShortcutShow" @mouseleave="handleShortCutHidden">
|
|
7
|
+
<i class="iconfontui icon-jianpan_o"></i>
|
|
8
|
+
<transition name="slide-fade">
|
|
9
|
+
<shortcutKey v-show="shortCutShow" />
|
|
10
|
+
</transition>
|
|
11
|
+
</span>
|
|
12
|
+
<span @click="handleCanvasSize()" title="复位">
|
|
13
|
+
<i class="iconfontui icon-huanyuan"></i>
|
|
14
|
+
</span>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import { defineComponent, ref, inject, computed } from "vue";
|
|
19
|
+
import shortcutKey from "./ShortcutKey.vue";
|
|
20
|
+
import type { Controls } from "@/type";
|
|
21
|
+
export default defineComponent({
|
|
22
|
+
components: {
|
|
23
|
+
shortcutKey,
|
|
24
|
+
},
|
|
25
|
+
setup() {
|
|
26
|
+
const { uiControl } = inject<Controls>("control") || {};
|
|
27
|
+
const controllerSize = ref();
|
|
28
|
+
const shortCutShow = ref(false);
|
|
29
|
+
const handleCanvasSize = (size?: number) => {
|
|
30
|
+
if (!size) {
|
|
31
|
+
uiControl?.set<number>("scale", 1);
|
|
32
|
+
} else {
|
|
33
|
+
uiControl?.set<number>("scale", (uiControl?.get<number>("scale") || 1) + size);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const handleShortCutHidden = () => {
|
|
37
|
+
shortCutShow.value = false;
|
|
38
|
+
};
|
|
39
|
+
const handleShortcutShow = () => {
|
|
40
|
+
shortCutShow.value = true;
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
size: computed(() => uiControl?.get<number>("scale") || 1),
|
|
44
|
+
handleCanvasSize,
|
|
45
|
+
controllerSize,
|
|
46
|
+
shortCutShow,
|
|
47
|
+
handleShortCutHidden,
|
|
48
|
+
handleShortcutShow,
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="starfish-editor">
|
|
3
|
+
<div class="starfish-editor-nav">
|
|
4
|
+
<slot name="nav"></slot>
|
|
5
|
+
</div>
|
|
6
|
+
<div
|
|
7
|
+
class="starfish-editor-content"
|
|
8
|
+
:class="!headerShow ? 'starfish-editor-content-page' : ''"
|
|
9
|
+
>
|
|
10
|
+
<div
|
|
11
|
+
class="starfish-editor-framework-left"
|
|
12
|
+
:class="leftClose ? 'hide-status' : ''"
|
|
13
|
+
:style="`width:${leftClose ? 0 : columnWidth?.left}px`"
|
|
14
|
+
>
|
|
15
|
+
<slot name="left"></slot>
|
|
16
|
+
<div class="container-left-arrow" @click="onLeftArrow"></div>
|
|
17
|
+
</div>
|
|
18
|
+
<!-- resizer组件 -->
|
|
19
|
+
<resizer type="left"></resizer>
|
|
20
|
+
<div
|
|
21
|
+
class="starfish-editor-framework-center"
|
|
22
|
+
>
|
|
23
|
+
<slot name="navlist"></slot>
|
|
24
|
+
<slot name="workspace"></slot>
|
|
25
|
+
</div>
|
|
26
|
+
<resizer type="right"></resizer>
|
|
27
|
+
<div
|
|
28
|
+
class="starfish-editor-framework-right"
|
|
29
|
+
:class="rightClose ? 'hide-status' : ''"
|
|
30
|
+
:style="`width:${rightClose ? 0 : columnWidth?.right}px`"
|
|
31
|
+
>
|
|
32
|
+
<slot name="propsPanel"></slot>
|
|
33
|
+
<div class="container-right-arrow" @click="onRightArrow"></div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<slot name="other"></slot>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
<script lang="ts">
|
|
40
|
+
import { defineComponent, inject, computed } from "vue";
|
|
41
|
+
import Resizer from "./Resizer.vue";
|
|
42
|
+
import type { Controls } from "@/type";
|
|
43
|
+
export default defineComponent({
|
|
44
|
+
props: {
|
|
45
|
+
headerShow: {
|
|
46
|
+
type: Boolean,
|
|
47
|
+
default: true,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
components: {
|
|
51
|
+
Resizer,
|
|
52
|
+
},
|
|
53
|
+
setup() {
|
|
54
|
+
const { uiControl } = inject<Controls>("control") || {};
|
|
55
|
+
const columnWidth: any = computed(
|
|
56
|
+
() => uiControl?.get("columnWidth") || {}
|
|
57
|
+
);
|
|
58
|
+
const leftClose: any = computed(() => uiControl?.get("leftClose"));
|
|
59
|
+
const rightClose: any = computed(() => uiControl?.get("rightClose"));
|
|
60
|
+
|
|
61
|
+
function onLeftArrow() {
|
|
62
|
+
uiControl?.set("leftClose", !leftClose.value);
|
|
63
|
+
}
|
|
64
|
+
function onRightArrow() {
|
|
65
|
+
uiControl?.set("rightClose", !rightClose.value);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
columnWidth,
|
|
69
|
+
leftClose,
|
|
70
|
+
rightClose,
|
|
71
|
+
onLeftArrow,
|
|
72
|
+
onRightArrow,
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
</script>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="starfish-editor-resizer" ref="target"></div>
|
|
3
|
+
</template>
|
|
4
|
+
<script lang="ts">
|
|
5
|
+
import {
|
|
6
|
+
defineComponent,
|
|
7
|
+
inject,
|
|
8
|
+
ref,
|
|
9
|
+
onMounted,
|
|
10
|
+
toRaw,
|
|
11
|
+
onUnmounted,
|
|
12
|
+
} from "vue";
|
|
13
|
+
import type { Controls, setColumnWidth } from "@/type";
|
|
14
|
+
import Gesto from "gesto";
|
|
15
|
+
export default defineComponent({
|
|
16
|
+
props: {
|
|
17
|
+
type: {
|
|
18
|
+
type: String,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
setup(props) {
|
|
22
|
+
const target = ref<HTMLDivElement>();
|
|
23
|
+
const { uiControl } = inject<Controls>("control") || {};
|
|
24
|
+
let getso: Gesto;
|
|
25
|
+
onMounted(() => {
|
|
26
|
+
if (!target.value) return;
|
|
27
|
+
getso = new Gesto(target.value, {
|
|
28
|
+
container: window,
|
|
29
|
+
pinchOutside: true,
|
|
30
|
+
}).on("drag", (e) => {
|
|
31
|
+
if (!target.value || !uiControl) return;
|
|
32
|
+
let { right, left } = {
|
|
33
|
+
...toRaw(uiControl?.get("columnWidth") as Required<setColumnWidth>),
|
|
34
|
+
};
|
|
35
|
+
if (props.type == "right") {
|
|
36
|
+
right -= e.deltaX;
|
|
37
|
+
} else {
|
|
38
|
+
left += e.deltaX;
|
|
39
|
+
}
|
|
40
|
+
uiControl?.set("columnWidth", { left, right });
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
onUnmounted(() => {
|
|
45
|
+
getso?.unset();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
target,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="shortCutKey">
|
|
3
|
+
<div class="title">快捷键</div>
|
|
4
|
+
<div class="keyContent">
|
|
5
|
+
<div v-for="(item, index) in keyList" :key="index">
|
|
6
|
+
<span>{{item.key}}</span>
|
|
7
|
+
<span>{{item.value}}</span>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="san"></div>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
import { defineComponent, reactive} from "vue";
|
|
15
|
+
|
|
16
|
+
export default defineComponent({
|
|
17
|
+
setup(){
|
|
18
|
+
const keyList = reactive([
|
|
19
|
+
{
|
|
20
|
+
key: 'ctrl + C',
|
|
21
|
+
value: '复制组件'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
key: 'ctrl + V',
|
|
25
|
+
value: '粘贴组件'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: 'ctrl + X',
|
|
29
|
+
value: '裁剪组件'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'delete',
|
|
33
|
+
value: '删除组件'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: 'ctrl + E',
|
|
37
|
+
value: '清空画布'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'ctrl + ↑',
|
|
41
|
+
value: '组件上移'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: 'ctrl + ↓',
|
|
45
|
+
value: '组件下移'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
key: '↑',
|
|
49
|
+
value: '选中上移'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: '↓',
|
|
53
|
+
value: '选中下移'
|
|
54
|
+
},
|
|
55
|
+
])
|
|
56
|
+
return {
|
|
57
|
+
keyList
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
</script>
|
package/src/main.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { App, defineAsyncComponent } from "vue";
|
|
2
|
+
import "element-plus/dist/index.css";
|
|
3
|
+
import "@/styles/index.scss";
|
|
4
|
+
import "jsoneditor/dist/jsoneditor.min.css";
|
|
5
|
+
import StarfishForm from "starfish-form";
|
|
6
|
+
import vm from "./utils/vm";
|
|
7
|
+
import flex from "./utils/_";
|
|
8
|
+
import "starfish-form/dist/style.css";
|
|
9
|
+
import StarfishEditor from "./starfish-editor.vue";
|
|
10
|
+
import Loading from "@/common/Loading.vue";
|
|
11
|
+
export default {
|
|
12
|
+
install: (app: App) => {
|
|
13
|
+
app.config.globalProperties.$EventBus = vm;
|
|
14
|
+
app.config.globalProperties.$Flex = flex;
|
|
15
|
+
window.VApp = app.config.globalProperties;
|
|
16
|
+
// 如果想在方法中使用自定义的方法,可以挂载到window中
|
|
17
|
+
window.VueContext = {
|
|
18
|
+
$Flex: flex,
|
|
19
|
+
};
|
|
20
|
+
// 合并使用的
|
|
21
|
+
app.use(StarfishForm);
|
|
22
|
+
const starfishformlist = app.config.globalProperties.$formcomponents;
|
|
23
|
+
for (const key in starfishformlist) {
|
|
24
|
+
app.component(key, starfishformlist[key]);
|
|
25
|
+
}
|
|
26
|
+
app.component(
|
|
27
|
+
"CustomDialog",
|
|
28
|
+
defineAsyncComponent(() => import("@/common/CustomDialog.vue"))
|
|
29
|
+
);
|
|
30
|
+
app.component(
|
|
31
|
+
"ConditionSelect",
|
|
32
|
+
defineAsyncComponent(() => import("@/common/ConditionSelect.vue"))
|
|
33
|
+
);
|
|
34
|
+
app.component(
|
|
35
|
+
"HighConditionSelect",
|
|
36
|
+
defineAsyncComponent(() => import("@/common/ConditionSelect/ConditionModule.vue"))
|
|
37
|
+
);
|
|
38
|
+
app.component(
|
|
39
|
+
"draggable",
|
|
40
|
+
defineAsyncComponent({
|
|
41
|
+
loader: () => import("vuedraggable"),
|
|
42
|
+
loadingComponent: Loading,
|
|
43
|
+
})
|
|
44
|
+
);
|
|
45
|
+
app.component(
|
|
46
|
+
"Shape",
|
|
47
|
+
defineAsyncComponent(() => import("~editor/Shape.vue"))
|
|
48
|
+
);
|
|
49
|
+
app.component(
|
|
50
|
+
"FormStyle",
|
|
51
|
+
defineAsyncComponent(() => import("@/common/formStyle.vue"))
|
|
52
|
+
);
|
|
53
|
+
app.component("StarfishEditor", StarfishEditor);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
// app.mount("#app");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
declare module "*.vue" {
|
|
3
|
+
import type { DefineComponent } from "vue";
|
|
4
|
+
const component: DefineComponent<{}, {}, any>;
|
|
5
|
+
export default component;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare module "starfish-form";
|
|
9
|
+
|
|
10
|
+
declare module "jsoneditor";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 在d.ts文件中定义类型,就相当于global,不需要再declare global
|
|
14
|
+
*/
|
|
15
|
+
interface Window {
|
|
16
|
+
VueContext: {
|
|
17
|
+
$Flex: any;
|
|
18
|
+
};
|
|
19
|
+
clickCountLimitMock: boolean;
|
|
20
|
+
JSONEditor: any;
|
|
21
|
+
VApp: any;
|
|
22
|
+
Clipboard: any;
|
|
23
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<framework :headerShow="headerShow">
|
|
3
|
+
<template #nav v-if="headerShow">
|
|
4
|
+
<Nav></Nav>
|
|
5
|
+
</template>
|
|
6
|
+
<template #navlist>
|
|
7
|
+
<nav-list :menu="menu"></nav-list>
|
|
8
|
+
</template>
|
|
9
|
+
<template #left>
|
|
10
|
+
<component-list
|
|
11
|
+
:basic-fields="basicFields"
|
|
12
|
+
:layout-fields="layoutFields"
|
|
13
|
+
></component-list>
|
|
14
|
+
</template>
|
|
15
|
+
<template #workspace>
|
|
16
|
+
<workspace ref="workspace"></workspace>
|
|
17
|
+
</template>
|
|
18
|
+
<template #propsPanel v-if="panel.length > 0">
|
|
19
|
+
<props-panel
|
|
20
|
+
@save="onSave"
|
|
21
|
+
:column="menu.column"
|
|
22
|
+
:panel="panel"
|
|
23
|
+
></props-panel>
|
|
24
|
+
</template>
|
|
25
|
+
<template #other>
|
|
26
|
+
<form-preview ref="formPreview"></form-preview>
|
|
27
|
+
</template>
|
|
28
|
+
</framework>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script lang="ts">
|
|
32
|
+
import {
|
|
33
|
+
defineComponent,
|
|
34
|
+
provide,
|
|
35
|
+
ref,
|
|
36
|
+
onMounted,
|
|
37
|
+
onUnmounted,
|
|
38
|
+
PropType,
|
|
39
|
+
defineAsyncComponent,
|
|
40
|
+
} from "vue";
|
|
41
|
+
import Framework from "@/layouts/Framework.vue";
|
|
42
|
+
import NavList from "~editor/NavList.vue";
|
|
43
|
+
import Nav from "~editor/Nav.vue";
|
|
44
|
+
import ComponentList from "~editor/ComponentList.vue";
|
|
45
|
+
import Workspace from "~editor/Workspace.vue";
|
|
46
|
+
import PropsPanel from "~editor/PropsPanel.vue";
|
|
47
|
+
import uiControl from "@/controller/ui";
|
|
48
|
+
import hisContrl from "@/controller/history";
|
|
49
|
+
import formStore from "@/controller/form";
|
|
50
|
+
import actionContrl from "@/controller/action";
|
|
51
|
+
import store from "@/controller/shortcut";
|
|
52
|
+
import { listenGlobalKeyDown } from "@/utils/shortcutKey";
|
|
53
|
+
// 根据编辑器判断,走不同的快捷键逻辑
|
|
54
|
+
import formKeyconList from "@/utils/formKeycon";
|
|
55
|
+
import type { Controls, MenuBarData } from "./type";
|
|
56
|
+
import KeyController from "keycon";
|
|
57
|
+
|
|
58
|
+
export default defineComponent({
|
|
59
|
+
name: "StarfishEditor",
|
|
60
|
+
components: {
|
|
61
|
+
Framework,
|
|
62
|
+
NavList,
|
|
63
|
+
ComponentList,
|
|
64
|
+
Workspace,
|
|
65
|
+
PropsPanel,
|
|
66
|
+
FormPreview: defineAsyncComponent(() => import("~editor/FormPreview.vue")),
|
|
67
|
+
Nav,
|
|
68
|
+
},
|
|
69
|
+
props: {
|
|
70
|
+
/**
|
|
71
|
+
* 基础控件
|
|
72
|
+
*/
|
|
73
|
+
basicFields: {
|
|
74
|
+
type: Array,
|
|
75
|
+
default() {
|
|
76
|
+
return [];
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* 布局控件
|
|
81
|
+
*/
|
|
82
|
+
layoutFields: {
|
|
83
|
+
type: Array,
|
|
84
|
+
default() {
|
|
85
|
+
return [];
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* 是否禁用快捷键
|
|
90
|
+
*/
|
|
91
|
+
shortcutDisabled: {
|
|
92
|
+
type: Boolean,
|
|
93
|
+
default: false,
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* 导航头是否展示
|
|
97
|
+
*/
|
|
98
|
+
headerShow: {
|
|
99
|
+
type: Boolean,
|
|
100
|
+
default: true,
|
|
101
|
+
},
|
|
102
|
+
/** 顶部工具栏配置 */
|
|
103
|
+
menu: {
|
|
104
|
+
type: Object as PropType<MenuBarData>,
|
|
105
|
+
default: () => ({ left: [], right: [], column: true }),
|
|
106
|
+
},
|
|
107
|
+
// 右侧配置属性tab
|
|
108
|
+
panel: {
|
|
109
|
+
type: Array,
|
|
110
|
+
default: () => ["form", "json", "global"],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
setup(props: any, { emit }) {
|
|
114
|
+
const workspace = ref();
|
|
115
|
+
const formPreview = ref();
|
|
116
|
+
let dom: HTMLDivElement;
|
|
117
|
+
const mouseenterHandler = () => {
|
|
118
|
+
dom?.focus();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const mouseleaveHandler = () => {
|
|
122
|
+
dom?.blur();
|
|
123
|
+
};
|
|
124
|
+
const control: Controls = {
|
|
125
|
+
uiControl,
|
|
126
|
+
hisContrl,
|
|
127
|
+
formStore,
|
|
128
|
+
actionContrl,
|
|
129
|
+
store,
|
|
130
|
+
};
|
|
131
|
+
let keycons: KeyController;
|
|
132
|
+
onMounted(() => {
|
|
133
|
+
dom = workspace.value?.$el;
|
|
134
|
+
if (!props.shortcutDisabled) {
|
|
135
|
+
dom.addEventListener("mouseenter", mouseenterHandler);
|
|
136
|
+
dom.addEventListener("mouseleave", mouseleaveHandler);
|
|
137
|
+
keycons = listenGlobalKeyDown(formKeyconList, dom);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
onUnmounted(() => {
|
|
141
|
+
if (!props.shortcutDisabled) {
|
|
142
|
+
dom.removeEventListener("mouseenter", mouseenterHandler);
|
|
143
|
+
dom.removeEventListener("mouseleave", mouseleaveHandler);
|
|
144
|
+
keycons.destroy();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
provide("control", control);
|
|
148
|
+
return {
|
|
149
|
+
workspace,
|
|
150
|
+
formPreview,
|
|
151
|
+
onSave() {
|
|
152
|
+
emit("save", formStore?.get("AllFormResult"));
|
|
153
|
+
},
|
|
154
|
+
getJson() {
|
|
155
|
+
window.VApp.$EventBus.emit("setSave");
|
|
156
|
+
},
|
|
157
|
+
setJson(jsonList: any[]) {
|
|
158
|
+
const newJson = jsonList.map((json: any) => {
|
|
159
|
+
return window.VApp.$Flex.jsonToForm(json);
|
|
160
|
+
});
|
|
161
|
+
formStore.updateAllFormList(newJson);
|
|
162
|
+
formStore?.set("save", true);
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
</script>
|
|
168
|
+
|
|
169
|
+
<style>
|
|
170
|
+
#app {
|
|
171
|
+
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
172
|
+
-webkit-font-smoothing: antialiased;
|
|
173
|
+
-moz-osx-font-smoothing: grayscale;
|
|
174
|
+
text-align: center;
|
|
175
|
+
}
|
|
176
|
+
</style>
|