mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-11-29 17:58:08 +08:00
refactor(components): refactor space (#3757)
This commit is contained in:
parent
23a2ac5515
commit
3b9e63d587
@ -1,6 +1,6 @@
|
|||||||
import { nextTick, h } from 'vue'
|
import { nextTick, h } from 'vue'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import Space from '../src/index'
|
import Space from '../src/space'
|
||||||
|
|
||||||
const AXIOM = 'Rem is the best girl'
|
const AXIOM = 'Rem is the best girl'
|
||||||
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import Space from './src/index'
|
import { withInstall } from '@element-plus/utils/with-install'
|
||||||
|
|
||||||
import type { App } from 'vue'
|
import Space from './src/space'
|
||||||
import type { SFCWithInstall } from '@element-plus/utils/types'
|
|
||||||
|
|
||||||
const _Space = Space as SFCWithInstall<typeof Space>
|
export const ElSpace = withInstall(Space)
|
||||||
|
export default ElSpace
|
||||||
|
|
||||||
_Space.install = (app: App) => {
|
export * from './src/space'
|
||||||
app.component(_Space.name, _Space)
|
export * from './src/use-space'
|
||||||
}
|
|
||||||
|
|
||||||
export default _Space
|
|
||||||
export const ElSpace = _Space
|
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
import {
|
|
||||||
defineComponent,
|
|
||||||
renderSlot,
|
|
||||||
createVNode,
|
|
||||||
createTextVNode,
|
|
||||||
isVNode,
|
|
||||||
} from 'vue'
|
|
||||||
import {
|
|
||||||
PatchFlags,
|
|
||||||
isFragment,
|
|
||||||
isValidElementNode,
|
|
||||||
} from '@element-plus/utils/vnode'
|
|
||||||
import { isArray } from '@element-plus/utils/util'
|
|
||||||
import Item from './item.vue'
|
|
||||||
import { useSpace, defaultProps } from './useSpace'
|
|
||||||
|
|
||||||
import type { VNode, ExtractPropTypes, Slots } from 'vue'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'ElSpace',
|
|
||||||
props: defaultProps,
|
|
||||||
setup(props) {
|
|
||||||
return useSpace(props)
|
|
||||||
},
|
|
||||||
|
|
||||||
render(
|
|
||||||
ctx: ReturnType<typeof useSpace> &
|
|
||||||
ExtractPropTypes<typeof defaultProps> & { $slots: Slots }
|
|
||||||
) {
|
|
||||||
const {
|
|
||||||
classes,
|
|
||||||
$slots,
|
|
||||||
containerStyle,
|
|
||||||
itemStyle,
|
|
||||||
spacer,
|
|
||||||
prefixCls,
|
|
||||||
direction,
|
|
||||||
} = ctx
|
|
||||||
|
|
||||||
const children = renderSlot($slots, 'default', { key: 0 }, () => [])
|
|
||||||
// retrieve the children out via a simple for loop
|
|
||||||
// the edge case here is that when users uses directives like <v-for>, <v-if>
|
|
||||||
// we need to go one layer deeper
|
|
||||||
|
|
||||||
if (children.children.length === 0) return null
|
|
||||||
|
|
||||||
// loop the children, if current children is rendered via `renderList` or `<v-for>`
|
|
||||||
if (isArray(children.children)) {
|
|
||||||
let extractedChildren = []
|
|
||||||
children.children.forEach((child: VNode, loopKey) => {
|
|
||||||
if (isFragment(child)) {
|
|
||||||
if (isArray(child.children)) {
|
|
||||||
child.children.forEach((nested, key) => {
|
|
||||||
extractedChildren.push(
|
|
||||||
createVNode(
|
|
||||||
Item,
|
|
||||||
{
|
|
||||||
style: itemStyle,
|
|
||||||
prefixCls,
|
|
||||||
key: `nested-${key}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: () => [nested as VNode],
|
|
||||||
},
|
|
||||||
PatchFlags.PROPS | PatchFlags.STYLE,
|
|
||||||
['style', 'prefixCls']
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// if the current child is valid vnode, then append this current vnode
|
|
||||||
// to item as child node.
|
|
||||||
} else if (isValidElementNode(child)) {
|
|
||||||
extractedChildren.push(
|
|
||||||
createVNode(
|
|
||||||
Item,
|
|
||||||
{
|
|
||||||
style: itemStyle,
|
|
||||||
prefixCls,
|
|
||||||
key: `LoopKey${loopKey}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: () => [child as VNode],
|
|
||||||
},
|
|
||||||
PatchFlags.PROPS | PatchFlags.STYLE,
|
|
||||||
['style', 'prefixCls']
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (spacer) {
|
|
||||||
// track the current rendering index, when encounters the last element
|
|
||||||
// then no need to add a spacer after it.
|
|
||||||
const len = extractedChildren.length - 1
|
|
||||||
extractedChildren = extractedChildren.reduce((acc, child, idx) => {
|
|
||||||
return idx === len
|
|
||||||
? [...acc, child]
|
|
||||||
: [
|
|
||||||
...acc,
|
|
||||||
child,
|
|
||||||
createVNode(
|
|
||||||
'span',
|
|
||||||
// adding width 100% for vertical alignment,
|
|
||||||
// when the spacer inherit the width from the
|
|
||||||
// parent, this span's width was not set, so space
|
|
||||||
// might disappear
|
|
||||||
{
|
|
||||||
style: [
|
|
||||||
itemStyle,
|
|
||||||
direction === 'vertical' ? 'width: 100%' : null,
|
|
||||||
],
|
|
||||||
key: idx,
|
|
||||||
},
|
|
||||||
[
|
|
||||||
// if spacer is already a valid vnode, then append it to the current
|
|
||||||
// span element.
|
|
||||||
// otherwise, treat it as string.
|
|
||||||
isVNode(spacer)
|
|
||||||
? spacer
|
|
||||||
: createTextVNode(spacer as string, PatchFlags.TEXT),
|
|
||||||
],
|
|
||||||
PatchFlags.STYLE
|
|
||||||
),
|
|
||||||
]
|
|
||||||
}, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
// spacer container.
|
|
||||||
return createVNode(
|
|
||||||
'div',
|
|
||||||
{
|
|
||||||
class: classes,
|
|
||||||
style: containerStyle,
|
|
||||||
},
|
|
||||||
extractedChildren,
|
|
||||||
PatchFlags.STYLE | PatchFlags.CLASS
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return children.children
|
|
||||||
},
|
|
||||||
})
|
|
@ -1,22 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="classes">
|
<div :class="classes">
|
||||||
<slot></slot>
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, computed } from 'vue'
|
import { defineComponent, computed } from 'vue'
|
||||||
|
import { buildProps } from '@element-plus/utils/props'
|
||||||
|
|
||||||
|
const spaceItem = buildProps({
|
||||||
|
prefixCls: {
|
||||||
|
type: String,
|
||||||
|
default: 'el-space',
|
||||||
|
},
|
||||||
|
} as const)
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: spaceItem,
|
||||||
prefixCls: {
|
|
||||||
type: String,
|
|
||||||
default: 'el-space',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
const classes = computed(() => [`${props.prefixCls}__item`])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
classes: computed(() => `${props.prefixCls}__item`),
|
classes,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
208
packages/components/space/src/space.ts
Normal file
208
packages/components/space/src/space.ts
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
renderSlot,
|
||||||
|
createVNode,
|
||||||
|
createTextVNode,
|
||||||
|
isVNode,
|
||||||
|
} from 'vue'
|
||||||
|
import { isString } from '@vue/shared'
|
||||||
|
import {
|
||||||
|
PatchFlags,
|
||||||
|
isFragment,
|
||||||
|
isValidElementNode,
|
||||||
|
} from '@element-plus/utils/vnode'
|
||||||
|
import { isArray, isNumber } from '@element-plus/utils/util'
|
||||||
|
import {
|
||||||
|
buildProps,
|
||||||
|
componentSize,
|
||||||
|
definePropType,
|
||||||
|
} from '@element-plus/utils/props'
|
||||||
|
import Item from './item.vue'
|
||||||
|
import { useSpace } from './use-space'
|
||||||
|
|
||||||
|
import type { VNode, StyleValue, ExtractPropTypes, VNodeChild } from 'vue'
|
||||||
|
import type { AlignItemsProperty } from 'csstype'
|
||||||
|
|
||||||
|
export const spaceProps = buildProps({
|
||||||
|
direction: {
|
||||||
|
type: String,
|
||||||
|
values: ['horizontal', 'vertical'],
|
||||||
|
default: 'horizontal',
|
||||||
|
},
|
||||||
|
|
||||||
|
class: {
|
||||||
|
type: definePropType<string | string[] | Record<string, boolean>>([
|
||||||
|
String,
|
||||||
|
Object,
|
||||||
|
Array,
|
||||||
|
]),
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
|
||||||
|
style: {
|
||||||
|
type: definePropType<StyleValue>([String, Array, Object]),
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
|
||||||
|
alignment: {
|
||||||
|
type: definePropType<AlignItemsProperty>(String),
|
||||||
|
default: 'center',
|
||||||
|
},
|
||||||
|
|
||||||
|
prefixCls: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
spacer: {
|
||||||
|
type: definePropType<VNodeChild>([Object, String, Number, Array]),
|
||||||
|
default: null,
|
||||||
|
validator: (val: unknown) => isVNode(val) || isNumber(val) || isString(val),
|
||||||
|
},
|
||||||
|
|
||||||
|
wrap: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
fill: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
fillRatio: {
|
||||||
|
type: Number,
|
||||||
|
default: 100,
|
||||||
|
},
|
||||||
|
|
||||||
|
size: {
|
||||||
|
type: [String, Array, Number],
|
||||||
|
values: componentSize,
|
||||||
|
validator: (val: unknown): val is [number, number] | number => {
|
||||||
|
return (
|
||||||
|
isNumber(val) ||
|
||||||
|
(isArray(val) && val.length === 2 && val.every((i) => isNumber(i)))
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const)
|
||||||
|
export type SpaceProps = ExtractPropTypes<typeof spaceProps>
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ElSpace',
|
||||||
|
|
||||||
|
props: spaceProps,
|
||||||
|
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const { classes, containerStyle, itemStyle } = useSpace(props)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const { spacer, prefixCls, direction } = props
|
||||||
|
|
||||||
|
const children = renderSlot(slots, 'default', { key: 0 }, () => [])
|
||||||
|
// retrieve the children out via a simple for loop
|
||||||
|
// the edge case here is that when users uses directives like <v-for>, <v-if>
|
||||||
|
// we need to go one layer deeper
|
||||||
|
|
||||||
|
if ((children.children ?? []).length === 0) return null
|
||||||
|
|
||||||
|
// loop the children, if current children is rendered via `renderList` or `<v-for>`
|
||||||
|
if (isArray(children.children)) {
|
||||||
|
let extractedChildren: VNode[] = []
|
||||||
|
children.children.forEach((child, loopKey) => {
|
||||||
|
if (isFragment(child)) {
|
||||||
|
if (isArray(child.children)) {
|
||||||
|
child.children.forEach((nested, key) => {
|
||||||
|
extractedChildren.push(
|
||||||
|
createVNode(
|
||||||
|
Item,
|
||||||
|
{
|
||||||
|
style: itemStyle.value,
|
||||||
|
prefixCls,
|
||||||
|
key: `nested-${key}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () => [nested],
|
||||||
|
},
|
||||||
|
PatchFlags.PROPS | PatchFlags.STYLE,
|
||||||
|
['style', 'prefixCls']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// if the current child is valid vnode, then append this current vnode
|
||||||
|
// to item as child node.
|
||||||
|
} else if (isValidElementNode(child)) {
|
||||||
|
extractedChildren.push(
|
||||||
|
createVNode(
|
||||||
|
Item,
|
||||||
|
{
|
||||||
|
style: itemStyle.value,
|
||||||
|
prefixCls,
|
||||||
|
key: `LoopKey${loopKey}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () => [child],
|
||||||
|
},
|
||||||
|
PatchFlags.PROPS | PatchFlags.STYLE,
|
||||||
|
['style', 'prefixCls']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (spacer) {
|
||||||
|
// track the current rendering index, when encounters the last element
|
||||||
|
// then no need to add a spacer after it.
|
||||||
|
const len = extractedChildren.length - 1
|
||||||
|
extractedChildren = extractedChildren.reduce<VNode[]>(
|
||||||
|
(acc, child, idx) => {
|
||||||
|
const children = [...acc, child]
|
||||||
|
if (idx !== len) {
|
||||||
|
children.push(
|
||||||
|
createVNode(
|
||||||
|
'span',
|
||||||
|
// adding width 100% for vertical alignment,
|
||||||
|
// when the spacer inherit the width from the
|
||||||
|
// parent, this span's width was not set, so space
|
||||||
|
// might disappear
|
||||||
|
{
|
||||||
|
style: [
|
||||||
|
itemStyle.value,
|
||||||
|
direction === 'vertical' ? 'width: 100%' : null,
|
||||||
|
],
|
||||||
|
key: idx,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
// if spacer is already a valid vnode, then append it to the current
|
||||||
|
// span element.
|
||||||
|
// otherwise, treat it as string.
|
||||||
|
isVNode(spacer)
|
||||||
|
? spacer
|
||||||
|
: createTextVNode(spacer as string, PatchFlags.TEXT),
|
||||||
|
],
|
||||||
|
PatchFlags.STYLE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return children
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// spacer container.
|
||||||
|
return createVNode(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
class: classes.value,
|
||||||
|
style: containerStyle.value,
|
||||||
|
},
|
||||||
|
extractedChildren,
|
||||||
|
PatchFlags.STYLE | PatchFlags.CLASS
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return children.children
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
84
packages/components/space/src/use-space.ts
Normal file
84
packages/components/space/src/use-space.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { ref, computed, watchEffect } from 'vue'
|
||||||
|
import { isNumber } from '@element-plus/utils/util'
|
||||||
|
import type { SpaceProps } from './space'
|
||||||
|
|
||||||
|
import type { CSSProperties, StyleValue } from 'vue'
|
||||||
|
import type { ComponentSize } from '@element-plus/utils/types'
|
||||||
|
|
||||||
|
const SIZE_MAP: Record<ComponentSize, number> = {
|
||||||
|
mini: 4,
|
||||||
|
small: 8,
|
||||||
|
medium: 12,
|
||||||
|
large: 16,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSpace(props: SpaceProps) {
|
||||||
|
const classes = computed(() => [
|
||||||
|
'el-space',
|
||||||
|
`el-space--${props.direction}`,
|
||||||
|
props.class,
|
||||||
|
])
|
||||||
|
|
||||||
|
const horizontalSize = ref(0)
|
||||||
|
const verticalSize = ref(0)
|
||||||
|
|
||||||
|
const containerStyle = computed<StyleValue>(() => {
|
||||||
|
const wrapKls: CSSProperties =
|
||||||
|
props.wrap || props.fill
|
||||||
|
? { flexWrap: 'wrap', marginBottom: `-${verticalSize.value}px` }
|
||||||
|
: {}
|
||||||
|
const alignment: CSSProperties = {
|
||||||
|
alignItems: props.alignment,
|
||||||
|
}
|
||||||
|
return [wrapKls, alignment, props.style]
|
||||||
|
})
|
||||||
|
|
||||||
|
const itemStyle = computed<StyleValue>(() => {
|
||||||
|
const itemBaseStyle: CSSProperties = {
|
||||||
|
paddingBottom: `${verticalSize.value}px`,
|
||||||
|
marginRight: `${horizontalSize.value}px`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const fillStyle: CSSProperties = props.fill
|
||||||
|
? { flexGrow: 1, minWidth: `${props.fillRatio}%` }
|
||||||
|
: {}
|
||||||
|
|
||||||
|
return [itemBaseStyle, fillStyle]
|
||||||
|
})
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
const { size = 'small', wrap, direction: dir, fill } = props
|
||||||
|
|
||||||
|
// when the specified size have been given
|
||||||
|
if (Array.isArray(size)) {
|
||||||
|
const [h = 0, v = 0] = size
|
||||||
|
horizontalSize.value = h
|
||||||
|
verticalSize.value = v
|
||||||
|
} else {
|
||||||
|
let val: number
|
||||||
|
if (isNumber(size)) {
|
||||||
|
val = size
|
||||||
|
} else {
|
||||||
|
val = SIZE_MAP[size] || SIZE_MAP.small
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wrap || fill) && dir === 'horizontal') {
|
||||||
|
horizontalSize.value = verticalSize.value = val
|
||||||
|
} else {
|
||||||
|
if (dir === 'horizontal') {
|
||||||
|
horizontalSize.value = val
|
||||||
|
verticalSize.value = 0
|
||||||
|
} else {
|
||||||
|
verticalSize.value = val
|
||||||
|
horizontalSize.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
classes,
|
||||||
|
containerStyle,
|
||||||
|
itemStyle,
|
||||||
|
}
|
||||||
|
}
|
@ -1,147 +0,0 @@
|
|||||||
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'
|
|
||||||
import type { ComponentSize } from '@element-plus/utils/types'
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
|
|
||||||
fill: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
fillRatio: {
|
|
||||||
type: Number,
|
|
||||||
default: 100,
|
|
||||||
},
|
|
||||||
|
|
||||||
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, props.fill],
|
|
||||||
([size = 'small', wrap, dir, fill]) => {
|
|
||||||
// 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 || fill) && 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 || props.fill
|
|
||||||
? { flexWrap: 'wrap', marginBottom: `-${verticalSize.value}px` }
|
|
||||||
: null
|
|
||||||
const alignment: CSSProperties = {
|
|
||||||
alignItems: props.alignment,
|
|
||||||
}
|
|
||||||
return [wrapKls, alignment, props.style] as Array<CSSProperties>
|
|
||||||
})
|
|
||||||
|
|
||||||
const itemStyle = computed(() => {
|
|
||||||
const itemBaseStyle = {
|
|
||||||
paddingBottom: `${verticalSize.value}px`,
|
|
||||||
marginRight: `${horizontalSize.value}px`,
|
|
||||||
}
|
|
||||||
|
|
||||||
const fillStyle = props.fill
|
|
||||||
? { flexGrow: 1, minWidth: `${props.fillRatio}%` }
|
|
||||||
: null
|
|
||||||
|
|
||||||
return [itemBaseStyle, fillStyle] as Array<CSSProperties>
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
classes,
|
|
||||||
containerStyle,
|
|
||||||
itemStyle,
|
|
||||||
}
|
|
||||||
}
|
|
@ -32,7 +32,7 @@ type BuildPropOption<T, D, R, V, C> = {
|
|||||||
|
|
||||||
type IfUnknown<T, V> = [unknown] extends T ? V : T
|
type IfUnknown<T, V> = [unknown] extends T ? V : T
|
||||||
|
|
||||||
type BuildPropType<T, V, C> =
|
export type BuildPropType<T, V, C> =
|
||||||
| (T extends PropWrapper<unknown>
|
| (T extends PropWrapper<unknown>
|
||||||
? T[typeof wrapperKey]
|
? T[typeof wrapperKey]
|
||||||
: [V] extends [never]
|
: [V] extends [never]
|
||||||
|
@ -144,8 +144,8 @@ export {
|
|||||||
extend,
|
extend,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isBool = (val: unknown) => typeof val === 'boolean'
|
export const isBool = (val: unknown): val is boolean => typeof val === 'boolean'
|
||||||
export const isNumber = (val: unknown) => typeof val === 'number'
|
export const isNumber = (val: unknown): val is number => typeof val === 'number'
|
||||||
export const isHTMLElement = (val: unknown) => toRawType(val).startsWith('HTML')
|
export const isHTMLElement = (val: unknown) => toRawType(val).startsWith('HTML')
|
||||||
|
|
||||||
export function rafThrottle<T extends AnyFunction<any>>(
|
export function rafThrottle<T extends AnyFunction<any>>(
|
||||||
|
@ -35,8 +35,8 @@ export enum PatchFlags {
|
|||||||
BAIL = -2,
|
BAIL = -2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isFragment = (node: VNodeChild) =>
|
export const isFragment = (node: unknown): node is VNode =>
|
||||||
(node as VNode).type === Fragment
|
isVNode(node) && node.type === Fragment
|
||||||
|
|
||||||
export const isText = (node: VNodeChild) => (node as VNode).type === Text
|
export const isText = (node: VNodeChild) => (node as VNode).type === Text
|
||||||
|
|
||||||
@ -64,8 +64,8 @@ function getChildren(node: VNode, depth: number): undefined | VNode {
|
|||||||
* determine if the element is a valid element type rather than fragments and comment e.g. <template> v-if
|
* determine if the element is a valid element type rather than fragments and comment e.g. <template> v-if
|
||||||
* @param node {VNode} node to be tested
|
* @param node {VNode} node to be tested
|
||||||
*/
|
*/
|
||||||
export const isValidElementNode = (node: VNodeChild) =>
|
export const isValidElementNode = (node: unknown): node is VNode =>
|
||||||
!(isFragment(node) || isComment(node))
|
isVNode(node) && !isFragment(node) && !isComment(node)
|
||||||
|
|
||||||
export const getFirstValidNode = (
|
export const getFirstValidNode = (
|
||||||
nodes: VNodeChild,
|
nodes: VNodeChild,
|
||||||
|
Loading…
Reference in New Issue
Block a user