Skip to content

Commit

Permalink
feat(playground): 完善form editor
Browse files Browse the repository at this point in the history
  • Loading branch information
roymondchen committed Dec 15, 2023
1 parent b72e487 commit 538f96c
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 31 deletions.
1 change: 1 addition & 0 deletions packages/form/src/containers/Container.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<div
v-if="config"
:id="config.id"
:data-magic-id="config.id"
:style="config.tip ? 'display: flex;align-items: baseline;' : ''"
:class="`m-form-container m-container-${type || ''} ${config.className || ''}`"
>
Expand Down
6 changes: 3 additions & 3 deletions packages/stage/src/ActionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export default class ActionManager extends EventEmitter {
return el.id === this.selectedEl?.id;
}

public setSelectedEl(el: HTMLElement): void {
public setSelectedEl(el?: HTMLElement): void {
this.selectedEl = el;
}

Expand Down Expand Up @@ -258,7 +258,7 @@ export default class ActionManager extends EventEmitter {
}

public select(el: HTMLElement, event: MouseEvent | undefined): void {
this.selectedEl = el;
this.setSelectedEl(el);
this.clearSelectStatus(SelectStatus.MULTI_SELECT);
this.dr.select(el, event);
}
Expand Down Expand Up @@ -399,7 +399,7 @@ export default class ActionManager extends EventEmitter {
// 如果已有单选选中元素,不是magic-ui-page就可以加入多选列表
if (this.selectedEl && !this.selectedEl.className.includes(PAGE_CLASS)) {
this.selectedElList.push(this.selectedEl as HTMLElement);
this.selectedEl = undefined;
this.setSelectedEl(undefined);
}
// 判断元素是否已在多选列表
const existIndex = this.selectedElList.findIndex((selectedDom) => selectedDom.id === el.id);
Expand Down
6 changes: 0 additions & 6 deletions packages/stage/src/StageRender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,6 @@ export default class StageRender extends EventEmitter {
x = x - rect.left;
y = y - rect.top;
}
} else if (this.nativeContainer) {
const rect = this.nativeContainer.getClientRects()[0];
if (rect) {
x = x - rect.left;
y = y - rect.top;
}
}

return this.getDocument()?.elementsFromPoint(x / this.zoom, y / this.zoom) as HTMLElement[];
Expand Down
3 changes: 3 additions & 0 deletions playground/src/configs/form-config/checkbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { FormConfig } from '@tmagic/form';

export default [] as FormConfig;
27 changes: 27 additions & 0 deletions playground/src/configs/form-config/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { FormConfig } from '@tmagic/form';

export default [
{
name: 'id',
type: 'hidden',
},
{
name: 'type',
type: 'hidden',
},
{
name: 'name',
text: '表单key',
extra: '字段名',
},
{
name: 'text',
text: '标签文本',
extra: 'label 标签的文本',
},
{
name: 'labelWidth',
text: '标签宽度',
extra: '表单域标签的的宽度,例如 "50px"。支持 auto。',
},
] as FormConfig;
3 changes: 3 additions & 0 deletions playground/src/configs/form-config/display.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { FormConfig } from '@tmagic/form';

export default [] as FormConfig;
13 changes: 13 additions & 0 deletions playground/src/configs/form-config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import checkbox from './checkbox';
import display from './display';
import number from './number';
import switchConfig from './switch';
import text from './text';

export default {
text,
checkbox,
display,
number,
switch: switchConfig,
};
23 changes: 23 additions & 0 deletions playground/src/configs/form-config/number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { FormConfig } from '@tmagic/form';

export default [
{
type: 'number',
name: 'min',
text: '最小值',
},
{
type: 'number',
name: 'max',
text: '最大值',
},
{
type: 'number',
name: 'step',
text: '步数',
},
{
name: 'placeholder',
text: 'placeholder',
},
] as FormConfig;
3 changes: 3 additions & 0 deletions playground/src/configs/form-config/switch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { FormConfig } from '@tmagic/form';

export default [] as FormConfig;
26 changes: 26 additions & 0 deletions playground/src/configs/form-config/text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { FormConfig } from '@tmagic/form';

export default [
{
name: 'placeholder',
text: 'placeholder',
},
{
name: 'append',
legend: '后置按钮',
type: 'fieldset',
labelWidth: '80px',
items: [
{
name: 'text',
text: '按钮文案',
},
{
name: 'handler',
type: 'vs-code',
height: '400px',
text: '点击',
},
],
},
] as FormConfig;
6 changes: 5 additions & 1 deletion playground/src/pages/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</template>

<script lang="ts" setup>
import { computed, nextTick, ref, toRaw } from 'vue';
import { computed, nextTick, onBeforeUnmount, ref, toRaw } from 'vue';
import { useRouter } from 'vue-router';
import { Coin, Connection, Document } from '@element-plus/icons-vue';
import serialize from 'serialize-javascript';
Expand Down Expand Up @@ -233,6 +233,10 @@ editorService.usePlugin({
return [config, parent];
},
});
onBeforeUnmount(() => {
editorService.removeAllPlugins();
});
</script>

