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 8a55e234d..3a3380c81 100644 --- a/components/tag/index.tsx +++ b/components/tag/index.tsx @@ -1,15 +1,6 @@ -import { - inject, - ref, - HTMLAttributes, - defineComponent, - SetupContext, - App, - VNodeTypes, - CSSProperties, -} from 'vue'; +import { inject, ref, HTMLAttributes, defineComponent, App, VNodeTypes, watchEffect } from 'vue'; import classNames from '../_util/classNames'; -import omit from 'omit.js'; +import PropTypes from '../_util/vue-types'; import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; import Wave from '../_util/wave'; import { @@ -27,11 +18,9 @@ const PresetStatusColorRegex = new RegExp(`^(${PresetStatusColorTypes.join('|')} export interface TagProps extends HTMLAttributes { prefixCls?: string; - class?: string; color?: LiteralUnion; closable?: boolean; closeIcon?: VNodeTypes; - style?: CSSProperties; visible?: boolean; onClose?: (e: MouseEvent) => void; icon?: VNodeTypes; @@ -39,50 +28,48 @@ export interface TagProps extends HTMLAttributes { const Tag = defineComponent({ name: 'ATag', - inheritAttrs: false, - setup(_: TagProps, { slots, attrs }: SetupContext) { + emits: ['update:visible', 'close'], + setup(props: TagProps, { slots, emit, attrs }) { const { getPrefixCls } = inject('configProvider', defaultConfigProvider); const visible = ref(true); - const props = attrs as TagProps; + + watchEffect(() => { + if (props.visible !== undefined) { + visible.value = props.visible!; + } + }); + + const handleCloseClick = (e: MouseEvent) => { + e.stopPropagation(); + emit('update:visible', false); + emit('close', e); + + if (e.defaultPrevented) { + return; + } + if (props.visible === undefined) { + visible.value = false; + } + }; + + const isPresetColor = (): boolean => { + const { color } = props; + if (!color) { + return false; + } + return PresetColorRegex.test(color) || PresetStatusColorRegex.test(color); + }; return () => { const { prefixCls: customizePrefixCls, icon, color, - closeIcon, - class: className, - style = {}, + closeIcon = slots.closeIcon?.(), closable = false, - ...restProps } = props; - if ('visible' in props) { - visible.value = props.visible!; - } - - const handleCloseClick = (e: MouseEvent) => { - e.stopPropagation(); - if (props.onClose) { - props.onClose(e); - } - - if (e.defaultPrevented) { - return; - } - if (!('visible' in props)) { - visible.value = false; - } - }; - - const isPresetColor = (): boolean => { - if (!color) { - return false; - } - return PresetColorRegex.test(color) || PresetStatusColorRegex.test(color); - }; - const presetColor = isPresetColor(); const prefixCls = getPrefixCls('tag', customizePrefixCls); @@ -101,20 +88,14 @@ const Tag = defineComponent({ const tagStyle = { backgroundColor: color && !isPresetColor() ? color : undefined, - ...style, }; - const tagClassName = classNames( - prefixCls, - { - [`${prefixCls}-${color}`]: presetColor, - [`${prefixCls}-has-color`]: color && !presetColor, - [`${prefixCls}-hidden`]: !visible.value, - }, - className, - ); + const tagClassName = classNames(prefixCls, { + [`${prefixCls}-${color}`]: presetColor, + [`${prefixCls}-has-color`]: color && !presetColor, + [`${prefixCls}-hidden`]: !visible.value, + }); - const tagProps = omit(restProps, ['visible']); const iconNode = icon || null; const children = slots.default?.(); const kids = iconNode ? ( @@ -126,10 +107,10 @@ const Tag = defineComponent({ children ); - const isNeedWave = 'onClick' in props; + const isNeedWave = 'onClick' in attrs; const tagNode = ( - + {kids} {renderCloseIcon()} @@ -140,6 +121,19 @@ const Tag = defineComponent({ }, }); +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; Tag.install = (app: App) => {