mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-14 21:39:20 +08:00
Compare commits
329 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bd3d4a33b | ||
|
|
0f83e0a4ee | ||
|
|
d6c5e5358e | ||
|
|
f2e541ade5 | ||
|
|
7d32f99283 | ||
|
|
5676ea22d2 | ||
|
|
71e0f9b103 | ||
|
|
de9635efd3 | ||
|
|
04f333b4b6 | ||
|
|
99addfb985 | ||
|
|
3f38861fb8 | ||
|
|
dee4b25e8c | ||
|
|
ab349700ad | ||
|
|
fb2bafbfdc | ||
|
|
a9d7178c2b | ||
|
|
cd3d9efd9f | ||
|
|
8e2b2470b2 | ||
|
|
59f231ff92 | ||
|
|
5a07b85d9e | ||
|
|
0522d55f26 | ||
|
|
8ffaeb8cba | ||
|
|
a2f28f0ca7 | ||
|
|
59685afeeb | ||
|
|
a72f43b2c1 | ||
|
|
0b1894e83a | ||
|
|
bae2752be3 | ||
|
|
338018eba3 | ||
|
|
6db3711876 | ||
|
|
c93f54c7f1 | ||
|
|
51f9b95c1b | ||
|
|
37e5ce4f6a | ||
|
|
7366afa151 | ||
|
|
cfcdf2fd5f | ||
|
|
453c01aaae | ||
|
|
e75fa039ef | ||
|
|
4e1bbccd54 | ||
|
|
8bb4613bff | ||
|
|
04a27deb2b | ||
|
|
f7c37e5509 | ||
|
|
fc697007c5 | ||
|
|
e161a2ae76 | ||
|
|
a0851cdd34 | ||
|
|
1884c12a81 | ||
|
|
7c6731021d | ||
|
|
5fff041e8a | ||
|
|
311a6c0917 | ||
|
|
e43b808cc4 | ||
|
|
9cbc090a9a | ||
|
|
6ab74d9d7e | ||
|
|
fb5d709ccd | ||
|
|
3ac716d808 | ||
|
|
78b1f90e51 | ||
|
|
d582ba351b | ||
|
|
d8526f43f6 | ||
|
|
16572711a3 | ||
|
|
0674bb974f | ||
|
|
ba971b295b | ||
|
|
36a7621bb3 | ||
|
|
75d97c8bf1 | ||
|
|
535d4afc2d | ||
|
|
41bbcfe180 | ||
|
|
b41bdb0433 | ||
|
|
4aa81e576c | ||
|
|
7922090eaa | ||
|
|
b0c90f4b06 | ||
|
|
a877db72ef | ||
|
|
718a86d56b | ||
|
|
4a29aaaf6b | ||
|
|
5e4697e38b | ||
|
|
95710af9ef | ||
|
|
f04c8a61eb | ||
|
|
140adc6015 | ||
|
|
391aab44e8 | ||
|
|
c4283e4fff | ||
|
|
54cf1a924d | ||
|
|
3ab6c48640 | ||
|
|
95c41774ee | ||
|
|
2a399bfc32 | ||
|
|
634c202077 | ||
|
|
47dee4c7d7 | ||
|
|
8ab77d21df | ||
|
|
0a09b3b008 | ||
|
|
4680ddc009 | ||
|
|
3d378f2fd8 | ||
|
|
71b53b7175 | ||
|
|
e3273bb54e | ||
|
|
ba7ddfa046 | ||
|
|
e07bba91fa | ||
|
|
e5aea71b99 | ||
|
|
dc0dfea201 | ||
|
|
916c0659bd | ||
|
|
fb913f4f47 | ||
|
|
e1a4f2891e | ||
|
|
d41b5be377 | ||
|
|
66ca4a8b25 | ||
|
|
650d44e8a7 | ||
|
|
bbc8800cb8 | ||
|
|
3acbc941a6 | ||
|
|
3f7b7dedd6 | ||
|
|
18017d6ea5 | ||
|
|
3274c55bdf | ||
|
|
2875933c99 | ||
|
|
2228e91b01 | ||
|
|
4cc5fcdb24 | ||
|
|
948d0bd7bb | ||
|
|
8a60e19b8e | ||
|
|
8bae8bf27d | ||
|
|
1d5bd4a7aa | ||
|
|
0be5e334e4 | ||
|
|
8219438ecd | ||
|
|
5728763dcc | ||
|
|
049799ed0f | ||
|
|
b536643f76 | ||
|
|
49ecf9b738 | ||
|
|
7ae663da6d | ||
|
|
49c9ee40b4 | ||
|
|
46d0ff3e00 | ||
|
|
e9b0c29f55 | ||
|
|
2c864b9bc6 | ||
|
|
90a77c0f02 | ||
|
|
4a5b0e1669 | ||
|
|
5c10cf880b | ||
|
|
c387fdc0c6 | ||
|
|
7ce8235194 | ||
|
|
7961bb335c | ||
|
|
913c5bbc47 | ||
|
|
53b3c5af96 | ||
|
|
5aa32a3f17 | ||
|
|
a40b54aaa1 | ||
|
|
efa82940ba | ||
|
|
5004a925c0 | ||
|
|
0edbec10db | ||
|
|
81793758df | ||
|
|
61fc38901f | ||
|
|
0bc0a9de48 | ||
|
|
d85f6c8aa1 | ||
|
|
b83f432180 | ||
|
|
05bf1adbe8 | ||
|
|
fd31d91a9b | ||
|
|
4cca77eab7 | ||
|
|
e511e50655 | ||
|
|
df7e366563 | ||
|
|
6d7a87e7e0 | ||
|
|
d3b8bfa511 | ||
|
|
2de1a15da9 | ||
|
|
a2edbc326f | ||
|
|
c9a30ef766 | ||
|
|
136387fdb7 | ||
|
|
acbd1a9d28 | ||
|
|
d3e01385b5 | ||
|
|
b87fc9526a | ||
|
|
bd8d6d3e98 | ||
|
|
d0d181b6b8 | ||
|
|
75d5dff1f9 | ||
|
|
0e52f9a891 | ||
|
|
02ed4bd6b1 | ||
|
|
98e715fe3f | ||
|
|
a5efb30b83 | ||
|
|
9e9abfdc79 | ||
|
|
133577f45e | ||
|
|
9f78fd093a | ||
|
|
c9cecde2e8 | ||
|
|
17816b963e | ||
|
|
acce303817 | ||
|
|
34c220acf1 | ||
|
|
25bdb78410 | ||
|
|
8b4bd0c23d | ||
|
|
1e90eb1264 | ||
|
|
068556c029 | ||
|
|
3e4fd43a07 | ||
|
|
1d8c6f8d82 | ||
|
|
3e2cd50c87 | ||
|
|
974fb1b96c | ||
|
|
54ffa2cea6 | ||
|
|
ca6e2f36c8 | ||
|
|
020711ddd6 | ||
|
|
fa880907dd | ||
|
|
d9b058248d | ||
|
|
16dff49e46 | ||
|
|
a5bb161bb0 | ||
|
|
88cf4d5b7f | ||
|
|
0a284ca74d | ||
|
|
6803b89506 | ||
|
|
bcbc1e2ac2 | ||
|
|
a5b4252488 | ||
|
|
69d079e0ed | ||
|
|
6d9d04db29 | ||
|
|
da760b461f | ||
|
|
33afa7462c | ||
|
|
9515cef21d | ||
|
|
1f7d5066c2 | ||
|
|
1ae54f5432 | ||
|
|
f956b55c92 | ||
|
|
b188a5e4d2 | ||
|
|
721baa80f7 | ||
|
|
882225f65b | ||
|
|
d72f825f43 | ||
|
|
0f3f3dc521 | ||
|
|
8846122060 | ||
|
|
7404a7ea32 | ||
|
|
db24346d56 | ||
|
|
1acd7e2249 | ||
|
|
a9773d54e0 | ||
|
|
bc7179f0c6 | ||
|
|
f9058e0d8e | ||
|
|
81e6f509aa | ||
|
|
08000b217e | ||
|
|
1311ea8b35 | ||
|
|
0cccefbc77 | ||
|
|
fe30adc18d | ||
|
|
9ea143ba3a | ||
|
|
b935db8e34 | ||
|
|
7a964a075d | ||
|
|
fc81c1330c | ||
|
|
13dd1c4659 | ||
|
|
1f01b40e05 | ||
|
|
4d74609f4e | ||
|
|
2128ee28ae | ||
|
|
1200f7fe00 | ||
|
|
ba0af6e622 | ||
|
|
a9498bbbe2 | ||
|
|
df1817f91c | ||
|
|
4b8d76b983 | ||
|
|
ec84967a5d | ||
|
|
f986c6b459 | ||
|
|
5f6f325ef6 | ||
|
|
a19d338f08 | ||
|
|
56abebfb3c | ||
|
|
09810a28d9 | ||
|
|
6f695b050e | ||
|
|
632ba44917 | ||
|
|
5cd01d0470 | ||
|
|
98dfd2ac93 | ||
|
|
b786e6b48f | ||
|
|
d2e76d9480 | ||
|
|
bf5140b825 | ||
|
|
265a01e165 | ||
|
|
b2e206dd4b | ||
|
|
f659d23d22 | ||
|
|
e13a87053c | ||
|
|
c98b820700 | ||
|
|
11a0ebef90 | ||
|
|
e95466bc15 | ||
|
|
240865143f | ||
|
|
49e4cc817a | ||
|
|
563fa3ccc2 | ||
|
|
800e3ecab8 | ||
|
|
7743967bf6 | ||
|
|
588efe41c4 | ||
|
|
c3ac7308dc | ||
|
|
ff3225fcbb | ||
|
|
161801cd78 | ||
|
|
e98afc5145 | ||
|
|
a93fe5238e | ||
|
|
60536d3880 | ||
|
|
796d2aa000 | ||
|
|
e1ab352547 | ||
|
|
50606289d7 | ||
|
|
35c537ee2d | ||
|
|
15f0841606 | ||
|
|
30dd9a3b0e | ||
|
|
4490ee8483 | ||
|
|
caa6eb0973 | ||
|
|
31592426a8 | ||
|
|
5dd132340e | ||
|
|
1903ae0c13 | ||
|
|
4338a5b7cf | ||
|
|
c2bcf44f62 | ||
|
|
cf97324abd | ||
|
|
4615c70d95 | ||
|
|
f23f53bb1e | ||
|
|
f8af6972ba | ||
|
|
0704a06eba | ||
|
|
d2ba8e9802 | ||
|
|
b93d10d40b | ||
|
|
e71aee45ad | ||
|
|
d0f3c18508 | ||
|
|
f5a20fec82 | ||
|
|
c9a8f698b1 | ||
|
|
96a9583bf8 | ||
|
|
35aaf6b9e9 | ||
|
|
d0f95299cd | ||
|
|
01970b6913 | ||
|
|
ffe0645589 | ||
|
|
9157bc99a9 | ||
|
|
2189bf5f54 | ||
|
|
864138370f | ||
|
|
2e5928450d | ||
|
|
251ae17376 | ||
|
|
033f812311 | ||
|
|
49a37d10c7 | ||
|
|
580312bd1f | ||
|
|
499c46b220 | ||
|
|
d9f2c906ca | ||
|
|
02da860de1 | ||
|
|
7c180a7f31 | ||
|
|
d2aeaab486 | ||
|
|
577bc87bba | ||
|
|
e479f1f476 | ||
|
|
43bcd0ec8f | ||
|
|
701b3f5fc9 | ||
|
|
5d2596bda8 | ||
|
|
784ad7d57c | ||
|
|
bbd979f7ff | ||
|
|
19325b4175 | ||
|
|
4d6c8bc0b5 | ||
|
|
7ad1068006 | ||
|
|
61ad79dde5 | ||
|
|
d9bfc689a4 | ||
|
|
bf374da148 | ||
|
|
1e830d782c | ||
|
|
97b344e0c1 | ||
|
|
f4719ddf02 | ||
|
|
d8031aa4cb | ||
|
|
97f6ac9fc6 | ||
|
|
7864ab46c4 | ||
|
|
27afeaf3a1 | ||
|
|
3ad0e809b0 | ||
|
|
aa9b9db4e1 | ||
|
|
4cac0a9822 | ||
|
|
1b3a9d8656 | ||
|
|
eb28212da6 | ||
|
|
04669002bf | ||
|
|
774e679ee1 | ||
|
|
e5d644f71a | ||
|
|
e4a3b72e78 | ||
|
|
849237be0b | ||
|
|
9dc0378b3f | ||
|
|
50ab115141 |
@@ -3,7 +3,7 @@ version: 2
|
||||
references:
|
||||
container_config: &container_config
|
||||
docker:
|
||||
- image: circleci/node:8
|
||||
- image: circleci/node:lts
|
||||
working_directory: ~/ant-design
|
||||
|
||||
attach_workspace: &attach_workspace
|
||||
@@ -184,6 +184,7 @@ jobs:
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
LIB_DIR: dist
|
||||
REACT: 15
|
||||
|
||||
test_lib_15:
|
||||
<<: *container_config
|
||||
@@ -196,6 +197,7 @@ jobs:
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
LIB_DIR: lib
|
||||
REACT: 15
|
||||
|
||||
test_es_15:
|
||||
<<: *container_config
|
||||
@@ -208,6 +210,7 @@ jobs:
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
LIB_DIR: es
|
||||
REACT: 15
|
||||
|
||||
test_dom_15:
|
||||
<<: *container_config
|
||||
@@ -216,7 +219,10 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run: npm test -- -w 1 -u
|
||||
- run:
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
REACT: 15
|
||||
|
||||
test_node_15:
|
||||
<<: *container_config
|
||||
@@ -225,7 +231,10 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run: npm run test-node -- -w 1 -u
|
||||
- run:
|
||||
command: npm run test-node -- -w 1 -u
|
||||
environment:
|
||||
REACT: 15
|
||||
|
||||
check_metadata:
|
||||
<<: *container_config
|
||||
|
||||
@@ -70,6 +70,7 @@ const eslintrc = {
|
||||
'import/no-cycle': 0,
|
||||
'react/no-find-dom-node': 0,
|
||||
'no-underscore-dangle': 0,
|
||||
'react/sort-comp': 0,
|
||||
// label-has-for has been deprecated
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/label-has-for.md
|
||||
'jsx-a11y/label-has-for': 0,
|
||||
|
||||
2
.github/workflows/deploy-site.yml
vendored
2
.github/workflows/deploy-site.yml
vendored
@@ -1,8 +1,10 @@
|
||||
name: Deploy website
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
19
.github/workflows/nodejs.yml
vendored
19
.github/workflows/nodejs.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: Node CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Use Node.js 10.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
version: 10.x
|
||||
- name: npm install, build, and test
|
||||
run: |
|
||||
npm install
|
||||
npm run test-all
|
||||
14
.github/workflows/rebase.yml
vendored
Normal file
14
.github/workflows/rebase.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
name: Automatic Rebase
|
||||
jobs:
|
||||
rebase:
|
||||
name: Rebase
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
18
.github/workflows/test.yml
vendored
Normal file
18
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: test
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: install
|
||||
run: npm install
|
||||
|
||||
- name: test
|
||||
run: npm run test-all
|
||||
@@ -15,6 +15,127 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.24.1
|
||||
|
||||
`2019-10-17`
|
||||
|
||||
- 🐞 Fix Table throw `React.createRef is not a function error` in old version of React . [#19262](https://github.com/ant-design/ant-design/pull/19262)
|
||||
- 🐞 Fix Table TypeScript definition missing Column and ColumnGroup. [#19251](https://github.com/ant-design/ant-design/pull/19251)
|
||||
|
||||
## 3.24.0
|
||||
|
||||
`2019-10-16`
|
||||
|
||||
- 🔥 Promote [Yuque](https://www.yuque.com/?chInfo=ch_antd) on home page.
|
||||
- Table
|
||||
- 🌟 Added `tableLayout` property for `table-layout` attribute. And using `tableLayout="fixed"` by default in scroll table to resolve align issue caused by cell content. [#17284](https://github.com/ant-design/ant-design/pull/17284)
|
||||
- 🌟 Added `column.ellipsis` to ellipsize cell content.
|
||||
- 🌟 Added the `scroll.scrollToFirstRowOnChange` property to set whether to scroll to the top of the table after page changing. [#18726](https://github.com/ant-design/ant-design/pull/18726)
|
||||
- 🌟 `filterDropdown` added a `visible` parameter to get the display state of the dropdown box. [#17614](https://github.com/ant-design/ant-design/pull/17614) [@sedx](https://github.com/ant-design/ant-design/pull/17614)
|
||||
- 🌟 `title` added a `sortColumn` parameter to get the currently sorted column. [#19012](https://github.com/ant-design/ant-design/pull/19012) [@swillis12](https://github.com/swillis12)
|
||||
- 🌟 The `sorter` parameter of `onChange` will always contain `column` information when sorting. [#19226](https://github.com/ant-design/ant-design/pull/19226)
|
||||
- 🐞 Fix Table filter submenu checkbox margin. [#e1a4f28](https://github.com/ant-design/ant-design/commit/e1a4f2891e3c35ae26495432bd2d288d4d81064a)
|
||||
- 🌟 Anchor added a `onChange` attribute to listen for changes to anchor links. [#18715](https://github.com/ant-design/ant-design/pull/18715)
|
||||
- Upload
|
||||
- 🌟 Added `showDownloadIcon` attribute to display download icon. [#18664](https://github.com/ant-design/ant-design/pull/18664) [@qq645381995](https://github.com/qq645381995)
|
||||
- 🌟 Support for `onRemove` control of upload interrupts. [#18937](https://github.com/ant-design/ant-design/pull/18937) [@ladjzero](https://github.com/ladjzero)
|
||||
- 🌟 Input.Search added a `loading` property to show the state in the load. [#18771](https://github.com/ant-design/ant-design/pull/18771)
|
||||
- 🌟 Grid's `gutter` property added support for vertical spacing. Now you can set an array for `gutter` and the second value of the array for vertical spacing. [#18979](https://github.com/ant-design/ant-design/pull/18979)
|
||||
- 🌟 message added support for updating content with a unique key. [#18678](https://github.com/ant-design/ant-design/pull/18678)
|
||||
- 🌟 Layout added a `zeroWidthTriggerStyle` property to control the style of the special `trigger` that appears when `collapsedWidth` is `0`. [#19079](https://github.com/ant-design/ant-design/pull/19079)
|
||||
- 🌟 Drawer added the `drawerStyle` and `headerStyle` properties. [#19109](https://github.com/ant-design/ant-design/pull/19109)
|
||||
- PageHeader
|
||||
- 💄 Redesigned. [#19100](https://github.com/ant-design/ant-design/pull/19100)
|
||||
- 🌟 Added `ghost` property to set whether white background is needed. [#19100](https://github.com/ant-design/ant-design/pull/19100)
|
||||
- ConfigProvider
|
||||
- 🌟 Added `pageHeader` to globally control the style of PageHeader. [#19100](https://github.com/ant-design/ant-design/pull/19100)
|
||||
- 🐞 Fixed the issue that `moment` can't be tree-shark. [#19115](https://github.com/ant-design/ant-design/pull/19115)
|
||||
- 🐞 Fixed the issue that the `removeIcon` and `clearIcon` properties of TreeSelect didn't work. [#18949](https://github.com/ant-design/ant-design/pull/18949)
|
||||
- 🐞 Fixed the issue that the `switcherIcon` does not take effect after the Tree setting `showLine`. [#18829](https://github.com/ant-design/ant-design/pull/18829) [@MrHeer](https://github.com/MrHeer)
|
||||
- 🐞 Fixed the issue that the Slider component set the handle size and positioned incorrectly. [#19120](https://github.com/ant-design/ant-design/pull/19120)
|
||||
- Collapse
|
||||
- 🐞 Fix icon styles under IE 11. [#19135](https://github.com/ant-design/ant-design/pull/19135) [@GBcrimson](https://github.com/GBcrimson)
|
||||
- 🐞 Keep `className` given to `expandIcon`. [#19160](https://github.com/ant-design/ant-design/pull/19160) [@gpetrioli](https://github.com/gpetrioli)
|
||||
- 🐞 Fixed the issue that `defaultExpandAll` does not take effect when Tree.DirectoryTree component passed `treeData`. [#19148](https://github.com/ant-design/ant-design/pull/19148)
|
||||
- 🐞 Fixed the issue with some of the Menu styles under Dropdown. [#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
- 🐞 Fixed Cascader's `placeholder` internationalization error. [#19227](https://github.com/ant-design/ant-design/pull/19227) [@kagawagao](https://github.com/kagawagao)
|
||||
- 🌟 Added less variables `@typography-title-margin-top`, `@typography-title-margin-bottom`. [#18746](https://github.com/ant-design/ant-design/pull/18746)
|
||||
- 🗑 Discard the `autosize` property of Input.TextArea, use `autoSize` instead. [#19177](https://github.com/ant-design/ant-design/pull/19177)
|
||||
|
||||
## 3.23.6
|
||||
|
||||
`2019-10-05`
|
||||
|
||||
- 🐞 Fix Typography `ref` warning of React. [#19074](https://github.com/ant-design/ant-design/pull/19074)
|
||||
|
||||
## 3.23.5
|
||||
|
||||
`2019-09-29`
|
||||
|
||||
- 🐞 Fix Upload preview image cannot fill the picture card box. [#18990](https://github.com/ant-design/ant-design/pull/18990)
|
||||
- 🐞 Fix Breadcrumb not support `data-*` and `aria-*` attributes. [#18941](https://github.com/ant-design/ant-design/pull/18941) [@sosohime](https://github.com/sosohime)
|
||||
- 🐞 Fix TreeSelect `removeIcon` and `clearIcon` not working. [#18949](https://github.com/ant-design/ant-design/issues/18949) [@sosohime](https://github.com/sosohime)
|
||||
- 🐞 Fix Tree `switcherIcon` prop not working when `showLine` is true. [#18829](https://github.com/ant-design/ant-design/pull/18829) [@MrHeer](https://github.com/MrHeer)
|
||||
- 🐞 Fix style bug of Button with icon only when in Button.Group. [#18994](https://github.com/ant-design/ant-design/pull/18994)
|
||||
- 🐞 Remove Select useless prop `searchValue` which is a total misunderstanding. [#19003](https://github.com/ant-design/ant-design/pull/19003)
|
||||
- 🐞 Fix Avatar string blink when ssr render at first time. [#19029](https://github.com/ant-design/ant-design/pull/19029)
|
||||
- TypeScript
|
||||
- 🐞 Fix Grid type definition. [#18946](https://github.com/ant-design/ant-design/pull/18946) [@handycode](https://github.com/handycode)
|
||||
|
||||
## 3.23.4
|
||||
|
||||
`2019-09-21`
|
||||
|
||||
- 🐞 Fix item not disabled when Transfer is `disabled`. [#18849](https://github.com/ant-design/ant-design/pull/18849)
|
||||
- 🐞 Revert Dragger to class component to fix ref warning. [#18707](https://github.com/ant-design/ant-design/issues/18707)
|
||||
- 🐞 Fix Input `addonAfter` icon height bug in Chrome. [#18858](https://github.com/ant-design/ant-design/pull/18858)
|
||||
- 🐞 Fix Menu lost state when being collapsed to `0px`. [#18907](https://github.com/ant-design/ant-design/pull/18907)
|
||||
- 🐞 Disabled input should not trigger the action of suffix part. [#18900](https://github.com/ant-design/ant-design/pull/18900)
|
||||
- 🐞 Fix title and content of Alert not break line when long text exist. [#18929](https://github.com/ant-design/ant-design/pull/18929)
|
||||
- 💄 Add `@page-header-back-color` less variable. [#18887](https://github.com/ant-design/ant-design/pull/18887)
|
||||
- TypeScript
|
||||
- 🐞 Fix Table event type definition. [#18910](https://github.com/ant-design/ant-design/pull/18910)
|
||||
|
||||
## 3.23.3
|
||||
|
||||
`2019-09-16`
|
||||
|
||||
- 🐞 Fix ConfigProvider `locale` not working with Modal in some situation. [#18732](https://github.com/ant-design/ant-design/pull/18732)
|
||||
- 🐞 Fix Avatar extrusion style when using long pictures. [#18768](https://github.com/ant-design/ant-design/pull/18768) [@Eusen](https://github.com/Eusen)
|
||||
- 🐞 Fix InputNumber active border style. [#18791](https://github.com/ant-design/ant-design/pull/18791) [@escorponox](https://github.com/escorponox)
|
||||
- 🐞 Fix Input.Search not trigger `onSearch` when click clear icon. [#18783](https://github.com/ant-design/ant-design/pull/18783)
|
||||
- 🐞 Fix text color of Button inside Menu. [#18820](https://github.com/ant-design/ant-design/pull/18820)
|
||||
- 🐞 Fix `size="small"` Table header missing right border. [#18821](https://github.com/ant-design/ant-design/pull/18821)
|
||||
- ⌨️ Enhance accessibility of Alert close button. [#18750](https://github.com/ant-design/ant-design/pull/18750) [@MrHeer](https://github.com/MrHeer)
|
||||
- 💄 Tweak Button `type="link"` should not insert space. [#18724](https://github.com/ant-design/ant-design/pull/18724)
|
||||
- TypeScript
|
||||
- 🐞 Fix type definition of `onMouseEnter` and `onMouseLeave` for Tree. [#18796](https://github.com/ant-design/ant-design/pull/18796) [@MrHeer](https://github.com/MrHeer)
|
||||
|
||||
## 3.23.2
|
||||
|
||||
`2019-09-06`
|
||||
|
||||
- 🐞 Fix `round` Button font size too large. [#18701](https://github.com/ant-design/ant-design/pull/18701)
|
||||
- 🐞 Fix Descriptions warning with same key when bordered is true. [#18637](https://github.com/ant-design/ant-design/pull/18637)
|
||||
- 🐞 Fix Drawer animation when `placement` is right and `mask` is false. [#18636](https://github.com/ant-design/ant-design/pull/18636)
|
||||
- 🐞 Fix Icon that `component` and `children` prop should have priority over `type` prop. [#18592](https://github.com/ant-design/ant-design/pull/18592)
|
||||
- 🐞 Fix Layout.Sider boundary values for max-width. [#18553](https://github.com/ant-design/ant-design/pull/18553) [@Nikitenkova](https://github.com/Nikitenkova)
|
||||
- 🐞 Fix PageHeader that back icon can't coexist with breadcrumb. [#18691](https://github.com/ant-design/ant-design/pull/18691)
|
||||
- 🗑 Deprecated Select `inputValue` prop and use `searchValue` instead. [#18629](https://github.com/ant-design/ant-design/pull/18629)
|
||||
- TypeScript
|
||||
- 🐞 Fix type definition of `status` for Result. [#18445](https://github.com/ant-design/ant-design/pull/18445)
|
||||
- 🐞 Fix type definition of `target` for Anchor.Link. [#18646](https://github.com/ant-design/ant-design/pull/18646)
|
||||
- 🐞 Fix type definition of `transformFile` params for Upload. [#18671](https://github.com/ant-design/ant-design/pull/18671)
|
||||
- 🐞 Fix type definition of `title` and `footer` for Table. [#18697](https://github.com/ant-design/ant-design/pull/18697) [@yoyo837](https://github.com/yoyo837)
|
||||
|
||||
## 3.23.1
|
||||
|
||||
`2019-09-03`
|
||||
|
||||
- 🐞 Fix Upload can not upload more than one file when `multiple` is `false`. [#18626](https://github.com/ant-design/ant-design/pull/18626)
|
||||
- 🐞 Fix MonthPicker switch handler overflow style. [#18624](https://github.com/ant-design/ant-design/pull/18624)
|
||||
- 💄 Tree add `@tree-node-hover-bg` and `@tree-node-selected-bg` less variable. [#18593](https://github.com/ant-design/ant-design/pull/18593) [@MrHeer](https://github.com/MrHeer)
|
||||
|
||||
## 3.23.0
|
||||
|
||||
`2019-09-02`
|
||||
|
||||
@@ -15,6 +15,127 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.24.1
|
||||
|
||||
`2019-10-17`
|
||||
|
||||
- 🐞 修复 Table 在旧版 React 会报 `React.createRef is not a function` 的错误信息。[#19262](https://github.com/ant-design/ant-design/pull/19262)
|
||||
- 🐞 修复 Table TypeScript 定义丢失 Column 和 ColumnGroup 的问题。[#19251](https://github.com/ant-design/ant-design/pull/19251)
|
||||
|
||||
## 3.24.0
|
||||
|
||||
`2019-10-16`
|
||||
|
||||
- 🔥 首页新增[语雀](https://www.yuque.com/?chInfo=ch_antd)的推广链接。
|
||||
- Table
|
||||
- 🌟 新增 `tableLayout` 属性,支持设置表格的 `table-layout` 布局,并在固定表头/列下默认开启 `tableLayout="fixed"`,解决因为表格自动根据内容排版造成的列对齐问题。[#17284](https://github.com/ant-design/ant-design/pull/17284)
|
||||
- 🌟 新增 `column.ellipsis` 支持单元格内容自动省略。
|
||||
- 🌟 新增 `scroll.scrollToFirstRowOnChange` 属性,用于设置在翻页后是否滚动到表格顶部。[#18726](https://github.com/ant-design/ant-design/pull/18726)
|
||||
- 🌟 `filterDropdown` 新增 `visible` 参数,用于获取下拉框的显示状态。[#17614](https://github.com/ant-design/ant-design/pull/17614) [@sedx](https://github.com/ant-design/ant-design/pull/17614)
|
||||
- 🌟 `title` 方法新增 `sortColumn` 参数,用于获取当前排序的列。[#19012](https://github.com/ant-design/ant-design/pull/19012) [@swillis12](https://github.com/swillis12)
|
||||
- 🌟 排序时 `onChange` 的 `sorter` 参数将始终包含 `column` 信息。[#19226](https://github.com/ant-design/ant-design/pull/19226)
|
||||
- 🐞 修复过滤下拉菜单的间距问题。[#e1a4f28](https://github.com/ant-design/ant-design/commit/e1a4f2891e3c35ae26495432bd2d288d4d81064a)
|
||||
- 🌟 Anchor 新增 `onChange` 属性,用于监听锚点链接的改变。[#18715](https://github.com/ant-design/ant-design/pull/18715)
|
||||
- Upload
|
||||
- 🌟 新增 `showDownloadIcon` 属性,用于展示下载图标。[#18664](https://github.com/ant-design/ant-design/pull/18664) [@qq645381995](https://github.com/qq645381995)
|
||||
- 🌟 支持 `onRemove` 对上传中断的控制。[#18937](https://github.com/ant-design/ant-design/pull/18937) [@ladjzero](https://github.com/ladjzero)
|
||||
- 🌟 Input.Search 新增 `loading` 属性,用于展示加载中的状态。[#18771](https://github.com/ant-design/ant-design/pull/18771)
|
||||
- 🌟 Grid 的 `gutter` 属性新增垂直间距的支持,现在你可以给 `gutter` 设置一个数组,数组的第二个值就表示垂直间距。[#18979](https://github.com/ant-design/ant-design/pull/18979)
|
||||
- 🌟 message 新增支持通过唯一的 `key` 来更新内容。[#18678](https://github.com/ant-design/ant-design/pull/18678)
|
||||
- 🌟 Layout 新增 `zeroWidthTriggerStyle` 属性以控制当 `collapsedWidth` 为 `0` 时,出现的特殊 `trigger` 的样式。[#19079](https://github.com/ant-design/ant-design/pull/19079)
|
||||
- 🌟 Drawer 新增 `drawerStyle` 和 `headerStyle` 属性。[#19109](https://github.com/ant-design/ant-design/pull/19109)
|
||||
- PageHeader
|
||||
- 💄 重新设计了样式 [#19100](https://github.com/ant-design/ant-design/pull/19100)
|
||||
- 🌟 新增 `ghost` 属性,用于设置是否需要白底背景。[#19100](https://github.com/ant-design/ant-design/pull/19100)
|
||||
- ConfigProvider
|
||||
- 🌟 新增 `pageHeader` 用于全局控制 PageHeader 的样式。[#19100](https://github.com/ant-design/ant-design/pull/19100)
|
||||
- 🐞 修复 moment 不能被 tree shaking 的问题。[#19115](https://github.com/ant-design/ant-design/pull/19115)
|
||||
- 🐞 修复 TreeSelect 的 `removeIcon` 和 `clearIcon` 属性不生效的问题。[#18949](https://github.com/ant-design/ant-design/pull/18949)
|
||||
- 🐞 修复 Tree 设置 `showLine` 后 `switcherIcon` 不生效的问题。[#18829](https://github.com/ant-design/ant-design/pull/18829) [@MrHeer](https://github.com/MrHeer)
|
||||
- 🐞 修复 Slider 组件设置 `handle` 大小后定位错误的问题。[#19120](https://github.com/ant-design/ant-design/pull/19120)
|
||||
- Collapse
|
||||
- 🐞 修复在 IE 11 下的图标样式。[#19135](https://github.com/ant-design/ant-design/pull/19135) [@GBcrimson](https://github.com/GBcrimson)
|
||||
- 🐞 修复 `expandIcon` 的 `className` 会被覆盖的问题。[#19160](https://github.com/ant-design/ant-design/pull/19160) [@gpetrioli](https://github.com/gpetrioli)
|
||||
- 🐞 修复 Tree.DirectoryTree 组件传入 `treeData` 时 `defaultExpandAll` 不生效的问题。[#19148](https://github.com/ant-design/ant-design/pull/19148)
|
||||
- 🐞 修复 Dropdown 下部分 Menu 样式错乱的问题。[#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
- 🐞 修复 Cascader 的 `placeholder` 国际化错误。[#19227](https://github.com/ant-design/ant-design/pull/19227) [@kagawagao](https://github.com/kagawagao)
|
||||
- 🌟 新增 less 变量 `@typography-title-margin-top` 和 `@typography-title-margin-bottom`。[#18746](https://github.com/ant-design/ant-design/pull/18746)
|
||||
- 🗑 废弃 Input.TextArea 的 `autosize` 属性,请使用 `autoSize` 代替。[#19177](https://github.com/ant-design/ant-design/pull/19177)
|
||||
|
||||
## 3.23.6
|
||||
|
||||
`2019-10-05`
|
||||
|
||||
- 🐞 修复 Typography 提示获取不到 `ref` 的错误信息。[#19074](https://github.com/ant-design/ant-design/pull/19074)
|
||||
|
||||
## 3.23.5
|
||||
|
||||
`2019-09-29`
|
||||
|
||||
- 🐞 修复 Upload 预览图片无法填充满图片框的问题。[#18990](https://github.com/ant-design/ant-design/pull/18990)
|
||||
- 🐞 修复 Breadcrumb 不支持 `data-*` 和 `aria-*` 的问题。[#18941](https://github.com/ant-design/ant-design/pull/18941) [@sosohime](https://github.com/sosohime)
|
||||
- 🐞 修复 TreeSelect `removeIcon` 和 `clearIcon` 不工作的问题。[#18949](https://github.com/ant-design/ant-design/issues/18949) [@sosohime](https://github.com/sosohime)
|
||||
- 🐞 修复 Tree 组件当 `showLine` 设置后 `switcherIcon` 没有正常工作的问题。[#18829](https://github.com/ant-design/ant-design/pull/18829) [@MrHeer](https://github.com/MrHeer)
|
||||
- 🐞 修复按钮图标在 Button.Group 中的错位问题。[#18994](https://github.com/ant-design/ant-design/pull/18994)
|
||||
- 🐞 移除 Select 中无效属性 `searchValue` 的定义及文档。[#19003](https://github.com/ant-design/ant-design/pull/19003)
|
||||
- 🐞 修复 Avatar 文本头像在 ssr 时会闪烁的问题。[#19029](https://github.com/ant-design/ant-design/pull/19029)
|
||||
- TypeScript
|
||||
- 🐞 修复 Grid 组件的类型定义。[#18946](https://github.com/ant-design/ant-design/pull/18946) [@handycode](https://github.com/handycode)
|
||||
|
||||
## 3.23.4
|
||||
|
||||
`2019-09-21`
|
||||
|
||||
- 🐞 修复 Transfer `disabled` 下勾选框不被禁用的问题。[#18849](https://github.com/ant-design/ant-design/pull/18849)
|
||||
- 🐞 回滚 Dragger 到 class component 以修复 ref 警告信息。[#18707](https://github.com/ant-design/ant-design/issues/18707)
|
||||
- 🐞 修复 Input `addonAfter` 里图标高度在 Chrome 下偏大的问题。[#18858](https://github.com/ant-design/ant-design/pull/18858)
|
||||
- 🐞 修复 Menu 在 `collapsedWidth={0}` 时,折叠后丢失 `selectedKeys` 状态的问题。[#18907](https://github.com/ant-design/ant-design/pull/18907)
|
||||
- 🐞 修复 Input 在禁用状态时,后缀图标可点击的问题。[#18900](https://github.com/ant-design/ant-design/pull/18900)
|
||||
- 🐞 修复 Alert 标题和内容过长不换行的问题。[#18929](https://github.com/ant-design/ant-design/pull/18929)
|
||||
- 💄 增加 `@page-header-back-color` less 变量。[#18887](https://github.com/ant-design/ant-design/pull/18887)
|
||||
- TypeScript
|
||||
- 🐞 修复 Table 事件的类型定义。[#18910](https://github.com/ant-design/ant-design/pull/18910)
|
||||
|
||||
## 3.23.3
|
||||
|
||||
`2019-09-16`
|
||||
|
||||
- 🐞 修复 ConfigProvider `locale` 国际化在某些场景下对 Modal 不生效的问题。[#18732](https://github.com/ant-design/ant-design/pull/18732)
|
||||
- 🐞 修复 Avatar 长图片时被挤压的样式问题。[#18768](https://github.com/ant-design/ant-design/pull/18768) [@Eusen](https://github.com/Eusen)
|
||||
- 🐞 修复 InputNumber 高亮边框的样式问题。[#18791](https://github.com/ant-design/ant-design/pull/18791) [@escorponox](https://github.com/escorponox)
|
||||
- 🐞 修复 Input.Search 点击清除图标时没有触发 `onSearch` 的问题。[#18783](https://github.com/ant-design/ant-design/pull/18783)
|
||||
- 🐞 修复 Menu 内的 Button 字体颜色。[#18820](https://github.com/ant-design/ant-design/pull/18820)
|
||||
- 🐞 修复 Table `size="small"` 时丢失列头右边框的问题。[#18821](https://github.com/ant-design/ant-design/pull/18821)
|
||||
- ⌨️ 增强 Alert 关闭按钮的可访问性。[#18750](https://github.com/ant-design/ant-design/pull/18750) [@MrHeer](https://github.com/MrHeer)
|
||||
- 💄 优化 Button 类型为 `link` 时,中文字符之间不再自动插入空格。[#18724](https://github.com/ant-design/ant-design/pull/18724)
|
||||
- TypeScript
|
||||
- 🐞 修复 Tree 中 `onMouseEnter` 和 `onMouseLeave` 类型。[#18796](https://github.com/ant-design/ant-design/pull/18796) [@MrHeer](https://github.com/MrHeer)
|
||||
|
||||
## 3.23.2
|
||||
|
||||
`2019-09-06`
|
||||
|
||||
- 🐞 修复圆形按钮的字体大一号的问题。[#18701](https://github.com/ant-design/ant-design/pull/18701)
|
||||
- 🐞 修复 Descriptions 带边框时控制台告警的问题。[#18637](https://github.com/ant-design/ant-design/pull/18637)
|
||||
- 🐞 修复 Drawer 无遮罩从右边展开时的动画问题。[#18636](https://github.com/ant-design/ant-design/pull/18636)
|
||||
- 🐞 修复 Icon 中 `component` 和 `children` 属性优先级低于 `type` 的问题。[#18592](https://github.com/ant-design/ant-design/pull/18592)
|
||||
- 🐞 修复 Layout.Sider 的最大宽度的响应式断点值。[#18553](https://github.com/ant-design/ant-design/pull/18553) [@Nikitenkova](https://github.com/Nikitenkova)
|
||||
- 🐞 修复 PageHeader 中返回图标与面包屑无法共存的问题。[#18691](https://github.com/ant-design/ant-design/pull/18691)
|
||||
- 🗑 废弃 Select 的 `inputValue` 属性,请使用 `searchValue` 代替。[#18629](https://github.com/ant-design/ant-design/pull/18629)
|
||||
- TypeScript
|
||||
- 🐞 修复 Result 中 `status` 的类型定义。[#18445](https://github.com/ant-design/ant-design/pull/18445)
|
||||
- 🐞 修复 Anchor.Link 中 `target` 的类型定义。[#18646](https://github.com/ant-design/ant-design/pull/18646)
|
||||
- 🐞 修复 Upload 中 `transformFile` 函数的参数定义。[#18671](https://github.com/ant-design/ant-design/pull/18671)
|
||||
- 🐞 修复 Table 中 `title` 和 `footer` 的类型定义。[#18697](https://github.com/ant-design/ant-design/pull/18697) [@yoyo837](https://github.com/yoyo837)
|
||||
|
||||
## 3.23.1
|
||||
|
||||
`2019-09-03`
|
||||
|
||||
- 🐞 修复 Upload 在 `multiple` 为 `false` 时无法上传多于一个文件的问题。[#18626](https://github.com/ant-design/ant-design/pull/18626)
|
||||
- 🐞 修复 MonthPicker 切换按钮溢出的问题。[#18624](https://github.com/ant-design/ant-design/pull/18624)
|
||||
- 💄 Tree 增加 `@tree-node-hover-bg` 和 `@tree-node-selected-bg` less 变量。[#18593](https://github.com/ant-design/ant-design/pull/18593) [@MrHeer](https://github.com/MrHeer)
|
||||
|
||||
## 3.23.0
|
||||
|
||||
`2019-09-02`
|
||||
@@ -41,7 +162,7 @@ timeline: true
|
||||
- Descriptions
|
||||
- 🐞 修复 Descriptions.Item 最后一个宽度计算不正确的问题。[#18568](https://github.com/ant-design/ant-design/pull/18568)
|
||||
- 🐞 Description.Item 在渲染时会复用用户提供的 `key`。[#18578](https://github.com/ant-design/ant-design/pull/18578)
|
||||
- 🐞 修复 Tab 内容宽度在 Safari 下不正确的问题。[#18574](https://github.com/ant-design/ant-design/pull/18574)
|
||||
- 🐞 修复 Tabs 内容宽度在 Safari 下不正确的问题。[#18574](https://github.com/ant-design/ant-design/pull/18574)
|
||||
- 🐞 修复 Mentions 的 `prefix` 为空字符串时,弹窗位置不正确的问题。[#18576](https://github.com/ant-design/ant-design/pull/18576)
|
||||
- 🐞 修复 Upload.Dragger 在 `multiple` 为 false 时,仍然可以上传多份文件的问题。[#18580](https://github.com/ant-design/ant-design/pull/18580)
|
||||
- 🐞 修复 `Button[href]` 在 Card `actions` 中样式变形的问题。[#18588](https://github.com/ant-design/ant-design/pull/18588)
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
一套企业级的 UI 设计语言和 React 实现。
|
||||
一套企业级 UI 设计语言和 React 组件库。
|
||||
|
||||
[](https://circleci.com/gh/ant-design/ant-design) [](https://codecov.io/gh/ant-design/ant-design/branch/master) [](https://www.npmjs.org/package/antd) [](http://npmjs.com/antd)
|
||||
[](https://circleci.com/gh/ant-design/ant-design)  [](https://codecov.io/gh/ant-design/ant-design/branch/master) [](https://www.npmjs.com/package/antd) [](https://www.npmjs.com/package/antd) [](http://npmjs.com/antd)
|
||||
|
||||
[](https://david-dm.org/ant-design/ant-design) [](https://david-dm.org/ant-design/ant-design?type=dev) [](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
|
||||
|
||||
10
README.md
10
README.md
@@ -8,9 +8,9 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
An enterprise-class UI design language and React implementation.
|
||||
An enterprise-class UI design language and React UI library.
|
||||
|
||||
[](https://circleci.com/gh/ant-design/ant-design) [](https://codecov.io/gh/ant-design/ant-design/branch/master) [](https://www.npmjs.com/package/antd) [](http://npmjs.com/antd)
|
||||
[](https://circleci.com/gh/ant-design/ant-design)  [](https://codecov.io/gh/ant-design/ant-design/branch/master) [](https://www.npmjs.com/package/antd) [](https://www.npmjs.com/package/antd) [](http://npmjs.com/antd)
|
||||
|
||||
[](https://david-dm.org/ant-design/ant-design) [](https://david-dm.org/ant-design/ant-design?type=dev) [](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
|
||||
@@ -122,8 +122,8 @@ If you are a collaborator, please follow our [Pull Request principle](https://gi
|
||||
|
||||
[](https://issuehunt.io/repos/34526884)
|
||||
|
||||
## ❤️ Backers and Sponsors  
|
||||
|
||||
[](https://opencollective.com/ant-design#support)
|
||||
## ❤️ Sponsors and Backers [](https://opencollective.com/ant-design#support) [](https://opencollective.com/ant-design#support)
|
||||
|
||||
[](https://opencollective.com/ant-design#support)
|
||||
|
||||
[](https://opencollective.com/ant-design#support)
|
||||
|
||||
@@ -9,8 +9,6 @@ import triggerEvent from '../triggerEvent';
|
||||
import Wave from '../wave';
|
||||
import TransButton from '../transButton';
|
||||
import openAnimation from '../openAnimation';
|
||||
import ResizeObserver from '../resizeObserver';
|
||||
import { spyElementPrototype } from '../../__tests__/util/domHook';
|
||||
|
||||
describe('Test utils function', () => {
|
||||
beforeAll(() => {
|
||||
@@ -226,47 +224,4 @@ describe('Test utils function', () => {
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ResizeObserver', () => {
|
||||
let domMock;
|
||||
|
||||
beforeAll(() => {
|
||||
domMock = spyElementPrototype(HTMLDivElement, 'getBoundingClientRect', () => {
|
||||
return {
|
||||
width: 1128 + Math.random(),
|
||||
height: 903 + Math.random(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
domMock.mockRestore();
|
||||
});
|
||||
|
||||
it('should not trigger `onResize` if size shaking', () => {
|
||||
const onResize = jest.fn();
|
||||
let divNode;
|
||||
|
||||
const wrapper = mount(
|
||||
<ResizeObserver onResize={onResize}>
|
||||
<div
|
||||
ref={node => {
|
||||
divNode = node;
|
||||
}}
|
||||
/>
|
||||
</ResizeObserver>,
|
||||
);
|
||||
|
||||
// First trigger
|
||||
wrapper.instance().onResize([{ target: divNode }]);
|
||||
onResize.mockReset();
|
||||
|
||||
// Repeat trigger should not trigger outer `onResize` with shaking
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
wrapper.instance().onResize([{ target: divNode }]);
|
||||
}
|
||||
|
||||
expect(onResize).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
17
components/_util/ref.ts
Normal file
17
components/_util/ref.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
export function fillRef<T>(ref: React.Ref<T>, node: T) {
|
||||
if (typeof ref === 'function') {
|
||||
ref(node);
|
||||
} else if (typeof ref === 'object' && ref && 'current' in ref) {
|
||||
(ref as any).current = node;
|
||||
}
|
||||
}
|
||||
|
||||
export function composeRef<T>(...refs: React.Ref<T>[]): React.Ref<T> {
|
||||
return (node: T) => {
|
||||
refs.forEach(ref => {
|
||||
fillRef(ref, node);
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
||||
type DomElement = Element | null;
|
||||
|
||||
interface ResizeObserverProps {
|
||||
children?: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
onResize?: () => void;
|
||||
}
|
||||
|
||||
interface ResizeObserverState {
|
||||
height: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
class ReactResizeObserver extends React.Component<ResizeObserverProps, ResizeObserverState> {
|
||||
resizeObserver: ResizeObserver | null = null;
|
||||
|
||||
state = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.onComponentUpdated();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.onComponentUpdated();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.destroyObserver();
|
||||
}
|
||||
|
||||
onComponentUpdated() {
|
||||
const { disabled } = this.props;
|
||||
const element = findDOMNode(this) as DomElement;
|
||||
if (!this.resizeObserver && !disabled && element) {
|
||||
// Add resize observer
|
||||
this.resizeObserver = new ResizeObserver(this.onResize);
|
||||
this.resizeObserver.observe(element);
|
||||
} else if (disabled) {
|
||||
// Remove resize observer
|
||||
this.destroyObserver();
|
||||
}
|
||||
}
|
||||
|
||||
onResize: ResizeObserverCallback = (entries: ResizeObserverEntry[]) => {
|
||||
const { onResize } = this.props;
|
||||
|
||||
const { target } = entries[0];
|
||||
|
||||
const { width, height } = target.getBoundingClientRect();
|
||||
|
||||
/**
|
||||
* Resize observer trigger when content size changed.
|
||||
* In most case we just care about element size,
|
||||
* let's use `boundary` instead of `contentRect` here to avoid shaking.
|
||||
*/
|
||||
const fixedWidth = Math.floor(width);
|
||||
const fixedHeight = Math.floor(height);
|
||||
|
||||
if (this.state.width !== fixedWidth || this.state.height !== fixedHeight) {
|
||||
this.setState({
|
||||
width: fixedWidth,
|
||||
height: fixedHeight,
|
||||
});
|
||||
|
||||
if (onResize) {
|
||||
onResize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
destroyObserver() {
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.disconnect();
|
||||
this.resizeObserver = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children = null } = this.props;
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
export default ReactResizeObserver;
|
||||
@@ -2,6 +2,7 @@
|
||||
// https://github.com/WickyNilliams/enquire.js/issues/82
|
||||
let enquire: any;
|
||||
|
||||
// TODO: Will be removed in antd 4.0 because we will no longer support ie9
|
||||
if (typeof window !== 'undefined') {
|
||||
const matchMediaPolyfill = (mediaQuery: string) => {
|
||||
return {
|
||||
@@ -11,7 +12,8 @@ if (typeof window !== 'undefined') {
|
||||
removeListener() {},
|
||||
};
|
||||
};
|
||||
window.matchMedia = window.matchMedia || matchMediaPolyfill;
|
||||
// ref: https://github.com/ant-design/ant-design/issues/18774
|
||||
if (!window.matchMedia) window.matchMedia = matchMediaPolyfill as any;
|
||||
// eslint-disable-next-line global-require
|
||||
enquire = require('enquire.js');
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ describe('Affix Render', () => {
|
||||
// Mock trigger resize
|
||||
updateCalled.mockReset();
|
||||
wrapper
|
||||
.find('ReactResizeObserver')
|
||||
.find('ResizeObserver')
|
||||
.at(index)
|
||||
.instance()
|
||||
.onResize([{ target: { getBoundingClientRect: () => ({ width: 99, height: 99 }) } }]);
|
||||
|
||||
@@ -2,9 +2,9 @@ import * as React from 'react';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import ResizeObserver from 'rc-resize-observer';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
||||
import ResizeObserver from '../_util/resizeObserver';
|
||||
|
||||
import warning from '../_util/warning';
|
||||
import {
|
||||
@@ -35,6 +35,7 @@ export interface AffixProps {
|
||||
target?: () => Window | HTMLElement | null;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
children: React.ReactElement;
|
||||
}
|
||||
|
||||
enum AffixStatus {
|
||||
|
||||
@@ -66,10 +66,10 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<span
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
@@ -90,7 +90,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
<div
|
||||
@@ -172,10 +172,10 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<span
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
@@ -196,7 +196,7 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-error ant-alert-with-description ant-alert-no-icon ant-alert-closable"
|
||||
@@ -212,10 +212,10 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
|
||||
>
|
||||
Error Description Error Description Error Description Error Description Error Description Error Description
|
||||
</span>
|
||||
<span
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
@@ -236,7 +236,7 @@ exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -254,17 +254,17 @@ exports[`renders ./components/alert/demo/close-text.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<span
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-close-text"
|
||||
>
|
||||
Close Now
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -910,10 +910,10 @@ exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<span
|
||||
<button
|
||||
class="ant-alert-close-icon"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
@@ -934,7 +934,7 @@ exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<p>
|
||||
placeholder text here
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface AlertProps {
|
||||
/** Additional content of Alert */
|
||||
description?: React.ReactNode;
|
||||
/** Callback when close Alert */
|
||||
onClose?: React.MouseEventHandler<HTMLAnchorElement>;
|
||||
onClose?: React.MouseEventHandler<HTMLButtonElement>;
|
||||
/** Trigger when animation ending of Alert */
|
||||
afterClose?: () => void;
|
||||
/** Whether to show icon */
|
||||
@@ -57,7 +57,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
};
|
||||
}
|
||||
|
||||
handleClose = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
handleClose = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault();
|
||||
const dom = ReactDOM.findDOMNode(this) as HTMLElement;
|
||||
dom.style.height = `${dom.offsetHeight}px`;
|
||||
@@ -143,8 +143,8 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
);
|
||||
|
||||
const closeIcon = closable ? (
|
||||
<span
|
||||
role="button"
|
||||
<button
|
||||
type="button"
|
||||
onClick={this.handleClose}
|
||||
className={`${prefixCls}-close-icon`}
|
||||
tabIndex={0}
|
||||
@@ -154,7 +154,7 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
|
||||
) : (
|
||||
<Icon type="close" />
|
||||
)}
|
||||
</span>
|
||||
</button>
|
||||
) : null;
|
||||
|
||||
const dataOrAriaProps = getDataOrAriaProps(this.props);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
position: relative;
|
||||
padding: 8px 15px 8px 37px;
|
||||
word-wrap: break-word;
|
||||
border-radius: @border-radius-base;
|
||||
|
||||
&&-no-icon {
|
||||
@@ -74,6 +75,8 @@
|
||||
overflow: hidden;
|
||||
font-size: @font-size-sm;
|
||||
line-height: 22px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
.@{iconfont-css-prefix}-close {
|
||||
|
||||
@@ -62,6 +62,8 @@ export interface AnchorProps {
|
||||
) => void;
|
||||
/** Scroll to target offset value, if none, it's offsetTop prop value or 0. */
|
||||
targetOffset?: number;
|
||||
/** Listening event when scrolling change active link */
|
||||
onChange?: (currentActiveLink: string) => void;
|
||||
}
|
||||
|
||||
export interface AnchorState {
|
||||
@@ -205,7 +207,7 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
|
||||
handleScrollTo = (link: string) => {
|
||||
const { offsetTop, getContainer, targetOffset } = this.props as AnchorDefaultProps;
|
||||
|
||||
this.setState({ activeLink: link });
|
||||
this.setCurrentActiveLink(link);
|
||||
const container = getContainer();
|
||||
const scrollTop = getScroll(container, true);
|
||||
const sharpLinkMatch = sharpMatcherRegx.exec(link);
|
||||
@@ -234,21 +236,30 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState> {
|
||||
this.inkNode = node;
|
||||
};
|
||||
|
||||
setCurrentActiveLink = (link: string) => {
|
||||
const { activeLink } = this.state;
|
||||
const { onChange } = this.props;
|
||||
|
||||
if (activeLink !== link) {
|
||||
this.setState({
|
||||
activeLink: link,
|
||||
});
|
||||
if (onChange) {
|
||||
onChange(link);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleScroll = () => {
|
||||
if (this.animating) {
|
||||
return;
|
||||
}
|
||||
const { activeLink } = this.state;
|
||||
const { offsetTop, bounds, targetOffset } = this.props;
|
||||
const currentActiveLink = this.getCurrentAnchor(
|
||||
targetOffset !== undefined ? targetOffset : offsetTop || 0,
|
||||
bounds,
|
||||
);
|
||||
if (activeLink !== currentActiveLink) {
|
||||
this.setState({
|
||||
activeLink: currentActiveLink,
|
||||
});
|
||||
}
|
||||
this.setCurrentActiveLink(currentActiveLink);
|
||||
};
|
||||
|
||||
updateInk = () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
export interface AnchorLinkProps {
|
||||
prefixCls?: string;
|
||||
href: string;
|
||||
target: string;
|
||||
target?: string;
|
||||
title: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
|
||||
@@ -279,10 +279,13 @@ describe('Anchor Render', () => {
|
||||
let dateNowMock;
|
||||
|
||||
function dataNowMockFn() {
|
||||
return jest
|
||||
.spyOn(Date, 'now')
|
||||
.mockImplementationOnce(() => 0)
|
||||
.mockImplementationOnce(() => 1000);
|
||||
let start = 0;
|
||||
|
||||
const handler = () => {
|
||||
return (start += 1000);
|
||||
};
|
||||
|
||||
return jest.spyOn(Date, 'now').mockImplementation(handler);
|
||||
}
|
||||
|
||||
dateNowMock = dataNowMockFn();
|
||||
@@ -319,4 +322,18 @@ describe('Anchor Render', () => {
|
||||
dateNowMock.mockRestore();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('Anchor onChange prop', async () => {
|
||||
const onChange = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Anchor onChange={onChange}>
|
||||
<Link href="#API1" title="API1" />
|
||||
<Link href="#API2" title="API2" />
|
||||
</Anchor>,
|
||||
);
|
||||
expect(onChange).toHaveBeenCalledTimes(1);
|
||||
wrapper.instance().handleScrollTo('#API2');
|
||||
expect(onChange).toHaveBeenCalledTimes(2);
|
||||
expect(onChange).toHaveBeenCalledWith('#API2');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -166,6 +166,80 @@ exports[`renders ./components/anchor/demo/customizeHighlight.md correctly 1`] =
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/onChange.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
style="max-height:100vh"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor fixed"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-ink"
|
||||
>
|
||||
<span
|
||||
class="ant-anchor-ink-ball"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-basic"
|
||||
title="Basic demo"
|
||||
>
|
||||
Basic demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-static"
|
||||
title="Static demo"
|
||||
>
|
||||
Static demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#API"
|
||||
title="API"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Anchor-Props"
|
||||
title="Anchor Props"
|
||||
>
|
||||
Anchor Props
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Link-Props"
|
||||
title="Link Props"
|
||||
>
|
||||
Link Props
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/onClick.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
|
||||
36
components/anchor/demo/onChange.md
Normal file
36
components/anchor/demo/onChange.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 监听锚点链接改变
|
||||
en-US: Listening for anchor link change
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
监听锚点链接改变
|
||||
|
||||
## en-US
|
||||
|
||||
Listening for anchor link change.
|
||||
|
||||
```jsx
|
||||
import { Anchor } from 'antd';
|
||||
|
||||
const { Link } = Anchor;
|
||||
|
||||
const onChange = link => {
|
||||
console.log('Anchor:OnChange', link);
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Anchor affix={false} onChange={onChange}>
|
||||
<Link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<Link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<Link href="#API" title="API">
|
||||
<Link href="#Anchor-Props" title="Anchor Props" />
|
||||
<Link href="#Link-Props" title="Link Props" />
|
||||
</Link>
|
||||
</Anchor>,
|
||||
mountNode,
|
||||
);
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
order: 4
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 设置锚点滚动偏移量
|
||||
en-US: Set Anchor scroll offset
|
||||
|
||||
@@ -26,6 +26,7 @@ For displaying anchor hyperlinks on page and jumping between them.
|
||||
| onClick | set the handler to handle `click` event | Function(e: Event, link: Object) | - | 3.9.0 |
|
||||
| getCurrentAnchor | Customize the anchor highlight | () => string | - | 3.22.0 |
|
||||
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 |
|
||||
| onChange | Listening for anchor link change | (currentActiveLink: string) => void | | 3.24.0 |
|
||||
|
||||
### Link Props
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ title: Anchor
|
||||
| onClick | `click` 事件的 handler | Function(e: Event, link: Object) | - | 3.9.0 |
|
||||
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | 3.22.0 |
|
||||
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | 3.22.0 |
|
||||
| onChange | 监听锚点链接改变 | (currentActiveLink: string) => void | | 3.24.0 |
|
||||
|
||||
### Link Props
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
| children (for customize input element) | customize input element | HTMLInputElement <br /><br /> HTMLTextAreaElement <br /><br /> `React.ReactElement<InputProps>` | `<Input />` | |
|
||||
| children (for dataSource) | Data source to auto complete | `React.ReactElement<OptionProps>` <br /><br /> `Array<React.ReactElement<OptionProps>>` | - | |
|
||||
| dataSource | Data source for autocomplete | [DataSourceItemType](https://git.io/vMMKF)\[] | - | |
|
||||
| dropdownMenuStyle | additional style applied to dropdown menu | object | | |
|
||||
| defaultActiveFirstOption | Whether active first option by default | boolean | true | |
|
||||
| defaultValue | Initial selected option. | string\|string\[] | - | |
|
||||
| disabled | Whether disabled select | boolean | false | |
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface AutoCompleteProps extends Omit<AbstractSelectProps, 'loading'>
|
||||
value?: SelectValue;
|
||||
defaultValue?: SelectValue;
|
||||
dataSource?: DataSourceItemType[];
|
||||
dropdownMenuStyle?: React.CSSProperties;
|
||||
autoFocus?: boolean;
|
||||
backfill?: boolean;
|
||||
optionLabelProp?: string;
|
||||
|
||||
@@ -27,6 +27,7 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
| children (自定义输入框) | 自定义输入框 | HTMLInputElement <br /><br /> HTMLTextAreaElement <br /><br /> `React.ReactElement<InputProps>` | `<Input />` | |
|
||||
| children (自动完成的数据源) | 自动完成的数据源 | `React.ReactElement<OptionProps>` <br /><br /> `Array<React.ReactElement<OptionProps>>` | - | |
|
||||
| dataSource | 自动完成的数据源 | [DataSourceItemType](https://git.io/vMMKF)\[] | | |
|
||||
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | | |
|
||||
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | |
|
||||
| defaultValue | 指定默认选中的条目 | string\|string\[]\| 无 | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
|
||||
@@ -433,6 +433,7 @@ exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
@@ -486,6 +487,7 @@ exports[`renders ./components/avatar/demo/toggle-debug.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
>
|
||||
Avatar
|
||||
</span>
|
||||
@@ -507,6 +509,7 @@ exports[`renders ./components/avatar/demo/toggle-debug.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
>
|
||||
Avatar
|
||||
</span>
|
||||
@@ -554,6 +557,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
@@ -563,6 +567,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
>
|
||||
USER
|
||||
</span>
|
||||
@@ -580,6 +585,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
|
||||
@@ -29,6 +29,7 @@ export interface AvatarProps {
|
||||
|
||||
export interface AvatarState {
|
||||
scale: number;
|
||||
mounted: boolean;
|
||||
isImgExist: boolean;
|
||||
}
|
||||
|
||||
@@ -40,6 +41,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
|
||||
state = {
|
||||
scale: 1,
|
||||
mounted: false,
|
||||
isImgExist: true,
|
||||
};
|
||||
|
||||
@@ -53,6 +55,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
|
||||
componentDidMount() {
|
||||
this.setScale();
|
||||
this.setState({ mounted: true });
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: AvatarProps) {
|
||||
@@ -105,7 +108,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
...others
|
||||
} = this.props;
|
||||
|
||||
const { isImgExist, scale } = this.state;
|
||||
const { isImgExist, scale, mounted } = this.state;
|
||||
|
||||
const prefixCls = getPrefixCls('avatar', customizePrefixCls);
|
||||
|
||||
@@ -144,6 +147,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
WebkitTransform: transformString,
|
||||
transform: transformString,
|
||||
};
|
||||
|
||||
const sizeChildrenStyle: React.CSSProperties =
|
||||
typeof size === 'number'
|
||||
? {
|
||||
@@ -160,9 +164,15 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
const childrenStyle: React.CSSProperties = {};
|
||||
if (!mounted) {
|
||||
childrenStyle.opacity = 0;
|
||||
}
|
||||
|
||||
children = (
|
||||
<span
|
||||
className={`${prefixCls}-string`}
|
||||
style={{ opacity: 0 }}
|
||||
ref={(node: HTMLElement) => (this.avatarChildren = node)}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as React from 'react';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import toArray from 'rc-util/lib/Children/toArray';
|
||||
import omit from 'omit.js';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
import BreadcrumbSeparator from './BreadcrumbSeparator';
|
||||
import Menu from '../menu';
|
||||
@@ -144,6 +145,7 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
|
||||
className,
|
||||
routes,
|
||||
children,
|
||||
...restProps
|
||||
} = this.props;
|
||||
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
|
||||
if (routes && routes.length > 0) {
|
||||
@@ -169,7 +171,11 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div className={classNames(className, prefixCls)} style={style}>
|
||||
<div
|
||||
className={classNames(className, prefixCls)}
|
||||
style={style}
|
||||
{...omit(restProps, ['itemRender', 'params'])}
|
||||
>
|
||||
{crumbs}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -102,4 +102,14 @@ describe('Breadcrumb', () => {
|
||||
const wrapper = render(<Breadcrumb routes={routes} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should support custom attribute', () => {
|
||||
const wrapper = render(
|
||||
<Breadcrumb data-custom="custom">
|
||||
<Breadcrumb.Item data-custom="custom-item">xxx</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>yyy</Breadcrumb.Item>
|
||||
</Breadcrumb>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -157,3 +157,36 @@ exports[`Breadcrumb should render a menu 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Breadcrumb should support custom attribute 1`] = `
|
||||
<div
|
||||
class="ant-breadcrumb"
|
||||
data-custom="custom"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
data-custom="custom-item"
|
||||
>
|
||||
xxx
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
yyy
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -22,37 +22,6 @@ const breadcrumbNameMap = {
|
||||
'/apps/2/detail': 'Detail',
|
||||
};
|
||||
|
||||
const Home = withRouter(props => {
|
||||
const { location, history } = props;
|
||||
const pathSnippets = location.pathname.split('/').filter(i => i);
|
||||
const extraBreadcrumbItems = pathSnippets.map((_, index) => {
|
||||
const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
|
||||
return (
|
||||
<Breadcrumb.Item key={url}>
|
||||
<Link to={url}>{breadcrumbNameMap[url]}</Link>
|
||||
</Breadcrumb.Item>
|
||||
);
|
||||
});
|
||||
const breadcrumbItems = [
|
||||
<Breadcrumb.Item key="home">
|
||||
<Link to="/">Home</Link>
|
||||
</Breadcrumb.Item>,
|
||||
].concat(extraBreadcrumbItems);
|
||||
return (
|
||||
<div className="demo">
|
||||
<div className="demo-nav">
|
||||
<a onClick={() => history.push('/')}>Home</a>
|
||||
<a onClick={() => history.push('/apps')}>Application List</a>
|
||||
</div>
|
||||
<Switch>
|
||||
<Route path="/apps" component={Apps} />
|
||||
<Route render={() => <span>Home Page</span>} />
|
||||
</Switch>
|
||||
<Breadcrumb>{breadcrumbItems}</Breadcrumb>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
describe('react router', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
@@ -62,7 +31,37 @@ describe('react router', () => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
// https://github.com/airbnb/enzyme/issues/875
|
||||
it('react router 4', () => {
|
||||
(process.env.REACT === '15' ? it.skip : it)('react router 4', () => {
|
||||
const Home = withRouter(props => {
|
||||
const { location, history } = props;
|
||||
const pathSnippets = location.pathname.split('/').filter(i => i);
|
||||
const extraBreadcrumbItems = pathSnippets.map((_, index) => {
|
||||
const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
|
||||
return (
|
||||
<Breadcrumb.Item key={url}>
|
||||
<Link to={url}>{breadcrumbNameMap[url]}</Link>
|
||||
</Breadcrumb.Item>
|
||||
);
|
||||
});
|
||||
const breadcrumbItems = [
|
||||
<Breadcrumb.Item key="home">
|
||||
<Link to="/">Home</Link>
|
||||
</Breadcrumb.Item>,
|
||||
].concat(extraBreadcrumbItems);
|
||||
return (
|
||||
<div className="demo">
|
||||
<div className="demo-nav">
|
||||
<a onClick={() => history.push('/')}>Home</a>
|
||||
<a onClick={() => history.push('/apps')}>Application List</a>
|
||||
</div>
|
||||
<Switch>
|
||||
<Route path="/apps" component={Apps} />
|
||||
<Route render={() => <span>Home Page</span>} />
|
||||
</Switch>
|
||||
<Breadcrumb>{breadcrumbItems}</Breadcrumb>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
const wrapper = mount(
|
||||
<MemoryRouter initialEntries={['/']} initialIndex={0}>
|
||||
<Home />
|
||||
|
||||
@@ -188,6 +188,17 @@ exports[`Button renders Chinese characters correctly 6`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button renders Chinese characters correctly 7`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
按 钮
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button renders correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
@@ -222,6 +233,17 @@ exports[`Button should merge text if children using variable 1`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button should not insert space to link button 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-link"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
按钮
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button should not render as link button when href is undefined 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
@@ -233,6 +255,23 @@ exports[`Button should not render as link button when href is undefined 1`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button should render empty button without errors 1`] = `
|
||||
<Button
|
||||
block={false}
|
||||
ghost={false}
|
||||
htmlType="button"
|
||||
loading={false}
|
||||
>
|
||||
<Wave>
|
||||
<button
|
||||
className="ant-btn"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
/>
|
||||
</Wave>
|
||||
</Button>
|
||||
`;
|
||||
|
||||
exports[`Button should support link button 1`] = `
|
||||
<a
|
||||
class="ant-btn"
|
||||
|
||||
@@ -4,10 +4,15 @@ import renderer from 'react-test-renderer';
|
||||
import Button from '..';
|
||||
import Icon from '../../icon';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import { sleep } from '../../../tests/utils';
|
||||
|
||||
describe('Button', () => {
|
||||
mountTest(Button);
|
||||
mountTest(() => <Button size="large" />);
|
||||
mountTest(() => <Button size="small" />);
|
||||
mountTest(Button.Group);
|
||||
mountTest(() => <Button.Group size="large" />);
|
||||
mountTest(() => <Button.Group size="small" />);
|
||||
|
||||
it('renders correctly', () => {
|
||||
const wrapper = render(<Button>Follow</Button>);
|
||||
@@ -48,6 +53,14 @@ describe('Button', () => {
|
||||
// should insert space while loading
|
||||
const wrapper5 = render(<Button loading>按钮</Button>);
|
||||
expect(wrapper5).toMatchSnapshot();
|
||||
|
||||
// should insert space while only one nested element
|
||||
const wrapper6 = render(
|
||||
<Button>
|
||||
<span>按钮</span>
|
||||
</Button>,
|
||||
);
|
||||
expect(wrapper6).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders Chinese characters correctly in HOC', () => {
|
||||
@@ -70,6 +83,22 @@ describe('Button', () => {
|
||||
expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true);
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/18118
|
||||
it('should not insert space to link button', () => {
|
||||
const wrapper = render(<Button type="link">按钮</Button>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render empty button without errors', () => {
|
||||
const wrapper = mount(
|
||||
<Button>
|
||||
{null}
|
||||
{undefined}
|
||||
</Button>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('have static property for type detecting', () => {
|
||||
const wrapper = mount(<Button>Button Text</Button>);
|
||||
// eslint-disable-next-line
|
||||
@@ -125,6 +154,17 @@ describe('Button', () => {
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not clickable when button is loading', () => {
|
||||
const onClick = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Button loading onClick={onClick}>
|
||||
button
|
||||
</Button>,
|
||||
);
|
||||
wrapper.simulate('click');
|
||||
expect(onClick).not.toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should support link button', () => {
|
||||
const wrapper = mount(
|
||||
<Button target="_blank" href="http://ant.design">
|
||||
@@ -166,10 +206,34 @@ describe('Button', () => {
|
||||
it('should merge text if children using variable', () => {
|
||||
const wrapper = mount(
|
||||
<Button>
|
||||
{/* eslint-disable-next-line react/jsx-curly-brace-presence */}
|
||||
This {'is'} a test {1}
|
||||
</Button>,
|
||||
);
|
||||
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should support to change loading', async () => {
|
||||
const wrapper = mount(<Button>Button</Button>);
|
||||
wrapper.setProps({ loading: true });
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-btn-loading').length).toBe(1);
|
||||
wrapper.setProps({ loading: false });
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-btn-loading').length).toBe(0);
|
||||
wrapper.setProps({ loading: { delay: 50 } });
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-btn-loading').length).toBe(0);
|
||||
await sleep(50);
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-btn-loading').length).toBe(1);
|
||||
wrapper.setProps({ loading: false });
|
||||
await sleep(50);
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-btn-loading').length).toBe(0);
|
||||
expect(() => {
|
||||
wrapper.unmount();
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -134,16 +134,6 @@ class Button extends React.Component<ButtonProps, ButtonState> {
|
||||
title: PropTypes.string,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: ButtonProps, prevState: ButtonState) {
|
||||
if (nextProps.loading instanceof Boolean) {
|
||||
return {
|
||||
...prevState,
|
||||
loading: nextProps.loading,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private delayTimeout: number;
|
||||
|
||||
private buttonNode: HTMLElement | null;
|
||||
@@ -169,8 +159,10 @@ class Button extends React.Component<ButtonProps, ButtonState> {
|
||||
|
||||
const { loading } = this.props;
|
||||
if (loading && typeof loading !== 'boolean' && loading.delay) {
|
||||
this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay);
|
||||
} else if (prevProps.loading !== this.props.loading) {
|
||||
this.delayTimeout = window.setTimeout(() => {
|
||||
this.setState({ loading });
|
||||
}, loading.delay);
|
||||
} else if (prevProps.loading !== loading) {
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState({ loading });
|
||||
}
|
||||
@@ -217,8 +209,8 @@ class Button extends React.Component<ButtonProps, ButtonState> {
|
||||
}
|
||||
|
||||
isNeedInserted() {
|
||||
const { icon, children } = this.props;
|
||||
return React.Children.count(children) === 1 && !icon;
|
||||
const { icon, children, type } = this.props;
|
||||
return React.Children.count(children) === 1 && !icon && type !== 'link';
|
||||
}
|
||||
|
||||
renderButton = ({ getPrefixCls, autoInsertSpaceInButton }: ConfigConsumerProps) => {
|
||||
@@ -260,7 +252,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
|
||||
[`${prefixCls}-${shape}`]: shape,
|
||||
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
||||
[`${prefixCls}-icon-only`]: !children && children !== 0 && iconType,
|
||||
[`${prefixCls}-loading`]: loading,
|
||||
[`${prefixCls}-loading`]: !!loading,
|
||||
[`${prefixCls}-background-ghost`]: ghost,
|
||||
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
|
||||
[`${prefixCls}-block`]: block,
|
||||
|
||||
@@ -130,6 +130,11 @@
|
||||
.button-size(@btn-height-lg; @btn-padding-lg; @btn-font-size-lg; 0);
|
||||
line-height: @btn-height-lg - 2px;
|
||||
}
|
||||
&-lg > .@{btnClassName}.@{btnClassName}-icon-only {
|
||||
.square(@btn-height-lg);
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
&-sm > .@{btnClassName},
|
||||
&-sm > span > .@{btnClassName} {
|
||||
.button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; 0);
|
||||
@@ -138,6 +143,11 @@
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
}
|
||||
&-sm > .@{btnClassName}.@{btnClassName}-icon-only {
|
||||
.square(@btn-height-sm);
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
// Base styles of buttons
|
||||
// --------------------------------------------------
|
||||
@@ -225,10 +235,10 @@
|
||||
}
|
||||
// round button
|
||||
.btn-round(@btnClassName: btn) {
|
||||
.button-size(@btn-circle-size; 0 @btn-circle-size / 2; @font-size-base + 2px; @btn-circle-size);
|
||||
.button-size(@btn-circle-size; 0 @btn-circle-size / 2; @font-size-base; @btn-circle-size);
|
||||
&.@{btnClassName}-lg {
|
||||
.button-size(
|
||||
@btn-circle-size-lg; 0 @btn-circle-size-lg / 2; @btn-font-size-lg + 2px; @btn-circle-size-lg
|
||||
@btn-circle-size-lg; 0 @btn-circle-size-lg / 2; @btn-font-size-lg; @btn-circle-size-lg
|
||||
);
|
||||
}
|
||||
&.@{btnClassName}-sm {
|
||||
|
||||
@@ -6,6 +6,7 @@ import warning from '../_util/warning';
|
||||
|
||||
// matchMedia polyfill for
|
||||
// https://github.com/WickyNilliams/enquire.js/issues/82
|
||||
// TODO: Will be removed in antd 4.0 because we will no longer support ie9
|
||||
if (typeof window !== 'undefined') {
|
||||
const matchMediaPolyfill = (mediaQuery: string) => {
|
||||
return {
|
||||
@@ -15,7 +16,8 @@ if (typeof window !== 'undefined') {
|
||||
removeListener() {},
|
||||
};
|
||||
};
|
||||
window.matchMedia = window.matchMedia || matchMediaPolyfill;
|
||||
// ref: https://github.com/ant-design/ant-design/issues/18774
|
||||
if (!window.matchMedia) window.matchMedia = matchMediaPolyfill as any;
|
||||
}
|
||||
// Use require over import (will be lifted up)
|
||||
// make sure matchMedia polyfill run before require('react-slick')
|
||||
|
||||
@@ -952,7 +952,6 @@ exports[`Cascader should highlight keyword and filter when search in Cascader 1`
|
||||
},
|
||||
]
|
||||
}
|
||||
placeholder="Please select"
|
||||
popupClassName=""
|
||||
popupPlacement="bottomLeft"
|
||||
popupVisible={true}
|
||||
@@ -1250,7 +1249,6 @@ exports[`Cascader should render not found content 1`] = `
|
||||
},
|
||||
]
|
||||
}
|
||||
placeholder="Please select"
|
||||
popupClassName=""
|
||||
popupPlacement="bottomLeft"
|
||||
popupVisible={true}
|
||||
@@ -1578,7 +1576,6 @@ exports[`Cascader should show not found content when options.length is 0 1`] = `
|
||||
},
|
||||
]
|
||||
}
|
||||
placeholder="Please select"
|
||||
popupClassName=""
|
||||
popupPlacement="bottomLeft"
|
||||
popupVisible={true}
|
||||
|
||||
@@ -491,4 +491,15 @@ describe('Cascader', () => {
|
||||
);
|
||||
expect(popupWrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('placeholder works correctly', () => {
|
||||
const wrapper = mount(<Cascader options={[]} />);
|
||||
expect(wrapper.find('input').prop('placeholder')).toBe('Please select');
|
||||
|
||||
const customPlaceholder = 'Custom placeholder';
|
||||
wrapper.setProps({
|
||||
placeholder: customPlaceholder,
|
||||
});
|
||||
expect(wrapper.find('input').prop('placeholder')).toBe(customPlaceholder);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -216,7 +216,6 @@ function warningValueNotExist(list: CascaderOptionType[], fieldNames: FieldNames
|
||||
|
||||
class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||
static defaultProps = {
|
||||
placeholder: 'Please select',
|
||||
transitionName: 'slide-up',
|
||||
popupPlacement: 'bottomLeft',
|
||||
options: [],
|
||||
@@ -430,7 +429,7 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||
prefixCls: customizePrefixCls,
|
||||
inputPrefixCls: customizeInputPrefixCls,
|
||||
children,
|
||||
placeholder = locale.placeholder,
|
||||
placeholder = locale.placeholder || 'Please select',
|
||||
size,
|
||||
disabled,
|
||||
className,
|
||||
|
||||
@@ -45,14 +45,15 @@ export default class Collapse extends React.Component<CollapseProps, any> {
|
||||
|
||||
renderExpandIcon = (panelProps: PanelProps = {}, prefixCls: string) => {
|
||||
const { expandIcon } = this.props;
|
||||
const icon = expandIcon ? (
|
||||
const icon = (expandIcon ? (
|
||||
expandIcon(panelProps)
|
||||
) : (
|
||||
<Icon type="right" rotate={panelProps.isActive ? 90 : undefined} />
|
||||
);
|
||||
)) as React.ReactNode;
|
||||
|
||||
return React.isValidElement(icon)
|
||||
? React.cloneElement(icon as any, {
|
||||
className: `${prefixCls}-arrow`,
|
||||
className: classNames(icon.props.className, `${prefixCls}-arrow`),
|
||||
})
|
||||
: icon;
|
||||
};
|
||||
|
||||
@@ -638,7 +638,9 @@ exports[`renders ./components/collapse/demo/extra.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
Expand Icon Position:
|
||||
<span>
|
||||
Expand Icon Position:
|
||||
</span>
|
||||
<div
|
||||
class="ant-select ant-select-enabled"
|
||||
>
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Collapse from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
|
||||
describe('Collapse', () => {
|
||||
// Fix css-animation deps on these
|
||||
// https://github.com/yiminghe/css-animation/blob/a5986d73fd7dfce75665337f39b91483d63a4c8c/src/Event.js#L44
|
||||
window.AnimationEvent = window.AnimationEvent || (() => {});
|
||||
window.TransitionEvent = window.TransitionEvent || (() => {});
|
||||
|
||||
afterAll(() => {
|
||||
// restore it
|
||||
delete window.AnimationEvent;
|
||||
delete window.TransitionEvent;
|
||||
});
|
||||
|
||||
// eslint-disable-next-line global-require
|
||||
const Collapse = require('..').default;
|
||||
mountTest(Collapse);
|
||||
|
||||
it('should support remove expandIcon', () => {
|
||||
@@ -15,6 +27,22 @@ describe('Collapse', () => {
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should keep the className of the expandIcon', () => {
|
||||
const wrapper = mount(
|
||||
<Collapse
|
||||
expandIcon={() => (
|
||||
<button type="button" className="custom-expandicon-classname">
|
||||
action
|
||||
</button>
|
||||
)}
|
||||
>
|
||||
<Collapse.Panel header="header" />
|
||||
</Collapse>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.custom-expandicon-classname').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should render extra node of panel', () => {
|
||||
const wrapper = mount(
|
||||
<Collapse>
|
||||
@@ -24,4 +52,24 @@ describe('Collapse', () => {
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('could be expand and collapse', () => {
|
||||
jest.useFakeTimers();
|
||||
const wrapper = mount(
|
||||
<Collapse>
|
||||
<Collapse.Panel header="This is panel header 1" key="1">
|
||||
content
|
||||
</Collapse.Panel>
|
||||
</Collapse>,
|
||||
);
|
||||
expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(false);
|
||||
wrapper
|
||||
.find('.ant-collapse-header')
|
||||
.at(0)
|
||||
.simulate('click');
|
||||
expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(true);
|
||||
jest.runAllTimers();
|
||||
expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(true);
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ class Demo extends React.Component {
|
||||
</Panel>
|
||||
</Collapse>
|
||||
<br />
|
||||
Expand Icon Position:{' '}
|
||||
<span>Expand Icon Position: </span>
|
||||
<Select value={expandIconPosition} onChange={this.onPositionChange}>
|
||||
<Option value="left">left</Option>
|
||||
<Option value="right">right</Option>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
.@{collapse-prefix-cls}-arrow {
|
||||
right: @padding-md;
|
||||
left: initial;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,6 +360,7 @@ exports[`ConfigProvider components Avatar configProvider 1`] = `
|
||||
>
|
||||
<span
|
||||
class="config-avatar-string"
|
||||
style="opacity:0"
|
||||
/>
|
||||
</span>
|
||||
`;
|
||||
@@ -370,6 +371,7 @@ exports[`ConfigProvider components Avatar normal 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
style="opacity:0"
|
||||
/>
|
||||
</span>
|
||||
`;
|
||||
@@ -380,6 +382,7 @@ exports[`ConfigProvider components Avatar prefixCls 1`] = `
|
||||
>
|
||||
<span
|
||||
class="prefix-Avatar-string"
|
||||
style="opacity:0"
|
||||
/>
|
||||
</span>
|
||||
`;
|
||||
@@ -7407,14 +7410,14 @@ exports[`ConfigProvider components InputNumber configProvider 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemin="-9007199254740991"
|
||||
class="config-input-number-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemin="-9007199254740991"
|
||||
autocomplete="off"
|
||||
class="config-input-number-input"
|
||||
min="-9007199254740991"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value=""
|
||||
/>
|
||||
@@ -7485,14 +7488,14 @@ exports[`ConfigProvider components InputNumber normal 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemin="-9007199254740991"
|
||||
class="ant-input-number-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemin="-9007199254740991"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
min="-9007199254740991"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value=""
|
||||
/>
|
||||
@@ -7563,14 +7566,14 @@ exports[`ConfigProvider components InputNumber prefixCls 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemin="-9007199254740991"
|
||||
class="prefix-InputNumber-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemin="-9007199254740991"
|
||||
autocomplete="off"
|
||||
class="prefix-InputNumber-input"
|
||||
min="-9007199254740991"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value=""
|
||||
/>
|
||||
@@ -8015,7 +8018,7 @@ exports[`ConfigProvider components Menu configProvider 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
class="config-menu config-menu-sub config-menu-inline"
|
||||
class="config-menu config-menu-sub config-menu-inline"
|
||||
id="bamboo$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@@ -8068,7 +8071,7 @@ exports[`ConfigProvider components Menu normal 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="bamboo$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@@ -8121,7 +8124,7 @@ exports[`ConfigProvider components Menu prefixCls 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
class="prefix-Menu prefix-Menu-sub prefix-Menu-inline"
|
||||
class="prefix-Menu prefix-Menu-sub prefix-Menu-inline"
|
||||
id="bamboo$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@@ -8427,6 +8430,60 @@ exports[`ConfigProvider components Modal prefixCls 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components PageHeader configProvider 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="config-page-header"
|
||||
>
|
||||
<div
|
||||
class="config-page-header-heading"
|
||||
>
|
||||
<span
|
||||
class="config-page-header-heading-title"
|
||||
>
|
||||
pageHeader
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components PageHeader normal 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-page-header ant-page-header-ghost"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
pageHeader
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components PageHeader prefixCls 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="prefix-PageHeader prefix-PageHeader-ghost"
|
||||
>
|
||||
<div
|
||||
class="prefix-PageHeader-heading"
|
||||
>
|
||||
<span
|
||||
class="prefix-PageHeader-heading-title"
|
||||
>
|
||||
pageHeader
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfigProvider components Pagination configProvider 1`] = `
|
||||
<div>
|
||||
<ul
|
||||
@@ -11085,7 +11142,7 @@ exports[`ConfigProvider components Slider configProvider 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="config-slider-track"
|
||||
style="left:0%;width:0%"
|
||||
style="left:0%;right:auto;width:0%"
|
||||
/>
|
||||
<div
|
||||
class="config-slider-step"
|
||||
@@ -11097,7 +11154,7 @@ exports[`ConfigProvider components Slider configProvider 1`] = `
|
||||
aria-valuenow="0"
|
||||
class="config-slider-handle config-tooltip-open"
|
||||
role="slider"
|
||||
style="left:0%"
|
||||
style="left:0%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div>
|
||||
@@ -11134,7 +11191,7 @@ exports[`ConfigProvider components Slider normal 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-track"
|
||||
style="left:0%;width:0%"
|
||||
style="left:0%;right:auto;width:0%"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-step"
|
||||
@@ -11146,7 +11203,7 @@ exports[`ConfigProvider components Slider normal 1`] = `
|
||||
aria-valuenow="0"
|
||||
class="ant-slider-handle ant-tooltip-open"
|
||||
role="slider"
|
||||
style="left:0%"
|
||||
style="left:0%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div>
|
||||
@@ -11183,7 +11240,7 @@ exports[`ConfigProvider components Slider prefixCls 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="prefix-Slider-track"
|
||||
style="left:0%;width:0%"
|
||||
style="left:0%;right:auto;width:0%"
|
||||
/>
|
||||
<div
|
||||
class="prefix-Slider-step"
|
||||
@@ -11195,7 +11252,7 @@ exports[`ConfigProvider components Slider prefixCls 1`] = `
|
||||
aria-valuenow="0"
|
||||
class="prefix-Slider-handle prefix-Slider-tooltip-open"
|
||||
role="slider"
|
||||
style="left:0%"
|
||||
style="left:0%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div>
|
||||
@@ -17309,7 +17366,7 @@ exports[`ConfigProvider components Upload configProvider 1`] = `
|
||||
class="config-upload-list config-upload-list-text"
|
||||
>
|
||||
<div
|
||||
class="config-upload-list-item config-upload-list-item-done"
|
||||
class="config-upload-list-item config-upload-list-item-done config-upload-list-item-list-type-text"
|
||||
>
|
||||
<div
|
||||
class="config-upload-list-item-info"
|
||||
@@ -17335,34 +17392,67 @@ exports[`ConfigProvider components Upload configProvider 1`] = `
|
||||
</svg>
|
||||
</i>
|
||||
<span
|
||||
class="config-upload-list-item-name"
|
||||
class="config-upload-list-item-name config-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
xxx.png
|
||||
<span
|
||||
class="config-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
class="anticon anticon-close"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
@@ -17379,7 +17469,7 @@ exports[`ConfigProvider components Upload normal 1`] = `
|
||||
class="ant-upload-list ant-upload-list-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item ant-upload-list-item-done"
|
||||
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item-info"
|
||||
@@ -17405,34 +17495,67 @@ exports[`ConfigProvider components Upload normal 1`] = `
|
||||
</svg>
|
||||
</i>
|
||||
<span
|
||||
class="ant-upload-list-item-name"
|
||||
class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
xxx.png
|
||||
<span
|
||||
class="ant-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
class="anticon anticon-close"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
@@ -17449,7 +17572,7 @@ exports[`ConfigProvider components Upload prefixCls 1`] = `
|
||||
class="ant-upload-list ant-upload-list-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item ant-upload-list-item-done"
|
||||
class="ant-upload-list-item ant-upload-list-item-done ant-upload-list-item-list-type-text"
|
||||
>
|
||||
<div
|
||||
class="ant-upload-list-item-info"
|
||||
@@ -17475,34 +17598,67 @@ exports[`ConfigProvider components Upload prefixCls 1`] = `
|
||||
</svg>
|
||||
</i>
|
||||
<span
|
||||
class="ant-upload-list-item-name"
|
||||
class="ant-upload-list-item-name ant-upload-list-item-name-icon-count-2"
|
||||
title="xxx.png"
|
||||
>
|
||||
xxx.png
|
||||
<span
|
||||
class="ant-upload-list-item-card-actions "
|
||||
>
|
||||
<a
|
||||
title="Download file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: download"
|
||||
class="anticon anticon-download"
|
||||
tabindex="-1"
|
||||
title="Download file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="download"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
<a
|
||||
title="Remove file"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: delete"
|
||||
class="anticon anticon-delete"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="delete"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
class="anticon anticon-close"
|
||||
tabindex="-1"
|
||||
title="Remove file"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
@@ -31,6 +31,7 @@ import Mention from '../../mention';
|
||||
import Menu from '../../menu';
|
||||
import Modal from '../../modal';
|
||||
import Pagination from '../../pagination';
|
||||
import PageHeader from '../../page-header';
|
||||
import Popconfirm from '../../popconfirm';
|
||||
import Popover from '../../popover';
|
||||
import Progress from '../../progress';
|
||||
@@ -74,7 +75,11 @@ describe('ConfigProvider', () => {
|
||||
// configProvider
|
||||
it('configProvider', () => {
|
||||
expect(
|
||||
render(<ConfigProvider prefixCls="config">{renderComponent({})}</ConfigProvider>),
|
||||
render(
|
||||
<ConfigProvider pageHeader={{ ghost: false }} prefixCls="config">
|
||||
{renderComponent({})}
|
||||
</ConfigProvider>,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -368,6 +373,13 @@ describe('ConfigProvider', () => {
|
||||
</div>
|
||||
));
|
||||
|
||||
// PageHeader
|
||||
testPair('PageHeader', props => (
|
||||
<div>
|
||||
<PageHeader title="pageHeader" {...props} />
|
||||
</div>
|
||||
));
|
||||
|
||||
// Popconfirm
|
||||
testPair('Popconfirm', props => (
|
||||
<div>
|
||||
|
||||
@@ -2,10 +2,16 @@ import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import ConfigProvider from '..';
|
||||
import LocaleProvider from '../../locale-provider';
|
||||
import locale from '../../locale/zh_CN';
|
||||
import zhCN from '../../locale/zh_CN';
|
||||
import enUS from '../../locale/en_US';
|
||||
import TimePicker from '../../time-picker';
|
||||
import Modal from '../../modal';
|
||||
|
||||
describe('ConfigProvider.Locale', () => {
|
||||
function $$(className) {
|
||||
return document.body.querySelectorAll(className);
|
||||
}
|
||||
|
||||
it('not throw', () => {
|
||||
if (process.env.REACT === '15') {
|
||||
return;
|
||||
@@ -19,14 +25,54 @@ describe('ConfigProvider.Locale', () => {
|
||||
);
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/18731
|
||||
it('should not reset locale for Modal', () => {
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
showButton: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
showButton: true,
|
||||
});
|
||||
}
|
||||
|
||||
openConfirm = () => {
|
||||
Modal.confirm({
|
||||
title: 'title',
|
||||
content: 'Some descriptions',
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ConfigProvider locale={zhCN}>
|
||||
{this.state.showButton ? (
|
||||
<ConfigProvider locale={enUS}>
|
||||
<button type="button" onClick={this.openConfirm}>
|
||||
open
|
||||
</button>
|
||||
</ConfigProvider>
|
||||
) : null}
|
||||
</ConfigProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const wrapper = mount(<App />);
|
||||
wrapper.find('button').simulate('click');
|
||||
expect($$('.ant-btn-primary')[0].textContent).toBe('OK');
|
||||
});
|
||||
|
||||
describe('support legacy LocaleProvider', () => {
|
||||
function testLocale(wrapper) {
|
||||
expect(wrapper.find('input').props().placeholder).toBe(locale.TimePicker.placeholder);
|
||||
expect(wrapper.find('input').props().placeholder).toBe(zhCN.TimePicker.placeholder);
|
||||
}
|
||||
|
||||
it('LocaleProvider', () => {
|
||||
const wrapper = mount(
|
||||
<LocaleProvider locale={locale}>
|
||||
<LocaleProvider locale={zhCN}>
|
||||
<TimePicker />
|
||||
</LocaleProvider>,
|
||||
);
|
||||
@@ -36,7 +82,7 @@ describe('ConfigProvider.Locale', () => {
|
||||
|
||||
it('LocaleProvider > ConfigProvider', () => {
|
||||
const wrapper = mount(
|
||||
<LocaleProvider locale={locale}>
|
||||
<LocaleProvider locale={zhCN}>
|
||||
<ConfigProvider>
|
||||
<TimePicker />
|
||||
</ConfigProvider>
|
||||
@@ -48,7 +94,7 @@ describe('ConfigProvider.Locale', () => {
|
||||
|
||||
it('ConfigProvider > ConfigProvider', () => {
|
||||
const wrapper = mount(
|
||||
<ConfigProvider locale={locale}>
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<ConfigProvider>
|
||||
<TimePicker />
|
||||
</ConfigProvider>
|
||||
|
||||
33
components/config-provider/context.ts
Normal file
33
components/config-provider/context.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import createReactContext from '@ant-design/create-react-context';
|
||||
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
|
||||
import { Locale } from '../locale-provider';
|
||||
|
||||
export interface CSPConfig {
|
||||
nonce?: string;
|
||||
}
|
||||
|
||||
export interface ConfigConsumerProps {
|
||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||
rootPrefixCls?: string;
|
||||
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => string;
|
||||
renderEmpty: RenderEmptyHandler;
|
||||
csp?: CSPConfig;
|
||||
autoInsertSpaceInButton?: boolean;
|
||||
locale?: Locale;
|
||||
pageHeader?: {
|
||||
ghost: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export const ConfigContext = createReactContext<ConfigConsumerProps>({
|
||||
// We provide a default function for Context without provider
|
||||
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
|
||||
if (customizePrefixCls) return customizePrefixCls;
|
||||
|
||||
return `ant-${suffixCls}`;
|
||||
},
|
||||
|
||||
renderEmpty: defaultRenderEmpty,
|
||||
});
|
||||
|
||||
export const ConfigConsumer = ConfigContext.Consumer;
|
||||
@@ -43,3 +43,4 @@ Some component use dynamic style to support wave effect. You can config `csp` pr
|
||||
| getPopupContainer | to set the container of the popup element. The default is to create a `div` element in `body`. | Function(triggerNode) | `() => document.body` | 3.11.0 |
|
||||
| locale | language package setting, you can find the packages in [antd/es/locale](http://unpkg.com/antd/es/locale/) | object | 3.21.0 |
|
||||
| prefixCls | set prefix class | string | ant | 3.12.0 |
|
||||
| pageHeader | Unify the ghost of pageHeader ,Ref [pageHeader](<(/components/page-header)> | { ghost:boolean } | 'true' | 3.24.0 |
|
||||
|
||||
@@ -2,27 +2,13 @@
|
||||
// SFC has specified a displayName, but not worked.
|
||||
/* eslint-disable react/display-name */
|
||||
import * as React from 'react';
|
||||
import createReactContext from '@ant-design/create-react-context';
|
||||
|
||||
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
|
||||
import { RenderEmptyHandler } from './renderEmpty';
|
||||
import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import { ConfigConsumer, ConfigContext, CSPConfig, ConfigConsumerProps } from './context';
|
||||
|
||||
export { RenderEmptyHandler };
|
||||
|
||||
export interface CSPConfig {
|
||||
nonce?: string;
|
||||
}
|
||||
|
||||
export interface ConfigConsumerProps {
|
||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||
rootPrefixCls?: string;
|
||||
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => string;
|
||||
renderEmpty: RenderEmptyHandler;
|
||||
csp?: CSPConfig;
|
||||
autoInsertSpaceInButton?: boolean;
|
||||
locale?: Locale;
|
||||
}
|
||||
export { RenderEmptyHandler, ConfigConsumer, CSPConfig, ConfigConsumerProps };
|
||||
|
||||
export const configConsumerProps = [
|
||||
'getPopupContainer',
|
||||
@@ -32,6 +18,7 @@ export const configConsumerProps = [
|
||||
'csp',
|
||||
'autoInsertSpaceInButton',
|
||||
'locale',
|
||||
'pageHeader',
|
||||
];
|
||||
|
||||
export interface ConfigProviderProps {
|
||||
@@ -42,21 +29,11 @@ export interface ConfigProviderProps {
|
||||
csp?: CSPConfig;
|
||||
autoInsertSpaceInButton?: boolean;
|
||||
locale?: Locale;
|
||||
pageHeader?: {
|
||||
ghost: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const ConfigContext = createReactContext<ConfigConsumerProps>({
|
||||
// We provide a default function for Context without provider
|
||||
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
|
||||
if (customizePrefixCls) return customizePrefixCls;
|
||||
|
||||
return `ant-${suffixCls}`;
|
||||
},
|
||||
|
||||
renderEmpty: defaultRenderEmpty,
|
||||
});
|
||||
|
||||
export const ConfigConsumer = ConfigContext.Consumer;
|
||||
|
||||
class ConfigProvider extends React.Component<ConfigProviderProps> {
|
||||
getPrefixCls = (suffixCls: string, customizePrefixCls?: string) => {
|
||||
const { prefixCls = 'ant' } = this.props;
|
||||
@@ -74,6 +51,7 @@ class ConfigProvider extends React.Component<ConfigProviderProps> {
|
||||
csp,
|
||||
autoInsertSpaceInButton,
|
||||
locale,
|
||||
pageHeader,
|
||||
} = this.props;
|
||||
|
||||
const config: ConfigConsumerProps = {
|
||||
@@ -86,10 +64,15 @@ class ConfigProvider extends React.Component<ConfigProviderProps> {
|
||||
if (getPopupContainer) {
|
||||
config.getPopupContainer = getPopupContainer;
|
||||
}
|
||||
|
||||
if (renderEmpty) {
|
||||
config.renderEmpty = renderEmpty;
|
||||
}
|
||||
|
||||
if (pageHeader) {
|
||||
config.pageHeader = pageHeader;
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={config}>
|
||||
<LocaleProvider locale={locale || legacyLocale} _ANT_MARK__={ANT_MARK}>
|
||||
|
||||
@@ -44,3 +44,4 @@ return (
|
||||
| getPopupContainer | 弹出框(Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | Function(triggerNode) | () => document.body | 3.11.0 |
|
||||
| locale | 语言包配置,语言包可到 [antd/es/locale](http://unpkg.com/antd/es/locale/) 目录下寻找 | object | - | 3.21.0 |
|
||||
| prefixCls | 设置统一样式前缀 | string | ant | 3.12.0 |
|
||||
| pageHeader | 统一设置 pageHeader 的 ghost,参考 [pageHeader](<(/components/page-header)>) | { ghost: boolean } | 'true' | 3.24.0 |
|
||||
|
||||
@@ -47,7 +47,7 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
|
||||
const value = props.value || props.defaultValue;
|
||||
if (value && !interopDefault(moment).isMoment(value)) {
|
||||
throw new Error(
|
||||
'The value/defaultValue of DatePicker or MonthPicker must be ' +
|
||||
'The value/defaultValue of WeekPicker must be ' +
|
||||
'a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -390,14 +390,22 @@ describe('RangePicker', () => {
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/17135
|
||||
it('the end time should be less than the start time', () => {
|
||||
const wrapper = mount(
|
||||
<RangePicker defaultValue={[moment(), moment()]} />,
|
||||
);
|
||||
const wrapper = mount(<RangePicker defaultValue={[moment(), moment()]} />);
|
||||
wrapper.find('.ant-calendar-picker-input').simulate('click');
|
||||
const firstInput = wrapper.find('.ant-calendar-input').first();
|
||||
const secondInput = wrapper.find('.ant-calendar-input').last();
|
||||
firstInput.simulate('change', { target: { value: moment().add(1, 'day').format('YYYY-MM-DD')}});
|
||||
expect(firstInput.getDOMNode().value).toBe(moment().add(1, 'day').format('YYYY-MM-DD'));
|
||||
firstInput.simulate('change', {
|
||||
target: {
|
||||
value: moment()
|
||||
.add(1, 'day')
|
||||
.format('YYYY-MM-DD'),
|
||||
},
|
||||
});
|
||||
expect(firstInput.getDOMNode().value).toBe(
|
||||
moment()
|
||||
.add(1, 'day')
|
||||
.format('YYYY-MM-DD'),
|
||||
);
|
||||
expect(secondInput.getDOMNode().value).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { mount, render } from 'enzyme';
|
||||
import moment from 'moment';
|
||||
import { setMockDate, resetMockDate } from '../../../tests/utils';
|
||||
import DatePicker from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
@@ -71,4 +72,16 @@ describe('WeekPicker', () => {
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should support allowClear', () => {
|
||||
const onChange = jest.fn();
|
||||
const wrapper = mount(
|
||||
<WeekPicker defaultValue={moment()} onChange={onChange} />,
|
||||
);
|
||||
wrapper
|
||||
.find('.ant-calendar-picker-clear')
|
||||
.hostNodes()
|
||||
.simulate('click');
|
||||
expect(onChange).toHaveBeenCalledWith(null, '');
|
||||
});
|
||||
});
|
||||
|
||||
52
components/date-picker/__tests__/invalid.test.js
Normal file
52
components/date-picker/__tests__/invalid.test.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import DatePicker from '..';
|
||||
|
||||
const { MonthPicker, WeekPicker, RangePicker } = DatePicker;
|
||||
|
||||
describe('invalid value or defaultValue', () => {
|
||||
beforeAll(() => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error.mockRestore();
|
||||
});
|
||||
|
||||
it('DatePicker should throw error when value or defaultValue is not moment object', () => {
|
||||
expect(() => {
|
||||
mount(<DatePicker value={{}} />);
|
||||
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||
expect(() => {
|
||||
mount(<DatePicker defaultValue={{}} />);
|
||||
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value')
|
||||
});
|
||||
|
||||
it('WeekPicker should throw error when value or defaultValue is not moment object', () => {
|
||||
expect(() => {
|
||||
mount(<WeekPicker value={{}} />);
|
||||
}).toThrow('The value/defaultValue of WeekPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||
expect(() => {
|
||||
mount(<WeekPicker defaultValue={{}} />);
|
||||
}).toThrow('The value/defaultValue of WeekPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||
});
|
||||
|
||||
it('RangePicker should throw error when value or defaultValue is not moment object', () => {
|
||||
expect(() => {
|
||||
mount(<RangePicker value={[{}, {}]} />);
|
||||
}).toThrow('The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||
expect(() => {
|
||||
mount(<RangePicker defaultValue={[{}, {}]} />);
|
||||
}).toThrow('The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, see: https://u.ant.design/date-picker-value')
|
||||
});
|
||||
|
||||
it('MonthPicker should throw error when value or defaultValue is not moment object', () => {
|
||||
expect(() => {
|
||||
mount(<MonthPicker value={{}} />);
|
||||
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||
expect(() => {
|
||||
mount(<MonthPicker defaultValue={{}} />);
|
||||
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value')
|
||||
});
|
||||
});
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
.@{calendar-prefix-cls}-decade-panel-header {
|
||||
.calendarPanelHeader(~'@{calendar-prefix-cls}-decade-panel');
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-decade-panel-body {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
.@{calendar-prefix-cls}-month-panel-header {
|
||||
.calendarPanelHeader(~'@{calendar-prefix-cls}-month-panel');
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-month-panel-body {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
.@{calendar-prefix-cls}-year-panel-header {
|
||||
.calendarPanelHeader(~'@{calendar-prefix-cls}-year-panel');
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-year-panel-body {
|
||||
|
||||
@@ -904,7 +904,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
|
||||
</th>
|
||||
<th
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
colspan="5"
|
||||
colspan="3"
|
||||
>
|
||||
Usage Time
|
||||
</th>
|
||||
@@ -920,7 +920,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="5"
|
||||
colspan="3"
|
||||
>
|
||||
2019-04-24 18:00:00
|
||||
</td>
|
||||
|
||||
@@ -39,7 +39,7 @@ exports[`Descriptions Descriptions support colon 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={false}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -116,7 +116,7 @@ exports[`Descriptions Descriptions support style 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -183,7 +183,7 @@ exports[`Descriptions Descriptions.Item support className 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -241,7 +241,7 @@ exports[`Descriptions column is number 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -274,7 +274,7 @@ exports[`Descriptions column is number 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="1"
|
||||
key="label-1"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -307,7 +307,7 @@ exports[`Descriptions column is number 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="2"
|
||||
key="label-2"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -346,7 +346,7 @@ exports[`Descriptions column is number 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -414,7 +414,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="vertical"
|
||||
type="label"
|
||||
>
|
||||
@@ -446,7 +446,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="content-0"
|
||||
layout="vertical"
|
||||
type="content"
|
||||
>
|
||||
@@ -478,7 +478,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="vertical"
|
||||
type="label"
|
||||
>
|
||||
@@ -510,7 +510,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="content-0"
|
||||
layout="vertical"
|
||||
type="content"
|
||||
>
|
||||
@@ -542,7 +542,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="vertical"
|
||||
type="label"
|
||||
>
|
||||
@@ -574,7 +574,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="content-0"
|
||||
layout="vertical"
|
||||
type="content"
|
||||
>
|
||||
@@ -607,7 +607,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="vertical"
|
||||
type="label"
|
||||
>
|
||||
@@ -640,7 +640,7 @@ exports[`Descriptions vertical layout 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="content-0"
|
||||
layout="vertical"
|
||||
type="content"
|
||||
>
|
||||
@@ -701,7 +701,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -739,7 +739,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -777,7 +777,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
@@ -816,7 +816,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
|
||||
</DescriptionsItem>
|
||||
}
|
||||
colon={true}
|
||||
key="0"
|
||||
key="label-0"
|
||||
layout="horizontal"
|
||||
type="label"
|
||||
>
|
||||
|
||||
@@ -183,6 +183,6 @@ describe('Descriptions', () => {
|
||||
</Descriptions>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('Col').key()).toBe('bamboo');
|
||||
expect(wrapper.find('Col').key()).toBe('label-bamboo');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ class Demo extends React.Component {
|
||||
</Radio.Group>
|
||||
<br />
|
||||
<br />
|
||||
<Descriptions bordered title="Custom Size" border size={this.state.size}>
|
||||
<Descriptions bordered title="Custom Size" size={this.state.size}>
|
||||
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
|
||||
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
|
||||
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
|
||||
@@ -61,7 +61,7 @@ class Demo extends React.Component {
|
||||
</Descriptions>
|
||||
<br />
|
||||
<br />
|
||||
<Descriptions title="Custom Size" border size={this.state.size}>
|
||||
<Descriptions title="Custom Size" size={this.state.size}>
|
||||
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
|
||||
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
|
||||
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
|
||||
|
||||
@@ -22,7 +22,7 @@ ReactDOM.render(
|
||||
<Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item>
|
||||
<Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item>
|
||||
<Descriptions.Item label="Order time">2018-04-24 18:00:00</Descriptions.Item>
|
||||
<Descriptions.Item label="Usage Time" span={3}>
|
||||
<Descriptions.Item label="Usage Time" span={2}>
|
||||
2019-04-24 18:00:00
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Status" span={3}>
|
||||
|
||||
@@ -105,7 +105,7 @@ const renderRow = (
|
||||
bordered={bordered}
|
||||
colon={colon}
|
||||
type={type}
|
||||
key={colItem.key || idx}
|
||||
key={`${type}-${colItem.key || idx}`}
|
||||
layout={layout}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -32,4 +32,4 @@ cols: 1
|
||||
| label | 内容的描述 | ReactNode | - | 3.19.0 |
|
||||
| span | 包含列的数量 | number | 1 | 3.19.0 |
|
||||
|
||||
> span Description.Item 的数量。 span={2} 会占用两个 DescriptionItem 的宽度。
|
||||
> span 是 Description.Item 的数量。 span={2} 会占用两个 DescriptionItem 的宽度。
|
||||
|
||||
@@ -59,4 +59,23 @@ describe('Drawer', () => {
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('style/drawerStyle/headerStyle/bodyStyle should work', () => {
|
||||
const style = {
|
||||
backgroundColor: '#08c',
|
||||
};
|
||||
const wrapper = render(
|
||||
<Drawer
|
||||
visible
|
||||
style={style}
|
||||
drawerStyle={style}
|
||||
headerStyle={style}
|
||||
bodyStyle={style}
|
||||
getContainer={false}
|
||||
>
|
||||
Here is content of Drawer
|
||||
</Drawer>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -347,3 +347,68 @@ exports[`Drawer render top drawer 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Drawer style/drawerStyle/headerStyle/bodyStyle should work 1`] = `
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-drawer ant-drawer-right"
|
||||
style="background-color:#08c"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%;background-color:#08c"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-header-no-title"
|
||||
style="background-color:#08c"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-drawer-close"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: close"
|
||||
class="anticon anticon-close"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="close"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-drawer-body"
|
||||
style="background-color:#08c"
|
||||
>
|
||||
Here is content of Drawer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -104,7 +104,7 @@ class App extends React.Component {
|
||||
<p style={pStyle}>Personal</p>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<DescriptionItem title="Full Name" content="Lily" />{' '}
|
||||
<DescriptionItem title="Full Name" content="Lily" />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<DescriptionItem title="Account" content="AntDesign@example.com" />
|
||||
|
||||
@@ -25,12 +25,14 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
||||
| mask | Whether to show mask or not. | Boolean | true | 3.7.0 |
|
||||
| maskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | boolean | true | 3.7.0 |
|
||||
| maskStyle | Style for Drawer's mask element. | object | {} | 3.7.0 |
|
||||
| style | Style of drawer wrapper | object | - | 3.7.0 |
|
||||
| bodyStyle | Style of floating layer, typically used for adjusting its position. | object | - | 3.12.0 |
|
||||
| style | Style of wrapper element which **contains mask** compare to `drawerStyle` | object | - | 3.7.0 |
|
||||
| drawerStyle | Style of the popup layer element | object | - | 3.24.0 |
|
||||
| headerStyle | Style of the drawer header part | object | - | 3.24.0 |
|
||||
| bodyStyle | Style of the drawer content part | object | - | 3.12.0 |
|
||||
| title | The title for Drawer. | string\|ReactNode | - | 3.7.0 |
|
||||
| visible | Whether the Drawer dialog is visible or not. | boolean | false | 3.7.0 |
|
||||
| width | Width of the Drawer dialog. | string\|number | 256 | 3.7.0 |
|
||||
| height | placement is `top` or `bottom`, height of the Drawer dialog. | string\|number | - | 3.9.0 |
|
||||
| height | placement is `top` or `bottom`, height of the Drawer dialog. | string\|number | 256 | 3.9.0 |
|
||||
| className | The class name of the container of the Drawer dialog. | string | - | 3.8.0 |
|
||||
| zIndex | The `z-index` of the Drawer. | Number | 1000 | 3.7.0 |
|
||||
| placement | The placement of the Drawer. | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | 3.7.0 |
|
||||
|
||||
@@ -26,6 +26,9 @@ export interface DrawerProps {
|
||||
mask?: boolean;
|
||||
maskStyle?: React.CSSProperties;
|
||||
style?: React.CSSProperties;
|
||||
/** wrapper dom node style of header and body */
|
||||
drawerStyle?: React.CSSProperties;
|
||||
headerStyle?: React.CSSProperties;
|
||||
bodyStyle?: React.CSSProperties;
|
||||
title?: React.ReactNode;
|
||||
visible?: boolean;
|
||||
@@ -142,14 +145,14 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
|
||||
};
|
||||
|
||||
renderHeader() {
|
||||
const { title, prefixCls, closable } = this.props;
|
||||
const { title, prefixCls, closable, headerStyle } = this.props;
|
||||
if (!title && !closable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const headerClassName = title ? `${prefixCls}-header` : `${prefixCls}-header-no-title`;
|
||||
return (
|
||||
<div className={headerClassName}>
|
||||
<div className={headerClassName} style={headerStyle}>
|
||||
{title && <div className={`${prefixCls}-title`}>{title}</div>}
|
||||
{closable && this.renderCloseIcon()}
|
||||
</div>
|
||||
@@ -170,7 +173,7 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
|
||||
|
||||
// render drawer body dom
|
||||
renderBody = () => {
|
||||
const { bodyStyle, placement, prefixCls, visible } = this.props;
|
||||
const { bodyStyle, drawerStyle, placement, prefixCls, visible } = this.props;
|
||||
if (this.destroyClose && !visible) {
|
||||
return null;
|
||||
}
|
||||
@@ -195,7 +198,10 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
|
||||
return (
|
||||
<div
|
||||
className={`${prefixCls}-wrapper-body`}
|
||||
style={containerStyle}
|
||||
style={{
|
||||
...containerStyle,
|
||||
...drawerStyle,
|
||||
}}
|
||||
onTransitionEnd={this.onDestroyTransitionEnd}
|
||||
>
|
||||
{this.renderHeader()}
|
||||
@@ -240,6 +246,8 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
|
||||
'style',
|
||||
'closable',
|
||||
'destroyOnClose',
|
||||
'drawerStyle',
|
||||
'headerStyle',
|
||||
'bodyStyle',
|
||||
'title',
|
||||
'push',
|
||||
@@ -249,6 +257,7 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
|
||||
'getPrefixCls',
|
||||
'renderEmpty',
|
||||
'csp',
|
||||
'pageHeader',
|
||||
'autoInsertSpaceInButton',
|
||||
])}
|
||||
{...offsetStyle}
|
||||
|
||||
@@ -24,8 +24,10 @@ title: Drawer
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | 3.7.0 |
|
||||
| mask | 是否展示遮罩 | Boolean | true | 3.7.0 |
|
||||
| maskStyle | 遮罩样式 | object | {} | 3.7.0 |
|
||||
| style | 可用于设置 Drawer 最外层容器的样式 | object | - | 3.7.0 |
|
||||
| bodyStyle | 可用于设置 Drawer 的样式,调整浮层位置等 | object | - | 3.12.0 |
|
||||
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | object | - | 3.7.0 |
|
||||
| drawerStyle | 用于设置 Drawer 弹出层的样式 | object | - | 3.24.0 |
|
||||
| headerStyle | 用于设置 Drawer 头部的样式 | object | - | 3.24.0 |
|
||||
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | object | - | 3.12.0 |
|
||||
| title | 标题 | string \| ReactNode | - | 3.7.0 |
|
||||
| visible | Drawer 是否可见 | boolean | - | 3.7.0 |
|
||||
| width | 宽度 | string \| number | 256 | 3.7.0 |
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
z-index: @zindex-modal;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
transition: transform @animation-duration-slow @ease-base-out, height 0s ease @animation-duration-slow, width 0s ease @animation-duration-slow;
|
||||
transition: transform @animation-duration-slow @ease-base-out,
|
||||
height 0s ease @animation-duration-slow, width 0s ease @animation-duration-slow;
|
||||
> * {
|
||||
transition: transform @animation-duration-slow @ease-base-out,
|
||||
box-shadow @animation-duration-slow @ease-base-out;
|
||||
@@ -62,6 +63,11 @@
|
||||
.@{drawer-prefix-cls}-content-wrapper {
|
||||
box-shadow: @shadow-1-left;
|
||||
}
|
||||
// https://github.com/ant-design/ant-design/issues/18607, Avoid edge alignment bug.
|
||||
&.no-mask {
|
||||
right: 1px;
|
||||
transform: translateX(1px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +111,10 @@
|
||||
.@{drawer-prefix-cls}-content-wrapper {
|
||||
box-shadow: @shadow-1-up;
|
||||
}
|
||||
&.no-mask {
|
||||
bottom: 1px;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,34 @@ exports[`renders ./components/dropdown/demo/item.md correctly 1`] = `
|
||||
</a>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/dropdown/demo/menu-full.md correctly 1`] = `
|
||||
<a
|
||||
class="ant-dropdown-link ant-dropdown-trigger"
|
||||
href="#"
|
||||
>
|
||||
Hover to check menu style
|
||||
<i
|
||||
aria-label="icon: down"
|
||||
class="anticon anticon-down"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/dropdown/demo/overlay-visible.md correctly 1`] = `
|
||||
<a
|
||||
class="ant-dropdown-link ant-dropdown-trigger"
|
||||
|
||||
83
components/dropdown/demo/menu-full.md
Normal file
83
components/dropdown/demo/menu-full.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
order: 100
|
||||
title:
|
||||
zh-CN: Menu 完整样式
|
||||
en-US: Menu full styles
|
||||
debug: true
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
此演示需要注意查看 Dropdown 内 Menu 的样式是否正常。[#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
|
||||
## en-US
|
||||
|
||||
This demo was created for debugging Menu styles inside Dropdown. [#19150](https://github.com/ant-design/ant-design/pull/19150)
|
||||
|
||||
```jsx
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
|
||||
const menu = (
|
||||
<Menu selectedKeys={['1']} openKeys={['sub1']}>
|
||||
<SubMenu
|
||||
key="sub1"
|
||||
title={
|
||||
<span>
|
||||
<Icon type="mail" />
|
||||
<span>Navigation One</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Menu.ItemGroup key="g1" title="Item 1">
|
||||
<Menu.Item key="1">Option 1</Menu.Item>
|
||||
<Menu.Item key="2">Option 2</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
<Menu.ItemGroup key="g2" title="Item 2">
|
||||
<Menu.Item key="3">Option 3</Menu.Item>
|
||||
<Menu.Item key="4">Option 4</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</SubMenu>
|
||||
<SubMenu
|
||||
key="sub2"
|
||||
title={
|
||||
<span>
|
||||
<Icon type="appstore" />
|
||||
<span>Navigation Two</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Menu.Item key="5">Option 5</Menu.Item>
|
||||
<Menu.Item key="6">Option 6</Menu.Item>
|
||||
<SubMenu key="sub3" title="Submenu">
|
||||
<Menu.Item key="7">Option 7</Menu.Item>
|
||||
<Menu.Item key="8">Option 8</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu
|
||||
key="sub4"
|
||||
title={
|
||||
<span>
|
||||
<Icon type="setting" />
|
||||
<span>Navigation Three</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Menu.Item key="9">Option 9</Menu.Item>
|
||||
<Menu.Item key="10">Option 10</Menu.Item>
|
||||
<Menu.Item key="11">Option 11</Menu.Item>
|
||||
<Menu.Item key="12">Option 12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<Dropdown overlay={menu}>
|
||||
<a className="ant-dropdown-link" href="#">
|
||||
Hover to check menu style <Icon type="down" />
|
||||
</a>
|
||||
</Dropdown>,
|
||||
mountNode,
|
||||
);
|
||||
```
|
||||
@@ -72,6 +72,16 @@
|
||||
> .@{dropdown-prefix-cls}-menu {
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-right: 0.3em;
|
||||
margin-left: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
&-item,
|
||||
@@ -87,9 +97,10 @@
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
> .anticon:first-child {
|
||||
> span > .anticon:first-child {
|
||||
min-width: 12px;
|
||||
margin-right: 8px;
|
||||
font-size: @font-size-sm;
|
||||
}
|
||||
|
||||
> a {
|
||||
|
||||
@@ -2385,14 +2385,14 @@ exports[`renders ./components/form/demo/style-check-debug.md correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemin="-9007199254740991"
|
||||
class="ant-input-number-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemin="-9007199254740991"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
min="-9007199254740991"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value=""
|
||||
/>
|
||||
@@ -3244,13 +3244,12 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemax="10"
|
||||
aria-valuemin="1"
|
||||
aria-valuenow="3"
|
||||
class="ant-input-number-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemax="10"
|
||||
aria-valuemin="1"
|
||||
aria-valuenow="3"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
data-__field="[object Object]"
|
||||
@@ -3258,6 +3257,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
id="validate_other_input-number"
|
||||
max="10"
|
||||
min="1"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value="3"
|
||||
/>
|
||||
@@ -3343,7 +3343,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-track"
|
||||
style="left:0%;width:0%"
|
||||
style="left:0%;right:auto;width:0%"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-step"
|
||||
@@ -3380,7 +3380,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
aria-valuenow="0"
|
||||
class="ant-slider-handle"
|
||||
role="slider"
|
||||
style="left:0%"
|
||||
style="left:0%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
@@ -3388,37 +3388,37 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="left:0%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:0%"
|
||||
>
|
||||
A
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:20%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:20%"
|
||||
>
|
||||
B
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:40%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:40%"
|
||||
>
|
||||
C
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:60%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:60%"
|
||||
>
|
||||
D
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:80%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:80%"
|
||||
>
|
||||
E
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:100%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:100%"
|
||||
>
|
||||
F
|
||||
</span>
|
||||
@@ -4151,20 +4151,16 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-form-item-children"
|
||||
>
|
||||
<div
|
||||
class="dropbox"
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-upload ant-upload-drag"
|
||||
/>
|
||||
<div
|
||||
class="ant-upload-list ant-upload-list-text"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-upload ant-upload-drag"
|
||||
/>
|
||||
<div
|
||||
class="ant-upload-list ant-upload-list-text"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -5100,14 +5096,14 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemin="-9007199254740991"
|
||||
class="ant-input-number-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemin="-9007199254740991"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
min="-9007199254740991"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value=""
|
||||
/>
|
||||
@@ -5231,17 +5227,17 @@ exports[`renders ./components/form/demo/without-form-create.md correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
aria-valuemax="12"
|
||||
aria-valuemin="8"
|
||||
aria-valuenow="11"
|
||||
class="ant-input-number-input-wrap"
|
||||
role="spinbutton"
|
||||
>
|
||||
<input
|
||||
aria-valuemax="12"
|
||||
aria-valuemin="8"
|
||||
aria-valuenow="11"
|
||||
autocomplete="off"
|
||||
class="ant-input-number-input"
|
||||
max="12"
|
||||
min="8"
|
||||
role="spinbutton"
|
||||
step="1"
|
||||
value="11"
|
||||
/>
|
||||
|
||||
@@ -39,6 +39,7 @@ describe('Form', () => {
|
||||
pattern: /^$/,
|
||||
message: (
|
||||
<span>
|
||||
{/* eslint-disable-next-line react/jsx-curly-brace-presence */}
|
||||
Account does not exist,{' '}
|
||||
<a rel="noopener noreferrer" href="https://www.alipay.com/" target="_blank">
|
||||
Forgot account?
|
||||
|
||||
@@ -178,20 +178,18 @@ class Demo extends React.Component {
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Dragger">
|
||||
<div className="dropbox">
|
||||
{getFieldDecorator('dragger', {
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: this.normFile,
|
||||
})(
|
||||
<Upload.Dragger name="files" action="/upload.do">
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload</p>
|
||||
<p className="ant-upload-hint">Support for a single or bulk upload.</p>
|
||||
</Upload.Dragger>,
|
||||
)}
|
||||
</div>
|
||||
{getFieldDecorator('dragger', {
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: this.normFile,
|
||||
})(
|
||||
<Upload.Dragger name="files" action="/upload.do">
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload</p>
|
||||
<p className="ant-upload-hint">Support for a single or bulk upload.</p>
|
||||
</Upload.Dragger>,
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item wrapperCol={{ span: 12, offset: 6 }}>
|
||||
@@ -208,10 +206,3 @@ const WrappedDemo = Form.create({ name: 'validate_other' })(Demo);
|
||||
|
||||
ReactDOM.render(<WrappedDemo />, mountNode);
|
||||
```
|
||||
|
||||
```css
|
||||
#components-form-demo-validate-other .dropbox {
|
||||
height: 180px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,7 +43,7 @@ A form consists of one or more form fields whose type includes input, textarea,
|
||||
| layout | Define form layout | 'horizontal'\|'vertical'\|'inline' | 'horizontal' | |
|
||||
| onSubmit | Defines a function will be called if form data validation is successful. | Function(e:Event) | | |
|
||||
| wrapperCol | (Added in 3.14.0. Previous version can only set on FormItem.) The layout for input controls, same as `labelCol` | [object](https://ant.design/components/grid/#Col) | | 3.14.0 |
|
||||
| colon | change default props colon value of Form.Item | boolean | true | 3.15.0 |
|
||||
| colon | change default props colon value of Form.Item (only effective when prop layout is horizontal) | boolean | true | 3.15.0 |
|
||||
|
||||
### Form.create(options)
|
||||
|
||||
@@ -177,7 +177,7 @@ If you use `react@<15.3.0`, then, you can't use `getFieldDecorator` in stateless
|
||||
| id | The unique identifier is required. support [nested fields format](https://github.com/react-component/form/pull/48). | string | | |
|
||||
| options.getValueFromEvent | Specify how to get value from event or other onChange arguments | function(..args) | [reference](https://github.com/react-component/form#option-object) | |
|
||||
| options.getValueProps | Get the component props according to field value. | function(value): any | [reference](https://github.com/react-component/form#option-object) | 3.9.0 |
|
||||
| options.initialValue | You can specify initial value, type, optional value of children node. (Note: Because `Form` will test equality with `===` internally, we recommend to use variable as `initialValue`, instead of literal) | | n/a | |
|
||||
| options.initialValue | You can specify initial value, type, optional value of children node. ([Note: Because `Form` will test equality with `===` internally, we recommend to use variable as `initialValue`, instead of literal](https://github.com/ant-design/ant-design/issues/4093)) | | n/a | |
|
||||
| options.normalize | Normalize value to form component, [a select-all example](https://codepen.io/afc163/pen/JJVXzG?editors=001) | function(value, prevValue, allValues): any | - | |
|
||||
| options.preserve | Keep the field even if field removed | boolean | - | 3.12.0 |
|
||||
| options.rules | Includes validation rules. Please refer to "Validation Rules" part for details. | object\[] | n/a | |
|
||||
|
||||
@@ -46,7 +46,7 @@ title: Form
|
||||
| layout | 表单布局 | 'horizontal'\|'vertical'\|'inline' | 'horizontal' | |
|
||||
| onSubmit | 数据验证成功后回调事件 | Function(e:Event) | | |
|
||||
| wrapperCol | (3.14.0 新增,之前的版本只能设置到 FormItem 上。)需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | [object](https://ant.design/components/grid-cn/#Col) | | 3.14.0 |
|
||||
| colon | 配置 Form.Item 的 colon 的默认值 | boolean | true | 3.15.0 |
|
||||
| colon | 配置 Form.Item 的 colon 的默认值 (只有在属性 layout 为 horizontal 时有效) | boolean | true | 3.15.0 |
|
||||
|
||||
### Form.create(options)
|
||||
|
||||
@@ -179,7 +179,7 @@ validateFields(['field1', 'field2'], options, (errors, values) => {
|
||||
| --- | --- | --- | --- | --- |
|
||||
| id | 必填输入控件唯一标志。支持嵌套式的[写法](https://github.com/react-component/form/pull/48)。 | string | | |
|
||||
| options.getValueFromEvent | 可以把 onChange 的参数(如 event)转化为控件的值 | function(..args) | [reference](https://github.com/react-component/form#option-object) | |
|
||||
| options.initialValue | 子节点的初始值,类型、可选值均由子节点决定(注意:由于内部校验时使用 `===` 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量)) | | | |
|
||||
| options.initialValue | 子节点的初始值,类型、可选值均由子节点决定([注意:由于内部校验时使用 `===` 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量](https://github.com/ant-design/ant-design/issues/4093)) | | | |
|
||||
| options.normalize | 转换默认的 value 给控件,[一个选择全部的例子](https://codepen.io/afc163/pen/JJVXzG?editors=001) | function(value, prevValue, allValues): any | - | |
|
||||
| options.preserve | 即便字段不再使用,也保留该字段的值 | boolean | - | 3.12.0 |
|
||||
| options.rules | 校验规则,参考下方文档 | object\[] | | |
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
position: relative;
|
||||
top: -0.5px;
|
||||
margin: 0 8px 0 2px;
|
||||
margin: 0 @form-item-label-colon-margin-right 0 @form-item-label-colon-margin-left;
|
||||
}
|
||||
|
||||
&.@{form-prefix-cls}-item-no-colon::after {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import createContext, { Context } from '@ant-design/create-react-context';
|
||||
|
||||
export interface RowContextState {
|
||||
gutter?: number;
|
||||
gutter?: [number, number];
|
||||
}
|
||||
|
||||
const RowContext: Context<RowContextState> = createContext({});
|
||||
|
||||
@@ -414,6 +414,51 @@ exports[`renders ./components/grid/demo/gutter.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-top:-10px;margin-bottom:-10px"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6 gutter-row"
|
||||
style="padding-top:10px;padding-bottom:10px"
|
||||
>
|
||||
<div
|
||||
class="gutter-box"
|
||||
>
|
||||
col-6
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6 gutter-row"
|
||||
style="padding-top:10px;padding-bottom:10px"
|
||||
>
|
||||
<div
|
||||
class="gutter-box"
|
||||
>
|
||||
col-6
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6 gutter-row"
|
||||
style="padding-top:10px;padding-bottom:10px"
|
||||
>
|
||||
<div
|
||||
class="gutter-box"
|
||||
>
|
||||
col-6
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6 gutter-row"
|
||||
style="padding-top:10px;padding-bottom:10px"
|
||||
>
|
||||
<div
|
||||
class="gutter-box"
|
||||
>
|
||||
col-6
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -467,7 +512,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
<span
|
||||
style="margin-right:6px"
|
||||
>
|
||||
Gutter (px):
|
||||
Horizontal Gutter (px):
|
||||
</span>
|
||||
<div
|
||||
style="width:50%"
|
||||
@@ -480,7 +525,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-track"
|
||||
style="left:0%;width:20%"
|
||||
style="left:0%;right:auto;width:20%"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-step"
|
||||
@@ -517,7 +562,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
aria-valuenow="1"
|
||||
class="ant-slider-handle"
|
||||
role="slider"
|
||||
style="left:20%"
|
||||
style="left:20%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
@@ -525,37 +570,135 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="left:0%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:0%"
|
||||
>
|
||||
8
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="left:20%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:20%"
|
||||
>
|
||||
16
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:40%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:40%"
|
||||
>
|
||||
24
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:60%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:60%"
|
||||
>
|
||||
32
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:80%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:80%"
|
||||
>
|
||||
40
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:100%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:100%"
|
||||
>
|
||||
48
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
style="margin-right:6px"
|
||||
>
|
||||
Vertical Gutter (px):
|
||||
</span>
|
||||
<div
|
||||
style="width:50%"
|
||||
>
|
||||
<div
|
||||
class="ant-slider ant-slider-with-marks"
|
||||
>
|
||||
<div
|
||||
class="ant-slider-rail"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-track"
|
||||
style="left:0%;right:auto;width:20%"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-step"
|
||||
>
|
||||
<span
|
||||
class="ant-slider-dot ant-slider-dot-active"
|
||||
style="left:0%"
|
||||
/>
|
||||
<span
|
||||
class="ant-slider-dot ant-slider-dot-active"
|
||||
style="left:20%"
|
||||
/>
|
||||
<span
|
||||
class="ant-slider-dot"
|
||||
style="left:40%"
|
||||
/>
|
||||
<span
|
||||
class="ant-slider-dot"
|
||||
style="left:60%"
|
||||
/>
|
||||
<span
|
||||
class="ant-slider-dot"
|
||||
style="left:80%"
|
||||
/>
|
||||
<span
|
||||
class="ant-slider-dot"
|
||||
style="left:100%"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-valuemax="5"
|
||||
aria-valuemin="0"
|
||||
aria-valuenow="1"
|
||||
class="ant-slider-handle"
|
||||
role="slider"
|
||||
style="left:20%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-mark"
|
||||
>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:0%"
|
||||
>
|
||||
8
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:20%"
|
||||
>
|
||||
16
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:40%"
|
||||
>
|
||||
24
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:60%"
|
||||
>
|
||||
32
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:80%"
|
||||
>
|
||||
40
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:100%"
|
||||
>
|
||||
48
|
||||
</span>
|
||||
@@ -578,7 +721,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-track"
|
||||
style="left:0%;width:40%"
|
||||
style="left:0%;right:auto;width:40%"
|
||||
/>
|
||||
<div
|
||||
class="ant-slider-step"
|
||||
@@ -615,7 +758,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
aria-valuenow="2"
|
||||
class="ant-slider-handle"
|
||||
role="slider"
|
||||
style="left:40%"
|
||||
style="left:40%;right:auto;transform:translateX(-50%)"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
@@ -623,37 +766,37 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="left:0%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:0%"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="left:20%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:20%"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text ant-slider-mark-text-active"
|
||||
style="left:40%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:40%"
|
||||
>
|
||||
4
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:60%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:60%"
|
||||
>
|
||||
6
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:80%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:80%"
|
||||
>
|
||||
8
|
||||
</span>
|
||||
<span
|
||||
class="ant-slider-mark-text"
|
||||
style="left:100%;transform:translateX(-50%);-ms-transform:translateX(-50%)"
|
||||
style="transform:translateX(-50%);-ms-transform:translateX(-50%);left:100%"
|
||||
>
|
||||
12
|
||||
</span>
|
||||
@@ -663,11 +806,11 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-8px;margin-right:-8px"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-8px;margin-bottom:-8px"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
@@ -675,7 +818,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
@@ -683,7 +826,7 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
@@ -691,7 +834,44 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-8px;margin-right:-8px;margin-top:-8px;margin-bottom:-8px"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-col-6"
|
||||
style="padding-left:8px;padding-right:8px;padding-top:8px;padding-bottom:8px"
|
||||
>
|
||||
<div>
|
||||
Column
|
||||
@@ -699,7 +879,15 @@ exports[`renders ./components/grid/demo/playground.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<Row gutter={16}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
</Row>
|
||||
</pre>
|
||||
<pre>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
<Col span={6} />
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('Grid', () => {
|
||||
|
||||
it('when typeof getGutter is object', () => {
|
||||
const wrapper = mount(<Row gutter={{ xs: 8, sm: 16, md: 24 }} />);
|
||||
expect(wrapper.instance().getGutter()).toBe(8);
|
||||
expect(wrapper.instance().getGutter()).toEqual([8, 0]);
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
@@ -75,8 +75,18 @@ describe('Grid', () => {
|
||||
.update()
|
||||
.find('div')
|
||||
.prop('style'),
|
||||
).toEqual(undefined);
|
||||
).toEqual({});
|
||||
wrapper.unmount();
|
||||
expect(enquire.unregister).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should work currect when gutter is array', () => {
|
||||
const wrapper = mount(<Row gutter={[16, 20]} />);
|
||||
expect(wrapper.find('div').prop('style')).toEqual({
|
||||
marginLeft: -8,
|
||||
marginRight: -8,
|
||||
marginTop: -10,
|
||||
marginBottom: -10,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -102,13 +102,25 @@ export default class Col extends React.Component<ColProps, {}> {
|
||||
<RowContext.Consumer>
|
||||
{({ gutter }) => {
|
||||
let { style } = others;
|
||||
if (gutter! > 0) {
|
||||
|
||||
if (gutter) {
|
||||
style = {
|
||||
paddingLeft: gutter! / 2,
|
||||
paddingRight: gutter! / 2,
|
||||
...(gutter[0]! > 0
|
||||
? {
|
||||
paddingLeft: gutter[0]! / 2,
|
||||
paddingRight: gutter[0]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...(gutter[1]! > 0
|
||||
? {
|
||||
paddingTop: gutter[1]! / 2,
|
||||
paddingBottom: gutter[1]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...style,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...others} style={style} className={classes}>
|
||||
{children}
|
||||
|
||||
@@ -11,12 +11,16 @@ title:
|
||||
|
||||
如果要支持响应式,可以写成 `{ xs: 8, sm: 16, md: 24, lg: 32 }`。
|
||||
|
||||
如果需要垂直间距,可以写成数组形式 `[水平间距, 垂直间距]` `[16, { xs: 8, sm: 16, md: 24, lg: 32 }]`。
|
||||
|
||||
## en-US
|
||||
|
||||
You can use the `gutter` property of `Row` as grid spacing, we recommend set it to `(16 + 8n) px`. (`n` stands for natural number.)
|
||||
|
||||
You can set it to a object like `{ xs: 8, sm: 16, md: 24, lg: 32 }` for responsive design.
|
||||
|
||||
You can use a array to set vertical spacing, `[horizontal, vertical]` `[16, { xs: 8, sm: 16, md: 24, lg: 32 }]`.
|
||||
|
||||
```jsx
|
||||
import { Row, Col } from 'antd';
|
||||
|
||||
@@ -36,6 +40,20 @@ ReactDOM.render(
|
||||
<div className="gutter-box">col-6</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={[{ xs: 8, sm: 16, md: 24, lg: 32 }, 20]}>
|
||||
<Col className="gutter-row" span={6}>
|
||||
<div className="gutter-box">col-6</div>
|
||||
</Col>
|
||||
<Col className="gutter-row" span={6}>
|
||||
<div className="gutter-box">col-6</div>
|
||||
</Col>
|
||||
<Col className="gutter-row" span={6}>
|
||||
<div className="gutter-box">col-6</div>
|
||||
</Col>
|
||||
<Col className="gutter-row" span={6}>
|
||||
<div className="gutter-box">col-6</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>,
|
||||
mountNode,
|
||||
);
|
||||
|
||||
@@ -19,17 +19,23 @@ import { Row, Col, Slider } from 'antd';
|
||||
class App extends React.Component {
|
||||
gutters = {};
|
||||
|
||||
vgutters = {};
|
||||
|
||||
colCounts = {};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
gutterKey: 1,
|
||||
vgutterKey: 1,
|
||||
colCountKey: 2,
|
||||
};
|
||||
[8, 16, 24, 32, 40, 48].forEach((value, i) => {
|
||||
this.gutters[i] = value;
|
||||
});
|
||||
[8, 16, 24, 32, 40, 48].forEach((value, i) => {
|
||||
this.vgutters[i] = value;
|
||||
});
|
||||
[2, 3, 4, 6, 8, 12].forEach((value, i) => {
|
||||
this.colCounts[i] = value;
|
||||
});
|
||||
@@ -39,12 +45,16 @@ class App extends React.Component {
|
||||
this.setState({ gutterKey });
|
||||
};
|
||||
|
||||
onVGutterChange = vgutterKey => {
|
||||
this.setState({ vgutterKey });
|
||||
};
|
||||
|
||||
onColCountChange = colCountKey => {
|
||||
this.setState({ colCountKey });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { gutterKey, colCountKey } = this.state;
|
||||
const { gutterKey, vgutterKey, colCountKey } = this.state;
|
||||
const cols = [];
|
||||
const colCount = this.colCounts[colCountKey];
|
||||
let colCode = '';
|
||||
@@ -59,7 +69,7 @@ class App extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<span style={{ marginRight: 6 }}>Gutter (px): </span>
|
||||
<span style={{ marginRight: 6 }}>Horizontal Gutter (px): </span>
|
||||
<div style={{ width: '50%' }}>
|
||||
<Slider
|
||||
min={0}
|
||||
@@ -70,6 +80,17 @@ class App extends React.Component {
|
||||
step={null}
|
||||
/>
|
||||
</div>
|
||||
<span style={{ marginRight: 6 }}>Vertical Gutter (px): </span>
|
||||
<div style={{ width: '50%' }}>
|
||||
<Slider
|
||||
min={0}
|
||||
max={Object.keys(this.vgutters).length - 1}
|
||||
value={vgutterKey}
|
||||
onChange={this.onVGutterChange}
|
||||
marks={this.vgutters}
|
||||
step={null}
|
||||
/>
|
||||
</div>
|
||||
<span style={{ marginRight: 6 }}>Column Count:</span>
|
||||
<div style={{ width: '50%' }}>
|
||||
<Slider
|
||||
@@ -82,8 +103,10 @@ class App extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Row gutter={this.gutters[gutterKey]}>{cols}</Row>
|
||||
<pre>{`<Row gutter={${this.gutters[gutterKey]}}>\n${colCode}</Row>`}</pre>
|
||||
<Row gutter={[this.gutters[gutterKey], this.vgutters[vgutterKey]]}>{cols}</Row>
|
||||
<Row gutter={[this.gutters[gutterKey], this.vgutters[vgutterKey]]}>{cols}</Row>
|
||||
<pre>{`<Row gutter={[${this.gutters[gutterKey]}, ${this.vgutters[vgutterKey]}]}>\n${colCode}</Row>`}</pre>
|
||||
<pre>{`<Row gutter={[${this.gutters[gutterKey]}, ${this.vgutters[vgutterKey]}]}>\n${colCode}</Row>`}</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ If the Ant Design grid layout component does not meet your needs, you can use th
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| align | the vertical alignment of the flex layout: `top` `middle` `bottom` | string | `top` | |
|
||||
| gutter | spacing between grids, could be a number or a object like `{ xs: 8, sm: 16, md: 24}` | number/object | 0 | |
|
||||
| gutter | spacing between grids, could be a number or a object like `{ xs: 8, sm: 16, md: 24}`, or you can use array to make horizontal and vertical spacing work at the same time `[horizontal, vertical]` | number/object/array | 0 | |
|
||||
| justify | horizontal arrangement of the flex layout: `start` `end` `center` `space-around` `space-between` | string | `start` | |
|
||||
| type | layout mode, optional `flex`, [browser support](http://caniuse.com/#search=flex) | string | | |
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用
|
||||
| 成员 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| align | flex 布局下的垂直对齐方式:`top` `middle` `bottom` | string | `top` | |
|
||||
| gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number/object | 0 | |
|
||||
| gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 `{ xs: 8, sm: 16, md: 24}`,或者使用数组形式同时设置`[水平间距, 垂直间距]` | number/object/array | 0 | |
|
||||
| justify | flex 布局下的水平排列方式:`start` `end` `center` `space-around` `space-between` | string | `start` | |
|
||||
| type | 布局模式,可选 `flex`,[现代浏览器](http://caniuse.com/#search=flex) 下有效 | string | | |
|
||||
|
||||
|
||||
@@ -10,10 +10,12 @@ import ResponsiveObserve, {
|
||||
responsiveArray,
|
||||
} from '../_util/responsiveObserve';
|
||||
|
||||
const RowAligns = tuple('top', 'middle', 'bottom');
|
||||
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
|
||||
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
|
||||
|
||||
export type Gutter = number | Partial<Record<Breakpoint, number>>;
|
||||
export interface RowProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
gutter?: number | Partial<Record<Breakpoint, number>>;
|
||||
gutter?: Gutter | [Gutter, Gutter];
|
||||
type?: 'flex';
|
||||
align?: (typeof RowAligns)[number];
|
||||
justify?: (typeof RowJustify)[number];
|
||||
@@ -35,7 +37,7 @@ export default class Row extends React.Component<RowProps, RowState> {
|
||||
justify: PropTypes.oneOf(RowJustify),
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
gutter: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
gutter: PropTypes.oneOfType([PropTypes.object, PropTypes.number, PropTypes.array]),
|
||||
prefixCls: PropTypes.string,
|
||||
};
|
||||
|
||||
@@ -47,7 +49,11 @@ export default class Row extends React.Component<RowProps, RowState> {
|
||||
|
||||
componentDidMount() {
|
||||
this.token = ResponsiveObserve.subscribe(screens => {
|
||||
if (typeof this.props.gutter === 'object') {
|
||||
const { gutter } = this.props;
|
||||
if (
|
||||
typeof gutter === 'object' ||
|
||||
(Array.isArray(gutter) && (typeof gutter[0] === 'object' || typeof gutter[1] === 'object'))
|
||||
) {
|
||||
this.setState({ screens });
|
||||
}
|
||||
});
|
||||
@@ -57,17 +63,24 @@ export default class Row extends React.Component<RowProps, RowState> {
|
||||
ResponsiveObserve.unsubscribe(this.token);
|
||||
}
|
||||
|
||||
getGutter(): number | undefined {
|
||||
const { gutter } = this.props;
|
||||
if (typeof gutter === 'object') {
|
||||
for (let i = 0; i < responsiveArray.length; i++) {
|
||||
const breakpoint: Breakpoint = responsiveArray[i];
|
||||
if (this.state.screens[breakpoint] && gutter[breakpoint] !== undefined) {
|
||||
return gutter[breakpoint];
|
||||
getGutter(): [number, number] {
|
||||
const gutter: [number, number] = [0, 0];
|
||||
const { gutter: gutter_setting } = this.props;
|
||||
|
||||
(Array.isArray(gutter_setting) ? gutter_setting : [gutter_setting, 0]).forEach((g, index) => {
|
||||
if (typeof g === 'object') {
|
||||
for (let i = 0; i < responsiveArray.length; i++) {
|
||||
const breakpoint: Breakpoint = responsiveArray[i];
|
||||
if (this.state.screens[breakpoint] && g[breakpoint] !== undefined) {
|
||||
gutter[index] = g[breakpoint] as number;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gutter[index] = g as number;
|
||||
}
|
||||
}
|
||||
return gutter as number;
|
||||
});
|
||||
|
||||
return gutter;
|
||||
}
|
||||
|
||||
renderRow = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
@@ -92,16 +105,24 @@ export default class Row extends React.Component<RowProps, RowState> {
|
||||
},
|
||||
className,
|
||||
);
|
||||
const rowStyle =
|
||||
gutter! > 0
|
||||
const rowStyle = {
|
||||
...(gutter[0]! > 0
|
||||
? {
|
||||
marginLeft: gutter! / -2,
|
||||
marginRight: gutter! / -2,
|
||||
...style,
|
||||
marginLeft: gutter[0]! / -2,
|
||||
marginRight: gutter[0]! / -2,
|
||||
}
|
||||
: style;
|
||||
: {}),
|
||||
...(gutter[1]! > 0
|
||||
? {
|
||||
marginTop: gutter[1]! / -2,
|
||||
marginBottom: gutter[1]! / -2,
|
||||
}
|
||||
: {}),
|
||||
...style,
|
||||
};
|
||||
const otherProps = { ...others };
|
||||
delete otherProps.gutter;
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={{ gutter }}>
|
||||
<div {...otherProps} className={classes} style={rowStyle}>
|
||||
|
||||
@@ -12,11 +12,26 @@ exports[`Icon \`component\` prop can access to svg defs if has children 1`] = `
|
||||
height="1em"
|
||||
width="1em"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="gradient"
|
||||
>
|
||||
<stop
|
||||
offset="20%"
|
||||
stop-color="#39F"
|
||||
/>
|
||||
<stop
|
||||
offset="90%"
|
||||
stop-color="#F3F"
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<title>
|
||||
Cool Home
|
||||
</title>
|
||||
<path
|
||||
d="'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'"
|
||||
fill="scriptUrl(#gradient)"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
@@ -298,13 +313,14 @@ exports[`Icon should support svg react component 1`] = `
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
>
|
||||
<title>
|
||||
Cool Home
|
||||
Custom Svg
|
||||
</title>
|
||||
<path
|
||||
d="'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'"
|
||||
d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
|
||||
@@ -162,7 +162,7 @@ describe('Icon', () => {
|
||||
it('should support svg react component', () => {
|
||||
const SvgComponent = props => (
|
||||
<svg viewBox="0 0 24 24" {...props}>
|
||||
<title>Cool Home</title>
|
||||
<title>Custom Svg</title>
|
||||
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -26,6 +26,8 @@ ReactDOM.render(<IconDisplay />, mountNode);
|
||||
| component | The component used for the root node. This will override the **`type`** property. | ComponentType<CustomIconComponentProps\> | - | 3.9.0 |
|
||||
| twoToneColor | Only supports the two-tone icon. Specify the primary color. | string (hex color) | - | 3.9.0 |
|
||||
|
||||
> Note: icon rendering priority of the Icon component is component > children > type. When props is passed, higher priority item will works, and lower priority item would be invalid.
|
||||
|
||||
### SVG icons
|
||||
|
||||
We introduced SVG icons in `3.9.0` version replacing font icons which brings benefits below:
|
||||
@@ -121,7 +123,7 @@ ReactDOM.render(<Icon component={MessageSvg} />, mountNode);
|
||||
|
||||
The following properties are available for the component:
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| Property | Description | Type | Readonly | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| width | The width of the `svg` element | string \| number | '1em' | 3.10.0 |
|
||||
| height | The height of the `svg` element | string \| number | '1em' | 3.10.0 |
|
||||
|
||||
@@ -128,8 +128,6 @@ const Icon: IconComponent<IconProps> = props => {
|
||||
[`anticon-spin`]: !!spin || type === 'loading',
|
||||
});
|
||||
|
||||
let innerNode: React.ReactNode;
|
||||
|
||||
const svgStyle = rotate
|
||||
? {
|
||||
msTransform: `rotate(${rotate}deg)`,
|
||||
@@ -148,52 +146,54 @@ const Icon: IconComponent<IconProps> = props => {
|
||||
delete innerSvgProps.viewBox;
|
||||
}
|
||||
|
||||
// component > children > type
|
||||
if (Component) {
|
||||
innerNode = <Component {...innerSvgProps}>{children}</Component>;
|
||||
}
|
||||
const renderInnerNode = () => {
|
||||
// component > children > type
|
||||
if (Component) {
|
||||
return <Component {...innerSvgProps}>{children}</Component>;
|
||||
}
|
||||
|
||||
if (children) {
|
||||
warning(
|
||||
Boolean(viewBox) ||
|
||||
(React.Children.count(children) === 1 &&
|
||||
React.isValidElement(children) &&
|
||||
React.Children.only(children).type === 'use'),
|
||||
'Icon',
|
||||
'Make sure that you provide correct `viewBox`' +
|
||||
' prop (default `0 0 1024 1024`) to the icon.',
|
||||
);
|
||||
innerNode = (
|
||||
<svg {...innerSvgProps} viewBox={viewBox}>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
let computedType = type;
|
||||
if (theme) {
|
||||
const themeInName = getThemeFromTypeName(type);
|
||||
if (children) {
|
||||
warning(
|
||||
!themeInName || theme === themeInName,
|
||||
Boolean(viewBox) ||
|
||||
(React.Children.count(children) === 1 &&
|
||||
React.isValidElement(children) &&
|
||||
React.Children.only(children).type === 'use'),
|
||||
'Icon',
|
||||
`The icon name '${type}' already specify a theme '${themeInName}',` +
|
||||
` the 'theme' prop '${theme}' will be ignored.`,
|
||||
'Make sure that you provide correct `viewBox`' +
|
||||
' prop (default `0 0 1024 1024`) to the icon.',
|
||||
);
|
||||
return (
|
||||
<svg {...innerSvgProps} viewBox={viewBox}>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
computedType = withThemeSuffix(
|
||||
removeTypeTheme(alias(computedType)),
|
||||
dangerousTheme || theme || defaultTheme,
|
||||
);
|
||||
innerNode = (
|
||||
<ReactIcon
|
||||
className={svgClassString}
|
||||
type={computedType}
|
||||
primaryColor={twoToneColor}
|
||||
style={svgStyle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
let computedType = type;
|
||||
if (theme) {
|
||||
const themeInName = getThemeFromTypeName(type);
|
||||
warning(
|
||||
!themeInName || theme === themeInName,
|
||||
'Icon',
|
||||
`The icon name '${type}' already specify a theme '${themeInName}',` +
|
||||
` the 'theme' prop '${theme}' will be ignored.`,
|
||||
);
|
||||
}
|
||||
computedType = withThemeSuffix(
|
||||
removeTypeTheme(alias(computedType)),
|
||||
dangerousTheme || theme || defaultTheme,
|
||||
);
|
||||
return (
|
||||
<ReactIcon
|
||||
className={svgClassString}
|
||||
type={computedType}
|
||||
primaryColor={twoToneColor}
|
||||
style={svgStyle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let iconTabIndex = tabIndex;
|
||||
if (iconTabIndex === undefined && onClick) {
|
||||
@@ -210,7 +210,7 @@ const Icon: IconComponent<IconProps> = props => {
|
||||
onClick={onClick}
|
||||
className={classString}
|
||||
>
|
||||
{innerNode}
|
||||
{renderInnerNode()}
|
||||
</i>
|
||||
)}
|
||||
</LocaleReceiver>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user