Merge pull request #14565 from ant-design/feature

master merge feature
This commit is contained in:
zombieJ 2019-01-26 12:30:05 +08:00 committed by GitHub
commit 8b95eb1df6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
147 changed files with 5151 additions and 2120 deletions

View File

@ -35,6 +35,7 @@ Array [
"message",
"Menu",
"Modal",
"Statistic",
"notification",
"Pagination",
"Popconfirm",

View File

@ -2,6 +2,7 @@ import * as React from 'react';
import { findDOMNode } from 'react-dom';
import TransitionEvents from 'css-animation/lib/Event';
import raf from '../_util/raf';
import { ConfigConsumer, ConfigConsumerProps, CSPConfig } from '../config-provider';
let styleForPesudo: HTMLStyleElement | null;
@ -23,6 +24,7 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
private animationStartId: number;
private animationStart: boolean = false;
private destroy: boolean = false;
private csp?: CSPConfig;
isNotGrey(color: string) {
const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/);
@ -52,6 +54,11 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
!/rgba\(\d*, \d*, \d*, 0\)/.test(waveColor) && // any transparent rgba color
waveColor !== 'transparent'
) {
// Add nonce if CSP exist
if (this.csp && this.csp.nonce) {
styleForPesudo.nonce = this.csp.nonce;
}
extraNode.style.borderColor = waveColor;
styleForPesudo.innerHTML = `[ant-click-animating-without-extra-node="true"]:after { border-color: ${waveColor}; }`;
if (!document.body.contains(styleForPesudo)) {
@ -168,7 +175,14 @@ export default class Wave extends React.Component<{ insertExtraNode?: boolean }>
this.destroy = true;
}
renderWave = ({ csp }: ConfigConsumerProps) => {
const { children } = this.props;
this.csp = csp;
return children;
};
render() {
return this.props.children;
return <ConfigConsumer>{this.renderWave}</ConfigConsumer>;
}
}

View File

@ -7,6 +7,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon"
>
<svg
@ -38,6 +39,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon"
>
<svg
@ -66,6 +68,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
class="ant-alert-close-icon"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -104,6 +107,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-alert-icon"
>
<svg
@ -166,6 +170,7 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
class="ant-alert-close-icon"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -202,6 +207,7 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
class="ant-alert-close-icon"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -264,6 +270,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -294,6 +301,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -324,6 +332,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -354,6 +363,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -384,6 +394,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -416,6 +427,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -448,6 +460,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -480,6 +493,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-alert-icon"
>
<svg
@ -582,6 +596,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle ant-alert-icon"
>
<svg
@ -612,6 +627,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: info-circle"
class="anticon anticon-info-circle ant-alert-icon"
>
<svg
@ -642,6 +658,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon"
>
<svg
@ -672,6 +689,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-alert-icon"
>
<svg
@ -702,6 +720,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle ant-alert-icon"
>
<svg
@ -737,6 +756,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: info-circle"
class="anticon anticon-info-circle ant-alert-icon"
>
<svg
@ -772,6 +792,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon"
>
<svg
@ -807,6 +828,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
data-show="true"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-alert-icon"
>
<svg
@ -858,6 +880,7 @@ exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
class="ant-alert-close-icon"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg

View File

@ -51,6 +51,7 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -119,6 +120,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
class="ant-input-suffix"
>
<i
aria-label="icon: search"
class="anticon anticon-search certain-category-icon"
>
<svg
@ -152,6 +154,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -218,6 +221,7 @@ exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -290,6 +294,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -362,6 +367,7 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -434,6 +440,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -468,6 +475,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg

View File

@ -12,6 +12,7 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -200,6 +201,7 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -234,6 +236,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
style="width:64px;height:64px;line-height:64px;font-size:32px"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -255,6 +258,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -276,6 +280,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -297,6 +302,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-sm ant-avatar-circle ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -321,6 +327,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
style="width:64px;height:64px;line-height:64px;font-size:32px"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -342,6 +349,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-lg ant-avatar-square ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -363,6 +371,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -384,6 +393,7 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-sm ant-avatar-square ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -435,6 +445,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -492,6 +503,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
style="background-color:#87d068"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg

View File

@ -194,6 +194,7 @@ exports[`renders ./components/badge/demo/basic.md correctly 1`] = `
href="#"
/>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-scroll-number-custom-component"
style="color:#f5222d"
>
@ -398,6 +399,7 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: minus"
class="anticon anticon-minus"
>
<svg
@ -420,6 +422,7 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: plus"
class="anticon anticon-plus"
>
<svg
@ -475,6 +478,7 @@ exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
class="ant-badge"
>
<i
aria-label="icon: notification"
class="anticon anticon-notification"
>
<svg
@ -500,6 +504,7 @@ exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
class="ant-badge"
>
<i
aria-label="icon: notification"
class="anticon anticon-notification"
>
<svg

View File

@ -223,6 +223,7 @@ exports[`renders ./components/breadcrumb/demo/withIcon.md correctly 1`] = `
href=""
>
<i
aria-label="icon: home"
class="anticon anticon-home"
>
<svg
@ -252,6 +253,7 @@ exports[`renders ./components/breadcrumb/demo/withIcon.md correctly 1`] = `
href=""
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg

View File

@ -169,6 +169,7 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -197,6 +198,7 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
Go forward
</span>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -223,6 +225,7 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: cloud"
class="anticon anticon-cloud"
>
<svg
@ -245,6 +248,7 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: cloud-download"
class="anticon anticon-cloud-download"
>
<svg
@ -394,6 +398,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -416,6 +421,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -441,6 +447,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -463,6 +470,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -489,6 +497,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -511,6 +520,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -536,6 +546,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -558,6 +569,7 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -588,6 +600,7 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -613,6 +626,7 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -647,6 +661,7 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: poweroff"
class="anticon anticon-poweroff"
>
<svg
@ -673,6 +688,7 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -695,6 +711,7 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -741,6 +758,7 @@ exports[`renders ./components/button/demo/multiple.md correctly 1`] = `
Actions
</span>
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -865,6 +883,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: download"
class="anticon anticon-download"
>
<svg
@ -882,11 +901,38 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-round ant-btn-lg"
type="button"
>
<i
aria-label="icon: download"
class="anticon anticon-download"
>
<svg
aria-hidden="true"
class=""
data-icon="download"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
/>
</svg>
</i>
<span>
Download
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-lg"
type="button"
>
<i
aria-label="icon: download"
class="anticon anticon-download"
>
<svg
@ -916,6 +962,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -944,6 +991,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
Forward
</span>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg

View File

