resolve merge conflict

This commit is contained in:
afc163 2020-01-03 12:09:35 +08:00
commit 08f3643272
1110 changed files with 291275 additions and 302356 deletions

View File

@ -1,6 +1,8 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
// eslint-disable-next-line import/no-extraneous-dependencies
const packageInfo = require('./package.json'); const packageInfo = require('./package.json');
const darkVars = require('./scripts/dark-vars');
// We need compile additional content for antd user // We need compile additional content for antd user
function finalizeCompile() { function finalizeCompile() {
@ -57,6 +59,25 @@ function finalizeDist() {
// eslint-disable-next-line // eslint-disable-next-line
console.log('Built a entry less file to dist/antd.less'); console.log('Built a entry less file to dist/antd.less');
// Build less entry file: dist/antd.dark.less
fs.writeFileSync(
path.join(process.cwd(), 'dist', 'antd.dark.less'),
'@import "../lib/style/dark.less";\n@import "../lib/style/components.less";',
);
// eslint-disable-next-line
console.log('Built a entry less file to dist/antd.dark.less');
// Build dark.js: dist/dark-theme.js, for less-loader
fs.writeFileSync(
path.join(process.cwd(), 'dist', 'dark-theme.js'),
`module.exports = ${JSON.stringify(darkVars, null, 2)};`,
);
// eslint-disable-next-line
console.log('Built a dark theme js file to dist/dark-theme.js');
} }
} }

View File

@ -10,13 +10,6 @@ references:
attach_workspace: attach_workspace:
at: ~/ant-design at: ~/ant-design
install_react: &install_react
run: REACT=15 ./scripts/install-react.sh
react_15: &react_15
environment:
REACT: 15
react_16: &react_16 react_16: &react_16
environment: environment:
REACT: 16 REACT: 16
@ -51,21 +44,6 @@ references:
- test_node: - test_node:
requires: requires:
- setup - setup
- test_dist_15:
requires:
- dist
- test_lib_15:
requires:
- compile
- test_es_15:
requires:
- compile
- test_dom_15:
requires:
- setup
- test_node_15:
requires:
- setup
- check_metadata: - check_metadata:
requires: requires:
- setup - setup
@ -173,69 +151,6 @@ jobs:
- *attach_workspace - *attach_workspace
- run: npm run test-node -- -w 1 - run: npm run test-node -- -w 1
test_dist_15:
<<: *container_config
<<: *react_15
steps:
- checkout
- *attach_workspace
- *install_react
- run:
command: npm test -- -w 1 -u
environment:
LIB_DIR: dist
REACT: 15
test_lib_15:
<<: *container_config
<<: *react_15
steps:
- checkout
- *attach_workspace
- *install_react
- run:
command: npm test -- -w 1 -u
environment:
LIB_DIR: lib
REACT: 15
test_es_15:
<<: *container_config
<<: *react_15
steps:
- checkout
- *attach_workspace
- *install_react
- run:
command: npm test -- -w 1 -u
environment:
LIB_DIR: es
REACT: 15
test_dom_15:
<<: *container_config
<<: *react_15
steps:
- checkout
- *attach_workspace
- *install_react
- run:
command: npm test -- -w 1 -u
environment:
REACT: 15
test_node_15:
<<: *container_config
<<: *react_15
steps:
- checkout
- *attach_workspace
- *install_react
- run:
command: npm run test-node -- -w 1 -u
environment:
REACT: 15
check_metadata: check_metadata:
<<: *container_config <<: *container_config
steps: steps:

View File

@ -14,5 +14,9 @@ module.exports = {
pattern: /ConfigConsumer.*renderEmpty/ms, pattern: /ConfigConsumer.*renderEmpty/ms,
module: '../empty', module: '../empty',
}, },
{
pattern: /config-provider\/context.*renderEmpty/ms,
module: '../empty',
},
], ],
}; };

View File

@ -6,6 +6,7 @@ components/**/*.jsx
# Docs templates # Docs templates
site/theme/template/IconDisplay/*.js site/theme/template/IconDisplay/*.js
site/theme/template/IconDisplay/*.jsx site/theme/template/IconDisplay/*.jsx
site/theme/template/Home/**/*.jsx
typings typings
es/**/* es/**/*
lib/**/* lib/**/*

View File

