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.
Files changed (108) hide show
  1. package/auto-imports.d.ts +10 -0
  2. package/babel.config.js +8 -0
  3. package/components.d.ts +46 -0
  4. package/dist/ConditionModule.js +892 -0
  5. package/dist/ConditionSelect.js +483 -0
  6. package/dist/CustomDialog.js +105 -0
  7. package/dist/formStyle.js +245 -0
  8. package/dist/globalFormList.js +59 -0
  9. package/dist/jsonCode.js +74 -0
  10. package/dist/jsonEditor.js +71 -0
  11. package/dist/main.js +3319 -0
  12. package/dist/starfish-editor.es.js +30 -0
  13. package/dist/style.css +1 -0
  14. package/dist/types/editor/src/common/ConditionSelect/ConditionGroup.vue.d.ts +61 -0
  15. package/dist/types/editor/src/common/ConditionSelect/ConditionModule.vue.d.ts +43 -0
  16. package/dist/types/editor/src/common/ConditionSelect/ConditionTanc.vue.d.ts +48 -0
  17. package/dist/types/editor/src/common/ConditionSelect.vue.d.ts +72 -0
  18. package/dist/types/editor/src/common/CustomDialog.vue.d.ts +25 -0
  19. package/dist/types/editor/src/common/Loading.vue.d.ts +3 -0
  20. package/dist/types/editor/src/common/formJson.d.ts +80 -0
  21. package/dist/types/editor/src/common/jsonCode.vue.d.ts +110 -0
  22. package/dist/types/editor/src/components/ComponentList.vue.d.ts +32 -0
  23. package/dist/types/editor/src/components/FormPreview.vue.d.ts +25 -0
  24. package/dist/types/editor/src/components/Nav.vue.d.ts +9 -0
  25. package/dist/types/editor/src/components/PropsPanel.vue.d.ts +53 -0
  26. package/dist/types/editor/src/components/Shape.vue.d.ts +40 -0
  27. package/dist/types/editor/src/components/Workspace.vue.d.ts +22 -0
  28. package/dist/types/editor/src/components/globalFormList.vue.d.ts +6 -0
  29. package/dist/types/editor/src/components/jsonEditor.vue.d.ts +6 -0
  30. package/dist/types/editor/src/controller/action.d.ts +18 -0
  31. package/dist/types/editor/src/controller/form.d.ts +24 -0
  32. package/dist/types/editor/src/controller/history.d.ts +12 -0
  33. package/dist/types/editor/src/controller/shortcut.d.ts +20 -0
  34. package/dist/types/editor/src/controller/ui.d.ts +10 -0
  35. package/dist/types/editor/src/layouts/ControlEditSize.vue.d.ts +17 -0
  36. package/dist/types/editor/src/layouts/Framework.vue.d.ts +33 -0
  37. package/dist/types/editor/src/layouts/Resizer.vue.d.ts +13 -0
  38. package/dist/types/editor/src/layouts/ShortcutKey.vue.d.ts +8 -0
  39. package/dist/types/editor/src/main.d.ts +5 -0
  40. package/dist/types/editor/src/shims-vue.d.ts +23 -0
  41. package/dist/types/editor/src/starfish-editor.vue.d.ts +109 -0
  42. package/dist/types/editor/src/type.d.ts +224 -0
  43. package/dist/types/editor/src/utils/_.d.ts +33 -0
  44. package/dist/types/editor/src/utils/formKeycon.d.ts +18 -0
  45. package/dist/types/editor/src/utils/shortcutKey.d.ts +3 -0
  46. package/dist/types/editor/src/utils/vm.d.ts +3 -0
  47. package/dist/types/starfish-editor.d.ts +3 -0
  48. package/package.json +55 -0
  49. package/src/common/ConditionSelect/ConditionGroup.vue +167 -0
  50. package/src/common/ConditionSelect/ConditionModule.vue +118 -0
  51. package/src/common/ConditionSelect/ConditionTanc.vue +319 -0
  52. package/src/common/ConditionSelect.vue +268 -0
  53. package/src/common/CustomDialog.vue +77 -0
  54. package/src/common/Loading.vue +10 -0
  55. package/src/common/formJson.ts +143 -0
  56. package/src/common/formStyle.vue +170 -0
  57. package/src/common/jsonCode.vue +45 -0
  58. package/src/components/ComponentList.vue +156 -0
  59. package/src/components/FormPreview.vue +197 -0
  60. package/src/components/Nav.vue +128 -0
  61. package/src/components/NavList.vue +560 -0
  62. package/src/components/PropsPanel.vue +376 -0
  63. package/src/components/Shape.vue +178 -0
  64. package/src/components/Workspace.vue +258 -0
  65. package/src/components/globalFormList.vue +30 -0
  66. package/src/components/jsonEditor.vue +41 -0
  67. package/src/controller/action.ts +37 -0
  68. package/src/controller/form.ts +207 -0
  69. package/src/controller/history.ts +57 -0
  70. package/src/controller/shortcut.ts +81 -0
  71. package/src/controller/ui.ts +91 -0
  72. package/src/layouts/ControlEditSize.vue +52 -0
  73. package/src/layouts/Framework.vue +76 -0
  74. package/src/layouts/Resizer.vue +54 -0
  75. package/src/layouts/ShortcutKey.vue +61 -0
  76. package/src/main.ts +56 -0
  77. package/src/shims-vue.d.ts +23 -0
  78. package/src/starfish-editor.vue +176 -0
  79. package/src/styles/common/normalize.css +455 -0
  80. package/src/styles/component-list.scss +64 -0
  81. package/src/styles/condition-select.scss +176 -0
  82. package/src/styles/control_edit_size.scss +36 -0
  83. package/src/styles/custom-dialog.scss +110 -0
  84. package/src/styles/form-preview.scss +47 -0
  85. package/src/styles/framework.scss +150 -0
  86. package/src/styles/iconfont/iconfont.css +247 -0
  87. package/src/styles/iconfont/iconfont.js +1 -0
  88. package/src/styles/iconfont/iconfont.json +415 -0
  89. package/src/styles/iconfont/iconfont.ttf +0 -0
  90. package/src/styles/iconfont/iconfont.woff +0 -0
  91. package/src/styles/iconfont/iconfont.woff2 +0 -0
  92. package/src/styles/index.scss +18 -0
  93. package/src/styles/nav-list.scss +59 -0
  94. package/src/styles/nav.scss +46 -0
  95. package/src/styles/props-panel.scss +115 -0
  96. package/src/styles/resizer.scss +15 -0
  97. package/src/styles/shape.scss +101 -0
  98. package/src/styles/shortcutkey.scss +44 -0
  99. package/src/styles/variables.scss +36 -0
  100. package/src/styles/work-space.scss +126 -0
  101. package/src/type.ts +240 -0
  102. package/src/utils/_.ts +349 -0
  103. package/src/utils/formKeycon.ts +42 -0
  104. package/src/utils/shortcutKey.ts +46 -0
  105. package/src/utils/vm.ts +3 -0
  106. package/stats.html +4949 -0
  107. package/tsconfig.json +19 -0
  108. 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>