<style lang="scss">
Expand Down
88 changes: 67 additions & 21 deletions playground/src/pages/FormEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
:menu="menu"
:sidebar="sidebar"
:component-group-list="componentGroupList"
:render-type="RenderType.NATIVE"
:props-configs="propsConfigs"
:render="render"
:can-select="canSelect"
:update-drag-el="updateDragEl"
:stage-rect="{ width: 'calc(100% - 70px)', height: '100%' }"
:moveable-options="{ resizable: false }"
>
<template #layer-node-label="{ data }">
{{ data.text || data.name || 'container' }}
Expand All @@ -17,21 +17,33 @@
</template>

<script setup lang="tsx">
import { createApp, nextTick, ref } from 'vue';
import { createApp, onBeforeUnmount, ref } from 'vue';
import { useRouter } from 'vue-router';
import { Document } from '@element-plus/icons-vue';
import cssStyle from 'element-plus/dist/index.css?raw';
import { ComponentGroup, MenuBarData, SideBarData, TMagicEditor, traverseNode, uiService } from '@tmagic/editor';
import MagicForm, { MForm } from '@tmagic/form';
import { MApp, MNode, NodeType } from '@tmagic/schema';
import { getOffset, RenderType, RuntimeWindow, TargetElement } from '@tmagic/stage';
import { guid } from '@tmagic/utils';
import {
ComponentGroup,
MenuBarData,
propsService,
SideBarData,
TMagicEditor,
traverseNode,
uiService,
} from '@tmagic/editor';
import MagicForm, { type FormConfig, MForm } from '@tmagic/form';
import { type MApp, type MNode, NodeType } from '@tmagic/schema';
import type StageCore from '@tmagic/stage';
import { guid, injectStyle } from '@tmagic/utils';
import propsConfigs from '../configs/form-config';
import commonConfig from '../configs/form-config/common';
import formDsl from '../configs/formDsl';
formDsl.forEach((item) => {
traverseNode<any>(item, (item) => {
item.id = `${item.type}_${guid()}`;
item.type = item.type || (item.items ? 'container' : 'text');
item.style = {
left: 0,
top: 0,
Expand All @@ -53,30 +65,43 @@ const config = ref<MApp>({
],
});
const render = () => {
const el = globalThis.document.createElement('div');
el.style.position = 'relative';
const render = (stage: StageCore) => {
injectStyle(stage.renderer.getDocument()!, cssStyle);
injectStyle(
stage.renderer.getDocument()!,
`
html,
body,
#app {
width: 100%;
height: 100%;
margin: 0;
}
::-webkit-scrollbar {
width: 0;
}
`,
);
const el: HTMLDivElement = globalThis.document.createElement('div');
el.id = 'app';
el.style.overflow = 'auto';
createApp(MForm, {
config: formDsl,
config: config.value.items[0].items,
initValues: {},
})
.use(MagicForm)
.mount(el);
nextTick(() => {
(globalThis as unknown as RuntimeWindow).magic.onPageElUpdate(el);
stage.renderer.contentWindow?.magic?.onRuntimeReady({});
setTimeout(() => {
stage.renderer.contentWindow?.magic.onPageElUpdate(el.children[0] as HTMLElement);
uiService.set('showRule', false);
});
return el;
};
const updateDragEl = (el: TargetElement, target: TargetElement, container: HTMLElement) => {
const { left, top } = getOffset(container);
el.style.left = `${globalThis.parseFloat(el.style.left) - left}px`;
el.style.top = `${globalThis.parseFloat(el.style.top) - top}px`;
};
const componentGroupList: ComponentGroup[] = [
{
title: '容器',
Expand Down Expand Up @@ -162,5 +187,26 @@ const sidebar: SideBarData = {
items: ['component-list', 'layer'],
};
const canSelect = (el: HTMLElement) => el.classList.contains('m-form-container');
const canSelect = (el: HTMLElement) => Boolean(el.dataset.magicId);
propsService.usePlugin({
afterFillConfig(config: FormConfig, itemConfig: FormConfig) {
return [
{
type: 'tab',
items: [
{
title: '属性',
labelWidth: '80px',
items: [...commonConfig, ...itemConfig],
},
],
},
];
},
});
onBeforeUnmount(() => {
propsService.removeAllPlugins();
});
</script>

0 comments on commit 538f96c

Please sign in to comment.