diff --git a/components/grid/Col.tsx b/components/grid/Col.tsx index a42e2ca7b..bac7e59e1 100644 --- a/components/grid/Col.tsx +++ b/components/grid/Col.tsx @@ -1,5 +1,6 @@ import { inject, defineComponent, HTMLAttributes, CSSProperties } from 'vue'; import classNames from '../_util/classNames'; +import PropTypes from '../_util/vue-types'; import { defaultConfigProvider } from '../config-provider'; import { rowContextState } from './Row'; @@ -43,40 +44,26 @@ function parseFlex(flex: FlexType): string { return flex; } -export default defineComponent({ +const ACol = defineComponent({ name: 'ACol', - inheritAttrs: false, - setup(_: ColProps, { slots, attrs }) { + setup(props, { slots }) { const configProvider = inject('configProvider', defaultConfigProvider); const rowContext = inject('rowContext', {}); return () => { const { gutter } = rowContext; - const { - prefixCls: customizePrefixCls, - span, - order, - offset, - push, - pull, - class: className, - flex, - style, - ...others - } = attrs as ColProps; + const { prefixCls: customizePrefixCls, span, order, offset, push, pull, flex } = props; const prefixCls = configProvider.getPrefixCls('col', customizePrefixCls); let sizeClassObj = {}; ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach(size => { let sizeProps: ColSize = {}; - const propSize = attrs[size]; + const propSize = props[size]; if (typeof propSize === 'number') { sizeProps.span = propSize; } else if (typeof propSize === 'object') { sizeProps = propSize || {}; } - delete (others as any)[size]; - sizeClassObj = { ...sizeClassObj, [`${prefixCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined, @@ -97,10 +84,9 @@ export default defineComponent({ [`${prefixCls}-push-${push}`]: push, [`${prefixCls}-pull-${pull}`]: pull, }, - className, sizeClassObj, ); - let mergedStyle: CSSProperties = { ...(style as CSSProperties) }; + let mergedStyle: CSSProperties = {}; if (gutter) { mergedStyle = { ...(gutter[0]! > 0 @@ -123,10 +109,40 @@ export default defineComponent({ } return ( -
+
{slots.default?.()}
); }; }, }); + +const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); + +export const ColSize = PropTypes.shape({ + span: stringOrNumber, + order: stringOrNumber, + offset: stringOrNumber, + push: stringOrNumber, + pull: stringOrNumber, +}).loose; + +const objectOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number, ColSize]); + +ACol.props = { + span: stringOrNumber, + order: stringOrNumber, + offset: stringOrNumber, + push: stringOrNumber, + pull: stringOrNumber, + xs: objectOrNumber, + sm: objectOrNumber, + md: objectOrNumber, + lg: objectOrNumber, + xl: objectOrNumber, + xxl: objectOrNumber, + prefixCls: PropTypes.string, + flex: stringOrNumber, +}; + +export default ACol; diff --git a/components/grid/Row.tsx b/components/grid/Row.tsx index 4b2ac63cc..8c7a5f25f 100644 --- a/components/grid/Row.tsx +++ b/components/grid/Row.tsx @@ -18,13 +18,6 @@ import ResponsiveObserve, { responsiveArray, } from '../_util/responsiveObserve'; -const RowProps = { - gutter: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]), - type: PropTypes.oneOf(['flex']), - align: PropTypes.oneOf(['top', 'middle', 'bottom', 'stretch']), - justify: PropTypes.oneOf(['start', 'end', 'center', 'space-around', 'space-between']), - prefixCls: PropTypes.string, -}; const RowAligns = tuple('top', 'middle', 'bottom', 'stretch'); const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between'); @@ -35,22 +28,21 @@ export interface rowContextState { } export interface RowProps extends HTMLAttributes { + type?: 'flex'; gutter?: Gutter | [Gutter, Gutter]; align?: typeof RowAligns[number]; justify?: typeof RowJustify[number]; prefixCls?: string; } -export default defineComponent({ +const ARow = defineComponent({ name: 'ARow', - setup(_: RowProps, { slots, attrs }) { + setup(props, { slots }) { const rowContext = reactive({ gutter: undefined, }); provide('rowContext', rowContext); - const props = attrs as RowProps; - let token: number; onMounted(() => { @@ -81,8 +73,7 @@ export default defineComponent({ const gutterRef = ref(); gutterRef.value = props.gutter; - const configProvider = inject('configProvider', defaultConfigProvider); - const { getPrefixCls } = configProvider; + const { getPrefixCls } = inject('configProvider', defaultConfigProvider); const getGutter = (): [number, number] => { const results: [number, number] = [0, 0]; @@ -105,24 +96,13 @@ export default defineComponent({ }; return () => { - const { - prefixCls: customizePrefixCls, - justify, - align, - class: className, - style, - ...others - } = props; + const { prefixCls: customizePrefixCls, justify, align } = props; const prefixCls = getPrefixCls('row', customizePrefixCls); const gutter = getGutter(); - const classes = classNames( - prefixCls, - { - [`${prefixCls}-${justify}`]: justify, - [`${prefixCls}-${align}`]: align, - }, - className, - ); + const classes = classNames(prefixCls, { + [`${prefixCls}-${justify}`]: justify, + [`${prefixCls}-${align}`]: align, + }); const rowStyle = { ...(gutter[0]! > 0 ? { @@ -137,15 +117,23 @@ export default defineComponent({ } : {}), }; - const otherProps = { ...others, style }; - delete otherProps.gutter; rowContext.gutter = gutter; return ( -
+
{slots.default?.()}
); }; }, }); + +ARow.props = { + type: PropTypes.oneOf(['flex']), + align: PropTypes.oneOf(RowAligns), + justify: PropTypes.oneOf(RowJustify), + prefixCls: PropTypes.string, + gutter: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]).def(0), +}; + +export default ARow; diff --git a/components/tag/CheckableTag.tsx b/components/tag/CheckableTag.tsx index 331e3a500..d95aeb222 100644 --- a/components/tag/CheckableTag.tsx +++ b/components/tag/CheckableTag.tsx @@ -1,40 +1,45 @@ -import { inject, CSSProperties, SetupContext } from 'vue'; +import { inject, defineComponent, PropType } from 'vue'; import classNames from '../_util/classNames'; import { defaultConfigProvider } from '../config-provider'; +import PropTypes from '../_util/vue-types'; -export interface CheckableTagProps { - prefixCls?: string; - class?: string; - style?: CSSProperties; - checked: boolean; - onChange?: (checked: boolean) => void; - onClick?: (e: MouseEvent) => void; -} +const CheckableTag = defineComponent({ + name: 'ACheckableTag', + props: { + prefixCls: PropTypes.string, + checked: PropTypes.bool, + onChange: { + type: Function as PropType<(checked: boolean) => void>, + }, + onClick: { + type: Function as PropType<(e: MouseEvent) => void>, + }, + }, + emits: ['update:checked', 'change', 'click'], + setup(props, { slots, emit }) { + const { getPrefixCls } = inject('configProvider', defaultConfigProvider); + const handleClick = (e: MouseEvent) => { + const { checked } = props; + emit('update:checked', !checked); + emit('change', !checked); + emit('click', e); + }; -const CheckableTag = (props: CheckableTagProps, { slots }: SetupContext) => { - const { getPrefixCls } = inject('configProvider', defaultConfigProvider); - const handleClick = (e: MouseEvent) => { - const { checked, onChange, onClick } = props; - if (onChange) { - onChange(!checked); - } - if (onClick) { - onClick(e); - } - }; + return () => { + const { checked, prefixCls: customizePrefixCls } = props; + const prefixCls = getPrefixCls('tag', customizePrefixCls); + const cls = classNames(prefixCls, { + [`${prefixCls}-checkable`]: true, + [`${prefixCls}-checkable-checked`]: checked, + }); - const { prefixCls: customizePrefixCls, checked } = props; - const prefixCls = getPrefixCls('tag', customizePrefixCls); - const cls = classNames(prefixCls, { - [`${prefixCls}-checkable`]: true, - [`${prefixCls}-checkable-checked`]: checked, - }); - - return ( - - {slots.default?.()} - - ); -}; + return ( + + {slots.default?.()} + + ); + }; + }, +}); export default CheckableTag; diff --git a/components/tag/index.tsx b/components/tag/index.tsx index c55e10c74..3a3380c81 100644 --- a/components/tag/index.tsx +++ b/components/tag/index.tsx @@ -1,14 +1,6 @@ -import { - inject, - ref, - HTMLAttributes, - defineComponent, - SetupContext, - App, - VNodeTypes, - watchEffect, -} from 'vue'; +import { inject, ref, HTMLAttributes, defineComponent, App, VNodeTypes, watchEffect } from 'vue'; import classNames from '../_util/classNames'; +import PropTypes from '../_util/vue-types'; import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; import Wave from '../_util/wave'; import { @@ -36,29 +28,27 @@ export interface TagProps extends HTMLAttributes { const Tag = defineComponent({ name: 'ATag', - emits: ['update:visible'], - setup(props: TagProps, { slots, emit, attrs }: SetupContext) { + emits: ['update:visible', 'close'], + setup(props: TagProps, { slots, emit, attrs }) { const { getPrefixCls } = inject('configProvider', defaultConfigProvider); const visible = ref(true); watchEffect(() => { - if ('visible' in props) { + if (props.visible !== undefined) { visible.value = props.visible!; } }); const handleCloseClick = (e: MouseEvent) => { e.stopPropagation(); - if (props.onClose) { - emit('update:visible', false); - props.onClose(e); - } + emit('update:visible', false); + emit('close', e); if (e.defaultPrevented) { return; } - if (!('visible' in props)) { + if (props.visible === undefined) { visible.value = false; } }; @@ -131,7 +121,18 @@ const Tag = defineComponent({ }, }); -Tag.props = ['prefixCls', 'color', 'closable', 'closeIcon', 'visible', 'icon']; +Tag.props = { + prefixCls: PropTypes.string, + color: PropTypes.string, + closable: PropTypes.bool.def(false), + closeIcon: PropTypes.any, + visible: { + type: Boolean, + default: undefined, + }, + onClose: PropTypes.func, + icon: PropTypes.any, +}; Tag.CheckableTag = CheckableTag;