mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 12:09:14 +08:00
Merge pull request #24185 from ant-design/master
chore: merge master into feature
This commit is contained in:
commit
02dccd9643
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: '⚠️ Please use new-issue.ant.design ⚠️'
|
||||
about: The issue which is not created via http://new-issue.ant.design will be closed immediately.
|
||||
labels:
|
||||
---
|
||||
|
||||
The issue which is not created via http://new-issue.ant.design will be closed immediately.
|
||||
|
||||
---
|
||||
|
||||
注意:不是用 http://new-issue.ant.design 创建的 issue 会被立即关闭。
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Create new issue
|
||||
url: http://new-issue.ant.design
|
||||
about: The issue which is not created via http://new-issue.ant.design will be closed immediately.
|
@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<a href="http://ant.design">
|
||||
<a href="https://ant.design">
|
||||
<img width="200" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg">
|
||||
</a>
|
||||
</p>
|
||||
@ -10,15 +10,44 @@
|
||||
|
||||
Uma solução empresarial de design e biblioteca UI para React.
|
||||
|
||||
[![CircleCI branch](https://img.shields.io/circleci/project/github/ant-design/ant-design/master.svg?style=flat-square)](https://circleci.com/gh/ant-design/ant-design) ![CI Status](https://github.com/ant-design/ant-design/workflows/test/badge.svg) [![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master) [![](https://flat.badgen.net/npm/v/antd?icon=npm)](https://www.npmjs.com/package/antd) [![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://npmjs.com/antd)
|
||||
[![CircleCI status][circleci-image]][circleci-url] [![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
||||
|
||||
[![Dependencies](https://img.shields.io/david/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design) [![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design?type=dev) [![Total alerts](https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design)](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [![Issues need help](https://flat.badgen.net/github/label-issues/ant-design/ant-design/help%20wanted/open)](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
[![david deps][david-image]][david-url] [![david devDeps][david-dev-image]][david-dev-url] [![Total alerts][lgtm-image]][lgtm-url] [![FOSSA Status][fossa-image]][fossa-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||
|
||||
[![](https://img.shields.io/twitter/follow/AntDesignUI.svg?label=Ant%20Design&style=social)](https://twitter.com/AntDesignUI) [![Gitter](https://img.shields.io/gitter/room/ant-design/ant-design-english.svg?style=flat-square&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjEyMzUiIGhlaWdodD0iNjUwIiB2aWV3Qm94PSIwIDAgNzQxMCAzOTAwIj4NCjxyZWN0IHdpZHRoPSI3NDEwIiBoZWlnaHQ9IjM5MDAiIGZpbGw9IiNiMjIyMzQiLz4NCjxwYXRoIGQ9Ik0wLDQ1MEg3NDEwbTAsNjAwSDBtMCw2MDBINzQxMG0wLDYwMEgwbTAsNjAwSDc0MTBtMCw2MDBIMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwMCIvPg0KPHJlY3Qgd2lkdGg9IjI5NjQiIGhlaWdodD0iMjEwMCIgZmlsbD0iIzNjM2I2ZSIvPg0KPGcgZmlsbD0iI2ZmZiI%2BDQo8ZyBpZD0iczE4Ij4NCjxnIGlkPSJzOSI%2BDQo8ZyBpZD0iczUiPg0KPGcgaWQ9InM0Ij4NCjxwYXRoIGlkPSJzIiBkPSJNMjQ3LDkwIDMxNy41MzQyMzAsMzA3LjA4MjAzOSAxMzIuODczMjE4LDE3Mi45MTc5NjFIMzYxLjEyNjc4MkwxNzYuNDY1NzcwLDMwNy4wODIwMzl6Ii8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB5PSI0MjAiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHk9Ijg0MCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTI2MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTY4MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjczQiIHg9IjI0NyIgeT0iMjEwIi8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzOSIgeD0iNDk0Ii8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzMTgiIHg9Ijk4OCIvPg0KPHVzZSB4bGluazpocmVmPSIjczkiIHg9IjE5NzYiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3M1IiB4PSIyNDcwIi8%2BDQo8L2c%2BDQo8L3N2Zz4%3D)](https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Join the chat at https://gitter.im/ant-design/ant-design](https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2MDAiIHZpZXdCb3g9IjAgMCAzMCAyMCI%2BDQo8ZGVmcz4NCjxwYXRoIGlkPSJzIiBkPSJNMCwtMSAwLjU4Nzc4NSwwLjgwOTAxNyAtMC45NTEwNTcsLTAuMzA5MDE3SDAuOTUxMDU3TC0wLjU4Nzc4NSwwLjgwOTAxN3oiIGZpbGw9IiNmZmRlMDAiLz4NCjwvZGVmcz4NCjxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2RlMjkxMCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSw1KSBzY2FsZSgzKSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsMikgcm90YXRlKDIzLjAzNjI0MykiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLDQpIHJvdGF0ZSg0NS44Njk4OTgpIi8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMiw3KSByb3RhdGUoNjkuOTQ1Mzk2KSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsOSkgcm90YXRlKDIwLjY1OTgwOCkiLz4NCjwvc3ZnPg%3D%3D)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[![Follow Twitter][twitter-image]][twitter-url] [![Gitter][gitter-english-image]][gitter-english-url] [![Gitter][gitter-chinese-image]][gitter-chinese-url] [![[SemVer stability]][semver-stability-image]][semver-stability-url]
|
||||
|
||||
[npm-image]: http://img.shields.io/npm/v/antd.svg?style=flat-square
|
||||
[npm-url]: http://npmjs.org/package/antd
|
||||
[circleci-image]: https://img.shields.io/travis/com/ant-design/ant-design.svg?style=flat-square
|
||||
[circleci-url]: https://travis-ci.com/ant-design/ant-design
|
||||
[github-action-image]: https://github.com/ant-design/ant-design/workflows/test/badge.svg
|
||||
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3Atest
|
||||
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
||||
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
||||
[david-image]: https://img.shields.io/david/ant-design/ant-design?style=flat-square
|
||||
[david-dev-url]: https://david-dm.org/ant-design/ant-design?type=dev
|
||||
[david-dev-image]: https://img.shields.io/david/dev/ant-design/ant-design?style=flat-square
|
||||
[david-url]: https://david-dm.org/ant-design/ant-design
|
||||
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
||||
[download-url]: https://npmjs.org/package/antd
|
||||
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
||||
[lgtm-url]: https://lgtm.com/projects/g/ant-design/ant-design/alerts/
|
||||
[fossa-image]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield
|
||||
[fossa-url]: https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield
|
||||
[help-wanted-image]: https://flat.badgen.net/github/label-issues/ant-design/ant-design/help%20wanted/open
|
||||
[help-wanted-url]: https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22
|
||||
[twitter-image]: https://img.shields.io/twitter/follow/AntDesignUI.svg?label=Ant%20Design&style=social
|
||||
[twitter-url]: https://twitter.com/AntDesignUI
|
||||
[gitter-english-image]: https://img.shields.io/gitter/room/ant-design/ant-design-english.svg?style=flat-square&logoWidth=18&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjEyMzUiIGhlaWdodD0iNjUwIiB2aWV3Qm94PSIwIDAgNzQxMCAzOTAwIj4NCjxyZWN0IHdpZHRoPSI3NDEwIiBoZWlnaHQ9IjM5MDAiIGZpbGw9IiNiMjIyMzQiLz4NCjxwYXRoIGQ9Ik0wLDQ1MEg3NDEwbTAsNjAwSDBtMCw2MDBINzQxMG0wLDYwMEgwbTAsNjAwSDc0MTBtMCw2MDBIMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwMCIvPg0KPHJlY3Qgd2lkdGg9IjI5NjQiIGhlaWdodD0iMjEwMCIgZmlsbD0iIzNjM2I2ZSIvPg0KPGcgZmlsbD0iI2ZmZiI%2BDQo8ZyBpZD0iczE4Ij4NCjxnIGlkPSJzOSI%2BDQo8ZyBpZD0iczUiPg0KPGcgaWQ9InM0Ij4NCjxwYXRoIGlkPSJzIiBkPSJNMjQ3LDkwIDMxNy41MzQyMzAsMzA3LjA4MjAzOSAxMzIuODczMjE4LDE3Mi45MTc5NjFIMzYxLjEyNjc4MkwxNzYuNDY1NzcwLDMwNy4wODIwMzl6Ii8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB5PSI0MjAiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHk9Ijg0MCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTI2MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTY4MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjczQiIHg9IjI0NyIgeT0iMjEwIi8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzOSIgeD0iNDk0Ii8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzMTgiIHg9Ijk4OCIvPg0KPHVzZSB4bGluazpocmVmPSIjczkiIHg9IjE5NzYiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3M1IiB4PSIyNDcwIi8%2BDQo8L2c%2BDQo8L3N2Zz4%3D
|
||||
[gitter-english-url]: https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
||||
[gitter-chinese-image]: https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square&logoWidth=18&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2MDAiIHZpZXdCb3g9IjAgMCAzMCAyMCI%2BDQo8ZGVmcz4NCjxwYXRoIGlkPSJzIiBkPSJNMCwtMSAwLjU4Nzc4NSwwLjgwOTAxNyAtMC45NTEwNTcsLTAuMzA5MDE3SDAuOTUxMDU3TC0wLjU4Nzc4NSwwLjgwOTAxN3oiIGZpbGw9IiNmZmRlMDAiLz4NCjwvZGVmcz4NCjxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2RlMjkxMCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSw1KSBzY2FsZSgzKSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsMikgcm90YXRlKDIzLjAzNjI0MykiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLDQpIHJvdGF0ZSg0NS44Njk4OTgpIi8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMiw3KSByb3RhdGUoNjkuOTQ1Mzk2KSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsOSkgcm90YXRlKDIwLjY1OTgwOCkiLz4NCjwvc3ZnPg%3D%3D
|
||||
[gitter-chinese-url]: https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
[semver-stability-url]: https://dependabot.com/compatibility-score.html/?dependency-name=antd&package-manager=npm_and_yarn&new-version=latest
|
||||
[semver-stability-image]: https://api.dependabot.com/badges/compatibility_score?dependency-name=antd&package-manager=npm_and_yarn&target-version=latest&version-scheme=semver
|
||||
|
||||
</div>
|
||||
|
||||
[![](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Yl83RJhUE7kAAAAAAAAAAABkARQnAQ)](http://ant.design)
|
||||
[![](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Yl83RJhUE7kAAAAAAAAAAABkARQnAQ)](https://ant.design)
|
||||
|
||||
[English](./README.md) | Português | [简体中文](./README-zh_CN.md)
|
||||
|
||||
@ -70,20 +99,18 @@ Importe o estilo manualmente:
|
||||
import 'antd/dist/antd.css'; // ou 'antd/dist/antd.less'
|
||||
```
|
||||
|
||||
Ou use [babel-plugin-import](https://ant.design/docs/react/getting-started#Import-on-Demand).
|
||||
|
||||
### TypeScript
|
||||
|
||||
Veja [Uso no Typescript](https://ant.design/docs/react/use-in-typescript).
|
||||
|
||||
## 🌍 Internacionalização
|
||||
|
||||
Veja [i18n](http://ant.design/docs/react/i18n).
|
||||
Veja [i18n](https://ant.design/docs/react/i18n).
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- [Página inicial](http://ant.design/)
|
||||
- [Componentes](http://ant.design/docs/react/introduce)
|
||||
- [Página inicial](https://ant.design/)
|
||||
- [Componentes](https://ant.design/components/button)
|
||||
- [Ant Design Pro](http://pro.ant.design/)
|
||||
- [Change Log](CHANGELOG.en-US.md)
|
||||
- [rc-components](http://react-component.github.io/)
|
||||
@ -101,7 +128,7 @@ Veja [i18n](http://ant.design/docs/react/i18n).
|
||||
- [FAQ](https://ant.design/docs/react/faq)
|
||||
- [CodeSandbox Template](https://u.ant.design/codesandbox-repro) para relatório de erros
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [Customize Theme](http://ant.design/docs/react/customize-theme)
|
||||
- [Customize Theme](https://ant.design/docs/react/customize-theme)
|
||||
- [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
|
||||
|
||||
## ⌨️ Desenvolvimento
|
||||
|
@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<a href="http://ant.design">
|
||||
<a href="https://ant.design">
|
||||
<img width="200" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg">
|
||||
</a>
|
||||
</p>
|
||||
@ -10,15 +10,44 @@
|
||||
|
||||
一套企业级 UI 设计语言和 React 组件库。
|
||||
|
||||
[![CircleCI branch](https://img.shields.io/circleci/project/github/ant-design/ant-design/master.svg?style=flat-square)](https://circleci.com/gh/ant-design/ant-design) ![CI Status](https://github.com/ant-design/ant-design/workflows/Node%20CI/badge.svg) [![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master) [![](https://flat.badgen.net/npm/v/antd?icon=npm)](https://www.npmjs.com/package/antd) [![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://npmjs.com/antd)
|
||||
[![CircleCI status][circleci-image]][circleci-url] [![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
|
||||
|
||||
[![Dependencies](https://img.shields.io/david/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design) [![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design?type=dev) [![Total alerts](https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design)](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [![Issues need help](https://flat.badgen.net/github/label-issues/ant-design/ant-design/help%20wanted/open)](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
[![david deps][david-image]][david-url] [![david devDeps][david-dev-image]][david-dev-url] [![Total alerts][lgtm-image]][lgtm-url] [![FOSSA Status][fossa-image]][fossa-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||
|
||||
[![](https://img.shields.io/twitter/follow/AntDesignUI.svg?label=Ant%20Design&style=social)](https://twitter.com/AntDesignUI) [![Gitter](https://img.shields.io/gitter/room/ant-design/ant-design-english.svg?style=flat-square&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjEyMzUiIGhlaWdodD0iNjUwIiB2aWV3Qm94PSIwIDAgNzQxMCAzOTAwIj4NCjxyZWN0IHdpZHRoPSI3NDEwIiBoZWlnaHQ9IjM5MDAiIGZpbGw9IiNiMjIyMzQiLz4NCjxwYXRoIGQ9Ik0wLDQ1MEg3NDEwbTAsNjAwSDBtMCw2MDBINzQxMG0wLDYwMEgwbTAsNjAwSDc0MTBtMCw2MDBIMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwMCIvPg0KPHJlY3Qgd2lkdGg9IjI5NjQiIGhlaWdodD0iMjEwMCIgZmlsbD0iIzNjM2I2ZSIvPg0KPGcgZmlsbD0iI2ZmZiI%2BDQo8ZyBpZD0iczE4Ij4NCjxnIGlkPSJzOSI%2BDQo8ZyBpZD0iczUiPg0KPGcgaWQ9InM0Ij4NCjxwYXRoIGlkPSJzIiBkPSJNMjQ3LDkwIDMxNy41MzQyMzAsMzA3LjA4MjAzOSAxMzIuODczMjE4LDE3Mi45MTc5NjFIMzYxLjEyNjc4MkwxNzYuNDY1NzcwLDMwNy4wODIwMzl6Ii8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB5PSI0MjAiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHk9Ijg0MCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTI2MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTY4MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjczQiIHg9IjI0NyIgeT0iMjEwIi8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzOSIgeD0iNDk0Ii8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzMTgiIHg9Ijk4OCIvPg0KPHVzZSB4bGluazpocmVmPSIjczkiIHg9IjE5NzYiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3M1IiB4PSIyNDcwIi8%2BDQo8L2c%2BDQo8L3N2Zz4%3D)](https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Join the chat at https://gitter.im/ant-design/ant-design](https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square&logoWidth=20&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2MDAiIHZpZXdCb3g9IjAgMCAzMCAyMCI%2BDQo8ZGVmcz4NCjxwYXRoIGlkPSJzIiBkPSJNMCwtMSAwLjU4Nzc4NSwwLjgwOTAxNyAtMC45NTEwNTcsLTAuMzA5MDE3SDAuOTUxMDU3TC0wLjU4Nzc4NSwwLjgwOTAxN3oiIGZpbGw9IiNmZmRlMDAiLz4NCjwvZGVmcz4NCjxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2RlMjkxMCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSw1KSBzY2FsZSgzKSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsMikgcm90YXRlKDIzLjAzNjI0MykiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLDQpIHJvdGF0ZSg0NS44Njk4OTgpIi8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMiw3KSByb3RhdGUoNjkuOTQ1Mzk2KSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsOSkgcm90YXRlKDIwLjY1OTgwOCkiLz4NCjwvc3ZnPg%3D%3D)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[![Follow Twitter][twitter-image]][twitter-url] [![Gitter][gitter-english-image]][gitter-english-url] [![Gitter][gitter-chinese-image]][gitter-chinese-url] [![[SemVer stability]][semver-stability-image]][semver-stability-url]
|
||||
|
||||
[npm-image]: http://img.shields.io/npm/v/antd.svg?style=flat-square
|
||||
[npm-url]: http://npmjs.org/package/antd
|
||||
[circleci-image]: https://img.shields.io/travis/com/ant-design/ant-design.svg?style=flat-square
|
||||
[circleci-url]: https://travis-ci.com/ant-design/ant-design
|
||||
[github-action-image]: https://github.com/ant-design/ant-design/workflows/test/badge.svg
|
||||
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3Atest
|
||||
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
||||
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
||||
[david-image]: https://img.shields.io/david/ant-design/ant-design?style=flat-square
|
||||
[david-dev-url]: https://david-dm.org/ant-design/ant-design?type=dev
|
||||
[david-dev-image]: https://img.shields.io/david/dev/ant-design/ant-design?style=flat-square
|
||||
[david-url]: https://david-dm.org/ant-design/ant-design
|
||||
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
||||
[download-url]: https://npmjs.org/package/antd
|
||||
[lgtm-image]: https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design
|
||||
[lgtm-url]: https://lgtm.com/projects/g/ant-design/ant-design/alerts/
|
||||
[fossa-image]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield
|
||||
[fossa-url]: https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield
|
||||
[help-wanted-image]: https://flat.badgen.net/github/label-issues/ant-design/ant-design/help%20wanted/open
|
||||
[help-wanted-url]: https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22
|
||||
[twitter-image]: https://img.shields.io/twitter/follow/AntDesignUI.svg?label=Ant%20Design&style=social
|
||||
[twitter-url]: https://twitter.com/AntDesignUI
|
||||
[gitter-english-image]: https://img.shields.io/gitter/room/ant-design/ant-design-english.svg?style=flat-square&logoWidth=18&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjEyMzUiIGhlaWdodD0iNjUwIiB2aWV3Qm94PSIwIDAgNzQxMCAzOTAwIj4NCjxyZWN0IHdpZHRoPSI3NDEwIiBoZWlnaHQ9IjM5MDAiIGZpbGw9IiNiMjIyMzQiLz4NCjxwYXRoIGQ9Ik0wLDQ1MEg3NDEwbTAsNjAwSDBtMCw2MDBINzQxMG0wLDYwMEgwbTAsNjAwSDc0MTBtMCw2MDBIMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwMCIvPg0KPHJlY3Qgd2lkdGg9IjI5NjQiIGhlaWdodD0iMjEwMCIgZmlsbD0iIzNjM2I2ZSIvPg0KPGcgZmlsbD0iI2ZmZiI%2BDQo8ZyBpZD0iczE4Ij4NCjxnIGlkPSJzOSI%2BDQo8ZyBpZD0iczUiPg0KPGcgaWQ9InM0Ij4NCjxwYXRoIGlkPSJzIiBkPSJNMjQ3LDkwIDMxNy41MzQyMzAsMzA3LjA4MjAzOSAxMzIuODczMjE4LDE3Mi45MTc5NjFIMzYxLjEyNjc4MkwxNzYuNDY1NzcwLDMwNy4wODIwMzl6Ii8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB5PSI0MjAiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHk9Ijg0MCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTI2MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjcyIgeT0iMTY4MCIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjczQiIHg9IjI0NyIgeT0iMjEwIi8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzOSIgeD0iNDk0Ii8%2BDQo8L2c%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzMTgiIHg9Ijk4OCIvPg0KPHVzZSB4bGluazpocmVmPSIjczkiIHg9IjE5NzYiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3M1IiB4PSIyNDcwIi8%2BDQo8L2c%2BDQo8L3N2Zz4%3D
|
||||
[gitter-english-url]: https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
||||
[gitter-chinese-image]: https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square&logoWidth=18&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI2MDAiIHZpZXdCb3g9IjAgMCAzMCAyMCI%2BDQo8ZGVmcz4NCjxwYXRoIGlkPSJzIiBkPSJNMCwtMSAwLjU4Nzc4NSwwLjgwOTAxNyAtMC45NTEwNTcsLTAuMzA5MDE3SDAuOTUxMDU3TC0wLjU4Nzc4NSwwLjgwOTAxN3oiIGZpbGw9IiNmZmRlMDAiLz4NCjwvZGVmcz4NCjxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2RlMjkxMCIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNSw1KSBzY2FsZSgzKSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsMikgcm90YXRlKDIzLjAzNjI0MykiLz4NCjx1c2UgeGxpbms6aHJlZj0iI3MiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLDQpIHJvdGF0ZSg0NS44Njk4OTgpIi8%2BDQo8dXNlIHhsaW5rOmhyZWY9IiNzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMiw3KSByb3RhdGUoNjkuOTQ1Mzk2KSIvPg0KPHVzZSB4bGluazpocmVmPSIjcyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAsOSkgcm90YXRlKDIwLjY1OTgwOCkiLz4NCjwvc3ZnPg%3D%3D
|
||||
[gitter-chinese-url]: https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
[semver-stability-url]: https://dependabot.com/compatibility-score.html/?dependency-name=antd&package-manager=npm_and_yarn&new-version=latest
|
||||
[semver-stability-image]: https://api.dependabot.com/badges/compatibility_score?dependency-name=antd&package-manager=npm_and_yarn&target-version=latest&version-scheme=semver
|
||||
|
||||
</div>
|
||||
|
||||
[![](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Ey3wTo-5__QAAAAAAAAAAABkARQnAQ)](http://ant.design/index-cn)
|
||||
[![](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Ey3wTo-5__QAAAAAAAAAAABkARQnAQ)](https://ant.design/index-cn)
|
||||
|
||||
[English](./README.md) | [Português](./README-pt_BR.md) | 简体中文
|
||||
|
||||
@ -31,7 +60,7 @@
|
||||
- 🌍 数十个国际化语言支持。
|
||||
- 🎨 深入每个细节的主题定制能力。
|
||||
|
||||
## 🖥 支持环境
|
||||
## 🖥 兼容环境
|
||||
|
||||
- 现代浏览器和 IE11(需要 [polyfills](https://ant.design/docs/react/getting-started-cn#兼容性))。
|
||||
- 支持服务端渲染。
|
||||
@ -70,8 +99,6 @@ const App = () => (
|
||||
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
```
|
||||
|
||||
你也可以使用 [babel-plugin-import](https://ant.design/docs/react/getting-started-cn#按需加载)。
|
||||
|
||||
### 🌈 定制主题
|
||||
|
||||
参考 [定制主题](https://ant.design/docs/react/customize-theme-cn) 文档。
|
||||
@ -82,12 +109,12 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
|
||||
## 🌍 国际化
|
||||
|
||||
参考 [国际化文档](http://ant.design/docs/react/i18n-cn)。
|
||||
参考 [国际化文档](https://ant.design/docs/react/i18n-cn)。
|
||||
|
||||
## 🔗 链接
|
||||
|
||||
- [首页](http://ant.design/)
|
||||
- [组件库](http://ant.design/docs/react/introduce)
|
||||
- [首页](https://ant.design/)
|
||||
- [组件库](https://ant.design/docs/react/introduce)
|
||||
- [Ant Design Pro](http://pro.ant.design/)
|
||||
- [更新日志](CHANGELOG.en-US.md)
|
||||
- [React 底层基础组件](http://react-component.github.io/)
|
||||
@ -106,7 +133,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
- [常见问题](https://ant.design/docs/react/faq-cn)
|
||||
- [CodeSandbox 模板](https://u.ant.design/codesandbox-repro) for bug reports
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [定制主题](http://ant.design/docs/react/customize-theme-cn)
|
||||
- [定制主题](https://ant.design/docs/react/customize-theme-cn)
|
||||
- [成为社区协作成员](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
|
||||
|
||||
## ⌨️ 本地开发
|
||||
|
12
README.md
12
README.md
@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<a href="http://ant.design">
|
||||
<a href="https://ant.design">
|
||||
<img width="200" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg">
|
||||
</a>
|
||||
</p>
|
||||
@ -47,7 +47,7 @@ An enterprise-class UI design language and React UI library.
|
||||
|
||||
</div>
|
||||
|
||||
[![](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Yl83RJhUE7kAAAAAAAAAAABkARQnAQ)](http://ant.design)
|
||||
[![](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Yl83RJhUE7kAAAAAAAAAAABkARQnAQ)](https://ant.design)
|
||||
|
||||
English | [Português](./README-pt_BR.md) | [简体中文](./README-zh_CN.md)
|
||||
|
||||
@ -99,19 +99,17 @@ And import style manually:
|
||||
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
```
|
||||
|
||||
Or use [babel-plugin-import](https://ant.design/docs/react/getting-started#Import-on-Demand).
|
||||
|
||||
### TypeScript
|
||||
|
||||
See [Use in TypeScript](https://ant.design/docs/react/use-in-typescript).
|
||||
|
||||
## 🌍 Internationalization
|
||||
|
||||
See [i18n](http://ant.design/docs/react/i18n).
|
||||
See [i18n](https://ant.design/docs/react/i18n).
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- [Home page](http://ant.design/)
|
||||
- [Home page](https://ant.design/)
|
||||
- [Components](https://ant.design/components/button/)
|
||||
- [Ant Design Pro](http://pro.ant.design/)
|
||||
- [Change Log](CHANGELOG.en-US.md)
|
||||
@ -130,7 +128,7 @@ See [i18n](http://ant.design/docs/react/i18n).
|
||||
- [FAQ](https://ant.design/docs/react/faq)
|
||||
- [CodeSandbox Template](https://u.ant.design/codesandbox-repro) for bug reports
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [Customize Theme](http://ant.design/docs/react/customize-theme)
|
||||
- [Customize Theme](https://ant.design/docs/react/customize-theme)
|
||||
- [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
|
||||
|
||||
## ⌨️ Development
|
||||
|
@ -1,11 +1,57 @@
|
||||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
import getScroll from '../getScroll';
|
||||
|
||||
describe('getScroll', () => {
|
||||
it('getScroll return 0 in node envioronment', async () => {
|
||||
it('getScroll target null', async () => {
|
||||
expect(getScroll(null, true)).toBe(0);
|
||||
expect(getScroll(null, false)).toBe(0);
|
||||
});
|
||||
|
||||
it('getScroll window', async () => {
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
window.pageXOffset = x;
|
||||
window.pageYOffset = y;
|
||||
});
|
||||
window.scrollTo(200, 400);
|
||||
expect(getScroll(window, true)).toBe(400);
|
||||
expect(getScroll(window, false)).toBe(200);
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('getScroll document', async () => {
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
document.documentElement.scrollLeft = x;
|
||||
document.documentElement.scrollTop = y;
|
||||
});
|
||||
window.scrollTo(200, 400);
|
||||
expect(getScroll(document, true)).toBe(400);
|
||||
expect(getScroll(document, false)).toBe(200);
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('getScroll div', async () => {
|
||||
const div = document.createElement('div');
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
div.scrollLeft = x;
|
||||
div.scrollTop = y;
|
||||
});
|
||||
window.scrollTo(200, 400);
|
||||
expect(getScroll(div, true)).toBe(400);
|
||||
expect(getScroll(div, false)).toBe(200);
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('getScroll documentElement', async () => {
|
||||
const div = {};
|
||||
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => {
|
||||
div.scrollLeft = null;
|
||||
div.scrollTop = null;
|
||||
div.documentElement = {};
|
||||
div.documentElement.scrollLeft = x;
|
||||
div.documentElement.scrollTop = y;
|
||||
});
|
||||
window.scrollTo(200, 400);
|
||||
expect(getScroll(div, true)).toBe(400);
|
||||
expect(getScroll(div, false)).toBe(200);
|
||||
scrollToSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
11
components/_util/__tests__/getScrollNode.test.ts
Normal file
11
components/_util/__tests__/getScrollNode.test.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @jest-environment node
|
||||
*/
|
||||
import getScroll from '../getScroll';
|
||||
|
||||
describe('getScroll node', () => {
|
||||
it('getScroll return 0 in node environment', async () => {
|
||||
expect(getScroll(null, true)).toBe(0);
|
||||
expect(getScroll(null, false)).toBe(0);
|
||||
});
|
||||
});
|
@ -46,4 +46,21 @@ describe('Test ScrollTo function', () => {
|
||||
await sleep(20);
|
||||
expect(div.scrollTop).toBe(1000);
|
||||
});
|
||||
|
||||
it('test getContainer document - option', async () => {
|
||||
scrollTo(1000, {
|
||||
getContainer: () => document,
|
||||
});
|
||||
await sleep(20);
|
||||
expect(document.documentElement.scrollTop).toBe(1000);
|
||||
});
|
||||
|
||||
it('test duration - option', async () => {
|
||||
scrollTo(1000, {
|
||||
duration: 1100,
|
||||
getContainer: () => document,
|
||||
});
|
||||
await sleep(20);
|
||||
expect(document.documentElement.scrollTop).toBe(1000);
|
||||
});
|
||||
});
|
||||
|
@ -74,9 +74,10 @@ describe('Alert', () => {
|
||||
});
|
||||
|
||||
it('could be used with Tooltip', async () => {
|
||||
const ref = React.createRef<any>();
|
||||
jest.useRealTimers();
|
||||
const wrapper = mount(
|
||||
<Tooltip title="xxx" mouseEnterDelay={0}>
|
||||
<Tooltip title="xxx" mouseEnterDelay={0} ref={ref}>
|
||||
<Alert
|
||||
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
|
||||
type="warning"
|
||||
@ -85,7 +86,7 @@ describe('Alert', () => {
|
||||
);
|
||||
wrapper.find('.ant-alert').simulate('mouseenter');
|
||||
await sleep(0);
|
||||
expect(wrapper.find<Tooltip>(Tooltip).instance().getPopupDomNode()).toBeTruthy();
|
||||
expect(ref.current.getPopupDomNode()).toBeTruthy();
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
|
@ -38,23 +38,21 @@ describe('Badge', () => {
|
||||
it('should have an overriden title attribute', () => {
|
||||
const badge = mount(<Badge count={10} title="Custom title" />);
|
||||
expect(
|
||||
badge
|
||||
.find('.ant-scroll-number')
|
||||
.getDOMNode()
|
||||
.attributes.getNamedItem('title').value,
|
||||
badge.find('.ant-scroll-number').getDOMNode().attributes.getNamedItem('title').value,
|
||||
).toEqual('Custom title');
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/10626
|
||||
it('should be composable with Tooltip', () => {
|
||||
const ref = React.createRef();
|
||||
const wrapper = mount(
|
||||
<Tooltip title="Fix the error">
|
||||
<Tooltip title="Fix the error" ref={ref}>
|
||||
<Badge status="error" />
|
||||
</Tooltip>,
|
||||
);
|
||||
wrapper.find('Badge').simulate('mouseenter');
|
||||
jest.runAllTimers();
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
});
|
||||
|
||||
it('should render when count is changed', () => {
|
||||
|
@ -344,7 +344,7 @@ exports[`Button should render empty button without errors 1`] = `
|
||||
exports[`Button should support link button 1`] = `
|
||||
<a
|
||||
class="ant-btn"
|
||||
href="http://ant.design"
|
||||
href="https://ant.design"
|
||||
target="_blank"
|
||||
>
|
||||
<span>
|
||||
|
@ -178,7 +178,7 @@ describe('Button', () => {
|
||||
|
||||
it('should support link button', () => {
|
||||
const wrapper = mount(
|
||||
<Button target="_blank" href="http://ant.design">
|
||||
<Button target="_blank" href="https://ant.design">
|
||||
link button
|
||||
</Button>,
|
||||
);
|
||||
|
@ -23,7 +23,7 @@ There are five kinds of picker:
|
||||
|
||||
### Localization
|
||||
|
||||
The default locale is en-US, if you need to use other languages, recommend to use internationalized components provided by us at the entrance. Look at: [ConfigProvider](http://ant.design/components/config-provider/).
|
||||
The default locale is en-US, if you need to use other languages, recommend to use internationalized components provided by us at the entrance. Look at: [ConfigProvider](https://ant.design/components/config-provider/).
|
||||
|
||||
If there are special needs (only modifying single component language), Please use the property: local. Example: [default](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json).
|
||||
|
||||
|
@ -24,7 +24,7 @@ subtitle: 日期选择框
|
||||
|
||||
### 国际化配置
|
||||
|
||||
默认配置为 en-US,如果你需要设置其他语言,推荐在入口处使用我们提供的国际化组件,详见:[ConfigProvider 国际化](http://ant.design/components/config-provider-cn/)。
|
||||
默认配置为 en-US,如果你需要设置其他语言,推荐在入口处使用我们提供的国际化组件,详见:[ConfigProvider 国际化](https://ant.design/components/config-provider-cn/)。
|
||||
|
||||
如有特殊需求(仅修改单一组件的语言),请使用 locale 参数,参考:[默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json)。
|
||||
|
||||
|
@ -9,15 +9,15 @@ title:
|
||||
|
||||
自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件遵循以下的约定:
|
||||
|
||||
> - 提供受控属性 `value` 或其它与 [`valuePropName`](http://ant.design/components/form/#getFieldDecorator-参数) 的值同名的属性。
|
||||
> - 提供 `onChange` 事件或 [`trigger`](http://ant.design/components/form/#getFieldDecorator-参数) 的值同名的事件。
|
||||
> - 提供受控属性 `value` 或其它与 [`valuePropName`](https://ant.design/components/form/#getFieldDecorator-参数) 的值同名的属性。
|
||||
> - 提供 `onChange` 事件或 [`trigger`](https://ant.design/components/form/#getFieldDecorator-参数) 的值同名的事件。
|
||||
|
||||
## en-US
|
||||
|
||||
Customized or third-party form controls can be used in Form, too. Controls must follow these conventions:
|
||||
|
||||
> - It has a controlled property `value` or other name which is equal to the value of [`valuePropName`](http://ant.design/components/form/?locale=en-US#getFieldDecorator's-parameters).
|
||||
> - It has event `onChange` or an event which name is equal to the value of [`trigger`](http://ant.design/components/form/?locale=en-US#getFieldDecorator's-parameters).
|
||||
> - It has a controlled property `value` or other name which is equal to the value of [`valuePropName`](https://ant.design/components/form/?locale=en-US#getFieldDecorator's-parameters).
|
||||
> - It has event `onChange` or an event which name is equal to the value of [`trigger`](https://ant.design/components/form/?locale=en-US#getFieldDecorator's-parameters).
|
||||
|
||||
```tsx
|
||||
import React, { useState } from 'react';
|
||||
|
@ -144,6 +144,8 @@ You can import SVG icon as a react component by using `webpack` and [`@svgr/webp
|
||||
```jsx
|
||||
import Icon from '@ant-design/icons';
|
||||
import MessageSvg from 'path/to/message.svg'; // path to your '*.svg' file.
|
||||
// in create-react-app:
|
||||
// import { ReactComponent as MessageSvg } from 'path/to/message.svg';
|
||||
|
||||
ReactDOM.render(<Icon component={MessageSvg} />, mountNode);
|
||||
```
|
||||
|
@ -139,6 +139,8 @@ ReactDOM.render(<MyIcon type="icon-example" />, mountedNode);
|
||||
```jsx
|
||||
import Icon from '@ant-design/icons';
|
||||
import MessageSvg from 'path/to/message.svg'; // path to your '*.svg' file.
|
||||
// in create-react-app:
|
||||
// import { ReactComponent as MessageSvg } from 'path/to/message.svg';
|
||||
|
||||
ReactDOM.render(<Icon component={MessageSvg} />, mountNode);
|
||||
```
|
||||
|
@ -7,7 +7,7 @@ describe('List Item Layout', () => {
|
||||
const data = [
|
||||
{
|
||||
key: 1,
|
||||
href: 'http://ant.design',
|
||||
href: 'https://ant.design',
|
||||
title: `ant design`,
|
||||
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
|
||||
description:
|
||||
@ -29,12 +29,7 @@ describe('List Item Layout', () => {
|
||||
)}
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('.ant-list-item')
|
||||
.at(0)
|
||||
.hasClass('ant-list-item-no-flex'),
|
||||
).toBe(true);
|
||||
expect(wrapper.find('.ant-list-item').at(0).hasClass('ant-list-item-no-flex')).toBe(true);
|
||||
});
|
||||
|
||||
it('horizontal itemLayout List should be flex container defaultly', () => {
|
||||
@ -51,12 +46,7 @@ describe('List Item Layout', () => {
|
||||
)}
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('.ant-list-item')
|
||||
.at(0)
|
||||
.hasClass('ant-list-item-no-flex'),
|
||||
).toBe(false);
|
||||
expect(wrapper.find('.ant-list-item').at(0).hasClass('ant-list-item-no-flex')).toBe(false);
|
||||
});
|
||||
|
||||
it('vertical itemLayout List should be flex container when there is extra node', () => {
|
||||
@ -74,12 +64,7 @@ describe('List Item Layout', () => {
|
||||
)}
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('.ant-list-item')
|
||||
.at(0)
|
||||
.hasClass('ant-list-item-no-flex'),
|
||||
).toBe(false);
|
||||
expect(wrapper.find('.ant-list-item').at(0).hasClass('ant-list-item-no-flex')).toBe(false);
|
||||
});
|
||||
|
||||
it('vertical itemLayout List should not be flex container when there is not extra node', () => {
|
||||
@ -97,12 +82,7 @@ describe('List Item Layout', () => {
|
||||
)}
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('.ant-list-item')
|
||||
.at(0)
|
||||
.hasClass('ant-list-item-no-flex'),
|
||||
).toBe(true);
|
||||
expect(wrapper.find('.ant-list-item').at(0).hasClass('ant-list-item-no-flex')).toBe(true);
|
||||
});
|
||||
|
||||
it('horizontal itemLayout List should accept extra node', () => {
|
||||
|
@ -26,7 +26,7 @@ exports[`List Item Layout horizontal itemLayout List should accept extra node 1`
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
href="https://ant.design"
|
||||
>
|
||||
ant design
|
||||
</a>
|
||||
@ -83,7 +83,7 @@ exports[`List Item Layout should render in RTL direction 1`] = `
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
href="https://ant.design"
|
||||
>
|
||||
ant design
|
||||
</a>
|
||||
|
@ -917,7 +917,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
href="https://ant.design"
|
||||
>
|
||||
ant design part 0
|
||||
</a>
|
||||
@ -1086,7 +1086,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
href="https://ant.design"
|
||||
>
|
||||
ant design part 1
|
||||
</a>
|
||||
@ -1255,7 +1255,7 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
href="https://ant.design"
|
||||
>
|
||||
ant design part 2
|
||||
</a>
|
||||
|
@ -20,7 +20,7 @@ import { MessageOutlined, LikeOutlined, StarOutlined } from '@ant-design/icons';
|
||||
const listData = [];
|
||||
for (let i = 0; i < 23; i++) {
|
||||
listData.push({
|
||||
href: 'http://ant.design',
|
||||
href: 'https://ant.design',
|
||||
title: `ant design part ${i}`,
|
||||
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
|
||||
description:
|
||||
|
@ -24,7 +24,6 @@
|
||||
padding: 0;
|
||||
line-height: @select-height-without-border;
|
||||
transition: all 0.3s;
|
||||
pointer-events: none;
|
||||
|
||||
// Firefox inline-block position calculation is not same as Chrome & Safari. Patch this:
|
||||
@supports (-moz-appearance: meterbar) {
|
||||
@ -34,6 +33,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-item {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// For common baseline align
|
||||
&::after,
|
||||
// For '' value baseline align
|
||||
|
@ -20,7 +20,7 @@ import { StarOutlined, LikeOutlined, MessageOutlined } from '@ant-design/icons';
|
||||
const listData = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
listData.push({
|
||||
href: 'http://ant.design',
|
||||
href: 'https://ant.design',
|
||||
title: `ant design part ${i}`,
|
||||
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
|
||||
description:
|
||||
|
@ -1,9 +1,30 @@
|
||||
import * as React from 'react';
|
||||
import Tooltip, { TooltipProps } from '../tooltip';
|
||||
|
||||
export default function SliderTooltip(props: TooltipProps) {
|
||||
function useCombinedRefs(
|
||||
...refs: Array<React.MutableRefObject<unknown> | ((instance: unknown) => void) | null>
|
||||
) {
|
||||
const targetRef = React.useRef();
|
||||
|
||||
React.useEffect(() => {
|
||||
refs.forEach(ref => {
|
||||
if (!ref) return;
|
||||
|
||||
if (typeof ref === 'function') {
|
||||
ref(targetRef.current);
|
||||
} else {
|
||||
ref.current = targetRef.current;
|
||||
}
|
||||
});
|
||||
}, [refs]);
|
||||
|
||||
return targetRef;
|
||||
}
|
||||
|
||||
const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
const { visible } = props;
|
||||
const tooltipRef = React.useRef<Tooltip>(null);
|
||||
const innerRef = React.useRef<any>(null);
|
||||
const tooltipRef = useCombinedRefs(ref, innerRef);
|
||||
|
||||
const rafRef = React.useRef<number | null>(null);
|
||||
|
||||
@ -18,9 +39,7 @@ export default function SliderTooltip(props: TooltipProps) {
|
||||
}
|
||||
|
||||
rafRef.current = window.requestAnimationFrame(() => {
|
||||
if (tooltipRef.current && (tooltipRef.current as any).tooltip) {
|
||||
(tooltipRef.current as any).tooltip.forcePopupAlign();
|
||||
}
|
||||
(tooltipRef.current as any).forcePopupAlign();
|
||||
|
||||
rafRef.current = null;
|
||||
keepAlign();
|
||||
@ -38,4 +57,6 @@ export default function SliderTooltip(props: TooltipProps) {
|
||||
}, [visible]);
|
||||
|
||||
return <Tooltip ref={tooltipRef} {...props} />;
|
||||
}
|
||||
});
|
||||
|
||||
export default SliderTooltip;
|
||||
|
@ -5,6 +5,7 @@ import ConfigProvider from '../../config-provider';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
import SliderTooltip from '../SliderTooltip';
|
||||
import { sleep } from '../../../tests/utils';
|
||||
|
||||
describe('Slider', () => {
|
||||
@ -41,10 +42,19 @@ describe('Slider', () => {
|
||||
});
|
||||
|
||||
it('should keepAlign by calling forcePopupAlign', async () => {
|
||||
const wrapper = mount(<Slider defaultValue={30} tooltipVisible />);
|
||||
wrapper.find('Tooltip').instance().tooltip.forcePopupAlign = jest.fn();
|
||||
let ref;
|
||||
mount(
|
||||
<SliderTooltip
|
||||
title="30"
|
||||
visible
|
||||
ref={node => {
|
||||
ref = node;
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
ref.forcePopupAlign = jest.fn();
|
||||
await sleep(20);
|
||||
expect(wrapper.find('Tooltip').instance().tooltip.forcePopupAlign).toHaveBeenCalled();
|
||||
expect(ref.forcePopupAlign).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('tipFormatter should not crash with undefined value', () => {
|
||||
|
@ -103,6 +103,7 @@ const Slider = React.forwardRef<unknown, SliderProps>((props, ref) => {
|
||||
</SliderTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
tooltipPrefixCls: customizeTooltipPrefixCls,
|
||||
|
@ -17,9 +17,16 @@ describe('Tooltip', () => {
|
||||
|
||||
it('check `onVisibleChange` arguments', () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
const wrapper = mount(
|
||||
<Tooltip title="" mouseEnterDelay={0} mouseLeaveDelay={0} onVisibleChange={onVisibleChange}>
|
||||
<Tooltip
|
||||
title=""
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
<div id="hello">Hello world!</div>
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -28,43 +35,46 @@ describe('Tooltip', () => {
|
||||
const div = wrapper.find('#hello').at(0);
|
||||
div.simulate('mouseenter');
|
||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
|
||||
div.simulate('mouseleave');
|
||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
|
||||
// update `title` value.
|
||||
wrapper.setProps({ title: 'Have a nice day!' });
|
||||
wrapper.find('#hello').simulate('mouseenter');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
|
||||
wrapper.find('#hello').simulate('mouseleave');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
|
||||
// add `visible` props.
|
||||
wrapper.setProps({ visible: false });
|
||||
wrapper.find('#hello').simulate('mouseenter');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
const lastCount = onVisibleChange.mock.calls.length;
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
|
||||
// always trigger onVisibleChange
|
||||
wrapper.simulate('mouseleave');
|
||||
expect(onVisibleChange.mock.calls.length).toBe(lastCount); // no change with lastCount
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
});
|
||||
|
||||
it('should hide when mouse leave native disabled button', () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
const wrapper = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
<button type="button" disabled>
|
||||
Hello world!
|
||||
@ -76,23 +86,25 @@ describe('Tooltip', () => {
|
||||
const button = wrapper.find('span').at(0);
|
||||
button.simulate('mouseenter');
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
|
||||
button.simulate('mouseleave');
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
});
|
||||
|
||||
describe('should hide when mouse leave antd disabled component', () => {
|
||||
function testComponent(name, Component) {
|
||||
it(name, () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
const wrapper = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
<Component disabled />
|
||||
</Tooltip>,
|
||||
@ -102,11 +114,11 @@ describe('Tooltip', () => {
|
||||
const button = wrapper.find('span').at(0);
|
||||
button.simulate('mouseenter');
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
|
||||
button.simulate('mouseleave');
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -183,9 +195,10 @@ describe('Tooltip', () => {
|
||||
|
||||
it('should works for date picker', async () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
const wrapper = mount(
|
||||
<Tooltip title="date picker" onVisibleChange={onVisibleChange}>
|
||||
<Tooltip title="date picker" onVisibleChange={onVisibleChange} ref={ref}>
|
||||
<DatePicker />
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -195,19 +208,19 @@ describe('Tooltip', () => {
|
||||
picker.simulate('mouseenter');
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
|
||||
picker.simulate('mouseleave');
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
});
|
||||
|
||||
it('should works for input group', async () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
|
||||
const ref = React.createRef();
|
||||
const wrapper = mount(
|
||||
<Tooltip title="hello" onVisibleChange={onVisibleChange}>
|
||||
<Tooltip title="hello" onVisibleChange={onVisibleChange} ref={ref}>
|
||||
<Group>
|
||||
<Input style={{ width: '50%' }} />
|
||||
<Input style={{ width: '50%' }} />
|
||||
@ -220,12 +233,12 @@ describe('Tooltip', () => {
|
||||
picker.simulate('mouseenter');
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
|
||||
picker.simulate('mouseleave');
|
||||
await sleep(100);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/20891
|
||||
@ -279,6 +292,7 @@ describe('Tooltip', () => {
|
||||
});
|
||||
|
||||
it('other placement when mouse enter', async () => {
|
||||
const ref = React.createRef();
|
||||
const wrapper = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
@ -286,6 +300,7 @@ describe('Tooltip', () => {
|
||||
transitionName=""
|
||||
popupTransitionName=""
|
||||
mouseEnterDelay={0}
|
||||
ref={ref}
|
||||
>
|
||||
<span>Hello world!</span>
|
||||
</Tooltip>,
|
||||
@ -295,10 +310,11 @@ describe('Tooltip', () => {
|
||||
const button = wrapper.find('span').at(0);
|
||||
button.simulate('mouseenter');
|
||||
await sleep(500);
|
||||
expect(wrapper.instance().getPopupDomNode().className).toContain('placement-topRight');
|
||||
expect(ref.current.getPopupDomNode().className).toContain('placement-topRight');
|
||||
});
|
||||
|
||||
it('should works for mismatch placement', async () => {
|
||||
const ref = React.createRef();
|
||||
const wrapper = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
@ -306,6 +322,7 @@ describe('Tooltip', () => {
|
||||
points: ['bc', 'tl'],
|
||||
}}
|
||||
mouseEnterDelay={0}
|
||||
ref={ref}
|
||||
>
|
||||
<span>Hello world!</span>
|
||||
</Tooltip>,
|
||||
@ -313,6 +330,6 @@ describe('Tooltip', () => {
|
||||
const button = wrapper.find('span').at(0);
|
||||
button.simulate('mouseenter');
|
||||
await sleep(600);
|
||||
expect(wrapper.instance().getPopupDomNode().className).toContain('ant-tooltip');
|
||||
expect(ref.current.getPopupDomNode().className).toContain('ant-tooltip');
|
||||
});
|
||||
});
|
||||
|
@ -4,8 +4,8 @@ import { TooltipProps as RcTooltipProps } from 'rc-tooltip/lib/Tooltip';
|
||||
import classNames from 'classnames';
|
||||
import { BuildInPlacements } from 'rc-trigger/lib/interface';
|
||||
import getPlacements, { AdjustOverflow, PlacementsConfig } from './placements';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
|
||||
export { AdjustOverflow, PlacementsConfig };
|
||||
|
||||
@ -122,49 +122,35 @@ function getDisabledCompatibleChildren(element: React.ReactElement<any>, prefixC
|
||||
return element;
|
||||
}
|
||||
|
||||
class Tooltip extends React.Component<TooltipProps, any> {
|
||||
static defaultProps = {
|
||||
placement: 'top' as TooltipPlacement,
|
||||
transitionName: 'zoom-big-fast',
|
||||
mouseEnterDelay: 0.1,
|
||||
mouseLeaveDelay: 0.1,
|
||||
arrowPointAtCenter: false,
|
||||
autoAdjustOverflow: true,
|
||||
const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
const { getPopupContainer: getContextPopupContainer, getPrefixCls, direction } = React.useContext(
|
||||
ConfigContext,
|
||||
);
|
||||
|
||||
const [visible, setVisible] = React.useState(!!props.visible || !!props.defaultVisible);
|
||||
|
||||
React.useEffect(() => {
|
||||
if ('visible' in props) {
|
||||
setVisible(props.visible!);
|
||||
}
|
||||
}, [props.visible]);
|
||||
|
||||
const isNoTitle = () => {
|
||||
const { title, overlay } = props;
|
||||
return !title && !overlay && title !== 0; // overlay for old version compatibility
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: TooltipProps) {
|
||||
if ('visible' in nextProps) {
|
||||
return { visible: nextProps.visible };
|
||||
const onVisibleChange = (vis: boolean) => {
|
||||
if (!('visible' in props)) {
|
||||
setVisible(isNoTitle() ? false : vis);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private tooltip: typeof RcTooltip;
|
||||
|
||||
constructor(props: TooltipProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
visible: !!props.visible || !!props.defaultVisible,
|
||||
};
|
||||
}
|
||||
|
||||
onVisibleChange = (visible: boolean) => {
|
||||
const { onVisibleChange } = this.props;
|
||||
if (!('visible' in this.props)) {
|
||||
this.setState({ visible: this.isNoTitle() ? false : visible });
|
||||
}
|
||||
if (onVisibleChange && !this.isNoTitle()) {
|
||||
onVisibleChange(visible);
|
||||
if (props.onVisibleChange && !isNoTitle()) {
|
||||
props.onVisibleChange(vis);
|
||||
}
|
||||
};
|
||||
|
||||
getPopupDomNode() {
|
||||
return (this.tooltip as any).getPopupDomNode();
|
||||
}
|
||||
|
||||
getPlacements() {
|
||||
const { builtinPlacements, arrowPointAtCenter, autoAdjustOverflow } = this.props;
|
||||
const getTooltipPlacements = () => {
|
||||
const { builtinPlacements, arrowPointAtCenter, autoAdjustOverflow } = props;
|
||||
return (
|
||||
builtinPlacements ||
|
||||
getPlacements({
|
||||
@ -172,15 +158,11 @@ class Tooltip extends React.Component<TooltipProps, any> {
|
||||
autoAdjustOverflow,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
saveTooltip = (node: typeof RcTooltip) => {
|
||||
this.tooltip = node;
|
||||
};
|
||||
|
||||
// 动态设置动画点
|
||||
onPopupAlign = (domNode: HTMLElement, align: any) => {
|
||||
const placements: any = this.getPlacements();
|
||||
const onPopupAlign = (domNode: HTMLElement, align: any) => {
|
||||
const placements: any = getTooltipPlacements();
|
||||
// 当前返回的位置
|
||||
const placement = Object.keys(placements).filter(
|
||||
key =>
|
||||
@ -209,74 +191,69 @@ class Tooltip extends React.Component<TooltipProps, any> {
|
||||
domNode.style.transformOrigin = `${transformOrigin.left} ${transformOrigin.top}`;
|
||||
};
|
||||
|
||||
isNoTitle() {
|
||||
const { title, overlay } = this.props;
|
||||
return !title && !overlay && title !== 0; // overlay for old version compatibility
|
||||
}
|
||||
|
||||
getOverlay() {
|
||||
const { title, overlay } = this.props;
|
||||
const getOverlay = () => {
|
||||
const { title, overlay } = props;
|
||||
if (title === 0) {
|
||||
return title;
|
||||
}
|
||||
return overlay || title || '';
|
||||
}
|
||||
|
||||
renderTooltip = ({
|
||||
getPopupContainer: getContextPopupContainer,
|
||||
getPrefixCls,
|
||||
direction,
|
||||
}: ConfigConsumerProps) => {
|
||||
const { props, state } = this;
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
openClassName,
|
||||
getPopupContainer,
|
||||
getTooltipContainer,
|
||||
overlayClassName,
|
||||
} = props;
|
||||
const children = props.children as React.ReactElement<any>;
|
||||
const prefixCls = getPrefixCls('tooltip', customizePrefixCls);
|
||||
let { visible } = state;
|
||||
// Hide tooltip when there is no title
|
||||
if (!('visible' in props) && this.isNoTitle()) {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
const child = getDisabledCompatibleChildren(
|
||||
isValidElement(children) ? children : <span>{children}</span>,
|
||||
prefixCls,
|
||||
);
|
||||
|
||||
const childProps = child.props;
|
||||
const childCls = classNames(childProps.className, {
|
||||
[openClassName || `${prefixCls}-open`]: true,
|
||||
});
|
||||
|
||||
const customOverlayClassName = classNames(overlayClassName, {
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
});
|
||||
return (
|
||||
<RcTooltip
|
||||
{...this.props}
|
||||
prefixCls={prefixCls}
|
||||
overlayClassName={customOverlayClassName}
|
||||
getTooltipContainer={getPopupContainer || getTooltipContainer || getContextPopupContainer}
|
||||
ref={this.saveTooltip}
|
||||
builtinPlacements={this.getPlacements()}
|
||||
overlay={this.getOverlay()}
|
||||
visible={visible}
|
||||
onVisibleChange={this.onVisibleChange}
|
||||
onPopupAlign={this.onPopupAlign}
|
||||
>
|
||||
{visible ? cloneElement(child, { className: childCls }) : child}
|
||||
</RcTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
return <ConfigConsumer>{this.renderTooltip}</ConfigConsumer>;
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
openClassName,
|
||||
getPopupContainer,
|
||||
getTooltipContainer,
|
||||
overlayClassName,
|
||||
} = props;
|
||||
const children = props.children as React.ReactElement<any>;
|
||||
const prefixCls = getPrefixCls('tooltip', customizePrefixCls);
|
||||
let tempVisible = visible;
|
||||
// Hide tooltip when there is no title
|
||||
if (!('visible' in props) && isNoTitle()) {
|
||||
tempVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
const child = getDisabledCompatibleChildren(
|
||||
isValidElement(children) ? children : <span>{children}</span>,
|
||||
prefixCls,
|
||||
);
|
||||
const childProps = child.props;
|
||||
const childCls = classNames(childProps.className, {
|
||||
[openClassName || `${prefixCls}-open`]: true,
|
||||
});
|
||||
|
||||
const customOverlayClassName = classNames(overlayClassName, {
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
});
|
||||
|
||||
return (
|
||||
<RcTooltip
|
||||
{...props}
|
||||
prefixCls={prefixCls}
|
||||
overlayClassName={customOverlayClassName}
|
||||
getTooltipContainer={getPopupContainer || getTooltipContainer || getContextPopupContainer}
|
||||
ref={ref}
|
||||
builtinPlacements={getTooltipPlacements()}
|
||||
overlay={getOverlay()}
|
||||
visible={tempVisible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
onPopupAlign={onPopupAlign}
|
||||
>
|
||||
{tempVisible ? cloneElement(child, { className: childCls }) : child}
|
||||
</RcTooltip>
|
||||
);
|
||||
});
|
||||
|
||||
Tooltip.displayName = 'Tooltip';
|
||||
|
||||
Tooltip.defaultProps = {
|
||||
placement: 'top' as TooltipPlacement,
|
||||
transitionName: 'zoom-big-fast',
|
||||
mouseEnterDelay: 0.1,
|
||||
mouseLeaveDelay: 0.1,
|
||||
arrowPointAtCenter: false,
|
||||
autoAdjustOverflow: true,
|
||||
};
|
||||
|
||||
export default Tooltip;
|
||||
|
@ -37,21 +37,6 @@ No, we follow Ant Design specification. https://github.com/ant-design/ant-design
|
||||
|
||||
You can override its style but we don't recommend doing so. antd is not only a set of React components but also a design specification.
|
||||
|
||||
### I just want to use `Menu`/`Button`(etc.), but it seems that I have to import the whole of antd and its style.
|
||||
|
||||
Try [babel-plugin-import](https://github.com/ant-design/babel-plugin-import), or import what you need in this way:
|
||||
|
||||
```jsx
|
||||
import Menu from 'antd/es/menu';
|
||||
import 'antd/es/menu/style/css';
|
||||
```
|
||||
|
||||
or (ES6 way with tree shaking):
|
||||
|
||||
```jsx
|
||||
import { Menu, Breadcrumb, Icon } from 'antd';
|
||||
```
|
||||
|
||||
### How to replace Moment.js to Day.js to reduce bundle size?
|
||||
|
||||
Please refer to [Replace Moment.js](/docs/react/replace-moment).
|
||||
|
@ -37,21 +37,6 @@ https://ant.design/components/select/#Select-props
|
||||
|
||||
你可以覆盖它们的样式,但是我们不推荐这么做。antd 是一系列 React 组件,但同样是一套设计规范。
|
||||
|
||||
### 我只想使用 `Menu`/`Button` 等,但似乎我必须 import 整个 antd 和它的样式文件。
|
||||
|
||||
试试 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import),或者用下面这种方式来按需加载:
|
||||
|
||||
```jsx
|
||||
import Menu from 'antd/es/menu';
|
||||
import 'antd/es/menu/style/css';
|
||||
```
|
||||
|
||||
或者(ES6 支持的 tree shaking 方式):
|
||||
|
||||
```jsx
|
||||
import { Menu, Breadcrumb, Icon } from 'antd';
|
||||
```
|
||||
|
||||
### 如何使用 Day.js 替换 Moment.js 来减小打包大小?
|
||||
|
||||
可以参考[替换 Moment.js](/docs/react/replace-moment)。
|
||||
|
@ -95,61 +95,18 @@ In the real world you will need a development workflow consisting of `compile/bu
|
||||
- [d2-admin](https://github.com/d2-projects/d2-admin)
|
||||
- more scaffolds at [Scaffold Market](http://scaffold.ant.design/)
|
||||
|
||||
## Compatibility
|
||||
|
||||
Ant Design React supports all modern browsers and IE11+.
|
||||
|
||||
| [<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 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
Polyfills are needed for IE browsers. We recommend [babel-preset-env](https://babeljs.io/docs/en/babel-preset-env) for it. You can set `targets` config if you are using [umi](http://umijs.org/).
|
||||
|
||||
Ant Design 3.0 supports both React 15 and 16 but we strongly suggest React 16 for better performance and fewer bugs.
|
||||
|
||||
#### IE note
|
||||
|
||||
> We drop support of IE8 after `antd@2.0`, IE9/10 after `antd@4.0`,
|
||||
|
||||
## Customized Work Flow
|
||||
|
||||
If you want to customize your work flow, we recommend using [webpack](http://webpack.github.io/) to build and debug code.
|
||||
|
||||
Also, you can use any [scaffold](https://github.com/enaqx/awesome-react#boilerplates) available in the React ecosystem. If you encounter problems, you can use our [webpack config](https://github.com/ant-tool/atool-build/blob/master/src/getWebpackCommonConfig.js) and [modify it](http://ant-tool.github.io/webpack-config.html).
|
||||
|
||||
If you are trying [parcel](https://parceljs.org), here is [a demo repository](https://github.com/ant-design/parcel-antd).
|
||||
|
||||
There are some [scaffolds](http://scaffold.ant.design/) which have already integrated antd, so you can try and start with one of these and even contribute.
|
||||
|
||||
## Import on Demand
|
||||
|
||||
If you see logs like in the screenshot below, you might be importing all components by writing `import { Button } from 'antd';`. This will affect your app's network performance.
|
||||
`antd` supports tree shaking of ES modules, so using `import { Button } from 'antd';` would drop js code you didn't use.
|
||||
|
||||
If you see logs like in the screenshot below, you might still be using `webpack@1.x` or have a wrong webpack config which can't support tree shaking.
|
||||
|
||||
```
|
||||
You are using a whole package of antd, please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.
|
||||
You are using a whole package of antd, please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size. Please upgrade webpack or check the config.
|
||||
```
|
||||
|
||||
> ![console warning](https://zos.alipayobjects.com/rmsportal/GHIRszVcmjccgZRakJDQ.png)
|
||||
|
||||
However, we can import individual components on demand:
|
||||
|
||||
```jsx
|
||||
import Button from 'antd/es/button';
|
||||
import 'antd/es/button/style'; // or antd/es/button/style/css for css format file
|
||||
```
|
||||
|
||||
> Note: antd supports ES6 tree shaking, so `import { Button } from 'antd';` will drop the js code you don't use too.
|
||||
|
||||
We strongly recommend using [babel-plugin-import](https://github.com/ant-design/babel-plugin-import), which can convert the following code to the 'antd/es/xxx' way:
|
||||
|
||||
```jsx
|
||||
import { Button } from 'antd';
|
||||
```
|
||||
|
||||
And this plugin can load styles too. Read [usage](https://github.com/ant-design/babel-plugin-import#usage) for more details.
|
||||
|
||||
> FYI, babel-plugin-import's `style` option will importing some global reset styles, don't use it if you don't need those styles. You can import styles manually via `import 'antd/dist/antd.css'` and override the global reset styles.
|
||||
|
||||
## Replace momentjs to Day.js
|
||||
|
||||
You can use [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) plugin to replace momentjs to Day.js to reduce bundle size dramatically. You need to update your webpack config file like this:
|
||||
@ -164,7 +121,8 @@ module.exports = {
|
||||
};
|
||||
```
|
||||
|
||||
## Customization
|
||||
## Customized Work Flow
|
||||
|
||||
- [Customize Theme](/docs/react/customize-theme)
|
||||
- [Local Iconfont](https://github.com/ant-design/antd-init/tree/master/examples/local-iconfont)
|
||||
If you want to customize your work flow, we recommend using [webpack](http://webpack.github.io/) to build and debug code. You can try out plents of [boilerplates](https://github.com/enaqx/awesome-react#react-tools) available in the React ecosystem.
|
||||
|
||||
There are some [scaffolds](http://scaffold.ant.design/) which have already integrated antd, so you can try and start with one of these and even contribute.
|
||||
|
@ -99,62 +99,21 @@ render(<App />, document.getElementById('root'));
|
||||
- [d2-admin](https://github.com/d2-projects/d2-admin)
|
||||
- 更多脚手架可以查看 [脚手架市场](http://scaffold.ant.design/)
|
||||
|
||||
## 兼容性
|
||||
|
||||
Ant Design React 支持所有的现代浏览器和 IE11+。
|
||||
|
||||
| [<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 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
对于 IE 系列浏览器,需要提供相应的 Polyfill 支持,建议使用 [babel-preset-env](https://babeljs.io/docs/en/babel-preset-env) 来解决浏览器兼容问题。如果你在使用 [umi](http://umijs.org/),可以直接使用 [targets](https://umijs.org/zh/config/#targets) 配置。
|
||||
|
||||
Ant Design 3.0 对 React 15/16 两个版本提供支持,但是我们强烈建议你升级到 React 16,以便获得更好的性能和遇到更少的问题。
|
||||
|
||||
#### IE note
|
||||
|
||||
> `antd@2.0` 之后将不再支持 IE8,`antd@4.0` 之后将不再支持 IE9/10。
|
||||
|
||||
## 自行构建
|
||||
|
||||
如果想自己维护工作流,我们推荐使用 [webpack](http://webpack.github.io/) 进行构建和调试。理论上你可以利用 React 生态圈中的 [各种脚手架](https://github.com/enaqx/awesome-react#boilerplates) 进行开发,如果遇到问题可参考我们所使用的 [webpack 配置](https://github.com/ant-tool/atool-build/blob/master/src/getWebpackCommonConfig.js) 进行 [定制](http://ant-tool.github.io/webpack-config.html)。
|
||||
|
||||
如果你使用 [parcel](https://parceljs.org),这里也有 [一个例子](https://github.com/ant-design/parcel-antd) 可以参考。
|
||||
|
||||
目前社区也有很多基于 antd 定制的 [脚手架](http://scaffold.ant.design/),欢迎进行试用和贡献。
|
||||
|
||||
## 按需加载
|
||||
|
||||
如果你在开发环境的控制台看到下面的提示,那么你可能使用了 `import { Button } from 'antd';` 的写法引入了 antd 下所有的模块,这会影响应用的网络性能。
|
||||
`antd` 默认支持基于 ES modules 的 tree shaking,对于 js 部分,直接引入 `import { Button } from 'antd'` 就会有按需加载的效果。
|
||||
|
||||
如果你在开发环境的控制台看到下面的提示,那么你可能还在使用 `webpack@1.x` 或者 tree shaking 失效,请升级或检查相关配置。
|
||||
|
||||
```
|
||||
You are using a whole package of antd, please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.
|
||||
```
|
||||
|
||||
> ![控制台警告](https://zos.alipayobjects.com/rmsportal/GHIRszVcmjccgZRakJDQ.png)
|
||||
![控制台警告](https://zos.alipayobjects.com/rmsportal/GHIRszVcmjccgZRakJDQ.png)
|
||||
|
||||
可以通过以下的写法来按需加载组件。
|
||||
## 使用 Day.js 替换 Moment.js 优化打包大小
|
||||
|
||||
```jsx
|
||||
import Button from 'antd/es/button';
|
||||
import 'antd/es/button/style'; // 或者 antd/es/button/style/css 加载 css 文件
|
||||
```
|
||||
|
||||
> 注意:antd 默认支持基于 ES module 的 tree shaking,对于 js 部分,直接引入 `import { Button } from 'antd'` 也会有按需加载的效果。
|
||||
|
||||
如果你使用了 babel,那么可以使用 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 来进行按需加载,加入这个插件后。你可以仍然这么写:
|
||||
|
||||
```jsx
|
||||
import { Button } from 'antd';
|
||||
```
|
||||
|
||||
插件会帮你转换成 `antd/es/xxx` 的写法。另外此插件配合 [style](https://github.com/ant-design/babel-plugin-import#usage) 属性可以做到模块样式的按需自动加载。
|
||||
|
||||
> 注意,babel-plugin-import 的 `style` 属性除了引入对应组件的样式,也会引入一些必要的全局样式。如果你不需要它们,建议不要使用此属性。你可以 `import 'antd/dist/antd.css'` 手动引入,并覆盖全局样式。
|
||||
|
||||
## 使用 Day.js 替换 momentjs 优化打包大小
|
||||
|
||||
你可以使用 [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) 插件用 Day.js 替换 momentjs 来大幅减小打包大小。这需要更新 webpack 的配置文件如下:
|
||||
你可以使用 [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) 插件用 [Day.js](https://day.js.org/) 替换 Moment.js 来大幅减小打包大小。这需要更新 webpack 的配置文件如下:
|
||||
|
||||
```js
|
||||
// webpack-config.js
|
||||
@ -166,7 +125,8 @@ module.exports = {
|
||||
};
|
||||
```
|
||||
|
||||
## 配置主题和字体
|
||||
## 自行构建
|
||||
|
||||
- [改变主题](/docs/react/customize-theme)
|
||||
- [使用本地字体](https://github.com/ant-design/antd-init/tree/master/examples/local-iconfont)
|
||||
如果想自己维护工作流,我们推荐使用 [webpack](https://webpack.github.io/) 进行构建和调试,可以使用 React 生态圈中的 [各种脚手架](https://github.com/enaqx/awesome-react#react-tools) 进行开发。
|
||||
|
||||
目前社区也有很多基于 antd 定制的 [React 脚手架](http://scaffold.ant.design/),欢迎进行试用和贡献。
|
||||
|
@ -36,10 +36,20 @@ Following the Ant Design specification, we developed a React UI library `antd` t
|
||||
|
||||
## Environment Support
|
||||
|
||||
- Modern browsers and Internet Explorer 11 (with [polyfills](/docs/react/getting-started#Compatibility))
|
||||
- Modern browsers and Internet Explorer 11 (with [polyfills](https://ant.design/docs/react/getting-started#Compatibility))
|
||||
- Server-side Rendering
|
||||
- [Electron](https://www.electronjs.org/)
|
||||
|
||||
| [<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 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
Polyfills are needed for IE browsers. We recommend [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env) for it. You can set `targets` config if you are using [umi](http://umijs.org/).
|
||||
|
||||
`antd@3.x` supports both React 15 and 16 but we strongly suggest React 16 for better performance and fewer bugs.
|
||||
|
||||
> We drop support of IE8 after `antd@2.0`, IE9/10 after `antd@4.0`,
|
||||
|
||||
## Version
|
||||
|
||||
- Stable: [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd)
|
||||
@ -88,37 +98,11 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
|
||||
### Use modularized antd
|
||||
|
||||
> Note: antd support ES6 tree shaking by default even without the below plugin.
|
||||
|
||||
- Use [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) (Recommended)
|
||||
|
||||
```js
|
||||
// .babelrc or babel-loader option
|
||||
{
|
||||
"plugins": [
|
||||
["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] // `style: true` for less
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This allows you to import components from antd without having to manually import the corresponding stylesheet. The antd babel plugin will automatically import stylesheets.
|
||||
|
||||
```jsx
|
||||
// import js and css modularly, parsed by babel-plugin-import
|
||||
import { DatePicker } from 'antd';
|
||||
```
|
||||
|
||||
- Manually import
|
||||
|
||||
```jsx
|
||||
import DatePicker from 'antd/es/date-picker'; // for js
|
||||
import 'antd/es/date-picker/style/css'; // for css
|
||||
// import 'antd/es/date-picker/style'; // that will import less
|
||||
```
|
||||
`antd` supports ES modules tree shaking by default for JS part.
|
||||
|
||||
### TypeScript
|
||||
|
||||
- Don't use @types/antd, as antd provides a built-in ts definition already.
|
||||
`antd` provides a built-in ts definition, don't install @types/antd`.
|
||||
|
||||
## Links
|
||||
|
||||
|
@ -34,11 +34,21 @@ title: Ant Design of React
|
||||
- 🌍 数十个国际化语言支持。
|
||||
- 🎨 深入每个细节的主题定制能力。
|
||||
|
||||
## 支持环境
|
||||
## 兼容环境
|
||||
|
||||
- 现代浏览器和 IE11(需要 [polyfills](/docs/react/getting-started-cn#兼容性))。
|
||||
- 现代浏览器和 IE11(需要 [polyfills](https://ant.design/docs/react/getting-started-cn#兼容性))。
|
||||
- 支持服务端渲染。
|
||||
- [Electron](https://electronjs.org/)
|
||||
- [Electron](https://www.electronjs.org/)
|
||||
|
||||
| [<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 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
对于 IE 系列浏览器,需要提供相应的 Polyfill 支持,建议使用 [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env) 来解决浏览器兼容问题。如果你在使用 [umi](http://umijs.org/),可以直接使用 [targets](https://umijs.org/zh/config/#targets) 配置。
|
||||
|
||||
`antd@3.x` 对 React 15/16 两个版本提供支持,但是我们强烈建议你升级到 React 16,以便获得更好的性能和遇到更少的问题。
|
||||
|
||||
> `antd@2.0` 之后不再支持 IE8,`antd@4.0` 之后不再支持 IE9/10。
|
||||
|
||||
## 版本
|
||||
|
||||
@ -88,39 +98,11 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
|
||||
### 按需加载
|
||||
|
||||
> 注意:antd 默认支持基于 ES module 的 tree shaking,不使用以下插件也会有按需加载的效果。
|
||||
`antd` 的 JS 代码默认支持基于 ES modules 的 tree shaking。
|
||||
|
||||
下面两种方式都可以只加载用到的组件。
|
||||
### TypeScript
|
||||
|
||||
- 使用 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import)(推荐)。
|
||||
|
||||
```js
|
||||
// .babelrc or babel-loader option
|
||||
{
|
||||
"plugins": [
|
||||
["import", {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": "css" // `style: true` 会加载 less 文件
|
||||
}]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
然后只需从 antd 引入模块即可,无需单独引入样式。等同于下面手动引入的方式。
|
||||
|
||||
```jsx
|
||||
// babel-plugin-import 会帮助你加载 JS 和 CSS
|
||||
import { DatePicker } from 'antd';
|
||||
```
|
||||
|
||||
- 手动引入
|
||||
|
||||
```jsx
|
||||
import DatePicker from 'antd/es/date-picker'; // 加载 JS
|
||||
import 'antd/es/date-picker/style/css'; // 加载 CSS
|
||||
// import 'antd/es/date-picker/style'; // 加载 LESS
|
||||
```
|
||||
`antd` 使用 TypeScript 进行书写并提供了完整的定义文件。(不要引用 `@types/antd`)。
|
||||
|
||||
## 链接
|
||||
|
||||
|
@ -46,20 +46,16 @@ $ yarn add antd
|
||||
|
||||
Modify `src/App.tsx`, import Button component from `antd`.
|
||||
|
||||
```jsx
|
||||
import React, { Component } from 'react';
|
||||
import Button from 'antd/es/button';
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
const App: FC = () => (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
@ -68,131 +64,93 @@ Add `antd/dist/antd.css` at the top of `src/App.css`.
|
||||
|
||||
```css
|
||||
@import '~antd/dist/antd.css';
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Ok, reboot with `yarn start`, you should now see a blue primary button displayed on the page. Next you can choose any components of `antd` to develop your application. Visit other workflows of `create-react-app` at it's [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md).
|
||||
Ok, reboot with `yarn start`, you should now see a blue primary button displayed on the page. Next you can choose any components of `antd` to develop your application. Visit other workflows of `create-react-app` at it's [User Guide](https://create-react-app.dev/docs/getting-started#creating-a-typescript-app).
|
||||
|
||||
`antd` is written in TypeScript with complete definitions, try out and enjoy the property suggestion and typing check.
|
||||
|
||||
![](https://gw.alipayobjects.com/zos/antfincdn/26L5vPoLug/8d7da796-175e-40af-8eea-e7031ba09f9f.png)
|
||||
|
||||
> Don't install `@types/antd`.
|
||||
|
||||
## Advanced Guides
|
||||
|
||||
We are successfully running antd components now but in the real world, there are still lots of problems about antd-demo-ts. For instance, we actually import all styles of components in the project which may be a network performance issue.
|
||||
In the real world, we usually have to modify default webpack config for custom needs such as themes. We can achieve that by using [craco](https://github.com/gsoft-inc/craco) which is one of create-react-app's custom config solutions.
|
||||
|
||||
Now we need to customize the default webpack config. We can achieve that by using [react-app-rewired](https://github.com/timarney/react-app-rewired) which is one of create-react-app's custom config solutions.
|
||||
Install craco and modify the `scripts` field in `package.json`.
|
||||
|
||||
Import react-app-rewired and modify the `scripts` field in package.json. Due to new [react-app-rewired@2.x](https://github.com/timarney/react-app-rewired#alternatives) issue, you shall need [customize-cra](https://github.com/arackaf/customize-cra) along with react-app-rewired.
|
||||
|
||||
```
|
||||
$ yarn add react-app-rewired customize-cra
|
||||
```bash
|
||||
$ yarn add @craco/craco
|
||||
```
|
||||
|
||||
```diff
|
||||
/* package.json */
|
||||
"scripts": {
|
||||
- "start": "react-scripts start",
|
||||
+ "start": "react-app-rewired start",
|
||||
- "build": "react-scripts build",
|
||||
+ "build": "react-app-rewired build",
|
||||
- "test": "react-scripts test",
|
||||
+ "test": "react-app-rewired test",
|
||||
+ "start": "craco start",
|
||||
+ "build": "craco build",
|
||||
+ "test": "craco test",
|
||||
}
|
||||
```
|
||||
|
||||
Then create a `config-overrides.js` at root directory of your project for further overriding.
|
||||
Then create a `craco.config.js` at root directory of your project for further overriding.
|
||||
|
||||
```js
|
||||
module.exports = function override(config, env) {
|
||||
// do stuff with the webpack config...
|
||||
return config;
|
||||
/* craco.config.js */
|
||||
module.exports = {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### Use babel-plugin-import
|
||||
|
||||
[babel-plugin-import](https://github.com/ant-design/babel-plugin-import) is a babel plugin for importing components on demand ([How does it work?](/docs/react/getting-started#Import-on-Demand)). We are now trying to install it and modify `config-overrides.js`.
|
||||
|
||||
```bash
|
||||
$ yarn add babel-plugin-import
|
||||
```
|
||||
|
||||
```diff
|
||||
+ const { override, fixBabelImports } = require('customize-cra');
|
||||
|
||||
- module.exports = function override(config, env) {
|
||||
- // do stuff with the webpack config...
|
||||
- return config;
|
||||
- };
|
||||
+ module.exports = override(
|
||||
+ fixBabelImports('import', {
|
||||
+ libraryName: 'antd',
|
||||
+ libraryDirectory: 'es',
|
||||
+ style: 'css',
|
||||
+ }),
|
||||
+ );
|
||||
```
|
||||
|
||||
Remove the `@import '~antd/dist/antd.css';` statement added before because `babel-plugin-import` will import styles and import components like below:
|
||||
|
||||
```diff
|
||||
// src/App.js
|
||||
import React, { Component } from 'react';
|
||||
- import Button from 'antd/es/button';
|
||||
+ import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
const App: React.FC<{}> = () => (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
Then reboot with `yarn start` and visit the demo page, you should not find any [warning messages](https://zos.alipayobjects.com/rmsportal/vgcHJRVZFmPjAawwVoXK.png) in the console, which prove that the `import on demand` config is working now. You will find more info about it in [this guide](/docs/react/getting-started#Import-on-Demand).
|
||||
|
||||
### Customize Theme
|
||||
|
||||
According to the [Customize Theme documentation](/docs/react/customize-theme), to customize the theme, we need to modify `less` variables with tools such as [less-loader](https://github.com/webpack/less-loader). We can also use [addLessLoader](https://github.com/arackaf/customize-cra/blob/master/api.md#addlessloaderloaderoptions) to achieve this. Import it and modify `config-overrides.js` like below.
|
||||
According to the [Customize Theme documentation](/docs/react/customize-theme), we need to modify less variables via loader like [less-loader](https://github.com/webpack/less-loader). We can use [craco-less](https://github.com/DocSpring/craco-less) to achieve that,
|
||||
|
||||
```bash
|
||||
$ yarn add less less-loader
|
||||
```
|
||||
First we should import less other then css.
|
||||
|
||||
```diff
|
||||
- const { override, fixBabelImports } = require('customize-cra');
|
||||
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
|
||||
|
||||
module.exports = override(
|
||||
fixBabelImports('import', {
|
||||
libraryName: 'antd',
|
||||
libraryDirectory: 'es',
|
||||
- style: 'css',
|
||||
+ style: true,
|
||||
}),
|
||||
+ addLessLoader({
|
||||
+ javascriptEnabled: true,
|
||||
+ modifyVars: { '@primary-color': '#1DA57A' },
|
||||
+ }),
|
||||
);
|
||||
- @import '~antd/dist/antd.css';
|
||||
+ @import '~antd/dist/antd.less';
|
||||
```
|
||||
|
||||
We use `modifyVars` option of [less-loader](https://github.com/webpack/less-loader#less-options) here, you can see a green button rendered on the page after rebooting the start server.
|
||||
Then install `craco-less` and modify `craco.config.js` like below.
|
||||
|
||||
> You could also try [craco](https://github.com/sharegate/craco) and [craco-antd](https://github.com/FormAPI/craco-antd) to customize create-react-app webpack config same as customize-cra does.
|
||||
```bash
|
||||
$ yarn add craco-less
|
||||
```
|
||||
|
||||
```js
|
||||
const CracoLessPlugin = require('craco-less');
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
{
|
||||
plugin: CracoLessPlugin,
|
||||
options: {
|
||||
lessLoaderOptions: {
|
||||
modifyVars: { '@primary-color': '#1DA57A' },
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
By adding `modifyVars` option of [less-loader](https://github.com/webpack/less-loader#less-options) here, we should see a green button rendered on the page after rebooting the server now.
|
||||
|
||||
We provide built-in dark theme and compact theme in antd, you can reference to [Use dark or compact theme](/docs/react/customize-theme#Use-dark-or-compact-theme).
|
||||
|
||||
> You could also try [react-scripts-rewired](https://github.com/timarney/react-app-rewired) and [customize-cra](https://github.com/arackaf/customize-cra) to customize create-react-app webpack config like craco did.
|
||||
|
||||
## Alternative ways
|
||||
|
||||
You can also follow instructions in [Use in create-react-app](/docs/react/use-with-create-react-app), then use to setup the TypeScript development environment by yourself.
|
||||
|
||||
And you can use [react-scripts-ts-antd](https://www.npmjs.com/package/react-scripts-ts-antd) which includes ts-import-plugin, react-app-rewired, scss, less and etc. You can create a new project that without any configurations by running just one command.
|
||||
Follow manual in [Adding TypeScript](https://create-react-app.dev/docs/adding-typescript) to setup TypeScript development environment if you already create a project by [Use in create-react-app](/docs/react/use-with-create-react-app).
|
||||
|
||||
- [Create React apps (with Typescript and antd) with no build configuration](https://github.com/SZzzzz/react-scripts-ts-antd)
|
||||
- [react-app-rewire-typescript](https://github.com/lwd-technology/react-app-rewire-typescript)
|
||||
- [ts-import-plugin](https://github.com/Brooooooklyn/ts-import-plugin)
|
||||
- [create-react-app Adding TypeScript](https://facebook.github.io/create-react-app/docs/adding-typescript)
|
||||
- [Migrating from create-react-app-typescript to Create React App](https://vincenttunru.com/migrate-create-react-app-typescript-to-create-react-app/)
|
||||
|
@ -17,10 +17,6 @@ title: 在 TypeScript 中使用
|
||||
|
||||
```bash
|
||||
$ yarn create react-app antd-demo-ts --template typescript
|
||||
|
||||
# or
|
||||
|
||||
npx create-react-app my-app --template typescript
|
||||
```
|
||||
|
||||
如果你使用的是 npm(接下来我们都会用 yarn 作为例子,如果你习惯用 npm 也没问题)。
|
||||
@ -46,151 +42,113 @@ $ yarn add antd
|
||||
|
||||
修改 `src/App.tsx`,引入 antd 的按钮组件。
|
||||
|
||||
```jsx
|
||||
import React, { Component } from 'react';
|
||||
import Button from 'antd/es/button';
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
const App: FC = () => (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
修改 `src/App.css` 引入 antd 的样式。
|
||||
修改 `src/App.css`,在文件顶部引入 antd 的样式。
|
||||
|
||||
```css
|
||||
@import '~antd/dist/antd.css';
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
重新启动 `yarn start`,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的[官方文档](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md)。
|
||||
重新启动 `yarn start`,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的[官方文档](https://create-react-app.dev/docs/getting-started#creating-a-typescript-app)。
|
||||
|
||||
`antd` 使用 TypeScript 书写并提供了完整的定义,你可以享受组件属性输入建议和定义检查的功能。
|
||||
|
||||
![](https://gw.alipayobjects.com/zos/antfincdn/26L5vPoLug/8d7da796-175e-40af-8eea-e7031ba09f9f.png)
|
||||
|
||||
> 注意不要安装 `@types/antd`。
|
||||
|
||||
## 高级配置
|
||||
|
||||
我们现在已经把组件成功运行起来了,但是在实际开发过程中还有很多问题,例如上面的例子实际上加载了全部的 antd 组件的样式(对前端性能是个隐患)。
|
||||
这个例子在实际开发中还有一些优化的空间,比如无法进行主题配置。
|
||||
|
||||
此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 [react-app-rewired](https://github.com/timarney/react-app-rewired) (一个对 create-react-app 进行自定义配置的社区解决方案)。
|
||||
此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 [craco](https://github.com/gsoft-inc/craco) (一个对 create-react-app 进行自定义配置的社区解决方案)。
|
||||
|
||||
引入 react-app-rewired 并修改 package.json 里的启动配置。由于新的 [react-app-rewired@2.x](https://github.com/timarney/react-app-rewired#alternatives) 版本的关系,你还需要安装 [customize-cra](https://github.com/arackaf/customize-cra)。
|
||||
现在我们安装 craco 并修改 `package.json` 里的 `scripts` 属性。
|
||||
|
||||
```
|
||||
$ yarn add react-app-rewired customize-cra
|
||||
```bash
|
||||
$ yarn add @craco/craco
|
||||
```
|
||||
|
||||
```diff
|
||||
/* package.json */
|
||||
"scripts": {
|
||||
- "start": "react-scripts start",
|
||||
+ "start": "react-app-rewired start",
|
||||
- "build": "react-scripts build",
|
||||
+ "build": "react-app-rewired build",
|
||||
- "test": "react-scripts test",
|
||||
+ "test": "react-app-rewired test",
|
||||
+ "start": "craco start",
|
||||
+ "build": "craco build",
|
||||
+ "test": "craco test",
|
||||
}
|
||||
```
|
||||
|
||||
然后在项目根目录创建一个 `config-overrides.js` 用于修改默认配置。
|
||||
然后在项目根目录创建一个 `craco.config.js` 用于修改默认配置。
|
||||
|
||||
```js
|
||||
module.exports = function override(config, env) {
|
||||
// do stuff with the webpack config...
|
||||
return config;
|
||||
/* craco.config.js */
|
||||
module.exports = {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### 使用 babel-plugin-import
|
||||
|
||||
[babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 是一个用于按需加载组件代码和样式的 babel 插件([原理](/docs/react/getting-started#按需加载)),现在我们尝试安装它并修改 `config-overrides.js` 文件。
|
||||
|
||||
```bash
|
||||
$ yarn add babel-plugin-import
|
||||
```
|
||||
|
||||
```diff
|
||||
+ const { override, fixBabelImports } = require('customize-cra');
|
||||
|
||||
- module.exports = function override(config, env) {
|
||||
- // do stuff with the webpack config...
|
||||
- return config;
|
||||
- };
|
||||
+ module.exports = override(
|
||||
+ fixBabelImports('import', {
|
||||
+ libraryName: 'antd',
|
||||
+ libraryDirectory: 'es',
|
||||
+ style: 'css',
|
||||
+ }),
|
||||
+ );
|
||||
```
|
||||
|
||||
然后移除前面在 `src/App.css` 里全量添加的 `@import '~antd/dist/antd.css';` 样式代码,并且按下面的格式引入模块。
|
||||
|
||||
```diff
|
||||
// src/App.tsx
|
||||
import React, { Component } from 'react';
|
||||
- import Button from 'antd/es/button';
|
||||
+ import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
const App: React.FC<{}> = () => (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
最后重启 `yarn start` 访问页面,antd 组件的 js 和 css 代码都会按需加载,你在控制台也不会看到这样的[警告信息](https://zos.alipayobjects.com/rmsportal/vgcHJRVZFmPjAawwVoXK.png)。关于按需加载的原理和其他方式可以阅读[这里](/docs/react/getting-started#按需加载)。
|
||||
|
||||
### 自定义主题
|
||||
|
||||
按照 [配置主题](/docs/react/customize-theme) 的要求,自定义主题需要用到 less 变量覆盖功能。我们可以引入 `customize-cra` 中提供的 less 相关的函数 [addLessLoader](https://github.com/arackaf/customize-cra/blob/master/api.md#addlessloaderloaderoptions) 来帮助加载 less 样式,同时修改 `config-overrides.js` 文件如下。
|
||||
按照 [配置主题](/docs/react/customize-theme) 的要求,自定义主题需要用到类似 [less-loader](https://github.com/webpack-contrib/less-loader/) 提供的 less 变量覆盖功能。我们可以引入 [craco-less](https://github.com/DocSpring/craco-less) 来帮助加载 less 样式和修改变量。
|
||||
|
||||
首先修改样式引用为 less 文件。
|
||||
|
||||
```diff
|
||||
- const { override, fixBabelImports } = require('customize-cra');
|
||||
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
|
||||
|
||||
module.exports = override(
|
||||
fixBabelImports('import', {
|
||||
libraryName: 'antd',
|
||||
libraryDirectory: 'es',
|
||||
- style: 'css',
|
||||
+ style: true,
|
||||
}),
|
||||
+ addLessLoader({
|
||||
+ javascriptEnabled: true,
|
||||
+ modifyVars: { '@primary-color': '#1DA57A' },
|
||||
+ }),
|
||||
);
|
||||
- @import '~antd/dist/antd.css';
|
||||
+ @import '~antd/dist/antd.less';
|
||||
```
|
||||
|
||||
这里利用了 [less-loader](https://github.com/webpack/less-loader#less-options) 的 `modifyVars` 来进行主题配置,变量和其他配置方式可以参考 [配置主题](/docs/react/customize-theme) 文档。
|
||||
然后安装 `craco-less` 并修改 `config-overrides.js` 文件如下。
|
||||
|
||||
修改后重启 `yarn start`,如果看到一个绿色的按钮就说明配置成功了。
|
||||
```bash
|
||||
$ yarn add craco-less
|
||||
```
|
||||
|
||||
> 对于自定义 webpack 配置,你也可以使用 [craco](https://github.com/sharegate/craco) 和 [craco-antd](https://github.com/FormAPI/craco-antd) 来实现和 customize-cra 一样的修改 create-react-app 配置的功能。
|
||||
```js
|
||||
const CracoLessPlugin = require('craco-less');
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
{
|
||||
plugin: CracoLessPlugin,
|
||||
options: {
|
||||
lessLoaderOptions: {
|
||||
modifyVars: { '@primary-color': '#1DA57A' },
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
这里利用了 [less-loader](https://github.com/webpack/less-loader#less-options) 的 `modifyVars` 来进行主题配置,变量和其他配置方式可以参考 [配置主题](/docs/react/customize-theme) 文档。修改后重启 `yarn start`,如果看到一个绿色的按钮就说明配置成功了。
|
||||
|
||||
antd 内建了深色主题和紧凑主题,你可以参照 [使用暗色主题和紧凑主题](/docs/react/customize-theme#使用暗色主题和紧凑主题) 进行接入。
|
||||
|
||||
> 同样,你可以使用 [react-scripts-rewired](https://github.com/timarney/react-app-rewired) 和 [customize-cra](https://github.com/arackaf/customize-cra) 来自定义 create-react-app 的 webpack 配置。
|
||||
|
||||
## 其他方案
|
||||
|
||||
先按照 [在 create-react-app 中使用](/docs/react/use-with-create-react-app) 中的说明操作,再配置 TypeScript 开发环境。
|
||||
|
||||
你也可以使用 [react-scripts-ts-antd](https://www.npmjs.com/package/react-scripts-ts-antd),其中包括了 ts-import-plugin,react-app-rewired,scss,less 等插件。你可以通过只运行一个命令来创建一个没有任何配置的新项目。
|
||||
如果你已经按照 [在 create-react-app 中使用](/docs/react/use-with-create-react-app) 初始化了环境,可以参考官方文档里的 [Adding TypeScript](https://create-react-app.dev/docs/adding-typescript) 配置 TypeScript 开发环境。
|
||||
|
||||
- [Create React apps (with Typescript and antd) with no build configuration](https://github.com/SZzzzz/react-scripts-ts-antd)
|
||||
- [react-app-rewire-typescript](https://github.com/lwd-technology/react-app-rewire-typescript)
|
||||
- [ts-import-plugin](https://github.com/Brooooooklyn/ts-import-plugin)
|
||||
- [create-react-app Adding TypeScript](https://facebook.github.io/create-react-app/docs/adding-typescript)
|
||||
- [Migrating from create-react-app-typescript to Create React App](https://vincenttunru.com/migrate-create-react-app-typescript-to-create-react-app/)
|
||||
|
@ -76,30 +76,20 @@ Add `antd/dist/antd.css` at the top of `src/App.css`.
|
||||
|
||||
```css
|
||||
@import '~antd/dist/antd.css';
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Ok, you should now see a blue primary button displayed on the page. Next you can choose any components of `antd` to develop your application. Visit other workflows of `create-react-app` at its [User Guide](https://github.com/facebook/create-react-app/blob/master/packages/cra-template/template/README.md).
|
||||
Ok, you should now see a blue primary button displayed on the page. Next you can choose any components of `antd` to develop your application. Visit other workflows of `create-react-app` at its [User Guide](https://create-react-app.dev/docs/getting-started).
|
||||
|
||||
We are successfully running antd components now, go build your own application!
|
||||
|
||||
## Advanced Guides
|
||||
|
||||
In the real world, there are still lots of problems about antd-demo. For instance, we actually import styles of all components in the project which may be a css bundle size issue (It is OK then if you don't care the gzipped 60kb css file size).
|
||||
In the real world, we usually have to modify default webpack config for custom needs such as themes. We can achieve that by using [craco](https://github.com/gsoft-inc/craco) which is one of create-react-app's custom config solutions.
|
||||
|
||||
Now we need to customize the default webpack config. We can achieve that by using [react-app-rewired](https://github.com/timarney/react-app-rewired) which is one of create-react-app's custom config solutions.
|
||||
|
||||
Import react-app-rewired and modify the `scripts` field in package.json. Due to new [react-app-rewired@2.x](https://github.com/timarney/react-app-rewired#alternatives) issue, you shall need [customize-cra](https://github.com/arackaf/customize-cra) along with react-app-rewired.
|
||||
Install craco and modify the `scripts` field in `package.json`.
|
||||
|
||||
```bash
|
||||
$ yarn add react-app-rewired customize-cra
|
||||
# use less-loader@6.0.0
|
||||
$ yarn add react-app-rewired customize-cra@next
|
||||
$ yarn add @craco/craco
|
||||
```
|
||||
|
||||
```diff
|
||||
@ -108,130 +98,68 @@ $ yarn add react-app-rewired customize-cra@next
|
||||
- "start": "react-scripts start",
|
||||
- "build": "react-scripts build",
|
||||
- "test": "react-scripts test",
|
||||
+ "start": "react-app-rewired start",
|
||||
+ "build": "react-app-rewired build",
|
||||
+ "test": "react-app-rewired test",
|
||||
+ "start": "craco start",
|
||||
+ "build": "craco build",
|
||||
+ "test": "craco test",
|
||||
}
|
||||
```
|
||||
|
||||
Then create a `config-overrides.js` at root directory of your project for further overriding.
|
||||
Then create a `craco.config.js` at root directory of your project for further overriding.
|
||||
|
||||
```js
|
||||
module.exports = function override(config, env) {
|
||||
// do stuff with the webpack config...
|
||||
return config;
|
||||
/* craco.config.js */
|
||||
module.exports = {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### Use babel-plugin-import
|
||||
|
||||
> Note: antd support ES6 tree shaking by default even without this babel plugin for js part.
|
||||
|
||||
[babel-plugin-import](https://github.com/ant-design/babel-plugin-import) is a babel plugin for importing components on demand ([How does it work?](/docs/react/getting-started#Import-on-Demand)). We are now trying to install it and modify `config-overrides.js`.
|
||||
|
||||
```bash
|
||||
$ yarn add babel-plugin-import
|
||||
```
|
||||
|
||||
```diff
|
||||
+ const { override, fixBabelImports } = require('customize-cra');
|
||||
|
||||
- module.exports = function override(config, env) {
|
||||
- // do stuff with the webpack config...
|
||||
- return config;
|
||||
- };
|
||||
+ module.exports = override(
|
||||
+ fixBabelImports('antd', {
|
||||
+ libraryDirectory: 'es',
|
||||
+ style: 'css',
|
||||
+ }),
|
||||
+ );
|
||||
```
|
||||
|
||||
Remove the `@import '~antd/dist/antd.css';` statement added before because `babel-plugin-import` will import styles and import components like below:
|
||||
|
||||
```diff
|
||||
// src/App.js
|
||||
import React, { Component } from 'react';
|
||||
- import Button from 'antd/es/button';
|
||||
+ import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
const App = () => (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
Then reboot with `yarn start` and visit the demo page, you should not find any [warning messages](https://zos.alipayobjects.com/rmsportal/vgcHJRVZFmPjAawwVoXK.png) in the console, which prove that the `import on demand` config is working now. You will find more info about it in [this guide](/docs/react/getting-started#Import-on-Demand).
|
||||
|
||||
### Customize Theme
|
||||
|
||||
According to the [Customize Theme documentation](/docs/react/customize-theme), to customize the theme, we need to modify `less` variables with tools such as [less-loader](https://github.com/webpack/less-loader). We can also use [addLessLoader](https://github.com/arackaf/customize-cra/blob/master/api.md#addlessloaderloaderoptions) to achieve this. Import it and modify `config-overrides.js` like below.
|
||||
According to the [Customize Theme documentation](/docs/react/customize-theme), we need to modify less variables via loader like [less-loader](https://github.com/webpack/less-loader). We can use [craco-less](https://github.com/DocSpring/craco-less) to achieve that,
|
||||
|
||||
```bash
|
||||
$ yarn add less less-loader
|
||||
```
|
||||
First we should import less other then css.
|
||||
|
||||
```diff
|
||||
- const { override, fixBabelImports } = require('customize-cra');
|
||||
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
|
||||
|
||||
module.exports = override(
|
||||
fixBabelImports('antd', {
|
||||
libraryDirectory: 'es',
|
||||
- style: 'css',
|
||||
+ style: true,
|
||||
}),
|
||||
+ addLessLoader({
|
||||
+ lessOptions: { // If you are using less-loader@5 please spread the lessOptions to options directly
|
||||
+ javascriptEnabled: true,
|
||||
+ modifyVars: { '@primary-color': '#1DA57A' },
|
||||
+ },
|
||||
+ }),
|
||||
);
|
||||
- @import '~antd/dist/antd.css';
|
||||
+ @import '~antd/dist/antd.less';
|
||||
```
|
||||
|
||||
We use `modifyVars` option of [less-loader](https://github.com/webpack/less-loader#less-options) here. If you see a green button rendered on the page after rebooting the server, then the configuration was successful.
|
||||
|
||||
We have built-in dark theme and compact theme in antd, you can reference to [Use dark or compact theme](/docs/react/customize-theme#Use-dark-or-compact-theme).
|
||||
|
||||
> You could also try [craco](https://github.com/sharegate/craco) and [craco-antd](https://github.com/FormAPI/craco-antd) to customize create-react-app webpack config same as customize-cra does.
|
||||
|
||||
> Note: It is recommended to use the latest version of `less`, or a minimum version greater than `3.0.1`.
|
||||
|
||||
## Replace momentjs to Day.js
|
||||
|
||||
You can use [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) plugin to replace momentjs to Day.js to reduce bundle size dramatically.
|
||||
Then install `craco-less` and modify `craco.config.js` like below.
|
||||
|
||||
```bash
|
||||
$ yarn add antd-dayjs-webpack-plugin
|
||||
$ yarn add craco-less
|
||||
```
|
||||
|
||||
```js
|
||||
const { override, addWebpackPlugin } = require('customize-cra');
|
||||
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin');
|
||||
const CracoLessPlugin = require('craco-less');
|
||||
|
||||
module.exports = override(addWebpackPlugin(new AntdDayjsWebpackPlugin()));
|
||||
module.exports = {
|
||||
plugins: [
|
||||
{
|
||||
plugin: CracoLessPlugin,
|
||||
options: {
|
||||
lessLoaderOptions: {
|
||||
modifyVars: { '@primary-color': '#1DA57A' },
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
By adding `modifyVars` option of [less-loader](https://github.com/webpack/less-loader#less-options) here, we should see a green button rendered on the page after rebooting the server now.
|
||||
|
||||
We provide built-in dark theme and compact theme in antd, you can reference to [Use dark or compact theme](/docs/react/customize-theme#Use-dark-or-compact-theme).
|
||||
|
||||
> You could also try [react-scripts-rewired](https://github.com/timarney/react-app-rewired) and [customize-cra](https://github.com/arackaf/customize-cra) to customize create-react-app webpack config like craco did.
|
||||
|
||||
## eject
|
||||
|
||||
You can also eject your application using [yarn run eject](https://facebook.github.io/create-react-app/docs/available-scripts#npm-run-eject) for a custom setup of create-react-app, although you should dig into it by yourself.
|
||||
|
||||
## Source code and other boilerplates
|
||||
## Summary
|
||||
|
||||
Finally, we used antd with create-react-app successfully, you can learn these practices for your own webpack workflow too, and find more webpack configs in the [atool-build](https://github.com/ant-tool/atool-build/blob/master/src/getWebpackCommonConfig.js). (For instance, add [moment noParse](https://github.com/ant-tool/atool-build/blob/e4bd2959689b6a95cb5c1c854a5db8c98676bdb3/src/getWebpackCommonConfig.js#L90) to avoid loading all language files.)
|
||||
Finally, we used antd with create-react-app successfully, the source code of this guide was pushed to [create-react-app-antd](https://github.com/ant-design/create-react-app-antd) which you could clone and use it directly.
|
||||
|
||||
There are a lot of great boilerplates like create-react-app in the React community. There are some source code samples of importing antd in them if you encounter some problems.
|
||||
|
||||
- [create-react-app-antd](https://github.com/ant-design/create-react-app-antd)
|
||||
- [comerc/cra-ts-antd](https://github.com/comerc/cra-ts-antd)
|
||||
- [react-boilerplate/react-boilerplate](https://github.com/ant-design/react-boilerplate)
|
||||
- [kriasoft/react-starter-kit](https://github.com/ant-design/react-starter-kit)
|
||||
- [next.js](https://github.com/zeit/next.js/tree/master/examples/with-ant-design)
|
||||
- [nwb](https://github.com/insin/nwb-examples/tree/master/react-app-antd)
|
||||
- [antd-react-scripts](https://github.com/minesaner/create-react-app/tree/antd/packages/react-scripts)
|
||||
Next part, We will intruduce how to use antd in [TypeScript](/docs/react/use-in-typescript) and [Umi](/docs/react/practical-projects), let's keep moving!
|
||||
|
@ -60,7 +60,7 @@ $ yarn add antd
|
||||
|
||||
```jsx
|
||||
import React from 'react';
|
||||
import Button from 'antd/es/button';
|
||||
import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
const App = () => (
|
||||
@ -76,30 +76,22 @@ export default App;
|
||||
|
||||
```css
|
||||
@import '~antd/dist/antd.css';
|
||||
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
好了,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的[官方文档](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md)。
|
||||
好了,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的[官方文档](https://create-react-app.dev/docs/getting-started)。
|
||||
|
||||
我们现在已经把 antd 组件成功运行起来了,开始开发你的应用吧!
|
||||
|
||||
## 高级配置
|
||||
|
||||
这个例子在实际开发中还有一些优化的空间,比如无法进行主题配置,而且上面的例子加载了全部的 antd 组件的样式(gzipped 后一共大约 60kb)。
|
||||
这个例子在实际开发中还有一些优化的空间,比如无法进行主题配置。
|
||||
|
||||
此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 [react-app-rewired](https://github.com/timarney/react-app-rewired) (一个对 create-react-app 进行自定义配置的社区解决方案)。
|
||||
此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 [craco](https://github.com/gsoft-inc/craco) (一个对 create-react-app 进行自定义配置的社区解决方案)。
|
||||
|
||||
引入 react-app-rewired 并修改 package.json 里的启动配置。由于新的 [react-app-rewired@2.x](https://github.com/timarney/react-app-rewired#alternatives) 版本的关系,你还需要安装 [customize-cra](https://github.com/arackaf/customize-cra)。
|
||||
现在我们安装 craco 并修改 `package.json` 里的 `scripts` 属性。
|
||||
|
||||
```bash
|
||||
$ yarn add react-app-rewired customize-cra
|
||||
# 使用less-loader@6.0.0
|
||||
$ yarn add react-app-rewired customize-cra@next
|
||||
$ yarn add @craco/craco
|
||||
```
|
||||
|
||||
```diff
|
||||
@ -108,130 +100,70 @@ $ yarn add react-app-rewired customize-cra@next
|
||||
- "start": "react-scripts start",
|
||||
- "build": "react-scripts build",
|
||||
- "test": "react-scripts test",
|
||||
+ "start": "react-app-rewired start",
|
||||
+ "build": "react-app-rewired build",
|
||||
+ "test": "react-app-rewired test",
|
||||
+ "start": "craco start",
|
||||
+ "build": "craco build",
|
||||
+ "test": "craco test",
|
||||
}
|
||||
```
|
||||
|
||||
然后在项目根目录创建一个 `config-overrides.js` 用于修改默认配置。
|
||||
然后在项目根目录创建一个 `craco.config.js` 用于修改默认配置。
|
||||
|
||||
```js
|
||||
module.exports = function override(config, env) {
|
||||
// do stuff with the webpack config...
|
||||
return config;
|
||||
/* craco.config.js */
|
||||
module.exports = {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
### 使用 babel-plugin-import
|
||||
|
||||
> 注意:antd 默认支持基于 ES module 的 tree shaking,js 代码部分不使用这个插件也会有按需加载的效果。
|
||||
|
||||
[babel-plugin-import](https://github.com/ant-design/babel-plugin-import) 是一个用于按需加载组件代码和样式的 babel 插件([原理](/docs/react/getting-started#按需加载)),现在我们尝试安装它并修改 `config-overrides.js` 文件。
|
||||
|
||||
```bash
|
||||
$ yarn add babel-plugin-import
|
||||
```
|
||||
|
||||
```diff
|
||||
+ const { override, fixBabelImports } = require('customize-cra');
|
||||
|
||||
- module.exports = function override(config, env) {
|
||||
- // do stuff with the webpack config...
|
||||
- return config;
|
||||
- };
|
||||
+ module.exports = override(
|
||||
+ fixBabelImports('antd', {
|
||||
+ libraryDirectory: 'es',
|
||||
+ style: 'css',
|
||||
+ }),
|
||||
+ );
|
||||
```
|
||||
|
||||
然后移除前面在 `src/App.css` 里全量添加的 `@import '~antd/dist/antd.css';` 样式代码,并且按下面的格式引入模块。
|
||||
|
||||
```diff
|
||||
// src/App.js
|
||||
import React, { Component } from 'react';
|
||||
- import Button from 'antd/es/button';
|
||||
+ import { Button } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
const App = () => (
|
||||
<div className="App">
|
||||
<Button type="primary">Button</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
最后重启 `yarn start` 访问页面,antd 组件的 js 和 css 代码都会按需加载,你在控制台也不会看到这样的[警告信息](https://zos.alipayobjects.com/rmsportal/vgcHJRVZFmPjAawwVoXK.png)。关于按需加载的原理和其他方式可以阅读[这里](/docs/react/getting-started#按需加载)。
|
||||
|
||||
### 自定义主题
|
||||
|
||||
按照 [配置主题](/docs/react/customize-theme) 的要求,自定义主题需要用到 less 变量覆盖功能。我们可以引入 `customize-cra` 中提供的 less 相关的函数 [addLessLoader](https://github.com/arackaf/customize-cra/blob/master/api.md#addlessloaderloaderoptions) 来帮助加载 less 样式,同时修改 `config-overrides.js` 文件如下。
|
||||
按照 [配置主题](/docs/react/customize-theme) 的要求,自定义主题需要用到类似 [less-loader](https://github.com/webpack-contrib/less-loader/) 提供的 less 变量覆盖功能。我们可以引入 [craco-less](https://github.com/DocSpring/craco-less) 来帮助加载 less 样式和修改变量。
|
||||
|
||||
```bash
|
||||
$ yarn add less less-loader
|
||||
```
|
||||
首先修改样式引用为 less 文件。
|
||||
|
||||
```diff
|
||||
- const { override, fixBabelImports } = require('customize-cra');
|
||||
+ const { override, fixBabelImports, addLessLoader } = require('customize-cra');
|
||||
- @import '~antd/dist/antd.css';
|
||||
+ @import '~antd/dist/antd.less';
|
||||
```
|
||||
|
||||
module.exports = override(
|
||||
fixBabelImports('antd', {
|
||||
libraryDirectory: 'es',
|
||||
- style: 'css',
|
||||
+ style: true,
|
||||
}),
|
||||
+ addLessLoader({
|
||||
+ lessOptions: { // 如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。
|
||||
+ javascriptEnabled: true,
|
||||
+ modifyVars: { '@primary-color': '#1DA57A' },
|
||||
+ },
|
||||
+ }),
|
||||
);
|
||||
然后安装 `craco-less` 并修改 `config-overrides.js` 文件如下。
|
||||
|
||||
```bash
|
||||
$ yarn add craco-less
|
||||
```
|
||||
|
||||
```js
|
||||
const CracoLessPlugin = require('craco-less');
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
{
|
||||
plugin: CracoLessPlugin,
|
||||
options: {
|
||||
lessLoaderOptions: {
|
||||
modifyVars: { '@primary-color': '#1DA57A' },
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
这里利用了 [less-loader](https://github.com/webpack/less-loader#less-options) 的 `modifyVars` 来进行主题配置,变量和其他配置方式可以参考 [配置主题](/docs/react/customize-theme) 文档。修改后重启 `yarn start`,如果看到一个绿色的按钮就说明配置成功了。
|
||||
|
||||
antd 内建了深色主题和紧凑主题,你可以参照 [使用暗色主题和紧凑主题](/docs/react/customize-theme#使用暗色主题和紧凑主题) 进行接入。
|
||||
|
||||
> 同样,你可以使用 [craco](https://github.com/sharegate/craco) 和 [craco-antd](https://github.com/FormAPI/craco-antd) 来自定义 create-react-app 的 webpack 配置,类似于 customize-cra。
|
||||
|
||||
> 注意:建议使用最新版本的 `less`,或不低于 `3.0.1`。
|
||||
|
||||
## 使用 Day.js 替换 momentjs 优化打包大小
|
||||
|
||||
你可以使用 [antd-dayjs-webpack-plugin](https://github.com/ant-design/antd-dayjs-webpack-plugin) 插件用 Day.js 替换 momentjs 来大幅减小打包大小。
|
||||
|
||||
```bash
|
||||
$ yarn add antd-dayjs-webpack-plugin
|
||||
```
|
||||
|
||||
```js
|
||||
const { override, addWebpackPlugin } = require('customize-cra');
|
||||
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin');
|
||||
|
||||
module.exports = override(addWebpackPlugin(new AntdDayjsWebpackPlugin()));
|
||||
```
|
||||
> 同样,你可以使用 [react-scripts-rewired](https://github.com/timarney/react-app-rewired) 和 [customize-cra](https://github.com/arackaf/customize-cra) 来自定义 create-react-app 的 webpack 配置。
|
||||
|
||||
## eject
|
||||
|
||||
你也可以使用 create-react-app 提供的 [yarn run eject](https://facebook.github.io/create-react-app/docs/available-scripts#npm-run-eject) 命令将所有内建的配置暴露出来。不过这种配置方式需要你自行探索,不在本文讨论范围内。
|
||||
你也可以使用 create-react-app 提供的 [yarn run eject](https://create-react-app.dev/docs/available-scripts/#npm-run-eject) 命令将所有内建的配置暴露出来。不过这种配置方式需要你自行探索,不在本文讨论范围内。
|
||||
|
||||
## 源码和其他脚手架
|
||||
## 小结
|
||||
|
||||
以上是在 create-react-app 中使用 antd 的相关实践,你也可以借鉴此文的做法在自己的 webpack 工作流中使用 antd,更多 webpack 配置可参考 [atool-build](https://github.com/ant-tool/atool-build/blob/master/src/getWebpackCommonConfig.js)。(例如加入 [moment noParse](https://github.com/ant-tool/atool-build/blob/e4bd2959689b6a95cb5c1c854a5db8c98676bdb3/src/getWebpackCommonConfig.js#L90) 避免加载所有语言文件)
|
||||
以上是在 create-react-app 中使用 antd 的相关实践,你也可以借鉴此文的做法在自己的 webpack 工作流中使用 antd。
|
||||
|
||||
React 生态圈中还有很多优秀的脚手架,使用它们并引入 antd 时,你可能会遇到一些问题,下面是一些著名脚手架使用 antd 的范例,包括本文的 create-react-app。
|
||||
上述教程的脚手架源码我们放在 [create-react-app-antd](https://github.com/ant-design/create-react-app-antd) 中,你可以直接下载使用。
|
||||
|
||||
- [react-boilerplate/react-boilerplate](https://github.com/ant-design/react-boilerplate)
|
||||
- [kriasoft/react-starter-kit](https://github.com/ant-design/react-starter-kit)
|
||||
- [create-react-app-antd](https://github.com/ant-design/create-react-app-antd)
|
||||
- [cra-ts-antd](https://github.com/comerc/cra-ts-antd)
|
||||
- [next.js](https://github.com/zeit/next.js/tree/master/examples/with-ant-design)
|
||||
- [nwb](https://github.com/insin/nwb-examples/tree/master/react-app-antd)
|
||||
- [antd-react-scripts](https://github.com/minesaner/create-react-app/tree/antd/packages/react-scripts)
|
||||
接下来我们会介绍如何在 [TypeScript](/docs/react/use-in-typescript) 和 [Umi](/docs/react/practical-projects) 中使用 antd,欢迎继续阅读。
|
||||
|
@ -13,7 +13,7 @@
|
||||
"react-component",
|
||||
"ui"
|
||||
],
|
||||
"homepage": "http://ant.design/",
|
||||
"homepage": "https://ant.design/",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ant-design/ant-design/issues"
|
||||
},
|
||||
@ -128,7 +128,7 @@
|
||||
"rc-notification": "~4.3.0",
|
||||
"rc-pagination": "~2.2.0",
|
||||
"rc-picker": "~1.4.0",
|
||||
"rc-progress": "~2.6.0",
|
||||
"rc-progress": "~3.0.0",
|
||||
"rc-rate": "~2.6.0",
|
||||
"rc-resize-observer": "^0.2.0",
|
||||
"rc-select": "~10.3.0",
|
||||
|
Loading…
Reference in New Issue
Block a user