|
|
@@ -1,290 +1,236 @@
|
|
|
<template>
|
|
|
- <el-scrollbar :height="'calc(100vh - 198px)'" class="config pr-10px pl-10px">
|
|
|
- <el-form label-position="top">
|
|
|
- <el-form-item label="名称">
|
|
|
- <el-input v-model="data.name" />
|
|
|
- </el-form-item>
|
|
|
- <el-collapse v-model="activeNames">
|
|
|
- <el-collapse-item title="Transform" name="transform">
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item v-if="hasKey('x')" label="X" class="flex-1">
|
|
|
- <el-input-number v-model="data.x" style="width: 100%" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('y')" label="Y" class="flex-1">
|
|
|
- <el-input-number v-model="data.y" style="width: 100%" />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item v-if="hasKey('width')" label="宽度" class="flex-1">
|
|
|
- <el-input-number v-model="data.width" style="width: 100%" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('height')" label="高度" class="flex-1">
|
|
|
- <el-input-number v-model="data.height" style="width: 100%" />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
-
|
|
|
- <el-form-item v-if="hasKey('parent')" label="父级组件">
|
|
|
- <el-input v-model="data.parent" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('text')" label="文本">
|
|
|
- <el-input v-model="data.text" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('align')" label="对齐方式">
|
|
|
- <el-select v-model="data.align">
|
|
|
- <el-option label="居中" value="center" />
|
|
|
- <el-option label="左上" value="top_left" />
|
|
|
- <el-option label="上中" value="top_center" />
|
|
|
- <el-option label="右上" value="top_right" />
|
|
|
- <el-option label="左下" value="bottom_left" />
|
|
|
- <el-option label="下中" value="bottom_center" />
|
|
|
- <el-option label="右下" value="bottom_right" />
|
|
|
- <el-option label="左" value="left" />
|
|
|
- <el-option label="右" value="right" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('state')" label="状态">
|
|
|
- <el-checkbox-group v-model="data.state">
|
|
|
- <el-checkbox label="选中" value="checked" />
|
|
|
- <el-checkbox label="禁用" value="disabled" />
|
|
|
- <el-checkbox label="聚焦" value="focused" />
|
|
|
- <el-checkbox label="按下" value="pressed" />
|
|
|
- <el-checkbox label="编辑" value="edited" />
|
|
|
- </el-checkbox-group>
|
|
|
- </el-form-item>
|
|
|
- </el-collapse-item>
|
|
|
- <!-- 样式 -->
|
|
|
- <el-collapse-item
|
|
|
- v-if="hasKey('styleMain') || hasKey('styleItems')"
|
|
|
- title="样式设置"
|
|
|
- name="style"
|
|
|
- >
|
|
|
- <el-collapse-item v-if="hasKey('styleMain')" class="p-5px bg-#00000080" title="主体样式">
|
|
|
- <el-collapse-item v-if="hasBackground" title="背景" class="p-5px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.border_radius')" label="圆角">
|
|
|
- <el-input-number v-model="data.styleMain.border_radius" :min="0" />
|
|
|
- </el-form-item>
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.bg_color')" label="背景色" class="flex-1">
|
|
|
- <el-input v-model="data.styleMain.bg_color" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.bg_opa')" label="透明度" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.bg_opa"
|
|
|
- :min="0"
|
|
|
- :max="1"
|
|
|
- :step="0.01"
|
|
|
- class="flex-1 mr-5px"
|
|
|
- />
|
|
|
- <el-color-picker v-model="data.styleMain.bg_color" class="w-40px" />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <el-form-item
|
|
|
- v-if="hasKey('styleMain.gradient')"
|
|
|
- label="背景渐变色"
|
|
|
- class="flex flex-1"
|
|
|
+ <el-scrollbar :height="'calc(100vh - 185px)'">
|
|
|
+ <el-form label-position="top" class="h-full">
|
|
|
+ <SplitterCollapse>
|
|
|
+ <SplitterCollapseItem title="组件属性" class="flex-none">
|
|
|
+ <el-collapse v-model="activeNames" class="p-10px">
|
|
|
+ <el-scrollbar
|
|
|
+ :height="
|
|
|
+ data.type && LvglWidgets[data.type].config.props && data.type != 'page'
|
|
|
+ ? 'calc(100vh - 280px)'
|
|
|
+ : ''
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <template
|
|
|
+ v-for="prop in data.type && LvglWidgets[data.type].config.props"
|
|
|
+ :key="prop.field"
|
|
|
>
|
|
|
- <el-input v-model="data.styleMain.gradient" class="flex-1" />
|
|
|
- <el-color-picker v-model="data.styleMain.gradient" class="w-40px mr-5px ml-5px" />
|
|
|
- <el-select
|
|
|
- v-if="hasKey('styleMain.gradient')"
|
|
|
- v-model="data.theme"
|
|
|
- placeholder="可选主题色"
|
|
|
- class="mt-10px"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.shade')" label="阴影" class="flex-1">
|
|
|
- <el-input-number v-model="data.styleMain.shade" :min="0" style="width: 100%" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.tint')" label="高光" class="flex-1">
|
|
|
- <el-input-number v-model="data.styleMain.tint" :min="0" style="width: 100%" />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <el-form-item v-if="hasKey('styleMain.gradient_direction')" label="渐变方向">
|
|
|
- <el-select v-model="data.styleMain.gradient_direction">
|
|
|
- <el-option label="无" value="none" />
|
|
|
- <el-option label="横向" value="horizontal" />
|
|
|
- <el-option label="纵向" value="vertical" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.LV_PART_Image')" label="背景图片">
|
|
|
- <el-input v-model="data.styleMain.LV_PART_Image" />
|
|
|
- </el-form-item>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item v-if="hasBorder" title="边框" class="p-5px">
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.border_color')" label="颜色" class="flex-1">
|
|
|
- <el-input v-model="data.styleMain.border_color" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.border_opa')" label="透明度" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.border_opa"
|
|
|
- :max="255"
|
|
|
- :min="0"
|
|
|
- class="flex-1"
|
|
|
- />
|
|
|
- <el-color-picker v-model="data.styleMain.border_color" class="ml-10px w-40px" />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <el-select
|
|
|
- v-if="hasKey('styleMain.border_color')"
|
|
|
- v-model="data.theme"
|
|
|
- placeholder="可选主题色"
|
|
|
- class="mt-10px mb-10px"
|
|
|
- />
|
|
|
- <el-form-item v-if="hasKey('styleMain.border_width')" label="宽度">
|
|
|
- <el-input-number v-model="data.styleMain.border_width" :min="0" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.border_style')" label="样式">
|
|
|
- <el-select v-model="data.styleMain.border_style">
|
|
|
- <el-option label="无" value="none" />
|
|
|
- <el-option label="实线" value="solid" />
|
|
|
- <el-option label="虚线" value="dashed" />
|
|
|
- <el-option label="点状" value="dotted" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item v-if="hasOutline" title="元素外框线" class="p-5px">
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.outline_color')" label="颜色" class="flex-1">
|
|
|
- <el-input v-model="data.styleMain.outline_color" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.outline_opa')" label="透明度" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.outline_opa"
|
|
|
- :max="255"
|
|
|
- :min="0"
|
|
|
- class="flex-1"
|
|
|
- />
|
|
|
- <el-color-picker v-model="data.styleMain.outline_color" class="ml-10px w-40px" />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <el-select
|
|
|
- v-if="hasKey('styleMain.outline_color')"
|
|
|
- v-model="data.theme"
|
|
|
- placeholder="可选主题色"
|
|
|
- class="mt-10px mb-10px"
|
|
|
- />
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item v-if="hasBoxShadow" title="阴影效果" class="p-5px">
|
|
|
- <div class="flex flex-1 gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.boxShadow_color')" label="颜色">
|
|
|
- <el-input v-model="data.styleMain.boxShadow_color" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- v-if="hasKey('styleMain.boxShadow_opa')"
|
|
|
- label="透明度"
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.boxShadow_opa"
|
|
|
- :max="255"
|
|
|
- :min="0"
|
|
|
- class="flex-1"
|
|
|
- />
|
|
|
- <el-color-picker
|
|
|
- v-model="data.styleMain.boxShadow_color"
|
|
|
- class="ml-10px w-40px"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item
|
|
|
- v-if="hasKey('styleMain.boxShadow_x')"
|
|
|
- label="水平偏移"
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.boxShadow_x"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- v-if="hasKey('styleMain.boxShadow_y')"
|
|
|
- label="垂直偏移"
|
|
|
- class="flex-1"
|
|
|
- >
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.boxShadow_y"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item
|
|
|
- v-if="hasKey('styleMain.boxShadow_blur')"
|
|
|
- label="模糊距离"
|
|
|
- class="flex-1"
|
|
|
+ <!-- 判断是否为 group 类型 -->
|
|
|
+ <template v-if="prop.valueType === 'group'">
|
|
|
+ <el-collapse-item :title="prop.label" :name="prop.label">
|
|
|
+ <div
|
|
|
+ v-for="child in prop.children"
|
|
|
+ :key="child.field"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ >
|
|
|
+ <el-form-item :label="child.label" class="flex w-full">
|
|
|
+ <el-input-number
|
|
|
+ v-if="child.valueType === 'number'"
|
|
|
+ v-model="data.props[child.field]"
|
|
|
+ :min="0"
|
|
|
+ :placeholder="child.componentProps.placeholder"
|
|
|
+ :readonly="child.componentProps.readOnly"
|
|
|
+ :disabled="child.componentProps.disabled"
|
|
|
+ style="width: 100%"
|
|
|
+ :step="0.1"
|
|
|
+ />
|
|
|
+ <el-input
|
|
|
+ v-if="child.valueType === 'text' && child.field === 'name'"
|
|
|
+ v-model="data[child.field]"
|
|
|
+ :placeholder="child.componentProps.placeholder"
|
|
|
+ :readonly="child.componentProps.readOnly"
|
|
|
+ :disabled="child.componentProps.disabled"
|
|
|
+ />
|
|
|
+ <el-input
|
|
|
+ v-if="child.valueType === 'text' && child.field !== 'name'"
|
|
|
+ v-model="data.props[child.field]"
|
|
|
+ :placeholder="child.componentProps.placeholder"
|
|
|
+ :readonly="child.componentProps.readOnly"
|
|
|
+ :disabled="child.componentProps.disabled"
|
|
|
+ />
|
|
|
+ <el-select
|
|
|
+ v-if="child.valueType === 'select'"
|
|
|
+ v-model="data.props[child.field]"
|
|
|
+ :placeholder="child.componentProps.placeholder"
|
|
|
+ :readonly="child.componentProps.readOnly"
|
|
|
+ :disabled="child.componentProps.disabled"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="select in child.componentProps.options"
|
|
|
+ :key="select.value"
|
|
|
+ :label="select.label"
|
|
|
+ :value="select.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <!-- <div class="chart-container">
|
|
|
+ <div class="chart-placeholder">xxx</div>
|
|
|
+ </div> -->
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 多选平铺 -->
|
|
|
+ <template
|
|
|
+ v-else-if="
|
|
|
+ prop.valueType === 'checkbox' &&
|
|
|
+ ['addFlags', 'removeFlags'].includes(prop.field)
|
|
|
+ "
|
|
|
>
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.boxShadow_blur"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
+ <el-collapse-item :title="prop.label" :name="prop.label">
|
|
|
+ <div class="flex flex-wrap gap-10px mb-10px">
|
|
|
+ <div
|
|
|
+ v-for="addFlags in prop.componentProps?.options"
|
|
|
+ :key="addFlags.value"
|
|
|
+ :class="[
|
|
|
+ 'bg-#333333',
|
|
|
+ 'h-[30px]',
|
|
|
+ 'rounded-[5px]',
|
|
|
+ 'line-height-[30px]',
|
|
|
+ 'text-center',
|
|
|
+ 'cursor-pointer',
|
|
|
+ { 'bg-[var(--accent-blue)]': isActive(prop, addFlags) }
|
|
|
+ ]"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ @click="handleClick(prop, addFlags)"
|
|
|
+ >
|
|
|
+ {{ addFlags.label }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 非 group 类型的字段 -->
|
|
|
+ <template v-else>
|
|
|
+ <el-form-item :label="prop.label">
|
|
|
+ <!-- 文本类型字段 -->
|
|
|
+ <el-input
|
|
|
+ v-if="prop.valueType === 'text' && prop.field === 'name'"
|
|
|
+ v-model="data[prop.field]"
|
|
|
+ :placeholder="prop.componentProps?.placeholder"
|
|
|
+ />
|
|
|
+ <el-input
|
|
|
+ v-if="prop.valueType === 'text' && prop.field !== 'name'"
|
|
|
+ v-model="data.props[prop.field]"
|
|
|
+ :placeholder="prop.componentProps?.placeholder"
|
|
|
+ />
|
|
|
+ <!-- 数字类型字段 -->
|
|
|
+ <el-input-number
|
|
|
+ v-if="prop.valueType === 'number'"
|
|
|
+ v-model="data.props[prop.field]"
|
|
|
+ style="width: 100%"
|
|
|
+ :min="0"
|
|
|
+ :step="0.1"
|
|
|
+ />
|
|
|
+ <!-- 下拉类型字段 -->
|
|
|
+ <el-select
|
|
|
+ v-if="prop.valueType === 'select'"
|
|
|
+ v-model="data.props[prop.field]"
|
|
|
+ :placeholder="prop.componentProps?.placeholder"
|
|
|
+ :readonly="prop.componentProps?.readOnly"
|
|
|
+ :disabled="prop.componentProps?.disabled"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="select in prop.componentProps?.options"
|
|
|
+ :key="select.value"
|
|
|
+ :label="select.label"
|
|
|
+ :value="select.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <!-- <div class="chart-container">
|
|
|
+ <div class="chart-placeholder"></div>
|
|
|
+ </div> -->
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </el-scrollbar>
|
|
|
+ </el-collapse>
|
|
|
+ </SplitterCollapseItem>
|
|
|
+
|
|
|
+ <!-- -->
|
|
|
+
|
|
|
+ <SplitterCollapseItem title="样式配置" class="flex-none">
|
|
|
+ <el-collapse v-model="activeNames" class="p-10px">
|
|
|
+ <el-scrollbar
|
|
|
+ :height="
|
|
|
+ data.type && LvglWidgets[data.type].config.styles && data.type != 'page'
|
|
|
+ ? 'calc(100vh - 280px)'
|
|
|
+ : ''
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <template
|
|
|
+ v-for="prop in data.type && LvglWidgets[data.type].config.styles"
|
|
|
+ :key="prop.field"
|
|
|
+ >
|
|
|
+ <el-form-item v-if="prop.field === 'part'" :label="prop.label" class="flex w-full">
|
|
|
+ <div class="flex flex-1 justify-between items-center">
|
|
|
+ <!-- 模块 -->
|
|
|
+ <el-select v-model="moduleValue" @change="handlePartChange">
|
|
|
+ <el-option
|
|
|
+ v-for="part in LvglWidgets[data.type].parts"
|
|
|
+ :key="part.name"
|
|
|
+ :label="part.name"
|
|
|
+ :value="part.name"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+
|
|
|
+ <!-- 状态 -->
|
|
|
+ <el-select v-model="stateValue" @change="handleStateChange">
|
|
|
+ <el-option
|
|
|
+ v-for="state in getStateList(moduleValue)"
|
|
|
+ :key="state"
|
|
|
+ :label="state"
|
|
|
+ :value="state"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <!-- 控制区域 -->
|
|
|
+ <el-icon style="width: 60px" class="cursor-pointer" @click="handleVisibleStyle"
|
|
|
+ ><View
|
|
|
+ /></el-icon>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
- <el-form-item
|
|
|
- v-if="hasKey('styleMain.boxShadow_spread')"
|
|
|
- label="扩散距离"
|
|
|
- class="flex-1"
|
|
|
+ </template>
|
|
|
+ <!-- 样式配置区域 -->
|
|
|
+ <template v-if="visibleStyle">
|
|
|
+ <template
|
|
|
+ v-for="prop in data.type && LvglWidgets[data.type].config.styles"
|
|
|
+ :key="prop.field"
|
|
|
>
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.boxShadow_spread"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item v-if="hasPadding" title="内边距" class="p-5px">
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.padding_top')" label="上" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.padding_top"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.padding_bottom')" label="下" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.padding_bottom"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <div class="flex gap-10px">
|
|
|
- <el-form-item v-if="hasKey('styleMain.padding_left')" label="左" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.padding_left"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item v-if="hasKey('styleMain.padding_right')" label="右" class="flex-1">
|
|
|
- <el-input-number
|
|
|
- v-model="data.styleMain.padding_right"
|
|
|
- :min="0"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- </el-collapse-item>
|
|
|
+ <!-- 固定依赖 -->
|
|
|
+ <el-form-item
|
|
|
+ v-if="prop.field !== 'part'"
|
|
|
+ :label="prop.label"
|
|
|
+ class="flex w-full"
|
|
|
+ >
|
|
|
+ <el-input />
|
|
|
+ </el-form-item>
|
|
|
|
|
|
- <el-collapse-item v-if="hasKey('styleItems')" class="p-5px bg-#00000080" title="子项样式">
|
|
|
- 123
|
|
|
- </el-collapse-item>
|
|
|
- </el-collapse-item>
|
|
|
- </el-collapse>
|
|
|
+ <!-- 动态显示依赖项 -->
|
|
|
+ <template v-if="prop.valueType === 'dependency'">
|
|
|
+ <el-form-item
|
|
|
+ v-for="dependency in getDynamicFields(prop)"
|
|
|
+ :key="dependency.field"
|
|
|
+ :label="dependency.label"
|
|
|
+ >
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </el-scrollbar>
|
|
|
+ </el-collapse>
|
|
|
+ </SplitterCollapseItem>
|
|
|
+ </SplitterCollapse>
|
|
|
</el-form>
|
|
|
</el-scrollbar>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, watch, computed } from 'vue'
|
|
|
+import { ref, watch } from 'vue'
|
|
|
import type { Page } from '@/types/page'
|
|
|
+import LvglWidgets from '@/lvgl-widgets'
|
|
|
+import { View } from '@element-plus/icons-vue'
|
|
|
+import { SplitterCollapse, SplitterCollapseItem } from '@/components/SplitterCollapse'
|
|
|
+
|
|
|
interface Emits {
|
|
|
(e: 'update:selected', val: Page['props']): void
|
|
|
}
|
|
|
@@ -294,78 +240,139 @@ const props = defineProps<{
|
|
|
const emit = defineEmits<Emits>()
|
|
|
const data = ref<Page['props']>(props.selected || ({} as Page['props']))
|
|
|
watch(data, (val) => emit('update:selected', val))
|
|
|
-const hasKey = (path: string) => {
|
|
|
- const keys = path.split('.')
|
|
|
- let obj = data.value as Page['props']
|
|
|
|
|
|
- for (const key of keys) {
|
|
|
- if (!obj || !Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
|
- return false
|
|
|
+watch(
|
|
|
+ () => props.selected,
|
|
|
+ (value) => {
|
|
|
+ if (value) {
|
|
|
+ moduleValue.value = LvglWidgets[data.value.type]?.parts[0].name
|
|
|
+ stateValue.value = LvglWidgets[data.value.type]?.parts[0].stateList[0]
|
|
|
+ data.value = value || ({} as Page['props'])
|
|
|
+ console.log(value)
|
|
|
}
|
|
|
- obj = obj[key]
|
|
|
}
|
|
|
- return true
|
|
|
+)
|
|
|
+
|
|
|
+const activeNames = ref<string[]>(['基本属性', '位置/大小', '添加标识', '删除标识'])
|
|
|
+
|
|
|
+const moduleValue = ref('main')
|
|
|
+const stateValue = ref('default')
|
|
|
+const visibleStyle = ref(true)
|
|
|
+
|
|
|
+const loadStyle = async (name) => {
|
|
|
+ try {
|
|
|
+ const Json = await import(`@/lvgl-widgets/${name}/style.json`)
|
|
|
+ return Json.default
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const getStateList = (partName) => {
|
|
|
+ const part = LvglWidgets[data.value.type].parts.find((item) => item.name === partName)
|
|
|
+ return part ? part.stateList : []
|
|
|
}
|
|
|
|
|
|
-const activeNames = ref<string[]>(['transform', 'style'])
|
|
|
+const isActive = (prop, addFlags) => {
|
|
|
+ return data.value.props[prop.field].some((item) => item.value === addFlags.value)
|
|
|
+}
|
|
|
|
|
|
-const hasBackground = computed(() => {
|
|
|
- const sm = data.value.styleMain || {}
|
|
|
- return (
|
|
|
- sm.border_radius !== undefined ||
|
|
|
- sm.bg_color !== undefined ||
|
|
|
- sm.bg_opa !== undefined ||
|
|
|
- sm.gradient !== undefined ||
|
|
|
- sm.shade !== undefined ||
|
|
|
- sm.tint !== undefined ||
|
|
|
- sm.gradient_direction !== undefined ||
|
|
|
- sm.LV_PART_Image !== undefined
|
|
|
- )
|
|
|
-})
|
|
|
+const handleClick = (prop, addFlags) => {
|
|
|
+ const selectedOptions = data.value.props[prop.field]
|
|
|
|
|
|
-const hasBorder = computed(() => {
|
|
|
- const sm = data.value.styleMain || {}
|
|
|
- return (
|
|
|
- sm.border_color !== undefined ||
|
|
|
- sm.border_opa !== undefined ||
|
|
|
- sm.border_width !== undefined ||
|
|
|
- sm.border_style !== undefined
|
|
|
- )
|
|
|
-})
|
|
|
+ const index = selectedOptions.findIndex((item) => item.value === addFlags.value)
|
|
|
|
|
|
-const hasOutline = computed(() => {
|
|
|
- const sm = data.value.styleMain || {}
|
|
|
- return sm.outline_color !== undefined || sm.outline_opa !== undefined
|
|
|
-})
|
|
|
+ if (index !== -1) {
|
|
|
+ selectedOptions.splice(index, 1)
|
|
|
+ } else {
|
|
|
+ selectedOptions.push(addFlags)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleVisibleStyle = () => {
|
|
|
+ visibleStyle.value = !visibleStyle.value
|
|
|
+}
|
|
|
+
|
|
|
+const handlePartChange = (targetPartName) => {
|
|
|
+ const existingPart = data.value.style.find((item) => item.part.name === targetPartName)
|
|
|
+ if (!existingPart) {
|
|
|
+ loadStyle(data.value.props.name).then((loadedStyle) => {
|
|
|
+ if (loadedStyle) {
|
|
|
+ const targetPart = loadedStyle.part.find((item) => item.partName === moduleValue.value)
|
|
|
+
|
|
|
+ if (targetPart) {
|
|
|
+ const targetStyle = targetPart.state.find((item) => item.state === targetPart)
|
|
|
+
|
|
|
+ if (targetStyle) {
|
|
|
+ targetStyle.style.part = {
|
|
|
+ name: moduleValue.value,
|
|
|
+ state: targetPart
|
|
|
+ }
|
|
|
+ data.value.style.push(targetStyle.style)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-const hasBoxShadow = computed(() => {
|
|
|
- const sm = data.value.styleMain || {}
|
|
|
- return (
|
|
|
- sm.box_shadow_color !== undefined ||
|
|
|
- sm.box_shadow_alpha !== undefined ||
|
|
|
- sm.box_shadow_x !== undefined ||
|
|
|
- sm.box_shadow_y !== undefined ||
|
|
|
- sm.box_shadow_blur !== undefined ||
|
|
|
- sm.box_shadow_spread !== undefined
|
|
|
- )
|
|
|
-})
|
|
|
+const handleStateChange = (targetState) => {
|
|
|
+ const existingState = data.value.style.find((item) => item.part.state === targetState)
|
|
|
|
|
|
-const hasPadding = computed(() => {
|
|
|
- const sm = data.value.styleMain || {}
|
|
|
- return (
|
|
|
- sm.padding_top !== undefined ||
|
|
|
- sm.padding_bottom !== undefined ||
|
|
|
- sm.padding_left !== undefined ||
|
|
|
- sm.padding_right !== undefined
|
|
|
- )
|
|
|
-})
|
|
|
+ if (!existingState) {
|
|
|
+ loadStyle(data.value.props.name).then((loadedStyle) => {
|
|
|
+ if (loadedStyle) {
|
|
|
+ const targetPart = loadedStyle.part.find((item) => item.partName === moduleValue.value)
|
|
|
+
|
|
|
+ if (targetPart) {
|
|
|
+ const targetStyle = targetPart.state.find((item) => item.state === targetState)
|
|
|
+
|
|
|
+ if (targetStyle) {
|
|
|
+ targetStyle.style.part = {
|
|
|
+ name: moduleValue.value,
|
|
|
+ state: targetState
|
|
|
+ }
|
|
|
+ data.value.style.push(targetStyle.style)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const getDynamicFields = (prop) => {
|
|
|
+ if (prop.valueType === 'dependency' && prop.name && Array.isArray(prop.name)) {
|
|
|
+ const fieldValues = prop.name.reduce((values, field) => {
|
|
|
+ if (field === 'part') {
|
|
|
+ values[field] = moduleValue.value
|
|
|
+ } else {
|
|
|
+ values[field] = data.value[field] || data.value.props[field]
|
|
|
+ }
|
|
|
+
|
|
|
+ return values
|
|
|
+ }, {})
|
|
|
+
|
|
|
+ return prop.dependency(fieldValues) || []
|
|
|
+ }
|
|
|
+ return []
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="less">
|
|
|
-:deep(.el-form-item) {
|
|
|
- margin-bottom: 5px;
|
|
|
-}
|
|
|
:deep(.el-collapse-item__header) {
|
|
|
padding-right: 0px;
|
|
|
}
|
|
|
+:deep(.el-collapse-item__content) {
|
|
|
+ padding-bottom: 0;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 0 10px;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-scrollbar__view) {
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+:deep(.flex-none) {
|
|
|
+ flex: none !important;
|
|
|
+}
|
|
|
</style>
|