UNPKG

element-plus

Version:

A Component Library for Vue3.0

130 lines (112 loc) 2.98 kB
import { ref, computed, watch, isVNode } from 'vue' import { isValidComponentSize } from '@element-plus/utils/validators' import { isNumber, isArray, isString } from '@element-plus/utils/util' import type { PropType, ExtractPropTypes, CSSProperties, VNodeChild } from 'vue' const SizeMap: Record<ComponentSize, number> = { mini: 4, small: 8, medium: 12, large: 16, } export const defaultProps = { direction: { type: String as PropType<'horizontal' | 'vertical'>, default: 'horizontal', }, class: { type: [String, Object, Array], default: '', }, style: { type: [String, Array, Object] as PropType< string | Array<any> | CSSProperties >, }, alignment: { type: String as PropType<''>, default: 'center', }, prefixCls: { type: String, }, spacer: { type: [Object, String, Number] as PropType<VNodeChild>, default: null, validator: (val: unknown) => { return isVNode(val) || isNumber(val) || isString(val) }, }, wrap: { type: Boolean, default: false, }, size: { type: [String, Array, Number] as PropType< ComponentSize | [number, number] | number >, validator: (val: unknown) => { return ( isValidComponentSize(val as string) || isNumber(val) || isArray(val) ) }, }, } export function useSpace(props: ExtractPropTypes<typeof defaultProps>) { const classes = computed(() => [ 'el-space', `el-space--${props.direction}`, props.class, ]) const horizontalSize = ref(0) const verticalSize = ref(0) watch( () => [props.size, props.wrap, props.direction], ([size = 'small', wrap, dir]) => { // when the specified size have been given if (isArray(size)) { const [h = 0, v = 0] = size horizontalSize.value = h verticalSize.value = v } else { let val: number if (isNumber(size)) { val = size as number } else { val = SizeMap[size as string] || SizeMap.small } if (wrap && dir === 'horizontal') { horizontalSize.value = verticalSize.value = val } else { if (dir === 'horizontal') { horizontalSize.value = val verticalSize.value = 0 } else { verticalSize.value = val horizontalSize.value = 0 } } } }, { immediate: true }, ) const containerStyle = computed(() => { const wrapKls: CSSProperties = props.wrap ? { flexWrap: 'wrap', marginBottom: `-${verticalSize.value}px` } : null const alignment: CSSProperties = { alignItems: props.alignment, } return [wrapKls, alignment, props.style] as Array<CSSProperties> }) const itemStyle = computed(() => { return { paddingBottom: `${verticalSize.value}px`, marginRight: `${horizontalSize.value}px`, } }) return { classes, containerStyle, itemStyle, } }