refactor: cascader checkbox collapse comment description divider by ts

pull/2992/head
tanjinzhou 2020-10-14 17:57:38 +08:00
parent c732d09745
commit db31c526d9
18 changed files with 266 additions and 185 deletions

View File

@ -3,7 +3,7 @@ import Select from '../select';
import { Group, Button } from '../radio';
import PropTypes from '../_util/vue-types';
import { defaultConfigProvider } from '../config-provider';
import { VueNode } from 'components/_util/type';
import { VueNode } from '../_util/type';
const { Option } = Select;

View File

@ -1,5 +1,5 @@
import { App, defineComponent, inject, provide, PropType } from 'vue';
import PropTypes, { withUndefined } from '../_util/vue-types';
import { App, inject, provide, PropType, defineComponent, CSSProperties } from 'vue';
import PropTypes from '../_util/vue-types';
import VcCascader from '../vc-cascader';
import arrayTreeFilter from 'array-tree-filter';
import classNames from '../_util/classNames';
@ -23,7 +23,8 @@ import BaseMixin from '../_util/BaseMixin';
import { cloneElement } from '../_util/vnode';
import warning from '../_util/warning';
import { defaultConfigProvider } from '../config-provider';
import { tuple, VueNode } from 'components/_util/type';
import { tuple, VueNode } from '../_util/type';
import { RenderEmptyHandler } from '../config-provider/renderEmpty';
export interface CascaderOptionType {
value?: string | number;
@ -31,7 +32,7 @@ export interface CascaderOptionType {
disabled?: boolean;
isLeaf?: boolean;
loading?: boolean;
children?: Array<CascaderOptionType>;
children?: CascaderOptionType[];
[key: string]: any;
}
@ -90,7 +91,7 @@ function noop() {}
const CascaderProps = {
/** 可选项数据源 */
options: { type: Array as PropType<CascaderOptionType>, default: [] },
options: { type: Array as PropType<CascaderOptionType[]>, default: [] },
/** 默认的选中项 */
defaultValue: PropTypes.array,
/** 指定选中项 */
@ -116,8 +117,8 @@ const CascaderProps = {
/** 是否支持清除*/
allowClear: PropTypes.looseBool.def(true),
showSearch: {
type: [Boolean, Object] as PropType<ShowSearchType>,
default: undefined,
type: [Boolean, Object] as PropType<boolean | ShowSearchType | undefined>,
default: undefined as PropType<boolean | ShowSearchType | undefined>,
},
notFoundContent: PropTypes.VNodeChild,
loadData: PropTypes.func,
@ -143,8 +144,6 @@ const CascaderProps = {
'onUpdate:value': PropTypes.func,
};
type CascaderPropsTypes = typeof CascaderProps;
// We limit the filtered item count by default
const defaultLimit = 50;
@ -169,7 +168,7 @@ function defaultSortFilteredOption(
return a.findIndex(callback) - b.findIndex(callback);
}
function getFilledFieldNames(props: CascaderPropsTypes) {
function getFilledFieldNames(props: any) {
const fieldNames = (props.fieldNames || {}) as FieldNamesType;
const names: FilledFieldNamesType = {
children: fieldNames.children || 'children',
@ -181,7 +180,7 @@ function getFilledFieldNames(props: CascaderPropsTypes) {
function flattenTree(
options: CascaderOptionType[],
props: CascaderPropsTypes,
props: any,
ancestor: CascaderOptionType[] = [],
) {
const names: FilledFieldNamesType = getFilledFieldNames(props);
@ -201,7 +200,7 @@ function flattenTree(
const defaultDisplayRender = ({ labels }) => labels.join(' / ');
const Cascader = {
const Cascader = defineComponent({
inheritAttrs: false,
name: 'ACascader',
mixins: [BaseMixin],
@ -216,11 +215,13 @@ const Cascader = {
setup() {
return {
configProvider: inject('configProvider', defaultConfigProvider),
localeData: inject('localeData', {}),
localeData: inject('localeData', {} as any),
cachedOptions: [],
popupRef: undefined,
input: undefined,
};
},
data() {
this.cachedOptions = [];
const { value, defaultValue, popupVisible, showSearch, options } = this.$props;
return {
sValue: value || defaultValue || [],
@ -246,15 +247,15 @@ const Cascader = {
},
options(val) {
if (this.showSearch) {
this.setState({ flattenOptions: flattenTree(val, this.$props) });
this.setState({ flattenOptions: flattenTree(val, this.$props as any) });
}
},
},
methods: {
savePopupRef(ref) {
savePopupRef(ref: any) {
this.popupRef = ref;
},
highlightKeyword(str, keyword, prefixCls) {
highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
return str
.split(keyword)
.map((node, index) =>
@ -264,7 +265,13 @@ const Cascader = {
);
},
defaultRenderFilteredOption({ inputValue, path, prefixCls, names }) {
defaultRenderFilteredOption(opt: {
inputValue: string,
path: CascaderOptionType[],
prefixCls: string | undefined,
names: FilledFieldNamesType,
}) {
const { inputValue, path, prefixCls, names } = opt
return path.map((option, index) => {
const label = option[names.label];
const node =
@ -274,10 +281,10 @@ const Cascader = {
return index === 0 ? node : [' / ', node];
});
},
saveInput(node) {
saveInput(node: any) {
this.input = node;
},
handleChange(value, selectedOptions) {
handleChange(value: any, selectedOptions: CascaderOptionType[]) {
this.setState({ inputValue: '' });
if (selectedOptions[0].__IS_FILTERED_OPTION) {
const unwrappedValue = value[0];
@ -288,9 +295,9 @@ const Cascader = {
this.setValue(value, selectedOptions);
},
handlePopupVisibleChange(popupVisible) {
handlePopupVisibleChange(popupVisible: boolean) {
if (!hasProp(this, 'popupVisible')) {
this.setState(state => ({
this.setState((state: any) => ({
sPopupVisible: popupVisible,
inputFocused: popupVisible,
inputValue: popupVisible ? state.inputValue : '',
@ -298,18 +305,18 @@ const Cascader = {
}
this.$emit('popupVisibleChange', popupVisible);
},
handleInputFocus(e) {
handleInputFocus(e: InputEvent) {
this.$emit('focus', e);
},
handleInputBlur(e) {
handleInputBlur(e: InputEvent) {
this.setState({
inputFocused: false,
});
this.$emit('blur', e);
},
handleInputClick(e) {
handleInputClick(e: MouseEvent & {nativeEvent?: any}) {
const { inputFocused, sPopupVisible } = this;
// Prevent `Trigger` behaviour.
if (inputFocused || sPopupVisible) {
@ -320,19 +327,19 @@ const Cascader = {
}
},
handleKeyDown(e) {
handleKeyDown(e: KeyboardEvent) {
if (e.keyCode === KeyCode.BACKSPACE || e.keyCode === KeyCode.SPACE) {
e.stopPropagation();
}
},
handleInputChange(e) {
const inputValue = e.target.value;
handleInputChange(e: Event) {
const inputValue = (e.target as any).value;
this.setState({ inputValue });
this.$emit('search', inputValue);
},
setValue(value, selectedOptions) {
setValue(value: string[] | number[], selectedOptions: CascaderOptionType[] = []) {
if (!hasProp(this, 'value')) {
this.setState({ sValue: value });
}
@ -355,7 +362,7 @@ const Cascader = {
return displayRender({ labels, selectedOptions });
},
clearSelection(e) {
clearSelection(e: MouseEvent) {
e.preventDefault();
e.stopPropagation();
if (!this.inputValue) {
@ -366,23 +373,23 @@ const Cascader = {
}
},
generateFilteredOptions(prefixCls, renderEmpty) {
generateFilteredOptions(prefixCls: string | undefined, renderEmpty: RenderEmptyHandler) {
const { showSearch, notFoundContent } = this;
const names = getFilledFieldNames(this.$props);
const names: FilledFieldNamesType = getFilledFieldNames(this.$props);
const {
filter = defaultFilterOption,
// render = this.defaultRenderFilteredOption,
sort = defaultSortFilteredOption,
limit = defaultLimit,
} = showSearch;
} = showSearch as ShowSearchType;
const render =
showSearch.render ||
(showSearch as ShowSearchType).render ||
getComponent(this, 'showSearchRender') ||
this.defaultRenderFilteredOption;
const { flattenOptions = [], inputValue } = this.$data;
// Limit the filter if needed
let filtered;
let filtered: Array<CascaderOptionType[]>
if (limit > 0) {
filtered = [];
let matchCount = 0;
@ -453,7 +460,7 @@ const Cascader = {
showSearch = false,
notFoundContent,
...otherProps
} = props;
} = props as any;
const { onEvents, extraAttrs } = splitAttrs(this.$attrs);
const { class: className, style, ...restAttrs } = extraAttrs;
const getPrefixCls = this.configProvider.getPrefixCls;
@ -536,7 +543,7 @@ const Cascader = {
this.cachedOptions = options;
}
const dropdownMenuColumnStyle = {};
const dropdownMenuColumnStyle: CSSProperties = {};
const isNotFound =
(options || []).length === 1 && options[0].value === 'ANT_CASCADER_NOT_FOUND';
if (isNotFound) {
@ -609,7 +616,7 @@ const Cascader = {
};
return <VcCascader {...cascaderProps}>{input}</VcCascader>;
},
};
});
Cascader.install = function(app: App) {
app.component(Cascader.name, Cascader);

View File

@ -1,4 +1,4 @@
import { inject } from 'vue';
import { defineComponent, inject } from 'vue';
import PropTypes from '../_util/vue-types';
import classNames from '../_util/classNames';
import VcCheckbox from '../vc-checkbox';
@ -7,7 +7,7 @@ import { defaultConfigProvider } from '../config-provider';
import warning from '../_util/warning';
function noop() {}
export default {
export default defineComponent({
name: 'ACheckbox',
inheritAttrs: false,
__ANT_CHECKBOX: true,
@ -65,17 +65,17 @@ export default {
}
},
methods: {
handleChange(event) {
const targetChecked = event.target.checked;
handleChange(event: Event) {
const targetChecked = (event.target as any).checked;
this.$emit('update:checked', targetChecked);
// this.$emit('input', targetChecked);
this.$emit('change', event);
},
focus() {
this.$refs.vcCheckbox.focus();
(this.$refs.vcCheckbox as any).focus();
},
blur() {
this.$refs.vcCheckbox.blur();
(this.$refs.vcCheckbox as any).blur();
},
},
@ -93,8 +93,8 @@ export default {
class: className,
style,
...restAttrs
} = $attrs;
const checkboxProps = {
} = $attrs as any;
const checkboxProps: any = {
...restProps,
prefixCls,
...restAttrs,
@ -126,12 +126,12 @@ export default {
<label
class={classString}
style={style}
onMouseenter={onMouseenter}
onMouseenter={onMouseleave}
onMouseenter={onMouseenter as EventHandlerNonNull}
onMouseleave={onMouseleave as EventHandlerNonNull}
>
<VcCheckbox {...checkboxProps} class={checkboxClass} ref="vcCheckbox" />
{children.length ? <span>{children}</span> : null}
</label>
);
},
};
});

View File

@ -1,18 +1,27 @@
import { inject, provide } from 'vue';
import { defineComponent, inject, PropType, provide } from 'vue';
import PropTypes from '../_util/vue-types';
import Checkbox from './Checkbox';
import hasProp, { getSlot } from '../_util/props-util';
import { defaultConfigProvider } from '../config-provider';
import { VueNode } from '../_util/type';
export type CheckboxValueType = string | number | boolean;
export interface CheckboxOptionType {
label: VueNode;
value: CheckboxValueType;
disabled?: boolean;
indeterminate?: boolean;
onChange?: (e: Event) => void;
}
function noop() {}
export default {
export default defineComponent({
name: 'ACheckboxGroup',
props: {
name: PropTypes.string,
prefixCls: PropTypes.string,
defaultValue: PropTypes.array,
value: PropTypes.array,
options: PropTypes.array.def([]),
defaultValue: { type: Array as PropType<Array<CheckboxValueType>>},
value: { type: Array as PropType<Array<CheckboxValueType>>},
options: {type: Array as PropType<Array<CheckboxOptionType | string>>},
disabled: PropTypes.looseBool,
onChange: PropTypes.func,
},
@ -54,14 +63,14 @@ export default {
return { ...option, label };
});
},
cancelValue(value) {
cancelValue(value: CheckboxValueType) {
this.registeredValues = this.registeredValues.filter(val => val !== value);
},
registerValue(value) {
registerValue(value: CheckboxValueType) {
this.registeredValues = [...this.registeredValues, value];
},
toggleOption(option) {
toggleOption(option: CheckboxOptionType) {
const { registeredValues } = this;
const optionIndex = this.sValue.indexOf(option.value);
const value = [...this.sValue];
@ -111,4 +120,4 @@ export default {
}
return <div class={groupPrefixCls}>{children}</div>;
},
};
});

View File

@ -1,10 +1,11 @@
import { App } from 'vue';
import Checkbox from './Checkbox';
import CheckboxGroup from './Group';
Checkbox.Group = CheckboxGroup;
/* istanbul ignore next */
Checkbox.install = function(app) {
Checkbox.install = function(app: App) {
app.component(Checkbox.name, Checkbox);
app.component(CheckboxGroup.name, CheckboxGroup);
return app;

View File

@ -1,32 +1,53 @@
import { inject } from 'vue';
import { CSSProperties, defineComponent, inject, PropType } from 'vue';
import animation from '../_util/openAnimation';
import {
getOptionProps,
initDefaultProps,
getComponent,
isValidElement,
getSlot,
} from '../_util/props-util';
import { cloneElement } from '../_util/vnode';
import VcCollapse, { collapseProps } from '../vc-collapse';
import VcCollapse from '../vc-collapse';
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import { defaultConfigProvider } from '../config-provider';
import PropTypes from '../_util/vue-types';
import { tuple, VueNode } from '../_util/type';
export default {
interface PanelProps {
isActive?: boolean;
header?: VueNode;
className?: string;
class?: string;
style?: CSSProperties;
showArrow?: boolean;
forceRender?: boolean;
disabled?: boolean;
extra?: VueNode;
}
type ActiveKeyType = Array<string | number> | string | number;
export default defineComponent({
name: 'ACollapse',
inheritAttrs: false,
props: initDefaultProps(collapseProps(), {
bordered: true,
openAnimation: animation,
expandIconPosition: 'left',
}),
props: {
prefixCls: PropTypes.string,
activeKey: {type: [Array, Number, String] as PropType<ActiveKeyType>},
defaultActiveKey: {type: [Array, Number, String] as PropType<ActiveKeyType>},
accordion: PropTypes.looseBool,
destroyInactivePanel: PropTypes.looseBool,
bordered: PropTypes.looseBool.def(true),
expandIcon: PropTypes.func,
openAnimation: PropTypes.object.def(animation),
expandIconPosition: PropTypes.oneOf(tuple('left', 'right')).def('left'),
'onUpdate:activeKey': PropTypes.func,
onChange: PropTypes.func,
},
setup() {
return {
configProvider: inject('configProvider', defaultConfigProvider),
};
},
methods: {
renderExpandIcon(panelProps, prefixCls) {
renderExpandIcon(panelProps: PanelProps={}, prefixCls: string) {
const expandIcon = getComponent(this, 'expandIcon', panelProps);
const icon = expandIcon || <RightOutlined rotate={panelProps.isActive ? 90 : undefined} />;
return isValidElement(Array.isArray(expandIcon) ? icon[0] : icon)
@ -35,7 +56,7 @@ export default {
})
: icon;
},
handleChange(activeKey) {
handleChange(activeKey: ActiveKeyType) {
this.$emit('update:activeKey', activeKey);
this.$emit('change', activeKey);
},
@ -44,7 +65,7 @@ export default {
const { prefixCls: customizePrefixCls, bordered, expandIconPosition } = this;
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
const { class: className, ...restAttrs } = this.$attrs;
const { class: className, ...restAttrs } = this.$attrs as any;
const collapseClassName = {
[className]: className,
[`${prefixCls}-borderless`]: !bordered,
@ -53,13 +74,12 @@ export default {
const rcCollapeProps = {
...getOptionProps(this),
prefixCls,
expandIcon: panelProps => this.renderExpandIcon(panelProps, prefixCls),
expandIcon: (panelProps: PanelProps) => this.renderExpandIcon(panelProps, prefixCls),
class: collapseClassName,
...restAttrs,
onChange: this.handleChange,
'onUpdate:change': undefined,
};
return <VcCollapse {...rcCollapeProps}>{getSlot(this)}</VcCollapse>;
},
};
});

View File

@ -1,13 +1,26 @@
import { inject } from 'vue';
import { defineComponent, inject } from 'vue';
import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
import VcCollapse, { panelProps } from '../vc-collapse';
import VcCollapse from '../vc-collapse';
import { defaultConfigProvider } from '../config-provider';
import PropTypes from '../_util/vue-types';
export default {
export default defineComponent({
name: 'ACollapsePanel',
inheritAttrs: false,
props: {
...panelProps(),
openAnimation: PropTypes.object,
prefixCls: PropTypes.string,
header: PropTypes.VNodeChild,
headerClass: PropTypes.string,
showArrow: PropTypes.looseBool,
isActive: PropTypes.looseBool,
destroyInactivePanel: PropTypes.looseBool,
disabled: PropTypes.looseBool,
accordion: PropTypes.looseBool,
forceRender: PropTypes.looseBool,
expandIcon: PropTypes.func,
extra: PropTypes.VNodeChild,
panelKey: PropTypes.VNodeChild,
},
setup() {
return {
@ -18,7 +31,7 @@ export default {
const { prefixCls: customizePrefixCls, showArrow = true } = this;
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
const { class: className, ...restAttrs } = this.$attrs;
const { class: className, ...restAttrs } = this.$attrs as any;
const collapsePanelClassName = {
[className]: className,
[`${prefixCls}-no-arrow`]: !showArrow,
@ -34,4 +47,4 @@ export default {
};
return <VcCollapse.Panel {...rcCollapePanelProps}>{getSlot(this)}</VcCollapse.Panel>;
},
};
});

View File

@ -1,94 +1,101 @@
import { inject, VNodeTypes, CSSProperties, App, SetupContext } from 'vue';
import classNames from '../_util/classNames';
import { App, defineComponent, inject } from 'vue';
import PropsTypes from '../_util/vue-types';
import { getComponent, getSlot } from '../_util/props-util';
import { defaultConfigProvider } from '../config-provider';
export interface CommentProps {
/** List of action items rendered below the comment content */
actions?: Array<VNodeTypes>;
import { VueNode } from '../_util/type';
export const CommentProps = {
actions: PropsTypes.array,
/** The element to display as the comment author. */
author?: VNodeTypes;
author: PropsTypes.VNodeChild,
/** The element to display as the comment avatar - generally an antd Avatar */
avatar?: VNodeTypes;
avatar: PropsTypes.VNodeChild,
/** The main content of the comment */
content: VNodeTypes;
content: PropsTypes.VNodeChild,
/** Comment prefix defaults to '.ant-comment' */
prefixCls?: string;
/** Additional style for the comment */
style?: CSSProperties;
prefixCls: PropsTypes.string,
/** A datetime element containing the time to be displayed */
datetime?: VNodeTypes;
}
datetime: PropsTypes.VNodeChild,
};
const Comment = (
{
actions,
author,
avatar,
content,
prefixCls: customizePrefixCls,
datetime,
...otherProps
}: CommentProps,
{ slots }: SetupContext,
) => {
const { getPrefixCls } = inject('configProvider', defaultConfigProvider);
const Comment = defineComponent({
name: 'AComment',
props: CommentProps,
setup() {
return {
configProvider: inject('configProvider', defaultConfigProvider),
};
},
methods: {
getAction(actions: VueNode[]) {
if (!actions || !actions.length) {
return null;
}
const actionList = actions.map((action, index) => <li key={`action-${index}`}>{action}</li>);
return actionList;
},
renderNested(prefixCls: string, children: VueNode) {
return <div class={`${prefixCls}-nested`}>{children}</div>;
},
},
const renderNested = (prefixCls: string, nestedChildren: any) => {
return <div class={classNames(`${prefixCls}-nested`)}>{nestedChildren}</div>;
};
render() {
const { prefixCls: customizePrefixCls } = this.$props;
const prefixCls = getPrefixCls('comment', customizePrefixCls);
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('comment', customizePrefixCls);
const avatarDom = avatar ? (
<div class={`${prefixCls}-avatar`}>
{typeof avatar === 'string' ? <img src={avatar} alt="comment-avatar" /> : avatar}
</div>
) : null;
const actions = getComponent(this, 'actions');
const author = getComponent(this, 'author');
const avatar = getComponent(this, 'avatar');
const content = getComponent(this, 'content');
const datetime = getComponent(this, 'datetime');
const actionDom =
actions && actions.length ? (
const avatarDom = (
<div class={`${prefixCls}-avatar`}>
{typeof avatar === 'string' ? <img src={avatar} alt="comment-avatar" /> : avatar}
</div>
);
const actionDom = actions ? (
<ul class={`${prefixCls}-actions`}>
{actions.map((action, index) => (
<li key={`action-${index}`}>{action}</li>
))}
{this.getAction(Array.isArray(actions) ? actions : [actions])}
</ul>
) : null;
const authorContent = (author || datetime) && (
<div class={`${prefixCls}-content-author`}>
{author && <span class={`${prefixCls}-content-author-name`}>{author}</span>}
{datetime && <span class={`${prefixCls}-content-author-time`}>{datetime}</span>}
</div>
);
const authorContent = (
<div class={`${prefixCls}-content-author`}>
{author && <span class={`${prefixCls}-content-author-name`}>{author}</span>}
{datetime && <span class={`${prefixCls}-content-author-time`}>{datetime}</span>}
</div>
);
const contentDom = (
<div class={`${prefixCls}-content`}>
{authorContent}
<div class={`${prefixCls}-content-detail`}>{content}</div>
{actionDom}
</div>
);
const cls = classNames(prefixCls);
const contentDom = (
<div class={`${prefixCls}-content`}>
{authorContent}
<div class={`${prefixCls}-content-detail`}>{content}</div>
{actionDom}
</div>
);
const children = slots.default?.();
return (
<div {...otherProps} class={cls}>
const comment = (
<div class={`${prefixCls}-inner`}>
{avatarDom}
{contentDom}
</div>
{children ? renderNested(prefixCls, children) : null}
</div>
);
};
Comment.displayName = 'AComment';
);
const children = getSlot(this);
return (
<div class={prefixCls}>
{comment}
{children && children.length ? this.renderNested(prefixCls, children) : null}
</div>
);
},
});
/* istanbul ignore next */
Comment.install = function(app: App) {
app.component(Comment.name, Comment);
return app;
};
export default Comment;

View File

@ -1,13 +1,22 @@
import { SetupContext, VNode } from 'vue';
import { getOptionProps } from '../_util/props-util';
const Col = (_, { attrs }) => {
const { child = {}, bordered, colon, type, layout, colKey: key } = attrs;
interface ColProps {
child: VNode;
bordered: boolean;
colon: boolean;
type?: 'label' | 'content';
layout?: 'horizontal' | 'vertical';
colKey?: string
}
const Col = (_props: ColProps, { attrs }: SetupContext) => {
const { child = {} as VNode, bordered, colon, type, layout, colKey: key } = attrs as unknown as ColProps;
const { prefixCls, span = 1 } = getOptionProps(child);
const { children = {}, props = {} } = child;
const { children = {} as any, props = {} } = child;
const label = props.label || (children.label && children.label());
const defaultSlot = children.default && children.default();
const labelProps = {
const labelProps: any = {
class: [
`${prefixCls}-item-label`,
{

View File

@ -1,17 +1,17 @@
import { inject, cloneVNode } from 'vue';
import { inject, cloneVNode, App, defineComponent, PropType, VNode } from 'vue';
import warning from '../_util/warning';
import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
import ResponsiveObserve, { Breakpoint, responsiveArray } from '../_util/responsiveObserve';
import { defaultConfigProvider } from '../config-provider';
import Col from './Col';
import PropTypes from '../_util/vue-types';
import {
initDefaultProps,
getOptionProps,
getComponent,
isValidElement,
getSlot,
} from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin';
import { tuple, VueNode } from '../_util/type';
export const DescriptionsItemProps = {
prefixCls: PropTypes.string,
@ -19,7 +19,7 @@ export const DescriptionsItemProps = {
span: PropTypes.number,
};
function toArray(value) {
function toArray(value: any) {
let ret = value;
if (value === undefined) {
ret = [];
@ -31,19 +31,35 @@ function toArray(value) {
export const DescriptionsItem = {
name: 'ADescriptionsItem',
props: initDefaultProps(DescriptionsItemProps, { span: 1 }),
props: {
prefixCls: PropTypes.string,
label: PropTypes.VNodeChild,
span: PropTypes.number.def(1),
},
render() {
return null;
},
};
const defaultColumnMap = {
xxl: 3,
xl: 3,
lg: 3,
md: 3,
sm: 2,
xs: 1,
};
export const DescriptionsProps = {
prefixCls: PropTypes.string,
bordered: PropTypes.looseBool,
size: PropTypes.oneOf(['default', 'middle', 'small']).def('default'),
title: PropTypes.any,
column: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
layout: PropTypes.oneOf(['horizontal', 'vertical']),
size: PropTypes.oneOf(tuple('default', 'middle', 'small')).def('default'),
title: PropTypes.VNodeChild,
column: {
type: [Number, Object] as PropType<number | Partial<Record<Breakpoint, number>>>,
default: () => defaultColumnMap
},
layout: PropTypes.oneOf(tuple('horizontal', 'vertical')),
colon: PropTypes.looseBool,
};
@ -52,13 +68,13 @@ export const DescriptionsProps = {
* @param children: DescriptionsItem
* @param column: number
*/
const generateChildrenRows = (children, column) => {
const generateChildrenRows = (children: VueNode, column: number) => {
const rows = [];
let columns = null;
let leftSpans;
let leftSpans: number;
const itemNodes = toArray(children);
itemNodes.forEach((node, index) => {
itemNodes.forEach((node: VNode, index: number) => {
const itemProps = getOptionProps(node);
let itemNode = node;
@ -97,22 +113,11 @@ const generateChildrenRows = (children, column) => {
return rows;
};
const defaultColumnMap = {
xxl: 3,
xl: 3,
lg: 3,
md: 3,
sm: 2,
xs: 1,
};
const Descriptions = {
const Descriptions = defineComponent({
name: 'ADescriptions',
Item: DescriptionsItem,
mixins: [BaseMixin],
props: initDefaultProps(DescriptionsProps, {
column: defaultColumnMap,
}),
props: DescriptionsProps,
setup() {
return {
configProvider: inject('configProvider', defaultConfigProvider),
@ -143,8 +148,19 @@ const Descriptions = {
// Maybe there are some strange environments
return 3;
},
renderRow(children, index, { prefixCls }, bordered, layout, colon) {
const renderCol = (colItem, type, idx) => {
renderRow(
children: VNode[],
index: number,
{ prefixCls }: { prefixCls: string },
bordered: boolean,
layout: 'horizontal' | 'vertical',
colon: boolean
) {
const renderCol = (
colItem: VNode,
type: 'label' | 'content',
idx: number
) => {
return (
<Col
child={colItem}
@ -160,7 +176,7 @@ const Descriptions = {
const cloneChildren = [];
const cloneContentChildren = [];
toArray(children).forEach((childrenItem, idx) => {
toArray(children).forEach((childrenItem: VNode, idx: number) => {
cloneChildren.push(renderCol(childrenItem, 'label', idx));
if (layout === 'vertical') {
cloneContentChildren.push(renderCol(childrenItem, 'content', idx));
@ -216,7 +232,7 @@ const Descriptions = {
const column = this.getColumn();
const children = getSlot(this);
const cloneChildren = toArray(children)
.map(child => {
.map((child: VNode) => {
if (isValidElement(child)) {
return cloneVNode(child, {
prefixCls,
@ -259,9 +275,9 @@ const Descriptions = {
</div>
);
},
};
});
Descriptions.install = function(app) {
Descriptions.install = function(app: App) {
app.component(Descriptions.name, Descriptions);
app.component(Descriptions.Item.name, Descriptions.Item);
return app;

View File

@ -1,4 +1,4 @@
import { App, computed, defineComponent, inject, PropType, unref } from 'vue';
import { App, computed, defineComponent, inject, PropType } from 'vue';
import { defaultConfigProvider } from '../config-provider';
const Divider = defineComponent({
@ -25,7 +25,7 @@ const Divider = defineComponent({
const classString = computed(() => {
const { type, dashed, orientation } = props;
const orientationPrefix = orientation.length > 0 ? '-' + orientation : orientation;
const prefixClsRef = unref(prefixCls);
const prefixClsRef = prefixCls.value;
return {
[prefixClsRef]: true,
[`${prefixClsRef}-${type}`]: true,

View File

@ -18,7 +18,6 @@ const collapseProps = () => ({
expandIcon: PropTypes.func,
openAnimation: PropTypes.object,
expandIconPosition: PropTypes.oneOf(['left', 'right']),
'onUpdate:change': PropTypes.func,
onChange: PropTypes.func,
});