@ -37,6 +37,7 @@ const eslintrc = {
'react/forbid-prop-types': 0, 'react/forbid-prop-types': 0,
'react/jsx-indent': 0, 'react/jsx-indent': 0,
'react/jsx-wrap-multilines': ['error', { declaration: false, assignment: false }], 'react/jsx-wrap-multilines': ['error', { declaration: false, assignment: false }],
'import/extensions': 0,
'import/no-extraneous-dependencies': [ 'import/no-extraneous-dependencies': [
'error', 'error',
{ {
@ -87,7 +88,6 @@ const eslintrc = {
'react/static-property-placement': 0, 'react/static-property-placement': 0,
'jest/no-test-callback': 0, 'jest/no-test-callback': 0,
'jest/expect-expect': 0, 'jest/expect-expect': 0,
'import/extensions': 0,
}, },
globals: { globals: {
gtag: true, gtag: true,

6
.gitignore vendored
View File

@ -38,8 +38,12 @@ components/**/*.jsx
!components/**/__tests__/**/*.js !components/**/__tests__/**/*.js
!components/**/__tests__/**/*.js.snap !components/**/__tests__/**/*.js.snap
/.history /.history
*.tmp
# Docs templates # Docs templates
site/theme/template/IconDisplay/*.js site/theme/template/IconDisplay/*.js
site/theme/template/IconDisplay/*.jsx site/theme/template/IconDisplay/*.jsx
site/theme/template/IconDisplay/fields.js site/theme/template/IconDisplay/fields.js
*.tmp
site/theme/template/Home/**/*.jsx

View File

@ -1 +1,2 @@
~* ~*
dist/report.html

View File

@ -13,19 +13,11 @@ matrix:
fast_finish: true fast_finish: true
include: include:
- env: TEST_TYPE=lint - env: TEST_TYPE=lint
- env: REACT=16 TEST_TYPE=test:dist - env: TEST_TYPE=test:dist
- env: REACT=16 TEST_TYPE=test:lib - env: TEST_TYPE=test:lib
- env: REACT=16 TEST_TYPE=test:es - env: TEST_TYPE=test:es
- env: REACT=16 TEST_TYPE=test:dom - env: TEST_TYPE=test:dom
- env: REACT=16 TEST_TYPE=test:node - env: TEST_TYPE=test:node
- env: REACT=15 TEST_TYPE=test:dist
- env: REACT=15 TEST_TYPE=test:lib
- env: REACT=15 TEST_TYPE=test:es
- env: REACT=15 TEST_TYPE=test:dom
- env: REACT=15 TEST_TYPE=test:node
before_script:
- scripts/install-react.sh
script: script:
- scripts/travis-script.sh - scripts/travis-script.sh

View File

@ -33,13 +33,13 @@
## 🖥 支持环境 ## 🖥 支持环境
- 现代浏览器和 IE9 及以上。 - 现代浏览器和 IE11 及以上。
- 支持服务端渲染。 - 支持服务端渲染。
- [Electron](http://electron.atom.io/) - [Electron](http://electron.atom.io/)
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron | | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| IE9, IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions | | IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## 📦 安装 ## 📦 安装
@ -53,7 +53,7 @@ yarn add antd
## 🔨 示例 ## 🔨 示例
````jsx ```jsx
import { Button, DatePicker } from 'antd'; import { Button, DatePicker } from 'antd';
const App = () => ( const App = () => (
@ -62,12 +62,13 @@ const App = () => (
<DatePicker /> <DatePicker />
</> </>
); );
```
引入样式: 引入样式:
```jsx ```jsx
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less' import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
```` ```
你也可以使用 [babel-plugin-import](https://ant.design/docs/react/getting-started-cn#按需加载)。 你也可以使用 [babel-plugin-import](https://ant.design/docs/react/getting-started-cn#按需加载)。

View File

@ -39,7 +39,7 @@ English | [简体中文](./README-zh_CN.md)
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron | | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| IE9, IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions | | IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## 📦 Install ## 📦 Install

View File

@ -33,21 +33,6 @@ jobs:
node-react@16: node-react@16:
REACT: 16 REACT: 16
TEST_TYPE: test:node TEST_TYPE: test:node
dist-react@15:
REACT: 15
TEST_TYPE: test:dist
lib-react@15:
REACT: 15
TEST_TYPE: test:lib
es-react@15:
REACT: 15
TEST_TYPE: test:es
dom-react@15:
REACT: 15
TEST_TYPE: test:dom
node-react@15:
REACT: 15
TEST_TYPE: test:node
steps: steps:
- checkout: self - checkout: self
fetchDepth: 1 fetchDepth: 1
@ -57,8 +42,6 @@ jobs:
versionSpec: '10.x' versionSpec: '10.x'
- script: npm install - script: npm install
displayName: install displayName: install
- script: scripts/install-react.sh
displayName: install-react
- script: scripts/travis-script.sh - script: scripts/travis-script.sh
displayName: test displayName: test
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1

View File

@ -27,12 +27,10 @@ Array [
"Drawer", "Drawer",
"Empty", "Empty",
"Form", "Form",
"Icon",
"Input", "Input",
"InputNumber", "InputNumber",
"Layout", "Layout",
"List", "List",
"LocaleProvider",
"message", "message",
"Menu", "Menu",
"Mentions", "Mentions",
@ -64,7 +62,6 @@ Array [
"Timeline", "Timeline",
"Tooltip", "Tooltip",
"Typography", "Typography",
"Mention",
"Upload", "Upload",
"version", "version",
] ]

View File

@ -5,7 +5,6 @@ import KeyCode from 'rc-util/lib/KeyCode';
import delayRaf from '../raf'; import delayRaf from '../raf';
import throttleByAnimationFrame from '../throttleByAnimationFrame'; import throttleByAnimationFrame from '../throttleByAnimationFrame';
import getDataOrAriaProps from '../getDataOrAriaProps'; import getDataOrAriaProps from '../getDataOrAriaProps';
import triggerEvent from '../triggerEvent';
import Wave from '../wave'; import Wave from '../wave';
import TransButton from '../transButton'; import TransButton from '../transButton';
import openAnimation from '../openAnimation'; import openAnimation from '../openAnimation';
@ -126,19 +125,6 @@ describe('Test utils function', () => {
}); });
}); });
it('triggerEvent', () => {
const button = document.createElement('button');
button.addEventListener(
'click',
() => {
button.style.width = '100px';
},
true,
);
triggerEvent(button, 'click');
expect(button.style.width).toBe('100px');
});
describe('wave', () => { describe('wave', () => {
it('bindAnimationEvent should return when node is null', () => { it('bindAnimationEvent should return when node is null', () => {
const wrapper = mount( const wrapper = mount(
@ -183,9 +169,6 @@ describe('Test utils function', () => {
}); });
it('should not throw when no children', () => { it('should not throw when no children', () => {
if (process.env.REACT === '15') {
return;
}
expect(() => mount(<Wave />)).not.toThrow(); expect(() => mount(<Wave />)).not.toThrow();
}); });
}); });

View File

@ -1,5 +1,6 @@
import { tuple } from './type'; import { tuple } from './type';
export const PresetStatusColorTypes = tuple('success', 'processing', 'error', 'default', 'warning');
// eslint-disable-next-line import/prefer-default-export // eslint-disable-next-line import/prefer-default-export
export const PresetColorTypes = tuple( export const PresetColorTypes = tuple(
'pink', 'pink',
@ -18,3 +19,4 @@ export const PresetColorTypes = tuple(
); );
export type PresetColorType = (typeof PresetColorTypes)[number]; export type PresetColorType = (typeof PresetColorTypes)[number];
export type PresetStatusColorType = (typeof PresetStatusColorTypes)[number];

View File

@ -1,23 +1,3 @@
// matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82
let enquire: any;
// TODO: Will be removed in antd 4.0 because we will no longer support ie9
if (typeof window !== 'undefined') {
const matchMediaPolyfill = (mediaQuery: string) => {
return {
media: mediaQuery,
matches: false,
addListener() {},
removeListener() {},
};
};
// ref: https://github.com/ant-design/ant-design/issues/18774
if (!window.matchMedia) window.matchMedia = matchMediaPolyfill as any;
// eslint-disable-next-line global-require
enquire = require('enquire.js');
}
export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
export type BreakpointMap = Partial<Record<Breakpoint, string>>; export type BreakpointMap = Partial<Record<Breakpoint, string>>;
@ -42,6 +22,7 @@ let subUid = -1;
let screens = {}; let screens = {};
const responsiveObserve = { const responsiveObserve = {
matchHandlers: {},
dispatch(pointMap: BreakpointMap) { dispatch(pointMap: BreakpointMap) {
screens = pointMap; screens = pointMap;
if (subscribers.length < 1) { if (subscribers.length < 1) {
@ -73,31 +54,32 @@ const responsiveObserve = {
} }
}, },
unregister() { unregister() {
Object.keys(responsiveMap).map((screen: Breakpoint) => Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
enquire.unregister(responsiveMap[screen]), const matchMediaQuery = responsiveMap[screen]!;
); const handler = this.matchHandlers[matchMediaQuery];
if (handler && handler.mql && handler.listener) {
handler.mql.removeListener(handler.listener);
}
});
}, },
register() { register() {
Object.keys(responsiveMap).map((screen: Breakpoint) => Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
enquire.register(responsiveMap[screen], { const matchMediaQuery = responsiveMap[screen]!;
match: () => { const listener = ({ matches }: { matches: boolean }) => {
const pointMap = { this.dispatch({
...screens, ...screens,
[screen]: true, [screen]: matches,
}; });
this.dispatch(pointMap); };
}, const mql = window.matchMedia(matchMediaQuery);
unmatch: () => { mql.addListener(listener);
const pointMap = { this.matchHandlers[matchMediaQuery] = {
...screens, mql,
[screen]: false, listener,
}; };
this.dispatch(pointMap);
}, listener(mql);
// Keep a empty destory to avoid triggering unmatch when unregister });
destroy() {},
}),
);
}, },
}; };

View File

@ -1,8 +0,0 @@
export default function triggerEvent(el: Element, type: string) {
if ('createEvent' in document) {
// modern browsers, IE9+
const e = document.createEvent('HTMLEvents');
e.initEvent(type, false, true);
el.dispatchEvent(e);
}
}

View File

@ -4,6 +4,7 @@ import Affix from '..';
import { getObserverEntities } from '../utils'; import { getObserverEntities } from '../utils';
import Button from '../../button'; import Button from '../../button';
import { spyElementPrototype } from '../../__tests__/util/domHook'; import { spyElementPrototype } from '../../__tests__/util/domHook';
import rtlTest from '../../../tests/shared/rtlTest';
const events = {}; const events = {};
@ -40,6 +41,8 @@ class AffixMounter extends React.Component {
} }
describe('Affix Render', () => { describe('Affix Render', () => {
rtlTest(Affix);
let wrapper; let wrapper;
let domMock; let domMock;

View File

@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Affix Render rtl render component should be rendered correctly in RTL direction 1`] = `
<div>
<div
class=""
/>
</div>
`;

View File

@ -13,47 +13,31 @@ title:
The simplest usage. The simplest usage.
```jsx ```tsx
import React, { useState, FC } from 'react';
import { Affix, Button } from 'antd'; import { Affix, Button } from 'antd';
class Demo extends React.Component { const Demo: FC = () => {
state = { const [top, setTop] = useState(10);
top: 10, const [bottom, setBottom] = useState(10);
bottom: 10,
};
render() { return (
return ( <div>
<div> <Affix offsetTop={top}>
<Affix offsetTop={this.state.top}> <Button type="primary" onClick={() => setTop(top + 10)}>
<Button
type="primary"
onClick={() => {
this.setState({
top: this.state.top + 10,
});
}}
>
Affix top Affix top
</Button> </Button>
</Affix> </Affix>
<br /> <br />
<Affix offsetBottom={this.state.bottom}> <Affix offsetBottom={bottom}>
<Button <Button type="primary" onClick={() =>setBottom(bottom + 10)}>
type="primary"
onClick={() => {
this.setState({
bottom: this.state.bottom + 10,
});
}}
>
Affix bottom Affix bottom
</Button> </Button>
</Affix> </Affix>
</div> </div>
); )
}
} }
ReactDOM.render(<Demo />, mountNode); ReactDOM.render(<Demo />, mountNode);
``` ```

View File

@ -1,8 +1,8 @@
--- ---
order: 99 order: 99
title: title:
zh-CN: 调 zh-CN: 调整浏览器大小,观察 Affix 容器是否发生变化。跟随变化为正常。#17678
en-US: Debug en-US:
debug: true debug: true
--- ---
@ -14,36 +14,28 @@ DEBUG
DEBUG DEBUG
```jsx ```tsx
import React, { useState, FC } from 'react';
import { Affix, Button } from 'antd'; import { Affix, Button } from 'antd';
class Demo extends React.Component { const Demo: FC = () => {
state = { const [top, setTop] = useState(10);
top: 10, return (
}; <div style={{ height: 10000 }}>
<div>Top</div>
render() { <Affix offsetTop={top}>
return ( <div style={{ background: 'red' }}>
<div style={{ height: 10000 }}> <Button
<div>Top</div> type="primary"
<Affix offsetTop={this.state.top}> onClick={() => setTop(top + 10)}
<div style={{ background: 'red' }}> >
<Button Affix top
type="primary" </Button>
onClick={() => { </div>
this.setState({ </Affix>
top: this.state.top + 10, <div>Bottom</div>
}); </div>
}} );
>
Affix top
</Button>
</div>
</Affix>
<div>Bottom</div>
</div>
);
}
} }
ReactDOM.render(<Demo />, mountNode); ReactDOM.render(<Demo />, mountNode);

View File

@ -13,27 +13,23 @@ title:
Set a `target` for 'Affix', which is listen to scroll event of target element (default is `window`). Set a `target` for 'Affix', which is listen to scroll event of target element (default is `window`).
```jsx ```tsx
import React, { useState, FC } from 'react';
import { Affix, Button } from 'antd'; import { Affix, Button } from 'antd';
class Demo extends React.Component { const Demo: FC = () => {
render() { const [container, setContainer] = useState(null);
return ( return (
<div <div className="scrollable-container" ref={setContainer}>
className="scrollable-container" <div className="background">
ref={node => { <Affix target={() => container}>
this.container = node; <Button type="primary">Fixed at the top of container</Button>
}} </Affix>
>
<div className="background">
<Affix target={() => this.container}>
<Button type="primary">Fixed at the top of container</Button>
</Affix>
</div>
</div> </div>
); </div>
} )
} };
ReactDOM.render(<Demo />, mountNode); ReactDOM.render(<Demo />, mountNode);
``` ```

View File

@ -14,12 +14,12 @@ Please note that Affix should not cover other content on the page, especially wh
## API ## API
| Property | Description | Type | Default | Version | | Property | Description | Type | Default |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- |
| offsetBottom | Offset from the bottom of the viewport (in pixels) | number | - | | | offsetBottom | Offset from the bottom of the viewport (in pixels) | number | - |
| offsetTop | Offset from the top of the viewport (in pixels) | number | 0 | | | offsetTop | Offset from the top of the viewport (in pixels) | number | 0 |
| target | Specifies the scrollable area DOM node | () => HTMLElement | () => window | | | target | Specifies the scrollable area DOM node | () => HTMLElement | () => window |
| onChange | Callback for when Affix state is changed | Function(affixed) | - | | | onChange | Callback for when Affix state is changed | Function(affixed) | - |
**Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself: **Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself:

View File

@ -1,12 +1,10 @@
import * as React from 'react'; import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import classNames from 'classnames'; import classNames from 'classnames';
import omit from 'omit.js'; import omit from 'omit.js';
import ResizeObserver from 'rc-resize-observer'; import ResizeObserver from 'rc-resize-observer';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame'; import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
import warning from '../_util/warning';
import { import {
addObserveTarget, addObserveTarget,
removeObserveTarget, removeObserveTarget,
@ -25,7 +23,6 @@ export interface AffixProps {
* *
*/ */
offsetTop?: number; offsetTop?: number;
offset?: number;
/** 距离窗口底部达到指定偏移量后触发 */ /** 距离窗口底部达到指定偏移量后触发 */
offsetBottom?: number; offsetBottom?: number;
style?: React.CSSProperties; style?: React.CSSProperties;
@ -119,17 +116,8 @@ class Affix extends React.Component<AffixProps, AffixState> {
} }
getOffsetTop = () => { getOffsetTop = () => {
const { offset, offsetBottom } = this.props; const { offsetBottom } = this.props;
let { offsetTop } = this.props; let { offsetTop } = this.props;
if (typeof offsetTop === 'undefined') {
offsetTop = offset;
warning(
typeof offset === 'undefined',
'Affix',
'`offset` is deprecated. Please use `offsetTop` instead.',
);
}
if (offsetBottom === undefined && offsetTop === undefined) { if (offsetBottom === undefined && offsetTop === undefined) {
offsetTop = 0; offsetTop = 0;
} }
@ -299,6 +287,4 @@ class Affix extends React.Component<AffixProps, AffixState> {
} }
} }
polyfill(Affix);
export default Affix; export default Affix;

View File

@ -15,12 +15,12 @@ title: Affix
## API ## API
| 成员 | 说明 | 类型 | 默认值 | 版本 | | 成员 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- |
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | | | offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | - |
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | | | offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | - |
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window | | | target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window |
| onChange | 固定状态改变时触发的回调函数 | Function(affixed) | 无 | | | onChange | 固定状态改变时触发的回调函数 | Function(affixed) | - |
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位: **注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:

View File

@ -0,0 +1,43 @@
import * as React from 'react';
import Alert from '.';
interface ErrorBoundaryProps {
message?: React.ReactNode;
description?: React.ReactNode;
}
export default class ErrorBoundary extends React.Component<
ErrorBoundaryProps,
{
error?: Error | null;
info: {
componentStack?: string;
};
}
> {
state = {
error: undefined,
info: {
componentStack: '',
},
};
componentDidCatch(error: Error | null, info: object) {
this.setState({ error, info });
}
render() {
const { message, description, children } = this.props;
const { error, info } = this.state;
const componentStack = info && info.componentStack ? info.componentStack : null;
const errorMessage = typeof message === 'undefined' ? (error || '').toString() : message;
const errorDescription = typeof description === 'undefined' ? componentStack : description;
if (error) {
// You can render any custom fallback UI
return (
<Alert type="error" message={errorMessage} description={<pre>{errorDescription}</pre>} />
);
}
return children;
}
}

View File

@ -1,14 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders ./components/alert/demo/error-boundary.md correctly 1`] = `
<button
class="ant-btn ant-btn-danger"
type="button"
>
<span>
Click me to throw a error
</span>
</button>
`;
exports[`renders ./components/alert/demo/banner.md correctly 1`] = ` exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
<div> <div>
<div <div
class="ant-alert ant-alert-warning ant-alert-banner" class="ant-alert ant-alert-warning ant-alert-banner"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: exclamation-circle" aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon" class="anticon anticon-exclamation-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -21,10 +33,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 010-96 48.01 48.01 0 010 96z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -39,9 +51,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
class="ant-alert ant-alert-warning ant-alert-banner ant-alert-closable" class="ant-alert ant-alert-warning ant-alert-banner ant-alert-closable"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: exclamation-circle" aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon" class="anticon anticon-exclamation-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -54,10 +67,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 010-96 48.01 48.01 0 010 96z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -71,9 +84,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
tabindex="0" tabindex="0"
type="button" type="button"
> >
<i <span
aria-label="icon: close" aria-label="close"
class="anticon anticon-close" class="anticon anticon-close"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -86,10 +100,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z" d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
</div> </div>
<br /> <br />
@ -111,9 +125,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
class="ant-alert ant-alert-error ant-alert-banner" class="ant-alert ant-alert-error ant-alert-banner"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: close-circle" aria-label="close-circle"
class="anticon anticon-close-circle ant-alert-icon" class="anticon anticon-close-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -126,10 +141,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 01-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> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -177,9 +192,10 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
tabindex="0" tabindex="0"
type="button" type="button"
> >
<i <span
aria-label="icon: close" aria-label="close"
class="anticon anticon-close" class="anticon anticon-close"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -192,10 +208,10 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z" d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
</div> </div>
<div <div
@ -217,9 +233,10 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
tabindex="0" tabindex="0"
type="button" type="button"
> >
<i <span
aria-label="icon: close" aria-label="close"
class="anticon anticon-close" class="anticon anticon-close"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -232,10 +249,10 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z" d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
</div> </div>
</div> </div>
@ -287,9 +304,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-success" class="ant-alert ant-alert-success"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -302,10 +320,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -319,9 +337,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-info" class="ant-alert ant-alert-info"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -334,10 +353,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -351,9 +370,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-warning" class="ant-alert ant-alert-warning"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -366,10 +386,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -383,9 +403,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-error" class="ant-alert ant-alert-error"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -398,10 +419,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -415,9 +436,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-success ant-alert-with-description" class="ant-alert ant-alert-success ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -430,10 +452,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -449,9 +471,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-info ant-alert-with-description" class="ant-alert ant-alert-info ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -464,10 +487,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -483,9 +506,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-warning ant-alert-with-description" class="ant-alert ant-alert-warning ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -498,10 +522,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -517,9 +541,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
class="ant-alert ant-alert-error ant-alert-with-description" class="ant-alert ant-alert-error ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: smile" aria-label="smile"
class="anticon anticon-smile ant-alert-icon" class="anticon anticon-smile ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -532,10 +557,10 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z" d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -621,9 +646,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-success" class="ant-alert ant-alert-success"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: check-circle" aria-label="check-circle"
class="anticon anticon-check-circle ant-alert-icon" class="anticon anticon-check-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -636,10 +662,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -653,9 +679,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-info" class="ant-alert ant-alert-info"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: info-circle" aria-label="info-circle"
class="anticon anticon-info-circle ant-alert-icon" class="anticon anticon-info-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -668,10 +695,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -685,9 +712,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-warning" class="ant-alert ant-alert-warning"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: exclamation-circle" aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon" class="anticon anticon-exclamation-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -700,10 +728,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 010-96 48.01 48.01 0 010 96z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -717,9 +745,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-error" class="ant-alert ant-alert-error"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: close-circle" aria-label="close-circle"
class="anticon anticon-close-circle ant-alert-icon" class="anticon anticon-close-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -732,10 +761,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 01-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> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -749,9 +778,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-success ant-alert-with-description" class="ant-alert ant-alert-success ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: check-circle" aria-label="check-circle"
class="anticon anticon-check-circle ant-alert-icon" class="anticon anticon-check-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -764,13 +794,13 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0 0 51.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z" d="M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z"
/> />
<path <path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -786,9 +816,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-info ant-alert-with-description" class="ant-alert ant-alert-info ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: info-circle" aria-label="info-circle"
class="anticon anticon-info-circle ant-alert-icon" class="anticon anticon-info-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -804,10 +835,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/> />
<path <path
d="M464 336a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z" d="M464 336a48 48 0 1096 0 48 48 0 10-96 0zm72 112h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V456c0-4.4-3.6-8-8-8z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -823,9 +854,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-warning ant-alert-with-description" class="ant-alert ant-alert-warning ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: exclamation-circle" aria-label="exclamation-circle"
class="anticon anticon-exclamation-circle ant-alert-icon" class="anticon anticon-exclamation-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -841,10 +873,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/> />
<path <path
d="M464 688a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z" d="M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -860,9 +892,10 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
class="ant-alert ant-alert-error ant-alert-with-description" class="ant-alert ant-alert-error ant-alert-with-description"
data-show="true" data-show="true"
> >
<i <span
aria-label="icon: close-circle" aria-label="close-circle"
class="anticon anticon-close-circle ant-alert-icon" class="anticon anticon-close-circle ant-alert-icon"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -875,13 +908,13 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M685.4 354.8c0-4.4-3.6-8-8-8l-66 .3L512 465.6l-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 670a8.32 8.32 0 0 0-1.9 5.2c0 4.4 3.6 8 8 8l66.1-.3L512 564.4l99.3 118.4 66 .3c4.4 0 8-3.5 8-8 0-1.9-.7-3.7-1.9-5.2L553.5 515l130.1-155c1.2-1.4 1.8-3.3 1.8-5.2z" d="M685.4 354.8c0-4.4-3.6-8-8-8l-66 .3L512 465.6l-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 670a8.32 8.32 0 00-1.9 5.2c0 4.4 3.6 8 8 8l66.1-.3L512 564.4l99.3 118.4 66 .3c4.4 0 8-3.5 8-8 0-1.9-.7-3.7-1.9-5.2L553.5 515l130.1-155c1.2-1.4 1.8-3.3 1.8-5.2z"
/> />
<path <path
d="M512 65C264.6 65 64 265.6 64 513s200.6 448 448 448 448-200.6 448-448S759.4 65 512 65zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" d="M512 65C264.6 65 64 265.6 64 513s200.6 448 448 448 448-200.6 448-448S759.4 65 512 65zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
/> />
</svg> </svg>
</i> </span>
<span <span
class="ant-alert-message" class="ant-alert-message"
> >
@ -915,9 +948,10 @@ exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
tabindex="0" tabindex="0"
type="button" type="button"
> >
<i <span
aria-label="icon: close" aria-label="close"
class="anticon anticon-close" class="anticon anticon-close"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -930,10 +964,10 @@ exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z" d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
</div> </div>
<p> <p>

View File

@ -0,0 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Alert ErrorBoundary 1`] = `
<div
class="ant-alert ant-alert-error ant-alert-with-description ant-alert-no-icon"
data-show="true"
>
<span
class="ant-alert-message"
>
ReferenceError: NotExisted is not defined
</span>
<span
class="ant-alert-description"
>
<pre>
in ThrowError
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent
</pre>
</span>
</div>
`;
exports[`Alert rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-alert ant-alert-info ant-alert-no-icon ant-alert-rtl"
data-show="true"
>
<span
class="ant-alert-message"
/>
<span
class="ant-alert-description"
/>
</div>
`;

View File

@ -1,8 +1,13 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import Alert from '..'; import Alert from '..';
import rtlTest from '../../../tests/shared/rtlTest';
const { ErrorBoundary } = Alert;
describe('Alert', () => { describe('Alert', () => {
rtlTest(Alert);
beforeAll(() => { beforeAll(() => {
jest.useFakeTimers(); jest.useFakeTimers();
}); });
@ -50,18 +55,15 @@ describe('Alert', () => {
}); });
}); });
it('warning for props#iconType', () => { const testIt = process.env.REACT === '15' ? it.skip : it;
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); testIt('ErrorBoundary', () => {
mount( const ThrowError = () => <NotExisted />; // eslint-disable-line
<Alert const wrapper = mount(
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text" <ErrorBoundary>
type="warning" <ThrowError />
iconType="up" </ErrorBoundary>,
/>,
); );
expect(warnSpy).toHaveBeenCalledWith( // eslint-disable-next-line jest/no-standalone-expect
'Warning: [antd: Alert] `iconType` is deprecated. Please use `icon` instead.', expect(wrapper.render()).toMatchSnapshot();
);
warnSpy.mockRestore();
}); });
}); });

View File

@ -20,7 +20,7 @@ ReactDOM.render(<Alert message="Success Text" type="success" />, mountNode);
``` ```
<style> <style>
.ant-alert { .code-box-demo .ant-alert {
margin-bottom: 16px; margin-bottom: 16px;
} }
</style> </style>

View File

@ -15,9 +15,10 @@ title:
A relevant icon makes information clearer and more friendly. A relevant icon makes information clearer and more friendly.
```jsx ```jsx
import { Alert, Icon } from 'antd'; import { Alert } from 'antd';
import { SmileOutlined } from '@ant-design/icons';
const icon = <Icon type="smile" />; const icon = <SmileOutlined />;
ReactDOM.render( ReactDOM.render(
<div> <div>

View File

@ -0,0 +1,51 @@
---
order: 8
title:
zh-CN: ErrorBoundary
en-US: React 错误处理
---
## zh-CN
友好的 [React 错误处理](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html) 包裹组件。
## en-US
ErrorBoundary Component for making error handling easier in [React](https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html).
```jsx
import { Button, Alert } from 'antd';
const { ErrorBoundary } = Alert;
class ThrowError extends React.Component {
state = {
error: null,
};
onClick = () => {
this.setState({
error: new Error('An Uncaught Error'),
});
};
render() {
const { error } = this.state;
if (error) {
throw error;
}
return (
<Button type="danger" onClick={this.onClick}>
Click me to throw a error
</Button>
);
}
}
ReactDOM.render(
<ErrorBoundary>
<ThrowError />
</ErrorBoundary>,
mountNode,
);
```

View File

@ -13,15 +13,22 @@ Alert component for feedback.
## API ## API
| Property | Description | Type | Default | Version | | Property | Description | Type | Default |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- |
| afterClose | Called when close animation is finished | () => void | - | 3.3.1 | | afterClose | Called when close animation is finished | () => void | - |
| banner | Whether to show as banner | boolean | false | | | banner | Whether to show as banner | boolean | false |
| closable | Whether Alert can be closed | boolean | - | | | closable | Whether Alert can be closed | boolean | - |
| closeText | Close text to show | string\|ReactNode | - | | | closeText | Close text to show | string\|ReactNode | - |
| description | Additional content of Alert | string\|ReactNode | - | | | description | Additional content of Alert | string\|ReactNode | - |
| icon | Custom icon, effective when `showIcon` is `true` | ReactNode | - | 3.10.0 | | icon | Custom icon, effective when `showIcon` is `true` | ReactNode | - |
| message | Content of Alert | string\|ReactNode | - | | | message | Content of Alert | string\|ReactNode | - |
| showIcon | Whether to show icon | boolean | false, in `banner` mode default is true | | | showIcon | Whether to show icon | boolean | false, in `banner` mode default is true |
| type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` | | | type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` |
| onClose | Callback when Alert is closed | (e: MouseEvent) => void | - | | | onClose | Callback when Alert is closed | (e: MouseEvent) => void | - |
### Alert.ErrorBoundary
| Property | Description | Type | Default | Version |
| ----------- | -------------------------------- | --------- | ------------------- | ------- |
| message | custom error message to show | ReactNode | `{{ error }}` | |
| description | custom error description to show | ReactNode | `{{ error stack }}` | |

View File

@ -1,11 +1,22 @@
import * as React from 'react'; import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import {
CloseOutlined,
CheckCircleOutlined,
ExclamationCircleOutlined,
InfoCircleOutlined,
CloseCircleOutlined,
CheckCircleFilled,
ExclamationCircleFilled,
InfoCircleFilled,
CloseCircleFilled,
} from '@ant-design/icons';
import Animate from 'rc-animate'; import Animate from 'rc-animate';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon, { ThemeType } from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import getDataOrAriaProps from '../_util/getDataOrAriaProps'; import getDataOrAriaProps from '../_util/getDataOrAriaProps';
import warning from '../_util/warning'; import ErrorBoundary from './ErrorBoundary';
function noop() {} function noop() {}
@ -28,7 +39,6 @@ export interface AlertProps {
afterClose?: () => void; afterClose?: () => void;
/** Whether to show icon */ /** Whether to show icon */
showIcon?: boolean; showIcon?: boolean;
iconType?: string;
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string; prefixCls?: string;
className?: string; className?: string;
@ -41,21 +51,27 @@ export interface AlertState {
closed: boolean; closed: boolean;
} }
const iconMapFilled = {
success: CheckCircleFilled,
info: InfoCircleFilled,
error: CloseCircleFilled,
warning: ExclamationCircleFilled,
};
const iconMapOutlined = {
success: CheckCircleOutlined,
info: InfoCircleOutlined,
error: CloseCircleOutlined,
warning: ExclamationCircleOutlined,
};
export default class Alert extends React.Component<AlertProps, AlertState> { export default class Alert extends React.Component<AlertProps, AlertState> {
constructor(props: AlertProps) { static ErrorBoundary = ErrorBoundary;
super(props);
warning( state = {
!('iconType' in props), closing: false,
'Alert', closed: false,
'`iconType` is deprecated. Please use `icon` instead.', };
);
this.state = {
closing: false,
closed: false,
};
}
handleClose = (e: React.MouseEvent<HTMLButtonElement>) => { handleClose = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault(); e.preventDefault();
@ -79,7 +95,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
(this.props.afterClose || noop)(); (this.props.afterClose || noop)();
}; };
renderAlert = ({ getPrefixCls }: ConfigConsumerProps) => { renderAlert = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { const {
description, description,
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
@ -90,7 +106,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
style, style,
icon, icon,
} = this.props; } = this.props;
let { closable, type, showIcon, iconType } = this.props; let { closable, type, showIcon } = this.props;
const { closing, closed } = this.state; const { closing, closed } = this.state;
const prefixCls = getPrefixCls('alert', customizePrefixCls); const prefixCls = getPrefixCls('alert', customizePrefixCls);
@ -100,30 +116,8 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
// banner模式默认为警告 // banner模式默认为警告
type = banner && type === undefined ? 'warning' : type || 'info'; type = banner && type === undefined ? 'warning' : type || 'info';
let iconTheme: ThemeType = 'filled'; // use outline icon in alert with description
if (!iconType) { const iconType = (description ? iconMapOutlined : iconMapFilled)[type] || null;
switch (type) {
case 'success':
iconType = 'check-circle';
break;
case 'info':
iconType = 'info-circle';
break;
case 'error':
iconType = 'close-circle';
break;
case 'warning':
iconType = 'exclamation-circle';
break;
default:
iconType = 'default';
}
// use outline icon in alert with description
if (description) {
iconTheme = 'outlined';
}
}
// closeable when closeText is assigned // closeable when closeText is assigned
if (closeText) { if (closeText) {
@ -139,6 +133,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
[`${prefixCls}-no-icon`]: !showIcon, [`${prefixCls}-no-icon`]: !showIcon,
[`${prefixCls}-banner`]: !!banner, [`${prefixCls}-banner`]: !!banner,
[`${prefixCls}-closable`]: closable, [`${prefixCls}-closable`]: closable,
[`${prefixCls}-rtl`]: direction === 'rtl',
}, },
className, className,
); );
@ -153,23 +148,25 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
{closeText ? ( {closeText ? (
<span className={`${prefixCls}-close-text`}>{closeText}</span> <span className={`${prefixCls}-close-text`}>{closeText}</span>
) : ( ) : (
<Icon type="close" /> <CloseOutlined />
)} )}
</button> </button>
) : null; ) : null;
const dataOrAriaProps = getDataOrAriaProps(this.props); const dataOrAriaProps = getDataOrAriaProps(this.props);
const iconNode = (icon && const iconNode =
(React.isValidElement<{ className?: string }>(icon) ? ( (icon &&
React.cloneElement(icon, { (React.isValidElement<{ className?: string }>(icon) ? (
className: classNames(`${prefixCls}-icon`, { React.cloneElement(icon, {
[icon.props.className as string]: icon.props.className, className: classNames(`${prefixCls}-icon`, {
}), [icon.props.className as string]: icon.props.className,
}) }),
) : ( })
<span className={`${prefixCls}-icon`}>{icon}</span> ) : (
))) || <Icon className={`${prefixCls}-icon`} type={iconType} theme={iconTheme} />; <span className={`${prefixCls}-icon`}>{icon}</span>
))) ||
React.createElement(iconType, { className: `${prefixCls}-icon` });
return closed ? null : ( return closed ? null : (
<Animate <Animate

View File

@ -14,15 +14,22 @@ title: Alert
## API ## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| afterClose | 关闭动画结束后触发的回调函数 | () => void | - |
| banner | 是否用作顶部公告 | boolean | false |
| closable | 默认不显示关闭按钮 | boolean | 无 |
| closeText | 自定义关闭按钮 | string\|ReactNode | 无 |
| description | 警告提示的辅助性文字介绍 | string\|ReactNode | 无 |
| icon | 自定义图标,`showIcon` 为 `true` 时有效 | ReactNode | - |
| message | 警告提示内容 | string\|ReactNode | 无 |
| showIcon | 是否显示辅助图标 | boolean | false`banner` 模式下默认值为 true |
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info``banner` 模式下默认值为 `warning` |
| onClose | 关闭时触发的回调函数 | (e: MouseEvent) => void | 无 |
### Alert.ErrorBoundary
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| afterClose | 关闭动画结束后触发的回调函数 | () => void | - | 3.3.1 | | message | 自定义错误标题,如果未指定会展示原生报错信息 | ReactNode | `{{ error }}` | |
| banner | 是否用作顶部公告 | boolean | false | | | description | 自定义错误内容,如果未指定会展示报错堆栈 | ReactNode | `{{ error stack }}` | |
| closable | 默认不显示关闭按钮 | boolean | 无 | |
| closeText | 自定义关闭按钮 | string\|ReactNode | 无 | |
| description | 警告提示的辅助性文字介绍 | string\|ReactNode | 无 | |
| icon | 自定义图标,`showIcon` 为 `true` 时有效 | ReactNode | - | 3.10.0 |
| message | 警告提示内容 | string\|ReactNode | 无 | |
| showIcon | 是否显示辅助图标 | boolean | false`banner` 模式下默认值为 true | |
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info``banner` 模式下默认值为 `warning` | |
| onClose | 关闭时触发的回调函数 | (e: MouseEvent) => void | 无 | |

View File

@ -3,11 +3,6 @@
@alert-prefix-cls: ~'@{ant-prefix}-alert'; @alert-prefix-cls: ~'@{ant-prefix}-alert';
@alert-message-color: @heading-color;
@alert-text-color: @text-color;
@alert-close-color: @text-color-secondary;
@alert-close-hover-color: @icon-color-hover;
.@{alert-prefix-cls} { .@{alert-prefix-cls} {
.reset-component; .reset-component;
@ -16,18 +11,33 @@
word-wrap: break-word; word-wrap: break-word;
border-radius: @border-radius-base; border-radius: @border-radius-base;
&-rtl {
padding: 8px 37px 8px 15px;
direction: rtl;
}
&&-no-icon { &&-no-icon {
padding: 8px 15px; padding: 8px 15px;
} }
&&-closable { &&-closable {
padding-right: 30px; padding-right: 30px;
.@{alert-prefix-cls}-rtl& {
padding-right: 15px;
padding-left: 30px;
}
} }
&-icon { &-icon {
position: absolute; position: absolute;
top: 8px + @font-size-base * @line-height-base / 2 - @font-size-base / 2; top: 8px + @font-size-base * @line-height-base / 2 - @font-size-base / 2;
left: 16px; left: 16px;
.@{alert-prefix-cls}-rtl & {
right: 16px;
left: auto;
}
} }
&-description { &-description {
@ -63,9 +73,15 @@
&-error { &-error {
background-color: @alert-error-bg-color; background-color: @alert-error-bg-color;
border: @border-width-base @border-style-base @alert-error-border-color; border: @border-width-base @border-style-base @alert-error-border-color;
.@{alert-prefix-cls}-icon { .@{alert-prefix-cls}-icon {
color: @alert-error-icon-color; color: @alert-error-icon-color;
} }
.@{alert-prefix-cls}-description > pre {
margin: 0;
padding: 0;
}
} }
&-close-icon { &-close-icon {
@ -80,6 +96,11 @@
outline: none; outline: none;
cursor: pointer; cursor: pointer;
.@{alert-prefix-cls}-rtl & {
right: auto;
left: 16px;
}
.@{iconfont-css-prefix}-close { .@{iconfont-css-prefix}-close {
color: @alert-close-color; color: @alert-close-color;
transition: color 0.3s; transition: color 0.3s;
@ -103,6 +124,10 @@
color: @alert-text-color; color: @alert-text-color;
line-height: @line-height-base; line-height: @line-height-base;
border-radius: @border-radius-base; border-radius: @border-radius-base;
.@{alert-prefix-cls}-rtl& {
padding: 15px 64px 15px 15px;
}
} }
&-with-description&-no-icon { &-with-description&-no-icon {
@ -114,6 +139,11 @@
top: 16px; top: 16px;
left: 24px; left: 24px;
font-size: 24px; font-size: 24px;
.@{alert-prefix-cls}-rtl& {
right: 24px;
left: auto;
}
} }
&-with-description &-close-icon { &-with-description &-close-icon {
@ -122,6 +152,11 @@
right: 16px; right: 16px;
font-size: @font-size-base; font-size: @font-size-base;
cursor: pointer; cursor: pointer;
.@{alert-prefix-cls}-rtl& {
right: auto;
left: 16px;
}
} }
&-with-description &-message { &-with-description &-message {

View File

@ -1,6 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import { polyfill } from 'react-lifecycles-compat';
import classNames from 'classnames'; import classNames from 'classnames';
import { AntAnchor } from './Anchor'; import { AntAnchor } from './Anchor';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
@ -83,6 +82,4 @@ class AnchorLink extends React.Component<AnchorLinkProps, any> {
} }
} }
polyfill(AnchorLink);
export default AnchorLink; export default AnchorLink;

View File

@ -19,14 +19,14 @@ For displaying anchor hyperlinks on page and jumping between them.
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| affix | Fixed mode of Anchor | boolean | true | | | affix | Fixed mode of Anchor | boolean | true | |
| bounds | Bounding distance of anchor area | number | 5(px) | | | bounds | Bounding distance of anchor area | number | 5(px) | |
| getContainer | Scrolling container | () => HTMLElement | () => window | 3.4.0 | | getContainer | Scrolling container | () => HTMLElement | () => window | |
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | | | offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | |
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | | | offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | |
| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | | | showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | |
| onClick | set the handler to handle `click` event | Function(e: Event, link: Object) | - | 3.9.0 | | onClick | set the handler to handle `click` event | Function(e: Event, link: Object) | - | |
| getCurrentAnchor | Customize the anchor highlight | () => string | - | 3.22.0 | | getCurrentAnchor | Customize the anchor highlight | () => string | - | |
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 | | targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | |
| onChange | Listening for anchor link change | (currentActiveLink: string) => void | | 3.24.0 | | onChange | Listening for anchor link change | (currentActiveLink: string) => void | | |
### Link Props ### Link Props

View File

@ -20,14 +20,14 @@ title: Anchor
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| affix | 固定模式 | boolean | true | | | affix | 固定模式 | boolean | true | |
| bounds | 锚点区域边界 | number | 5(px) | | | bounds | 锚点区域边界 | number | 5(px) | |
| getContainer | 指定滚动的容器 | () => HTMLElement | () => window | 3.4.0 | | getContainer | 指定滚动的容器 | () => HTMLElement | () => window | |
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | | | offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | |
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | | | offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
| showInkInFixed | 固定模式是否显示小圆点 | boolean | false | | | showInkInFixed | 固定模式是否显示小圆点 | boolean | false | |
| onClick | `click` 事件的 handler | Function(e: Event, link: Object) | - | 3.9.0 | | onClick | `click` 事件的 handler | Function(e: Event, link: Object) | - | |
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | 3.22.0 | | getCurrentAnchor | 自定义高亮的锚点 | () => string | - | |
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 | | targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | |
| onChange | 监听锚点链接改变 | (currentActiveLink: string) => void | | 3.24.0 | | onChange | 监听锚点链接改变 | (currentActiveLink: string) => void | | |
### Link Props ### Link Props

View File

@ -13,7 +13,7 @@
margin-left: -4px; margin-left: -4px;
padding-left: 4px; padding-left: 4px;
overflow: auto; overflow: auto;
background-color: @component-background; background-color: @anchor-bg;
} }
&-ink { &-ink {

View File

@ -1,25 +0,0 @@
import * as React from 'react';
export interface InputElementProps {
children: React.ReactElement<any>;
}
export default class InputElement extends React.Component<InputElementProps, any> {
saveRef = (ele: HTMLInputElement) => {
const { ref: childRef } = this.props.children as any;
if (typeof childRef === 'function') {
childRef(ele);
}
};
render() {
return React.cloneElement(
this.props.children,
{
...this.props,
ref: this.saveRef,
},
null,
);
}
}

View File

@ -0,0 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AutoComplete with Custom Input Element Render rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-select ant-select-auto-complete ant-select-rtl ant-select-single ant-select-show-search"
>
<div
class="ant-select-selector"
>
<span
class="ant-select-selection-search"
>
<input
aria-activedescendant="undefined_list_0"
aria-autocomplete="list"
aria-controls="undefined_list"
aria-haspopup="listbox"
aria-owns="undefined_list"
autocomplete="off"
class="ant-select-selection-search-input"
role="combobox"
value=""
/>
</span>
<span
class="ant-select-selection-placeholder"
/>
</div>
</div>
`;

View File

@ -1,11 +1,6 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import AutoComplete from '..'; import AutoComplete from '..';
import focusTest from '../../../tests/shared/focusTest';
describe('AutoComplete could be focus', () => {
focusTest(AutoComplete);
});
describe('AutoComplete children could be focus', () => { describe('AutoComplete children could be focus', () => {
beforeAll(() => { beforeAll(() => {
@ -67,7 +62,11 @@ describe('AutoComplete children could be focus', () => {
let inputRef; let inputRef;
mount( mount(
<AutoComplete dataSource={[]}> <AutoComplete dataSource={[]}>
<input ref={node => { inputRef = node; }} /> <input
ref={node => {
inputRef = node;
}}
/>
</AutoComplete>, </AutoComplete>,
); );
expect(typeof inputRef.focus).toBe('function'); expect(typeof inputRef.focus).toBe('function');

View File

@ -2,9 +2,11 @@ import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import AutoComplete from '..'; import AutoComplete from '..';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
describe('AutoComplete with Custom Input Element Render', () => { describe('AutoComplete with Custom Input Element Render', () => {
mountTest(AutoComplete); mountTest(AutoComplete);
rtlTest(AutoComplete);
it('AutoComplete with custom Input render perfectly', () => { it('AutoComplete with custom Input render perfectly', () => {
const wrapper = mount( const wrapper = mount(
@ -15,34 +17,27 @@ describe('AutoComplete with Custom Input Element Render', () => {
expect(wrapper.find('textarea').length).toBe(1); expect(wrapper.find('textarea').length).toBe(1);
wrapper.find('textarea').simulate('change', { target: { value: '123' } }); wrapper.find('textarea').simulate('change', { target: { value: '123' } });
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
// should not filter data source defaultly // should not filter data source defaultly
expect(dropdownWrapper.find('MenuItem').length).toBe(3); expect(wrapper.find('.ant-select-item-option').length).toBe(3);
}); });
it('AutoComplete should work when dataSource is object array', () => { it('AutoComplete should work when dataSource is object array', () => {
const wrapper = mount( const wrapper = mount(
<AutoComplete dataSource={[{ text: 'text', value: 'value' }, { text: 'abc', value: 'xxx' }]}> <AutoComplete
dataSource={[
{ text: 'text', value: 'value' },
{ text: 'abc', value: 'xxx' },
]}
>
<input /> <input />
</AutoComplete>, </AutoComplete>,
); );
expect(wrapper.find('input').length).toBe(1); expect(wrapper.find('input').length).toBe(1);
wrapper.find('input').simulate('change', { target: { value: 'a' } }); wrapper.find('input').simulate('change', { target: { value: 'a' } });
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
// should not filter data source defaultly // should not filter data source defaultly
expect(dropdownWrapper.find('MenuItem').length).toBe(2); expect(wrapper.find('.ant-select-item-option').length).toBe(2);
}); });
it('AutoComplete throws error when contains invalid dataSource', () => { it('AutoComplete throws error when contains invalid dataSource', () => {

View File

@ -7,28 +7,36 @@ title:
## zh-CN ## zh-CN
基本使用。通过 dataSource 设置自动完成的数据源 基本使用。通过 options 设置自动完成的数据源
## en-US ## en-US
Basic Usage, set data source of autocomplete with `dataSource` property. Basic Usage, set data source of autocomplete with `options` property.
```jsx ```tsx
import { AutoComplete } from 'antd'; import { AutoComplete } from 'antd';
function onSelect(value) { function onSelect(value) {
console.log('onSelect', value); console.log('onSelect', value);
} }
function mockVal(str: string, repeat: number = 1) {
return {
value: str.repeat(repeat),
};
}
class Complete extends React.Component { class Complete extends React.Component {
state = { state = {
value: '', value: '',
dataSource: [], options: [],
}; };
onSearch = searchText => { onSearch = searchText => {
this.setState({ this.setState({
dataSource: !searchText ? [] : [searchText, searchText.repeat(2), searchText.repeat(3)], options: !searchText
? []
: [mockVal(searchText), mockVal(searchText, 2), mockVal(searchText, 3)],
}); });
}; };
@ -37,11 +45,12 @@ class Complete extends React.Component {
}; };
render() { render() {
const { dataSource, value } = this.state; const { options, value } = this.state;
return ( return (
<div> <div>
<AutoComplete <AutoComplete
dataSource={dataSource} options={[]}
style={{ width: 200 }} style={{ width: 200 }}
onSelect={onSelect} onSelect={onSelect}
onSearch={this.onSearch} onSearch={this.onSearch}
@ -51,7 +60,7 @@ class Complete extends React.Component {
<br /> <br />
<AutoComplete <AutoComplete
value={value} value={value}
dataSource={dataSource} options={options}
style={{ width: 200 }} style={{ width: 200 }}
onSelect={onSelect} onSelect={onSelect}
onSearch={this.onSearch} onSearch={this.onSearch}

View File

@ -11,52 +11,15 @@ title:
## en-US ## en-US
Demonstration of [Lookup Patterns: Certain Category](https://ant.design/docs/spec/reaction#Lookup-Patterns). Basic Usage, set datasource of autocomplete with `dataSource` property. Demonstration of [Lookup Patterns: Certain Category](https://ant.design/docs/spec/reaction#Lookup-Patterns). Basic Usage, set options of autocomplete with `options` property.
```jsx ```tsx
import { Icon, Input, AutoComplete } from 'antd'; import { Input, AutoComplete } from 'antd';
import { SearchOutlined, UserOutlined } from '@ant-design/icons';
const { Option, OptGroup } = AutoComplete; const { Option, OptGroup } = AutoComplete;
const dataSource = [ function renderTitle(title: string) {
{
title: 'Libraries',
children: [
{
title: 'AntDesign',
count: 10000,
},
{
title: 'AntDesign UI',
count: 10600,
},
],
},
{
title: 'Solutions',
children: [
{
title: 'AntDesign UI',
count: 60100,
},
{
title: 'AntDesign',
count: 30010,
},
],
},
{
title: 'Articles',
children: [
{
title: 'AntDesign design language',
count: 100000,
},
],
},
];
function renderTitle(title) {
return ( return (
<span> <span>
{title} {title}
@ -72,24 +35,34 @@ function renderTitle(title) {
); );
} }
const options = dataSource function renderItem(title: string, count: number) {
.map(group => ( return {
<OptGroup key={group.title} label={renderTitle(group.title)}> value: title,
{group.children.map(opt => ( label: (
<Option key={opt.title} value={opt.title}> <>
{opt.title} {title}
<span className="certain-search-item-count">{opt.count} people</span> <span className="certain-search-item-count">
</Option> <UserOutlined /> {count}
))} </span>
</OptGroup> </>
)) ),
.concat([ };
<Option disabled key="all" className="show-all"> }
<a href="https://www.google.com/search?q=antd" target="_blank" rel="noopener noreferrer">
View all results const options = [
</a> {
</Option>, label: renderTitle('Libraries'),
]); options: [renderItem('AntDesign', 10000), renderItem('AntDesign UI', 10600)],
},
{
label: renderTitle('Solutions'),
options: [renderItem('AntDesign UI FAQ', 60100), renderItem('AntDesign FAQ', 30010)],
},
{
label: renderTitle('Articles'),
options: [renderItem('AntDesign design language', 100000)],
},
];
function Complete() { function Complete() {
return ( return (
@ -97,15 +70,15 @@ function Complete() {
<AutoComplete <AutoComplete
className="certain-category-search" className="certain-category-search"
dropdownClassName="certain-category-search-dropdown" dropdownClassName="certain-category-search-dropdown"
dropdownMatchSelectWidth={false} dropdownMatchSelectWidth={500}
dropdownStyle={{ width: 300 }}
size="large"
style={{ width: '100%' }} style={{ width: '100%' }}
dataSource={options} options={options}
placeholder="input here"
optionLabelProp="value"
> >
<Input suffix={<Icon type="search" className="certain-category-icon" />} /> <Input
size="large"
suffix={<SearchOutlined className="certain-category-icon" />}
placeholder="input here"
/>
</AutoComplete> </AutoComplete>
</div> </div>
); );

View File

@ -24,12 +24,14 @@ function onSelect(value) {
class Complete extends React.Component { class Complete extends React.Component {
state = { state = {
dataSource: [], options: [],
}; };
handleSearch = value => { handleSearch = value => {
this.setState({ this.setState({
dataSource: !value ? [] : [value, value + value, value + value + value], options: !value
? []
: [{ value }, { value: value + value }, { value: value + value + value }],
}); });
}; };
@ -38,10 +40,10 @@ class Complete extends React.Component {
}; };
render() { render() {
const { dataSource } = this.state; const { options } = this.state;
return ( return (
<AutoComplete <AutoComplete
dataSource={dataSource} options={options}
style={{ width: 200 }} style={{ width: 200 }}
onSelect={onSelect} onSelect={onSelect}
onSearch={this.handleSearch} onSearch={this.handleSearch}

View File

@ -0,0 +1,73 @@
---
order: 999
title:
zh-CN: 在 Form 中 Debug
en-US: Debug in Form
debug: true
---
```jsx
import { Input, AutoComplete, Form, TreeSelect, Button } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
};
ReactDOM.render(
<Form style={{ margin: '0 auto' }}>
<Form.Item label="单独 AutoComplete" {...formItemLayout}>
<AutoComplete />
</Form.Item>
<Form.Item label="单独 TreeSelect" {...formItemLayout}>
<TreeSelect />
</Form.Item>
<Form.Item label="添加 Input.Group 正常" {...formItemLayout}>
<Input.Group compact>
<TreeSelect style={{ width: '30%' }} />
<AutoComplete />
</Input.Group>
</Form.Item>
<Form.Item label="包含 search 图标正常" {...formItemLayout}>
<AutoComplete>
<Input suffix={<SearchOutlined />} />
</AutoComplete>
</Form.Item>
<Form.Item label="同时有 Input.Group 和图标发生移位" {...formItemLayout}>
<Input.Group compact>
<TreeSelect style={{ width: '30%' }} />
<AutoComplete>
<Input suffix={<SearchOutlined />} />
</AutoComplete>
</Input.Group>
</Form.Item>
<Form.Item label="同时有 Input.Group 和 Search 组件发生移位" {...formItemLayout}>
<Input.Group compact>
<TreeSelect style={{ width: '30%' }} />
<AutoComplete>
<Input.Search />
</AutoComplete>
</Input.Group>
</Form.Item>
<Form.Item label="Input Group 和 Button 结合" {...formItemLayout}>
<Input.Group compact>
<TreeSelect style={{ width: '20%' }} />
<AutoComplete>
<Input.Search />
</AutoComplete>
<Button type="primary" icon={<SearchOutlined />}>
Search
</Button>
</Input.Group>
</Form.Item>
</Form>,
mountNode,
);
```

View File

@ -16,16 +16,20 @@ A non-case-sensitive AutoComplete
```jsx ```jsx
import { AutoComplete } from 'antd'; import { AutoComplete } from 'antd';
const dataSource = ['Burns Bay Road', 'Downing Street', 'Wall Street']; const options = [
{ value: 'Burns Bay Road' },
{ value: 'Downing Street' },
{ value: 'Wall Street' },
];
function Complete() { function Complete() {
return ( return (
<AutoComplete <AutoComplete
style={{ width: 200 }} style={{ width: 200 }}
dataSource={dataSource} options={options}
placeholder="try to type `b`" placeholder="try to type `b`"
filterOption={(inputValue, option) => filterOption={(inputValue, option) =>
option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1 option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
} }
/> />
); );

View File

@ -7,11 +7,11 @@ title:
## zh-CN ## zh-CN
也可以直接传 `AutoComplete.Option` 作为 `AutoComplete``children`,而非使用 `dataSource`。 也可以直接传 `AutoComplete.Option` 作为 `AutoComplete``children`,而非使用 `options`。
## en-US ## en-US
You could pass `AutoComplete.Option` as children of `AutoComplete`, instead of using `dataSource`。 You could pass `AutoComplete.Option` as children of `AutoComplete`, instead of using `options`。
```jsx ```jsx
import { AutoComplete } from 'antd'; import { AutoComplete } from 'antd';

View File

@ -11,12 +11,11 @@ title:
## en-US ## en-US
Demonstration of [Lookup Patterns: Uncertain Category](https://ant.design/docs/spec/reaction#Lookup-Patterns). Basic Usage, set datasource of autocomplete with `dataSource` property. Demonstration of [Lookup Patterns: Uncertain Category](https://ant.design/docs/spec/reaction#Lookup-Patterns).
```jsx ```jsx
import { Icon, Button, Input, AutoComplete } from 'antd'; import { Button, Input, AutoComplete } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
const { Option } = AutoComplete;
function onSelect(value) { function onSelect(value) {
console.log('onSelect', value); console.log('onSelect', value);
@ -30,57 +29,50 @@ function searchResult(query) {
return new Array(getRandomInt(5)) return new Array(getRandomInt(5))
.join('.') .join('.')
.split('.') .split('.')
.map((item, idx) => ({ .map((item, idx) => {
query, const category = `${query}${idx}`;
category: `${query}${idx}`, return {
count: getRandomInt(200, 100), value: category,
})); label: (
} <div className="global-search-item">
<span className="global-search-item-desc">
function renderOption(item) { Found {query} on{' '}
return ( <a
<Option key={item.category} text={item.category}> href={`https://s.taobao.com/search?q=${query}`}
<div className="global-search-item"> target="_blank"
<span className="global-search-item-desc"> rel="noopener noreferrer"
Found {item.query} on >
<a {category}
href={`https://s.taobao.com/search?q=${item.query}`} </a>
target="_blank" </span>
rel="noopener noreferrer" <span className="global-search-item-count">{getRandomInt(200, 100)} results</span>
> </div>
{item.category} ),
</a> };
</span> });
<span className="global-search-item-count">{item.count} results</span>
</div>
</Option>
);
} }
class Complete extends React.Component { class Complete extends React.Component {
state = { state = {
dataSource: [], options: [],
}; };
handleSearch = value => { handleSearch = value => {
this.setState({ this.setState({
dataSource: value ? searchResult(value) : [], options: value ? searchResult(value) : [],
}); });
}; };
render() { render() {
const { dataSource } = this.state; const { options } = this.state;
return ( return (
<div className="global-search-wrapper" style={{ width: 300 }}> <div className="global-search-wrapper" style={{ width: 300 }}>
<AutoComplete <AutoComplete
className="global-search" className="global-search"
size="large"
style={{ width: '100%' }} style={{ width: '100%' }}
dataSource={dataSource.map(renderOption)} options={options}
onSelect={onSelect} onSelect={onSelect}
onSearch={this.handleSearch} onSearch={this.handleSearch}
placeholder="input here"
optionLabelProp="text"
> >
<Input <Input
suffix={ suffix={
@ -90,9 +82,11 @@ class Complete extends React.Component {
size="large" size="large"
type="primary" type="primary"
> >
<Icon type="search" /> <SearchOutlined />
</Button> </Button>
} }
size="large"
placeholder="input here"
/> />
</AutoComplete> </AutoComplete>
</div> </div>

View File

@ -13,11 +13,6 @@ When there is a need for autocomplete functionality.
## API ## API
```jsx
const dataSource = ['12345', '23456', '34567'];
<AutoComplete dataSource={dataSource} />;
```
| Property | Description | Type | Default | Version | | Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| allowClear | Show clear button, effective in multiple mode only. | boolean | false | | | allowClear | Show clear button, effective in multiple mode only. | boolean | false | |
@ -25,8 +20,6 @@ const dataSource = ['12345', '23456', '34567'];
| backfill | backfill selected item the input when using keyboard | boolean | false | | | backfill | backfill selected item the input when using keyboard | boolean | false | |
| children (for customize input element) | customize input element | HTMLInputElement <br /><br /> HTMLTextAreaElement <br /><br /> `React.ReactElement<InputProps>` | `<Input />` | | | children (for customize input element) | customize input element | HTMLInputElement <br /><br /> HTMLTextAreaElement <br /><br /> `React.ReactElement<InputProps>` | `<Input />` | |
| children (for dataSource) | Data source to auto complete | `React.ReactElement<OptionProps>` <br /><br /> `Array<React.ReactElement<OptionProps>>` | - | | | children (for dataSource) | Data source to auto complete | `React.ReactElement<OptionProps>` <br /><br /> `Array<React.ReactElement<OptionProps>>` | - | |
| dataSource | Data source for autocomplete | [DataSourceItemType](https://git.io/vMMKF)\[] | - | |
| dropdownMenuStyle | additional style applied to dropdown menu | object | | |
| defaultActiveFirstOption | Whether active first option by default | boolean | true | | | defaultActiveFirstOption | Whether active first option by default | boolean | true | |
| defaultValue | Initial selected option. | string\|string\[] | - | | | defaultValue | Initial selected option. | string\|string\[] | - | |
| disabled | Whether disabled select | boolean | false | | | disabled | Whether disabled select | boolean | false | |
@ -34,14 +27,14 @@ const dataSource = ['12345', '23456', '34567'];
| optionLabelProp | Which prop value of option will render as content of select. | string | `children` | | | optionLabelProp | Which prop value of option will render as content of select. | string | `children` | |
| placeholder | placeholder of input | string | - | | | placeholder | placeholder of input | string | - | |
| value | selected option | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | - | | | value | selected option | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | - | |
| onBlur | Called when leaving the component. | function() | - | 3.6.5 | | onBlur | Called when leaving the component. | function() | - | |
| onChange | Called when select an option or input value change, or value of input is changed | function(value) | - | | | onChange | Called when select an option or input value change, or value of input is changed | function(value) | - | |
| onFocus | Called when entering the component | function() | - | 3.6.5 | | onFocus | Called when entering the component | function() | - | |
| onSearch | Called when searching items. | function(value) | - | | | onSearch | Called when searching items. | function(value) | - | |
| onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - | | | onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - | |
| defaultOpen | Initial open state of dropdown | boolean | - | 3.9.3 | | defaultOpen | Initial open state of dropdown | boolean | - | |
| open | Controlled open state of dropdown | boolean | - | 3.9.3 | | open | Controlled open state of dropdown | boolean | - | |
| onDropdownVisibleChange | Call when dropdown open | function(open) | - | 3.9.3 | | onDropdownVisibleChange | Call when dropdown open | function(open) | - | |
## Methods ## Methods

View File

@ -1,160 +1,136 @@
/**
* TODO: 4.0
* - remove `dataSource`
* - `size` not work with customizeInput
* - customizeInput not feedback `ENTER` key since accessibility enhancement
*/
import * as React from 'react'; import * as React from 'react';
import { Option, OptGroup } from 'rc-select'; import toArray from 'rc-util/lib/Children/toArray';
import { SelectProps as RcSelectProps } from 'rc-select';
import classNames from 'classnames'; import classNames from 'classnames';
import InputElement from './InputElement'; import omit from 'omit.js';
import Input, { InputProps } from '../input'; import Select, { InternalSelectProps, OptionType } from '../select';
import Select, { AbstractSelectProps, SelectValue, OptionProps, OptGroupProps } from '../select';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { Omit } from '../_util/type'; import warning from '../_util/warning';
const { Option } = Select;
const InternalSelect = Select as React.ComponentClass<RcSelectProps>;
export interface DataSourceItemObject { export interface DataSourceItemObject {
value: string; value: string;
text: string; text: string;
} }
export type DataSourceItemType = export type DataSourceItemType = string | DataSourceItemObject;
| string
| DataSourceItemObject
| React.ReactElement<OptionProps>
| React.ReactElement<OptGroupProps>;
export interface AutoCompleteInputProps { export interface AutoCompleteProps
onChange?: React.FormEventHandler<any>; extends Omit<InternalSelectProps<string>, 'inputIcon' | 'loading' | 'mode' | 'optionLabelProp'> {
value: any;
}
export type ValidInputElement =
| HTMLInputElement
| HTMLTextAreaElement
| React.ReactElement<AutoCompleteInputProps>;
export interface AutoCompleteProps extends Omit<AbstractSelectProps, 'loading'> {
value?: SelectValue;
defaultValue?: SelectValue;
dataSource?: DataSourceItemType[]; dataSource?: DataSourceItemType[];
dropdownMenuStyle?: React.CSSProperties;
autoFocus?: boolean;
backfill?: boolean;
optionLabelProp?: string;
onChange?: (value: SelectValue) => void;
onSelect?: (value: SelectValue, option: Object) => any;
onBlur?: (value: SelectValue) => void;
onFocus?: () => void;
children?:
| ValidInputElement
| React.ReactElement<InputProps>
| React.ReactElement<OptionProps>
| Array<React.ReactElement<OptionProps>>;
} }
function isSelectOptionOrSelectOptGroup(child: any): Boolean { function isSelectOptionOrSelectOptGroup(child: any): Boolean {
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup); return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
} }
export default class AutoComplete extends React.Component<AutoCompleteProps, {}> { const AutoComplete: React.RefForwardingComponent<Select, AutoCompleteProps> = (props, ref) => {
static Option = Option as React.ClassicComponentClass<OptionProps>; const { prefixCls: customizePrefixCls, className, children, dataSource } = props;
const childNodes: React.ReactElement[] = toArray(children);
static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>; const selectRef = React.useRef<Select>();
static defaultProps = { React.useImperativeHandle<Select, Select>(ref, () => selectRef.current!);
transitionName: 'slide-up',
optionLabelProp: 'children',
choiceTransitionName: 'zoom',
showSearch: false,
filterOption: false,
};
private select: any; // ============================= Input =============================
let customizeInput: React.ReactElement;
saveSelect = (node: any) => { if (
this.select = node; childNodes.length === 1 &&
}; React.isValidElement(childNodes[0]) &&
!isSelectOptionOrSelectOptGroup(childNodes[0])
getInputElement = () => { ) {
const { children } = this.props; customizeInput = childNodes[0];
const element =
children && React.isValidElement(children) && children.type !== Option ? (
React.Children.only(this.props.children)
) : (
<Input />
);
const elementProps = { ...(element as React.ReactElement<any>).props };
// https://github.com/ant-design/ant-design/pull/7742
delete elementProps.children;
return <InputElement {...elementProps}>{element}</InputElement>;
};
focus() {
this.select.focus();
} }
blur() { const getInputElement = (): React.ReactElement => customizeInput;
this.select.blur();
// ============================ Options ============================
let optionChildren: React.ReactNode;
// [Legacy] convert `children` or `dataSource` into option children
if (childNodes.length && isSelectOptionOrSelectOptGroup(childNodes[0])) {
optionChildren = children;
} else {
optionChildren = dataSource
? dataSource.map(item => {
if (React.isValidElement(item)) {
return item;
}
switch (typeof item) {
case 'string':
return (
<Option key={item} value={item}>
{item}
</Option>
);
case 'object': {
const { value: optionValue } = item as DataSourceItemObject;
return (
<Option key={optionValue} value={optionValue}>
{(item as DataSourceItemObject).text}
</Option>
);
}
default:
throw new Error('AutoComplete[dataSource] only supports type `string[] | Object[]`.');
}
})
: [];
} }
renderAutoComplete = ({ getPrefixCls }: ConfigConsumerProps) => { // ============================ Warning ============================
const { React.useEffect(() => {
prefixCls: customizePrefixCls, warning(
size, !('dataSource' in props),
className = '', 'AutoComplete',
notFoundContent, '`dataSource` is deprecated, please use `options` instead.',
optionLabelProp,
dataSource,
children,
} = this.props;
const prefixCls = getPrefixCls('select', customizePrefixCls);
const cls = classNames({
[`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-sm`]: size === 'small',
[className]: !!className,
[`${prefixCls}-show-search`]: true,
[`${prefixCls}-auto-complete`]: true,
});
let options;
const childArray = React.Children.toArray(children);
if (childArray.length && isSelectOptionOrSelectOptGroup(childArray[0])) {
options = children;
} else {
options = dataSource
? dataSource.map(item => {
if (React.isValidElement(item)) {
return item;
}
switch (typeof item) {
case 'string':
return <Option key={item}>{item}</Option>;
case 'object':
return (
<Option key={(item as DataSourceItemObject).value}>
{(item as DataSourceItemObject).text}
</Option>
);
default:
throw new Error(
'AutoComplete[dataSource] only supports type `string[] | Object[]`.',
);
}
})
: [];
}
return (
<Select
{...this.props}
className={cls}
mode={Select.SECRET_COMBOBOX_MODE_DO_NOT_USE}
optionLabelProp={optionLabelProp}
getInputElement={this.getInputElement}
notFoundContent={notFoundContent}
ref={this.saveSelect}
>
{options}
</Select>
); );
};
render() { warning(
return <ConfigConsumer>{this.renderAutoComplete}</ConfigConsumer>; !customizeInput || !('size' in props),
} 'AutoComplete',
} 'You need to control style self instead of setting `size` when using customize input.',
);
}, []);
return (
<ConfigConsumer>
{({ getPrefixCls }: ConfigConsumerProps) => {
const prefixCls = getPrefixCls('select', customizePrefixCls);
return (
<InternalSelect
ref={selectRef as any}
{...omit(props, ['dataSource'])}
prefixCls={prefixCls}
className={classNames(className, `${prefixCls}-auto-complete`)}
mode={Select.SECRET_COMBOBOX_MODE_DO_NOT_USE as any}
getInputElement={getInputElement}
>
{optionChildren}
</InternalSelect>
);
}}
</ConfigConsumer>
);
};
const RefAutoComplete = React.forwardRef<Select, AutoCompleteProps>(AutoComplete);
type RefAutoComplete = typeof RefAutoComplete & {
Option: OptionType;
};
(RefAutoComplete as RefAutoComplete).Option = Option;
export default RefAutoComplete as RefAutoComplete;

View File

@ -14,11 +14,6 @@ title: AutoComplete
## API ## API
```jsx
const dataSource = ['12345', '23456', '34567'];
<AutoComplete dataSource={dataSource} />;
```
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| allowClear | 支持清除, 单选模式有效 | boolean | false | | | allowClear | 支持清除, 单选模式有效 | boolean | false | |
@ -26,24 +21,22 @@ const dataSource = ['12345', '23456', '34567'];
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | | | backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement <br /><br /> HTMLTextAreaElement <br /><br /> `React.ReactElement<InputProps>` | `<Input />` | | | children (自定义输入框) | 自定义输入框 | HTMLInputElement <br /><br /> HTMLTextAreaElement <br /><br /> `React.ReactElement<InputProps>` | `<Input />` | |
| children (自动完成的数据源) | 自动完成的数据源 | `React.ReactElement<OptionProps>` <br /><br /> `Array<React.ReactElement<OptionProps>>` | - | | | children (自动完成的数据源) | 自动完成的数据源 | `React.ReactElement<OptionProps>` <br /><br /> `Array<React.ReactElement<OptionProps>>` | - | |
| dataSource | 自动完成的数据源 | [DataSourceItemType](https://git.io/vMMKF)\[] | | |
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | | |
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | | | defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | |
| defaultValue | 指定默认选中的条目 | string\|string\[]\| 无 | | | defaultValue | 指定默认选中的条目 | string\|string\[]\| 无 | |
| disabled | 是否禁用 | boolean | false | | | disabled | 是否禁用 | boolean | false | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | | | filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | Function(triggerNode) | () => document.body | 3.19.4 | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | Function(triggerNode) | () => document.body | |
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` | | | optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` | |
| placeholder | 输入框提示 | string | - | | | placeholder | 输入框提示 | string | - | |
| value | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | 无 | | | value | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | 无 | |
| onBlur | 失去焦点时的回调 | function() | - | 3.6.5 | | onBlur | 失去焦点时的回调 | function() | - | |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 | | | onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 | |
| onFocus | 获得焦点时的回调 | function() | - | 3.6.5 | | onFocus | 获得焦点时的回调 | function() | - | |
| onSearch | 搜索补全项的时候调用 | function(value) | 无 | | | onSearch | 搜索补全项的时候调用 | function(value) | 无 | |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 | | | onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | 3.9.3 | | defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| open | 是否展开下拉菜单 | boolean | - | 3.9.3 | | open | 是否展开下拉菜单 | boolean | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | 3.9.3 | | onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
## 方法 ## 方法

View File

@ -8,85 +8,4 @@
.@{autocomplete-prefix-cls} { .@{autocomplete-prefix-cls} {
.reset-component; .reset-component;
&.@{select-prefix-cls} {
.@{select-prefix-cls} {
&-selection {
border: 0;
box-shadow: none;
&__rendered {
height: 100%;
margin-right: 0;
margin-left: 0;
line-height: @input-height-base;
}
&__placeholder {
margin-right: (@input-padding-horizontal-base + 1px);
margin-left: (@input-padding-horizontal-base + 1px);
}
&--single {
height: auto;
}
}
}
// Fix https://github.com/ant-design/ant-design/issues/7800
.@{select-prefix-cls}-search--inline {
position: static;
float: left;
}
&-allow-clear {
.@{select-prefix-cls}-selection:hover .@{select-prefix-cls}-selection__rendered {
margin-right: 0 !important;
}
}
.@{input-prefix-cls} {
height: @input-height-base;
line-height: @line-height-base;
background: transparent;
border-width: @border-width-base;
&:focus,
&:hover {
.hover;
}
&[disabled] {
.disabled;
background-color: transparent;
}
}
&-lg {
.@{select-prefix-cls}-selection__rendered {
line-height: @input-height-lg;
}
.@{input-prefix-cls} {
height: @input-height-lg;
padding-top: @input-padding-vertical-lg;
padding-bottom: @input-padding-vertical-lg;
}
}
&-sm {
.@{select-prefix-cls}-selection__rendered {
line-height: @input-height-sm;
}
.@{input-prefix-cls} {
height: @input-height-sm;
padding-top: @input-padding-vertical-sm;
padding-bottom: @input-padding-vertical-sm;
}
}
}
}
// https://github.com/ant-design/ant-design/issues/14156
.@{input-prefix-cls}-group > .@{autocomplete-prefix-cls} {
.@{select-prefix-cls}-search__field.@{input-prefix-cls}-affix-wrapper {
display: inline;
float: none;
}
} }

View File

@ -3,4 +3,3 @@ import './index.less';
// style dependencies // style dependencies
import '../../select/style'; import '../../select/style';
import '../../input/style';

View File

@ -2,9 +2,11 @@ import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import Avatar from '..'; import Avatar from '..';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
describe('Avatar Render', () => { describe('Avatar Render', () => {
mountTest(Avatar); mountTest(Avatar);
rtlTest(Avatar);
let originOffsetWidth; let originOffsetWidth;
beforeAll(() => { beforeAll(() => {
@ -133,4 +135,15 @@ describe('Avatar Render', () => {
wrapper.setProps({ children: 'xx' }); wrapper.setProps({ children: 'xx' });
expect(wrapper.state().scale).toBe(0.32); expect(wrapper.state().scale).toBe(0.32);
}); });
it('should warning when pass a string as icon props', () => {
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(<Avatar size={64} icon="aa" />);
expect(warnSpy).not.toHaveBeenCalled();
mount(<Avatar size={64} icon="user" />);
expect(warnSpy).toHaveBeenCalledWith(
`Warning: [antd: Avatar] \`icon\` is using ReactNode instead of string naming in v4. Please check \`user\` at https://ant.design/components/icon`,
);
warnSpy.mockRestore();
});
}); });

View File

@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Avatar Render rtl render component should be rendered correctly in RTL direction 1`] = `
<span
class="ant-avatar ant-avatar-circle"
>
<span
class="ant-avatar-string"
style="opacity:0"
/>
</span>
`;

View File

@ -3,7 +3,7 @@
exports[`renders ./components/avatar/demo/badge.md correctly 1`] = ` exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
<div> <div>
<span <span
style="margin-right:24px" class="avatar-item"
> >
<span <span
class="ant-badge" class="ant-badge"
@ -11,9 +11,10 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
<span <span
class="ant-avatar ant-avatar-square ant-avatar-icon" class="ant-avatar ant-avatar-square ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -26,10 +27,10 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<sup <sup
class="ant-scroll-number ant-badge-count" class="ant-scroll-number ant-badge-count"
@ -201,9 +202,10 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
<span <span
class="ant-avatar ant-avatar-square ant-avatar-icon" class="ant-avatar ant-avatar-square ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -216,10 +218,10 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<sup <sup
class="ant-scroll-number ant-badge-dot" class="ant-scroll-number ant-badge-dot"
@ -237,9 +239,10 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-icon" class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="width:64px;height:64px;line-height:64px;font-size:32px" style="width:64px;height:64px;line-height:64px;font-size:32px"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -252,17 +255,18 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon" class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -275,17 +279,18 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-avatar ant-avatar-circle ant-avatar-icon" class="ant-avatar ant-avatar-circle ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -298,17 +303,18 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-avatar ant-avatar-sm ant-avatar-circle ant-avatar-icon" class="ant-avatar ant-avatar-sm ant-avatar-circle ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -321,10 +327,10 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
</div> </div>
<div> <div>
@ -332,9 +338,10 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
class="ant-avatar ant-avatar-square ant-avatar-icon" class="ant-avatar ant-avatar-square ant-avatar-icon"
style="width:64px;height:64px;line-height:64px;font-size:32px" style="width:64px;height:64px;line-height:64px;font-size:32px"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -347,17 +354,18 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-avatar ant-avatar-lg ant-avatar-square ant-avatar-icon" class="ant-avatar ant-avatar-lg ant-avatar-square ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -370,17 +378,18 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-avatar ant-avatar-square ant-avatar-icon" class="ant-avatar ant-avatar-square ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -393,17 +402,18 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-avatar ant-avatar-sm ant-avatar-square ant-avatar-icon" class="ant-avatar ant-avatar-sm ant-avatar-square ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -416,10 +426,10 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
</div> </div>
</div> </div>
@ -532,9 +542,10 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
<span <span
class="ant-avatar ant-avatar-circle ant-avatar-icon" class="ant-avatar ant-avatar-circle ant-avatar-icon"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -547,33 +558,10 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span>
<span
class="ant-avatar ant-avatar-circle ant-avatar-icon"
>
<i
aria-label="icon: user"
class="anticon anticon-user"
>
<svg
aria-hidden="true"
class=""
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</i>
</span> </span>
<span <span
class="ant-avatar ant-avatar-circle" class="ant-avatar ant-avatar-circle"
@ -617,9 +605,10 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
class="ant-avatar ant-avatar-circle ant-avatar-icon" class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color:#87d068" style="background-color:#87d068"
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -632,10 +621,10 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
</div> </div>
`; `;

View File

@ -15,20 +15,33 @@ Usually used for reminders and notifications.
```jsx ```jsx
import { Avatar, Badge } from 'antd'; import { Avatar, Badge } from 'antd';
import { UserOutlined } from '@ant-design/icons';
ReactDOM.render( ReactDOM.render(
<div> <div>
<span style={{ marginRight: 24 }}> <span className="avatar-item">
<Badge count={1}> <Badge count={1}>
<Avatar shape="square" icon="user" /> <Avatar shape="square" icon={<UserOutlined />} />
</Badge> </Badge>
</span> </span>
<span> <span>
<Badge dot> <Badge dot>
<Avatar shape="square" icon="user" /> <Avatar shape="square" icon={<UserOutlined />} />
</Badge> </Badge>
</span> </span>
</div>, </div>,
mountNode, mountNode,
); );
``` ```
```css
/* tile uploaded pictures */
.avatar-item {
margin-right: 24px;
}
[class*='-col-rtl'] .avatar-item {
margin-right: 0;
margin-left: 24px;
}
```

View File

@ -15,20 +15,21 @@ Three sizes and two shapes are available.
```jsx ```jsx
import { Avatar } from 'antd'; import { Avatar } from 'antd';
import { UserOutlined } from '@ant-design/icons';
ReactDOM.render( ReactDOM.render(
<div> <div>
<div> <div>
<Avatar size={64} icon="user" /> <Avatar size={64} icon={<UserOutlined />} />
<Avatar size="large" icon="user" /> <Avatar size="large" icon={<UserOutlined />} />
<Avatar icon="user" /> <Avatar icon={<UserOutlined />} />
<Avatar size="small" icon="user" /> <Avatar size="small" icon={<UserOutlined />} />
</div> </div>
<div> <div>
<Avatar shape="square" size={64} icon="user" /> <Avatar shape="square" size={64} icon={<UserOutlined />} />
<Avatar shape="square" size="large" icon="user" /> <Avatar shape="square" size="large" icon={<UserOutlined />} />
<Avatar shape="square" icon="user" /> <Avatar shape="square" icon={<UserOutlined />} />
<Avatar shape="square" size="small" icon="user" /> <Avatar shape="square" size="small" icon={<UserOutlined />} />
</div> </div>
</div>, </div>,
mountNode, mountNode,

View File

@ -14,17 +14,17 @@ title:
Image, Icon and letter are supported, and the latter two kinds of avatar can have custom colors and background colors. Image, Icon and letter are supported, and the latter two kinds of avatar can have custom colors and background colors.
```jsx ```jsx
import { Avatar, Icon } from 'antd'; import { Avatar } from 'antd';
import { UserOutlined } from '@ant-design/icons';
ReactDOM.render( ReactDOM.render(
<div> <div>
<Avatar icon="user" /> <Avatar icon={<UserOutlined />} />
<Avatar icon={<Icon type="user" />} />
<Avatar>U</Avatar> <Avatar>U</Avatar>
<Avatar>USER</Avatar> <Avatar>USER</Avatar>
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" /> <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
<Avatar style={{ color: '#f56a00', backgroundColor: '#fde3cf' }}>U</Avatar> <Avatar style={{ color: '#f56a00', backgroundColor: '#fde3cf' }}>U</Avatar>
<Avatar style={{ backgroundColor: '#87d068' }} icon="user" /> <Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} />
</div>, </div>,
mountNode, mountNode,
); );

View File

@ -10,10 +10,10 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
| Property | Description | Type | Default | Version | | Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| icon | the `Icon` type for an icon avatar, see `Icon` Component or use ReactNode | string \| ReactNode | - | | | icon | custom icon type for an icon avatar | ReactNode | - | |
| shape | the shape of avatar | `circle` \| `square` | `circle` | | | shape | the shape of avatar | `circle` \| `square` | `circle` | |
| size | the size of the avatar | number \| string: `large` `small` `default` | `default` | | | size | the size of the avatar | number \| string: `large` `small` `default` | `default` | |
| src | the address of the image for an image avatar | string | - | | | src | the address of the image for an image avatar | string | - | |
| srcSet | a list of sources to use for different screen resolutions | string | - | 3.11.0 | | srcSet | a list of sources to use for different screen resolutions | string | - | |
| alt | This attribute defines the alternative text describing the image | string | - | 3.7.0 | | alt | This attribute defines the alternative text describing the image | string | - | |
| onError | handler when img load error, return false to prevent default fallback behavior | () => boolean | - | 3.8.0 | | onError | handler when img load error, return false to prevent default fallback behavior | () => boolean | - | |

View File

@ -1,7 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning';
export interface AvatarProps { export interface AvatarProps {
/** Shape of avatar, options:`circle`, `square` */ /** Shape of avatar, options:`circle`, `square` */
@ -15,8 +16,8 @@ export interface AvatarProps {
src?: string; src?: string;
/** Srcset of image avatar */ /** Srcset of image avatar */
srcSet?: string; srcSet?: string;
/** Type of the Icon to be used in avatar */ /** icon to be used in avatar */
icon?: string | React.ReactNode; icon?: React.ReactNode;
style?: React.CSSProperties; style?: React.CSSProperties;
prefixCls?: string; prefixCls?: string;
className?: string; className?: string;
@ -108,6 +109,12 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
...others ...others
} = this.props; } = this.props;
warning(
!(typeof icon === 'string' && icon.length > 2),
'Avatar',
`\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
);
const { isImgExist, scale, mounted } = this.state; const { isImgExist, scale, mounted } = this.state;
const prefixCls = getPrefixCls('avatar', customizePrefixCls); const prefixCls = getPrefixCls('avatar', customizePrefixCls);
@ -137,11 +144,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
if (src && isImgExist) { if (src && isImgExist) {
children = <img src={src} srcSet={srcSet} onError={this.handleImgLoadError} alt={alt} />; children = <img src={src} srcSet={srcSet} onError={this.handleImgLoadError} alt={alt} />;
} else if (icon) { } else if (icon) {
if (typeof icon === 'string') { children = icon;
children = <Icon type={icon} />;
} else {
children = icon;
}
} else { } else {
const childrenNode = this.avatarChildren; const childrenNode = this.avatarChildren;
if (childrenNode || scale !== 1) { if (childrenNode || scale !== 1) {

View File

@ -15,10 +15,10 @@ title: Avatar
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| icon | 设置头像的图标类型,可设为 Icon 的 `type` 或 ReactNode | string \| ReactNode | - | | | icon | 设置头像的自定义图标 | ReactNode | - | |
| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` | | | shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` | |
| size | 设置头像的大小 | number \| Enum{ 'large', 'small', 'default' } | `default` | | | size | 设置头像的大小 | number \| Enum{ 'large', 'small', 'default' } | `default` | |
| src | 图片类头像的资源地址 | string | - | | | src | 图片类头像的资源地址 | string | - | |
| srcSet | 设置图片类头像响应式资源地址 | string | - | 3.11.0 | | srcSet | 设置图片类头像响应式资源地址 | string | - | |
| alt | 图像无法显示时的替代文本 | string | - | 3.7.0 | | alt | 图像无法显示时的替代文本 | string | - | |
| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - | 3.8.0 | | onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - | |

View File

@ -4,7 +4,7 @@ exports[`renders ./components/back-top/demo/basic.md correctly 1`] = `
<div> <div>
Scroll down to see the bottom-right Scroll down to see the bottom-right
<strong <strong
style="color:rgba(64, 64, 64, 0.6)" class="site-back-top-basic"
> >
gray gray
</strong> </strong>

View File

@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BackTop rtl render component should be rendered correctly in RTL direction 1`] = `null`;

View File

@ -2,10 +2,12 @@ import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import { sleep } from '../../../tests/utils'; import { sleep } from '../../../tests/utils';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import BackTop from '..'; import BackTop from '..';
describe('BackTop', () => { describe('BackTop', () => {
mountTest(BackTop); mountTest(BackTop);
rtlTest(BackTop);
it('should scroll to top after click it', async () => { it('should scroll to top after click it', async () => {
const wrapper = mount(<BackTop visibilityHeight={-1} />); const wrapper = mount(<BackTop visibilityHeight={-1} />);

View File

@ -20,9 +20,21 @@ ReactDOM.render(
<div> <div>
<BackTop /> <BackTop />
Scroll down to see the bottom-right Scroll down to see the bottom-right
<strong style={{ color: 'rgba(64, 64, 64, 0.6)' }}> gray </strong> <strong className="site-back-top-basic"> gray </strong>
button. button.
</div>, </div>,
mountNode, mountNode,
); );
``` ```
```css
.site-back-top-basic {
color: rgba(64, 64, 64, 0.6);
}
```
<style>
[data-theme="dark"] .site-back-top-basic {
color: rgba(255,255,255,.45);
}
</style>

View File

@ -65,10 +65,12 @@ export default class BackTop extends React.Component<BackTopProps, any> {
}); });
}; };
renderBackTop = ({ getPrefixCls }: ConfigConsumerProps) => { renderBackTop = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, className = '', children } = this.props; const { prefixCls: customizePrefixCls, className = '', children } = this.props;
const prefixCls = getPrefixCls('back-top', customizePrefixCls); const prefixCls = getPrefixCls('back-top', customizePrefixCls);
const classString = classNames(prefixCls, className); const classString = classNames(prefixCls, className, {
[`${prefixCls}-rtl`]: direction === 'rtl',
});
const defaultElement = ( const defaultElement = (
<div className={`${prefixCls}-content`}> <div className={`${prefixCls}-content`}>

View File

@ -14,6 +14,11 @@
height: 40px; height: 40px;
cursor: pointer; cursor: pointer;
&-rtl {
right: auto;
left: 100px;
}
&-content { &-content {
width: 40px; width: 40px;
height: 40px; height: 40px;

View File

@ -1,7 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import omit from 'omit.js'; import omit from 'omit.js';
import classNames from 'classnames'; import classNames from 'classnames';
import { polyfill } from 'react-lifecycles-compat';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
function getNumberArray(num: string | number | undefined | null) { function getNumberArray(num: string | number | undefined | null) {
@ -208,6 +207,4 @@ class ScrollNumber extends React.Component<ScrollNumberProps, ScrollNumberState>
} }
} }
polyfill(ScrollNumber);
export default ScrollNumber; export default ScrollNumber;

View File

@ -193,9 +193,10 @@ exports[`renders ./components/badge/demo/basic.md correctly 1`] = `
class="head-example" class="head-example"
href="#" href="#"
/> />
<i <span
aria-label="icon: clock-circle" aria-label="clock-circle"
class="anticon anticon-clock-circle ant-scroll-number-custom-component" class="anticon anticon-clock-circle ant-scroll-number-custom-component"
role="img"
style="color:#f5222d" style="color:#f5222d"
> >
<svg <svg
@ -215,7 +216,7 @@ exports[`renders ./components/badge/demo/basic.md correctly 1`] = `
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z" d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
</div> </div>
`; `;
@ -399,9 +400,10 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: minus" aria-label="minus"
class="anticon anticon-minus" class="anticon anticon-minus"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -417,15 +419,16 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
d="M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z" d="M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: plus" aria-label="plus"
class="anticon anticon-plus" class="anticon anticon-plus"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -437,6 +440,7 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
viewBox="64 64 896 896" viewBox="64 64 896 896"
width="1em" width="1em"
> >
<defs />
<path <path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z" d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/> />
@ -444,7 +448,7 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z" d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
</div> </div>
</div> </div>
@ -739,9 +743,10 @@ exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
<span <span
class="ant-badge" class="ant-badge"
> >
<i <span
aria-label="icon: notification" aria-label="notification"
class="anticon anticon-notification" class="anticon anticon-notification"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -757,7 +762,7 @@ exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
d="M880 112c-3.8 0-7.7.7-11.6 2.3L292 345.9H128c-8.8 0-16 7.4-16 16.6v299c0 9.2 7.2 16.6 16 16.6h101.7c-3.7 11.6-5.7 23.9-5.7 36.4 0 65.9 53.8 119.5 120 119.5 55.4 0 102.1-37.6 115.9-88.4l408.6 164.2c3.9 1.5 7.8 2.3 11.6 2.3 16.9 0 32-14.2 32-33.2V145.2C912 126.2 897 112 880 112zM344 762.3c-26.5 0-48-21.4-48-47.8 0-11.2 3.9-21.9 11-30.4l84.9 34.1c-2 24.6-22.7 44.1-47.9 44.1zm496 58.4L318.8 611.3l-12.9-5.2H184V417.9h121.9l12.9-5.2L840 203.3v617.4z" d="M880 112c-3.8 0-7.7.7-11.6 2.3L292 345.9H128c-8.8 0-16 7.4-16 16.6v299c0 9.2 7.2 16.6 16 16.6h101.7c-3.7 11.6-5.7 23.9-5.7 36.4 0 65.9 53.8 119.5 120 119.5 55.4 0 102.1-37.6 115.9-88.4l408.6 164.2c3.9 1.5 7.8 2.3 11.6 2.3 16.9 0 32-14.2 32-33.2V145.2C912 126.2 897 112 880 112zM344 762.3c-26.5 0-48-21.4-48-47.8 0-11.2 3.9-21.9 11-30.4l84.9 34.1c-2 24.6-22.7 44.1-47.9 44.1zm496 58.4L318.8 611.3l-12.9-5.2H184V417.9h121.9l12.9-5.2L840 203.3v617.4z"
/> />
</svg> </svg>
</i> </span>
<sup <sup
class="ant-scroll-number ant-badge-dot" class="ant-scroll-number ant-badge-dot"
data-show="true" data-show="true"
@ -766,9 +771,10 @@ exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
<span <span
class="ant-badge" class="ant-badge"
> >
<i <span
aria-label="icon: notification" aria-label="notification"
class="anticon anticon-notification" class="anticon anticon-notification"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -784,7 +790,7 @@ exports[`renders ./components/badge/demo/dot.md correctly 1`] = `
d="M880 112c-3.8 0-7.7.7-11.6 2.3L292 345.9H128c-8.8 0-16 7.4-16 16.6v299c0 9.2 7.2 16.6 16 16.6h101.7c-3.7 11.6-5.7 23.9-5.7 36.4 0 65.9 53.8 119.5 120 119.5 55.4 0 102.1-37.6 115.9-88.4l408.6 164.2c3.9 1.5 7.8 2.3 11.6 2.3 16.9 0 32-14.2 32-33.2V145.2C912 126.2 897 112 880 112zM344 762.3c-26.5 0-48-21.4-48-47.8 0-11.2 3.9-21.9 11-30.4l84.9 34.1c-2 24.6-22.7 44.1-47.9 44.1zm496 58.4L318.8 611.3l-12.9-5.2H184V417.9h121.9l12.9-5.2L840 203.3v617.4z" d="M880 112c-3.8 0-7.7.7-11.6 2.3L292 345.9H128c-8.8 0-16 7.4-16 16.6v299c0 9.2 7.2 16.6 16 16.6h101.7c-3.7 11.6-5.7 23.9-5.7 36.4 0 65.9 53.8 119.5 120 119.5 55.4 0 102.1-37.6 115.9-88.4l408.6 164.2c3.9 1.5 7.8 2.3 11.6 2.3 16.9 0 32-14.2 32-33.2V145.2C912 126.2 897 112 880 112zM344 762.3c-26.5 0-48-21.4-48-47.8 0-11.2 3.9-21.9 11-30.4l84.9 34.1c-2 24.6-22.7 44.1-47.9 44.1zm496 58.4L318.8 611.3l-12.9-5.2H184V417.9h121.9l12.9-5.2L840 203.3v617.4z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-badge" class="ant-badge"
@ -1300,12 +1306,11 @@ exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `
</sup> </sup>
</span> </span>
<span <span
class="ant-badge ant-badge-not-a-wrapper" class="site-badge-count-4 ant-badge ant-badge-not-a-wrapper"
> >
<sup <sup
class="ant-scroll-number ant-badge-count" class="ant-scroll-number ant-badge-count"
data-show="true" data-show="true"
style="background-color:#fff;color:#999;box-shadow:0 0 0 1px #d9d9d9 inset"
title="4" title="4"
> >
<span <span
@ -1466,7 +1471,7 @@ exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `
</sup> </sup>
</span> </span>
<span <span
class="ant-badge ant-badge-not-a-wrapper" class="site-badge-count-109 ant-badge ant-badge-not-a-wrapper"
> >
<sup <sup
class="ant-scroll-number ant-badge-count ant-badge-multiple-words" class="ant-scroll-number ant-badge-count ant-badge-multiple-words"

View File

@ -724,6 +724,12 @@ exports[`Badge render correct with negative number 1`] = `
</div> </div>
`; `;
exports[`Badge rtl render component should be rendered correctly in RTL direction 1`] = `
<span
class="ant-badge ant-badge-not-a-wrapper ant-badge-rtl"
/>
`;
exports[`Badge should be compatible with borderColor style 1`] = ` exports[`Badge should be compatible with borderColor style 1`] = `
<span <span
class="ant-badge ant-badge-not-a-wrapper" class="ant-badge ant-badge-not-a-wrapper"

View File

@ -3,9 +3,11 @@ import { mount, render } from 'enzyme';
import Badge from '../index'; import Badge from '../index';
import Tooltip from '../../tooltip'; import Tooltip from '../../tooltip';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
describe('Badge', () => { describe('Badge', () => {
mountTest(Badge); mountTest(Badge);
rtlTest(Badge);
beforeEach(() => { beforeEach(() => {
jest.useFakeTimers(); jest.useFakeTimers();

View File

@ -14,7 +14,8 @@ title:
Simplest Usage. Badge will be hidden when `count` is `0`, but we can use `showZero` to show it. Simplest Usage. Badge will be hidden when `count` is `0`, but we can use `showZero` to show it.
```jsx ```jsx
import { Badge, Icon } from 'antd'; import { Badge } from 'antd';
import { ClockCircleOutlined } from '@ant-design/icons';
ReactDOM.render( ReactDOM.render(
<div> <div>
@ -24,7 +25,7 @@ ReactDOM.render(
<Badge count={0} showZero> <Badge count={0} showZero>
<a href="#" className="head-example" /> <a href="#" className="head-example" />
</Badge> </Badge>
<Badge count={<Icon type="clock-circle" style={{ color: '#f5222d' }} />}> <Badge count={<ClockCircleOutlined style={{ color: '#f5222d' }} />}>
<a href="#" className="head-example" /> <a href="#" className="head-example" />
</Badge> </Badge>
</div>, </div>,
@ -36,12 +37,19 @@ ReactDOM.render(
.ant-badge:not(.ant-badge-not-a-wrapper) { .ant-badge:not(.ant-badge-not-a-wrapper) {
margin-right: 20px; margin-right: 20px;
} }
.ant-badge.ant-badge-rtl:not(.ant-badge-not-a-wrapper) {
margin-right: 0;
margin-left: 20px;
}
.head-example { .head-example {
width: 42px; width: 42px;
height: 42px; height: 42px;
border-radius: 4px; border-radius: 2px;
background: #eee; background: #eee;
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
} }
[data-theme="dark"] .head-example {
background: rgba(255,255,255,.12);
}
</style> </style>

View File

@ -14,7 +14,8 @@ title:
The count will be animated as it changes. The count will be animated as it changes.
```jsx ```jsx
import { Badge, Button, Icon, Switch } from 'antd'; import { Badge, Button, Switch } from 'antd';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
const ButtonGroup = Button.Group; const ButtonGroup = Button.Group;
@ -50,10 +51,10 @@ class Demo extends React.Component {
</Badge> </Badge>
<ButtonGroup> <ButtonGroup>
<Button onClick={this.decline}> <Button onClick={this.decline}>
<Icon type="minus" /> <MinusOutlined />
</Button> </Button>
<Button onClick={this.increase}> <Button onClick={this.increase}>
<Icon type="plus" /> <PlusOutlined />
</Button> </Button>
</ButtonGroup> </ButtonGroup>
</div> </div>

View File

@ -14,15 +14,16 @@ title:
This will simply display a red badge, without a specific count. If count equals 0, it won't display the dot. This will simply display a red badge, without a specific count. If count equals 0, it won't display the dot.
```jsx ```jsx
import { Badge, Icon } from 'antd'; import { Badge } from 'antd';
import { NotificationOutlined } from '@ant-design/icons';
ReactDOM.render( ReactDOM.render(
<div> <div>
<Badge dot> <Badge dot>
<Icon type="notification" /> <NotificationOutlined />
</Badge> </Badge>
<Badge count={0} dot> <Badge count={0} dot>
<Icon type="notification" /> <NotificationOutlined />
</Badge> </Badge>
<Badge dot> <Badge dot>
<a href="#">Link something</a> <a href="#">Link something</a>

View File

@ -21,18 +21,31 @@ import { Badge } from 'antd';
ReactDOM.render( ReactDOM.render(
<div> <div>
<Badge count={25} /> <Badge count={25} />
<Badge <Badge count={4} className="site-badge-count-4" />
count={4} <Badge className="site-badge-count-109" count={109} style={{ backgroundColor: '#52c41a' }} />
style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset' }}
/>
<Badge count={109} style={{ backgroundColor: '#52c41a' }} />
</div>, </div>,
mountNode, mountNode,
); );
``` ```
```css
.site-badge-count-4 .ant-badge-count {
background-color: #fff;
color: #999;
box-shadow: 0 0 0 1px #d9d9d9 inset;
}
```
<style> <style>
.ant-badge-not-a-wrapper:not(.ant-badge-status) { .ant-badge-not-a-wrapper:not(.ant-badge-status) {
margin-right: 8px; margin-right: 8px;
} }
.ant-badge.ant-badge-rtl:not(.ant-badge-not-a-wrapper) {
margin-right: 0;
margin-left: 20px;
}
[data-theme="dark"] .site-badge-count-4 .ant-badge-count {
background-color: #141414;
box-shadow: 0 0 0 1px #434343 inset;
}
</style> </style>

View File

@ -31,11 +31,20 @@ ReactDOM.render(
.ant-badge:not(.ant-badge-not-a-wrapper) { .ant-badge:not(.ant-badge-not-a-wrapper) {
margin-right: 20px; margin-right: 20px;
} }
.ant-badge.ant-badge-rtl:not(.ant-badge-not-a-wrapper) {
margin-right: 0;
margin-left: 20px;
}
.head-example { .head-example {
width: 42px; width: 42px;
height: 42px; height: 42px;
border-radius: 4px; border-radius: 2px;
background: #eee; background: #eee;
display: inline-block; display: inline-block;
} }
[data-theme="dark"] .head-example {
background: rgba(255,255,255,.12);
}
</style> </style>

View File

@ -24,7 +24,7 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
| Property | Description | Type | Default | Version | | Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| color | Customize Badge dot color | string | - | 3.16.0 | | color | Customize Badge dot color | string | - | |
| count | Number to show in badge | ReactNode | | | | count | Number to show in badge | ReactNode | | |
| dot | Whether to display a red dot instead of `count` | boolean | `false` | | | dot | Whether to display a red dot instead of `count` | boolean | `false` | |
| offset | set offset of the badge dot, like`[x, y]` | `[number, number]` | - | | | offset | set offset of the badge dot, like`[x, y]` | `[number, number]` | - | |
@ -32,4 +32,4 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
| showZero | Whether to show badge when `count` is zero | boolean | `false` | | | showZero | Whether to show badge when `count` is zero | boolean | `false` | |
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` | | | status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` | |
| text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` | | | text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` | |
| title | Text to show when hovering over the badge | string | `count` | 3.5.0 | | title | Text to show when hovering over the badge | string | `count` | |

View File

@ -1,5 +1,4 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types';
import Animate from 'rc-animate'; import Animate from 'rc-animate';
import omit from 'omit.js'; import omit from 'omit.js';
import classNames from 'classnames'; import classNames from 'classnames';
@ -40,13 +39,6 @@ export default class Badge extends React.Component<BadgeProps, any> {
overflowCount: 99, overflowCount: 99,
}; };
static propTypes = {
count: PropTypes.node,
showZero: PropTypes.bool,
dot: PropTypes.bool,
overflowCount: PropTypes.number,
};
getNumberedDispayCount() { getNumberedDispayCount() {
const { count, overflowCount } = this.props; const { count, overflowCount } = this.props;
const displayCount = const displayCount =
@ -82,11 +74,12 @@ export default class Badge extends React.Component<BadgeProps, any> {
: style; : style;
} }
getBadgeClassName(prefixCls: string) { getBadgeClassName(prefixCls: string, direction: string = 'ltr') {
const { className, children } = this.props; const { className, children } = this.props;
return classNames(className, prefixCls, { return classNames(className, prefixCls, {
[`${prefixCls}-status`]: this.hasStatus(), [`${prefixCls}-status`]: this.hasStatus(),
[`${prefixCls}-not-a-wrapper`]: !children, [`${prefixCls}-not-a-wrapper`]: !children,
[`${prefixCls}-rtl`]: direction === 'rtl',
}) as string; }) as string;
} }
@ -164,7 +157,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
); );
} }
renderBadge = ({ getPrefixCls }: ConfigConsumerProps) => { renderBadge = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
scrollNumberPrefixCls: customizeScrollNumberPrefixCls, scrollNumberPrefixCls: customizeScrollNumberPrefixCls,
@ -208,7 +201,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
return ( return (
<span <span
{...omit(restProps, omitArr)} {...omit(restProps, omitArr)}
className={this.getBadgeClassName(prefixCls)} className={this.getBadgeClassName(prefixCls, direction)}
style={styleWithOffset} style={styleWithOffset}
> >
<span className={statusCls} style={statusStyle} /> <span className={statusCls} style={statusStyle} />
@ -220,7 +213,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
} }
return ( return (
<span {...omit(restProps, omitArr)} className={this.getBadgeClassName(prefixCls)}> <span {...omit(restProps, omitArr)} className={this.getBadgeClassName(prefixCls, direction)}>
{children} {children}
<Animate <Animate
component="" component=""

View File

@ -25,7 +25,7 @@ title: Badge
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| color | 自定义小圆点的颜色 | string | - | 3.16.0 | | color | 自定义小圆点的颜色 | string | - | |
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | ReactNode | | | | count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | ReactNode | | |
| dot | 不展示数字,只有一个小红点 | boolean | false | | | dot | 不展示数字,只有一个小红点 | boolean | false | |
| offset | 设置状态点的位置偏移,格式为 `[x, y]` | `[number, number]` | - | | | offset | 设置状态点的位置偏移,格式为 `[x, y]` | `[number, number]` | - | |
@ -33,4 +33,4 @@ title: Badge
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false | | | showZero | 当数值为 0 时,是否展示 Badge | boolean | false | |
| status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' | | | status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' | |
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' | | | text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' | |
| title | 设置鼠标放在状态点上时显示的文字 | string | `count` | 3.5.0 | | title | 设置鼠标放在状态点上时显示的文字 | string | `count` | |

View File

@ -12,6 +12,10 @@
color: unset; color: unset;
line-height: 1; line-height: 1;
&-rtl {
direction: rtl;
}
&-count { &-count {
z-index: @zindex-badge; z-index: @zindex-badge;
min-width: @badge-height; min-width: @badge-height;
@ -53,6 +57,20 @@
right: 0; right: 0;
transform: translate(50%, -50%); transform: translate(50%, -50%);
transform-origin: 100% 0%; transform-origin: 100% 0%;
.@{badge-prefix-cls}-rtl & {
right: auto;
left: 0;
transform: translate(-50%, -50%);
transform-origin: 0% 0%;
}
}
.@{badge-prefix-cls}-rtl& .@{number-prefix-cls}-custom-component {
right: auto;
left: 0;
transform: translate(-50%, -50%);
transform-origin: 0% 0%;
} }
&-status { &-status {
@ -111,6 +129,11 @@
margin-left: 8px; margin-left: 8px;
color: @text-color; color: @text-color;
font-size: @font-size-base; font-size: @font-size-base;
.@{badge-prefix-cls}-rtl & {
margin-right: 8px;
margin-left: 0;
}
} }
} }
@ -118,11 +141,19 @@
&-zoom-enter { &-zoom-enter {
animation: antZoomBadgeIn 0.3s @ease-out-back; animation: antZoomBadgeIn 0.3s @ease-out-back;
animation-fill-mode: both; animation-fill-mode: both;
.@{badge-prefix-cls}-rtl & {
animation-name: antZoomBadgeInRtl;
}
} }
&-zoom-leave { &-zoom-leave {
animation: antZoomBadgeOut 0.3s @ease-in-back; animation: antZoomBadgeOut 0.3s @ease-in-back;
animation-fill-mode: both; animation-fill-mode: both;
.@{badge-prefix-cls}-rtl & {
animation-name: antZoomBadgeOutRtl;
}
} }
&-not-a-wrapper { &-not-a-wrapper {
@ -189,3 +220,23 @@
opacity: 0; opacity: 0;
} }
} }
@keyframes antZoomBadgeInRtl {
0% {
transform: scale(0) translate(-50%, -50%);
opacity: 0;
}
100% {
transform: scale(1) translate(-50%, -50%);
}
}
@keyframes antZoomBadgeOutRtl {
0% {
transform: scale(1) translate(-50%, -50%);
}
100% {
transform: scale(0) translate(-50%, -50%);
opacity: 0;
}
}

View File

@ -1,5 +1,4 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray'; import toArray from 'rc-util/lib/Children/toArray';
import omit from 'omit.js'; import omit from 'omit.js';
@ -68,22 +67,6 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
separator: '/', separator: '/',
}; };
static propTypes = {
prefixCls: PropTypes.string,
separator: PropTypes.node,
routes: PropTypes.array,
};
componentDidMount() {
const { props } = this;
warning(
!('linkRender' in props || 'nameRender' in props),
'Breadcrumb',
'`linkRender` and `nameRender` are removed, please use `itemRender` instead, ' +
'see: https://u.ant.design/item-render.',
);
}
getPath = (path: string, params: any) => { getPath = (path: string, params: any) => {
path = (path || '').replace(/^\//, ''); path = (path || '').replace(/^\//, '');
Object.keys(params).forEach(key => { Object.keys(params).forEach(key => {
@ -115,7 +98,7 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
paths.push(path); paths.push(path);
} }
// generated overlay by route.children // generated overlay by route.children
let overlay = null; let overlay;
if (route.children && route.children.length) { if (route.children && route.children.length) {
overlay = ( overlay = (
<Menu> <Menu>
@ -175,7 +158,7 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
<div <div
className={classNames(className, prefixCls)} className={classNames(className, prefixCls)}
style={style} style={style}
{...omit(restProps, ['itemRender', 'params'])} {...omit(restProps, ['itemRender', 'linkRender', 'nameRender', 'params'])}
> >
{crumbs} {crumbs}
</div> </div>

View File

@ -1,8 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types'; import { DownOutlined } from '@ant-design/icons';
import omit from 'omit.js'; import omit from 'omit.js';
import DropDown, { DropDownProps } from '../dropdown/dropdown'; import DropDown, { DropDownProps } from '../dropdown/dropdown';
import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
export interface BreadcrumbItemProps { export interface BreadcrumbItemProps {
@ -20,12 +20,6 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
separator: '/', separator: '/',
}; };
static propTypes = {
prefixCls: PropTypes.string,
separator: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
href: PropTypes.string,
};
renderBreadcrumbItem = ({ getPrefixCls }: ConfigConsumerProps) => { renderBreadcrumbItem = ({ getPrefixCls }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, separator, children, ...restProps } = this.props; const { prefixCls: customizePrefixCls, separator, children, ...restProps } = this.props;
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls); const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
@ -70,7 +64,7 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
<DropDown overlay={overlay} placement="bottomCenter"> <DropDown overlay={overlay} placement="bottomCenter">
<span className={`${prefixCls}-overlay-link`}> <span className={`${prefixCls}-overlay-link`}>
{breadcrumbItem} {breadcrumbItem}
<Icon type="down" /> <DownOutlined />
</span> </span>
</DropDown> </DropDown>
); );

View File

@ -2,9 +2,11 @@ import React from 'react';
import { mount, render } from 'enzyme'; import { mount, render } from 'enzyme';
import Breadcrumb from '../index'; import Breadcrumb from '../index';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
describe('Breadcrumb', () => { describe('Breadcrumb', () => {
mountTest(Breadcrumb); mountTest(Breadcrumb);
rtlTest(Breadcrumb);
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@ -103,6 +105,21 @@ describe('Breadcrumb', () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it('props#linkRender and props#nameRender do not warn anymore', () => {
const linkRender = jest.fn();
const nameRender = jest.fn();
mount(
<Breadcrumb linkRender={linkRender} nameRender={nameRender}>
<Breadcrumb.Item />
<Breadcrumb.Item>xxx</Breadcrumb.Item>
</Breadcrumb>,
);
expect(errorSpy.mock.calls.length).toBe(0);
expect(linkRender).not.toHaveBeenCalled();
expect(nameRender).not.toHaveBeenCalled();
});
it('should support custom attribute', () => { it('should support custom attribute', () => {
const wrapper = render( const wrapper = render(
<Breadcrumb data-custom="custom"> <Breadcrumb data-custom="custom">

View File

@ -32,6 +32,12 @@ exports[`Breadcrumb filter React.Fragment 1`] = `
</div> </div>
`; `;
exports[`Breadcrumb rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-breadcrumb"
/>
`;
exports[`Breadcrumb should allow Breadcrumb.Item is null or undefined 1`] = ` exports[`Breadcrumb should allow Breadcrumb.Item is null or undefined 1`] = `
<div <div
class="ant-breadcrumb" class="ant-breadcrumb"
@ -115,9 +121,10 @@ exports[`Breadcrumb should render a menu 1`] = `
first first
</a> </a>
</span> </span>
<i <span
aria-label="icon: down" aria-label="down"
class="anticon anticon-down" class="anticon anticon-down"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -133,7 +140,7 @@ exports[`Breadcrumb should render a menu 1`] = `
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z" d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-breadcrumb-separator" class="ant-breadcrumb-separator"

View File

@ -108,9 +108,10 @@ exports[`renders ./components/breadcrumb/demo/overlay.md correctly 1`] = `
General General
</a> </a>
</span> </span>
<i <span
aria-label="icon: down" aria-label="down"
class="anticon anticon-down" class="anticon anticon-down"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -126,7 +127,7 @@ exports[`renders ./components/breadcrumb/demo/overlay.md correctly 1`] = `
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z" d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/> />
</svg> </svg>
</i> </span>
</span> </span>
<span <span
class="ant-breadcrumb-separator" class="ant-breadcrumb-separator"
@ -267,9 +268,10 @@ exports[`renders ./components/breadcrumb/demo/withIcon.md correctly 1`] = `
class="ant-breadcrumb-link" class="ant-breadcrumb-link"
href="" href=""
> >
<i <span
aria-label="icon: home" aria-label="home"
class="anticon anticon-home" class="anticon anticon-home"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -282,10 +284,10 @@ exports[`renders ./components/breadcrumb/demo/withIcon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M946.5 505L560.1 118.8l-25.9-25.9a31.5 31.5 0 0 0-44.4 0L77.5 505a63.9 63.9 0 0 0-18.8 46c.4 35.2 29.7 63.3 64.9 63.3h42.5V940h691.8V614.3h43.4c17.1 0 33.2-6.7 45.3-18.8a63.6 63.6 0 0 0 18.7-45.3c0-17-6.7-33.1-18.8-45.2zM568 868H456V664h112v204zm217.9-325.7V868H632V640c0-22.1-17.9-40-40-40H432c-22.1 0-40 17.9-40 40v228H238.1V542.3h-96l370-369.7 23.1 23.1L882 542.3h-96.1z" d="M946.5 505L560.1 118.8l-25.9-25.9a31.5 31.5 0 00-44.4 0L77.5 505a63.9 63.9 0 00-18.8 46c.4 35.2 29.7 63.3 64.9 63.3h42.5V940h691.8V614.3h43.4c17.1 0 33.2-6.7 45.3-18.8a63.6 63.6 0 0018.7-45.3c0-17-6.7-33.1-18.8-45.2zM568 868H456V664h112v204zm217.9-325.7V868H632V640c0-22.1-17.9-40-40-40H432c-22.1 0-40 17.9-40 40v228H238.1V542.3h-96l370-369.7 23.1 23.1L882 542.3h-96.1z"
/> />
</svg> </svg>
</i> </span>
</a> </a>
<span <span
class="ant-breadcrumb-separator" class="ant-breadcrumb-separator"
@ -298,9 +300,10 @@ exports[`renders ./components/breadcrumb/demo/withIcon.md correctly 1`] = `
class="ant-breadcrumb-link" class="ant-breadcrumb-link"
href="" href=""
> >
<i <span
aria-label="icon: user" aria-label="user"
class="anticon anticon-user" class="anticon anticon-user"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -313,10 +316,10 @@ exports[`renders ./components/breadcrumb/demo/withIcon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z" d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Application List Application List
</span> </span>

View File

@ -80,7 +80,6 @@ exports[`react router react router 3 1`] = `
> >
<BreadcrumbItem <BreadcrumbItem
key="Home" key="Home"
overlay={null}
separator="/" separator="/"
> >
<span> <span>
@ -102,7 +101,6 @@ exports[`react router react router 3 1`] = `
</BreadcrumbItem> </BreadcrumbItem>
<BreadcrumbItem <BreadcrumbItem
key="Application List" key="Application List"
overlay={null}
separator="/" separator="/"
> >
<span> <span>
@ -124,7 +122,6 @@ exports[`react router react router 3 1`] = `
</BreadcrumbItem> </BreadcrumbItem>
<BreadcrumbItem <BreadcrumbItem
key="Application:id" key="Application:id"
overlay={null}
separator="/" separator="/"
> >
<span> <span>
@ -146,7 +143,6 @@ exports[`react router react router 3 1`] = `
</BreadcrumbItem> </BreadcrumbItem>
<BreadcrumbItem <BreadcrumbItem
key="Detail" key="Detail"
overlay={null}
separator="/" separator="/"
> >
<span> <span>

View File

@ -95,3 +95,9 @@ ReactDOM.render(
margin-top: 16px; margin-top: 16px;
} }
``` ```
<style>
[data-theme="dark"] .demo-nav {
background: #141414;
}
</style>

View File

@ -74,3 +74,9 @@ ReactDOM.render(
margin-top: 16px; margin-top: 16px;
} }
``` ```
<style>
[data-theme="dark"] .demo-nav {
background: #141414;
}
</style>

View File

@ -14,15 +14,16 @@ title:
The icon should be placed in front of the text. The icon should be placed in front of the text.
```jsx ```jsx
import { Breadcrumb, Icon } from 'antd'; import { Breadcrumb } from 'antd';
import { HomeOutlined, UserOutlined } from '@ant-design/icons';
ReactDOM.render( ReactDOM.render(
<Breadcrumb> <Breadcrumb>
<Breadcrumb.Item href=""> <Breadcrumb.Item href="">
<Icon type="home" /> <HomeOutlined />
</Breadcrumb.Item> </Breadcrumb.Item>
<Breadcrumb.Item href=""> <Breadcrumb.Item href="">
<Icon type="user" /> <UserOutlined />
<span>Application List</span> <span>Application List</span>
</Breadcrumb.Item> </Breadcrumb.Item>
<Breadcrumb.Item>Application</Breadcrumb.Item> <Breadcrumb.Item>Application</Breadcrumb.Item>

View File

@ -11,16 +11,46 @@ A breadcrumb displays the current location within a hierarchy. It allows going b
- When the system has more than two layers in a hierarchy. - When the system has more than two layers in a hierarchy.
- When you need to inform the user of where they are. - When you need to inform the user of where they are.
- When the user may need to navigate back to a higher level. - When the user may need to navigate back to a higher level.
- When the application has multi-layer architecture.
## API ## API
| Property | Description | Type | Optional | Default | Version | ### Breadcrumb
| --- | --- | --- | --- | --- | --- |
| itemRender | Custom item renderer | (route, params, routes, paths) => ReactNode | | - | | | Property | Description | Type | Default | Version |
| params | Routing parameters | object | | - | | | --- | --- | --- | --- | --- |
| routes | The routing stack information of router | [routes\[\]](#routes) | | - | | | itemRender | Custom item renderer | (route, params, routes, paths) => ReactNode | - | |
| separator | Custom separator | string\|ReactNode | | `/` | | | params | Routing parameters | object | - | |
| routes | The routing stack information of router | [routes\[\]](#routes) | - | |
| separator | Custom separator | string\|ReactNode | '/' | |
### Breadcrumb.Item
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| href | Target of hyperlink | string | - | |
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
| onClick | Set the handler to handle `click` event | (e:MouseEvent)=>void | - | |
### Breadcrumb.Separator
| Property | Description | Type | Default | Version |
| -------- | ---------------- | ----------------- | ------- | ------- |
| children | Custom separator | string\|ReactNode | '/' | |
> When using `Breadcrumb.Separator`,its parent component must be set to `separator=""`, otherwise the default separator of the parent component will appear.
### routes
```ts
interface Route {
path: string;
breadcrumbName: string;
children: Array<{
path: string;
breadcrumbName: string;
}>;
}
```
### Use with browserHistory ### Use with browserHistory

View File

@ -19,24 +19,24 @@ title: Breadcrumb
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| itemRender | 自定义链接函数,和 react-router 配置使用 | (route, params, routes, paths) => ReactNode | - | 3.17.0 | | itemRender | 自定义链接函数,和 react-router 配置使用 | (route, params, routes, paths) => ReactNode | - | |
| params | 路由的参数 | object | - | 3.17.0 | | params | 路由的参数 | object | - | |
| routes | router 的路由栈信息 | [routes\[\]](#routes) | - | 3.17.0 | | routes | router 的路由栈信息 | [routes\[\]](#routes) | - | |
| separator | 分隔符自定义 | string\|ReactNode | '/' | 3.17.0 | | separator | 分隔符自定义 | string\|ReactNode | '/' | |
### Breadcrumb.Item ### Breadcrumb.Item
| 参数 | 参数 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------- | -------------- | -------------------------------------- | ------ | ------ | | ------- | -------------- | -------------------------------------- | ------ | ------ |
| href | 链接的目的地 | string | - | 3.17.0 | | href | 链接的目的地 | string | - | |
| overlay | 下拉菜单的内容 | [Menu](/components/menu) \| () => Menu | - | 3.17.0 | | overlay | 下拉菜单的内容 | [Menu](/components/menu) \| () => Menu | - | |
| onClick | 单击事件 | (e:MouseEvent)=>void | - | 3.17.0 | | onClick | 单击事件 | (e:MouseEvent)=>void | - | |
### Breadcrumb.Separator `3.21.0` ### Breadcrumb.Separator
| 参数 | 参数 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| -------- | -------------- | ----------------- | ------ | ------ | | -------- | -------------- | ----------------- | ------ | ------ |
| children | 要显示的分隔符 | string\|ReactNode | '/' | 3.21.0 | | children | 要显示的分隔符 | string\|ReactNode | '/' | |
> 注意:在使用 `Breadcrumb.Separator` 时,其父组件的分隔符必须设置为 `separator=""`,否则会出现父组件默认的分隔符。 > 注意:在使用 `Breadcrumb.Separator` 时,其父组件的分隔符必须设置为 `separator=""`,否则会出现父组件默认的分隔符。

View File

@ -27,13 +27,29 @@ exports[`renders ./components/button/demo/basic.md correctly 1`] = `
</span> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-danger" class="ant-btn ant-btn-primary ant-btn-dangerous"
type="button" type="button"
> >
<span> <span>
Danger Danger
</span> </span>
</button> </button>
<button
class="ant-btn ant-btn-dangerous"
type="button"
>
<span>
Danger Default
</span>
</button>
<button
class="ant-btn ant-btn-link ant-btn-dangerous"
type="button"
>
<span>
Danger Link
</span>
</button>
<button <button
class="ant-btn ant-btn-link" class="ant-btn ant-btn-link"
type="button" type="button"
@ -72,13 +88,29 @@ exports[`renders ./components/button/demo/block.md correctly 1`] = `
</span> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-danger ant-btn-block" class="ant-btn ant-btn-primary ant-btn-block ant-btn-dangerous"
type="button" type="button"
> >
<span> <span>
Danger Danger
</span> </span>
</button> </button>
<button
class="ant-btn ant-btn-block ant-btn-dangerous"
type="button"
>
<span>
Danger Default
</span>
</button>
<button
class="ant-btn ant-btn-link ant-btn-block ant-btn-dangerous"
type="button"
>
<span>
Danger Link
</span>
</button>
<button <button
class="ant-btn ant-btn-link ant-btn-block" class="ant-btn ant-btn-link ant-btn-block"
type="button" type="button"
@ -90,264 +122,6 @@ exports[`renders ./components/button/demo/block.md correctly 1`] = `
</div> </div>
`; `;
exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
<div>
<h4>
Basic
</h4>
<div
class="ant-btn-group"
>
<button
class="ant-btn"
type="button"
>
<span>
Cancel
</span>
</button>
<button
class="ant-btn"
type="button"
>
<span>
OK
</span>
</button>
</div>
<div
class="ant-btn-group"
>
<button
class="ant-btn"
disabled=""
type="button"
>
<span>
L
</span>
</button>
<button
class="ant-btn"
disabled=""
type="button"
>
<span>
M
</span>
</button>
<button
class="ant-btn"
disabled=""
type="button"
>
<span>
R
</span>
</button>
</div>
<div
class="ant-btn-group"
>
<button
class="ant-btn"
type="button"
>
<span>
L
</span>
</button>
<button
class="ant-btn"
type="button"
>
<span>
M
</span>
</button>
<button
class="ant-btn"
type="button"
>
<span>
R
</span>
</button>
</div>
<h4>
With Icon
</h4>
<div
class="ant-btn-group"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
<span>
Go back
</span>
</button>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Go forward
</span>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
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"
/>
</svg>
</i>
</button>
</div>
<div
class="ant-btn-group"
>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
type="button"
>
<i
aria-label="icon: cloud"
class="anticon anticon-cloud"
>
<svg
aria-hidden="true"
class=""
data-icon="cloud"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M811.4 418.7C765.6 297.9 648.9 212 512.2 212S258.8 297.8 213 418.6C127.3 441.1 64 519.1 64 612c0 110.5 89.5 200 199.9 200h496.2C870.5 812 960 722.5 960 612c0-92.7-63.1-170.7-148.6-193.3zm36.3 281a123.07 123.07 0 0 1-87.6 36.3H263.9c-33.1 0-64.2-12.9-87.6-36.3A123.3 123.3 0 0 1 140 612c0-28 9.1-54.3 26.2-76.3a125.7 125.7 0 0 1 66.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4a245.6 245.6 0 0 1 52.4-49.9c41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10c54.3 14.5 92.1 63.8 92.1 120 0 33.1-12.9 64.3-36.3 87.7z"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
type="button"
>
<i
aria-label="icon: cloud-download"
class="anticon anticon-cloud-download"
>
<svg
aria-hidden="true"
class=""
data-icon="cloud-download"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M624 706.3h-74.1V464c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v242.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.7a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9z"
/>
<path
d="M811.4 366.7C765.6 245.9 648.9 160 512.2 160S258.8 245.8 213 366.6C127.3 389.1 64 467.2 64 560c0 110.5 89.5 200 199.9 200H304c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8h-40.1c-33.7 0-65.4-13.4-89-37.7-23.5-24.2-36-56.8-34.9-90.6.9-26.4 9.9-51.2 26.2-72.1 16.7-21.3 40.1-36.8 66.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4a245.6 245.6 0 0 1 52.4-49.9c41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10C846.1 454.5 884 503.8 884 560c0 33.1-12.9 64.3-36.3 87.7a123.07 123.07 0 0 1-87.6 36.3H720c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h40.1C870.5 760 960 670.5 960 560c0-92.7-63.1-170.7-148.6-193.3z"
/>
</svg>
</i>
</button>
</div>
<div
class="ant-btn-group"
>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<i
aria-label="icon: cloud"
class="anticon anticon-cloud"
>
<svg
aria-hidden="true"
class=""
data-icon="cloud"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M811.4 418.7C765.6 297.9 648.9 212 512.2 212S258.8 297.8 213 418.6C127.3 441.1 64 519.1 64 612c0 110.5 89.5 200 199.9 200h496.2C870.5 812 960 722.5 960 612c0-92.7-63.1-170.7-148.6-193.3zm36.3 281a123.07 123.07 0 0 1-87.6 36.3H263.9c-33.1 0-64.2-12.9-87.6-36.3A123.3 123.3 0 0 1 140 612c0-28 9.1-54.3 26.2-76.3a125.7 125.7 0 0 1 66.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4a245.6 245.6 0 0 1 52.4-49.9c41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10c54.3 14.5 92.1 63.8 92.1 120 0 33.1-12.9 64.3-36.3 87.7z"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<i
aria-label="icon: cloud-download"
class="anticon anticon-cloud-download"
>
<svg
aria-hidden="true"
class=""
data-icon="cloud-download"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M624 706.3h-74.1V464c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v242.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.7a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9z"
/>
<path
d="M811.4 366.7C765.6 245.9 648.9 160 512.2 160S258.8 245.8 213 366.6C127.3 389.1 64 467.2 64 560c0 110.5 89.5 200 199.9 200H304c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8h-40.1c-33.7 0-65.4-13.4-89-37.7-23.5-24.2-36-56.8-34.9-90.6.9-26.4 9.9-51.2 26.2-72.1 16.7-21.3 40.1-36.8 66.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4a245.6 245.6 0 0 1 52.4-49.9c41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10C846.1 454.5 884 503.8 884 560c0 33.1-12.9 64.3-36.3 87.7a123.07 123.07 0 0 1-87.6 36.3H720c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h40.1C870.5 760 960 670.5 960 560c0-92.7-63.1-170.7-148.6-193.3z"
/>
</svg>
</i>
</button>
</div>
</div>
`;
exports[`renders ./components/button/demo/disabled.md correctly 1`] = ` exports[`renders ./components/button/demo/disabled.md correctly 1`] = `
<div> <div>
<button <button
@ -421,8 +195,44 @@ exports[`renders ./components/button/demo/disabled.md correctly 1`] = `
Link(disabled) Link(disabled)
</span> </span>
</button> </button>
<br />
<button
class="ant-btn ant-btn-link ant-btn-dangerous"
type="button"
>
<span>
Danger Link
</span>
</button>
<button
class="ant-btn ant-btn-link ant-btn-dangerous"
disabled=""
type="button"
>
<span>
Danger Link(disabled)
</span>
</button>
<br />
<button
class="ant-btn ant-btn-dangerous"
type="button"
>
<span>
Danger Default
</span>
</button>
<button
class="ant-btn ant-btn-dangerous"
disabled=""
type="button"
>
<span>
Danger Default(disabled)
</span>
</button>
<div <div
style="padding:8px 8px 0 8px;background:rgb(190, 200, 200)" class="site-button-ghost-wrapper"
> >
<button <button
class="ant-btn ant-btn-background-ghost" class="ant-btn ant-btn-background-ghost"
@ -447,7 +257,7 @@ exports[`renders ./components/button/demo/disabled.md correctly 1`] = `
exports[`renders ./components/button/demo/ghost.md correctly 1`] = ` exports[`renders ./components/button/demo/ghost.md correctly 1`] = `
<div <div
style="background:rgb(190, 200, 200);padding:26px 16px 16px" class="site-button-ghost-wrapper"
> >
<button <button
class="ant-btn ant-btn-primary ant-btn-background-ghost" class="ant-btn ant-btn-primary ant-btn-background-ghost"
@ -466,21 +276,29 @@ exports[`renders ./components/button/demo/ghost.md correctly 1`] = `
</span> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-dashed ant-btn-background-ghost" class="ant-btn ant-btn-primary ant-btn-background-ghost ant-btn-dangerous"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-danger ant-btn-background-ghost"
type="button" type="button"
> >
<span> <span>
danger danger
</span> </span>
</button> </button>
<button
class="ant-btn ant-btn-background-ghost ant-btn-dangerous"
type="button"
>
<span>
Danger Default
</span>
</button>
<button
class="ant-btn ant-btn-link ant-btn-background-ghost ant-btn-dangerous"
type="button"
>
<span>
Danger Link
</span>
</button>
<button <button
class="ant-btn ant-btn-link ant-btn-background-ghost" class="ant-btn ant-btn-link ant-btn-background-ghost"
type="button" type="button"
@ -498,9 +316,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
class="ant-btn ant-btn-primary ant-btn-circle ant-btn-icon-only" class="ant-btn ant-btn-primary ant-btn-circle ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -513,10 +332,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-primary ant-btn-circle" class="ant-btn ant-btn-primary ant-btn-circle"
@ -530,9 +349,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
class="ant-btn ant-btn-primary" class="ant-btn ant-btn-primary"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -545,10 +365,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Search Search
</span> </span>
@ -557,9 +377,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
class="ant-btn ant-btn-circle ant-btn-icon-only" class="ant-btn ant-btn-circle ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -572,18 +393,19 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -596,10 +418,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Search Search
</span> </span>
@ -609,9 +431,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
class="ant-btn ant-btn-circle ant-btn-icon-only" class="ant-btn ant-btn-circle ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -624,18 +447,19 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -648,10 +472,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Search Search
</span> </span>
@ -660,9 +484,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
class="ant-btn ant-btn-dashed ant-btn-circle ant-btn-icon-only" class="ant-btn ant-btn-dashed ant-btn-circle ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -675,18 +500,19 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-dashed" class="ant-btn ant-btn-dashed"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -699,10 +525,10 @@ exports[`renders ./components/button/demo/icon.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Search Search
</span> </span>
@ -716,9 +542,10 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
class="ant-btn ant-btn-primary ant-btn-loading" class="ant-btn ant-btn-primary ant-btn-loading"
type="button" type="button"
> >
<i <span
aria-label="icon: loading" aria-label="loading"
class="anticon anticon-loading" class="anticon anticon-loading"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -731,10 +558,10 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Loading Loading
</span> </span>
@ -743,9 +570,10 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-loading" class="ant-btn ant-btn-primary ant-btn-sm ant-btn-loading"
type="button" type="button"
> >
<i <span
aria-label="icon: loading" aria-label="loading"
class="anticon anticon-loading" class="anticon anticon-loading"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -758,10 +586,10 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Loading Loading
</span> </span>
@ -779,9 +607,10 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
class="ant-btn ant-btn-primary" class="ant-btn ant-btn-primary"
type="button" type="button"
> >
<i <span
aria-label="icon: poweroff" aria-label="poweroff"
class="anticon anticon-poweroff" class="anticon anticon-poweroff"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -794,87 +623,14 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = `
width="1em" width="1em"
> >
<path <path
d="M705.6 124.9a8 8 0 0 0-11.6 7.2v64.2c0 5.5 2.9 10.6 7.5 13.6a352.2 352.2 0 0 1 62.2 49.8c32.7 32.8 58.4 70.9 76.3 113.3a355 355 0 0 1 27.9 138.7c0 48.1-9.4 94.8-27.9 138.7a355.92 355.92 0 0 1-76.3 113.3 353.06 353.06 0 0 1-113.2 76.4c-43.8 18.6-90.5 28-138.5 28s-94.7-9.4-138.5-28a353.06 353.06 0 0 1-113.2-76.4A355.92 355.92 0 0 1 184 650.4a355 355 0 0 1-27.9-138.7c0-48.1 9.4-94.8 27.9-138.7 17.9-42.4 43.6-80.5 76.3-113.3 19-19 39.8-35.6 62.2-49.8 4.7-2.9 7.5-8.1 7.5-13.6V132c0-6-6.3-9.8-11.6-7.2C178.5 195.2 82 339.3 80 506.3 77.2 745.1 272.5 943.5 511.2 944c239 .5 432.8-193.3 432.8-432.4 0-169.2-97-315.7-238.4-386.7zM480 560h64c4.4 0 8-3.6 8-8V88c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v464c0 4.4 3.6 8 8 8z" d="M705.6 124.9a8 8 0 00-11.6 7.2v64.2c0 5.5 2.9 10.6 7.5 13.6a352.2 352.2 0 0162.2 49.8c32.7 32.8 58.4 70.9 76.3 113.3a355 355 0 0127.9 138.7c0 48.1-9.4 94.8-27.9 138.7a355.92 355.92 0 01-76.3 113.3 353.06 353.06 0 01-113.2 76.4c-43.8 18.6-90.5 28-138.5 28s-94.7-9.4-138.5-28a353.06 353.06 0 01-113.2-76.4A355.92 355.92 0 01184 650.4a355 355 0 01-27.9-138.7c0-48.1 9.4-94.8 27.9-138.7 17.9-42.4 43.6-80.5 76.3-113.3 19-19 39.8-35.6 62.2-49.8 4.7-2.9 7.5-8.1 7.5-13.6V132c0-6-6.3-9.8-11.6-7.2C178.5 195.2 82 339.3 80 506.3 77.2 745.1 272.5 943.5 511.2 944c239 .5 432.8-193.3 432.8-432.4 0-169.2-97-315.7-238.4-386.7zM480 560h64c4.4 0 8-3.6 8-8V88c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v464c0 4.4 3.6 8 8 8z"
/> />
</svg> </svg>
</i> </span>
<span> <span>
Click me! Click me!
</span> </span>
</button> </button>
<br />
<button
class="ant-btn ant-btn-primary ant-btn-icon-only ant-btn-loading"
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-circle ant-btn-icon-only ant-btn-loading"
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-danger ant-btn-round ant-btn-icon-only ant-btn-loading"
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</i>
</button>
</div> </div>
`; `;
@ -903,9 +659,10 @@ exports[`renders ./components/button/demo/multiple.md correctly 1`] = `
<span> <span>
Actions Actions
</span> </span>
<i <span
aria-label="icon: down" aria-label="down"
class="anticon anticon-down" class="anticon anticon-down"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -921,7 +678,7 @@ exports[`renders ./components/button/demo/multiple.md correctly 1`] = `
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z" d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/> />
</svg> </svg>
</i> </span>
</button> </button>
</div> </div>
`; `;
@ -1005,7 +762,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
type="button" type="button"
> >
<span> <span>
Normal Default
</span> </span>
</button> </button>
<button <button
@ -1016,14 +773,31 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
Dashed Dashed
</span> </span>
</button> </button>
<br />
<button <button
class="ant-btn ant-btn-danger ant-btn-lg" class="ant-btn ant-btn-primary ant-btn-lg ant-btn-dangerous"
type="button" type="button"
> >
<span> <span>
Danger Danger
</span> </span>
</button> </button>
<button
class="ant-btn ant-btn-lg ant-btn-dangerous"
type="button"
>
<span>
Danger Default
</span>
</button>
<button
class="ant-btn ant-btn-link ant-btn-lg ant-btn-dangerous"
type="button"
>
<span>
Danger Link
</span>
</button>
<button <button
class="ant-btn ant-btn-link ant-btn-lg" class="ant-btn ant-btn-link ant-btn-lg"
type="button" type="button"
@ -1037,9 +811,10 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only" class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: download" aria-label="download"
class="anticon anticon-download" class="anticon anticon-download"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -1052,18 +827,19 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" d="M505.7 661a8 8 0 0012.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> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-primary ant-btn-circle ant-btn-lg ant-btn-icon-only" class="ant-btn ant-btn-primary ant-btn-circle ant-btn-lg ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: download" aria-label="download"
class="anticon anticon-download" class="anticon anticon-download"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -1076,18 +852,19 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" d="M505.7 661a8 8 0 0012.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> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-primary ant-btn-round ant-btn-lg ant-btn-icon-only" class="ant-btn ant-btn-primary ant-btn-round ant-btn-lg ant-btn-icon-only"
type="button" type="button"
> >
<i <span
aria-label="icon: download" aria-label="download"
class="anticon anticon-download" class="anticon anticon-download"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -1100,18 +877,19 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" d="M505.7 661a8 8 0 0012.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> </svg>
</i> </span>
</button> </button>
<button <button
class="ant-btn ant-btn-primary ant-btn-round ant-btn-lg" class="ant-btn ant-btn-primary ant-btn-round ant-btn-lg"
type="button" type="button"
> >
<i <span
aria-label="icon: download" aria-label="download"
class="anticon anticon-download" class="anticon anticon-download"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -1124,10 +902,10 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" d="M505.7 661a8 8 0 0012.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> </svg>
</i> </span>
<span> <span>
Download Download
</span> </span>
@ -1136,9 +914,10 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
class="ant-btn ant-btn-primary ant-btn-lg" class="ant-btn ant-btn-primary ant-btn-lg"
type="button" type="button"
> >
<i <span
aria-label="icon: download" aria-label="download"
class="anticon anticon-download" class="anticon anticon-download"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -1151,72 +930,13 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = `
width="1em" width="1em"
> >
<path <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" d="M505.7 661a8 8 0 0012.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> </svg>
</i> </span>
<span> <span>
Download Download
</span> </span>
</button> </button>
<br />
<div
class="ant-btn-group ant-btn-group-lg"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<i
aria-label="icon: left"
class="anticon anticon-left"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
<span>
Backward
</span>
</button>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Forward
</span>
<i
aria-label="icon: right"
class="anticon anticon-right"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
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"
/>
</svg>
</i>
</button>
</div>
</div> </div>
`; `;

View File

@ -43,9 +43,10 @@ exports[`Button renders Chinese characters correctly 2`] = `
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -58,10 +59,10 @@ exports[`Button renders Chinese characters correctly 2`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
按钮 按钮
</span> </span>
@ -73,9 +74,10 @@ exports[`Button renders Chinese characters correctly 3`] = `
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -88,10 +90,10 @@ exports[`Button renders Chinese characters correctly 3`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
按钮 按钮
</span> </span>
@ -103,9 +105,10 @@ exports[`Button renders Chinese characters correctly 4`] = `
class="ant-btn" class="ant-btn"
type="button" type="button"
> >
<i <span
aria-label="icon: search" aria-label="search"
class="anticon anticon-search" class="anticon anticon-search"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -118,10 +121,10 @@ exports[`Button renders Chinese characters correctly 4`] = `
width="1em" width="1em"
> >
<path <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" 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 0011.6 0l43.6-43.5a8.2 8.2 0 000-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"
/> />
</svg> </svg>
</i> </span>
<span> <span>
按钮 按钮
</span> </span>
@ -133,9 +136,10 @@ exports[`Button renders Chinese characters correctly 5`] = `
class="ant-btn ant-btn-loading" class="ant-btn ant-btn-loading"
type="button" type="button"
> >
<i <span
aria-label="icon: loading" aria-label="loading"
class="anticon anticon-loading" class="anticon anticon-loading"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -148,10 +152,10 @@ exports[`Button renders Chinese characters correctly 5`] = `
width="1em" width="1em"
> >
<path <path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/> />
</svg> </svg>
</i> </span>
<span> <span>
按钮 按钮
</span> </span>
@ -163,9 +167,10 @@ exports[`Button renders Chinese characters correctly 6`] = `
class="ant-btn ant-btn-loading" class="ant-btn ant-btn-loading"
type="button" type="button"
> >
<i <span
aria-label="icon: loading" aria-label="loading"
class="anticon anticon-loading" class="anticon anticon-loading"
role="img"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -178,10 +183,10 @@ exports[`Button renders Chinese characters correctly 6`] = `
width="1em" width="1em"
> >
<path <path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/> />
</svg> </svg>
</i> </span>
<span> <span>
按 钮 按 钮
</span> </span>
@ -210,6 +215,45 @@ exports[`Button renders correctly 1`] = `
</button> </button>
`; `;
exports[`Button rtl render component should be rendered correctly in RTL direction 1`] = `
<button
class="ant-btn ant-btn-rtl"
type="button"
/>
`;
exports[`Button rtl render component should be rendered correctly in RTL direction 2`] = `
<button
class="ant-btn ant-btn-lg ant-btn-rtl"
type="button"
/>
`;
exports[`Button rtl render component should be rendered correctly in RTL direction 3`] = `
<button
class="ant-btn ant-btn-sm ant-btn-rtl"
type="button"
/>
`;
exports[`Button rtl render component should be rendered correctly in RTL direction 4`] = `
<div
class="ant-btn-group ant-btn-group-rtl"
/>
`;
exports[`Button rtl render component should be rendered correctly in RTL direction 5`] = `
<div
class="ant-btn-group ant-btn-group-lg ant-btn-group-rtl"
/>
`;
exports[`Button rtl render component should be rendered correctly in RTL direction 6`] = `
<div
class="ant-btn-group ant-btn-group-sm ant-btn-group-rtl"
/>
`;
exports[`Button should has click wave effect 1`] = ` exports[`Button should has click wave effect 1`] = `
<button <button
ant-click-animating-without-extra-node="true" ant-click-animating-without-extra-node="true"

View File

@ -1,9 +1,10 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { render, mount } from 'enzyme'; import { render, mount } from 'enzyme';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import { SearchOutlined } from '@ant-design/icons';
import Button from '..'; import Button from '..';
import Icon from '../../icon';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { sleep } from '../../../tests/utils'; import { sleep } from '../../../tests/utils';
describe('Button', () => { describe('Button', () => {
@ -14,15 +15,19 @@ describe('Button', () => {
mountTest(() => <Button.Group size="large" />); mountTest(() => <Button.Group size="large" />);
mountTest(() => <Button.Group size="small" />); mountTest(() => <Button.Group size="small" />);
rtlTest(Button);
rtlTest(() => <Button size="large" />);
rtlTest(() => <Button size="small" />);
rtlTest(Button.Group);
rtlTest(() => <Button.Group size="large" />);
rtlTest(() => <Button.Group size="small" />);
it('renders correctly', () => { it('renders correctly', () => {
const wrapper = render(<Button>Follow</Button>); const wrapper = render(<Button>Follow</Button>);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it('mount correctly', () => { it('mount correctly', () => {
if (process.env.REACT === '15') {
return;
}
expect(() => renderer.create(<Button>Follow</Button>)).not.toThrow(); expect(() => renderer.create(<Button>Follow</Button>)).not.toThrow();
}); });
@ -30,22 +35,22 @@ describe('Button', () => {
const wrapper = render(<Button>按钮</Button>); const wrapper = render(<Button>按钮</Button>);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
// should not insert space when there is icon // should not insert space when there is icon
const wrapper1 = render(<Button icon="search">按钮</Button>); const wrapper1 = render(<Button icon={<SearchOutlined />}>按钮</Button>);
expect(wrapper1).toMatchSnapshot(); expect(wrapper1).toMatchSnapshot();
// should not insert space when there is icon // should not insert space when there is icon
const wrapper2 = render( const wrapper2 = render(
<Button> <Button>
<Icon type="search" /> <SearchOutlined />
按钮 按钮
</Button>, </Button>,
); );
expect(wrapper2).toMatchSnapshot(); expect(wrapper2).toMatchSnapshot();
// should not insert space when there is icon // should not insert space when there is icon
const wrapper3 = render(<Button icon="search">按钮</Button>); const wrapper3 = render(<Button icon={<SearchOutlined />}>按钮</Button>);
expect(wrapper3).toMatchSnapshot(); expect(wrapper3).toMatchSnapshot();
// should not insert space when there is icon while loading // should not insert space when there is icon while loading
const wrapper4 = render( const wrapper4 = render(
<Button icon="search" loading> <Button icon={<SearchOutlined />} loading>
按钮 按钮
</Button>, </Button>,
); );
@ -236,4 +241,15 @@ describe('Button', () => {
wrapper.unmount(); wrapper.unmount();
}).not.toThrow(); }).not.toThrow();
}); });
it('should warning when pass a string as icon props', () => {
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(<Button type="primary" icon="ab" />);
expect(warnSpy).not.toHaveBeenCalled();
mount(<Button type="primary" icon="search" />);
expect(warnSpy).toHaveBeenCalledWith(
`Warning: [antd: Button] \`icon\` is using ReactNode instead of string naming in v4. Please check \`search\` at https://ant.design/components/icon`,
);
warnSpy.mockRestore();
});
}); });

View File

@ -12,7 +12,7 @@ export interface ButtonGroupProps {
const ButtonGroup: React.SFC<ButtonGroupProps> = props => ( const ButtonGroup: React.SFC<ButtonGroupProps> = props => (
<ConfigConsumer> <ConfigConsumer>
{({ getPrefixCls }: ConfigConsumerProps) => { {({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, size, className, ...others } = props; const { prefixCls: customizePrefixCls, size, className, ...others } = props;
const prefixCls = getPrefixCls('btn-group', customizePrefixCls); const prefixCls = getPrefixCls('btn-group', customizePrefixCls);
@ -34,6 +34,7 @@ const ButtonGroup: React.SFC<ButtonGroupProps> = props => (
prefixCls, prefixCls,
{ {
[`${prefixCls}-${sizeCls}`]: sizeCls, [`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-rtl`]: direction === 'rtl',
}, },
className, className,
); );

View File

@ -1,14 +1,14 @@
/* eslint-disable react/button-has-type */ /* eslint-disable react/button-has-type */
import * as React from 'react'; import * as React from 'react';
import * as PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { polyfill } from 'react-lifecycles-compat'; import { LoadingOutlined } from '@ant-design/icons';
import omit from 'omit.js'; import omit from 'omit.js';
import Group from './button-group'; import Group from './button-group';
import Icon from '../icon';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Wave from '../_util/wave'; import Wave from '../_util/wave';
import { Omit, tuple } from '../_util/type'; import { Omit, tuple } from '../_util/type';
import warning from '../_util/warning';
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
@ -65,23 +65,24 @@ function spaceChildren(children: React.ReactNode, needInserted: boolean) {
} }
const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger', 'link'); const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger', 'link');
export type ButtonType = (typeof ButtonTypes)[number]; export type ButtonType = typeof ButtonTypes[number];
const ButtonShapes = tuple('circle', 'circle-outline', 'round'); const ButtonShapes = tuple('circle', 'circle-outline', 'round');
export type ButtonShape = (typeof ButtonShapes)[number]; export type ButtonShape = typeof ButtonShapes[number];
const ButtonSizes = tuple('large', 'default', 'small'); const ButtonSizes = tuple('large', 'default', 'small');
export type ButtonSize = (typeof ButtonSizes)[number]; export type ButtonSize = typeof ButtonSizes[number];
const ButtonHTMLTypes = tuple('submit', 'button', 'reset'); const ButtonHTMLTypes = tuple('submit', 'button', 'reset');
export type ButtonHTMLType = (typeof ButtonHTMLTypes)[number]; export type ButtonHTMLType = typeof ButtonHTMLTypes[number];
export interface BaseButtonProps { export interface BaseButtonProps {
type?: ButtonType; type?: ButtonType;
icon?: string; icon?: React.ReactNode;
shape?: ButtonShape; shape?: ButtonShape;
size?: ButtonSize; size?: ButtonSize;
loading?: boolean | { delay?: number }; loading?: boolean | { delay?: number };
prefixCls?: string; prefixCls?: string;
className?: string; className?: string;
ghost?: boolean; ghost?: boolean;
danger?: boolean;
block?: boolean; block?: boolean;
children?: React.ReactNode; children?: React.ReactNode;
} }
@ -121,19 +122,6 @@ class Button extends React.Component<ButtonProps, ButtonState> {
htmlType: 'button', htmlType: 'button',
}; };
static propTypes = {
type: PropTypes.string,
shape: PropTypes.oneOf(ButtonShapes),
size: PropTypes.oneOf(ButtonSizes),
htmlType: PropTypes.oneOf(ButtonHTMLTypes),
onClick: PropTypes.func,
loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
className: PropTypes.string,
icon: PropTypes.string,
block: PropTypes.bool,
title: PropTypes.string,
};
private delayTimeout: number; private delayTimeout: number;
private buttonNode: HTMLElement | null; private buttonNode: HTMLElement | null;
@ -213,10 +201,11 @@ class Button extends React.Component<ButtonProps, ButtonState> {
return React.Children.count(children) === 1 && !icon && type !== 'link'; return React.Children.count(children) === 1 && !icon && type !== 'link';
} }
renderButton = ({ getPrefixCls, autoInsertSpaceInButton }: ConfigConsumerProps) => { renderButton = ({ getPrefixCls, autoInsertSpaceInButton, direction }: ConfigConsumerProps) => {
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
type, type,
danger,
shape, shape,
size, size,
className, className,
@ -228,6 +217,12 @@ class Button extends React.Component<ButtonProps, ButtonState> {
} = this.props; } = this.props;
const { loading, hasTwoCNChar } = this.state; const { loading, hasTwoCNChar } = this.state;
warning(
!(typeof icon === 'string' && icon.length > 2),
'Button',
`\`icon\` is using ReactNode instead of string naming in v4. Please check \`${icon}\` at https://ant.design/components/icon`,
);
const prefixCls = getPrefixCls('btn', customizePrefixCls); const prefixCls = getPrefixCls('btn', customizePrefixCls);
const autoInsertSpace = autoInsertSpaceInButton !== false; const autoInsertSpace = autoInsertSpaceInButton !== false;
@ -256,9 +251,11 @@ class Button extends React.Component<ButtonProps, ButtonState> {
[`${prefixCls}-background-ghost`]: ghost, [`${prefixCls}-background-ghost`]: ghost,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace, [`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
[`${prefixCls}-block`]: block, [`${prefixCls}-block`]: block,
[`${prefixCls}-dangerous`]: !!danger,
[`${prefixCls}-rtl`]: direction === 'rtl',
}); });
const iconNode = iconType ? <Icon type={iconType} /> : null; const iconNode = loading ? <LoadingOutlined /> : icon || null;
const kids = const kids =
children || children === 0 children || children === 0
? spaceChildren(children, this.isNeedInserted() && autoInsertSpace) ? spaceChildren(children, this.isNeedInserted() && autoInsertSpace)
@ -307,6 +304,4 @@ class Button extends React.Component<ButtonProps, ButtonState> {
} }
} }
polyfill(Button);
export default Button; export default Button;

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