|
|
@@ -0,0 +1,112 @@
|
|
|
+<template>
|
|
|
+ <div :style="getProps.mainStyle">
|
|
|
+ <div :style="getProps.indicatorStyle"></div>
|
|
|
+ <div class="ml-8px">{{ props.text }}</div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { computed, type CSSProperties } from 'vue'
|
|
|
+import defaultStyle from './style.json'
|
|
|
+
|
|
|
+const props = defineProps<{
|
|
|
+ width?: number
|
|
|
+ height?: number
|
|
|
+ text?: string
|
|
|
+ styles: any
|
|
|
+ state?: string
|
|
|
+}>()
|
|
|
+
|
|
|
+const getProps = computed((): Record<string, CSSProperties> => {
|
|
|
+ const styles = props.styles
|
|
|
+
|
|
|
+ let mainStyle = styles.find((item) => item.state === props.state && item.part.name === 'main')
|
|
|
+ let indicatorStyle = styles.find((item) => item.part.name === 'indicator')
|
|
|
+
|
|
|
+ // 从默认样式获取样式
|
|
|
+ if (!mainStyle && props.state) {
|
|
|
+ mainStyle = defaultStyle.part
|
|
|
+ ?.find((item) => item.partName === 'main')
|
|
|
+ ?.state.find((item) => item.state === props.state)?.style
|
|
|
+ }
|
|
|
+ if (!indicatorStyle && props.state) {
|
|
|
+ indicatorStyle = defaultStyle.part
|
|
|
+ ?.find((item) => item.partName === 'selected')
|
|
|
+ ?.state.find((item) => item.state === 'checked')?.style
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ mainStyle: {
|
|
|
+ boxSizing: 'border-box',
|
|
|
+
|
|
|
+ backgroundColor: mainStyle?.background.color,
|
|
|
+
|
|
|
+ fontSize: `${mainStyle?.text.size}px`,
|
|
|
+ color: mainStyle?.text?.color,
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'center',
|
|
|
+ justifyContent: 'left',
|
|
|
+ fontWeight: mainStyle?.text?.weight === 'bold' ? 'bold' : 'normal',
|
|
|
+
|
|
|
+ borderRadius: `${mainStyle?.border.radius}px`,
|
|
|
+ borderStyle: 'solid',
|
|
|
+ borderColor: 'transparent',
|
|
|
+ borderWidth: `${mainStyle?.border.width}px`,
|
|
|
+ borderTopColor:
|
|
|
+ mainStyle?.border?.side?.includes('all') || mainStyle?.border?.side?.includes('top')
|
|
|
+ ? mainStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ borderRightColor:
|
|
|
+ mainStyle?.border?.side?.includes('all') || mainStyle?.border?.side?.includes('right')
|
|
|
+ ? mainStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ borderBottomColor:
|
|
|
+ mainStyle?.border?.side?.includes('all') || mainStyle?.border?.side?.includes('bottom')
|
|
|
+ ? mainStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ borderLeftColor:
|
|
|
+ mainStyle?.border?.side?.includes('all') || mainStyle?.border?.side?.includes('left')
|
|
|
+ ? mainStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ // 内边距
|
|
|
+ padding: `${mainStyle?.padding?.top}px ${mainStyle?.padding?.right}px ${mainStyle?.padding?.bottom}px ${mainStyle?.padding?.left}px`,
|
|
|
+ /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半径 | 阴影颜色 */
|
|
|
+ boxShadow: mainStyle?.shadow
|
|
|
+ ? `${mainStyle?.shadow?.x}px ${mainStyle?.shadow?.y}px ${mainStyle?.shadow?.width}px ${mainStyle?.shadow?.spread}px ${mainStyle?.shadow?.color}`
|
|
|
+ : 'none'
|
|
|
+ },
|
|
|
+ indicatorStyle: {
|
|
|
+ flexShrink: 0,
|
|
|
+ height: '16px',
|
|
|
+ width: '16px',
|
|
|
+ backgroundColor: indicatorStyle?.background.color,
|
|
|
+
|
|
|
+ borderRadius: `${indicatorStyle?.border.radius}px`,
|
|
|
+ borderStyle: 'solid',
|
|
|
+ borderColor: 'transparent',
|
|
|
+ borderWidth: `${indicatorStyle?.border.width}px`,
|
|
|
+ borderTopColor:
|
|
|
+ indicatorStyle?.border?.side?.includes('all') ||
|
|
|
+ indicatorStyle?.border?.side?.includes('top')
|
|
|
+ ? indicatorStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ borderRightColor:
|
|
|
+ indicatorStyle?.border?.side?.includes('all') ||
|
|
|
+ indicatorStyle?.border?.side?.includes('right')
|
|
|
+ ? indicatorStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ borderBottomColor:
|
|
|
+ indicatorStyle?.border?.side?.includes('all') ||
|
|
|
+ indicatorStyle?.border?.side?.includes('bottom')
|
|
|
+ ? indicatorStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ borderLeftColor:
|
|
|
+ indicatorStyle?.border?.side?.includes('all') ||
|
|
|
+ indicatorStyle?.border?.side?.includes('left')
|
|
|
+ ? indicatorStyle?.border?.color
|
|
|
+ : 'transparent',
|
|
|
+ padding: `${indicatorStyle?.padding?.left}px`
|
|
|
+ }
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|