|
|
@ -32,40 +32,47 @@ function isPresetColor(color?: string): boolean { |
|
|
|
return (PresetColorTypes as any[]).indexOf(color) !== -1; |
|
|
|
} |
|
|
|
|
|
|
|
export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
static defaultProps = { |
|
|
|
count: null, |
|
|
|
showZero: false, |
|
|
|
dot: false, |
|
|
|
overflowCount: 99, |
|
|
|
}; |
|
|
|
|
|
|
|
getNumberedDisplayCount() { |
|
|
|
const { count, overflowCount } = this.props; |
|
|
|
const Badge: React.FC<BadgeProps> = props => { |
|
|
|
const getNumberedDisplayCount = () => { |
|
|
|
const { count, overflowCount } = props; |
|
|
|
const displayCount = |
|
|
|
(count as number) > (overflowCount as number) ? `${overflowCount}+` : count; |
|
|
|
return displayCount as string | number | null; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
getDisplayCount() { |
|
|
|
const isDot = this.isDot(); |
|
|
|
const hasStatus = (): boolean => { |
|
|
|
const { status, color } = props; |
|
|
|
return !!status || !!color; |
|
|
|
}; |
|
|
|
|
|
|
|
const isZero = () => { |
|
|
|
const numberedDisplayCount = getNumberedDisplayCount(); |
|
|
|
return numberedDisplayCount === '0' || numberedDisplayCount === 0; |
|
|
|
}; |
|
|
|
|
|
|
|
const isDot = () => { |
|
|
|
const { dot } = props; |
|
|
|
return (dot && !isZero()) || hasStatus(); |
|
|
|
}; |
|
|
|
|
|
|
|
const getDisplayCount = () => { |
|
|
|
// dot mode don't need count
|
|
|
|
if (isDot) { |
|
|
|
if (isDot()) { |
|
|
|
return ''; |
|
|
|
} |
|
|
|
return this.getNumberedDisplayCount(); |
|
|
|
} |
|
|
|
return getNumberedDisplayCount(); |
|
|
|
}; |
|
|
|
|
|
|
|
getScrollNumberTitle() { |
|
|
|
const { title, count } = this.props; |
|
|
|
const getScrollNumberTitle = () => { |
|
|
|
const { title, count } = props; |
|
|
|
if (title) { |
|
|
|
return title; |
|
|
|
} |
|
|
|
return typeof count === 'string' || typeof count === 'number' ? count : undefined; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
getStyleWithOffset() { |
|
|
|
const { offset, style } = this.props; |
|
|
|
const getStyleWithOffset = () => { |
|
|
|
const { offset, style } = props; |
|
|
|
return offset |
|
|
|
? { |
|
|
|
right: -parseInt(offset[0] as string, 10), |
|
|
@ -73,79 +80,61 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
...style, |
|
|
|
} |
|
|
|
: style; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
getBadgeClassName(prefixCls: string, direction: string = 'ltr') { |
|
|
|
const { className, children } = this.props; |
|
|
|
const getBadgeClassName = (prefixCls: string, direction: string = 'ltr') => { |
|
|
|
const { className, children } = props; |
|
|
|
return classNames(className, prefixCls, { |
|
|
|
[`${prefixCls}-status`]: this.hasStatus(), |
|
|
|
[`${prefixCls}-status`]: hasStatus(), |
|
|
|
[`${prefixCls}-not-a-wrapper`]: !children, |
|
|
|
[`${prefixCls}-rtl`]: direction === 'rtl', |
|
|
|
}) as string; |
|
|
|
} |
|
|
|
|
|
|
|
hasStatus(): boolean { |
|
|
|
const { status, color } = this.props; |
|
|
|
return !!status || !!color; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
isZero() { |
|
|
|
const numberedDisplayCount = this.getNumberedDisplayCount(); |
|
|
|
return numberedDisplayCount === '0' || numberedDisplayCount === 0; |
|
|
|
} |
|
|
|
|
|
|
|
isDot() { |
|
|
|
const { dot } = this.props; |
|
|
|
const isZero = this.isZero(); |
|
|
|
return (dot && !isZero) || this.hasStatus(); |
|
|
|
} |
|
|
|
|
|
|
|
isHidden() { |
|
|
|
const { showZero } = this.props; |
|
|
|
const displayCount = this.getDisplayCount(); |
|
|
|
const isZero = this.isZero(); |
|
|
|
const isDot = this.isDot(); |
|
|
|
const isHidden = () => { |
|
|
|
const { showZero } = props; |
|
|
|
const displayCount = getDisplayCount(); |
|
|
|
const isEmpty = displayCount === null || displayCount === undefined || displayCount === ''; |
|
|
|
return (isEmpty || (isZero && !showZero)) && !isDot; |
|
|
|
} |
|
|
|
return (isEmpty || (isZero() && !showZero)) && !isDot(); |
|
|
|
}; |
|
|
|
|
|
|
|
renderStatusText(prefixCls: string) { |
|
|
|
const { text } = this.props; |
|
|
|
const hidden = this.isHidden(); |
|
|
|
const renderStatusText = (prefixCls: string) => { |
|
|
|
const { text } = props; |
|
|
|
const hidden = isHidden(); |
|
|
|
return hidden || !text ? null : <span className={`${prefixCls}-status-text`}>{text}</span>; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
renderDisplayComponent() { |
|
|
|
const { count } = this.props; |
|
|
|
const renderDisplayComponent = () => { |
|
|
|
const { count } = props; |
|
|
|
const customNode = count as React.ReactElement<any>; |
|
|
|
if (!customNode || typeof customNode !== 'object') { |
|
|
|
return undefined; |
|
|
|
} |
|
|
|
return React.cloneElement(customNode, { |
|
|
|
style: { |
|
|
|
...this.getStyleWithOffset(), |
|
|
|
...getStyleWithOffset(), |
|
|
|
...(customNode.props && customNode.props.style), |
|
|
|
}, |
|
|
|
}); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
renderBadgeNumber(prefixCls: string, scrollNumberPrefixCls: string) { |
|
|
|
const { status, count, color } = this.props; |
|
|
|
const renderBadgeNumber = (prefixCls: string, scrollNumberPrefixCls: string) => { |
|
|
|
const { status, count, color } = props; |
|
|
|
|
|
|
|
const displayCount = this.getDisplayCount(); |
|
|
|
const isDot = this.isDot(); |
|
|
|
const hidden = this.isHidden(); |
|
|
|
const displayCount = getDisplayCount(); |
|
|
|
const dot = isDot(); |
|
|
|
const hidden = isHidden(); |
|
|
|
|
|
|
|
const scrollNumberCls = classNames({ |
|
|
|
[`${prefixCls}-dot`]: isDot, |
|
|
|
[`${prefixCls}-count`]: !isDot, |
|
|
|
[`${prefixCls}-dot`]: dot, |
|
|
|
[`${prefixCls}-count`]: !dot, |
|
|
|
[`${prefixCls}-multiple-words`]: |
|
|
|
!isDot && count && count.toString && count.toString().length > 1, |
|
|
|
!dot && count && count.toString && count.toString().length > 1, |
|
|
|
[`${prefixCls}-status-${status}`]: !!status, |
|
|
|
[`${prefixCls}-status-${color}`]: isPresetColor(color), |
|
|
|
}); |
|
|
|
|
|
|
|
let statusStyle: React.CSSProperties | undefined = this.getStyleWithOffset(); |
|
|
|
let statusStyle: React.CSSProperties | undefined = getStyleWithOffset(); |
|
|
|
if (color && !isPresetColor(color)) { |
|
|
|
statusStyle = statusStyle || {}; |
|
|
|
statusStyle.background = color; |
|
|
@ -157,15 +146,15 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
data-show={!hidden} |
|
|
|
className={scrollNumberCls} |
|
|
|
count={displayCount} |
|
|
|
displayComponent={this.renderDisplayComponent()} // <Badge status="success" count={<Icon type="xxx" />}></Badge>
|
|
|
|
title={this.getScrollNumberTitle()} |
|
|
|
displayComponent={renderDisplayComponent()} // <Badge status="success" count={<Icon type="xxx" />}></Badge>
|
|
|
|
title={getScrollNumberTitle()} |
|
|
|
style={statusStyle} |
|
|
|
key="scrollNumber" |
|
|
|
/> |
|
|
|
); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
renderBadge = ({ getPrefixCls, direction }: ConfigConsumerProps) => { |
|
|
|
const renderBadge = ({ getPrefixCls, direction }: ConfigConsumerProps) => { |
|
|
|
const { |
|
|
|
prefixCls: customizePrefixCls, |
|
|
|
scrollNumberPrefixCls: customizeScrollNumberPrefixCls, |
|
|
@ -174,7 +163,7 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
text, |
|
|
|
color, |
|
|
|
...restProps |
|
|
|
} = this.props; |
|
|
|
} = props; |
|
|
|
const omitArr = [ |
|
|
|
'count', |
|
|
|
'showZero', |
|
|
@ -189,11 +178,11 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
const prefixCls = getPrefixCls('badge', customizePrefixCls); |
|
|
|
const scrollNumberPrefixCls = getPrefixCls('scroll-number', customizeScrollNumberPrefixCls); |
|
|
|
|
|
|
|
const scrollNumber = this.renderBadgeNumber(prefixCls, scrollNumberPrefixCls); |
|
|
|
const statusText = this.renderStatusText(prefixCls); |
|
|
|
const scrollNumber = renderBadgeNumber(prefixCls, scrollNumberPrefixCls); |
|
|
|
const statusText = renderStatusText(prefixCls); |
|
|
|
|
|
|
|
const statusCls = classNames({ |
|
|
|
[`${prefixCls}-status-dot`]: this.hasStatus(), |
|
|
|
[`${prefixCls}-status-dot`]: hasStatus(), |
|
|
|
[`${prefixCls}-status-${status}`]: !!status, |
|
|
|
[`${prefixCls}-status-${color}`]: isPresetColor(color), |
|
|
|
}); |
|
|
@ -203,13 +192,13 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
} |
|
|
|
|
|
|
|
// <Badge status="success" />
|
|
|
|
if (!children && this.hasStatus()) { |
|
|
|
const styleWithOffset = this.getStyleWithOffset(); |
|
|
|
if (!children && hasStatus()) { |
|
|
|
const styleWithOffset = getStyleWithOffset(); |
|
|
|
const statusTextColor = styleWithOffset && styleWithOffset.color; |
|
|
|
return ( |
|
|
|
<span |
|
|
|
{...omit(restProps, omitArr)} |
|
|
|
className={this.getBadgeClassName(prefixCls, direction)} |
|
|
|
className={getBadgeClassName(prefixCls, direction)} |
|
|
|
style={styleWithOffset} |
|
|
|
> |
|
|
|
<span className={statusCls} style={statusStyle} /> |
|
|
@ -221,7 +210,7 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
} |
|
|
|
|
|
|
|
return ( |
|
|
|
<span {...omit(restProps, omitArr)} className={this.getBadgeClassName(prefixCls, direction)}> |
|
|
|
<span {...omit(restProps, omitArr)} className={getBadgeClassName(prefixCls, direction)}> |
|
|
|
{children} |
|
|
|
<Animate |
|
|
|
component="" |
|
|
@ -236,7 +225,14 @@ export default class Badge extends React.Component<BadgeProps, any> { |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
render() { |
|
|
|
return <ConfigConsumer>{this.renderBadge}</ConfigConsumer>; |
|
|
|
} |
|
|
|
} |
|
|
|
return <ConfigConsumer>{renderBadge}</ConfigConsumer>; |
|
|
|
}; |
|
|
|
|
|
|
|
Badge.defaultProps = { |
|
|
|
count: null, |
|
|
|
showZero: false, |
|
|
|
dot: false, |
|
|
|
overflowCount: 99, |
|
|
|
}; |
|
|
|
|
|
|
|
export default Badge; |
|
|
|