mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 03:59:01 +08:00
Badge support customize color (#15764)
* popout * update snapshot * update doc * update def
This commit is contained in:
parent
aebb781000
commit
75cd91a966
18
components/_util/colors.ts
Normal file
18
components/_util/colors.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { tuple } from './type';
|
||||
|
||||
export const PresetColorTypes = tuple(
|
||||
'pink',
|
||||
'red',
|
||||
'yellow',
|
||||
'orange',
|
||||
'cyan',
|
||||
'green',
|
||||
'blue',
|
||||
'purple',
|
||||
'geekblue',
|
||||
'magenta',
|
||||
'volcano',
|
||||
'gold',
|
||||
'lime'
|
||||
);
|
||||
export type PresetColorType = (typeof PresetColorTypes)[number];
|
@ -475,6 +475,262 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/badge/demo/colorful.md correctly 1`] = `
|
||||
<div>
|
||||
<h4
|
||||
style="margin-bottom:16px"
|
||||
>
|
||||
Presets:
|
||||
</h4>
|
||||
<div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-pink"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
pink
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-red"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
red
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-yellow"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
yellow
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-orange"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
orange
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-cyan"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
cyan
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-green"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
green
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-blue"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
blue
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-purple"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
purple
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-geekblue"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
geekblue
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-magenta"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
magenta
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-volcano"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
volcano
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-gold"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
gold
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-lime"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
lime
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<h4
|
||||
style="margin:16px 0"
|
||||
>
|
||||
Custom:
|
||||
</h4>
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot"
|
||||
style="background:#f50"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
#f50
|
||||
</span>
|
||||
</span>
|
||||
<br />
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot"
|
||||
style="background:#2db7f5"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
#2db7f5
|
||||
</span>
|
||||
</span>
|
||||
<br />
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot"
|
||||
style="background:#87d068"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
#87d068
|
||||
</span>
|
||||
</span>
|
||||
<br />
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot"
|
||||
style="background:#108ee9"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
#108ee9
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
|
51
components/badge/demo/colorful.md
Normal file
51
components/badge/demo/colorful.md
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
order: 8
|
||||
title:
|
||||
zh-CN: 多彩徽标
|
||||
en-US: Colorful Badge
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
3.16.0 后新增。我们添加了多种预设色彩的徽标样式,用作不同场景使用。如果预设值不能满足你的需求,可以设置为具体的色值。
|
||||
|
||||
## en-US
|
||||
|
||||
New feature after 3.16.0. We preset a series of colorful Badge style for different situation usage.
|
||||
And you can always set it to a hex color string for custom color.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
const colors = ['pink', 'red', 'yellow', 'orange', 'cyan', 'green', 'blue', 'purple', 'geekblue', 'magenta', 'volcano', 'gold', 'lime'];
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<h4 style={{ marginBottom: 16 }}>Presets:</h4>
|
||||
<div>
|
||||
{colors.map((color) => (
|
||||
<div key={color}>
|
||||
<Badge color={color} text={color} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<h4 style={{ margin: '16px 0' }}>Custom:</h4>
|
||||
<div>
|
||||
<Badge color="#f50" text="#f50" />
|
||||
<br />
|
||||
<Badge color="#2db7f5" text="#2db7f5" />
|
||||
<br />
|
||||
<Badge color="#87d068" text="#87d068" />
|
||||
<br />
|
||||
<Badge color="#108ee9" text="#108ee9" />
|
||||
</div>
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
````
|
||||
|
||||
````css
|
||||
.ant-tag {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
````
|
@ -22,13 +22,14 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
|
||||
<Badge count={5} />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| count | Number to show in badge | ReactNode | |
|
||||
| dot | Whether to display a red dot instead of `count` | boolean | `false` |
|
||||
| offset | set offset of the badge dot, like`[x, y]` | `[number, number]` | - |
|
||||
| overflowCount | Max count to show | number | 99 |
|
||||
| showZero | Whether to show badge when `count` is zero | boolean | `false` |
|
||||
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` |
|
||||
| text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` |
|
||||
| title | Text to show when hovering over the badge | string | `count` |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| -------- | ----------- | ---- | ------- | ------- |
|
||||
| color | Customize Badge dot color | string | - | 3.16.0 |
|
||||
| count | Number to show in badge | ReactNode | | |
|
||||
| dot | Whether to display a red dot instead of `count` | boolean | `false` | |
|
||||
| offset | set offset of the badge dot, like`[x, y]` | `[number, number]` | - | |
|
||||
| overflowCount | Max count to show | number | 99 | |
|
||||
| showZero | Whether to show badge when `count` is zero | boolean | `false` | |
|
||||
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` | |
|
||||
| text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` | |
|
||||
| title | Text to show when hovering over the badge | string | `count` | |
|
||||
|
@ -3,6 +3,7 @@ import * as PropTypes from 'prop-types';
|
||||
import Animate from 'rc-animate';
|
||||
import classNames from 'classnames';
|
||||
import ScrollNumber from './ScrollNumber';
|
||||
import { PresetColorTypes } from '../_util/colors';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
|
||||
export { ScrollNumberProps } from './ScrollNumber';
|
||||
@ -20,11 +21,16 @@ export interface BadgeProps {
|
||||
scrollNumberPrefixCls?: string;
|
||||
className?: string;
|
||||
status?: 'success' | 'processing' | 'default' | 'error' | 'warning';
|
||||
color?: string;
|
||||
text?: React.ReactNode;
|
||||
offset?: [number | string, number | string];
|
||||
title?: string;
|
||||
}
|
||||
|
||||
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,
|
||||
@ -41,22 +47,27 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
};
|
||||
|
||||
getBadgeClassName(prefixCls: string) {
|
||||
const { className, status, children } = this.props;
|
||||
const { className, children } = this.props;
|
||||
return classNames(className, prefixCls, {
|
||||
[`${prefixCls}-status`]: !!status,
|
||||
[`${prefixCls}-status`]: this.hasStatus(),
|
||||
[`${prefixCls}-not-a-wrapper`]: !children,
|
||||
}) as string;
|
||||
}
|
||||
|
||||
hasStatus(): boolean {
|
||||
const { status, color } = this.props;
|
||||
return !!status || !!color;
|
||||
}
|
||||
|
||||
isZero() {
|
||||
const numberedDispayCount = this.getNumberedDispayCount();
|
||||
return numberedDispayCount === '0' || numberedDispayCount === 0;
|
||||
}
|
||||
|
||||
isDot() {
|
||||
const { dot, status } = this.props;
|
||||
const { dot } = this.props;
|
||||
const isZero = this.isZero();
|
||||
return (dot && !isZero) || status;
|
||||
return (dot && !isZero) || this.hasStatus();
|
||||
}
|
||||
|
||||
isHidden() {
|
||||
@ -124,7 +135,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
}
|
||||
|
||||
renderBadgeNumber(prefixCls: string, scrollNumberPrefixCls: string) {
|
||||
const { count, status } = this.props;
|
||||
const { status, count } = this.props;
|
||||
|
||||
const displayCount = this.getDispayCount();
|
||||
const isDot = this.isDot();
|
||||
@ -135,7 +146,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
[`${prefixCls}-count`]: !isDot,
|
||||
[`${prefixCls}-multiple-words`]:
|
||||
!isDot && count && count.toString && count.toString().length > 1,
|
||||
[`${prefixCls}-status-${status}`]: !!status,
|
||||
[`${prefixCls}-status-${status}`]: this.hasStatus(),
|
||||
});
|
||||
|
||||
return hidden ? null : (
|
||||
@ -167,6 +178,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
text,
|
||||
offset,
|
||||
title,
|
||||
color,
|
||||
...restProps
|
||||
} = this.props;
|
||||
|
||||
@ -177,17 +189,22 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
const statusText = this.renderStatusText(prefixCls);
|
||||
|
||||
const statusCls = classNames({
|
||||
[`${prefixCls}-status-dot`]: !!status,
|
||||
[`${prefixCls}-status-dot`]: this.hasStatus(),
|
||||
[`${prefixCls}-status-${status}`]: !!status,
|
||||
[`${prefixCls}-status-${color}`]: isPresetColor(color),
|
||||
});
|
||||
const statusStyle: React.CSSProperties = {};
|
||||
if (color && !isPresetColor(color)) {
|
||||
statusStyle.background = color;
|
||||
}
|
||||
|
||||
// <Badge status="success" />
|
||||
if (!children && status) {
|
||||
if (!children && this.hasStatus()) {
|
||||
const styleWithOffset = this.getStyleWithOffset();
|
||||
const statusTextColor = styleWithOffset && styleWithOffset.color;
|
||||
return (
|
||||
<span {...restProps} className={this.getBadgeClassName(prefixCls)} style={styleWithOffset}>
|
||||
<span className={statusCls} />
|
||||
<span className={statusCls} style={statusStyle} />
|
||||
<span style={{ color: statusTextColor }} className={`${prefixCls}-status-text`}>
|
||||
{text}
|
||||
</span>
|
||||
|
@ -23,13 +23,14 @@ title: Badge
|
||||
<Badge count={5} />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | ReactNode | |
|
||||
| dot | 不展示数字,只有一个小红点 | boolean | false |
|
||||
| offset | 设置状态点的位置偏移,格式为 `[x, y]` | `[number, number]` | - |
|
||||
| overflowCount | 展示封顶的数字值 | number | 99 |
|
||||
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false |
|
||||
| status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' |
|
||||
| title | 设置鼠标放在状态点上时显示的文字 | string | `count` |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| color | 自定义小圆点的颜色 | string | - | 3.16.0 |
|
||||
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | ReactNode | | |
|
||||
| dot | 不展示数字,只有一个小红点 | boolean | false | |
|
||||
| offset | 设置状态点的位置偏移,格式为 `[x, y]` | `[number, number]` | - | |
|
||||
| overflowCount | 展示封顶的数字值 | number | 99 | |
|
||||
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false | |
|
||||
| status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' | |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' | |
|
||||
| title | 设置鼠标放在状态点上时显示的文字 | string | `count` | |
|
||||
|
@ -94,6 +94,18 @@
|
||||
&-warning {
|
||||
background-color: @warning-color;
|
||||
}
|
||||
|
||||
// mixin to iterate over colors and create CSS class for each one
|
||||
.make-color-classes(@i: length(@preset-colors)) when (@i > 0) {
|
||||
.make-color-classes(@i - 1);
|
||||
@color: extract(@preset-colors, @i);
|
||||
@darkColor: '@{color}-6';
|
||||
&-@{color} {
|
||||
background: @@darkColor;
|
||||
}
|
||||
}
|
||||
.make-color-classes();
|
||||
|
||||
&-text {
|
||||
margin-left: 8px;
|
||||
color: @text-color;
|
||||
|
@ -144,3 +144,6 @@
|
||||
@gold-8: color(~`colorPalette('@{gold-6}', 8) `);
|
||||
@gold-9: color(~`colorPalette('@{gold-6}', 9) `);
|
||||
@gold-10: color(~`colorPalette('@{gold-6}', 10) `);
|
||||
|
||||
@preset-colors: pink, magenta, red, volcano, orange, yellow, gold, cyan, lime, green, blue, geekblue,
|
||||
purple;
|
||||
|
@ -6,6 +6,7 @@ import { polyfill } from 'react-lifecycles-compat';
|
||||
import Icon from '../icon';
|
||||
import CheckableTag from './CheckableTag';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { PresetColorTypes } from '../_util/colors';
|
||||
import Wave from '../_util/wave';
|
||||
|
||||
export { CheckableTagProps } from './CheckableTag';
|
||||
@ -29,6 +30,8 @@ interface InnterTagProps extends TagProps {
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
const PresetColorRegex = new RegExp(`^(${PresetColorTypes.join('|')})(-inverse)?$`);
|
||||
|
||||
const InnerTag = ({ show, ...restProps }: InnterTagProps) => {
|
||||
const divProps = omit(restProps, ['onClose', 'afterClose', 'color', 'visible', 'closable']);
|
||||
return <div {...divProps} />;
|
||||
@ -83,9 +86,7 @@ class Tag extends React.Component<TagProps, TagState> {
|
||||
if (!color) {
|
||||
return false;
|
||||
}
|
||||
return /^(pink|red|yellow|orange|cyan|green|blue|purple|geekblue|magenta|volcano|gold|lime)(-inverse)?$/.test(
|
||||
color,
|
||||
);
|
||||
return PresetColorRegex.test(color);
|
||||
}
|
||||
|
||||
getTagStyle() {
|
||||
|
@ -98,13 +98,10 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
@colors: pink, magenta, red, volcano, orange, yellow, gold, cyan, lime, green, blue, geekblue,
|
||||
purple;
|
||||
|
||||
// mixin to iterate over colors and create CSS class for each one
|
||||
.make-color-classes(@i: length(@colors)) when (@i > 0) {
|
||||
.make-color-classes(@i: length(@preset-colors)) when (@i > 0) {
|
||||
.make-color-classes(@i - 1);
|
||||
@color: extract(@colors, @i);
|
||||
@color: extract(@preset-colors, @i);
|
||||
@lightColor: '@{color}-1';
|
||||
@lightBorderColor: '@{color}-3';
|
||||
@darkColor: '@{color}-6';
|
||||
|
Loading…
Reference in New Issue
Block a user