Browse Source

feat: Badge support classNames & styles (#43245)

* feat: Badge support classNames & styles

* update docs

* fix

* fix

* fix

* Update components/badge/index.en-US.md

---------

Co-authored-by: MadCcc <1075746765@qq.com>
pull/43270/head
lijianan 1 year ago
committed by GitHub
parent
commit
2490d43eab
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      components/badge/__tests__/index.test.tsx
  2. 9
      components/badge/index.en-US.md
  3. 31
      components/badge/index.tsx
  4. 9
      components/badge/index.zh-CN.md

28
components/badge/__tests__/index.test.tsx

@ -221,4 +221,32 @@ describe('Badge', () => {
expect(container.querySelectorAll('.ant-badge-count')).toHaveLength(4);
expect(container.querySelectorAll('[title="0"]')).toHaveLength(4);
});
it('should support classNames and styles', () => {
const { container } = render(
<Badge
count={10}
classNames={{
root: 'test-root',
indicator: 'test-indicator',
}}
styles={{
root: { backgroundColor: 'yellow' },
indicator: { backgroundColor: 'blue' },
}}
>
test
</Badge>,
);
const element = container.querySelector<HTMLSpanElement>('.ant-badge');
// classNames
expect(element).toHaveClass('test-root');
expect(element?.querySelector<HTMLElement>('sup')).toHaveClass('test-indicator');
// styles
expect(element).toHaveStyle({ backgroundColor: 'yellow' });
expect(element?.querySelector<HTMLElement>('sup')).toHaveStyle({ backgroundColor: 'bule' });
});
});

9
components/badge/index.en-US.md

@ -41,12 +41,14 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
| --- | --- | --- | --- | --- |
| color | Customize Badge dot color | string | - | |
| count | Number to show in badge | ReactNode | - | |
| classNames | Semantic DOM class | Record<SemanticDOM, string> | - | 5.7.0 |
| dot | Whether to display a red dot instead of `count` | boolean | false | |
| offset | Set offset of the badge dot | \[number, number] | - | |
| overflowCount | Max count to show | number | 99 | |
| showZero | Whether to show badge when `count` is zero | boolean | false | |
| size | If `count` is set, `size` sets the size of badge | `default` \| `small` | - | 4.6.0 |
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| styles | Semantic DOM style | Record<SemanticDOM, CSSProperties> | - | 5.7.0 |
| text | If `status` is set, `text` sets the display text of the status `dot` | ReactNode | - | |
| title | Text to show when hovering over the badge | string | - | |
@ -58,6 +60,13 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
| placement | The placement of the Ribbon, `start` and `end` follow text direction (RTL or LTR) | `start` \| `end` | `end` | |
| text | Content inside the Ribbon | ReactNode | - | |
### `styles` and `classNames` attribute
| Property | Description | Version |
| --------- | ------------------- | ------- |
| root | set `root` element | 5.7.0 |
| indicator | set `badge` element | 5.7.0 |
## Design Token
<ComponentTokenTable component="Badge"></ComponentTokenTable>

31
components/badge/index.tsx

