|
|
|
@ -1,6 +1,6 @@
|
|
|
|
|
import { |
|
|
|
|
inject, |
|
|
|
|
ref, |
|
|
|
|
Ref, |
|
|
|
|
App, |
|
|
|
|
defineComponent, |
|
|
|
|
PropType, |
|
|
|
@ -10,6 +10,11 @@ import {
|
|
|
|
|
onMounted, |
|
|
|
|
onBeforeUnmount, |
|
|
|
|
Plugin, |
|
|
|
|
CSSProperties, |
|
|
|
|
provide, |
|
|
|
|
toRef, |
|
|
|
|
InjectionKey, |
|
|
|
|
computed, |
|
|
|
|
} from 'vue'; |
|
|
|
|
import warning from '../_util/warning'; |
|
|
|
|
import ResponsiveObserve, { |
|
|
|
@ -17,12 +22,12 @@ import ResponsiveObserve, {
|
|
|
|
|
responsiveArray, |
|
|
|
|
ScreenMap, |
|
|
|
|
} from '../_util/responsiveObserve'; |
|
|
|
|
import { defaultConfigProvider } from '../config-provider'; |
|
|
|
|
import Row from './Row'; |
|
|
|
|
import PropTypes from '../_util/vue-types'; |
|
|
|
|
import { tuple } from '../_util/type'; |
|
|
|
|
import { cloneElement } from '../_util/vnode'; |
|
|
|
|
import { filterEmpty } from '../_util/props-util'; |
|
|
|
|
import { flattenChildren } from '../_util/props-util'; |
|
|
|
|
import useConfigInject from '../_util/hooks/useConfigInject'; |
|
|
|
|
|
|
|
|
|
export const DescriptionsItemProps = { |
|
|
|
|
prefixCls: PropTypes.string, |
|
|
|
@ -30,15 +35,22 @@ export const DescriptionsItemProps = {
|
|
|
|
|
span: PropTypes.number, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const descriptionsItemProp = { |
|
|
|
|
prefixCls: PropTypes.string, |
|
|
|
|
label: PropTypes.VNodeChild, |
|
|
|
|
labelStyle: PropTypes.style, |
|
|
|
|
contentStyle: PropTypes.style, |
|
|
|
|
span: PropTypes.number.def(1), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export type DescriptionsItemProp = Partial<ExtractPropTypes<typeof descriptionsItemProp>>; |
|
|
|
|
|
|
|
|
|
export const DescriptionsItem = defineComponent({ |
|
|
|
|
name: 'ADescriptionsItem', |
|
|
|
|
props: { |
|
|
|
|
prefixCls: PropTypes.string, |
|
|
|
|
label: PropTypes.VNodeChild, |
|
|
|
|
span: PropTypes.number.def(1), |
|
|
|
|
}, |
|
|
|
|
render() { |
|
|
|
|
return null; |
|
|
|
|
props: descriptionsItemProp, |
|
|
|
|
slots: ['label'], |
|
|
|
|
setup(_, { slots }) { |
|
|
|
|
return () => slots.default?.(); |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
@ -87,7 +99,7 @@ function getFilledItem(node: VNode, span: number | undefined, rowRestCol: number
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getRows(children: VNode[], column: number) { |
|
|
|
|
const childNodes = filterEmpty(children); |
|
|
|
|
const childNodes = flattenChildren(children); |
|
|
|
|
const rows: VNode[][] = []; |
|
|
|
|
|
|
|
|
|
let tmpRow: VNode[] = []; |
|
|
|
@ -130,17 +142,29 @@ const descriptionsProps = {
|
|
|
|
|
}, |
|
|
|
|
layout: PropTypes.oneOf(tuple('horizontal', 'vertical')), |
|
|
|
|
colon: PropTypes.looseBool, |
|
|
|
|
labelStyle: PropTypes.style, |
|
|
|
|
contentStyle: PropTypes.style, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export type DescriptionsProps = HTMLAttributes & |
|
|
|
|
Partial<ExtractPropTypes<typeof descriptionsProps>>; |
|
|
|
|
|
|
|
|
|
export interface DescriptionsContextProp { |
|
|
|
|
labelStyle?: Ref<CSSProperties>; |
|
|
|
|
contentStyle?: Ref<CSSProperties>; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export const descriptionsContext: InjectionKey<DescriptionsContextProp> = Symbol( |
|
|
|
|
'descriptionsContext', |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const Descriptions = defineComponent({ |
|
|
|
|
name: 'ADescriptions', |
|
|
|
|
props: descriptionsProps, |
|
|
|
|
slots: ['title', 'extra'], |
|
|
|
|
Item: DescriptionsItem, |
|
|
|
|
setup(props, { slots }) { |
|
|
|
|
const { getPrefixCls } = inject('configProvider', defaultConfigProvider); |
|
|
|
|
const { prefixCls, direction } = useConfigInject('descriptions', props); |
|
|
|
|
|
|
|
|
|
let token: number; |
|
|
|
|
|
|
|
|
@ -160,10 +184,15 @@ const Descriptions = defineComponent({
|
|
|
|
|
ResponsiveObserve.unsubscribe(token); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
provide(descriptionsContext, { |
|
|
|
|
labelStyle: toRef(props, 'labelStyle'), |
|
|
|
|
contentStyle: toRef(props, 'contentStyle'), |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const mergeColumn = computed(() => getColumn(props.column, screens.value)); |
|
|
|
|
|
|
|
|
|
return () => { |
|
|
|
|
const { |
|
|
|
|
prefixCls: customizePrefixCls, |
|
|
|
|
column, |
|
|
|
|
size, |
|
|
|
|
bordered = false, |
|
|
|
|
layout = 'horizontal', |
|
|
|
@ -172,28 +201,27 @@ const Descriptions = defineComponent({
|
|
|
|
|
extra = slots.extra?.(), |
|
|
|
|
} = props; |
|
|
|
|
|
|
|
|
|
const prefixCls = getPrefixCls('descriptions', customizePrefixCls); |
|
|
|
|
const mergeColumn = getColumn(column, screens.value); |
|
|
|
|
const children = slots.default?.(); |
|
|
|
|
const rows = getRows(children, mergeColumn); |
|
|
|
|
const rows = getRows(children, mergeColumn.value); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div |
|
|
|
|
class={[ |
|
|
|
|
prefixCls, |
|
|
|
|
prefixCls.value, |
|
|
|
|
{ |
|
|
|
|
[`${prefixCls}-${size}`]: size !== 'default', |
|
|
|
|
[`${prefixCls}-bordered`]: !!bordered, |
|
|
|
|
[`${prefixCls.value}-${size}`]: size !== 'default', |
|
|
|
|
[`${prefixCls.value}-bordered`]: !!bordered, |
|
|
|
|
[`${prefixCls.value}-rtl`]: direction.value === 'rtl', |
|
|
|
|
}, |
|
|
|
|
]} |
|
|
|
|
> |
|
|
|
|
{(title || extra) && ( |
|
|
|
|
<div class={`${prefixCls}-header`}> |
|
|
|
|
<div class={`${prefixCls}-title`}>{title}</div> |
|
|
|
|
<div class={`${prefixCls}-extra`}>{extra}</div> |
|
|
|
|
<div class={`${prefixCls.value}-header`}> |
|
|
|
|
{title && <div class={`${prefixCls.value}-title`}>{title}</div>} |
|
|
|
|
{extra && <div class={`${prefixCls.value}-extra`}>{extra}</div>} |
|
|
|
|
</div> |
|
|
|
|
)} |
|
|
|
|
<div class={`${prefixCls}-view`}> |
|
|
|
|
<div class={`${prefixCls.value}-view`}> |
|
|
|
|
<table> |
|
|
|
|
<tbody> |
|
|
|
|
{rows.map((row, index) => ( |
|
|
|
@ -201,7 +229,7 @@ const Descriptions = defineComponent({
|
|
|
|
|
key={index} |
|
|
|
|
index={index} |
|
|
|
|
colon={colon} |
|
|
|
|
prefixCls={prefixCls} |
|
|
|
|
prefixCls={prefixCls.value} |
|
|
|
|
vertical={layout === 'vertical'} |
|
|
|
|
bordered={bordered} |
|
|
|
|
row={row} |
|
|
|
|