@ -44,6 +44,7 @@ exports[`Button renders Chinese characters correctly 2`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -72,6 +73,7 @@ exports[`Button renders Chinese characters correctly 3`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -100,6 +102,7 @@ exports[`Button renders Chinese characters correctly 4`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -128,6 +131,7 @@ exports[`Button renders Chinese characters correctly 5`] = `
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -156,6 +160,7 @@ exports[`Button renders Chinese characters correctly 6`] = `
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg

View File

@ -42,7 +42,7 @@ function insertSpace(child: React.ReactChild, needInserted: boolean) {
const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger');
export type ButtonType = (typeof ButtonTypes)[number];
const ButtonShapes = tuple('circle', 'circle-outline');
const ButtonShapes = tuple('circle', 'circle-outline', 'round');
export type ButtonShape = (typeof ButtonShapes)[number];
const ButtonSizes = tuple('large', 'default', 'small');
export type ButtonSize = (typeof ButtonSizes)[number];
@ -191,7 +191,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
return React.Children.count(children) === 1 && !icon;
}
renderButton = ({ getPrefixCls }: ConfigConsumerProps) => {
renderButton = ({ getPrefixCls, autoInsertSpaceInButton }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
type,
@ -208,6 +208,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
const { loading, hasTwoCNChar } = this.state;
const prefixCls = getPrefixCls('btn', customizePrefixCls);
const autoInsertSpace = autoInsertSpaceInButton !== false;
// large => lg
// small => sm
@ -229,7 +230,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
[`${prefixCls}-icon-only`]: !children && children !== 0 && icon,
[`${prefixCls}-loading`]: loading,
[`${prefixCls}-background-ghost`]: ghost,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
[`${prefixCls}-block`]: block,
});
@ -237,7 +238,9 @@ class Button extends React.Component<ButtonProps, ButtonState> {
const iconNode = iconType ? <Icon type={iconType} /> : null;
const kids =
children || children === 0
? React.Children.map(children, child => insertSpace(child, this.isNeedInserted()))
? React.Children.map(children, child =>
insertSpace(child, this.isNeedInserted() && autoInsertSpace),
)
: null;
const linkButtonRestProps = omit(rest as AnchorButtonProps, ['htmlType']);

View File

@ -45,6 +45,7 @@ class ButtonSize extends React.Component {
<Button type="danger" size={size}>Danger</Button>
<br />
<Button type="primary" shape="circle" icon="download" size={size} />
<Button type="primary" shape="round" icon="download" size={size}>Download</Button>
<Button type="primary" icon="download" size={size}>Download</Button>
<br />
<Button.Group size={size}>

View File

@ -22,7 +22,7 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
| htmlType | set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` |
| icon | set the icon of button, see: Icon component | string | - |
| loading | set the loading status of button | boolean \| { delay: number } | false |
| shape | can be set to `circle` or omitted | string | - |
| shape | can be set to `circle`, `round` or omitted | string | - |
| size | can be set to `small` `large` or omitted | string | `default` |
| target | same as target attribute of a, works when href is specified | string | - |
| type | can be set to `primary` `ghost` `dashed` `danger`(added in 2.7) or omitted (meaning `default`) | string | `default` |
@ -35,6 +35,12 @@ It accepts all props which native button support.
`<Button href="http://example.com">Hello world!</Button>` will be rendered into `<a href="http://example.com"><span>Hello world!</span></a>`.
## FAQ
### How to remove space between 2 chinese characters
Use [ConfigProvider](/components/config-provider/#API) to set `autoInsertSpaceInButton` as `false`.
<style>
[id^=components-button-demo-] .ant-btn {
margin-right: 8px;

View File

@ -25,7 +25,7 @@ subtitle: 按钮
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` |
| icon | 设置按钮的图标类型 | string | - |
| loading | 设置按钮载入状态 | boolean \| { delay: number } | `false` |
| shape | 设置按钮形状,可选值为 `circle` 或者不设 | string | - |
| shape | 设置按钮形状,可选值为 `circle``round` 或者不设 | string | - |
| size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default` |
| target | 相当于 a 链接的 target 属性href 存在时生效 | string | - |
| type | 设置按钮类型,可选值为 `primary` `dashed` `danger`(版本 2.7 中增加) 或者不设 | string | - |
@ -38,6 +38,13 @@ subtitle: 按钮
`<Button href="http://example.com">Hello world!</Button>` 则会渲染为 `<a href="http://example.com"><span>Hello world!</span></a>`
## FAQ
### 如何移除 2 个汉字时字间的空格
设置 [ConfigProvider](/components/config-provider/#API) 的 `autoInsertSpaceInButton``false`
<style>
[id^="components-button-demo-"] .ant-btn {
margin-right: 8px;

View File

@ -69,6 +69,10 @@
.btn-danger;
}
&-round {
.btn-round(@btn-prefix-cls);
}
&-circle,
&-circle-outline {
.btn-circle(@btn-prefix-cls);

View File

@ -220,6 +220,20 @@
.btn-danger() {
.button-variant-danger(@btn-danger-color, @btn-danger-bg, @btn-danger-border);
}
// round button
.btn-round(@btnClassName: btn) {
.button-size(@btn-circle-size; 0 @btn-circle-size / 2; @font-size-base + 2px; @btn-circle-size);
&.@{btnClassName}-lg {
.button-size(
@btn-circle-size-lg; 0 @btn-circle-size-lg / 2; @btn-font-size-lg + 2px; @btn-circle-size-lg
);
}
&.@{btnClassName}-sm {
.button-size(
@btn-circle-size-sm; 0 @btn-circle-size-sm / 2; @font-size-base; @btn-circle-size-sm
);
}
}
// circle button: the content only contains icon
.btn-circle(@btnClassName: btn) {
.square(@btn-circle-size);

View File

@ -37,6 +37,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -86,6 +87,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -1080,6 +1082,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -1129,6 +1132,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -2121,6 +2125,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -2170,6 +2175,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -3572,6 +3578,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -3621,6 +3628,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg

View File

@ -36,6 +36,7 @@ exports[`Calendar Calendar should support locale 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -84,6 +85,7 @@ exports[`Calendar Calendar should support locale 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg

View File

@ -612,6 +612,7 @@ exports[`renders ./components/card/demo/loading.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -635,6 +636,7 @@ exports[`renders ./components/card/demo/loading.md correctly 1`] = `
>
<span>
<i
aria-label="icon: edit"
class="anticon anticon-edit"
>
<svg
@ -658,6 +660,7 @@ exports[`renders ./components/card/demo/loading.md correctly 1`] = `
>
<span>
<i
aria-label="icon: ellipsis"
class="anticon anticon-ellipsis"
>
<svg
@ -735,6 +738,7 @@ exports[`renders ./components/card/demo/meta.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -758,6 +762,7 @@ exports[`renders ./components/card/demo/meta.md correctly 1`] = `
>
<span>
<i
aria-label="icon: edit"
class="anticon anticon-edit"
>
<svg
@ -781,6 +786,7 @@ exports[`renders ./components/card/demo/meta.md correctly 1`] = `
>
<span>
<i
aria-label="icon: ellipsis"
class="anticon anticon-ellipsis"
>
<svg
@ -870,6 +876,7 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
class="ant-tabs-tab-prev-icon"
>
<i
aria-label="icon: left"
class="anticon anticon-left ant-tabs-tab-prev-icon-target"
>
<svg
@ -896,6 +903,7 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
class="ant-tabs-tab-next-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right ant-tabs-tab-next-icon-target"
>
<svg
@ -1026,6 +1034,7 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
class="ant-tabs-tab-prev-icon"
>
<i
aria-label="icon: left"
class="anticon anticon-left ant-tabs-tab-prev-icon-target"
>
<svg
@ -1052,6 +1061,7 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
class="ant-tabs-tab-next-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right ant-tabs-tab-next-icon-target"
>
<svg

View File

@ -17,6 +17,7 @@ exports[`renders ./components/cascader/demo/basic.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -53,6 +54,7 @@ exports[`renders ./components/cascader/demo/change-on-select.md correctly 1`] =
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -103,7 +105,9 @@ exports[`renders ./components/cascader/demo/custom-render.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-cascader-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -120,6 +124,7 @@ exports[`renders ./components/cascader/demo/custom-render.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -169,7 +174,9 @@ exports[`renders ./components/cascader/demo/default-value.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-cascader-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -186,6 +193,7 @@ exports[`renders ./components/cascader/demo/default-value.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -222,6 +230,7 @@ exports[`renders ./components/cascader/demo/disabled-option.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -258,6 +267,7 @@ exports[`renders ./components/cascader/demo/fields-name.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -294,6 +304,7 @@ exports[`renders ./components/cascader/demo/hover.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -330,6 +341,7 @@ exports[`renders ./components/cascader/demo/lazy.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -365,6 +377,7 @@ exports[`renders ./components/cascader/demo/search.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -402,6 +415,7 @@ exports[`renders ./components/cascader/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -437,6 +451,7 @@ exports[`renders ./components/cascader/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -472,6 +487,7 @@ exports[`renders ./components/cascader/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -512,6 +528,7 @@ exports[`renders ./components/cascader/demo/suffix.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-cascader-picker-arrow"
>
<svg

View File

@ -18,6 +18,7 @@ exports[`Cascader can be selected 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -45,6 +46,7 @@ exports[`Cascader can be selected 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -76,6 +78,7 @@ exports[`Cascader can be selected 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -118,6 +121,7 @@ exports[`Cascader can be selected 2`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -145,6 +149,7 @@ exports[`Cascader can be selected 2`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -176,6 +181,7 @@ exports[`Cascader can be selected 2`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -228,6 +234,7 @@ exports[`Cascader can be selected 3`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -255,6 +262,7 @@ exports[`Cascader can be selected 3`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -286,6 +294,7 @@ exports[`Cascader can be selected 3`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -348,6 +357,7 @@ exports[`Cascader popup correctly when panel is open 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -375,6 +385,7 @@ exports[`Cascader popup correctly when panel is open 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -417,6 +428,7 @@ exports[`Cascader popup correctly with defaultValue 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -444,6 +456,7 @@ exports[`Cascader popup correctly with defaultValue 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -475,6 +488,7 @@ exports[`Cascader popup correctly with defaultValue 1`] = `
class="ant-cascader-menu-item-expand-icon"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -1227,7 +1241,9 @@ exports[`Cascader support controlled mode 1`] = `
value=""
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-cascader-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -1244,6 +1260,7 @@ exports[`Cascader support controlled mode 1`] = `
</svg>
</i>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg

View File

@ -17,6 +17,17 @@ export interface CollapseProps {
className?: string;
bordered?: boolean;
prefixCls?: string;
expandIcon?: (panelProps: any) => React.ReactNode;
}
interface PanelProps {
isActive?: boolean;
header?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
showArrow?: boolean;
forceRender?: boolean;
disabled?: boolean;
}
export default class Collapse extends React.Component<CollapseProps, any> {
@ -27,8 +38,18 @@ export default class Collapse extends React.Component<CollapseProps, any> {
openAnimation: { ...animation, appear() {} },
};
renderExpandIcon = () => {
return <Icon type="right" className={`arrow`} />;
renderExpandIcon = (panelProps: PanelProps = {}, prefixCls: string) => {
const { expandIcon } = this.props;
const icon = expandIcon ? (
expandIcon(panelProps)
) : (
<Icon type="right" rotate={panelProps.isActive ? 90 : undefined} />
);
return React.isValidElement(icon)
? React.cloneElement(icon as any, {
className: `${prefixCls}-arrow`,
})
: icon;
};
renderCollapse = ({ getPrefixCls }: ConfigConsumerProps) => {
@ -43,9 +64,9 @@ export default class Collapse extends React.Component<CollapseProps, any> {
return (
<RcCollapse
{...this.props}
expandIcon={(panelProps: PanelProps) => this.renderExpandIcon(panelProps, prefixCls)}
prefixCls={prefixCls}
className={collapseClassName}
expandIcon={this.renderExpandIcon}
/>
);
};

View File

@ -15,7 +15,8 @@ exports[`renders ./components/collapse/demo/accordion.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -44,7 +45,8 @@ exports[`renders ./components/collapse/demo/accordion.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -73,7 +75,8 @@ exports[`renders ./components/collapse/demo/accordion.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -109,7 +112,8 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -117,6 +121,7 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
data-icon="right"
fill="currentColor"
height="1em"
style="-ms-transform:rotate(90deg);transform:rotate(90deg)"
viewBox="64 64 896 896"
width="1em"
>
@ -153,7 +158,8 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -182,7 +188,8 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
tabindex="-1"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -218,7 +225,8 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -226,6 +234,7 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
data-icon="right"
fill="currentColor"
height="1em"
style="-ms-transform:rotate(90deg);transform:rotate(90deg)"
viewBox="64 64 896 896"
width="1em"
>
@ -260,7 +269,8 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -289,7 +299,8 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -326,19 +337,21 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: caret-right"
class="anticon anticon-caret-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
data-icon="caret-right"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
style="-ms-transform:rotate(90deg);transform:rotate(90deg)"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
d="M715.8 493.5L335 165.1c-14.2-12.2-35-1.2-35 18.5v656.8c0 19.7 20.8 30.7 35 18.5l380.8-328.4c10.9-9.4 10.9-27.6 0-37z"
/>
</svg>
</i>
@ -371,19 +384,20 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: caret-right"
class="anticon anticon-caret-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
data-icon="caret-right"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
d="M715.8 493.5L335 165.1c-14.2-12.2-35-1.2-35 18.5v656.8c0 19.7 20.8 30.7 35 18.5l380.8-328.4c10.9-9.4 10.9-27.6 0-37z"
/>
</svg>
</i>
@ -401,19 +415,20 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: caret-right"
class="anticon anticon-caret-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
data-icon="caret-right"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
d="M715.8 493.5L335 165.1c-14.2-12.2-35-1.2-35 18.5v656.8c0 19.7 20.8 30.7 35 18.5l380.8-328.4c10.9-9.4 10.9-27.6 0-37z"
/>
</svg>
</i>
@ -437,7 +452,8 @@ exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -466,7 +482,8 @@ exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -495,7 +512,8 @@ exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -531,7 +549,8 @@ exports[`renders ./components/collapse/demo/noarrow.md correctly 1`] = `
tabindex="0"
>
<i
class="anticon anticon-right arrow"
aria-label="icon: right"
class="anticon anticon-right ant-collapse-arrow"
>
<svg
aria-hidden="true"
@ -539,6 +558,7 @@ exports[`renders ./components/collapse/demo/noarrow.md correctly 1`] = `
data-icon="right"
fill="currentColor"
height="1em"
style="-ms-transform:rotate(90deg);transform:rotate(90deg)"
viewBox="64 64 896 896"
width="1em"
>

View File

@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Collapse should support remove expandIcon 1`] = `
<div
class="ant-collapse"
>
<div
class="ant-collapse-item"
>
<div
aria-expanded="false"
class="ant-collapse-header"
role="button"
tabindex="0"
>
header
</div>
</div>
</div>
`;

View File

@ -0,0 +1,14 @@
import React from 'react';
import { mount } from 'enzyme';
import Collapse from '..';
describe('Collapse', () => {
it('should support remove expandIcon', () => {
const wrapper = mount(
<Collapse expandIcon={() => null}>
<Collapse.Panel header="header" />
</Collapse>
);
expect(wrapper.render()).toMatchSnapshot();
});
});

View File

@ -7,14 +7,14 @@ title:
## zh-CN
自定义各个面板的背景色、圆角和边距
自定义各个面板的背景色、圆角、边距和图标
## en-US
Customize the background, border and margin styles for each panel.
Customize the background, border, margin styles and icon for each panel.
````jsx
import { Collapse } from 'antd';
import { Collapse, Icon } from 'antd';
const Panel = Collapse.Panel;
@ -33,7 +33,11 @@ const customPanelStyle = {
};
ReactDOM.render(
<Collapse bordered={false} defaultActiveKey={['1']}>
<Collapse
bordered={false}
defaultActiveKey={['1']}
expandIcon={({ isActive }) => <Icon type="caret-right" rotate={isActive ? 90 : 0} />}
>
<Panel header="This is panel header 1" key="1" style={customPanelStyle}>
<p>{text}</p>
</Panel>

View File

@ -18,11 +18,12 @@ A content area which can be collapsed and expanded.
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| accordion | If `true`, `Collapse` renders as `Accordion` | boolean | `false` |
| activeKey | Key of the active panel | string\[]\|string | No default value. In `accordion` mode, it's the key of the first panel. |
| bordered | Toggles rendering of the border around the collapse block | boolean | `true` |
| defaultActiveKey | Key of the initial active panel | string | - |
| bordered | Toggles rendering of the border around the collapse block | boolean | `true` |
| accordion | If `true`, `Collapse` renders as `Accordion` | boolean | `false` |
| onChange | Callback function executed when active panel is changed | Function | - |
| expandIcon | allow to customize collapse icon | (panelProps) => ReactNode | - |
| destroyInactivePanel | Destroy Inactive Panel | boolean | `false` |
### Collapse.Panel

View File

@ -21,7 +21,11 @@ cols: 1
| --- | --- | --- | --- |
| activeKey | 当前激活 tab 面板的 key | string\[]\|string | 默认无accordion模式下默认第一个元素 |
| defaultActiveKey | 初始化选中面板的 key | string | 无 |
| bordered | 带边框风格的折叠面板 | boolean | `true` |
| accordion | 手风琴模式 | boolean | `false` |
| onChange | 切换面板的回调 | Function | 无 |
| expandIcon | 自定义切换图标 | (panelProps) => ReactNode | - |
| destroyInactivePanel | 销毁折叠隐藏的面板 | boolean | `false` |
### Collapse.Panel
@ -31,6 +35,7 @@ cols: 1
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
| header | 面板头内容 | string\|ReactNode | 无 |
| key | 对应 activeKey | string | 无 |
| showArrow | 是否展示当前面板上的箭头 | boolean | `true` |
## FAQ

View File

@ -3,13 +3,6 @@
@collapse-prefix-cls: ~'@{ant-prefix}-collapse';
.collapse-close() {
transform: rotate(0);
}
.collapse-open() {
transform: rotate(90deg);
}
.@{collapse-prefix-cls} {
.reset-component;
background-color: @collapse-header-bg;
@ -35,7 +28,7 @@
position: relative;
transition: all 0.3s;
.arrow {
.@{collapse-prefix-cls}-arrow {
.iconfont-mixin();
font-size: @font-size-sm;
position: absolute;
@ -43,10 +36,11 @@
line-height: 46px;
vertical-align: top;
top: 50%;
margin-top: 2px;
transform: translateY(-50%);
left: @padding-md;
& svg {
.collapse-close();
transition: transform 0.24s;
}
}
@ -88,12 +82,6 @@
}
}
& > &-item > &-header[aria-expanded='true'] {
.anticon-right svg {
.collapse-open();
}
}
&-borderless {
background-color: @component-background;
border: 0;

View File

@ -53,7 +53,9 @@ exports[`renders ./components/comment/demo/basic.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: like"
class="anticon anticon-like"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -79,7 +81,9 @@ exports[`renders ./components/comment/demo/basic.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: dislike"
class="anticon anticon-dislike"
tabindex="-1"
>
<svg
aria-hidden="true"

View File

@ -0,0 +1,559 @@
import React from 'react';
import { render } from 'enzyme';
import moment from 'moment';
import ConfigProvider from '..';
import Alert from '../../alert';
import Anchor from '../../anchor';
import AutoComplete from '../../auto-complete';
import Avatar from '../../avatar';
import BackTop from '../../back-top';
import Badge from '../../badge';
import Breadcrumb from '../../breadcrumb';
import Button from '../../button';
import Calendar from '../../calendar';
import Card from '../../card';
import Carousel from '../../carousel';
import Cascader from '../../cascader';
import Checkbox from '../../checkbox';
import Collapse from '../../collapse';
import Comment from '../../comment';
import DatePicker from '../../date-picker';
import Divider from '../../divider';
import Drawer from '../../drawer';
import Dropdown from '../../dropdown';
import Form from '../../form';
import { Row, Col } from '../../grid';
import Input from '../../input';
import InputNumber from '../../input-number';
import Layout from '../../layout';
import List from '../../list';
import Mention from '../../mention';
import Menu from '../../menu';
import Modal from '../../modal';
import Pagination from '../../pagination';
import Popconfirm from '../../popconfirm';
import Popover from '../../popover';
import Progress from '../../progress';
import Radio from '../../radio';
import Rate from '../../rate';
import Select from '../../select';
import Skeleton from '../../skeleton';
import Slider from '../../slider';
import Spin from '../../spin';
import Statistic from '../../statistic';
import Steps from '../../steps';
import Switch from '../../switch';
import Table from '../../table';
import Tabs from '../../tabs';
import Tag from '../../tag';
import TimePicker from '../../time-picker';
import Timeline from '../../timeline';
import Tooltip from '../../tooltip';
import Transfer from '../../transfer';
import Tree from '../../tree';
import TreeSelect from '../../tree-select';
import Upload from '../../upload';
jest.mock('draft-js/lib/generateRandomKey', () => () => '123');
jest.mock('rc-util/lib/Portal');
describe('ConfigProvider', () => {
describe('components', () => {
function testPair(name, renderComponent) {
describe(name, () => {
// normal
it('normal', () => {
expect(render(renderComponent({}))).toMatchSnapshot();
});
// prefixCls
it('prefixCls', () => {
expect(render(renderComponent({ prefixCls: `prefix-${name}` }))).toMatchSnapshot();
});
// configProvider
it('configProvider', () => {
expect(
render(<ConfigProvider prefixCls="config">{renderComponent({})}</ConfigProvider>),
).toMatchSnapshot();
});
});
}
// Alert
testPair('Alert', props => (
<Alert {...props} message="Bamboo is Little Light" type="success" />
));
// Anchor
testPair('Anchor', props => (
<Anchor {...props}>
<Anchor.Link {...props} href="#bamboo" title="Little Light" />
</Anchor>
));
// AutoComplete
testPair('AutoComplete', props => <AutoComplete {...props} />);
// Avatar
testPair('Avatar', props => <Avatar {...props} />);
// BackTop
testPair('BackTop', props => <BackTop visible {...props} />);
// Badge
testPair('Badge', props => {
const newProps = {
...props,
};
// Hook for additional `scrollNumberPrefixCls` prop
if (props.prefixCls) {
newProps.scrollNumberPrefixCls = 'prefix-scroll-number';
}
return (
<div>
<Badge {...newProps} count={5}>
<span />
</Badge>
<Badge {...newProps} dot>
<span />
</Badge>
</div>
);
});
// Breadcrumb
testPair('Breadcrumb', props => (
<Breadcrumb {...props}>
<Breadcrumb.Item {...props}>Bamboo</Breadcrumb.Item>
<Breadcrumb.Item {...props}>Light</Breadcrumb.Item>
</Breadcrumb>
));
// Button
testPair('Button', props => (
<div>
<Button {...props}>Bamboo</Button>
<Button.Group {...props}>
<Button {...props}>Little</Button>
<Button {...props}>Light</Button>
</Button.Group>
</div>
));
// Calendar
testPair('Calendar', props => (
<div>
<Calendar {...props} value={moment('2000-09-03')} mode="month" />
<Calendar {...props} value={moment('2000-09-03')} mode="year" />
</div>
));
// Card
testPair('Card', props => (
<Card {...props}>
<Card.Grid {...props}>
<Card.Meta {...props} />
</Card.Grid>
</Card>
));
// Carousel
testPair('Carousel', props => (
<Carousel {...props}>
<div>
<h3>Bamboo</h3>
</div>
<div>
<h3>Light</h3>
</div>
</Carousel>
));
// Cascader
testPair('Cascader', props => <Cascader {...props} options={[]} showSearch />);
// Checkbox
testPair('Checkbox', props => (
<Checkbox.Group {...props}>
<Checkbox {...props}>Bamboo</Checkbox>
</Checkbox.Group>
));
// Collapse
testPair('Collapse', props => (
<Collapse {...props}>
<Collapse.Panel header="Bamboo">
<p>Light</p>
</Collapse.Panel>
</Collapse>
));
// Comment
testPair('Comment', props => (
<Comment {...props} content="Bamboo">
<Comment {...props} content="Light" />
</Comment>
));
// DatePicker
describe('DatePicker', () => {
testPair('DatePicker', props => (
<div>
<DatePicker {...props} />
</div>
));
// RangePicker
testPair('RangePicker', props => (
<div>
<DatePicker.RangePicker {...props} />
</div>
));
// MonthPicker
testPair('MonthPicker', props => (
<div>
<DatePicker.MonthPicker {...props} />
</div>
));
// WeekPicker
testPair('WeekPicker', props => (
<div>
<DatePicker.WeekPicker {...props} />
</div>
));
});
// Divider
testPair('Divider', props => <Divider {...props} />);
// Drawer
testPair('Drawer', props => <Drawer {...props} visible getContainer={false} />);
// Dropdown
testPair('Dropdown', props => {
const menu = (
<Menu {...props}>
<Menu.Item {...props}>Bamboo</Menu.Item>
</Menu>
);
return (
<Dropdown.Button {...props} overlay={menu}>
Light
</Dropdown.Button>
);
});
// Form
testPair('Form', props => (
<Form {...props}>
<Form.Item {...props} validateStatus="error" help="Bamboo is Light">
<Input {...props} />
</Form.Item>
</Form>
));
// Grid
testPair('Grid', props => {
const rowProps = {};
const colProps = {};
if (props.prefixCls) {
rowProps.prefixCls = 'prefix-row';
colProps.prefixCls = 'prefix-col';
}
return (
<Row {...rowProps}>
<Col {...colProps} span={1} />
</Row>
);
});
// Input
testPair('Input', props => (
<div>
<Input.Group {...props}>
<Input {...props} />
<Input.Search {...props} />
</Input.Group>
<Input.TextArea {...props} />
</div>
));
// InputNumber
testPair('InputNumber', props => <InputNumber {...props} />);
// Layout
testPair('Layout', props => {
const siderProps = {};
const headerProps = {};
const contentProps = {};
const footerProps = {};
if (props.prefixCls) {
siderProps.prefixCls = 'prefix-sider';
headerProps.prefixCls = 'prefix-header';
contentProps.prefixCls = 'prefix-content';
footerProps.prefixCls = 'prefix-footer';
}
return (
<Layout {...props}>
<Layout.Sider {...siderProps} />
<Layout {...props}>
<Layout.Header {...headerProps} />
<Layout.Content {...contentProps} />
<Layout.Footer {...footerProps} />
</Layout>
</Layout>
);
});
// List
testPair('List', props => (
<List
{...props}
itemLayout="horizontal"
dataSource={['']}
renderItem={() => (
<List.Item {...props}>
<List.Item.Meta
{...props}
avatar={
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
}
title="Ant Design"
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
/>
</List.Item>
)}
/>
));
// Mention
testPair('Mention', props => <Mention {...props} />);
// Menu
testPair('Menu', props => (
<Menu {...props} defaultOpenKeys={['bamboo']} mode="inline">
<Menu.SubMenu {...props} key="bamboo" title="bamboo">
<Menu.ItemGroup {...props} key="g1" title="Item 1">
<Menu.Item {...props} key="1">
Light
</Menu.Item>
</Menu.ItemGroup>
</Menu.SubMenu>
</Menu>
));
// Modal
testPair('Modal', props => (
<div>
<Modal {...props} visible>
Bamboo is Little Light
</Modal>
</div>
));
// Pagination
testPair('Pagination', props => (
<div>
<Pagination showSizeChanger showQuickJumper {...props} />
<Pagination size="small" showSizeChanger showQuickJumper {...props} />
</div>
));
// Popconfirm
testPair('Popconfirm', props => (
<div>
<Popconfirm {...props} visible>
<span>Bamboo</span>
</Popconfirm>
</div>
));
// Popover
testPair('Popover', props => (
<div>
<Popover {...props} visible>
<span>Light</span>
</Popover>
</div>
));
// Progress
testPair('Progress', props => <Progress {...props} />);
// Radio
testPair('Radio', props => (
<div>
<Radio.Group {...props}>
<Radio {...props}>Bamboo</Radio>
</Radio.Group>
<Radio.Group {...props}>
<Radio.Button {...props}>Light</Radio.Button>
</Radio.Group>
</div>
));
// Rate
testPair('Rate', props => <Rate {...props} />);
// Select
testPair('Select', props => (
<Select {...props} open>
<Select.OptGroup key="grp">
<Select.Option key="Bamboo">Light</Select.Option>
</Select.OptGroup>
</Select>
));
// Skeleton
testPair('Skeleton', props => <Skeleton title avatar paragraph {...props} />);
// Slider
testPair('Slider', props => {
const myProps = { ...props };
if (myProps.prefixCls) {
myProps.tooltipPrefixCls = `${myProps.prefixCls}-tooltip`;
}
return <Slider tooltipVisible {...myProps} />;
});
// Spin
testPair('Spin', props => <Spin {...props} />);
// Statistic
testPair('Statistic', props => <Statistic {...props} value={0} />);
// Steps
testPair('Steps', props => {
const myProps = { ...props };
if (props.prefixCls) {
myProps.iconPrefix = 'prefixIcon';
}
return (
<Steps {...props}>
<Steps.Step title="Bamboo" description="Little Light" />
</Steps>
);
});
// Switch
testPair('Switch', props => <Switch {...props} />);
// Table
testPair('Table', props => {
const columns = [
{
title: 'Name',
dataIndex: 'name',
filters: [
{
text: 'Joe',
value: 'Joe',
},
{
text: 'Submenu',
value: 'Submenu',
children: [
{
text: 'Green',
value: 'Green',
},
],
},
],
filterDropdownVisible: true,
onFilter: (value, record) => record.name.indexOf(value) === 0,
sorter: (a, b) => a.name.length - b.name.length,
},
];
const myProps = { ...props };
if (props.prefixCls) {
myProps.dropdownPrefixCls = 'prefix-dropdown';
}
return <Table columns={columns} {...props} />;
});
// Tabs
testPair('Tabs', props => (
<Tabs {...props}>
<Tabs.TabPane tab="Bamboo" key="Light" />
</Tabs>
));
// Tags
testPair('Tags', props => (
<div>
<Tag {...props}>Bamboo</Tag>
<Tag.CheckableTag {...props}>Light</Tag.CheckableTag>
</div>
));
// TimePicker
testPair('TimePicker', props => (
<TimePicker {...props} open defaultOpenValue={moment('00:00:00', 'HH:mm:ss')} />
));
// Timeline
testPair('Timeline', props => (
<Timeline {...props}>
<Timeline.Item {...props}>Bamboo</Timeline.Item>
</Timeline>
));
// Tooltip
testPair('Tooltip', props => (
<Tooltip {...props} title="Bamboo" visible>
<span>Light</span>
</Tooltip>
));
// Transfer
testPair('Transfer', props => <Transfer {...props} dataSource={[]} />);
// Tree
testPair('Tree', props => (
<div>
<Tree {...props}>
<Tree.TreeNode title="bamboo" />
</Tree>
<Tree.DirectoryTree {...props}>
<Tree.TreeNode title="bamboo" />
</Tree.DirectoryTree>
</div>
));
// TreeSelect
testPair('TreeSelect', props => (
<TreeSelect {...props} open>
<TreeSelect.TreeNode title="bamboo" value="light" />
</TreeSelect>
));
// Upload
testPair('Upload', props => (
<Upload
{...props}
defaultFileList={[
{
uid: '1',
name: 'xxx.png',
status: 'done',
},
]}
>
<span />
</Upload>
));
});
});

View File

@ -1,555 +1,27 @@
import React from 'react';
import { render } from 'enzyme';
import moment from 'moment';
import { mount } from 'enzyme';
import ConfigProvider from '..';
import Alert from '../../alert';
import Anchor from '../../anchor';
import AutoComplete from '../../auto-complete';
import Avatar from '../../avatar';
import BackTop from '../../back-top';
import Badge from '../../badge';
import Breadcrumb from '../../breadcrumb';
import Button from '../../button';
import Calendar from '../../calendar';
import Card from '../../card';
import Carousel from '../../carousel';
import Cascader from '../../cascader';
import Checkbox from '../../checkbox';
import Collapse from '../../collapse';
import Comment from '../../comment';
import DatePicker from '../../date-picker';
import Divider from '../../divider';
import Drawer from '../../drawer';
import Dropdown from '../../dropdown';
import Form from '../../form';
import { Row, Col } from '../../grid';
import Input from '../../input';
import InputNumber from '../../input-number';
import Layout from '../../layout';
import List from '../../list';
import Mention from '../../mention';
import Menu from '../../menu';
import Modal from '../../modal';
import Pagination from '../../pagination';
import Popconfirm from '../../popconfirm';
import Popover from '../../popover';
import Progress from '../../progress';
import Radio from '../../radio';
import Rate from '../../rate';
import Select from '../../select';
import Skeleton from '../../skeleton';
import Slider from '../../slider';
import Spin from '../../spin';
import Steps from '../../steps';
import Switch from '../../switch';
import Table from '../../table';
import Tabs from '../../tabs';
import Tag from '../../tag';
import TimePicker from '../../time-picker';
import Timeline from '../../timeline';
import Tooltip from '../../tooltip';
import Transfer from '../../transfer';
import Tree from '../../tree';
import TreeSelect from '../../tree-select';
import Upload from '../../upload';
jest.mock('draft-js/lib/generateRandomKey', () => () => '123');
jest.mock('rc-util/lib/Portal');
describe('ConfigProvider', () => {
describe('components', () => {
function testPair(name, renderComponent) {
describe(name, () => {
// normal
it('normal', () => {
expect(render(renderComponent({}))).toMatchSnapshot();
});
it('Content Security Policy', () => {
const csp = { nonce: 'test-antd' };
const wrapper = mount(
<ConfigProvider csp={csp}>
<Button />
</ConfigProvider>,
);
// prefixCls
it('prefixCls', () => {
expect(render(renderComponent({ prefixCls: `prefix-${name}` }))).toMatchSnapshot();
});
expect(wrapper.find('Wave').instance().csp).toBe(csp);
});
// configProvider
it('configProvider', () => {
expect(
render(<ConfigProvider prefixCls="config">{renderComponent({})}</ConfigProvider>),
).toMatchSnapshot();
});
});
}
it('autoInsertSpaceInButton', () => {
const wrapper = mount(
<ConfigProvider autoInsertSpaceInButton={false}>
<Button>确定</Button>
</ConfigProvider>,
);
// Alert
testPair('Alert', props => (
<Alert {...props} message="Bamboo is Little Light" type="success" />
));
// Anchor
testPair('Anchor', props => (
<Anchor {...props}>
<Anchor.Link {...props} href="#bamboo" title="Little Light" />
</Anchor>
));
// AutoComplete
testPair('AutoComplete', props => <AutoComplete {...props} />);
// Avatar
testPair('Avatar', props => <Avatar {...props} />);
// BackTop
testPair('BackTop', props => <BackTop visible {...props} />);
// Badge
testPair('Badge', props => {
const newProps = {
...props,
};
// Hook for additional `scrollNumberPrefixCls` prop
if (props.prefixCls) {
newProps.scrollNumberPrefixCls = 'prefix-scroll-number';
}
return (
<div>
<Badge {...newProps} count={5}>
<span />
</Badge>
<Badge {...newProps} dot>
<span />
</Badge>
</div>
);
});
// Breadcrumb
testPair('Breadcrumb', props => (
<Breadcrumb {...props}>
<Breadcrumb.Item {...props}>Bamboo</Breadcrumb.Item>
<Breadcrumb.Item {...props}>Light</Breadcrumb.Item>
</Breadcrumb>
));
// Button
testPair('Button', props => (
<div>
<Button {...props}>Bamboo</Button>
<Button.Group {...props}>
<Button {...props}>Little</Button>
<Button {...props}>Light</Button>
</Button.Group>
</div>
));
// Calendar
testPair('Calendar', props => (
<div>
<Calendar {...props} value={moment('2000-09-03')} mode="month" />
<Calendar {...props} value={moment('2000-09-03')} mode="year" />
</div>
));
// Card
testPair('Card', props => (
<Card {...props}>
<Card.Grid {...props}>
<Card.Meta {...props} />
</Card.Grid>
</Card>
));
// Carousel
testPair('Carousel', props => (
<Carousel {...props}>
<div>
<h3>Bamboo</h3>
</div>
<div>
<h3>Light</h3>
</div>
</Carousel>
));
// Cascader
testPair('Cascader', props => <Cascader {...props} options={[]} showSearch />);
// Checkbox
testPair('Checkbox', props => (
<Checkbox.Group {...props}>
<Checkbox {...props}>Bamboo</Checkbox>
</Checkbox.Group>
));
// Collapse
testPair('Collapse', props => (
<Collapse {...props}>
<Collapse.Panel header="Bamboo">
<p>Light</p>
</Collapse.Panel>
</Collapse>
));
// Comment
testPair('Comment', props => (
<Comment {...props} content="Bamboo">
<Comment {...props} content="Light" />
</Comment>
));
// DatePicker
describe('DatePicker', () => {
testPair('DatePicker', props => (
<div>
<DatePicker {...props} />
</div>
));
// RangePicker
testPair('RangePicker', props => (
<div>
<DatePicker.RangePicker {...props} />
</div>
));
// MonthPicker
testPair('MonthPicker', props => (
<div>
<DatePicker.MonthPicker {...props} />
</div>
));
// WeekPicker
testPair('WeekPicker', props => (
<div>
<DatePicker.WeekPicker {...props} />
</div>
));
});
// Divider
testPair('Divider', props => <Divider {...props} />);
// Drawer
testPair('Drawer', props => <Drawer {...props} visible getContainer={false} />);
// Dropdown
testPair('Dropdown', props => {
const menu = (
<Menu {...props}>
<Menu.Item {...props}>Bamboo</Menu.Item>
</Menu>
);
return (
<Dropdown.Button {...props} overlay={menu}>
Light
</Dropdown.Button>
);
});
// Form
testPair('Form', props => (
<Form {...props}>
<Form.Item {...props} validateStatus="error" help="Bamboo is Light">
<Input {...props} />
</Form.Item>
</Form>
));
// Grid
testPair('Grid', props => {
const rowProps = {};
const colProps = {};
if (props.prefixCls) {
rowProps.prefixCls = 'prefix-row';
colProps.prefixCls = 'prefix-col';
}
return (
<Row {...rowProps}>
<Col {...colProps} span={1} />
</Row>
);
});
// Input
testPair('Input', props => (
<div>
<Input.Group {...props}>
<Input {...props} />
<Input.Search {...props} />
</Input.Group>
<Input.TextArea {...props} />
</div>
));
// InputNumber
testPair('InputNumber', props => <InputNumber {...props} />);
// Layout
testPair('Layout', props => {
const siderProps = {};
const headerProps = {};
const contentProps = {};
const footerProps = {};
if (props.prefixCls) {
siderProps.prefixCls = 'prefix-sider';
headerProps.prefixCls = 'prefix-header';
contentProps.prefixCls = 'prefix-content';
footerProps.prefixCls = 'prefix-footer';
}
return (
<Layout {...props}>
<Layout.Sider {...siderProps} />
<Layout {...props}>
<Layout.Header {...headerProps} />
<Layout.Content {...contentProps} />
<Layout.Footer {...footerProps} />
</Layout>
</Layout>
);
});
// List
testPair('List', props => (
<List
{...props}
itemLayout="horizontal"
dataSource={['']}
renderItem={() => (
<List.Item {...props}>
<List.Item.Meta
{...props}
avatar={
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
}
title="Ant Design"
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
/>
</List.Item>
)}
/>
));
// Mention
testPair('Mention', props => <Mention {...props} />);
// Menu
testPair('Menu', props => (
<Menu {...props} defaultOpenKeys={['bamboo']} mode="inline">
<Menu.SubMenu {...props} key="bamboo" title="bamboo">
<Menu.ItemGroup {...props} key="g1" title="Item 1">
<Menu.Item {...props} key="1">
Light
</Menu.Item>
</Menu.ItemGroup>
</Menu.SubMenu>
</Menu>
));
// Modal
testPair('Modal', props => (
<div>
<Modal {...props} visible>
Bamboo is Little Light
</Modal>
</div>
));
// Pagination
testPair('Pagination', props => (
<div>
<Pagination showSizeChanger showQuickJumper {...props} />
<Pagination size="small" showSizeChanger showQuickJumper {...props} />
</div>
));
// Popconfirm
testPair('Popconfirm', props => (
<div>
<Popconfirm {...props} visible>
<span>Bamboo</span>
</Popconfirm>
</div>
));
// Popover
testPair('Popover', props => (
<div>
<Popover {...props} visible>
<span>Light</span>
</Popover>
</div>
));
// Progress
testPair('Progress', props => <Progress {...props} />);
// Radio
testPair('Radio', props => (
<div>
<Radio.Group {...props}>
<Radio {...props}>Bamboo</Radio>
</Radio.Group>
<Radio.Group {...props}>
<Radio.Button {...props}>Light</Radio.Button>
</Radio.Group>
</div>
));
// Rate
testPair('Rate', props => <Rate {...props} />);
// Select
testPair('Select', props => (
<Select {...props} open>
<Select.OptGroup key="grp">
<Select.Option key="Bamboo">Light</Select.Option>
</Select.OptGroup>
</Select>
));
// Skeleton
testPair('Skeleton', props => <Skeleton title avatar paragraph {...props} />);
// Slider
testPair('Slider', props => {
const myProps = { ...props };
if (myProps.prefixCls) {
myProps.tooltipPrefixCls = `${myProps.prefixCls}-tooltip`;
}
return <Slider tooltipVisible {...myProps} />;
});
// Spin
testPair('Spin', props => <Spin {...props} />);
// Steps
testPair('Steps', props => {
const myProps = { ...props };
if (props.prefixCls) {
myProps.iconPrefix = 'prefixIcon';
}
return (
<Steps {...props}>
<Steps.Step title="Bamboo" description="Little Light" />
</Steps>
);
});
// Switch
testPair('Switch', props => <Switch {...props} />);
// Table
testPair('Table', props => {
const columns = [
{
title: 'Name',
dataIndex: 'name',
filters: [
{
text: 'Joe',
value: 'Joe',
},
{
text: 'Submenu',
value: 'Submenu',
children: [
{
text: 'Green',
value: 'Green',
},
],
},
],
filterDropdownVisible: true,
onFilter: (value, record) => record.name.indexOf(value) === 0,
sorter: (a, b) => a.name.length - b.name.length,
},
];
const myProps = { ...props };
if (props.prefixCls) {
myProps.dropdownPrefixCls = 'prefix-dropdown';
}
return <Table columns={columns} {...props} />;
});
// Tabs
testPair('Tabs', props => (
<Tabs {...props}>
<Tabs.TabPane tab="Bamboo" key="Light" />
</Tabs>
));
// Tags
testPair('Tags', props => (
<div>
<Tag {...props}>Bamboo</Tag>
<Tag.CheckableTag {...props}>Light</Tag.CheckableTag>
</div>
));
// TimePicker
testPair('TimePicker', props => (
<TimePicker {...props} open defaultOpenValue={moment('00:00:00', 'HH:mm:ss')} />
));
// Timeline
testPair('Timeline', props => (
<Timeline {...props}>
<Timeline.Item {...props}>Bamboo</Timeline.Item>
</Timeline>
));
// Tooltip
testPair('Tooltip', props => (
<Tooltip {...props} title="Bamboo" visible>
<span>Light</span>
</Tooltip>
));
// Transfer
testPair('Transfer', props => <Transfer {...props} dataSource={[]} />);
// Tree
testPair('Tree', props => (
<div>
<Tree {...props}>
<Tree.TreeNode title="bamboo" />
</Tree>
<Tree.DirectoryTree {...props}>
<Tree.TreeNode title="bamboo" />
</Tree.DirectoryTree>
</div>
));
// TreeSelect
testPair('TreeSelect', props => (
<TreeSelect {...props} open>
<TreeSelect.TreeNode title="bamboo" value="light" />
</TreeSelect>
));
// Upload
testPair('Upload', props => (
<Upload
{...props}
defaultFileList={[
{
uid: '1',
name: 'xxx.png',
status: 'done',
},
]}
>
<span />
</Upload>
));
expect(wrapper.find('Button').text()).toBe('确定');
});
});

View File

@ -23,10 +23,21 @@ return (
);
```
### Content Security Policy
Some component use dynamic style to support wave effect. You can config `csp` prop if Content Security Policy (CSP) is enabled:
```jsx
<ConfigProvider csp={{ nonce: 'YourNonceCode' }}>
<Button>My Button</Button>
</ConfigProvider>
```
## API
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| autoInsertSpaceInButton | Set `false` to remove space between 2 chinese characters on Button | boolean | true |
| renderEmpty | set empty content of components. Ref [Empty](/components/empty/) | Function(componentName: string): ReactNode | - |
| getPopupContainer | to set the container of the popup element. The default is to create a `div` element in `body`. | Function(triggerNode) | `() => document.body` |
| prefixCls | set prefix class | string | ant |

View File

@ -5,11 +5,17 @@ import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
export { RenderEmptyHandler };
export interface CSPConfig {
nonce?: string;
}
export interface ConfigConsumerProps {
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
rootPrefixCls?: string;
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => string;
renderEmpty: RenderEmptyHandler;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
}
interface ConfigProviderProps {
@ -17,6 +23,8 @@ interface ConfigProviderProps {
prefixCls?: string;
children?: React.ReactNode;
renderEmpty?: RenderEmptyHandler;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
}
const ConfigContext: Context<ConfigConsumerProps | null> = createReactContext({
@ -42,11 +50,13 @@ class ConfigProvider extends React.Component<ConfigProviderProps> {
};
renderProvider = (context: ConfigConsumerProps) => {
const { children, getPopupContainer, renderEmpty } = this.props;
const { children, getPopupContainer, renderEmpty, csp, autoInsertSpaceInButton } = this.props;
const config: ConfigConsumerProps = {
...context,
getPrefixCls: this.getPrefixCls,
csp,
autoInsertSpaceInButton,
};
if (getPopupContainer) {
@ -80,9 +90,9 @@ interface ConsumerConfig {
}
export function withConfigConsumer<ExportProps extends BasicExportProps>(config: ConsumerConfig) {
return function(Component: IReactComponent): React.SFC<ExportProps> {
return function <ComponentDef>(Component: IReactComponent): React.SFC<ExportProps> & ComponentDef {
// Wrap with ConfigConsumer. Since we need compatible with react 15, be care when using ref methods
return (props: ExportProps) => (
return ((props: ExportProps) => (
<ConfigConsumer>
{(configProps: ConfigConsumerProps) => {
const { prefixCls: basicPrefixCls } = config;
@ -92,7 +102,7 @@ export function withConfigConsumer<ExportProps extends BasicExportProps>(config:
return <Component {...configProps} {...props} prefixCls={prefixCls} />;
}}
</ConfigConsumer>
);
)) as React.SFC<ExportProps> & ComponentDef;
};
}

View File

@ -24,10 +24,21 @@ return (
);
```
### Content Security Policy
部分组件为了支持波纹效果,使用了动态样式。如果开启了 Content Security Policy (CSP),你可以通过 `csp` 属性来进行配置:
```jsx
<ConfigProvider csp={{ nonce: 'YourNonceCode' }}>
<Button>My Button</Button>
</ConfigProvider>
```
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| autoInsertSpaceInButton | 设置为 `false` 时,移除按钮中 2 个汉字之间的空格 | boolean | true |
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty/) | Function(componentName: string): ReactNode | - |
| getPopupContainer | 弹出框Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | Function(triggerNode) | () => document.body |
| prefixCls | 设置统一样式前缀 | string | ant |

View File

@ -12,6 +12,7 @@ exports[`DatePicker disabled date 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -46,7 +47,9 @@ exports[`DatePicker prop locale should works 1`] = `
value="2000-01-01"
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -63,6 +66,7 @@ exports[`DatePicker prop locale should works 1`] = `
</svg>
</i>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg

View File

@ -801,6 +801,7 @@ exports[`WeekPicker should support style prop 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg

View File

@ -13,6 +13,7 @@ exports[`renders ./components/date-picker/demo/basic.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -43,6 +44,7 @@ exports[`renders ./components/date-picker/demo/basic.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -89,6 +91,7 @@ exports[`renders ./components/date-picker/demo/basic.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -121,6 +124,7 @@ exports[`renders ./components/date-picker/demo/basic.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -155,6 +159,7 @@ exports[`renders ./components/date-picker/demo/date-render.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -200,6 +205,7 @@ exports[`renders ./components/date-picker/demo/date-render.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -235,6 +241,7 @@ exports[`renders ./components/date-picker/demo/disabled.md correctly 1`] = `
value="2015-06-06"
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -266,6 +273,7 @@ exports[`renders ./components/date-picker/demo/disabled.md correctly 1`] = `
value="2015-06"
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -314,6 +322,7 @@ exports[`renders ./components/date-picker/demo/disabled.md correctly 1`] = `
value="2015-06-06"
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -349,6 +358,7 @@ exports[`renders ./components/date-picker/demo/disabled-date.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -379,6 +389,7 @@ exports[`renders ./components/date-picker/demo/disabled-date.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -426,6 +437,7 @@ exports[`renders ./components/date-picker/demo/disabled-date.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -460,6 +472,7 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -490,6 +503,7 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -535,6 +549,7 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -581,6 +596,7 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -610,6 +626,7 @@ exports[`renders ./components/date-picker/demo/extra-footer.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -644,7 +661,9 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
value="2015/01/01"
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -661,6 +680,7 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -691,7 +711,9 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
value="2015/01"
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -708,6 +730,7 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -754,7 +777,9 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
value="2015/01/01"
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -771,6 +796,7 @@ exports[`renders ./components/date-picker/demo/format.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -806,6 +832,7 @@ exports[`renders ./components/date-picker/demo/mode.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -852,6 +879,7 @@ exports[`renders ./components/date-picker/demo/mode.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -902,6 +930,7 @@ exports[`renders ./components/date-picker/demo/presetted-ranges.md correctly 1`]
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -949,6 +978,7 @@ exports[`renders ./components/date-picker/demo/presetted-ranges.md correctly 1`]
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1047,6 +1077,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1077,6 +1108,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1123,6 +1155,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1155,6 +1188,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1190,6 +1224,7 @@ exports[`renders ./components/date-picker/demo/start-end.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1220,6 +1255,7 @@ exports[`renders ./components/date-picker/demo/start-end.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1254,6 +1290,7 @@ exports[`renders ./components/date-picker/demo/suffix.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-calendar-picker-icon"
>
<svg
@ -1284,6 +1321,7 @@ exports[`renders ./components/date-picker/demo/suffix.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-calendar-picker-icon"
>
<svg
@ -1330,6 +1368,7 @@ exports[`renders ./components/date-picker/demo/suffix.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-calendar-picker-icon"
>
<svg
@ -1362,6 +1401,7 @@ exports[`renders ./components/date-picker/demo/suffix.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-calendar-picker-icon"
>
<svg
@ -1487,6 +1527,7 @@ exports[`renders ./components/date-picker/demo/time.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -1534,6 +1575,7 @@ exports[`renders ./components/date-picker/demo/time.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg

View File

@ -973,3 +973,214 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
</div>
</div>
`;
exports[`Picker format by locale date 1`] = `
<span
class="ant-calendar-picker"
>
<div>
<input
class="ant-calendar-picker-input ant-input"
placeholder="请选择日期"
readonly=""
value="2000 年 1 月 1 日"
/>
<i
aria-label="图标: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="close-circle"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
<i
aria-label="图标: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="calendar"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
/>
</svg>
</i>
</div>
</span>
`;
exports[`Picker format by locale dateTime 1`] = `
<span
class="ant-calendar-picker"
style="width: 195px;"
>
<div>
<input
class="ant-calendar-picker-input ant-input"
placeholder="请选择日期"
readonly=""
value="2000 年 1 月 1 日 0 时 0 分 0 秒"
/>
<i
aria-label="图标: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="close-circle"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
<i
aria-label="图标: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="calendar"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
/>
</svg>
</i>
</div>
</span>
`;
exports[`Picker format by locale month 1`] = `
<span
class="ant-calendar-picker"
>
<div>
<input
class="ant-calendar-picker-input ant-input"
placeholder="请选择日期"
readonly=""
value="2000 年 1 月"
/>
<i
aria-label="图标: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="close-circle"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
<i
aria-label="图标: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="calendar"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
/>
</svg>
</i>
</div>
</span>
`;
exports[`Picker format by locale week 1`] = `
<span
class="ant-calendar-picker"
>
<span
style="display: inline-block; width: 100%;"
>
<input
class="ant-calendar-picker-input ant-input"
placeholder="请选择日期"
readonly=""
value="2000 年 52 周"
/>
<i
aria-label="图标: close-circle"
class="anticon anticon-close-circle ant-calendar-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="close-circle"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</i>
<i
aria-label="图标: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="calendar"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
/>
</svg>
</i>
</span>
</span>
`;

View File

@ -2,9 +2,42 @@ import React from 'react';
import { mount, render } from 'enzyme';
import moment from 'moment';
import DatePicker from '..';
import LocaleProvider from '../../locale-provider';
import locale from '../../locale-provider/zh_CN';
const { MonthPicker, WeekPicker } = DatePicker;
describe('Picker format by locale', () => {
const myLocale = {
...locale,
DatePicker: {
...locale.DatePicker,
dateFormat: 'YYYY 年 M 月 D 日',
dateTimeFormat: 'YYYY 年 M 月 D 日 H 时 m 分 s 秒',
weekFormat: 'YYYY 年 W 周',
monthFormat: 'YYYY 年 M 月',
},
};
const date = moment('2000-01-01', 'YYYY-MM-DD');
function matchPicker(name, Picker, props) {
it(name, () => {
const wrapper = mount(
<LocaleProvider locale={myLocale}>
<Picker value={date} {...props} />
</LocaleProvider>,
);
expect(wrapper.render()).toMatchSnapshot();
});
}
matchPicker('date', DatePicker);
matchPicker('dateTime', DatePicker, { showTime: true });
matchPicker('week', WeekPicker);
matchPicker('month', MonthPicker);
});
describe('MonthPicker and WeekPicker', () => {
it('render MonthPicker', () => {
const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');

View File

@ -31,7 +31,6 @@ ReactDOM.render(
<div>
<DatePicker
showTime
format="YYYY-MM-DD HH:mm:ss"
placeholder="Select Time"
onChange={onChange}
onOk={onOk}

View File

@ -7,16 +7,16 @@ import RangePicker from './RangePicker';
import WeekPicker from './WeekPicker';
import { DatePickerProps, DatePickerDecorator } from './interface';
const DatePicker = wrapPicker(createPicker(RcCalendar)) as React.ClassicComponentClass<
const DatePicker = wrapPicker(createPicker(RcCalendar), 'date') as React.ClassicComponentClass<
DatePickerProps
>;
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'YYYY-MM');
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'month');
Object.assign(DatePicker, {
RangePicker: wrapPicker(RangePicker),
RangePicker: wrapPicker(RangePicker, 'date'),
MonthPicker,
WeekPicker: wrapPicker(WeekPicker, 'gggg-wo'),
WeekPicker: wrapPicker(WeekPicker, 'week'),
});
export default DatePicker as DatePickerDecorator;

View File

@ -31,5 +31,9 @@
},
"timePickerLocale": {
"placeholder": "Select time"
}
},
"dateFormat": "YYYY-MM-DD",
"dateTimeFormat": "YYYY-MM-DD HH:mm:ss",
"weekFormat": "YYYY-wo",
"monthFormat": "YYYY-MM"
}

View File

@ -6,6 +6,25 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { generateShowHourMinuteSecond } from '../time-picker';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
type PickerType = 'date' | 'week' | 'month';
interface PickerMap {
[name: string]: string;
}
const DEFAULT_FORMAT: PickerMap = {
date: 'YYYY-MM-DD',
week: 'gggg-wo',
month: 'YYYY-MM',
};
const LOCALE_FORMAT_MAPPING: PickerMap = {
date: 'dateFormat',
dateTime: 'dateTimeFormat',
week: 'weekFormat',
month: 'monthFormat',
};
function getColumns({ showHour, showMinute, showSecond, use12Hours }: any) {
let column = 0;
if (showHour) {
@ -23,10 +42,9 @@ function getColumns({ showHour, showMinute, showSecond, use12Hours }: any) {
return column;
}
export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFormat?: string): any {
export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType: PickerType): any {
return class PickerWrapper extends React.Component<any, any> {
static defaultProps = {
format: defaultFormat || 'YYYY-MM-DD',
transitionName: 'slide-up',
popupStyle: {},
onChange() {},
@ -102,6 +120,13 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
};
renderPicker = (locale: any, localeCode: string) => {
const { format, showTime } = this.props;
const mergedPickerType = showTime ? `${pickerType}Time` : pickerType;
const mergedFormat =
format ||
locale[LOCALE_FORMAT_MAPPING[mergedPickerType]] ||
DEFAULT_FORMAT[mergedPickerType];
return (
<ConfigConsumer>
{({ getPrefixCls }: ConfigConsumerProps) => {
@ -110,7 +135,6 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
inputPrefixCls: customizeInputPrefixCls,
size,
disabled,
showTime,
} = this.props;
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
@ -145,6 +169,7 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
return (
<Picker
{...this.props}
format={mergedFormat}
ref={this.savePicker}
pickerClass={pickerClass}
pickerInputClass={pickerInputClass}

View File

@ -29,6 +29,7 @@ exports[`Drawer className is test_drawer 1`] = `
class="ant-drawer-close"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -121,6 +122,7 @@ exports[`Drawer destroyOnClose is true 1`] = `
class="ant-drawer-close"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -185,6 +187,7 @@ exports[`Drawer have a title 1`] = `
class="ant-drawer-close"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -244,6 +247,7 @@ exports[`Drawer render correctly 1`] = `
class="ant-drawer-close"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -302,6 +306,7 @@ exports[`Drawer render top drawer 1`] = `
class="ant-drawer-close"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg

View File

@ -38,6 +38,7 @@ exports[`Drawer render correctly 1`] = `
class="ant-drawer-close"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg

View File

@ -20,6 +20,7 @@ exports[`renders ./components/drawer/demo/form-in-drawer.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: plus"
class="anticon anticon-plus"
>
<svg

View File

@ -7,6 +7,7 @@ exports[`renders ./components/dropdown/demo/basic.md correctly 1`] = `
>
Hover me
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -53,6 +54,7 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: ellipsis"
class="anticon anticon-ellipsis"
>
<svg
@ -90,6 +92,7 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: ellipsis"
class="anticon anticon-ellipsis"
>
<svg
@ -117,6 +120,7 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
Button
</span>
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -144,6 +148,7 @@ exports[`renders ./components/dropdown/demo/event.md correctly 1`] = `
>
Hover me, Click menu item
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -170,6 +175,7 @@ exports[`renders ./components/dropdown/demo/item.md correctly 1`] = `
>
Hover me
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -196,6 +202,7 @@ exports[`renders ./components/dropdown/demo/overlay-visible.md correctly 1`] = `
>
Hover me
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -276,6 +283,7 @@ exports[`renders ./components/dropdown/demo/sub-menu.md correctly 1`] = `
>
Cascading menu
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -302,6 +310,7 @@ exports[`renders ./components/dropdown/demo/trigger.md correctly 1`] = `
>
Click me
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg

View File

@ -13,6 +13,7 @@ exports[`DropdownButton should support href like Button 1`] = `
type="button"
>
<i
aria-label="icon: ellipsis"
class="anticon anticon-ellipsis"
>
<svg

View File

@ -66,6 +66,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -110,6 +111,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
style="outline:none"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -148,6 +150,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -238,6 +241,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -261,6 +265,7 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg

View File

@ -449,6 +449,7 @@ exports[`renders ./components/form/demo/advanced-search.md correctly 1`] = `
>
Collapse
<i
aria-label="icon: down"
class="anticon anticon-down"
>
<svg
@ -572,6 +573,7 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -687,6 +689,7 @@ exports[`renders ./components/form/demo/customized-form-controls.md correctly 1`
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -760,6 +763,7 @@ exports[`renders ./components/form/demo/dynamic-form-item.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: plus"
class="anticon anticon-plus"
>
<svg
@ -1035,6 +1039,7 @@ exports[`renders ./components/form/demo/horizontal-login.md correctly 1`] = `
class="ant-input-prefix"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
style="color:rgba(0,0,0,.25)"
>
@ -1086,6 +1091,7 @@ exports[`renders ./components/form/demo/horizontal-login.md correctly 1`] = `
class="ant-input-prefix"
>
<i
aria-label="icon: lock"
class="anticon anticon-lock"
style="color:rgba(0,0,0,.25)"
>
@ -1353,6 +1359,7 @@ exports[`renders ./components/form/demo/normal-login.md correctly 1`] = `
class="ant-input-prefix"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
style="color:rgba(0,0,0,.25)"
>
@ -1404,6 +1411,7 @@ exports[`renders ./components/form/demo/normal-login.md correctly 1`] = `
class="ant-input-prefix"
>
<i
aria-label="icon: lock"
class="anticon anticon-lock"
style="color:rgba(0,0,0,.25)"
>
@ -1620,6 +1628,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
<span>
Nickname 
<i
aria-label="icon: question-circle-o"
class="anticon anticon-question-circle-o"
>
<svg
@ -1706,7 +1715,9 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-cascader-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -1723,6 +1734,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -1811,6 +1823,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -1920,6 +1933,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -2114,6 +2128,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -2172,6 +2187,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -2229,6 +2245,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -2302,6 +2319,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -2376,6 +2394,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -2435,6 +2454,7 @@ exports[`renders ./components/form/demo/time-related-controls.md correctly 1`] =
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
@ -2578,6 +2598,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -2714,6 +2735,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -2739,6 +2761,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -3319,6 +3342,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3340,6 +3364,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3373,6 +3398,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3394,6 +3420,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3427,6 +3454,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3448,6 +3476,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3481,6 +3510,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3502,6 +3532,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3535,6 +3566,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3556,6 +3588,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -3799,6 +3832,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -3858,6 +3892,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -3912,6 +3947,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle"
>
<svg
@ -3966,6 +4002,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle"
>
<svg
@ -4026,6 +4063,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -4048,6 +4086,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -4106,6 +4145,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
@ -4131,6 +4171,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: exclamation-circle"
class="anticon anticon-exclamation-circle"
>
<svg
@ -4204,6 +4245,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -4227,6 +4269,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle"
>
<svg
@ -4285,7 +4328,9 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle ant-cascader-picker-clear"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -4302,6 +4347,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
</svg>
</i>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -4323,6 +4369,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -4396,6 +4443,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -4452,6 +4500,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -4515,6 +4564,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -4540,6 +4590,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -4576,6 +4627,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-children-icon"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -4640,6 +4692,7 @@ exports[`renders ./components/form/demo/without-form-create.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -4665,6 +4718,7 @@ exports[`renders ./components/form/demo/without-form-create.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg

View File

@ -2,6 +2,7 @@
exports[`Icon \`component\` prop can access to svg defs if has children 1`] = `
<i
aria-label="icon: undefined"
class="anticon my-home-icon"
>
<svg
@ -24,12 +25,14 @@ exports[`Icon \`component\` prop can access to svg defs if has children 1`] = `
exports[`Icon should give warning and render <i>{null}</i> 1`] = `
<i
aria-label="icon: undefined"
class="anticon"
/>
`;
exports[`Icon should render to a <i class="xxx"><svg>...</svg></i> 1`] = `
<i
aria-label="icon: message"
class="anticon anticon-message my-icon-classname"
>
<svg
@ -51,6 +54,7 @@ exports[`Icon should render to a <i class="xxx"><svg>...</svg></i> 1`] = `
exports[`Icon should support basic usage 1`] = `
<div>
<i
aria-label="icon: home"
class="anticon anticon-home"
>
<svg
@ -68,6 +72,7 @@ exports[`Icon should support basic usage 1`] = `
</svg>
</i>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -85,6 +90,7 @@ exports[`Icon should support basic usage 1`] = `
</svg>
</i>
<i
aria-label="icon: smile"
class="anticon anticon-smile"
>
<svg
@ -102,6 +108,7 @@ exports[`Icon should support basic usage 1`] = `
</svg>
</i>
<i
aria-label="icon: sync"
class="anticon anticon-sync"
>
<svg
@ -119,6 +126,7 @@ exports[`Icon should support basic usage 1`] = `
</svg>
</i>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -140,6 +148,7 @@ exports[`Icon should support basic usage 1`] = `
exports[`Icon should support config global two-tone primary color 1`] = `
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -170,6 +179,7 @@ exports[`Icon should support config global two-tone primary color 1`] = `
exports[`Icon should support older usage 1`] = `
<div>
<i
aria-label="icon: home-o"
class="anticon anticon-home-o"
>
<svg
@ -187,6 +197,7 @@ exports[`Icon should support older usage 1`] = `
</svg>
</i>
<i
aria-label="icon: setting-fill"
class="anticon anticon-setting-fill"
>
<svg
@ -204,6 +215,7 @@ exports[`Icon should support older usage 1`] = `
</svg>
</i>
<i
aria-label="icon: smile-o"
class="anticon anticon-smile-o"
>
<svg
@ -221,6 +233,7 @@ exports[`Icon should support older usage 1`] = `
</svg>
</i>
<i
aria-label="icon: check-circle-twotone"
class="anticon anticon-check-circle-twotone"
>
<svg
@ -245,6 +258,7 @@ exports[`Icon should support older usage 1`] = `
exports[`Icon should support pass svg paths as children 1`] = `
<i
aria-label="icon: undefined"
class="anticon"
>
<svg
@ -268,6 +282,7 @@ exports[`Icon should support pass svg paths as children 1`] = `
exports[`Icon should support svg react component 1`] = `
<i
aria-label="icon: undefined"
class="anticon my-home-icon"
>
<svg
@ -290,6 +305,7 @@ exports[`Icon should support svg react component 1`] = `
exports[`Icon should support two-tone icon 1`] = `
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -322,6 +338,7 @@ exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
class="icons-list"
>
<i
aria-label="icon: undefined"
class="anticon"
>
<svg
@ -338,6 +355,7 @@ exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
</svg>
</i>
<i
aria-label="icon: undefined"
class="anticon"
>
<svg
@ -354,6 +372,7 @@ exports[`Icon.createFromIconfontCN() should support iconfont.cn 1`] = `
</svg>
</i>
<i
aria-label="icon: undefined"
class="anticon"
>
<svg

View File

@ -22,6 +22,7 @@ ReactDOM.render(
<Icon type="setting" theme="filled" />
<Icon type="smile" theme="outlined" />
<Icon type="sync" spin />
<Icon type="smile" rotate={180} />
<Icon type="loading" />
</div>,
mountNode

View File

@ -26,6 +26,7 @@ ReactDOM.render(<IconDisplay />, mountNode);
| style | Style properties of icon, like `fontSize` and `color` | CSSProperties | - |
| theme | Theme of the ant design icon | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' |
| spin | Rotate icon with animation | boolean | false |
| rotate | rateto degress (added in 3.13.0, not working in IE9) | number | - |
| component | The component used for the root node. This will override the **`type`** property. | ComponentType<CustomIconComponentProps\> | - |
| twoToneColor | Only support the two-tone icon. Specific the primary color. | string (hex color) | - |

View File

@ -11,6 +11,7 @@ import {
alias,
} from './utils';
import warning from '../_util/warning';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { getTwoToneColor, setTwoToneColor } from './twoTonePrimaryColor';
// Initial setting
@ -19,6 +20,10 @@ setTwoToneColor('#1890ff');
let defaultTheme: ThemeType = 'outlined';
let dangerousTheme: ThemeType | undefined = undefined;
export interface TransferLocale {
icon: string;
}
export interface CustomIconComponentProps {
width: string | number;
height: string | number;
@ -26,12 +31,15 @@ export interface CustomIconComponentProps {
viewBox?: string;
className?: string;
style?: React.CSSProperties;
spin?: boolean;
rotate?: number;
['aria-hidden']?: string;
}
export type ThemeType = 'filled' | 'outlined' | 'twoTone';
export interface IconProps {
tabIndex?: number;
type?: string;
className?: string;
theme?: ThemeType;
@ -41,6 +49,7 @@ export interface IconProps {
twoToneColor?: string;
viewBox?: string;
spin?: boolean;
rotate?: number;
style?: React.CSSProperties;
prefixCls?: string;
role?: string;
@ -64,6 +73,10 @@ const Icon: IconComponent<IconProps> = props => {
component: Component,
viewBox,
spin,
rotate,
tabIndex,
onClick,
// children
children,
@ -92,19 +105,24 @@ const Icon: IconComponent<IconProps> = props => {
[`anticon-spin`]: !!spin || type === 'loading',
});
let innerNode;
let innerNode: React.ReactNode;
const svgStyle = rotate
? {
msTransform: `rotate(${rotate}deg)`,
transform: `rotate(${rotate}deg)`,
}
: undefined;
const innerSvgProps: CustomIconComponentProps = {
...svgBaseProps,
className: svgClassString,
style: svgStyle,
viewBox,
};
// component > children > type
if (Component) {
const innerSvgProps: CustomIconComponentProps = {
...svgBaseProps,
className: svgClassString,
viewBox,
};
if (!viewBox) {
delete innerSvgProps.viewBox;
}
innerNode = <Component {...innerSvgProps}>{children}</Component>;
}
@ -117,10 +135,6 @@ const Icon: IconComponent<IconProps> = props => {
'Make sure that you provide correct `viewBox`' +
' prop (default `0 0 1024 1024`) to the icon.',
);
const innerSvgProps: CustomIconComponentProps = {
...svgBaseProps,
className: svgClassString,
};
innerNode = (
<svg {...innerSvgProps} viewBox={viewBox}>
{children}
@ -143,14 +157,34 @@ const Icon: IconComponent<IconProps> = props => {
dangerousTheme || theme || defaultTheme,
);
innerNode = (
<ReactIcon className={svgClassString} type={computedType} primaryColor={twoToneColor} />
<ReactIcon
className={svgClassString}
type={computedType}
primaryColor={twoToneColor}
style={svgStyle}
/>
);
}
let iconTabIndex = tabIndex;
if (iconTabIndex === undefined && onClick) {
iconTabIndex = -1;
}
return (
<i {...restProps} className={classString}>
{innerNode}
</i>
<LocaleReceiver componentName="Icon">
{(locale: TransferLocale) => (
<i
aria-label={`${locale.icon}: ${type}`}
{...restProps}
tabIndex={iconTabIndex}
onClick={onClick}
className={classString}
>
{innerNode}
</i>
)}
</LocaleReceiver>
);
};

View File

@ -31,6 +31,7 @@ ReactDOM.render(<IconDisplay />, mountNode);
| style | 设置图标的样式,例如 `fontSize``color` | CSSProperties | - |
| theme | 图标主题风格。可选实心、描线、双色等主题风格,适用于官方图标 | 'filled' \| 'outlined' \| 'twoTone' | 'outlined' |
| spin | 是否有旋转动画 | boolean | false |
| rotate | 图标旋转角度3.13.0 后新增IE9 无效) | number | - |
| component | 控制如何渲染图标,通常是一个渲染根标签为 `<svg>``React` 组件,**会使 `type` 属性失效** | ComponentType<CustomIconComponentProps\> | - |
| twoToneColor | 仅适用双色图标。设置双色图标的主要颜色 | string (十六进制颜色) | - |

View File

@ -81,6 +81,8 @@ export { default as Menu } from './menu';
export { default as Modal } from './modal';
export { default as Statistic } from './statistic';
export { default as notification } from './notification';
export { default as Pagination } from './pagination';

View File

@ -15,6 +15,7 @@ exports[`renders ./components/input-number/demo/basic.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -40,6 +41,7 @@ exports[`renders ./components/input-number/demo/basic.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -92,6 +94,7 @@ exports[`renders ./components/input-number/demo/digit.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -117,6 +120,7 @@ exports[`renders ./components/input-number/demo/digit.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -169,6 +173,7 @@ exports[`renders ./components/input-number/demo/disabled.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -194,6 +199,7 @@ exports[`renders ./components/input-number/demo/disabled.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -261,6 +267,7 @@ exports[`renders ./components/input-number/demo/formatter.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -286,6 +293,7 @@ exports[`renders ./components/input-number/demo/formatter.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -333,6 +341,7 @@ exports[`renders ./components/input-number/demo/formatter.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -358,6 +367,7 @@ exports[`renders ./components/input-number/demo/formatter.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -412,6 +422,7 @@ exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -437,6 +448,7 @@ exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -486,6 +498,7 @@ exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -511,6 +524,7 @@ exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -560,6 +574,7 @@ exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -585,6 +600,7 @@ exports[`renders ./components/input-number/demo/size.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg

View File

@ -72,6 +72,7 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -131,6 +132,7 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -172,6 +174,7 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
class="ant-input-group-addon"
>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -311,6 +314,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -371,6 +375,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -410,6 +415,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -435,6 +441,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -489,6 +496,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -542,6 +550,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -591,6 +600,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -645,6 +655,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -721,6 +732,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -790,6 +802,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -845,6 +858,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -881,6 +895,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: down"
class="anticon anticon-down ant-cascader-picker-arrow"
>
<svg
@ -917,7 +932,9 @@ exports[`renders ./components/input/demo/password-input.md correctly 1`] = `
class="ant-input-suffix"
>
<i
aria-label="icon: eye"
class="anticon anticon-eye ant-input-password-icon"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -945,6 +962,7 @@ exports[`renders ./components/input/demo/presuffix.md correctly 1`] = `
class="ant-input-prefix"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
style="color:rgba(0,0,0,.25)"
>
@ -988,7 +1006,9 @@ exports[`renders ./components/input/demo/search-input.md correctly 1`] = `
class="ant-input-suffix"
>
<i
aria-label="icon: search"
class="anticon anticon-search ant-input-search-icon"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -1028,6 +1048,7 @@ exports[`renders ./components/input/demo/search-input.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg

View File

@ -29,32 +29,38 @@ exports[`Input allowClear should change type when click 1`] = `
theme="filled"
type="close-circle"
>
<i
className="anticon anticon-close-circle ant-input-clear-icon"
onClick={[Function]}
role="button"
<LocaleReceiver
componentName="Icon"
>
<IconReact
className=""
type="close-circle-fill"
<i
aria-label="icon: close-circle"
className="anticon anticon-close-circle ant-input-clear-icon"
onClick={[Function]}
role="button"
tabIndex={-1}
>
<svg
aria-hidden="true"
<IconReact
className=""
data-icon="close-circle"
fill="currentColor"
height="1em"
key="svg-close-circle"
viewBox="64 64 896 896"
width="1em"
type="close-circle-fill"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
key="svg-close-circle-svg-0"
/>
</svg>
</IconReact>
</i>
<svg
aria-hidden="true"
className=""
data-icon="close-circle"
fill="currentColor"
height="1em"
key="svg-close-circle"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
key="svg-close-circle-svg-0"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>
@ -153,31 +159,37 @@ exports[`Input.Password should change type when click 1`] = `
onClick={[Function]}
type="eye"
>
<i
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
<LocaleReceiver
componentName="Icon"
>
<IconReact
className=""
type="eye-o"
<i
aria-label="icon: eye"
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
tabIndex={-1}
>
<svg
aria-hidden="true"
<IconReact
className=""
data-icon="eye"
fill="currentColor"
height="1em"
key="svg-eye"
viewBox="64 64 896 896"
width="1em"
type="eye-o"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
key="svg-eye-svg-0"
/>
</svg>
</IconReact>
</i>
<svg
aria-hidden="true"
className=""
data-icon="eye"
fill="currentColor"
height="1em"
key="svg-eye"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
key="svg-eye-svg-0"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>
@ -230,35 +242,41 @@ exports[`Input.Password should change type when click 2`] = `
onClick={[Function]}
type="eye-invisible"
>
<i
className="anticon anticon-eye-invisible ant-input-password-icon"
onClick={[Function]}
<LocaleReceiver
componentName="Icon"
>
<IconReact
className=""
type="eye-invisible-o"
<i
aria-label="icon: eye-invisible"
className="anticon anticon-eye-invisible ant-input-password-icon"
onClick={[Function]}
tabIndex={-1}
>
<svg
aria-hidden="true"
<IconReact
className=""
data-icon="eye-invisible"
fill="currentColor"
height="1em"
key="svg-eye-invisible"
viewBox="64 64 896 896"
width="1em"
type="eye-invisible-o"
>
<path
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 0 0 0-51.5zm-63.57-320.64L836 122.88a8 8 0 0 0-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 0 0 0 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 0 0 0 11.31L155.17 889a8 8 0 0 0 11.31 0l712.15-712.12a8 8 0 0 0 0-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 0 0-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 0 1 146.2-106.69L401.31 546.2A112 112 0 0 1 396 512z"
key="svg-eye-invisible-svg-0"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 0 0 227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 0 1-112 112z"
key="svg-eye-invisible-svg-1"
/>
</svg>
</IconReact>
</i>
<svg
aria-hidden="true"
className=""
data-icon="eye-invisible"
fill="currentColor"
height="1em"
key="svg-eye-invisible"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 0 0 0-51.5zm-63.57-320.64L836 122.88a8 8 0 0 0-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 0 0 0 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 0 0 0 11.31L155.17 889a8 8 0 0 0 11.31 0l712.15-712.12a8 8 0 0 0 0-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 0 0-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 0 1 146.2-106.69L401.31 546.2A112 112 0 0 1 396 512z"
key="svg-eye-invisible-svg-0"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 0 0 227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 0 1-112 112z"
key="svg-eye-invisible-svg-1"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>
@ -311,31 +329,37 @@ exports[`Input.Password should change type when click 3`] = `
onClick={[Function]}
type="eye"
>
<i
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
<LocaleReceiver
componentName="Icon"
>
<IconReact
className=""
type="eye-o"
<i
aria-label="icon: eye"
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
tabIndex={-1}
>
<svg
aria-hidden="true"
<IconReact
className=""
data-icon="eye"
fill="currentColor"
height="1em"
key="svg-eye"
viewBox="64 64 896 896"
width="1em"
type="eye-o"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
key="svg-eye-svg-0"
/>
</svg>
</IconReact>
</i>
<svg
aria-hidden="true"
className=""
data-icon="eye"
fill="currentColor"
height="1em"
key="svg-eye"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 0 0 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
key="svg-eye-svg-0"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>
@ -391,31 +415,37 @@ exports[`Input.Search should support suffix 1`] = `
onClick={[Function]}
type="search"
>
<i
className="anticon anticon-search ant-input-search-icon"
onClick={[Function]}
<LocaleReceiver
componentName="Icon"
>
<IconReact
className=""
type="search-o"
<i
aria-label="icon: search"
className="anticon anticon-search ant-input-search-icon"
onClick={[Function]}
tabIndex={-1}
>
<svg
aria-hidden="true"
<IconReact
className=""
data-icon="search"
fill="currentColor"
height="1em"
key="svg-search"
viewBox="64 64 896 896"
width="1em"
type="search-o"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
key="svg-search-svg-0"
/>
</svg>
</IconReact>
</i>
<svg
aria-hidden="true"
className=""
data-icon="search"
fill="currentColor"
height="1em"
key="svg-search"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
key="svg-search-svg-0"
/>
</svg>
</IconReact>
</i>
</LocaleReceiver>
</Icon>
</span>
</span>

View File

@ -147,6 +147,7 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -173,6 +174,7 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: video-camera"
class="anticon anticon-video-camera"
>
<svg
@ -199,6 +201,7 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: upload"
class="anticon anticon-upload"
>
<svg
@ -230,7 +233,9 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
style="background:#fff;padding:0"
>
<i
aria-label="icon: menu-fold"
class="anticon anticon-menu-fold trigger"
tabindex="-1"
>
<svg
aria-hidden="true"
@ -449,6 +454,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -477,6 +483,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: video-camera"
class="anticon anticon-video-camera"
>
<svg
@ -505,6 +512,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: upload"
class="anticon anticon-upload"
>
<svg
@ -533,6 +541,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: bar-chart"
class="anticon anticon-bar-chart"
>
<svg
@ -561,6 +570,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: cloud-o"
class="anticon anticon-cloud-o"
>
<svg
@ -589,6 +599,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: appstore-o"
class="anticon anticon-appstore-o"
>
<svg
@ -617,6 +628,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: team"
class="anticon anticon-team"
>
<svg
@ -645,6 +657,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: shop"
class="anticon anticon-shop"
>
<svg
@ -816,6 +829,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -844,6 +858,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: video-camera"
class="anticon anticon-video-camera"
>
<svg
@ -872,6 +887,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: upload"
class="anticon anticon-upload"
>
<svg
@ -900,6 +916,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -977,6 +994,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: pie-chart"
class="anticon anticon-pie-chart"
>
<svg
@ -1003,6 +1021,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: desktop"
class="anticon anticon-desktop"
>
<svg
@ -1035,6 +1054,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
>
<span>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -1073,6 +1093,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
>
<span>
<i
aria-label="icon: team"
class="anticon anticon-team"
>
<svg
@ -1105,6 +1126,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: file"
class="anticon anticon-file"
>
<svg
@ -1132,6 +1154,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
style="width:200px"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1554,6 +1577,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
>
<span>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -1623,6 +1647,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
>
<span>
<i
aria-label="icon: laptop"
class="anticon anticon-laptop"
>
<svg
@ -1659,6 +1684,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
>
<span>
<i
aria-label="icon: notification"
class="anticon anticon-notification"
>
<svg
@ -1838,6 +1864,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
>
<span>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
@ -1907,6 +1934,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
>
<span>
<i
aria-label="icon: laptop"
class="anticon anticon-laptop"
>
<svg
@ -1943,6 +1971,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
>
<span>
<i
aria-label="icon: notification"
class="anticon anticon-notification"
>
<svg

View File

@ -937,6 +937,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: star-o"
class="anticon anticon-star-o"
style="margin-right:8px"
>
@ -963,6 +964,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: like-o"
class="anticon anticon-like-o"
style="margin-right:8px"
>
@ -989,6 +991,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: message"
class="anticon anticon-message"
style="margin-right:8px"
>
@ -1075,6 +1078,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: star-o"
class="anticon anticon-star-o"
style="margin-right:8px"
>
@ -1101,6 +1105,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: like-o"
class="anticon anticon-like-o"
style="margin-right:8px"
>
@ -1127,6 +1132,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: message"
class="anticon anticon-message"
style="margin-right:8px"
>
@ -1213,6 +1219,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: star-o"
class="anticon anticon-star-o"
style="margin-right:8px"
>
@ -1239,6 +1246,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: like-o"
class="anticon anticon-like-o"
style="margin-right:8px"
>
@ -1265,6 +1273,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
<li>
<span>
<i
aria-label="icon: message"
class="anticon anticon-message"
style="margin-right:8px"
>
@ -1326,6 +1335,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1426,6 +1436,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg

View File

@ -46,6 +46,7 @@ exports[`List.pagination renders pagination correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -92,6 +93,7 @@ exports[`List.pagination renders pagination correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg

View File

@ -108,6 +108,14 @@
}
}
&-header {
background: @list-header-background;
}
&-footer {
background: @list-footer-background;
}
&-header,
&-footer {
padding-top: 12px;

View File

@ -72,6 +72,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -145,6 +146,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -196,6 +198,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -264,6 +267,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -294,6 +298,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -326,6 +331,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-time-picker-icon"
>
<i
aria-label="icon: clock-circle"
class="anticon anticon-clock-circle ant-time-picker-clock-icon"
>
<svg
@ -375,6 +381,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
value=""
/>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar ant-calendar-picker-icon"
>
<svg
@ -482,6 +489,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -533,6 +541,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -556,6 +565,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -623,6 +633,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
@ -706,6 +717,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -755,6 +767,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -1747,7 +1760,9 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
Name
</div>
<i
aria-label="icon: filter"
class="anticon anticon-filter ant-dropdown-trigger"
tabindex="-1"
title="Filter menu"
>
<svg
@ -1825,6 +1840,7 @@ exports[`renders ./components/locale-provider/demo/basic.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="图标: left"
class="anticon anticon-left"
>
<svg
@ -1898,6 +1914,7 @@ exports[`renders ./components/locale-provider/demo/basic.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="图标: right"
class="anticon anticon-right"
>
<svg
@ -1949,6 +1966,7 @@ exports[`renders ./components/locale-provider/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="图标: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg

View File

@ -44,4 +44,7 @@ export default {
Empty: {
description: 'No Data',
},
Icon: {
icon: 'icon',
},
};

View File

@ -44,4 +44,7 @@ export default {
Empty: {
description: '暂无数据',
},
Icon: {
icon: '图标',
},
};

View File

@ -28,6 +28,7 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
role="menuitem"
>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -70,6 +71,7 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
role="menuitem"
>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -119,6 +121,7 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
class="submenu-title-wrapper"
>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -212,6 +215,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
>
<span>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -311,6 +315,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
>
<span>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -349,6 +354,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -388,6 +394,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: menu-fold"
class="anticon anticon-menu-fold"
>
<svg
@ -415,6 +422,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: pie-chart"
class="anticon anticon-pie-chart"
>
<svg
@ -441,6 +449,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: desktop"
class="anticon anticon-desktop"
>
<svg
@ -467,6 +476,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: inbox"
class="anticon anticon-inbox"
>
<svg
@ -500,6 +510,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
>
<span>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -571,6 +582,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
>
<span>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -620,6 +632,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
>
<span>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -691,6 +704,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
>
<span>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -729,6 +743,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -799,6 +814,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -823,6 +839,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
style="padding-left:24px"
>
<i
aria-label="icon: calendar"
class="anticon anticon-calendar"
>
<svg
@ -854,6 +871,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
>
<span>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -929,6 +947,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -994,6 +1013,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
>
<span>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -1065,6 +1085,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
>
<span>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -1103,6 +1124,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg
@ -1150,6 +1172,7 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
>
<span>
<i
aria-label="icon: mail"
class="anticon anticon-mail"
>
<svg
@ -1186,6 +1209,7 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
>
<span>
<i
aria-label="icon: appstore"
class="anticon anticon-appstore"
>
<svg
@ -1222,6 +1246,7 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
>
<span>
<i
aria-label="icon: setting"
class="anticon anticon-setting"
>
<svg

View File

@ -81,6 +81,7 @@ export interface ModalFuncProps {
icon?: React.ReactNode;
/* Deperated */
iconType?: string;
mask?: boolean;
maskClosable?: boolean;
zIndex?: number;
okCancel?: boolean;
@ -90,6 +91,8 @@ export interface ModalFuncProps {
keyboard?: boolean;
getContainer?: (instance: React.ReactInstance) => HTMLElement;
autoFocusButton?: null | 'ok' | 'cancel';
transitionName?: string;
maskTransitionName?: string;
}
export type ModalFunc = (

View File

@ -34,6 +34,7 @@ exports[`Modal render correctly 1`] = `
class="ant-modal-close-x"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-modal-close-icon"
>
<svg
@ -126,6 +127,7 @@ exports[`Modal render without footer 1`] = `
class="ant-modal-close-x"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-modal-close-icon"
>
<svg

View File

@ -168,4 +168,9 @@ describe('Modal.confirm triggers callbacks correctly', () => {
expect($$('.custom-modal-confirm')).toHaveLength(1);
expect($$('.custom-modal-confirm-body-wrapper')).toHaveLength(1);
});
it('should be Modal.confirm without mask', () => {
open({ mask: false });
expect($$('.ant-modal-mask')).toHaveLength(0);
});
});

View File

@ -43,12 +43,15 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
const okCancel = 'okCancel' in props ? props.okCancel! : true;
const width = props.width || 416;
const style = props.style || {};
const mask = props.mask === undefined ? true : props.mask;
// 默认为 false保持旧版默认行为
const maskClosable = props.maskClosable === undefined ? false : props.maskClosable;
const runtimeLocale = getConfirmLocale();
const okText = props.okText || (okCancel ? runtimeLocale.okText : runtimeLocale.justOkText);
const cancelText = props.cancelText || runtimeLocale.cancelText;
const autoFocusButton = props.autoFocusButton === null ? false : props.autoFocusButton || 'ok';
const transitionName = props.transitionName || 'zoom';
const maskTransitionName = props.maskTransitionName || 'fade';
const classString = classNames(
contentPrefixCls,
@ -77,9 +80,10 @@ const ConfirmDialog = (props: ConfirmDialogProps) => {
onCancel={close.bind(this, { triggerCancel: true })}
visible={visible}
title=""
transitionName="zoom"
transitionName={transitionName}
footer=""
maskTransitionName="fade"
maskTransitionName={maskTransitionName}
mask={mask}
maskClosable={maskClosable}
maskStyle={maskStyle}
style={style}

View File

@ -71,6 +71,7 @@ The properties of the object are follows:
| icon | custom icon (`Added in 3.12.0`) | string\|ReactNode | `<Icon type="question-circle">` |
| iconType | Icon `type` of the Icon component (deperated after `3.12.0`) | string | `question-circle` |
| keyboard | Whether support press esc to close | Boolean | true |
| mask | Whether show mask or not. | Boolean | true |
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | Boolean | `false` |
| okText | Text of the OK button | string | `OK` |
| okType | Button `type` of the OK button | string | `primary` |

View File

@ -69,6 +69,7 @@ title: Modal
| content | 内容 | string\|ReactNode | 无 |
| icon | 自定义图标3.12.0 新增) | string\|ReactNode | `<Icon type="question-circle">` |
| iconType | 图标类型3.12.0 后废弃,请使用 `icon` | string | `question-circle` |
| mask | 是否展示遮罩 | Boolean | true |
| maskClosable | 点击蒙层是否允许关闭 | Boolean | `false` |
| okText | 确认按钮文字 | string | 确定 |
| okType | 确认按钮类型 | string | primary |

View File

@ -77,6 +77,7 @@ exports[`renders ./components/notification/demo/placement.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg

View File

@ -14,6 +14,7 @@ exports[`renders ./components/pagination/demo/basic.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -87,6 +88,7 @@ exports[`renders ./components/pagination/demo/basic.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -123,6 +125,7 @@ exports[`renders ./components/pagination/demo/changer.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -198,6 +201,7 @@ exports[`renders ./components/pagination/demo/changer.md correctly 1`] = `
class="ant-pagination-item-container"
>
<i
aria-label="icon: double-right"
class="anticon anticon-double-right ant-pagination-item-link-icon"
>
<svg
@ -241,6 +245,7 @@ exports[`renders ./components/pagination/demo/changer.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -292,6 +297,7 @@ exports[`renders ./components/pagination/demo/changer.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -330,6 +336,7 @@ exports[`renders ./components/pagination/demo/controlled.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -403,6 +410,7 @@ exports[`renders ./components/pagination/demo/controlled.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -495,6 +503,7 @@ exports[`renders ./components/pagination/demo/itemRender.md correctly 1`] = `
class="ant-pagination-item-container"
>
<i
aria-label="icon: double-right"
class="anticon anticon-double-right ant-pagination-item-link-icon"
>
<svg
@ -556,6 +565,7 @@ exports[`renders ./components/pagination/demo/jump.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -631,6 +641,7 @@ exports[`renders ./components/pagination/demo/jump.md correctly 1`] = `
class="ant-pagination-item-container"
>
<i
aria-label="icon: double-right"
class="anticon anticon-double-right ant-pagination-item-link-icon"
>
<svg
@ -674,6 +685,7 @@ exports[`renders ./components/pagination/demo/jump.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -723,6 +735,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -796,6 +809,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -828,6 +842,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -901,6 +916,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -952,6 +968,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -1000,6 +1017,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1073,6 +1091,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -1110,6 +1129,7 @@ exports[`renders ./components/pagination/demo/more.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1149,6 +1169,7 @@ exports[`renders ./components/pagination/demo/more.md correctly 1`] = `
class="ant-pagination-item-container"
>
<i
aria-label="icon: double-left"
class="anticon anticon-double-left ant-pagination-item-link-icon"
>
<svg
@ -1230,6 +1251,7 @@ exports[`renders ./components/pagination/demo/more.md correctly 1`] = `
class="ant-pagination-item-container"
>
<i
aria-label="icon: double-right"
class="anticon anticon-double-right ant-pagination-item-link-icon"
>
<svg
@ -1273,6 +1295,7 @@ exports[`renders ./components/pagination/demo/more.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -1308,6 +1331,7 @@ exports[`renders ./components/pagination/demo/simple.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1352,6 +1376,7 @@ exports[`renders ./components/pagination/demo/simple.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -1393,6 +1418,7 @@ exports[`renders ./components/pagination/demo/total.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1466,6 +1492,7 @@ exports[`renders ./components/pagination/demo/total.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
@ -1504,6 +1531,7 @@ exports[`renders ./components/pagination/demo/total.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
@ -1577,6 +1605,7 @@ exports[`renders ./components/pagination/demo/total.md correctly 1`] = `
class="ant-pagination-item-link"
>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg

View File

@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Popconfirm should show overlay when trigger is clicked 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><i class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z\\"></path></svg></i><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div></div>"`;
exports[`Popconfirm should show overlay when trigger is clicked 1`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><i aria-label=\\"icon: exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z\\"></path></svg></i><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div></div>"`;
exports[`Popconfirm should show overlay when trigger is clicked 2`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><i class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z\\"></path></svg></i><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div></div>"`;
exports[`Popconfirm should show overlay when trigger is clicked 2`] = `"<div class=\\"ant-popover-content\\"><div class=\\"ant-popover-arrow\\"></div><div class=\\"ant-popover-inner\\" role=\\"tooltip\\"><div><div class=\\"ant-popover-inner-content\\"><div class=\\"ant-popover-message\\"><i aria-label=\\"icon: exclamation-circle\\" class=\\"anticon anticon-exclamation-circle\\"><svg viewBox=\\"64 64 896 896\\" class=\\"\\" data-icon=\\"exclamation-circle\\" width=\\"1em\\" height=\\"1em\\" fill=\\"currentColor\\" aria-hidden=\\"true\\"><path d=\\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z\\"></path></svg></i><div class=\\"ant-popover-message-title\\">code</div></div><div class=\\"ant-popover-buttons\\"><button type=\\"button\\" class=\\"ant-btn ant-btn-sm\\"><span>Cancel</span></button><button type=\\"button\\" class=\\"ant-btn ant-btn-primary ant-btn-sm\\"><span>OK</span></button></div></div></div></div></div>"`;

View File

@ -0,0 +1,72 @@
import * as React from 'react';
import { Circle as RCCircle } from 'rc-progress';
import { validProgress } from './utils';
import { ProgressProps } from './progress';
interface CircleProps extends ProgressProps {
prefixCls: string;
children: React.ReactNode;
progressStatus: string;
}
const statusColorMap: Record<string, string> = {
normal: '#108ee9',
exception: '#ff5500',
success: '#87d068',
};
function getPercentage({ percent, successPercent }: CircleProps) {
const ptg = validProgress(percent);
if (!successPercent) return ptg;
const successPtg = validProgress(successPercent);
return [successPercent, validProgress(ptg - successPtg)];
}
function getStrokeColor({ progressStatus, successPercent, strokeColor }: CircleProps) {
const color = strokeColor || statusColorMap[progressStatus];
if (!successPercent) return color;
return [statusColorMap.success, color];
}
const Circle: React.SFC<CircleProps> = props => {
const {
prefixCls,
width,
strokeWidth,
trailColor,
strokeLinecap,
gapPosition,
gapDegree,
type,
children,
} = props;
const circleSize = width || 120;
const circleStyle = {
width: circleSize,
height: circleSize,
fontSize: circleSize * 0.15 + 6,
};
const circleWidth = strokeWidth || 6;
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top';
const gapDeg = gapDegree || (type === 'dashboard' && 75);
return (
<div className={`${prefixCls}-inner`} style={circleStyle}>
<RCCircle
percent={getPercentage(props)}
strokeWidth={circleWidth}
trailWidth={circleWidth}
strokeColor={getStrokeColor(props)}
strokeLinecap={strokeLinecap}
trailColor={trailColor}
prefixCls={prefixCls}
gapDegree={gapDeg}
gapPosition={gapPos}
/>
{children}
</div>
);
};
export default Circle;

View File

@ -0,0 +1,49 @@
import * as React from 'react';
import { validProgress } from './utils';
import { ProgressProps } from './progress';
interface LineProps extends ProgressProps {
prefixCls: string;
children: React.ReactNode;
}
const Line: React.SFC<LineProps> = props => {
const {
prefixCls,
percent,
successPercent,
strokeWidth,
size,
strokeColor,
strokeLinecap,
children,
} = props;
const percentStyle = {
width: `${validProgress(percent)}%`,
height: strokeWidth || (size === 'small' ? 6 : 8),
background: strokeColor,
borderRadius: strokeLinecap === 'square' ? 0 : '100px',
};
const successPercentStyle = {
width: `${validProgress(successPercent)}%`,
height: strokeWidth || (size === 'small' ? 6 : 8),
borderRadius: strokeLinecap === 'square' ? 0 : '100px',
};
const successSegment =
successPercent !== undefined ? (
<div className={`${prefixCls}-success-bg`} style={successPercentStyle} />
) : null;
return (
<div>
<div className={`${prefixCls}-outer`}>
<div className={`${prefixCls}-inner`}>
<div className={`${prefixCls}-bg`} style={percentStyle} />
{successSegment}
</div>
</div>
{children}
</div>
);
};
export default Line;

View File

@ -22,7 +22,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -63,7 +63,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -80,6 +80,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -119,7 +120,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -136,6 +137,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: check"
class="anticon anticon-check"
>
<svg
@ -180,7 +182,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -209,6 +211,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: minus"
class="anticon anticon-minus"
>
<svg
@ -231,6 +234,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: plus"
class="anticon anticon-plus"
>
<svg
@ -274,7 +278,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -315,7 +319,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -332,6 +336,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: close"
class="anticon anticon-close"
>
<svg
@ -371,7 +376,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -388,6 +393,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: check"
class="anticon anticon-check"
>
<svg
@ -431,7 +437,7 @@ exports[`renders ./components/progress/demo/dashboard.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -488,6 +494,7 @@ exports[`renders ./components/progress/demo/dynamic.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: minus"
class="anticon anticon-minus"
>
<svg
@ -510,6 +517,7 @@ exports[`renders ./components/progress/demo/dynamic.md correctly 1`] = `
type="button"
>
<i
aria-label="icon: plus"
class="anticon anticon-plus"
>
<svg
@ -553,7 +561,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -594,7 +602,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -688,6 +696,7 @@ exports[`renders ./components/progress/demo/line.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle"
>
<svg
@ -727,6 +736,7 @@ exports[`renders ./components/progress/demo/line.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -839,6 +849,7 @@ exports[`renders ./components/progress/demo/line-mini.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: close-circle"
class="anticon anticon-close-circle"
>
<svg
@ -878,6 +889,7 @@ exports[`renders ./components/progress/demo/line-mini.md correctly 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -946,7 +958,7 @@ exports[`renders ./components/progress/demo/linecap.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="square"
stroke-width="6"
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -987,7 +999,7 @@ exports[`renders ./components/progress/demo/linecap.md correctly 1`] = `
stroke="#f3f3f3"
stroke-linecap="square"
stroke-width="6"
style="stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s"
style="stroke:#f3f3f3;stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
@ -1012,32 +1024,136 @@ exports[`renders ./components/progress/demo/linecap.md correctly 1`] = `
`;
exports[`renders ./components/progress/demo/segment.md correctly 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div>
<div
class="ant-progress-outer"
>
<div>
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div>
<div
class="ant-progress-inner"
class="ant-progress-outer"
>
<div
class="ant-progress-bg"
style="width:60%;height:8px;border-radius:100px"
/>
<div
class="ant-progress-success-bg"
style="width:30%;height:8px;border-radius:100px"
/>
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
style="width:60%;height:8px;border-radius:100px"
/>
<div
class="ant-progress-success-bg"
style="width:30%;height:8px;border-radius:100px"
/>
</div>
</div>
<span
class="ant-progress-text"
title="60%"
>
60%
</span>
</div>
<span
class="ant-progress-text"
title="60%"
</div>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div
class="ant-progress-inner"
style="width:120px;height:120px;font-size:24px"
>
60%
</span>
<svg
class="ant-progress-circle "
viewBox="0 0 100 100"
>
<path
class="ant-progress-circle-trail"
d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94"
fill-opacity="0"
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke:#f3f3f3;stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94"
fill-opacity="0"
stroke-linecap="round"
stroke-width="6"
style="stroke:#87d068;stroke-dasharray:88.59291283123217px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94"
fill-opacity="0"
stroke-linecap="round"
stroke-width="6"
style="stroke:#108ee9;stroke-dasharray:88.59291283123217px 295.3097094374406px;stroke-dashoffset:-88.59291283123217px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
</svg>
<span
class="ant-progress-text"
title="60%"
>
60%
</span>
</div>
</div>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div
class="ant-progress-inner"
style="width:120px;height:120px;font-size:24px"
>
<svg
class="ant-progress-circle "
viewBox="0 0 100 100"
>
<path
class="ant-progress-circle-trail"
d="M 50,50 m 0,47
a 47,47 0 1 1 0,-94
a 47,47 0 1 1 0,94"
fill-opacity="0"
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke:#f3f3f3;stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
d="M 50,50 m 0,47
a 47,47 0 1 1 0,-94
a 47,47 0 1 1 0,94"
fill-opacity="0"
stroke-linecap="round"
stroke-width="6"
style="stroke:#87d068;stroke-dasharray:66.09291283123217px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
<path
class="ant-progress-circle-path"
d="M 50,50 m 0,47
a 47,47 0 1 1 0,-94
a 47,47 0 1 1 0,94"
fill-opacity="0"
stroke-linecap="round"
stroke-width="6"
style="stroke:#108ee9;stroke-dasharray:66.09291283123217px 295.3097094374406px;stroke-dashoffset:-103.59291283123217px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s"
/>
</svg>
<span
class="ant-progress-text"
title="60%"
>
60%
</span>
</div>
</div>
</div>
`;

View File

@ -137,6 +137,7 @@ exports[`Progress render out-of-range progress 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -179,6 +180,7 @@ exports[`Progress render out-of-range progress with info 1`] = `
class="ant-progress-text"
>
<i
aria-label="icon: check-circle"
class="anticon anticon-check-circle"
>
<svg
@ -221,7 +223,7 @@ exports[`Progress render strokeColor 1`] = `
stroke="#f3f3f3"
stroke-linecap="round"
stroke-width="6"
style="stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px;"
style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px;"
/>
<path
class="ant-progress-circle-path"

View File

@ -17,9 +17,19 @@ A standard progress bar.
import { Tooltip, Progress } from 'antd';
ReactDOM.render(
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} successPercent={30} />
</Tooltip>,
<div>
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} successPercent={30} />
</Tooltip>
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} successPercent={30} type="circle" />
</Tooltip>
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} successPercent={30} type="dashboard" />
</Tooltip>
</div>,
mountNode
);
````

View File

@ -27,6 +27,6 @@ If it will take a long time to complete an operation, you can use `Progress` to
| strokeWidth `(type=circle)` | to set the width of the circular progress bar, unit: percentage of the canvas width | number | 6 |
| strokeLinecap | to set the style of the progress linecap | Enum{ 'round', 'square' } | `round` |
| strokeColor | color of progress bar | string | - |
| successPercent | segmented success percent, works when `type="line"` | number | 0 |
| successPercent | segmented success percent | number | 0 |
| type | to set the type, options: `line` `circle` `dashboard` | string | `line` |
| width `(type=circle)` | to set the canvas width of the circular progress bar, unit: `px` | number | 132 |

View File

@ -28,6 +28,6 @@ title: Progress
| strokeWidth `(type=circle)` | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 |
| strokeLinecap | | Enum{ 'round', 'square' } | `round` |
| strokeColor | 进度条的色彩 | string | - |
| successPercent | 已完成的分段百分比`type="line"` 时有效 | number | 0 |
| successPercent | 已完成的分段百分比 | number | 0 |
| type | 类型,可选 `line` `circle` `dashboard` | string | line |
| width `(type=circle)` | 圆形进度条画布宽度,单位 px | number | 132 |

View File

@ -1,16 +1,12 @@
import * as PropTypes from 'prop-types';
import * as React from 'react';
import Icon from '../icon';
import { Circle } from 'rc-progress';
import classNames from 'classnames';
import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { tuple } from '../_util/type';
const statusColorMap: Record<string, string> = {
normal: '#108ee9',
exception: '#ff5500',
success: '#87d068',
};
import Line from './Line';
import Circle from './Circle';
import { validProgress } from './utils';
const ProgressTypes = tuple('line', 'circle', 'dashboard');
export type ProgressType = (typeof ProgressTypes)[number];
@ -37,22 +33,15 @@ export interface ProgressProps {
size?: ProgressSize;
}
const validProgress = (progress: number | undefined) => {
if (!progress || progress < 0) {
return 0;
} else if (progress > 100) {
return 100;
}
return progress;
};
export default class Progress extends React.Component<ProgressProps, {}> {
static defaultProps = {
type: 'line' as ProgressProps['type'],
type: 'line',
percent: 0,
showInfo: true,
trailColor: '#f3f3f3',
size: 'default' as ProgressSize,
size: 'default',
gapDegree: 0,
strokeLinecap: 'round',
};
static propTypes = {
@ -70,6 +59,27 @@ export default class Progress extends React.Component<ProgressProps, {}> {
default: PropTypes.oneOf(['default', 'small']),
};
renderProcessInfo(prefixCls: string, progressStatus: (typeof ProgressStatuses)[number]) {
const { showInfo, format, type, percent, successPercent } = this.props;
if (!showInfo) return null;
let text;
const textFormatter = format || (percentNumber => `${percentNumber}%`);
const iconType = type === 'circle' || type === 'dashboard' ? '' : '-circle';
if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) {
text = textFormatter(validProgress(percent), validProgress(successPercent));
} else if (progressStatus === 'exception') {
text = <Icon type={`close${iconType}`} theme={type === 'line' ? 'filled' : 'outlined'} />;
} else if (progressStatus === 'success') {
text = <Icon type={`check${iconType}`} theme={type === 'line' ? 'filled' : 'outlined'} />;
}
return (
<span className={`${prefixCls}-text`} title={typeof text === 'string' ? text : undefined}>
{text}
</span>
);
}
renderProgress = ({ getPrefixCls }: ConfigConsumerProps) => {
const props = this.props;
const {
@ -97,79 +107,22 @@ export default class Progress extends React.Component<ProgressProps, {}> {
!('status' in props)
? 'success'
: status || 'normal';
let progressInfo;
let progress;
const textFormatter = format || (percentNumber => `${percentNumber}%`);
if (showInfo) {
let text;
const iconType = type === 'circle' || type === 'dashboard' ? '' : '-circle';
if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) {
text = textFormatter(validProgress(percent), validProgress(successPercent));
} else if (progressStatus === 'exception') {
text = <Icon type={`close${iconType}`} theme={type === 'line' ? 'filled' : 'outlined'} />;
} else if (progressStatus === 'success') {
text = <Icon type={`check${iconType}`} theme={type === 'line' ? 'filled' : 'outlined'} />;
}
progressInfo = (
<span className={`${prefixCls}-text`} title={typeof text === 'string' ? text : undefined}>
{text}
</span>
);
}
const progressInfo = this.renderProcessInfo(prefixCls, progressStatus);
// Render progress shape
if (type === 'line') {
const percentStyle = {
width: `${validProgress(percent)}%`,
height: strokeWidth || (size === 'small' ? 6 : 8),
background: strokeColor,
borderRadius: strokeLinecap === 'square' ? 0 : '100px',
};
const successPercentStyle = {
width: `${validProgress(successPercent)}%`,
height: strokeWidth || (size === 'small' ? 6 : 8),
borderRadius: strokeLinecap === 'square' ? 0 : '100px',
};
const successSegment =
successPercent !== undefined ? (
<div className={`${prefixCls}-success-bg`} style={successPercentStyle} />
) : null;
progress = (
<div>
<div className={`${prefixCls}-outer`}>
<div className={`${prefixCls}-inner`}>
<div className={`${prefixCls}-bg`} style={percentStyle} />
{successSegment}
</div>
</div>
<Line {...this.props} prefixCls={prefixCls}>
{progressInfo}
</div>
</Line>
);
} else if (type === 'circle' || type === 'dashboard') {
const circleSize = width || 120;
const circleStyle = {
width: circleSize,
height: circleSize,
fontSize: circleSize * 0.15 + 6,
};
const circleWidth = strokeWidth || 6;
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top';
const gapDeg = gapDegree || (type === 'dashboard' && 75);
progress = (
<div className={`${prefixCls}-inner`} style={circleStyle}>
<Circle
percent={validProgress(percent)}
strokeWidth={circleWidth}
trailWidth={circleWidth}
strokeColor={strokeColor || statusColorMap[progressStatus]}
strokeLinecap={strokeLinecap}
trailColor={trailColor}
prefixCls={prefixCls}
gapDegree={gapDeg}
gapPosition={gapPos}
/>
<Circle {...this.props} prefixCls={prefixCls} progressStatus={progressStatus}>
{progressInfo}
</div>
</Circle>
);
}

View File

@ -0,0 +1,8 @@
export function validProgress(progress: number | undefined) {
if (!progress || progress < 0) {
return 0;
} else if (progress > 100) {
return 100;
}
return progress;
};

View File

@ -20,6 +20,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -41,6 +42,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -74,6 +76,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -95,6 +98,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -128,6 +132,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -149,6 +154,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -182,6 +188,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -203,6 +210,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -236,6 +244,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -257,6 +266,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -300,6 +310,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -321,6 +332,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -354,6 +366,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -375,6 +388,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -408,6 +422,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -429,6 +444,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -462,6 +478,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -483,6 +500,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -516,6 +534,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -537,6 +556,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: heart"
class="anticon anticon-heart"
>
<svg
@ -816,6 +836,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -837,6 +858,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -870,6 +892,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -891,6 +914,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -924,6 +948,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -945,6 +970,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -978,6 +1004,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -999,6 +1026,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1032,6 +1060,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1053,6 +1082,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1094,6 +1124,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1115,6 +1146,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1148,6 +1180,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1169,6 +1202,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1202,6 +1236,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1223,6 +1258,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1256,6 +1292,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1277,6 +1314,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1310,6 +1348,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1331,6 +1370,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1375,6 +1415,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1396,6 +1437,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1429,6 +1471,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1450,6 +1493,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1483,6 +1527,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1504,6 +1549,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1537,6 +1583,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1558,6 +1605,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1591,6 +1639,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1612,6 +1661,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1654,6 +1704,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1675,6 +1726,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1708,6 +1760,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1729,6 +1782,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1762,6 +1816,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1783,6 +1838,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1816,6 +1872,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1837,6 +1894,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1870,6 +1928,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1891,6 +1950,7 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1934,6 +1994,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1955,6 +2016,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -1988,6 +2050,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2009,6 +2072,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2042,6 +2106,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2063,6 +2128,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2096,6 +2162,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2117,6 +2184,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2150,6 +2218,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-first"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg
@ -2171,6 +2240,7 @@ exports[`renders ./components/rate/demo/text.md correctly 1`] = `
class="ant-rate-star-second"
>
<i
aria-label="icon: star"
class="anticon anticon-star"
>
<svg

View File

@ -75,6 +75,7 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -125,6 +126,7 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -175,6 +177,7 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
@ -230,6 +233,7 @@ exports[`renders ./components/select/demo/coordinate.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -280,6 +284,7 @@ exports[`renders ./components/select/demo/coordinate.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -334,6 +339,7 @@ exports[`renders ./components/select/demo/custom-dropdown-menu.md correctly 1`]
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -436,6 +442,7 @@ exports[`renders ./components/select/demo/label-in-value.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -498,6 +505,7 @@ exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
class="ant-select-selection__choice__remove"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-select-remove-icon"
>
<svg
@ -532,6 +540,7 @@ exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
class="ant-select-selection__choice__remove"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-select-remove-icon"
>
<svg
@ -606,6 +615,7 @@ exports[`renders ./components/select/demo/optgroup.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -678,6 +688,7 @@ exports[`renders ./components/select/demo/search.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -894,6 +905,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg
@ -954,6 +966,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
class="ant-select-selection__choice__remove"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-select-remove-icon"
>
<svg
@ -988,6 +1001,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
class="ant-select-selection__choice__remove"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-select-remove-icon"
>
<svg
@ -1069,6 +1083,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
class="ant-select-selection__choice__remove"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-select-remove-icon"
>
<svg
@ -1103,6 +1118,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
class="ant-select-selection__choice__remove"
>
<i
aria-label="icon: close"
class="anticon anticon-close ant-select-remove-icon"
>
<svg
@ -1179,6 +1195,7 @@ exports[`renders ./components/select/demo/suffix.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: smile"
class="anticon anticon-smile ant-select-arrow-icon"
>
<svg
@ -1229,6 +1246,7 @@ exports[`renders ./components/select/demo/suffix.md correctly 1`] = `
unselectable="on"
>
<i
aria-label="icon: meh"
class="anticon anticon-meh ant-select-arrow-icon"
>
<svg

View File

@ -22,6 +22,7 @@ exports[`Select Select Custom Icons should support customized icons 1`] = `
unselectable="on"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-select-arrow-icon"
>
<svg

View File

@ -77,7 +77,7 @@
background-color: @component-background;
border-radius: @border-radius-base;
border: @border-width-base @border-style-base @border-color-base;
border: @border-width-base @border-style-base @select-border-color;
// strange align fix for chrome but works
// https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif
border-top-width: @border-width-base + 0.02px;
@ -125,7 +125,7 @@
&:hover,
&:focus,
&:active {
border-color: @border-color-base;
border-color: @select-border-color;
box-shadow: none;
}

View File

@ -154,6 +154,7 @@ exports[`renders ./components/slider/demo/icon-slider.md correctly 1`] = `
class="icon-wrapper"
>
<i
aria-label="icon: frown-o"
class="anticon anticon-frown-o"
style="color:rgba(0, 0, 0, .45)"
>
@ -199,6 +200,7 @@ exports[`renders ./components/slider/demo/icon-slider.md correctly 1`] = `
/>
</div>
<i
aria-label="icon: smile-o"
class="anticon anticon-smile-o"
style="color:"
>
@ -273,6 +275,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -298,6 +301,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg
@ -387,6 +391,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: up"
class="anticon anticon-up ant-input-number-handler-up-inner"
>
<svg
@ -412,6 +417,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
unselectable="unselectable"
>
<i
aria-label="icon: down"
class="anticon anticon-down ant-input-number-handler-down-inner"
>
<svg

View File

@ -20,6 +20,7 @@ exports[`renders ./components/spin/demo/custom-indicator.md correctly 1`] = `
class="ant-spin ant-spin-spinning"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading ant-spin-dot"
style="font-size:24px"
>

View File

@ -3,7 +3,7 @@ import { mount } from 'enzyme';
import Spin from '..';
describe('delay spinning', () => {
it('should render with delay when it\'s mounted with spinning=true and delay', () => {
it("should render with delay when it's mounted with spinning=true and delay", () => {
const wrapper = mount(<Spin spinning delay={500} />);
expect(
wrapper

View File

@ -0,0 +1,78 @@
import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import * as moment from 'moment';
import interopDefault from '../_util/interopDefault';
import Statistic, { StatisticProps } from './Statistic';
import { formatCountdown, countdownValueType, FormatConfig } from './utils';
const REFRESH_INTERVAL = 1000 / 30;
interface CountdownProps extends StatisticProps {
value?: countdownValueType;
format?: string;
}
class Countdown extends React.Component<CountdownProps, {}> {
static defaultProps: Partial<CountdownProps> = {
format: 'HH:mm:ss',
};
countdownId?: number = undefined;
componentDidMount() {
this.syncTimer();
}
componentDidUpdate() {
this.syncTimer();
}
componentWillUnmount() {
this.stopTimer();
}
syncTimer = () => {
const { value } = this.props;
const timestamp = interopDefault(moment)(value).valueOf();
if (timestamp >= Date.now()) {
this.startTimer();
} else {
this.stopTimer();
}
};
startTimer = () => {
if (this.countdownId !== undefined) return;
this.countdownId = window.setInterval(() => {
this.forceUpdate();
}, REFRESH_INTERVAL);
};
stopTimer = () => {
clearInterval(this.countdownId);
this.countdownId = undefined;
};
formatCountdown = (value: countdownValueType, config: FormatConfig) => {
const { format } = this.props;
return formatCountdown(value, { ...config, format });
};
// Countdown do not need display the timestamp
valueRender = (node: React.ReactElement<HTMLDivElement>) =>
React.cloneElement(node, {
title: undefined,
});
render() {
return (
<Statistic valueRender={this.valueRender} {...this.props} formatter={this.formatCountdown} />
);
}
}
polyfill(Countdown);
export default Countdown;

View File

@ -0,0 +1,55 @@
import * as React from 'react';
import padEnd from 'lodash/padEnd';
import { valueType, FormatConfig } from './utils';
interface NumberProps extends FormatConfig {
value: valueType;
}
const StatisticNumber: React.SFC<NumberProps> = props => {
const { value, formatter, precision, decimalSeparator, groupSeparator = '', prefixCls } = props;
let valueNode: React.ReactNode;
if (typeof formatter === 'function') {
// Customize formatter
valueNode = formatter(value);
} else {
// Internal formatter
const val: string = String(value);
const cells = val.match(/^(\d*)(\.(\d+))?$/);
// Process if illegal number
if (!cells) {
valueNode = val;
} else {
let int = cells[1] || '0';
let decimal = cells[3] || '';
int = int.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator);
if (typeof precision === 'number') {
decimal = padEnd(decimal, precision, '0').slice(0, precision);
}
if (decimal) {
decimal = `${decimalSeparator}${decimal}`;
}
valueNode = [
<span key="int" className={`${prefixCls}-content-value-int`}>
{int}
</span>,
decimal && (
<span key="decimal" className={`${prefixCls}-content-value-decimal`}>
{decimal}
</span>
),
];
}
}
return <span className={`${prefixCls}-content-value`}>{valueNode}</span>;
};
export default StatisticNumber;

View File

@ -0,0 +1,65 @@
import * as React from 'react';
import classNames from 'classnames';
import { withConfigConsumer, ConfigConsumerProps } from '../config-provider';
import StatisticNumber from './Number';
import Countdown from './Countdown';
import { valueType, FormatConfig } from './utils';
interface StatisticComponent {
Countdown: typeof Countdown;
}
export interface StatisticProps extends FormatConfig {
prefixCls?: string;
className?: string;
style?: React.CSSProperties;
value?: valueType;
valueStyle?: React.CSSProperties;
valueRender?: (node: React.ReactNode) => React.ReactNode;
title?: React.ReactNode;
prefix?: React.ReactNode;
suffix?: React.ReactNode;
}
const Statistic: React.SFC<StatisticProps & ConfigConsumerProps> = props => {
const {
prefixCls,
className,
style,
valueStyle,
value = 0,
title,
valueRender,
prefix,
suffix,
} = props;
let valueNode: React.ReactNode = <StatisticNumber {...props} value={value} />;
if (valueRender) {
valueNode = valueRender(valueNode);
}
return (
<div className={classNames(prefixCls, className)} style={style}>
{title && <div className={`${prefixCls}-title`}>{title}</div>}
<div style={valueStyle} className={`${prefixCls}-content`}>
{prefix && <span className={`${prefixCls}-content-prefix`}>{prefix}</span>}
{valueNode}
{suffix && <span className={`${prefixCls}-content-suffix`}>{suffix}</span>}
</div>
</div>
);
};
Statistic.defaultProps = {
decimalSeparator: '.',
groupSeparator: ',',
};
const WrapperStatistic = withConfigConsumer<StatisticProps>({
prefixCls: 'statistic',
})<StatisticComponent>(Statistic);
export default WrapperStatistic;

View File

@ -0,0 +1,391 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders ./components/statistic/demo/basic.md correctly 1`] = `
<div
class="ant-row"
style="margin-left:-8px;margin-right:-8px"
>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Active Users
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-value"
>
<span
class="ant-statistic-content-value-int"
>
112,893
</span>
</span>
</div>
</div>
</div>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Account Balance (CNY)
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-value"
>
<span
class="ant-statistic-content-value-int"
>
112,893
</span>
<span
class="ant-statistic-content-value-decimal"
>
.00
</span>
</span>
</div>
</div>
<button
class="ant-btn ant-btn-primary"
style="margin-top:16px"
type="button"
>
<span>
Recharge
</span>
</button>
</div>
</div>
`;
exports[`renders ./components/statistic/demo/card.md correctly 1`] = `
<div
style="background:#ECECEC;padding:30px"
>
<div
class="ant-row"
style="margin-left:-8px;margin-right:-8px"
>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-card ant-card-bordered"
>
<div
class="ant-card-body"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Active
</div>
<div
class="ant-statistic-content"
style="color:#3f8600"
>
<span
class="ant-statistic-content-prefix"
>
<i
aria-label="icon: arrow-up"
class="anticon anticon-arrow-up"
>
<svg
aria-hidden="true"
class=""
data-icon="arrow-up"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M868 545.5L536.1 163a31.96 31.96 0 0 0-48.3 0L156 545.5a7.97 7.97 0 0 0 6 13.2h81c4.6 0 9-2 12.1-5.5L474 300.9V864c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V300.9l218.9 252.3c3 3.5 7.4 5.5 12.1 5.5h81c6.8 0 10.5-8 6-13.2z"
/>
</svg>
</i>
</span>
<span
class="ant-statistic-content-value"
>
<span
class="ant-statistic-content-value-int"
>
11
</span>
<span
class="ant-statistic-content-value-decimal"
>
.28
</span>
</span>
<span
class="ant-statistic-content-suffix"
>
%
</span>
</div>
</div>
</div>
</div>
</div>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-card ant-card-bordered"
>
<div
class="ant-card-body"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Idle
</div>
<div
class="ant-statistic-content"
style="color:#cf1322"
>
<span
class="ant-statistic-content-prefix"
>
<i
aria-label="icon: arrow-down"
class="anticon anticon-arrow-down"
>
<svg
aria-hidden="true"
class=""
data-icon="arrow-down"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M862 465.3h-81c-4.6 0-9 2-12.1 5.5L550 723.1V160c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v563.1L255.1 470.8c-3-3.5-7.4-5.5-12.1-5.5h-81c-6.8 0-10.5 8.1-6 13.2L487.9 861a31.96 31.96 0 0 0 48.3 0L868 478.5c4.5-5.2.8-13.2-6-13.2z"
/>
</svg>
</i>
</span>
<span
class="ant-statistic-content-value"
>
<span
class="ant-statistic-content-value-int"
>
9
</span>
<span
class="ant-statistic-content-value-decimal"
>
.30
</span>
</span>
<span
class="ant-statistic-content-suffix"
>
%
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`renders ./components/statistic/demo/countdown.md correctly 1`] = `
<div
class="ant-row"
style="margin-left:-8px;margin-right:-8px"
>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Countdown
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-value"
>
48:00:30
</span>
</div>
</div>
</div>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Million Seconds
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-value"
>
48:00:30:000
</span>
</div>
</div>
</div>
<div
class="ant-col-24"
style="padding-left:8px;padding-right:8px;margin-top:32px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Day Level
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-value"
>
2 天 0 时 0 分 30 秒
</span>
</div>
</div>
</div>
</div>
`;
exports[`renders ./components/statistic/demo/unit.md correctly 1`] = `
<div
class="ant-row"
style="margin-left:-8px;margin-right:-8px"
>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Feedback
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-prefix"
>
<i
aria-label="icon: like"
class="anticon anticon-like"
>
<svg
aria-hidden="true"
class=""
data-icon="like"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M885.9 533.7c16.8-22.2 26.1-49.4 26.1-77.7 0-44.9-25.1-87.4-65.5-111.1a67.67 67.67 0 0 0-34.3-9.3H572.4l6-122.9c1.4-29.7-9.1-57.9-29.5-79.4A106.62 106.62 0 0 0 471 99.9c-52 0-98 35-111.8 85.1l-85.9 311H144c-17.7 0-32 14.3-32 32v364c0 17.7 14.3 32 32 32h601.3c9.2 0 18.2-1.8 26.5-5.4 47.6-20.3 78.3-66.8 78.3-118.4 0-12.6-1.8-25-5.4-37 16.8-22.2 26.1-49.4 26.1-77.7 0-12.6-1.8-25-5.4-37 16.8-22.2 26.1-49.4 26.1-77.7-.2-12.6-2-25.1-5.6-37.1zM184 852V568h81v284h-81zm636.4-353l-21.9 19 13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 16.5-7.2 32.2-19.6 43l-21.9 19 13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 16.5-7.2 32.2-19.6 43l-21.9 19 13.9 25.4a56.2 56.2 0 0 1 6.9 27.3c0 22.4-13.2 42.6-33.6 51.8H329V564.8l99.5-360.5a44.1 44.1 0 0 1 42.2-32.3c7.6 0 15.1 2.2 21.1 6.7 9.9 7.4 15.2 18.6 14.6 30.5l-9.6 198.4h314.4C829 418.5 840 436.9 840 456c0 16.5-7.2 32.1-19.6 43z"
/>
</svg>
</i>
</span>
<span
class="ant-statistic-content-value"
>
<span
class="ant-statistic-content-value-int"
>
1,128
</span>
</span>
</div>
</div>
</div>
<div
class="ant-col-12"
style="padding-left:8px;padding-right:8px"
>
<div
class="ant-statistic"
>
<div
class="ant-statistic-title"
>
Unmerged
</div>
<div
class="ant-statistic-content"
>
<span
class="ant-statistic-content-value"
>
<span
class="ant-statistic-content-value-int"
>
93
</span>
</span>
<span
class="ant-statistic-content-suffix"
>
/ 100
</span>
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,3 @@
import demoTest from '../../../tests/shared/demoTest';
demoTest('statistic');

View File

@ -0,0 +1,70 @@
import React from 'react';
import MockDate from 'mockdate';
import moment from 'moment';
import { mount } from 'enzyme';
import Statistic from '..';
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
describe('Statistic', () => {
beforeAll(() => {
MockDate.set(moment('2018-11-28 00:00:00'));
});
afterAll(() => {
MockDate.reset();
});
it('customize formatter', () => {
const formatter = jest.fn(() => 93);
const wrapper = mount(<Statistic value={1128} formatter={formatter} />);
expect(formatter).toBeCalledWith(1128);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('93');
});
it('groupSeparator', () => {
const wrapper = mount(<Statistic value={1128} groupSeparator="__TEST__" />);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('1__TEST__128');
});
it('not a number', () => {
const wrapper = mount(<Statistic value="bamboo" />);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('bamboo');
});
describe('Countdown', () => {
it('render correctly', () => {
const now = moment()
.add(2, 'd')
.add(11, 'h')
.add(28, 'm')
.add(9, 's')
.add(3, 'ms');
[
['H:m:s', '59:28:9'],
['HH:mm:ss', '59:28:09'],
['HH:mm:ss:SSS', '59:28:09:003'],
['DD-HH:mm:ss', '02-11:28:09'],
].forEach(([format, value]) => {
const wrapper = mount(<Statistic.Countdown format={format} value={now} />);
expect(wrapper.find('.ant-statistic-content-value').text()).toEqual(value);
});
});
it('time going', async () => {
const now = Date.now() + 1000;
const wrapper = mount(<Statistic.Countdown value={now} />);
wrapper.update();
// setInterval should work
const instance = wrapper.instance();
expect(instance.countdownId).not.toBe(undefined);
await delay(50);
wrapper.unmount();
expect(instance.countdownId).toBe(undefined);
});
});
});

Some files were not shown because too many files have changed in this diff Show More