@ -1,13 +1,13 @@
import classNames from 'classnames';
import classnames from 'classnames';
import CSSMotion from 'rc-motion';
import * as React from 'react';
import { useMemo, useRef } from 'react';
import { ConfigContext } from '../config-provider';
import type { PresetColorKey } from '../theme/internal';
import type { PresetStatusColorType } from '../_util/colors';
import { isPresetColor } from '../_util/colors';
import { cloneElement } from '../_util/reactNode';
import type { LiteralUnion } from '../_util/type';
import { ConfigContext } from '../config-provider';
import type { PresetColorKey } from '../theme/internal';
import Ribbon from './Ribbon';
import ScrollNumber from './ScrollNumber';
import useStyle from './style';
@ -40,6 +40,14 @@ export interface BadgeProps {
offset?: [number | string, number | string];
title?: string;
children?: React.ReactNode;
classNames?: {
root?: string;
indicator?: string;
};
styles?: {
root?: React.CSSProperties;
indicator?: React.CSSProperties;
};
}
const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps> = (props, ref) => {
@ -59,6 +67,8 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
style,
className,
rootClassName,
classNames,
styles,
showZero = false,
...restProps
} = props;
@ -154,7 +164,7 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
const isInternalColor = isPresetColor(color, false);
// Shared styles
const statusCls = classNames({
const statusCls = classnames(classNames?.indicator, {
[`${prefixCls}-status-dot`]: hasStatus,
[`${prefixCls}-status-${status}`]: !!status,
[`${prefixCls}-color-${color}`]: isInternalColor,
@ -166,7 +176,7 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
statusStyle.background = color;
}
const badgeClassName = classNames(
const badgeClassName = classnames(
prefixCls,
{
[`${prefixCls}-status`]: hasStatus,
@ -175,6 +185,7 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
},
className,
rootClassName,
classNames?.root,
hashId,
);
@ -182,8 +193,8 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
if (!children && hasStatus) {
const statusTextColor = mergedStyle.color;
return wrapSSR(
<span {...restProps} className={badgeClassName} style={mergedStyle}>
<span className={statusCls} style={statusStyle} />
<span {...restProps} className={badgeClassName} style={{ ...styles?.root, ...mergedStyle }}>
<span className={statusCls} style={{ ...styles?.indicator, ...statusStyle }} />
{text && (
<span style={{ color: statusTextColor }} className={`${prefixCls}-status-text`}>
{text}
@ -194,7 +205,7 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
}
return wrapSSR(
<span ref={ref} {...restProps} className={badgeClassName}>
<span ref={ref} {...restProps} className={badgeClassName} style={styles?.root}>
{children}
<CSSMotion
visible={!isHidden}
@ -210,7 +221,7 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
const isDot = isDotRef.current;
const scrollNumberCls = classNames({
const scrollNumberCls = classnames(classNames?.indicator, {
[`${prefixCls}-dot`]: isDot,
[`${prefixCls}-count`]: !isDot,
[`${prefixCls}-count-sm`]: size === 'small',
@ -220,7 +231,7 @@ const InternalBadge: React.ForwardRefRenderFunction<HTMLSpanElement, BadgeProps>
[`${prefixCls}-color-${color}`]: isInternalColor,
});
let scrollNumberStyle: React.CSSProperties = { ...mergedStyle };
let scrollNumberStyle: React.CSSProperties = { ...styles?.indicator, ...mergedStyle };
if (color && !isInternalColor) {
scrollNumberStyle = scrollNumberStyle || {};
scrollNumberStyle.background = color;

9
components/badge/index.zh-CN.md

@ -42,12 +42,14 @@ group: 数据展示
| --- | --- | --- | --- | --- |
| color | 自定义小圆点的颜色 | string | - | |
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | ReactNode | - | |
| classNames | 语义化结构 class | Record<SemanticDOM, string> | - | 5.7.0 |
| dot | 不展示数字,只有一个小红点 | boolean | false | |
| offset | 设置状态点的位置偏移 | \[number, number] | - | |
| overflowCount | 展示封顶的数字值 | number | 99 | |
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false | |
| size | 在设置了 `count` 的前提下有效,设置小圆点的大小 | `default` \| `small` | - | 4.6.0 |
| status | 设置 Badge 为状态点 | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| styles | 语义化结构 style | Record<SemanticDOM, CSSProperties> | - | 5.7.0 |
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | ReactNode | - | |
| title | 设置鼠标放在状态点上时显示的文字 | string | - | |
@ -59,6 +61,13 @@ group: 数据展示
| placement | 缎带的位置,`start` 和 `end` 随文字方向(RTL 或 LTR)变动 | `start` \| `end` | `end` | |
| text | 缎带中填入的内容 | ReactNode | - | |
### `styles``classNames` 属性
| 名称 | 说明 | 版本 |
| --------- | ------------ | ----- |
| root | 设置根元素 | 5.7.0 |
| indicator | 设置徽标元素 | 5.7.0 |
## Design Token
<ComponentTokenTable component="Badge"></ComponentTokenTable>

Loading…
Cancel
Save