mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-03 22:39:52 +08:00
parent
9e167474a2
commit
2201fbe80c
@ -31,7 +31,7 @@
|
||||
|
||||
<template #props-panel>
|
||||
<slot name="props-panel">
|
||||
<props-panel ref="propsPanel" @mounted="(instance: any) => $emit('props-panel-mounted', instance)">
|
||||
<props-panel @mounted="(instance: any) => $emit('props-panel-mounted', instance)">
|
||||
<template #props-panel-header>
|
||||
<slot name="props-panel-header"></slot>
|
||||
</template>
|
||||
|
@ -2,9 +2,9 @@
|
||||
<div class="`m-editor-props-panel">
|
||||
<slot name="props-panel-header"></slot>
|
||||
<m-form
|
||||
ref="configForm"
|
||||
:class="`m-editor-props-panel ${propsPanelSize}`"
|
||||
:popper-class="`m-editor-props-panel-popper ${propsPanelSize}`"
|
||||
ref="configForm"
|
||||
:size="propsPanelSize"
|
||||
:init-values="values"
|
||||
:config="curFormConfig"
|
||||
@ -13,69 +13,67 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, getCurrentInstance, inject, onMounted, ref, watchEffect } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { computed, getCurrentInstance, inject, onMounted, ref, watchEffect } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
import type { FormValue, MForm } from '@tmagic/form';
|
||||
import type { MNode } from '@tmagic/schema';
|
||||
import type StageCore from '@tmagic/stage';
|
||||
|
||||
import type { Services } from '../type';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'm-editor-props-panel',
|
||||
const emit = defineEmits(['mounted']);
|
||||
|
||||
emits: ['mounted'],
|
||||
const internalInstance = getCurrentInstance();
|
||||
const values = ref<FormValue>({});
|
||||
const configForm = ref<InstanceType<typeof MForm>>();
|
||||
// ts类型应该是FormConfig, 但是打包时会出错,所以暂时用any
|
||||
const curFormConfig = ref<any>([]);
|
||||
const services = inject<Services>('services');
|
||||
const node = computed(() => services?.editorService.get<MNode | null>('node'));
|
||||
const propsPanelSize = computed(() => services?.uiService.get('propsPanelSize') || 'small');
|
||||
const stage = computed(() => services?.editorService.get<StageCore>('stage'));
|
||||
|
||||
setup(props, { emit }) {
|
||||
const internalInstance = getCurrentInstance();
|
||||
const values = ref<FormValue>({});
|
||||
const configForm = ref<InstanceType<typeof MForm>>();
|
||||
// ts类型应该是FormConfig, 但是打包时会出错,所以暂时用any
|
||||
const curFormConfig = ref<any>([]);
|
||||
const services = inject<Services>('services');
|
||||
const node = computed(() => services?.editorService.get<MNode | null>('node'));
|
||||
const init = async () => {
|
||||
if (!node.value) {
|
||||
curFormConfig.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
if (!node.value) {
|
||||
curFormConfig.value = [];
|
||||
return;
|
||||
}
|
||||
const type = node.value.type || (node.value.items ? 'container' : 'text');
|
||||
curFormConfig.value = (await services?.propsService.getPropsConfig(type)) || [];
|
||||
values.value = node.value;
|
||||
};
|
||||
|
||||
const type = node.value.type || (node.value.items ? 'container' : 'text');
|
||||
curFormConfig.value = (await services?.propsService.getPropsConfig(type)) || [];
|
||||
values.value = node.value;
|
||||
};
|
||||
watchEffect(init);
|
||||
services?.propsService.on('props-configs-change', init);
|
||||
|
||||
watchEffect(init);
|
||||
services?.propsService.on('props-configs-change', init);
|
||||
|
||||
onMounted(() => {
|
||||
emit('mounted', internalInstance);
|
||||
});
|
||||
|
||||
return {
|
||||
values,
|
||||
configForm,
|
||||
curFormConfig,
|
||||
propsPanelSize: computed(() => services?.uiService.get('propsPanelSize') || 'small'),
|
||||
|
||||
async submit() {
|
||||
try {
|
||||
const values = await configForm.value?.submitForm();
|
||||
services?.editorService.update(values);
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
ElMessage.closeAll();
|
||||
ElMessage.error({
|
||||
duration: 10000,
|
||||
showClose: true,
|
||||
message: e.message,
|
||||
dangerouslyUseHTMLString: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
onMounted(() => {
|
||||
emit('mounted', internalInstance);
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (configForm.value && stage.value) {
|
||||
configForm.value.formState.stage = stage.value;
|
||||
}
|
||||
});
|
||||
|
||||
const submit = async () => {
|
||||
try {
|
||||
const values = await configForm.value?.submitForm();
|
||||
services?.editorService.update(values);
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
ElMessage.closeAll();
|
||||
ElMessage.error({
|
||||
duration: 10000,
|
||||
showClose: true,
|
||||
message: e.message,
|
||||
dangerouslyUseHTMLString: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({ submit });
|
||||
</script>
|
||||
|
@ -519,6 +519,7 @@ export default class StageDragResize extends EventEmitter {
|
||||
|
||||
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
||||
const isFixed = this.mode === Mode.FIXED;
|
||||
const isSortable = this.mode === Mode.SORTABLE;
|
||||
|
||||
let { moveableOptions = {} } = this.core.config;
|
||||
|
||||
@ -573,7 +574,7 @@ export default class StageDragResize extends EventEmitter {
|
||||
// 设置0的话无法移动到left为0,所以只能设置为-1
|
||||
left: -1,
|
||||
right: this.container.clientWidth - 1,
|
||||
bottom: this.container.clientHeight,
|
||||
bottom: isSortable ? undefined : this.container.clientHeight,
|
||||
...(moveableOptions.bounds || {}),
|
||||
},
|
||||
...options,
|
||||
|
@ -9,3 +9,7 @@
|
||||
opacity: .1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.magic-ui-container.magic-layout-relative {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ const Container: React.FC<ContainerProps> = ({ config, id }) => {
|
||||
return (
|
||||
<div
|
||||
id={`${id || config.id || ''}`}
|
||||
className={`magic-ui-container${config.className ? ` ${config.className}` : ''}`}
|
||||
className={`magic-ui-container magic-layout-${config.layout}${config.className ? ` ${config.className}` : ''}`}
|
||||
style={app.transformStyle(config.style || {})}
|
||||
>
|
||||
{config.items?.map((item: MComponent | MContainer) => {
|
||||
|
@ -26,5 +26,16 @@ export default [
|
||||
{ value: 'absolute', text: '绝对定位' },
|
||||
{ value: 'relative', text: '流式布局' },
|
||||
],
|
||||
onChange: (formState: any, v: string, { model }: any) => {
|
||||
if (!model.style) return v;
|
||||
if (v === 'relative') {
|
||||
model.style.height = 'auto';
|
||||
} else {
|
||||
const el = formState.stage?.renderer?.contentWindow.document.getElementById(model.id);
|
||||
if (el) {
|
||||
model.style.height = el.getBoundingClientRect().height;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -39,7 +39,9 @@ const Page: React.FC<PageProps> = ({ config }) => {
|
||||
return (
|
||||
<div
|
||||
id={`${config.id || ''}`}
|
||||
className={`magic-ui-page magic-ui-container${config.className ? ` ${config.className}` : ''}`}
|
||||
className={`magic-ui-page magic-ui-container magic-layout-${config.layout}${
|
||||
config.className ? ` ${config.className}` : ''
|
||||
}`}
|
||||
style={app.transformStyle(config.style || {})}
|
||||
>
|
||||
{config.items?.map((item: MComponent | MContainer) => {
|
||||
|
@ -36,5 +36,16 @@ export default [
|
||||
{ value: 'absolute', text: '绝对定位' },
|
||||
{ value: 'relative', text: '流式布局' },
|
||||
],
|
||||
onChange: (formState: any, v: string, { model }: any) => {
|
||||
if (!model.style) return v;
|
||||
if (v === 'relative') {
|
||||
model.style.height = 'auto';
|
||||
} else {
|
||||
const el = formState.stage?.renderer?.contentWindow.document.getElementById(model.id);
|
||||
if (el) {
|
||||
model.style.height = el.getBoundingClientRect().height;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div
|
||||
v-if="display()"
|
||||
:id="config.id"
|
||||
:class="`magic-ui-container${config.className ? ` ${config.className}` : ''}`"
|
||||
:class="`magic-ui-container magic-layout-${config.layout}${config.className ? ` ${config.className}` : ''}`"
|
||||
:style="style"
|
||||
>
|
||||
<slot></slot>
|
||||
|
@ -26,5 +26,16 @@ export default [
|
||||
{ value: 'absolute', text: '绝对定位' },
|
||||
{ value: 'relative', text: '流式布局' },
|
||||
],
|
||||
onChange: (formState: any, v: string, { model }: any) => {
|
||||
if (!model.style) return v;
|
||||
if (v === 'relative') {
|
||||
model.style.height = 'auto';
|
||||
} else {
|
||||
const el = formState.stage?.renderer?.contentWindow.document.getElementById(model.id);
|
||||
if (el) {
|
||||
model.style.height = el.getBoundingClientRect().height;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -16,4 +16,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export default {};
|
||||
export default {
|
||||
items: [],
|
||||
style: {
|
||||
width: '375',
|
||||
height: '100',
|
||||
},
|
||||
};
|
||||
|
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
:id="config.id"
|
||||
:class="`magic-ui-page magic-ui-container${config.className ? ` ${config.className}` : ''}`"
|
||||
:class="`magic-ui-page magic-ui-container magic-layout-${config.layout}${
|
||||
config.className ? ` ${config.className}` : ''
|
||||
}`"
|
||||
:style="style"
|
||||
>
|
||||
<slot></slot>
|
||||
|
@ -36,5 +36,16 @@ export default [
|
||||
{ value: 'absolute', text: '绝对定位' },
|
||||
{ value: 'relative', text: '流式布局' },
|
||||
],
|
||||
onChange: (formState: any, v: string, { model }: any) => {
|
||||
if (!model.style) return v;
|
||||
if (v === 'relative') {
|
||||
model.style.height = 'auto';
|
||||
} else {
|
||||
const el = formState.stage?.renderer?.contentWindow.document.getElementById(model.id);
|
||||
if (el) {
|
||||
model.style.height = el.getBoundingClientRect().height;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div
|
||||
v-if="display()"
|
||||
:id="`${config.id || ''}`"
|
||||
:class="`magic-ui-container${config.className ? ` ${config.className}` : ''}`"
|
||||
:class="`magic-ui-container magic-layout-${config.layout}${config.className ? ` ${config.className}` : ''}`"
|
||||
:style="style"
|
||||
>
|
||||
<slot></slot>
|
||||
|
@ -26,5 +26,16 @@ export default [
|
||||
{ value: 'absolute', text: '绝对定位' },
|
||||
{ value: 'relative', text: '流式布局' },
|
||||
],
|
||||
onChange: (formState: any, v: string, { model }: any) => {
|
||||
if (!model.style) return v;
|
||||
if (v === 'relative') {
|
||||
model.style.height = 'auto';
|
||||
} else {
|
||||
const el = formState.stage?.renderer?.contentWindow.document.getElementById(model.id);
|
||||
if (el) {
|
||||
model.style.height = el.getBoundingClientRect().height;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -36,5 +36,16 @@ export default [
|
||||
{ value: 'absolute', text: '绝对定位' },
|
||||
{ value: 'relative', text: '流式布局' },
|
||||
],
|
||||
onChange: (formState: any, v: string, { model }: any) => {
|
||||
if (!model.style) return v;
|
||||
if (v === 'relative') {
|
||||
model.style.height = 'auto';
|
||||
} else {
|
||||
const el = formState.stage?.renderer?.contentWindow.document.getElementById(model.id);
|
||||
if (el) {
|
||||
model.style.height = el.getBoundingClientRect().height;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
:id="`${config.id || ''}`"
|
||||
:class="`magic-ui-page magic-ui-container${config.className ? ` ${config.className}` : ''}`"
|
||||
:class="`magic-ui-page magic-ui-container magic-layout-${config.layout}${
|
||||
config.className ? ` ${config.className}` : ''
|
||||
}`"
|
||||
:style="style"
|
||||
>
|
||||
<slot></slot>
|
||||
|
@ -67,10 +67,14 @@ export default defineComponent({
|
||||
|
||||
add({ config, parentId }: UpdateData) {
|
||||
console.log('add config', config);
|
||||
|
||||
if (!root.value) throw new Error('error');
|
||||
if (!selectedId.value) throw new Error('error');
|
||||
if (!parentId) throw new Error('error');
|
||||
|
||||
const parent = getNodePath(parentId, [root.value]).pop();
|
||||
if (!parent) throw new Error('未找到父节点');
|
||||
|
||||
if (parent.id !== selectedId.value) {
|
||||
const index = parent.items?.findIndex((child: MNode) => child.id === selectedId.value);
|
||||
parent.items?.splice(index + 1, 0, config);
|
||||
@ -82,11 +86,16 @@ export default defineComponent({
|
||||
|
||||
update({ config, parentId }: UpdateData) {
|
||||
console.log('update config', config);
|
||||
|
||||
if (!root.value) throw new Error('error');
|
||||
|
||||
const node = getNodePath(config.id, [root.value]).pop();
|
||||
const parent = getNodePath(parentId, [root.value]).pop();
|
||||
if (!node) throw new Error('未找到目标节点');
|
||||
|
||||
if (!parentId) throw new Error('error');
|
||||
const parent = getNodePath(parentId, [root.value]).pop();
|
||||
if (!parent) throw new Error('未找到父节点');
|
||||
|
||||
const index = parent.items?.findIndex((child: MNode) => child.id === node.id);
|
||||
parent.items.splice(index, 1, reactive(config));
|
||||
},
|
||||
|
@ -67,8 +67,11 @@ export default defineComponent({
|
||||
|
||||
add({ config, parentId }: UpdateData) {
|
||||
console.log('add config', config);
|
||||
|
||||
if (!root.value) throw new Error('error');
|
||||
if (!selectedId.value) throw new Error('error');
|
||||
if (!parentId) throw new Error('error');
|
||||
|
||||
const parent = getNodePath(parentId, [root.value]).pop();
|
||||
if (!parent) throw new Error('未找到父节点');
|
||||
if (parent.id !== selectedId.value) {
|
||||
@ -82,9 +85,13 @@ export default defineComponent({
|
||||
|
||||
update({ config, parentId }: UpdateData) {
|
||||
console.log('update config', config);
|
||||
|
||||
if (!root.value) throw new Error('error');
|
||||
const node = getNodePath(config.id, [root.value]).pop();
|
||||
|
||||
if (!parentId) throw new Error('error');
|
||||
const parent = getNodePath(parentId, [root.value]).pop();
|
||||
|
||||
if (!node) throw new Error('未找到目标节点');
|
||||
if (!parent) throw new Error('未找到父节点');
|
||||
const index = parent.items?.findIndex((child: MNode) => child.id === node.id);
|
||||
@ -93,10 +100,13 @@ export default defineComponent({
|
||||
|
||||
remove({ id, parentId }: RemoveData) {
|
||||
if (!root.value) throw new Error('error');
|
||||
|
||||
const node = getNodePath(id, [root.value]).pop();
|
||||
if (!node) throw new Error('未找到目标元素');
|
||||
|
||||
const parent = getNodePath(parentId, [root.value]).pop();
|
||||
if (!parent) throw new Error('未找到父元素');
|
||||
|
||||
const index = parent.items?.findIndex((child: MNode) => child.id === node.id);
|
||||
parent.items.splice(index, 1);
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user