You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.7 KiB
135 lines
3.7 KiB
<script setup lang="ts">
|
|
import lodash from "lodash";
|
|
import { computed, reactive } from "vue";
|
|
import { ElCollapse, ElCollapseItem } from "element-plus";
|
|
import DataForm from "@/components/data-form/DataForm.vue";
|
|
import type { PropertyFlattenSetter, PropertySetterGroup } from "@/core/base/PropertyTypes.ts";
|
|
import type { DataFormProps } from "@/components/data-form/DataFormTypes.ts";
|
|
import { defDataFormProps } from "@/editor/widgets/property/PropertyPanelConstant.ts";
|
|
import Viewport, { type ViewportState } from "@/core/engine/Viewport.ts";
|
|
|
|
defineOptions({
|
|
name: 'PropertyPanel',
|
|
});
|
|
|
|
// 定义 Props 类型
|
|
interface PropertyPanelProps {
|
|
/** 待编辑数据 */
|
|
data?: any;
|
|
/** Viewport */
|
|
viewport: Viewport;
|
|
/** ViewportState */
|
|
viewportState: ViewportState;
|
|
/** 默认的DataFormProps */
|
|
defDataFormProps?: DataFormProps;
|
|
/** 最上面平铺的设置器 */
|
|
flatten?: PropertyFlattenSetter;
|
|
/** 设置器分组集合 */
|
|
groups?: Array<PropertySetterGroup>;
|
|
}
|
|
|
|
// 读取组件 props 属性
|
|
const props = withDefaults(defineProps<PropertyPanelProps>(), {});
|
|
|
|
// 定义 State 类型
|
|
interface PropertyPanelState {
|
|
/** 待编辑数据 */
|
|
data?: any;
|
|
/** 已展开的分组 */
|
|
expandGroups: Array<string>;
|
|
}
|
|
|
|
// state 属性
|
|
const state = reactive<PropertyPanelState>({
|
|
data: lodash.cloneDeep(props.data),
|
|
expandGroups: [],
|
|
});
|
|
|
|
// 定义 Data 类型
|
|
interface PropertyPanelData {
|
|
}
|
|
|
|
// 内部数据
|
|
const data: PropertyPanelData = {};
|
|
const flattenFormProps = computed(() => getDefFormProps(props.flatten));
|
|
|
|
function getDefFormProps(setter?: PropertyFlattenSetter) {
|
|
const formProps: DataFormProps = {
|
|
...defDataFormProps,
|
|
...props.defDataFormProps,
|
|
};
|
|
fillFormProps(setter);
|
|
return formProps;
|
|
}
|
|
|
|
function fillFormProps(formProps: DataFormProps, setter?: PropertyFlattenSetter) {
|
|
if (!setter) return;
|
|
if (setter.size) formProps.size = setter.size;
|
|
if (setter.labelWidth) formProps.labelWidth = setter.labelWidth;
|
|
}
|
|
|
|
function getCollapseItemId(group: PropertySetterGroup, idx: number) {
|
|
return `_${idx}_${group.title}`;
|
|
}
|
|
|
|
function onDataChange(newData: any) {
|
|
const viewport = props.viewport;
|
|
if (!viewport) return;
|
|
viewport.stateManager.beginStateUpdate();
|
|
lodash.merge(props.data, newData);
|
|
console.log("onDataChange", props.data === newData);
|
|
viewport.stateManager.endStateUpdate();
|
|
}
|
|
|
|
interface PropertyPanelExpose {
|
|
state: PropertyPanelState;
|
|
data: PropertyPanelData;
|
|
}
|
|
|
|
const expose: PropertyPanelExpose = {
|
|
state,
|
|
data,
|
|
};
|
|
// 定义组件公开内容
|
|
defineExpose(expose);
|
|
|
|
export type {
|
|
PropertyPanelProps,
|
|
PropertyPanelState,
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="property-panel">
|
|
<DataForm
|
|
v-if="props.flatten"
|
|
class="property-panel-form"
|
|
v-bind="flattenFormProps"
|
|
:data="state.data"
|
|
:formFields="props.flatten.fields"
|
|
@dataChange="onDataChange"
|
|
/>
|
|
<ElCollapse v-if="props.groups" v-model="state.expandGroups">
|
|
<ElCollapseItem
|
|
v-for="(group, idx) in props.groups"
|
|
:name="getCollapseItemId(group, idx)"
|
|
:title="group.title"
|
|
>
|
|
<DataForm
|
|
v-if="group"
|
|
class="property-panel-form"
|
|
v-bind="getDefFormProps(group)"
|
|
:data="state.data"
|
|
:formFields="props.flatten.fields"
|
|
@dataChange="onDataChange"
|
|
/>
|
|
</ElCollapseItem>
|
|
</ElCollapse>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.property-panel {
|
|
padding: 8px 12px 16px 0;
|
|
}
|
|
</style>
|
|
|