|
@@ -0,0 +1,373 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="config pr-20px pl-20px h-[calc(100vh-198px)] overflow-auto">
|
|
|
|
|
+ <el-form label-position="top">
|
|
|
|
|
+ <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 v-model="data.x" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('y')" label="Y" class="flex-1">
|
|
|
|
|
+ <el-input v-model="data.y" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="flex gap-10px">
|
|
|
|
|
+ <el-form-item v-if="hasKey('width')" label="宽度" class="flex-1">
|
|
|
|
|
+ <el-input v-model="data.width" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('height')" label="高度" class="flex-1">
|
|
|
|
|
+ <el-input v-model="data.height" />
|
|
|
|
|
+ </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.borderRadius')" label="圆角">
|
|
|
|
|
+ <el-input-number v-model="data.styleMain.borderRadius" :min="0" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <div class="flex gap-10px">
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.bgColor')" label="背景色" class="flex-1">
|
|
|
|
|
+ <el-input v-model="data.styleMain.bgColor" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.bgAlpha')" label="透明度" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.bgAlpha"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :max="1"
|
|
|
|
|
+ :step="0.01"
|
|
|
|
|
+ class="flex-1 mr-5px"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-color-picker v-model="data.styleMain.bgColor" class="w-40px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-form-item
|
|
|
|
|
+ v-if="hasKey('styleMain.gradient')"
|
|
|
|
|
+ label="背景渐变色"
|
|
|
|
|
+ class="flex flex-1"
|
|
|
|
|
+ >
|
|
|
|
|
+ <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.gradientDirection')" label="渐变方向">
|
|
|
|
|
+ <el-select v-model="data.styleMain.gradientDirection">
|
|
|
|
|
+ <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.bgImage')" label="背景图片">
|
|
|
|
|
+ <el-input v-model="data.styleMain.bgImage" />
|
|
|
|
|
+ </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.borderColor')" label="颜色" class="flex-1">
|
|
|
|
|
+ <el-input v-model="data.styleMain.borderColor" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.borderAlpha')" label="透明度" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.borderAlpha"
|
|
|
|
|
+ :max="255"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ class="flex-1"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-color-picker v-model="data.styleMain.borderColor" class="ml-10px w-40px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-if="hasKey('styleMain.borderColor')"
|
|
|
|
|
+ v-model="data.theme"
|
|
|
|
|
+ placeholder="可选主题色"
|
|
|
|
|
+ class="mt-10px mb-10px"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.borderWidth')" label="宽度">
|
|
|
|
|
+ <el-input-number v-model="data.styleMain.borderWidth" :min="0" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.borderStyle')" label="样式">
|
|
|
|
|
+ <el-select v-model="data.styleMain.borderStyle">
|
|
|
|
|
+ <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.outlineColor')" label="颜色" class="flex-1">
|
|
|
|
|
+ <el-input v-model="data.styleMain.outlineColor" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.outlineAlpha')" label="透明度" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.outlineAlpha"
|
|
|
|
|
+ :max="255"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ class="flex-1"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-color-picker v-model="data.styleMain.outlineColor" class="ml-10px w-40px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-if="hasKey('styleMain.outlineColor')"
|
|
|
|
|
+ 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.boxShadowColor')" label="颜色">
|
|
|
|
|
+ <el-input v-model="data.styleMain.boxShadowColor" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item
|
|
|
|
|
+ v-if="hasKey('styleMain.boxShadowAlpha')"
|
|
|
|
|
+ label="透明度"
|
|
|
|
|
+ class="flex-1"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.boxShadowAlpha"
|
|
|
|
|
+ :max="255"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ class="flex-1"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-color-picker v-model="data.styleMain.boxShadowColor" class="ml-10px w-40px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="flex gap-10px">
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.boxShadowX')" label="水平偏移" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.boxShadowX"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.boxShadowY')" label="垂直偏移" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.boxShadowY"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="flex gap-10px">
|
|
|
|
|
+ <el-form-item
|
|
|
|
|
+ v-if="hasKey('styleMain.boxShadowBlur')"
|
|
|
|
|
+ label="模糊距离"
|
|
|
|
|
+ class="flex-1"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.boxShadowBlur"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item
|
|
|
|
|
+ v-if="hasKey('styleMain.boxShadowSpread')"
|
|
|
|
|
+ label="扩散距离"
|
|
|
|
|
+ class="flex-1"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.boxShadowSpread"
|
|
|
|
|
+ :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.paddingTop')" label="上" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.paddingTop"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.paddingBottom')" label="下" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.paddingBottom"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="flex gap-10px">
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.paddingLeft')" label="左" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.paddingLeft"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item v-if="hasKey('styleMain.paddingRight')" label="右" class="flex-1">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="data.styleMain.paddingRight"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-collapse-item>
|
|
|
|
|
+ </el-collapse-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-collapse-item v-if="hasKey('styleItems')" class="p-5px bg-#00000080" title="子项样式">
|
|
|
|
|
+ 123
|
|
|
|
|
+ </el-collapse-item>
|
|
|
|
|
+ </el-collapse-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 事件 -->
|
|
|
|
|
+ <el-collapse-item v-if="hasKey('events')" title="事件" name="events">
|
|
|
|
|
+ <div class="flex justify-center items-center">
|
|
|
|
|
+ <el-button type="primary">添加事件</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-collapse-item>
|
|
|
|
|
+ </el-collapse>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { ref, watch, defineEmits, computed } from 'vue'
|
|
|
|
|
+import type { Page } from '@/types/page'
|
|
|
|
|
+interface Emits {
|
|
|
|
|
+ (e: 'update:selected', val: Page['props']): void
|
|
|
|
|
+}
|
|
|
|
|
+const props = defineProps<{
|
|
|
|
|
+ selected?: Page['props']
|
|
|
|
|
+}>()
|
|
|
|
|
+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
|
|
|
|
|
+ }
|
|
|
|
|
+ obj = obj[key]
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const activeNames = ref<string[]>(['transform', 'style'])
|
|
|
|
|
+
|
|
|
|
|
+const hasBackground = computed(() => {
|
|
|
|
|
+ const sm = data.value.styleMain || {}
|
|
|
|
|
+ return (
|
|
|
|
|
+ sm.borderRadius !== undefined ||
|
|
|
|
|
+ sm.bgColor !== undefined ||
|
|
|
|
|
+ sm.bgAlpha !== undefined ||
|
|
|
|
|
+ sm.gradient !== undefined ||
|
|
|
|
|
+ sm.shade !== undefined ||
|
|
|
|
|
+ sm.tint !== undefined ||
|
|
|
|
|
+ sm.gradientDirection !== undefined ||
|
|
|
|
|
+ sm.bgImage !== undefined
|
|
|
|
|
+ )
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const hasBorder = computed(() => {
|
|
|
|
|
+ const sm = data.value.styleMain || {}
|
|
|
|
|
+ return (
|
|
|
|
|
+ sm.borderColor !== undefined ||
|
|
|
|
|
+ sm.borderAlpha !== undefined ||
|
|
|
|
|
+ sm.borderWidth !== undefined ||
|
|
|
|
|
+ sm.borderStyle !== undefined
|
|
|
|
|
+ )
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const hasOutline = computed(() => {
|
|
|
|
|
+ const sm = data.value.styleMain || {}
|
|
|
|
|
+ return sm.outlineColor !== undefined || sm.outlineAlpha !== undefined
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const hasBoxShadow = computed(() => {
|
|
|
|
|
+ const sm = data.value.styleMain || {}
|
|
|
|
|
+ return (
|
|
|
|
|
+ sm.boxShadowColor !== undefined ||
|
|
|
|
|
+ sm.boxShadowAlpha !== undefined ||
|
|
|
|
|
+ sm.boxShadowX !== undefined ||
|
|
|
|
|
+ sm.boxShadowY !== undefined ||
|
|
|
|
|
+ sm.boxShadowBlur !== undefined ||
|
|
|
|
|
+ sm.boxShadowSpread !== undefined
|
|
|
|
|
+ )
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const hasPadding = computed(() => {
|
|
|
|
|
+ const sm = data.value.styleMain || {}
|
|
|
|
|
+ return (
|
|
|
|
|
+ sm.paddingTop !== undefined ||
|
|
|
|
|
+ sm.paddingBottom !== undefined ||
|
|
|
|
|
+ sm.paddingLeft !== undefined ||
|
|
|
|
|
+ sm.paddingRight !== undefined
|
|
|
|
|
+ )
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="less">
|
|
|
|
|
+:deep(.el-form-item) {
|
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
|
+}
|
|
|
|
|
+// :deep(.el-input__wrapper) {
|
|
|
|
|
+// box-shadow: none !important;
|
|
|
|
|
+// border-radius: 0 !important;
|
|
|
|
|
+// border: none !important;
|
|
|
|
|
+// border-bottom: 1px solid #dcdfe6 !important;
|
|
|
|
|
+// box-sizing: border-box !important;
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+// :deep(.el-input__wrapper.is-focus) {
|
|
|
|
|
+// box-shadow: none !important;
|
|
|
|
|
+// border-bottom: 1px solid #409eff !important;
|
|
|
|
|
+// }
|
|
|
|
|
+</style>
|