import { defineComponent , computed , toRefs , CSSProperties , PropType , Slot , } from 'vue' ; import { getPrefixCls } from '../_utils/global-config' ; export const COLORS = [ 'red' , 'orangered' , 'orange' , 'gold' , 'lime' , 'green' , 'cyan' , 'arcoblue' , 'purple' , 'pinkpurple' , 'magenta' , 'gray' , ] as const ; export type ColorType = typeof COLORS [ number ] ; export const BADGE_STATUSES = [ 'normal' , 'processing' , 'success' , 'warning' , 'danger' , ] as const ; export type BadgeStatus = typeof BADGE_STATUSES [ number ] ; export default defineComponent ( { name : 'Badge' , props : { zh en text : { type : String } , zh en dot : { type : Boolean } , zh en dotStyle : { type : Object } , zh en maxCount : { type : Number , default : 99 } , zh en offset : { type : Array as PropType < number [ ] > , default : ( ) => [ ] } , zh en color : { type : String as PropType < ColorType | string > } , zh en values status : { type : String as PropType < BadgeStatus > , validator : ( value ) => { return BADGE_STATUSES . includes ( value ) ; } } , zh en count : { type : Number } } , setup ( props , { slots } ) { const { status , color , dotStyle , offset , text , dot , maxCount , count } = toRefs ( props ) ; const prefixCls = getPrefixCls ( 'badge' ) ; const wrapperClassName = useWrapperClass ( prefixCls , status ?. value , slots ?. default ) ; const computedStyleRef = computed ( ( ) => { const computedDotStyle = { ... ( dotStyle ?. value || { } ) } ; const [ leftOffset , topOffset ] = offset ?. value || [ ] ; if ( leftOffset ) { computedDotStyle . marginRight = `${ - leftOffset }px` ; } if ( topOffset ) { computedDotStyle . marginTop = `${ topOffset }px` ; } const computedColorStyle = ! color ?. value || COLORS . includes ( color ?. value as typeof COLORS [ number ] ) ? { } : { backgroundColor : color . value } ; const mergedStyle = { ... computedColorStyle , ... computedDotStyle } as CSSProperties ; return { mergedStyle , computedDotStyle , computedColorStyle } ; } ) ; const getDot = ( ) => { const textValue = text ?. value ; const colorValue = color ?. value ; const statusValue = status ?. value ; const dotValue = dot ?. value ; const countValue = Number ( count ?. value ) ; const hasCount = count ?. value != null ; const { computedDotStyle , mergedStyle } = computedStyleRef . value ; if ( slots . content ) { return ( < span class = { `${ prefixCls }-custom-dot` } style = { computedDotStyle } > { slots . content ( ) } < /span>); } if ( textValue && ! colorValue && ! statusValue ) { return ( < span class = { `${ prefixCls }-text` } style = { computedDotStyle } > { textValue } < /span>); } if ( statusValue || ( colorValue && ! hasCount ) ) { return ( < span class = { `${ prefixCls }-status-wrapper` } > < span class = { [ `${ prefixCls }-status-dot` , { [ `${ prefixCls }-status-${ statusValue }` ] : statusValue , [ `${ prefixCls }-color-${ colorValue }` ] : colorValue } , ] } style = { mergedStyle } / > { textValue && ( < span class = { `${ prefixCls }-status-text` } > { textValue } < /span>)} < /span>); } if ( ( dotValue || colorValue ) && countValue > 0 ) { return ( < span class = { [ `${ prefixCls }-dot` , { [ `${ prefixCls }-color-${ colorValue }` ] : colorValue } , ] } style = { mergedStyle } / > ) ; } if ( countValue === 0 ) { return null ; } return ( < span class = { `${ prefixCls }-number` } style = { mergedStyle } > < span > { maxCount . value && countValue > maxCount . value ? `${ maxCount . value }+` : countValue } < /span> < /span>); } ; return ( ) => { return ( < span class = { wrapperClassName . value } > { slots . default && slots . default ( ) } { getDot ( ) } < /span>); } ; } } ) ; const useWrapperClass = ( prefixCls , status ? , children ? ) => { return computed ( ( ) => [ prefixCls , { [ `${ prefixCls }-status` ] : status , [ `${ prefixCls }-no-children` ] : ! children } , ] ) ; } ;