mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 10:59:19 +08:00
Compare commits
719 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0234375d9 | ||
|
|
7baa81ced1 | ||
|
|
80686df38e | ||
|
|
a827553604 | ||
|
|
7d082c1dc5 | ||
|
|
0ecb6ad45f | ||
|
|
9cdae0053d | ||
|
|
f64ddef4ff | ||
|
|
705f568f6c | ||
|
|
6b38d2b6e9 | ||
|
|
f688e732f5 | ||
|
|
7a98f6236f | ||
|
|
b49c0ac35c | ||
|
|
202230356a | ||
|
|
028dcea5ec | ||
|
|
3af6464db4 | ||
|
|
404677a68a | ||
|
|
9b2ca4b1aa | ||
|
|
f005974c56 | ||
|
|
754d330bae | ||
|
|
7521348606 | ||
|
|
f54d73617f | ||
|
|
7d58589cf5 | ||
|
|
3cb0e2e7e1 | ||
|
|
b84bf85526 | ||
|
|
e71b68dd1d | ||
|
|
df1c56ee18 | ||
|
|
fffde2d836 | ||
|
|
a9797ac4ce | ||
|
|
336c3613e8 | ||
|
|
e496fffbb5 | ||
|
|
d825e27667 | ||
|
|
8f1fd4d68b | ||
|
|
0eac8aa1c6 | ||
|
|
cd5761ffe6 | ||
|
|
d6e429cd70 | ||
|
|
3e0df406f1 | ||
|
|
d1568c959c | ||
|
|
d7dcb56dfc | ||
|
|
45559c84be | ||
|
|
1db952b575 | ||
|
|
68d4e34a10 | ||
|
|
1a0301bc08 | ||
|
|
107949be01 | ||
|
|
1ec68e7ba6 | ||
|
|
31a0654ef9 | ||
|
|
e13c6d87fa | ||
|
|
913daa2668 | ||
|
|
a3271d9a03 | ||
|
|
eae1a0044c | ||
|
|
b5f13b49ae | ||
|
|
edd592cb9d | ||
|
|
f780759f91 | ||
|
|
68c1da8045 | ||
|
|
e8d3be5dc2 | ||
|
|
accf92336d | ||
|
|
687b058dc0 | ||
|
|
18723a37ee | ||
|
|
7a50248477 | ||
|
|
36831c7f1d | ||
|
|
d7475f47cb | ||
|
|
9bbfe534b2 | ||
|
|
43628b9848 | ||
|
|
a1ada4f4f6 | ||
|
|
b77adb352f | ||
|
|
0589b23693 | ||
|
|
b84cb4ba45 | ||
|
|
61ab3a4a9e | ||
|
|
dd3f7f2da1 | ||
|
|
6d0b488d7f | ||
|
|
0402e0333d | ||
|
|
3eb91cef47 | ||
|
|
1b2a9550d9 | ||
|
|
e27061ea5b | ||
|
|
693d3cec9c | ||
|
|
28f8e03ecf | ||
|
|
4d74d5c22e | ||
|
|
bf27b99947 | ||
|
|
9bcb8b8eec | ||
|
|
427be4cff5 | ||
|
|
28d13e2539 | ||
|
|
2e45074fab | ||
|
|
ed44dfaeb8 | ||
|
|
12b6fceb37 | ||
|
|
4d7ce541cd | ||
|
|
3162dd3b51 | ||
|
|
b541fad312 | ||
|
|
cc5fb7bf2d | ||
|
|
58b018a06e | ||
|
|
99cf727c01 | ||
|
|
b02aa7bddc | ||
|
|
2713870460 | ||
|
|
4bd06af002 | ||
|
|
e022eac717 | ||
|
|
6b3daed369 | ||
|
|
6ed30ada37 | ||
|
|
6836487e18 | ||
|
|
44b529b0d5 | ||
|
|
cd1af8b903 | ||
|
|
9d7fec97c1 | ||
|
|
49e036e9a6 | ||
|
|
e73349e7d3 | ||
|
|
342f7c4a63 | ||
|
|
ed41ca0dbb | ||
|
|
86ebc32250 | ||
|
|
c9b2efc9e8 | ||
|
|
6172f773ac | ||
|
|
5f35a69858 | ||
|
|
329da9e55f | ||
|
|
b8e6a5fb9e | ||
|
|
1f0ee08574 | ||
|
|
ebcf7b43e8 | ||
|
|
aa81956603 | ||
|
|
cc43bd3f12 | ||
|
|
4dc310c331 | ||
|
|
554d27e725 | ||
|
|
59cb320a7b | ||
|
|
81472aaf3b | ||
|
|
6bb368083b | ||
|
|
76b4afb752 | ||
|
|
85416ce577 | ||
|
|
45815d1148 | ||
|
|
bbbdb9911d | ||
|
|
1e47a6c518 | ||
|
|
f26261de31 | ||
|
|
90736521bc | ||
|
|
bba0fd4220 | ||
|
|
5e48badbb7 | ||
|
|
2299ad41aa | ||
|
|
e613dc9050 | ||
|
|
d2dc88c470 | ||
|
|
25f51cdd64 | ||
|
|
ee93047bad | ||
|
|
1b9b92f67d | ||
|
|
c6f4b38471 | ||
|
|
0b31c256e3 | ||
|
|
7fa0599695 | ||
|
|
01f4b4e713 | ||
|
|
5458c6a40c | ||
|
|
071149cfbb | ||
|
|
6f37caefe7 | ||
|
|
51b6e4904a | ||
|
|
dfc6ca49a6 | ||
|
|
f7a8d02f09 | ||
|
|
378084376a | ||
|
|
57dcc78989 | ||
|
|
b44a0c93cd | ||
|
|
4aeb811b72 | ||
|
|
b8b591c593 | ||
|
|
5871691e77 | ||
|
|
927853a1f1 | ||
|
|
05200385ee | ||
|
|
b531de3fee | ||
|
|
179528af50 | ||
|
|
16b69312db | ||
|
|
44c52561e5 | ||
|
|
eeb642e2bd | ||
|
|
be1cbd4eae | ||
|
|
91fc059c9d | ||
|
|
250eed0fc9 | ||
|
|
2aedc275d4 | ||
|
|
c08e486e1a | ||
|
|
0710f826f3 | ||
|
|
49a49adae3 | ||
|
|
721a5621c8 | ||
|
|
bd9fba9f45 | ||
|
|
04a00e6e14 | ||
|
|
6f312a716b | ||
|
|
57d80c0c70 | ||
|
|
58e742d987 | ||
|
|
c8a49c45fc | ||
|
|
72741db902 | ||
|
|
086ecec310 | ||
|
|
143a7232e3 | ||
|
|
ea338eb637 | ||
|
|
095acc4839 | ||
|
|
b2810f2fa9 | ||
|
|
daf596a898 | ||
|
|
c0b7bdb9f3 | ||
|
|
bf70d30a60 | ||
|
|
9a49a5c775 | ||
|
|
cd7a04a069 | ||
|
|
539cca5cc4 | ||
|
|
7604495ab4 | ||
|
|
61968b91cf | ||
|
|
892de0c609 | ||
|
|
1662710acd | ||
|
|
eb5d423ca7 | ||
|
|
8e907cebde | ||
|
|
0865824b61 | ||
|
|
e6940ad721 | ||
|
|
6707824611 | ||
|
|
da14cba722 | ||
|
|
c23e24b0f0 | ||
|
|
1c7eb398d7 | ||
|
|
dada590d2d | ||
|
|
a64337748a | ||
|
|
b2b60fdac4 | ||
|
|
b90b04f3fe | ||
|
|
8b2d7e3982 | ||
|
|
4a81e5584f | ||
|
|
58fa1885fd | ||
|
|
462d7aa876 | ||
|
|
605c685503 | ||
|
|
d2b59938b8 | ||
|
|
541b9d146a | ||
|
|
b8a08f6e1d | ||
|
|
c0a42480ae | ||
|
|
c27d4deb72 | ||
|
|
db560bb10d | ||
|
|
de340a83ba | ||
|
|
ebce4b3599 | ||
|
|
f4dc69f5f0 | ||
|
|
50f85480d1 | ||
|
|
669b3c5b2e | ||
|
|
ecaf3a0883 | ||
|
|
2fe2e35a52 | ||
|
|
9fd3588ac4 | ||
|
|
93fcbdf334 | ||
|
|
ad21c9837f | ||
|
|
bebc57978d | ||
|
|
05c702838d | ||
|
|
bcbdd12ce1 | ||
|
|
f14d57dc14 | ||
|
|
dc322a6a9c | ||
|
|
e7042ae541 | ||
|
|
084b444252 | ||
|
|
b075aa606e | ||
|
|
b6c6ee8f3e | ||
|
|
d8f6c3bd8c | ||
|
|
446977b916 | ||
|
|
7ef169dbdc | ||
|
|
3646d0f9bc | ||
|
|
a8e5690805 | ||
|
|
499b81f79d | ||
|
|
1e1baf01f6 | ||
|
|
8292808292 | ||
|
|
c4c3e74149 | ||
|
|
9b5a16ba93 | ||
|
|
b647078baa | ||
|
|
5cb5a2ae9d | ||
|
|
8260e32d1d | ||
|
|
08d27b92ee | ||
|
|
6db2630e90 | ||
|
|
81fc6d613c | ||
|
|
9dd858cc62 | ||
|
|
00ff041d16 | ||
|
|
5e9daf08d7 | ||
|
|
2cf3414d69 | ||
|
|
ac7212eba8 | ||
|
|
54b1715d2a | ||
|
|
6837aedf69 | ||
|
|
cbaf54415e | ||
|
|
03e4411589 | ||
|
|
45135e4ec8 | ||
|
|
e8b4892a70 | ||
|
|
814f9a72de | ||
|
|
3406c6598a | ||
|
|
7049a45d8e | ||
|
|
c37b1e8425 | ||
|
|
8e6e91b932 | ||
|
|
09fd564af9 | ||
|
|
5e0dd59e5c | ||
|
|
2de0a6a522 | ||
|
|
cd67045e11 | ||
|
|
09aaa56243 | ||
|
|
ca44eb9cd9 | ||
|
|
5d38ccf892 | ||
|
|
4a97ed4bf0 | ||
|
|
409959e7c7 | ||
|
|
bf4ad93f2c | ||
|
|
076c40ac31 | ||
|
|
816226ff92 | ||
|
|
d5b56e522e | ||
|
|
9fb590fe9d | ||
|
|
9678d3fcfd | ||
|
|
22e5c0d954 | ||
|
|
a4213c22af | ||
|
|
0627d9a3a0 | ||
|
|
797754d3fd | ||
|
|
8ca9c9513d | ||
|
|
5cca35cab9 | ||
|
|
b3b3ee043e | ||
|
|
32d96e366b | ||
|
|
633708fee9 | ||
|
|
67336fca7b | ||
|
|
5970dbb1ec | ||
|
|
ac463a10f2 | ||
|
|
a5bf187271 | ||
|
|
f78d33ed59 | ||
|
|
b39c5cc569 | ||
|
|
ca171f2a20 | ||
|
|
8fcb214100 | ||
|
|
4f1da98045 | ||
|
|
479a5cb743 | ||
|
|
b77e7ed554 | ||
|
|
fdf0c11ec7 | ||
|
|
f6a730e2fe | ||
|
|
1e1c6d1c72 | ||
|
|
46d1296045 | ||
|
|
06a1b6ed23 | ||
|
|
9a9196ca10 | ||
|
|
11a3ce4cc6 | ||
|
|
9b552087cd | ||
|
|
1117de7c6f | ||
|
|
e0be248847 | ||
|
|
4535800fa3 | ||
|
|
fce6862696 | ||
|
|
fbafe9eac1 | ||
|
|
bf36ebdf5e | ||
|
|
e3da638b53 | ||
|
|
716c49c55f | ||
|
|
645be586f3 | ||
|
|
16133aac65 | ||
|
|
a4faaad810 | ||
|
|
5402dfe66e | ||
|
|
65b5769abd | ||
|
|
cad769af91 | ||
|
|
2ecb52cd7c | ||
|
|
3c648820a0 | ||
|
|
09af43c314 | ||
|
|
b46cb4b740 | ||
|
|
55c85f77a1 | ||
|
|
fe7386746c | ||
|
|
4999a60643 | ||
|
|
58e3743c6d | ||
|
|
2e126c1323 | ||
|
|
0c7ce9db17 | ||
|
|
c1ce2cd82c | ||
|
|
b53e76cbd5 | ||
|
|
54188b8e97 | ||
|
|
148e5bd887 | ||
|
|
ea185fe288 | ||
|
|
0eca38ba2f | ||
|
|
b3e1192482 | ||
|
|
4022374f33 | ||
|
|
855e0ff78d | ||
|
|
856ecd4ae3 | ||
|
|
97a889da00 | ||
|
|
d30e398859 | ||
|
|
8395de01a2 | ||
|
|
dd531b8428 | ||
|
|
1b45a2c005 | ||
|
|
9ffd545b24 | ||
|
|
23033cb9c1 | ||
|
|
c168a92f18 | ||
|
|
72aa5e0763 | ||
|
|
10ab3f5187 | ||
|
|
00227e8688 | ||
|
|
198d033e21 | ||
|
|
4790f84657 | ||
|
|
2d17d8a768 | ||
|
|
e5a57ff60a | ||
|
|
b740d86bbf | ||
|
|
a99c8c7175 | ||
|
|
11f91bd451 | ||
|
|
67fee48c6a | ||
|
|
42e219389d | ||
|
|
f02cd9cd52 | ||
|
|
5e7c735935 | ||
|
|
1338c4f4f8 | ||
|
|
bdceb5f083 | ||
|
|
2f0197599f | ||
|
|
ac96bad478 | ||
|
|
d6ace6663b | ||
|
|
714b4ae06a | ||
|
|
6bedfb6a5c | ||
|
|
be38298f8e | ||
|
|
ffe36725d6 | ||
|
|
92aa34c1b5 | ||
|
|
32b2c21145 | ||
|
|
5fc64a8433 | ||
|
|
de0493d82b | ||
|
|
c00a2aabe2 | ||
|
|
59db56e953 | ||
|
|
ca1b79ad34 | ||
|
|
43864988e3 | ||
|
|
a5c3a6c930 | ||
|
|
1af37103f3 | ||
|
|
9b2c40cdd7 | ||
|
|
05c56553a2 | ||
|
|
3cef86ece5 | ||
|
|
b4bd906bf0 | ||
|
|
dd8b6347c7 | ||
|
|
a3610603bf | ||
|
|
09c2df4093 | ||
|
|
cfb871cf58 | ||
|
|
692efefe31 | ||
|
|
1c8fbb8899 | ||
|
|
bf82b4c49b | ||
|
|
51785aa6eb | ||
|
|
9583bb4c85 | ||
|
|
36df1c5f83 | ||
|
|
dbe451a199 | ||
|
|
81cf43905d | ||
|
|
3072aff31f | ||
|
|
cc305209c0 | ||
|
|
3e7ade8d4e | ||
|
|
2075b056f7 | ||
|
|
ace590273a | ||
|
|
0c44489cb3 | ||
|
|
296dfc7375 | ||
|
|
4c20b49db3 | ||
|
|
b38c9c11a8 | ||
|
|
8c904de7d4 | ||
|
|
7ff7519207 | ||
|
|
2a14b4667d | ||
|
|
7cc3e2c1cd | ||
|
|
58fe3277d8 | ||
|
|
a617a9593a | ||
|
|
f72ff080f2 | ||
|
|
80b7b57eae | ||
|
|
7c3a483190 | ||
|
|
70291d5514 | ||
|
|
d12f247e63 | ||
|
|
b61cb8f99e | ||
|
|
f64e24af8c | ||
|
|
39f0b67b0d | ||
|
|
25a013a84b | ||
|
|
7537aa11d0 | ||
|
|
0908293c42 | ||
|
|
23caba1b65 | ||
|
|
d96284c798 | ||
|
|
b7a7758f37 | ||
|
|
978a0cbc64 | ||
|
|
5db04b6d4b | ||
|
|
7acf29bc9c | ||
|
|
fce4860243 | ||
|
|
091b84008f | ||
|
|
3729304166 | ||
|
|
099d5a0822 | ||
|
|
8f50324a94 | ||
|
|
53906a2f0b | ||
|
|
11c3abb3aa | ||
|
|
c44f9528be | ||
|
|
ec30f15dc6 | ||
|
|
cbcc073aca | ||
|
|
a5074bf475 | ||
|
|
ed41f697e3 | ||
|
|
0e5155567c | ||
|
|
e2bff100bd | ||
|
|
e5699aff68 | ||
|
|
e641638c33 | ||
|
|
bbb1a3a828 | ||
|
|
7776cf62a7 | ||
|
|
35f1bf5f94 | ||
|
|
89a3b22791 | ||
|
|
d8c9b77468 | ||
|
|
695bd8a6c0 | ||
|
|
2ef2925c8e | ||
|
|
67be1eafa9 | ||
|
|
9181db8a01 | ||
|
|
43f5ed30ac | ||
|
|
c472ed27f8 | ||
|
|
3f57d5f56d | ||
|
|
529f9fa933 | ||
|
|
ef443ad047 | ||
|
|
7ea572bfc8 | ||
|
|
e6ec022fc4 | ||
|
|
a5aba1fc51 | ||
|
|
f18c8a4ecf | ||
|
|
3bf9c8c4c5 | ||
|
|
4431c5d70d | ||
|
|
839703bb55 | ||
|
|
856ae3e291 | ||
|
|
7ef4771ddf | ||
|
|
43bf7c5595 | ||
|
|
7c8702ec61 | ||
|
|
ca3835bf58 | ||
|
|
b2e2a83662 | ||
|
|
a68dd71cff | ||
|
|
91b2d9ab9a | ||
|
|
4ab7c648ce | ||
|
|
b51bc4a63a | ||
|
|
ca0504da35 | ||
|
|
91ffaea060 | ||
|
|
009ba523d7 | ||
|
|
f55c66d0a1 | ||
|
|
f87a64316a | ||
|
|
90e82f1cff | ||
|
|
914fec9ac4 | ||
|
|
ffffd0f4c5 | ||
|
|
d0b08cd2ea | ||
|
|
a9073988ec | ||
|
|
70491fe4ad | ||
|
|
ad4d5ce18a | ||
|
|
0b5f770fec | ||
|
|
825e088d45 | ||
|
|
f74252b9de | ||
|
|
c5ffc3b4f0 | ||
|
|
274985d320 | ||
|
|
31132d1b5b | ||
|
|
5f37d9df24 | ||
|
|
cad6be884c | ||
|
|
f8f3e0f936 | ||
|
|
b80d705a2d | ||
|
|
161f0800d3 | ||
|
|
dfb3b4136b | ||
|
|
91a64d0567 | ||
|
|
00bfa49031 | ||
|
|
9dfde961f3 | ||
|
|
19324e3360 | ||
|
|
26e416c364 | ||
|
|
fe44e33689 | ||
|
|
e2c4ad3ba7 | ||
|
|
14a58c9960 | ||
|
|
11ff9e0d6a | ||
|
|
fa315e9f6d | ||
|
|
31d1ce91f7 | ||
|
|
e4e54a66d6 | ||
|
|
58089c7832 | ||
|
|
6e78ffd0a6 | ||
|
|
94c6c910ff | ||
|
|
05c211d0b7 | ||
|
|
6b609aa5da | ||
|
|
9ddbad1088 | ||
|
|
57d5038d1c | ||
|
|
48847e14e0 | ||
|
|
efe0f3480a | ||
|
|
1ef4cc277b | ||
|
|
9a96e9f9d1 | ||
|
|
0bce5c83f9 | ||
|
|
9053192ae9 | ||
|
|
b0381a6ce4 | ||
|
|
b174331be4 | ||
|
|
b4ed4e6d3f | ||
|
|
278ae9b9c7 | ||
|
|
064afd9b85 | ||
|
|
163366deeb | ||
|
|
43a2ae2905 | ||
|
|
244a2fd2da | ||
|
|
fd7c90fb5a | ||
|
|
6aa4138c00 | ||
|
|
8feaf83003 | ||
|
|
190bebd65f | ||
|
|
87ec78ce2e | ||
|
|
e5edb4ac0f | ||
|
|
d3b98d311a | ||
|
|
9f0091dcd3 | ||
|
|
91fc781b6c | ||
|
|
a3c3ec8070 | ||
|
|
c5487ad1eb | ||
|
|
802bd98f16 | ||
|
|
c775311d11 | ||
|
|
154773e5ce | ||
|
|
89c507c4ba | ||
|
|
934c4c0de1 | ||
|
|
af5c8e8b1a | ||
|
|
a1c17f3006 | ||
|
|
172a9ede10 | ||
|
|
9c3c88d3cc | ||
|
|
b544e3aef8 | ||
|
|
4eb9d5ef56 | ||
|
|
8c0875239e | ||
|
|
c9768e1099 | ||
|
|
054444f619 | ||
|
|
7a8a1a8ee3 | ||
|
|
25771bed77 | ||
|
|
02b69f482d | ||
|
|
09addde73c | ||
|
|
70ff604b81 | ||
|
|
1f2425615e | ||
|
|
901ceb2507 | ||
|
|
2bced36f0c | ||
|
|
b4bf7198e7 | ||
|
|
cfec43f5eb | ||
|
|
a3c7d6611c | ||
|
|
7899dcf299 | ||
|
|
83533660db | ||
|
|
ec59996ba6 | ||
|
|
2730344ff7 | ||
|
|
7bfe6878dd | ||
|
|
829b5f87bf | ||
|
|
4719309bd7 | ||
|
|
c64f46c217 | ||
|
|
73000a226b | ||
|
|
60feaebd54 | ||
|
|
8127d3b579 | ||
|
|
f9754c8a25 | ||
|
|
420c2666a9 | ||
|
|
14e2a56b75 | ||
|
|
36a54a8a8c | ||
|
|
b7aee09758 | ||
|
|
ca8ff1c27a | ||
|
|
42fc8bc2a5 | ||
|
|
20dae8f33e | ||
|
|
2ebf70013b | ||
|
|
7cc386df52 | ||
|
|
91b97d7b25 | ||
|
|
ca06211494 | ||
|
|
306a5699a7 | ||
|
|
7a7b18032c | ||
|
|
40e43a80e7 | ||
|
|
3eb4937fd4 | ||
|
|
6507aefd8e | ||
|
|
c9069dfdf6 | ||
|
|
f111855b8c | ||
|
|
6ad3fe5200 | ||
|
|
3bd0b94228 | ||
|
|
2170b401bf | ||
|
|
31ca08c2b4 | ||
|
|
af7f0c3777 | ||
|
|
412d7eebba | ||
|
|
e7ccdfef74 | ||
|
|
8b3ef51c4f | ||
|
|
759b0bb821 | ||
|
|
bb411517cf | ||
|
|
df69320fc2 | ||
|
|
3cdb06fe70 | ||
|
|
acc4061eeb | ||
|
|
f8c5849bfa | ||
|
|
b7632c3ee7 | ||
|
|
00973fdb72 | ||
|
|
2f7b75562c | ||
|
|
1b7b172f44 | ||
|
|
fe7c85fece | ||
|
|
d1bb0b3634 | ||
|
|
72845f55ec | ||
|
|
61dcdae271 | ||
|
|
abf18b9ec4 | ||
|
|
047f62e9b4 | ||
|
|
b59d776554 | ||
|
|
0a3f6822f6 | ||
|
|
823e07bc75 | ||
|
|
dab6f43c02 | ||
|
|
174c98cdca | ||
|
|
ea5ccce90d | ||
|
|
579becd894 | ||
|
|
2e8e9ccf61 | ||
|
|
2570ba8fe6 | ||
|
|
b24483545c | ||
|
|
0ac7ccaa8f | ||
|
|
7bee69a9df | ||
|
|
f7cc779c5d | ||
|
|
13a11d6fc3 | ||
|
|
070b2696ba | ||
|
|
8c0c6ecf6e | ||
|
|
5a474709ff | ||
|
|
a85447f993 | ||
|
|
5c766b1f99 | ||
|
|
4664e36fa4 | ||
|
|
32b7a3f752 | ||
|
|
825a3d5e95 | ||
|
|
581ddb2b49 | ||
|
|
3195cc182c | ||
|
|
fe12d8d579 | ||
|
|
5724a55c7b | ||
|
|
025ea8ede9 | ||
|
|
290ccd68ee | ||
|
|
bceb15c4e6 | ||
|
|
78f2b0aa5d | ||
|
|
abdf14c8a3 | ||
|
|
dac447a57d | ||
|
|
78c1bebd7a | ||
|
|
053054bc65 | ||
|
|
ab6620f1f1 | ||
|
|
68ff1b6ff0 | ||
|
|
c0df7f4142 | ||
|
|
a933961aae | ||
|
|
68139cdbda | ||
|
|
cdac7cd28a | ||
|
|
dca17bcc12 | ||
|
|
0f778d2a4a | ||
|
|
8d517a9647 | ||
|
|
f3911b3707 | ||
|
|
75518241d6 | ||
|
|
e4860bfac0 | ||
|
|
0a9e28226b | ||
|
|
33c41e97f7 | ||
|
|
44f63ae010 | ||
|
|
f2fe374a18 | ||
|
|
429cdb448d | ||
|
|
9c477bf8fd | ||
|
|
5a971b24ad | ||
|
|
8f6c0d8fc9 | ||
|
|
7714926be5 | ||
|
|
aa9f97dfda | ||
|
|
b10f7726c3 | ||
|
|
e2d6488f1c | ||
|
|
0d4baf302d | ||
|
|
94709bf968 | ||
|
|
2666eef671 | ||
|
|
2620318172 | ||
|
|
56f0716b03 | ||
|
|
2d9b374a76 | ||
|
|
dc7dfd38c6 | ||
|
|
3b59a03c00 | ||
|
|
c28c2f6b1e | ||
|
|
fc11c69d3f | ||
|
|
b84b17d981 | ||
|
|
2dedc5ec7f | ||
|
|
b0da6adf8c | ||
|
|
9c925d7c9b | ||
|
|
2318cd47a4 | ||
|
|
4e68750777 | ||
|
|
8ed6883d70 | ||
|
|
3c5e0d4fb8 | ||
|
|
ecef5887b6 | ||
|
|
600d589617 | ||
|
|
314c095fbf | ||
|
|
cd6b017ce5 | ||
|
|
6e49d02a07 | ||
|
|
1c518c3d97 | ||
|
|
0034d0529c | ||
|
|
a59bcf7e90 | ||
|
|
22ef7d1147 | ||
|
|
33e822b0c8 | ||
|
|
af1e862aef | ||
|
|
bd1e9a0182 | ||
|
|
bab429d838 | ||
|
|
fab125d741 | ||
|
|
b48f749e26 | ||
|
|
d324b28e1a | ||
|
|
5836a49899 | ||
|
|
5b85d7019c | ||
|
|
bf7814452f | ||
|
|
f8f34fc1f4 | ||
|
|
12bbe3776c | ||
|
|
2b1bed42c9 |
66
.github/CONTRIBUTING.md
vendored
66
.github/CONTRIBUTING.md
vendored
@@ -1,58 +1,66 @@
|
||||
# Contributing to Ant Design
|
||||
|
||||
[中文版](./CONTRIBUTING.zh-CN.md)
|
||||
|
||||
The following is a set of guidelines for contributing to Ant Design. Please spend several minutes in reading these guidelines before you create an issue or pull request.
|
||||
|
||||
Anyway, these are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request.
|
||||
## Code of Conduct
|
||||
|
||||
We have adopted a [Code of Conduct](../CODE_OF_CONDUCT.md) that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
## Do your homework before asking a question
|
||||
## Open Development
|
||||
|
||||
It's a great idea to read Eric Steven Raymond's [How To Ask Questions The Smart Way](http://www.catb.org/esr/faqs/smart-questions.html) twice before asking a question. But if you are busy now, I recommend to read [Don't post homework questions](http://www.catb.org/esr/faqs/smart-questions.html#homework) first.
|
||||
All work on Ant Design happens directly on [GitHub](https://github.com/ant-design). Both core team members and external contributors send pull requests which go through the same review process.
|
||||
|
||||
The following guidelines are about *How to avoid Homework Questions*.
|
||||
## Branch Organization
|
||||
|
||||
### 1. Read the documentation.
|
||||
According to our [release schedule](../CHANGELOG.md#release-schedule), we'll cut a `feature` branch (e.g. `feature-3.1` for 3.1 release) from `master` every month. If you send a bugfix pull request, please do it against the `master` branch, if it's a feature pull request, please do it against the `feature` branch.
|
||||
|
||||
It sad but true that someone just glance(not read) [Ant Design's documentation](http://ant.design/). Please read the documentation closely. What's more, you can modify and run our demo with [CodePen](http://codepen.io/benjycui/pen/KgPZrE?editors=001). It's helpful to understand our documentation.
|
||||
## Bugs
|
||||
|
||||
Tips: choose the corresponding documentation with versions selector which in the bottom-right corner.
|
||||
We are using [GitHub Issues](https://github.com/ant-design/ant-design/issues) for bug tracing. The best way to get your bug fixed is using our [issue helper](http://new-issue.ant.design) and provide a reprduction with this [template](https://u.ant.design/codesandbox-repro).
|
||||
|
||||
### 2. Make sure that your question is about Ant Design, not React
|
||||
Before you reporting a bug, please make sure you've searched exists issues, and read our [FAQ](https://github.com/ant-design/ant-design/wiki/FAQ).
|
||||
|
||||
Someone may think all of the questions that he/she meets in developing are about Ant Design, but it's not true. So, please read [React's documentation](http://facebook.github.io/react/docs/getting-started.html) or just Google (not Baidu, seriously) your questions with keyword *React* first. If you are sure that your question is about Ant Design, go ahead.
|
||||
## Proposing a Change
|
||||
|
||||
### 3. Read the FAQ and search the issues list of Ant Design
|
||||
If you intend to change the public API or introduce new feature, we also recommend use our [issue helper](http://new-issue.ant.design) to create a feature request issue.
|
||||
|
||||
Your questions may be asked and solved by others. So please spend several minutes on searching. Remember [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself), both code and questions.
|
||||
## Your First Pull Request
|
||||
|
||||
P.S.
|
||||
Working on your first Pull Request? You can learn how from this free video series:
|
||||
|
||||
1. [FAQ](https://github.com/ant-design/ant-design/wiki/FAQ)
|
||||
1. [Issues list](https://github.com/ant-design/ant-design/issues)
|
||||
[How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
|
||||
|
||||
## Close your issue if it's solved
|
||||
To help you get your feet wet and get you familiar with our contribution process, we have a list of [good first issues](https://github.com/ant-design/ant-design/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) that contain bugs or small features that have a relatively limited scope. This is a great place to get started.
|
||||
|
||||
It is a good habit which will save maintainers' time. Thank you!
|
||||
If you decide to fix an issue, please be sure to check the comment thread in case somebody is already working on a fix. If nobody is working on it at the moment, please leave a comment stating that you intend to work on it so other people don’t accidentally duplicate your effort.
|
||||
|
||||
## Providing a demo while reporting a bug
|
||||
If somebody claims an issue but doesn’t follow up for more than two weeks, it’s fine to take over it but you should still leave a comment.
|
||||
|
||||
It would be helpful to provide a demo which can re-produce the bug 100%. Please fork this [CodePen](http://codepen.io/benjycui/pen/KgPZrE?editors=001) and re-produce the bug you met. Then, create an issue. The most important thing is: double check before claiming that you have found a bug.
|
||||
## Sending a Pull Request
|
||||
|
||||
The core team is monitoring for pull requests. We will review your pull request and either merge it, request changes to it, or close it with an explanation.
|
||||
|
||||
## Tips about Feature Request
|
||||
**Before submitting a pull request**, please make sure the following is done:
|
||||
|
||||
If you believe that Ant Design should provide some features, but it does not. You could create an issue to discuss. However, Ant Design is not Swiss Army Knife, there are some features which Ant Design will not support:
|
||||
1. Fork the repository and create your branch from [proper branch](./CONTRIBUTING.md#branch-organization).
|
||||
1. Run `npm install` in the repository root.
|
||||
1. If you’ve fixed a bug or added code that should be tested, add tests!
|
||||
1. Ensure the test suite passes (npm run test). Tip: `npm test -- --watch TestName` is helpful in development.
|
||||
1. Run `npm test -- -u` to update [jest snapshot](http://facebook.github.io/jest/docs/en/snapshot-testing.html#snapshot-testing-with-jest) and commit these changes as well (if has).
|
||||
1. Make sure your code lints (npm run lint). Tip: Lint runs automatically when you `git commit`.
|
||||
|
||||
1. Request or operate data
|
||||
Sending a Pull Request to [react-component](https://github.com/react-component/):
|
||||
|
||||
Since antd's components are based on react-component, sometimes you may need to send pull request to the corresponding react-component repository. If it's a bugfix pull request, after it's merged, the core team will release a patch release for that component as soon as possible, then you only need to do is reinstalling antd in your project to get the latest patch release. If it's a feature pull request, after it's merged, the core team will release a minor release, then you need raise another pull request to [Ant Design](https://github.com/ant-design/ant-design/) to update dependencies, document and TypeScript interfaces (if needed).
|
||||
|
||||
## Tips about Pull Request
|
||||
## Development Workflow
|
||||
|
||||
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
|
||||
After cloning antd, run `npm install` to fetch its dependencies. Then, you can run several commands:
|
||||
|
||||
It's welcomed to pull request. And there are some tips about that:
|
||||
|
||||
1. It is a good habit to create a feature request issue to discuss whether the feature is necessary before you implement it. However, it's unnecessary to create an issue to claim that you found a typo or improved the readability of documentation, just create a pull request.
|
||||
1. Run `npm run lint` and fix those errors before committing in order to keep consistent code style.
|
||||
1. Rebase before creating a PR to keep commit history clear.
|
||||
1. Add some descriptions and refer relative issues for you PR.
|
||||
1. `npm start` runs Ant Design website locally.
|
||||
1. `npm run lint` checks the code style.
|
||||
1. `npm test` runs the complete test suite.
|
||||
1. `npm run compile` compiles TypeScript code to the `lib` and `es` directory.
|
||||
1. `npm run dist` creates UMD build of antd.
|
||||
|
||||
64
.github/CONTRIBUTING.zh-CN.md
vendored
Normal file
64
.github/CONTRIBUTING.zh-CN.md
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# 贡献指南
|
||||
|
||||
这篇指南会指导你如何为 Ant Design 贡献一份自己的力量,请在你要提 issue 或者 pull request 之前花几分钟来阅读一遍这篇指南。
|
||||
|
||||
## 行为准则
|
||||
|
||||
我们有一份[行为准则](../CODE_OF_CONDUCT.md),希望所有的贡献者都能遵守,请花时间阅读一遍全文以确保你能明白哪些是可以做的,哪些是不可以做的。
|
||||
|
||||
## 透明的开发
|
||||
|
||||
我们所有的工作都会放在 [GitHub](https://github.com/ant-design) 上。不管是核心团队的成员还是外部贡献者的 pull request 都需要进过同样流程的 review。
|
||||
|
||||
## 分支管理
|
||||
|
||||
基于我们的[发布周期](../CHANGELOG.zh-CN.md#release-schedule), 我们每个月都会从 `master` 分支切一个 `feature` 分支出来(比如 `features-3.1` 分支用来发布 3.1 版本)。 如果你要修一个 bug,那么请发 pull request 到 `master`;如果你要提一个增加新功能的 pull request,那么请基于 `feature` 分支来做。
|
||||
|
||||
## Bugs
|
||||
|
||||
我们使用 [GitHub Issues](https://github.com/ant-design/ant-design/issues) 来做 bug 追踪。 如果你想要你发现的 bug 被快速解决,最好的办法就是通过我们提供的 [issue 小助手](http://new-issue.ant.design) 来提 issue。 并且能使用这个[模板](https://u.ant.design/codesandbox-repro)来提供重现。
|
||||
|
||||
在你报告一个 bug 之前,请先确保已经搜索过已有的 issue 和阅读了我们的[常见问题](https://github.com/ant-design/ant-design/wiki/FAQ)。
|
||||
|
||||
## 新增功能
|
||||
|
||||
如果你有改进我们的 API 或者新增功能的想法, 我们同样推荐你使用我们提供的[issue 小助手](http://new-issue.ant.design)来新建一个添加新功能的 issue。
|
||||
|
||||
## 第一次贡献
|
||||
|
||||
如果你还不清楚怎么在 GitHub 上提 Pull Request ,可以阅读下面这篇文章来学习:
|
||||
|
||||
[如何优雅地在 GitHub 上贡献代码](https://segmentfault.com/a/1190000000736629)
|
||||
|
||||
为了能帮助你开始你的第一次尝试,我们用 [good first issues](https://github.com/ant-design/ant-design/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) 标记了一些比较比较容易修复的 bug 和小功能。这些 issue 可以很好地做为你的首次尝试。
|
||||
|
||||
如果你打算开始处理一个 issue,请先检查一下 issue 下面的留言以确保没有别人正在处理这个 issue。如果当前没有人在处理的话你可以留言告知其他人你将会处理这个 issue,以免别人重复劳动。
|
||||
|
||||
如果之前有人留言说会处理这个 issue 但是一两个星期都没有动静,那么你也可以接手处理这个 issue,当然还是需要留言告知其他人。
|
||||
|
||||
## Pull Request
|
||||
|
||||
Ant Design 团队会关注所有的 pull request,我们会 review 以及合并你的代码,也有可能要求你做一些修改或者告诉你我们为什么不能接受这样的修改。
|
||||
|
||||
**在你发送 Pull Request 之前**,请确认你是按照下面的步骤来做的:
|
||||
|
||||
1. 基于[正确的分支](./CONTRIBUTING.zh-CN.md#branch-organization)来做修改。
|
||||
1. 在项目根目录下运行了 `npm install`。
|
||||
1. 如果你修复了一个 bug 或者新增了一个功能,请确保写了相应的测试, 这很重要。
|
||||
1. 确认所有的测试都是通过的 `npm run test`。 小贴士:开发过程中可以用 `npm test -- --watch TestName` 来运行指定的测试。
|
||||
1. 运行 `npm test -- -u` 来更新 [jest snapshot](http://facebook.github.io/jest/docs/en/snapshot-testing.html#snapshot-testing-with-jest) 并且把这些更新也提交上来(如果有的话)。
|
||||
1. 确保你的代码通过了 lint 检查 `npm run lint`. 小贴士: Lint 会在你 `git commit` 的时候自动运行。
|
||||
|
||||
给 [react-component](https://github.com/react-component/) 发送 pull request:
|
||||
|
||||
由于 antd 的大部分组件都是基于 react-component 的,所以有时候你可能需要给相应的 react-component 仓库发送 pull request。如果你是修复了某个 bug,那么我们在合并你的修改后会尽快发布一个 patch 版本,然后你只要重新安装你的依赖就可以使用新发布的版本了。如果你的 pull request 是新增了某个功能,那么在你的修改合并并且发布版本后,你还需要发送一个 pull request 到 [Ant Design](https://github.com/ant-design/ant-design/) 来升级相应的依赖、文档以及 TypeScript 的类型定义。
|
||||
|
||||
## 开发流程
|
||||
|
||||
在你 clone 了 antd 的代码并且使用 `npm install` 安装完依赖后,你还可以运行下面几个常用的命令:
|
||||
|
||||
1. `npm start` 在本地运行 Ant Design 的网站。
|
||||
1. `npm run lint` 检查代码风格。
|
||||
1. `npm test` 运行测试。
|
||||
1. `npm run compile` 编译 TypeScript 代码到 lib 和 es 目录。
|
||||
1. `npm run dist` 构建 antd 的 UMD 版本到 dist 目录。
|
||||
5
.jest.js
5
.jest.js
@@ -42,4 +42,9 @@ module.exports = {
|
||||
snapshotSerializers: [
|
||||
'enzyme-to-json/serializer',
|
||||
],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfigFile: './tsconfig.test.json',
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -18,4 +18,9 @@ module.exports = {
|
||||
snapshotSerializers: [
|
||||
'enzyme-to-json/serializer'
|
||||
],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfigFile: './tsconfig.test.json',
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
"selector-list-comma-newline-after": null,
|
||||
"selector-pseudo-element-colon-notation": null,
|
||||
"unit-no-unknown": null,
|
||||
"value-list-max-empty-lines": null
|
||||
"value-list-max-empty-lines": null,
|
||||
"font-family-no-missing-generic-family-keyword": null,
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
||||
|
||||
49
.travis.yml
49
.travis.yml
@@ -3,35 +3,26 @@ sudo: false
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "8.5"
|
||||
- 8
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TEST_TYPE=lint
|
||||
- TEST_TYPE=test:dist
|
||||
- TEST_TYPE=test:lib
|
||||
- TEST_TYPE=test:es
|
||||
- TEST_TYPE=test:dom
|
||||
- TEST_TYPE=test:node
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- env: TEST_TYPE=lint
|
||||
- env: REACT=16 TEST_TYPE=test:dist
|
||||
- env: REACT=16 TEST_TYPE=test:lib
|
||||
- env: REACT=16 TEST_TYPE=test:es
|
||||
- env: REACT=16 TEST_TYPE=test:dom
|
||||
- env: REACT=16 TEST_TYPE=test:node
|
||||
- env: REACT=15 TEST_TYPE=test:dist
|
||||
- env: REACT=15 TEST_TYPE=test:lib
|
||||
- env: REACT=15 TEST_TYPE=test:es
|
||||
- env: REACT=15 TEST_TYPE=test:dom
|
||||
- env: REACT=15 TEST_TYPE=test:node
|
||||
- env: REACT=16 TEST_TYPE=bisheng:build
|
||||
|
||||
before_script:
|
||||
- scripts/install-react.sh
|
||||
|
||||
script:
|
||||
- |
|
||||
if [ "$TEST_TYPE" = lint ]; then
|
||||
npm run lint
|
||||
elif [ "$TEST_TYPE" = test:dist ]; then
|
||||
npm run dist && \
|
||||
node ./tests/dekko/dist.test.js && \
|
||||
LIB_DIR=dist npm test -- -w 2
|
||||
elif [ "$TEST_TYPE" = test:lib ]; then
|
||||
npm run compile && \
|
||||
node ./tests/dekko/lib.test.js && \
|
||||
LIB_DIR=lib npm test -- -w 2
|
||||
elif [ "$TEST_TYPE" = test:es ]; then
|
||||
npm run compile && \
|
||||
LIB_DIR=es npm test -- -w 2
|
||||
elif [ "$TEST_TYPE" = test:dom ]; then
|
||||
npm test -- --coverage -w 2 && \
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
elif [ "$TEST_TYPE" = test:node ]; then
|
||||
npm run test-node -- -w 2
|
||||
fi
|
||||
- scripts/travis-script.sh
|
||||
|
||||
1530
CHANGELOG.en-US.md
1530
CHANGELOG.en-US.md
File diff suppressed because it is too large
Load Diff
1524
CHANGELOG.zh-CN.md
1524
CHANGELOG.zh-CN.md
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
<p align="center">
|
||||
<a href="http://ant.design">
|
||||
<img width="320" src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg">
|
||||
<img width="230" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
npm install antd
|
||||
npm install antd --save
|
||||
```
|
||||
|
||||
## 示例
|
||||
@@ -56,36 +56,22 @@ ReactDOM.render(<DatePicker />, mountNode);
|
||||
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
```
|
||||
|
||||
按需加载可通过此写法 `import DatePicker from 'antd/lib/date-picker'` 或使用 Babel 插件 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import),或使用 TypeScript 插件 [ts-import-plugin](https://github.com/Brooooooklyn/ts-import-plugin)。
|
||||
你也可以[按需加载组件](https://ant.design/docs/react/getting-started-cn#按需加载)。
|
||||
|
||||
## TypeScript
|
||||
|
||||
```js
|
||||
// tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 注意:
|
||||
> - 设置 `allowSyntheticDefaultImports` 避免 `error TS1192: Module 'react' has no default export` 的错误。
|
||||
> - 不要使用 @types/antd, antd 已经自带了 TypeScript 定义。
|
||||
参考 [在 TypeScript 中使用](https://ant.design/docs/react/use-in-typescript-cn)
|
||||
|
||||
## 国际化
|
||||
|
||||
参考 [国际化文档](http://ant.design/docs/react/i18n)。
|
||||
参考 [国际化文档](http://ant.design/docs/react/i18n-cn)。
|
||||
|
||||
## 链接
|
||||
|
||||
- [首页](http://ant.design/index-cn)
|
||||
- [UI 组件库](http://ant.design/docs/react/introduce-cn)
|
||||
- [首页](http://ant.design/)
|
||||
- [组件库](http://ant.design/docs/react/introduce)
|
||||
- [Ant Design Pro](http://pro.ant.design/)
|
||||
- [更新日志](CHANGELOG.en-US.md)
|
||||
- [官方脚手架](https://github.com/dvajs/dva-cli)
|
||||
- [开发工具文档](http://ant-tool.github.io/)
|
||||
- [脚手架市场](http://scaffold.ant.design)
|
||||
- [React 底层基础组件](http://react-component.github.io/)
|
||||
- [移动端组件](http://mobile.ant.design)
|
||||
@@ -94,7 +80,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
- [开发者说明](https://github.com/ant-design/ant-design/wiki/Development)
|
||||
- [版本发布规则](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B)
|
||||
- [常见问题](https://github.com/ant-design/ant-design/wiki/FAQ)
|
||||
- [CodePen 模板](http://codepen.io/benjycui/pen/KgPZrE?editors=001) for bug reports
|
||||
- [CodeSandbox 模板](https://u.ant.design/codesandbox-repro) for bug reports
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [定制主题](http://ant.design/docs/react/customize-theme-cn)
|
||||
|
||||
@@ -110,7 +96,7 @@ $ npm start
|
||||
|
||||
## 如何贡献
|
||||
|
||||
在任何形式的参与前,请先阅读 [贡献者文档](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md)。如果你希望参与贡献,欢迎 [Pull Request](https://github.com/ant-design/ant-design/pulls),或给我们 [报告 Bug](http://new-issue.ant.design/)。
|
||||
阅读我们的[贡献指南](./.github/CONTRIBUTING.md).
|
||||
|
||||
> 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。
|
||||
|
||||
|
||||
72
README.md
72
README.md
@@ -1,6 +1,6 @@
|
||||
<p align="center">
|
||||
<a href="http://ant.design">
|
||||
<img width="320" src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg">
|
||||
<img width="230" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -20,6 +20,10 @@ An enterprise-class UI design language and React-based implementation.
|
||||
|
||||
[中文 README](README-zh_CN.md)
|
||||
|
||||
## 3.0 Released Now! :tada::tada::tada:
|
||||
|
||||
[Announcing Ant Design 3.0](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)
|
||||
|
||||
## Features
|
||||
|
||||
- An enterprise-class UI design language for web applications.
|
||||
@@ -35,12 +39,12 @@ An enterprise-class UI design language and React-based implementation.
|
||||
|
||||
## Let's build a better antd together [](http://makeapullrequest.com)
|
||||
|
||||
`antd` is an open source project; improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22). Actually, there are [many ways](https://opensource.guide/how-to-contribute/) to contribute. And we are always happy to [offer collaborator permission](https://github.com/ant-design/ant-design/issues/3222) for some active contributors.
|
||||
Read our [contributing guide](./.github/CONTRIBUTING.md).
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm install antd
|
||||
npm install antd --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -56,63 +60,12 @@ And import style manually:
|
||||
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
```
|
||||
|
||||
### Use modularized antd
|
||||
|
||||
- Manually import
|
||||
|
||||
```jsx
|
||||
import DatePicker from 'antd/lib/date-picker'; // for js
|
||||
import 'antd/lib/date-picker/style/css'; // for css
|
||||
// import 'antd/lib/date-picker/style'; // that will import less
|
||||
```
|
||||
|
||||
- Use [babel-plugin-import](https://github.com/ant-design/babel-plugin-import)
|
||||
|
||||
```js
|
||||
// .babelrc or babel-loader option
|
||||
{
|
||||
"plugins": [
|
||||
["import", { libraryName: "antd", style: "css" }] // `style: true` for less
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Then you can import components from antd, equivalent to import manually below.
|
||||
|
||||
```jsx
|
||||
// import js and css modularly, parsed by babel-plugin-import
|
||||
import { DatePicker } from 'antd';
|
||||
```
|
||||
Or [import components on demand](https://ant.design/docs/react/getting-started#Import-on-Demand)
|
||||
|
||||
### TypeScript
|
||||
|
||||
```js
|
||||
// tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
```
|
||||
See [Use in TypeScript](https://ant.design/docs/react/use-in-typescript)
|
||||
|
||||
> Note:
|
||||
> - set `allowSyntheticDefaultImports` to prevent `error TS1192: Module 'react' has no default export`.
|
||||
> - Don't use @types/antd, antd provide a built-in ts definition already.
|
||||
|
||||
#### Use [ts-import-plugin](https://github.com/Brooooooklyn/ts-import-plugin) with modularized antd
|
||||
|
||||
```js
|
||||
{
|
||||
loader: "ts-loader", // or awesome-typescript-loader
|
||||
options {
|
||||
getCustomTransformers: () => ({
|
||||
before: [ tsImportPluginFactory({ libraryName: "antd", style: "css" }) ]
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Internationalization
|
||||
|
||||
@@ -121,10 +74,9 @@ See [i18n](http://ant.design/docs/react/i18n).
|
||||
## Links
|
||||
|
||||
- [Home page](http://ant.design/)
|
||||
- [UI library](http://ant.design/docs/react/introduce)
|
||||
- [Components](http://ant.design/docs/react/introduce)
|
||||
- [Ant Design Pro](http://pro.ant.design/)
|
||||
- [Change Log](CHANGELOG.en-US.md)
|
||||
- [Official Scaffold Tool](https://github.com/dvajs/dva-cli/)
|
||||
- [Development Tool](http://ant-tool.github.io/)
|
||||
- [Scaffold Market](http://scaffold.ant.design)
|
||||
- [rc-components](http://react-component.github.io/)
|
||||
- [Mobile UI](http://mobile.ant.design)
|
||||
@@ -132,7 +84,7 @@ See [i18n](http://ant.design/docs/react/i18n).
|
||||
- [Developer Instruction](https://github.com/ant-design/ant-design/wiki/Development)
|
||||
- [Versioning Release Note](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B)
|
||||
- [FAQ](https://github.com/ant-design/ant-design/wiki/FAQ)
|
||||
- [CodePen boilerplate](http://codepen.io/benjycui/pen/KgPZrE?editors=001) for bug reports
|
||||
- [CodeSandbox Template](https://u.ant.design/codesandbox-repro) for bug reports
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [Customize Theme](http://ant.design/docs/react/customize-theme)
|
||||
|
||||
|
||||
@@ -19,12 +19,14 @@ Array [
|
||||
"Checkbox",
|
||||
"Col",
|
||||
"DatePicker",
|
||||
"Divider",
|
||||
"Dropdown",
|
||||
"Form",
|
||||
"Icon",
|
||||
"Input",
|
||||
"InputNumber",
|
||||
"Layout",
|
||||
"List",
|
||||
"LocaleProvider",
|
||||
"message",
|
||||
"Menu",
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import throttleByAnimationFrame from '../throttleByAnimationFrame';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
describe('Test utils function', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('throttle function should work', () => {
|
||||
const callback = jest.fn();
|
||||
const throttled = throttleByAnimationFrame(callback);
|
||||
|
||||
4
components/_util/callMoment.tsx
Normal file
4
components/_util/callMoment.tsx
Normal file
@@ -0,0 +1,4 @@
|
||||
// https://github.com/moment/moment/issues/3650
|
||||
export default function callMoment(moment: any, ...args: any[]) {
|
||||
return (moment.default || moment)(...args);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
export function getComponentLocale(props, context, componentName, getDefaultLocale) {
|
||||
let locale: any = {};
|
||||
if (context && context.antLocale && context.antLocale[componentName]) {
|
||||
locale = context.antLocale[componentName];
|
||||
} else {
|
||||
const defaultLocale = getDefaultLocale();
|
||||
// TODO: make default lang of antd be English
|
||||
// https://github.com/ant-design/ant-design/issues/6334
|
||||
locale = defaultLocale.default || defaultLocale;
|
||||
}
|
||||
|
||||
const result = {
|
||||
...locale,
|
||||
...props.locale,
|
||||
};
|
||||
result.lang = {
|
||||
...locale.lang,
|
||||
...props.locale.lang,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getLocaleCode(context) {
|
||||
const localeCode = context.antLocale && context.antLocale.locale;
|
||||
// Had use LocaleProvide but didn't set locale
|
||||
if (context.antLocale && context.antLocale.exist && !localeCode) {
|
||||
return 'zh-cn';
|
||||
}
|
||||
return localeCode;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ const availablePrefixs = ['moz', 'ms', 'webkit'];
|
||||
|
||||
function requestAnimationFramePolyfill() {
|
||||
let lastTime = 0;
|
||||
return function(callback) {
|
||||
return function(callback: (n: number) => void) {
|
||||
const currTime = new Date().getTime();
|
||||
const timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
const id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
|
||||
@@ -23,11 +23,11 @@ export default function getRequestAnimationFrame() {
|
||||
const prefix = availablePrefixs.filter(key => `${key}RequestAnimationFrame` in window)[0];
|
||||
|
||||
return prefix
|
||||
? window[`${prefix}RequestAnimationFrame`]
|
||||
? (window as any)[`${prefix}RequestAnimationFrame`]
|
||||
: requestAnimationFramePolyfill();
|
||||
}
|
||||
|
||||
export function cancelRequestAnimationFrame(id) {
|
||||
export function cancelRequestAnimationFrame(id: number) {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
@@ -39,6 +39,8 @@ export function cancelRequestAnimationFrame(id) {
|
||||
)[0];
|
||||
|
||||
return prefix ?
|
||||
(window[`${prefix}CancelAnimationFrame`] || window[`${prefix}CancelRequestAnimationFrame`]).call(this, id)
|
||||
: clearTimeout(id);
|
||||
(
|
||||
(window as any)[`${prefix}CancelAnimationFrame`] ||
|
||||
(window as any)[`${prefix}CancelRequestAnimationFrame`]
|
||||
).call(this, id) : clearTimeout(id);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function getScroll(target, top): number {
|
||||
export default function getScroll(target: any, top: boolean): number {
|
||||
if (typeof window === 'undefined') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
let animation;
|
||||
let animation: boolean;
|
||||
|
||||
function isCssAnimationSupported() {
|
||||
if (animation !== undefined) {
|
||||
@@ -11,7 +11,7 @@ function isCssAnimationSupported() {
|
||||
}
|
||||
if (animation !== undefined) {
|
||||
for (let i = 0; i < domPrefixes.length; i++) {
|
||||
if (elm.style[`${domPrefixes[i]}AnimationName`] !== undefined) {
|
||||
if ((elm.style as any)[`${domPrefixes[i]}AnimationName`] !== undefined) {
|
||||
animation = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,18 +3,18 @@ import getRequestAnimationFrame, { cancelRequestAnimationFrame } from './getRequ
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
function animate(node, show, done) {
|
||||
let height;
|
||||
let requestAnimationFrameId;
|
||||
function animate(node: HTMLElement, show: boolean, done: () => void) {
|
||||
let height: number;
|
||||
let requestAnimationFrameId: number;
|
||||
return cssAnimation(node, 'ant-motion-collapse', {
|
||||
start() {
|
||||
if (!show) {
|
||||
node.style.height = `${node.offsetHeight}px`;
|
||||
node.style.opacity = 1;
|
||||
node.style.opacity = '1';
|
||||
} else {
|
||||
height = node.offsetHeight;
|
||||
node.style.height = 0;
|
||||
node.style.opacity = 0;
|
||||
node.style.height = '0px';
|
||||
node.style.opacity = '0';
|
||||
}
|
||||
},
|
||||
active() {
|
||||
@@ -23,7 +23,7 @@ function animate(node, show, done) {
|
||||
}
|
||||
requestAnimationFrameId = reqAnimFrame(() => {
|
||||
node.style.height = `${show ? height : 0}px`;
|
||||
node.style.opacity = show ? 1 : 0;
|
||||
node.style.opacity = show ? '1' : '0';
|
||||
});
|
||||
},
|
||||
end() {
|
||||
@@ -38,13 +38,13 @@ function animate(node, show, done) {
|
||||
}
|
||||
|
||||
const animation = {
|
||||
enter(node, done) {
|
||||
enter(node: HTMLElement, done: () => void) {
|
||||
return animate(node, true, done);
|
||||
},
|
||||
leave(node, done) {
|
||||
leave(node: HTMLElement, done: () => void) {
|
||||
return animate(node, false, done);
|
||||
},
|
||||
appear(node, done) {
|
||||
appear(node: HTMLElement, done: () => void) {
|
||||
return animate(node, true, done);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,27 +2,27 @@ import getRequestAnimationFrame, { cancelRequestAnimationFrame } from '../_util/
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
export default function throttleByAnimationFrame(fn) {
|
||||
let requestId;
|
||||
export default function throttleByAnimationFrame(fn: () => void) {
|
||||
let requestId: number | null;
|
||||
|
||||
const later = args => () => {
|
||||
const later = (args: any[]) => () => {
|
||||
requestId = null;
|
||||
fn(...args);
|
||||
};
|
||||
|
||||
const throttled = (...args) => {
|
||||
const throttled = (...args: any[]) => {
|
||||
if (requestId == null) {
|
||||
requestId = reqAnimFrame(later(args));
|
||||
}
|
||||
};
|
||||
|
||||
(throttled as any).cancel = () => cancelRequestAnimationFrame(requestId);
|
||||
(throttled as any).cancel = () => cancelRequestAnimationFrame(requestId!);
|
||||
|
||||
return throttled;
|
||||
}
|
||||
|
||||
export function throttleByAnimationFrameDecorator() {
|
||||
return function(target, key, descriptor) {
|
||||
return function(target: any, key: string, descriptor: any) {
|
||||
let fn = descriptor.value;
|
||||
let definingProperty = false;
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function triggerEvent(el, type) {
|
||||
export default function triggerEvent(el: Element, type: string) {
|
||||
if ('createEvent' in document) {
|
||||
// modern browsers, IE9+
|
||||
const e = document.createEvent('HTMLEvents');
|
||||
|
||||
@@ -3,8 +3,6 @@ import { mount } from 'enzyme';
|
||||
import Affix from '..';
|
||||
import Button from '../../button';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
const events = {};
|
||||
|
||||
class AffixMounter extends React.Component {
|
||||
@@ -48,13 +46,21 @@ class AffixMounter extends React.Component {
|
||||
}
|
||||
|
||||
describe('Affix Render', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('Anchor render perfectly', () => {
|
||||
document.body.innerHTML = '<div id="mounter" />';
|
||||
|
||||
const wrapper = mount(<AffixMounter />, { attachTo: document.getElementById('mounter') });
|
||||
jest.runAllTimers();
|
||||
|
||||
wrapper.node.affix.refs.fixedNode.parentNode.getBoundingClientRect = jest.fn(() => {
|
||||
wrapper.instance().affix.fixedNode.parentNode.getBoundingClientRect = jest.fn(() => {
|
||||
return {
|
||||
bottom: 100, height: 28, left: 0, right: 0, top: -50, width: 195,
|
||||
};
|
||||
@@ -65,6 +71,6 @@ describe('Affix Render', () => {
|
||||
});
|
||||
|
||||
jest.runAllTimers();
|
||||
expect(wrapper.node.affix.state.affixStyle).not.toBe(null);
|
||||
expect(wrapper.instance().affix.state.affixStyle).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
@@ -8,13 +8,13 @@ import omit from 'omit.js';
|
||||
import getScroll from '../_util/getScroll';
|
||||
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
||||
|
||||
function getTargetRect(target): ClientRect {
|
||||
function getTargetRect(target: HTMLElement | Window | null): ClientRect {
|
||||
return target !== window ?
|
||||
target.getBoundingClientRect() :
|
||||
{ top: 0, left: 0, bottom: 0 };
|
||||
(target as HTMLElement).getBoundingClientRect() :
|
||||
{ top: 0, left: 0, bottom: 0 } as ClientRect;
|
||||
}
|
||||
|
||||
function getOffset(element: HTMLElement, target) {
|
||||
function getOffset(element: HTMLElement, target: HTMLElement | Window | null) {
|
||||
const elemRect = element.getBoundingClientRect();
|
||||
const targetRect = getTargetRect(target);
|
||||
|
||||
@@ -55,11 +55,16 @@ export interface AffixProps {
|
||||
/** 固定状态改变时触发的回调函数 */
|
||||
onChange?: (affixed?: boolean) => void;
|
||||
/** 设置 Affix 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 */
|
||||
target?: () => Window | HTMLElement;
|
||||
target?: () => Window | HTMLElement | null;
|
||||
prefixCls?: string;
|
||||
}
|
||||
|
||||
export default class Affix extends React.Component<AffixProps, any> {
|
||||
export interface AffixState {
|
||||
affixStyle: React.CSSProperties | undefined;
|
||||
placeholderStyle: React.CSSProperties | undefined;
|
||||
}
|
||||
|
||||
export default class Affix extends React.Component<AffixProps, AffixState> {
|
||||
static propTypes = {
|
||||
offsetTop: PropTypes.number,
|
||||
offsetBottom: PropTypes.number,
|
||||
@@ -69,9 +74,6 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
scrollEvent: any;
|
||||
resizeEvent: any;
|
||||
timeout: any;
|
||||
refs: {
|
||||
fixedNode: HTMLElement;
|
||||
};
|
||||
|
||||
events = [
|
||||
'resize',
|
||||
@@ -83,17 +85,18 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
'load',
|
||||
];
|
||||
|
||||
eventHandlers = {};
|
||||
eventHandlers: {
|
||||
[key: string]: any;
|
||||
} = {};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
affixStyle: null,
|
||||
placeholderStyle: null,
|
||||
};
|
||||
}
|
||||
state: AffixState = {
|
||||
affixStyle: undefined,
|
||||
placeholderStyle: undefined,
|
||||
};
|
||||
|
||||
setAffixStyle(e, affixStyle) {
|
||||
private fixedNode: HTMLElement;
|
||||
|
||||
setAffixStyle(e: any, affixStyle: React.CSSProperties | null) {
|
||||
const { onChange = noop, target = getDefaultTarget } = this.props;
|
||||
const originalAffixStyle = this.state.affixStyle;
|
||||
const isWindow = target() === window;
|
||||
@@ -103,7 +106,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
if (shallowequal(affixStyle, originalAffixStyle)) {
|
||||
return;
|
||||
}
|
||||
this.setState({ affixStyle }, () => {
|
||||
this.setState({ affixStyle: affixStyle as React.CSSProperties }, () => {
|
||||
const affixed = !!this.state.affixStyle;
|
||||
if ((affixStyle && !originalAffixStyle) ||
|
||||
(!affixStyle && originalAffixStyle)) {
|
||||
@@ -112,16 +115,16 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
});
|
||||
}
|
||||
|
||||
setPlaceholderStyle(placeholderStyle) {
|
||||
setPlaceholderStyle(placeholderStyle: React.CSSProperties | null) {
|
||||
const originalPlaceholderStyle = this.state.placeholderStyle;
|
||||
if (shallowequal(placeholderStyle, originalPlaceholderStyle)) {
|
||||
return;
|
||||
}
|
||||
this.setState({ placeholderStyle });
|
||||
this.setState({ placeholderStyle: placeholderStyle as React.CSSProperties });
|
||||
}
|
||||
|
||||
@throttleByAnimationFrameDecorator()
|
||||
updatePosition(e) {
|
||||
updatePosition(e: any) {
|
||||
let { offsetTop, offsetBottom, offset, target = getDefaultTarget } = this.props;
|
||||
const targetNode = target();
|
||||
|
||||
@@ -131,8 +134,8 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
const affixNode = ReactDOM.findDOMNode(this) as HTMLElement;
|
||||
const elemOffset = getOffset(affixNode, targetNode);
|
||||
const elemSize = {
|
||||
width: this.refs.fixedNode.offsetWidth,
|
||||
height: this.refs.fixedNode.offsetHeight,
|
||||
width: this.fixedNode.offsetWidth,
|
||||
height: this.fixedNode.offsetHeight,
|
||||
};
|
||||
|
||||
const offsetMode = {
|
||||
@@ -154,10 +157,12 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
if (scrollTop > elemOffset.top - (offsetTop as number) && offsetMode.top) {
|
||||
// Fixed Top
|
||||
const width = elemOffset.width;
|
||||
const top = targetRect.top + (offsetTop as number);
|
||||
this.setAffixStyle(e, {
|
||||
position: 'fixed',
|
||||
top: targetRect.top + (offsetTop as number),
|
||||
top,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
maxHeight: `calc(100vh - ${top}px)`,
|
||||
width,
|
||||
});
|
||||
this.setPlaceholderStyle({
|
||||
@@ -200,10 +205,10 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
componentWillReceiveProps(nextProps: AffixProps) {
|
||||
if (this.props.target !== nextProps.target) {
|
||||
this.clearEventListeners();
|
||||
this.setTargetEventListeners(nextProps.target);
|
||||
this.setTargetEventListeners(nextProps.target!);
|
||||
|
||||
// Mock Event object.
|
||||
this.updatePosition({});
|
||||
@@ -216,7 +221,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
(this.updatePosition as any).cancel();
|
||||
}
|
||||
|
||||
setTargetEventListeners(getTarget) {
|
||||
setTargetEventListeners(getTarget: () => HTMLElement | Window | null) {
|
||||
const target = getTarget();
|
||||
if (!target) {
|
||||
return;
|
||||
@@ -237,6 +242,10 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
});
|
||||
}
|
||||
|
||||
saveFixedNode = (node: HTMLDivElement) => {
|
||||
this.fixedNode = node;
|
||||
}
|
||||
|
||||
render() {
|
||||
const className = classNames({
|
||||
[this.props.prefixCls || 'ant-affix']: this.state.affixStyle,
|
||||
@@ -246,7 +255,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
const placeholderStyle = { ...this.state.placeholderStyle, ...this.props.style };
|
||||
return (
|
||||
<div {...props} style={placeholderStyle}>
|
||||
<div className={className} ref="fixedNode" style={this.state.affixStyle}>
|
||||
<div className={className} ref={this.saveFixedNode} style={this.state.affixStyle}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
.@{ant-prefix}-affix {
|
||||
position: fixed;
|
||||
z-index: @zindex-affix;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import Animate from 'rc-animate';
|
||||
import Icon from '../icon';
|
||||
import classNames from 'classnames';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@alert-prefix-cls: ~"@{ant-prefix}-alert";
|
||||
|
||||
@@ -6,75 +7,71 @@
|
||||
@alert-text-color: @text-color;
|
||||
|
||||
.@{alert-prefix-cls} {
|
||||
.reset-component;
|
||||
position: relative;
|
||||
padding: 8px 48px 8px 38px;
|
||||
padding: 8px 15px 8px 37px;
|
||||
border-radius: @border-radius-base;
|
||||
color: @alert-text-color;
|
||||
font-size: @font-size-base;
|
||||
line-height: @line-height-base;
|
||||
|
||||
&&-no-icon {
|
||||
padding: 8px 48px 8px 16px;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
font-size: @font-size-lg;
|
||||
top: 8px + @font-size-base * @line-height-base / 2 - @font-size-lg / 2;
|
||||
top: 8px + @font-size-base * @line-height-base / 2 - @font-size-base / 2 + 1px;
|
||||
left: 16px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: @font-size-base;
|
||||
line-height: 21px;
|
||||
line-height: 22px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-success {
|
||||
border: @border-width-base @border-style-base @green-2;
|
||||
background-color: @green-1;
|
||||
border: @border-width-base @border-style-base ~`colorPalette("@{success-color}", 3)`;
|
||||
background-color: ~`colorPalette("@{success-color}", 1)`;
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-info {
|
||||
border: @border-width-base @border-style-base @primary-2;
|
||||
background-color: @primary-1;
|
||||
border: @border-width-base @border-style-base ~`colorPalette("@{info-color}", 3)`;
|
||||
background-color: ~`colorPalette("@{info-color}", 1)`;
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @info-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-warning {
|
||||
border: @border-width-base @border-style-base @yellow-2;
|
||||
background-color: @yellow-1;
|
||||
border: @border-width-base @border-style-base ~`colorPalette("@{warning-color}", 3)`;
|
||||
background-color: ~`colorPalette("@{warning-color}", 1)`;
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-error {
|
||||
border: @border-width-base @border-style-base @red-2;
|
||||
background-color: @red-1;
|
||||
border: @border-width-base @border-style-base ~`colorPalette("@{error-color}", 3)`;
|
||||
background-color: ~`colorPalette("@{error-color}", 1)`;
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @error-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-close-icon {
|
||||
font-size: @font-size-base;
|
||||
font-size: @font-size-sm;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 10px;
|
||||
height: 12px;
|
||||
line-height: 12px;
|
||||
top: 8px;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
.@{iconfont-css-prefix}-cross {
|
||||
color: @text-color-secondary;
|
||||
transition: color .3s ease;
|
||||
transition: color .3s;
|
||||
&:hover {
|
||||
color: #404040;
|
||||
}
|
||||
@@ -87,21 +84,21 @@
|
||||
}
|
||||
|
||||
&-with-description {
|
||||
padding: 16px 16px 16px 60px;
|
||||
padding: 15px 15px 15px 64px;
|
||||
position: relative;
|
||||
border-radius: @border-radius-base;
|
||||
color: @text-color;
|
||||
line-height: 1.5;
|
||||
line-height: @line-height-base;
|
||||
}
|
||||
|
||||
&-with-description&-no-icon {
|
||||
padding: 16px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
&-with-description &-icon {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 20px;
|
||||
left: 24px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
@@ -42,7 +42,7 @@ function easeInOutCubic(t: number, b: number, c: number, d: number) {
|
||||
}
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
function scrollTo(href: string, offsetTop = 0, target, callback = () => { }) {
|
||||
function scrollTo(href: string, offsetTop = 0, target: () => Window | HTMLElement, callback = () => { }) {
|
||||
const scrollTop = getScroll(target(), true);
|
||||
const targetElement = document.getElementById(href.substring(1));
|
||||
if (!targetElement) {
|
||||
@@ -95,9 +95,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
antAnchor: PropTypes.object,
|
||||
};
|
||||
|
||||
refs: {
|
||||
ink?: any;
|
||||
};
|
||||
private inkNode: HTMLSpanElement;
|
||||
|
||||
private links: String[];
|
||||
private scrollEvent: any;
|
||||
@@ -157,7 +155,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
});
|
||||
}
|
||||
|
||||
handleScrollTo = (link) => {
|
||||
handleScrollTo = (link: string) => {
|
||||
const { offsetTop, target = getDefaultTarget } = this.props;
|
||||
this.animating = true;
|
||||
this.setState({ activeLink: link });
|
||||
@@ -198,10 +196,14 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
const { prefixCls } = this.props;
|
||||
const linkNode = ReactDOM.findDOMNode(this as any).getElementsByClassName(`${prefixCls}-link-title-active`)[0];
|
||||
if (linkNode) {
|
||||
this.refs.ink.style.top = `${(linkNode as any).offsetTop + linkNode.clientHeight / 2 - 4.5}px`;
|
||||
this.inkNode.style.top = `${(linkNode as any).offsetTop + linkNode.clientHeight / 2 - 4.5}px`;
|
||||
}
|
||||
}
|
||||
|
||||
saveInkNode = (node: HTMLSpanElement) => {
|
||||
this.inkNode = node;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls,
|
||||
@@ -228,7 +230,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
<div className={wrapperClass} style={style}>
|
||||
<div className={anchorClass}>
|
||||
<div className={`${prefixCls}-ink`} >
|
||||
<span className={inkClass} ref="ink" />
|
||||
<span className={inkClass} ref={this.saveInkNode} />
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ describe('Anchor Render', () => {
|
||||
|
||||
wrapper.find('a[href="#API"]').simulate('click');
|
||||
|
||||
wrapper.node.handleScroll();
|
||||
expect(wrapper.node.state).not.toBe(null);
|
||||
wrapper.instance().handleScroll();
|
||||
expect(wrapper.instance().state).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -79,7 +79,7 @@ exports[`renders ./components/anchor/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/fixed.md correctly 1`] = `
|
||||
exports[`renders ./components/anchor/demo/static.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 固定
|
||||
en-US: Fixed Anchor
|
||||
zh-CN: 静态位置
|
||||
en-US: Static Anchor
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
@@ -1,5 +1,8 @@
|
||||
import Anchor from './Anchor';
|
||||
import AnchorLink from './AnchorLink';
|
||||
|
||||
export { AnchorProps } from './Anchor';
|
||||
export { AnchorLinkProps } from './AnchorLink';
|
||||
|
||||
Anchor.Link = AnchorLink;
|
||||
export default Anchor;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@anchor-border-width: 2px;
|
||||
|
||||
.@{ant-prefix}-anchor {
|
||||
.reset-component;
|
||||
position: relative;
|
||||
padding-left: @anchor-border-width;
|
||||
&-wrapper {
|
||||
background-color: @component-background;
|
||||
}
|
||||
@@ -14,7 +19,7 @@
|
||||
&:before {
|
||||
content: ' ';
|
||||
position: relative;
|
||||
width: 2px;
|
||||
width: @anchor-border-width;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: @border-color-split;
|
||||
@@ -23,10 +28,10 @@
|
||||
&-ball {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 9px;
|
||||
border: 3px solid @primary-color;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
border: 2px solid @primary-color;
|
||||
background-color: @component-background;
|
||||
left: 50%;
|
||||
transition: top .3s ease-in-out;
|
||||
@@ -42,7 +47,7 @@
|
||||
}
|
||||
|
||||
&-link {
|
||||
padding: 8px 0 8px 18px;
|
||||
padding: 8px 0 8px 16px;
|
||||
line-height: 1;
|
||||
|
||||
&-title {
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
|
||||
export default class InputElement extends React.Component<any, any> {
|
||||
export interface InputElementProps {
|
||||
children: React.ReactElement<any>;
|
||||
}
|
||||
|
||||
export default class InputElement extends React.Component<InputElementProps, any> {
|
||||
private ele: HTMLInputElement;
|
||||
|
||||
focus = () => {
|
||||
this.ele.focus ? this.ele.focus() : (findDOMNode(this.ele) as HTMLInputElement).focus();
|
||||
this.ele.focus ? this.ele.focus() : (ReactDOM.findDOMNode(this.ele) as HTMLInputElement).focus();
|
||||
}
|
||||
blur = () => {
|
||||
this.ele.blur ? this.ele.blur() : (findDOMNode(this.ele) as HTMLInputElement).blur();
|
||||
this.ele.blur ? this.ele.blur() : (ReactDOM.findDOMNode(this.ele) as HTMLInputElement).blur();
|
||||
}
|
||||
saveRef = (ele: HTMLInputElement) => {
|
||||
this.ele = ele;
|
||||
const childRef = this.props.children.ref;
|
||||
const { ref: childRef } = this.props.children as any;
|
||||
if (typeof childRef === 'function') {
|
||||
childRef(ele);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
style="width:200px"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -18,7 +18,7 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
@@ -46,7 +46,7 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
@@ -58,11 +58,11 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1`] = `
|
||||
<div
|
||||
class="certain-category-search-wrapper"
|
||||
style="width:250px;"
|
||||
style="width:250px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-lg ant-select-lg certain-category-search ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:100%;"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -77,7 +77,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
@@ -116,7 +116,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
@@ -129,7 +129,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
|
||||
exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
style="width:200px"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -152,7 +152,7 @@ exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
|
||||
<textarea
|
||||
class="ant-input custom ant-select-search__field"
|
||||
placeholder="input here"
|
||||
style="height:50px;"
|
||||
style="height:50px"
|
||||
/>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
@@ -165,7 +165,7 @@ exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
@@ -177,7 +177,7 @@ exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
|
||||
exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
style="width:200px"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -192,7 +192,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
try to type \`b\`
|
||||
@@ -220,7 +220,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
@@ -232,7 +232,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly
|
||||
exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
style="width:200px"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -247,7 +247,7 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
@@ -275,7 +275,7 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
@@ -287,11 +287,11 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly 1`] = `
|
||||
<div
|
||||
class="global-search-wrapper"
|
||||
style="width:300px;"
|
||||
style="width:300px"
|
||||
>
|
||||
<div
|
||||
class="ant-select-lg ant-select-lg global-search ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:100%;"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -306,7 +306,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
@@ -350,7 +350,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import AutoComplete from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
|
||||
describe('AutoComplete with Custom Input Element Render', () => {
|
||||
focusTest(AutoComplete);
|
||||
|
||||
it('AutoComplete with custom Input render perfectly', () => {
|
||||
const wrapper = mount(
|
||||
<AutoComplete dataSource={['12345', '23456', '34567']}>
|
||||
@@ -12,7 +15,7 @@ describe('AutoComplete with Custom Input Element Render', () => {
|
||||
|
||||
expect(wrapper.find('textarea').length).toBe(1);
|
||||
wrapper.find('textarea').simulate('change', { target: { value: '123' } });
|
||||
const dropdownWrapper = mount(wrapper.find('Trigger').node.getComponent());
|
||||
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
|
||||
// should not filter data source defaultly
|
||||
expect(dropdownWrapper.find('MenuItem').length).toBe(3);
|
||||
@@ -21,6 +21,7 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| allowClear | Show clear button, effective in multiple mode only. | boolean | false |
|
||||
| autoFocus | get focus when component mounted | boolean | false |
|
||||
| backfill | backfill selected item the input when using keyboard | boolean | false |
|
||||
| children (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |
|
||||
| children (for dataSource) | Data source for autocomplet | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
|
||||
@@ -35,3 +36,10 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
| onChange | Called when select an option or input value change, or value of input is changed | function(value, label) | - |
|
||||
| onSearch | Called when searching items. | function(value) | - |
|
||||
| onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - |
|
||||
|
||||
## Methods
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
| focus() | get focus |
|
||||
| blur() | remove focus |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import { Option, OptGroup } from 'rc-select';
|
||||
import classNames from 'classnames';
|
||||
import Select, { AbstractSelectProps, SelectValue, OptionProps, OptGroupProps } from '../select';
|
||||
@@ -8,7 +8,7 @@ import InputElement from './InputElement';
|
||||
export interface DataSourceItemObject { value: string; text: string; }
|
||||
export type DataSourceItemType = string | DataSourceItemObject;
|
||||
|
||||
export interface InputProps {
|
||||
export interface AutoCompleteInputProps {
|
||||
onChange?: React.FormEventHandler<any>;
|
||||
value: any;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export interface InputProps {
|
||||
export type ValidInputElement =
|
||||
HTMLInputElement |
|
||||
HTMLTextAreaElement |
|
||||
React.ReactElement<InputProps>;
|
||||
React.ReactElement<AutoCompleteInputProps>;
|
||||
|
||||
export interface AutoCompleteProps extends AbstractSelectProps {
|
||||
value?: SelectValue;
|
||||
@@ -34,7 +34,7 @@ function isSelectOptionOrSelectOptGroup(child: any): Boolean {
|
||||
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
|
||||
}
|
||||
|
||||
export default class AutoComplete extends React.Component<AutoCompleteProps, any> {
|
||||
export default class AutoComplete extends React.Component<AutoCompleteProps, {}> {
|
||||
static Option = Option as React.ClassicComponentClass<OptionProps>;
|
||||
static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>;
|
||||
|
||||
@@ -47,6 +47,8 @@ export default class AutoComplete extends React.Component<AutoCompleteProps, any
|
||||
filterOption: false,
|
||||
};
|
||||
|
||||
private select: any;
|
||||
|
||||
getInputElement = () => {
|
||||
const { children } = this.props;
|
||||
const element = children && React.isValidElement(children) && children.type !== Option ?
|
||||
@@ -59,6 +61,18 @@ export default class AutoComplete extends React.Component<AutoCompleteProps, any
|
||||
);
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.select.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.select.blur();
|
||||
}
|
||||
|
||||
saveSelect = (node: any) => {
|
||||
this.select = node;
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
size, className = '', notFoundContent, prefixCls, optionLabelProp, dataSource, children,
|
||||
@@ -106,6 +120,7 @@ export default class AutoComplete extends React.Component<AutoCompleteProps, any
|
||||
optionLabelProp={optionLabelProp}
|
||||
getInputElement={this.getInputElement}
|
||||
notFoundContent={notFoundContent}
|
||||
ref={this.saveSelect}
|
||||
>
|
||||
{options}
|
||||
</Select>
|
||||
|
||||
@@ -22,6 +22,7 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| allowClear | 支持清除, 单选模式有效 | boolean | false |
|
||||
| autoFocus | 自动获取焦点 | boolean | false |
|
||||
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false |
|
||||
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
|
||||
| children (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |
|
||||
@@ -36,3 +37,10 @@ const dataSource = ['12345', '23456', '34567'];
|
||||
| onChange | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) | 无 |
|
||||
| onSearch | 搜索补全项的时候调用 | function(value) | 无 |
|
||||
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |
|
||||
|
||||
## 方法
|
||||
|
||||
| 名称 | 描述 |
|
||||
| ---- | ----------- |
|
||||
| focus() | 获取焦点 |
|
||||
| blur() | 移除焦点 |
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
@autocomplete-prefix-cls: ~"@{select-prefix-cls}-auto-complete";
|
||||
|
||||
.@{autocomplete-prefix-cls} {
|
||||
.reset-component;
|
||||
|
||||
&.@{select-prefix-cls} {
|
||||
.@{select-prefix-cls} {
|
||||
&-selection {
|
||||
@@ -57,7 +59,9 @@
|
||||
line-height: @input-height-lg;
|
||||
}
|
||||
.@{input-prefix-cls} {
|
||||
.input-lg();
|
||||
padding-top: @input-padding-vertical-lg;
|
||||
padding-bottom: @input-padding-vertical-lg;
|
||||
height: @input-height-lg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +70,9 @@
|
||||
line-height: @input-height-sm;
|
||||
}
|
||||
.@{input-prefix-cls} {
|
||||
.input-sm();
|
||||
padding-top: @input-padding-vertical-sm;
|
||||
padding-bottom: @input-padding-vertical-sm;
|
||||
height: @input-height-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
style="margin-right:24px;"
|
||||
style="margin-right:24px"
|
||||
>
|
||||
<span
|
||||
class="ant-badge"
|
||||
@@ -22,7 +22,7 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1100%);-webkit-transform:translateY(-1100%);transform:translateY(-1100%);"
|
||||
style="transition:none;-ms-transform:translateY(-1100%);-webkit-transform:translateY(-1100%);transform:translateY(-1100%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -253,7 +253,7 @@ exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-lg ant-avatar-circle"
|
||||
style="background-color:#f56a00;"
|
||||
style="background-color:#f56a00;vertical-align:middle"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
@@ -263,7 +263,7 @@ exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
|
||||
</span>
|
||||
<button
|
||||
class="ant-btn ant-btn-sm"
|
||||
style="margin-left:16px;"
|
||||
style="margin-left:16px;vertical-align:middle"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
@@ -309,7 +309,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle"
|
||||
style="color:#f56a00;background-color:#fde3cf;"
|
||||
style="color:#f56a00;background-color:#fde3cf"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
@@ -319,7 +319,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
style="background-color:#87d068;"
|
||||
style="background-color:#87d068"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
|
||||
@@ -37,8 +37,12 @@ class Autoset extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Avatar style={{ backgroundColor: this.state.color }} size="large">{this.state.user}</Avatar>
|
||||
<Button size="small" style={{ marginLeft: 16 }} onClick={this.changeUser}>Change</Button>
|
||||
<Avatar style={{ backgroundColor: this.state.color, verticalAlign: 'middle' }} size="large">
|
||||
{this.state.user}
|
||||
</Avatar>
|
||||
<Button size="small" style={{ marginLeft: 16, verticalAlign: 'middle' }} onClick={this.changeUser}>
|
||||
Change
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import Icon from '../icon';
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@avatar-prefix-cls: ~"@{ant-prefix}-avatar";
|
||||
|
||||
.@{avatar-prefix-cls} {
|
||||
.reset-component;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
background: @avatar-bg;
|
||||
|
||||
@@ -4,7 +4,7 @@ exports[`renders ./components/back-top/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
Scroll down to see the bottom-right
|
||||
<strong
|
||||
style="color:rgba(64, 64, 64, 0.6);"
|
||||
style="color:rgba(64, 64, 64, 0.6)"
|
||||
>
|
||||
gray
|
||||
</strong>
|
||||
@@ -16,7 +16,7 @@ exports[`renders ./components/back-top/demo/custom.md correctly 1`] = `
|
||||
<div>
|
||||
Scroll down to see the bottom-right
|
||||
<strong
|
||||
style="color:#1088e9;"
|
||||
style="color:#1088e9"
|
||||
>
|
||||
blue
|
||||
</strong>
|
||||
|
||||
@@ -2,17 +2,23 @@ import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import BackTop from '..';
|
||||
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
|
||||
describe('BackTop', () => {
|
||||
it('should scroll to top after click it', async () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should scroll to top after click it', () => {
|
||||
const wrapper = mount(<BackTop visibilityHeight={-1} />);
|
||||
document.documentElement.scrollTop = 400;
|
||||
// trigger scroll manually
|
||||
wrapper.node.handleScroll();
|
||||
await delay(500);
|
||||
wrapper.instance().handleScroll();
|
||||
jest.runAllTimers();
|
||||
wrapper.find('.ant-back-top').simulate('click');
|
||||
await delay(500);
|
||||
jest.runAllTimers();
|
||||
expect(Math.round(document.documentElement.scrollTop)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import Animate from 'rc-animate';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import Icon from '../icon';
|
||||
import getScroll from '../_util/getScroll';
|
||||
import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
|
||||
|
||||
@@ -109,7 +108,7 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
|
||||
const defaultElement = (
|
||||
<div className={`${prefixCls}-content`}>
|
||||
<Icon className={`${prefixCls}-icon`} type="to-top" />
|
||||
<div className={`${prefixCls}-icon`} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@backtop-prefix-cls: ~"@{ant-prefix}-back-top";
|
||||
|
||||
.@{backtop-prefix-cls} {
|
||||
.reset-component;
|
||||
z-index: @zindex-back-top;
|
||||
position: fixed;
|
||||
right: 100px;
|
||||
@@ -19,6 +21,7 @@
|
||||
color: @back-top-color;
|
||||
text-align: center;
|
||||
transition: all .3s @ease-in-out;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
background-color: @back-top-hover-bg;
|
||||
@@ -27,7 +30,9 @@
|
||||
}
|
||||
|
||||
&-icon {
|
||||
font-size: 20px;
|
||||
margin-top: 10px;
|
||||
margin: 12px auto;
|
||||
width: 14px;
|
||||
height: 16px;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAoCAYAAACWwljjAAAABGdBTUEAALGPC/xhBQAAAbtJREFUWAntmMtKw0AUhhMvS5cuxILgQlRUpIggIoKIIoigG1eC+AA+jo+i6FIXBfeuXIgoeKVeitVWJX5HWhhDksnUpp3FDPyZk3Nm5nycmZKkXhAEOXSA3lG7muTeRzmfy6HneUvIhnYkQK+Q9NhAA0Opg0vBEhjBKHiyb8iGMyQMOYuK41BcBSypAL+MYXSKjtFAW7EAGEO3qN4uMQbbAkXiSfRQJ1H6a+yhlkKRcAoVFYiweYNjtCVQJJpBz2GCiPt7fBOZQpFgDpUikse5HgnkM4Fi4QX0Fpc5wf9EbLqpUCy4jMoJSXWhFwbMNgWKhVbRhy5jirhs9fy/oFhgHVVTJEs7RLZ8sSEoJm6iz7SZDMbJ+/OKERQTttCXQRLToRUmrKWCYuA2+jbN0MB4OQobYShfdTCgn/sL1K36M7TLrN3n+758aPy2rrpR6+/od5E8tf/A1uLS9aId5T7J3CNYihkQ4D9PiMdMC7mp4rjB9kjFjZp8BlnVHJBuO1yFXIV0FdDF3RlyFdJVQBdv5AxVdIsq8apiZ2PyYO1EVykesGfZEESsCkweyR8MUW+V8uJ1gkYipmpdP1pm2aJVPEGzAAAAAElFTkSuQmCC) ~"100%/100%" no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import { createElement, Component } from 'react';
|
||||
import omit from 'omit.js';
|
||||
import classNames from 'classnames';
|
||||
|
||||
function getNumberArray(num) {
|
||||
function getNumberArray(num: string | number | undefined) {
|
||||
return num ?
|
||||
num.toString()
|
||||
.split('')
|
||||
@@ -21,7 +21,12 @@ export interface ScrollNumberProps {
|
||||
title?: string | number;
|
||||
}
|
||||
|
||||
export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
export interface ScrollNumberState {
|
||||
animateStarted?: boolean;
|
||||
count?: string | number;
|
||||
}
|
||||
|
||||
export default class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-scroll-number',
|
||||
count: null,
|
||||
@@ -31,7 +36,7 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
|
||||
lastCount: any;
|
||||
|
||||
constructor(props) {
|
||||
constructor(props: ScrollNumberProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
animateStarted: true,
|
||||
@@ -39,14 +44,14 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
};
|
||||
}
|
||||
|
||||
getPositionByNum(num, i) {
|
||||
getPositionByNum(num: number, i: number) {
|
||||
if (this.state.animateStarted) {
|
||||
return 10 + num;
|
||||
}
|
||||
const currentDigit = getNumberArray(this.state.count)[i];
|
||||
const lastDigit = getNumberArray(this.lastCount)[i];
|
||||
// 同方向则在同一侧切换数字
|
||||
if (this.state.count > this.lastCount) {
|
||||
if (this.state.count! > this.lastCount) {
|
||||
if (currentDigit >= lastDigit) {
|
||||
return 10 + num;
|
||||
}
|
||||
@@ -58,7 +63,7 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
return num;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
componentWillReceiveProps(nextProps: ScrollNumberProps) {
|
||||
if ('count' in nextProps) {
|
||||
if (this.state.count === nextProps.count) {
|
||||
return;
|
||||
@@ -85,7 +90,7 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
}
|
||||
}
|
||||
|
||||
renderNumberList(position) {
|
||||
renderNumberList(position: number) {
|
||||
const childrenToReturn: React.ReactElement<any>[] = [];
|
||||
for (let i = 0; i < 30; i++) {
|
||||
const currentClassName = (position === i) ? 'current' : '';
|
||||
@@ -94,7 +99,7 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
return childrenToReturn;
|
||||
}
|
||||
|
||||
renderCurrentNumber(num, i) {
|
||||
renderCurrentNumber(num: number, i: number) {
|
||||
const position = this.getPositionByNum(num, i);
|
||||
const removeTransition = this.state.animateStarted ||
|
||||
(getNumberArray(this.lastCount)[i] === undefined);
|
||||
@@ -112,7 +117,7 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
|
||||
renderNumberElement() {
|
||||
const state = this.state;
|
||||
if (!state.count || isNaN(state.count)) {
|
||||
if (!state.count || isNaN(state.count as number)) {
|
||||
return state.count;
|
||||
}
|
||||
return getNumberArray(state.count)
|
||||
|
||||
@@ -16,7 +16,7 @@ exports[`renders ./components/badge/demo/basic.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%);"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -206,7 +206,7 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%);"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -383,7 +383,7 @@ exports[`renders ./components/badge/demo/change.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="margin-top:10px;"
|
||||
style="margin-top:10px"
|
||||
>
|
||||
<span
|
||||
class="ant-badge"
|
||||
@@ -456,7 +456,7 @@ exports[`renders ./components/badge/demo/link.md correctly 1`] = `
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%);"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -620,13 +620,13 @@ exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `
|
||||
class="ant-badge ant-badge-not-a-wrapper"
|
||||
>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
class="ant-scroll-number ant-badge-count ant-badge-multiple-words"
|
||||
data-show="true"
|
||||
title="25"
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1200%);-webkit-transform:translateY(-1200%);transform:translateY(-1200%);"
|
||||
style="transition:none;-ms-transform:translateY(-1200%);-webkit-transform:translateY(-1200%);transform:translateY(-1200%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -781,7 +781,7 @@ exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `
|
||||
</span>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%);"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -942,12 +942,12 @@ exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
data-show="true"
|
||||
style="background-color:#fff;color:#999;box-shadow:0 0 0 1px #d9d9d9 inset;"
|
||||
style="background-color:#fff;color:#999;box-shadow:0 0 0 1px #d9d9d9 inset"
|
||||
title="4"
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1400%);-webkit-transform:translateY(-1400%);transform:translateY(-1400%);"
|
||||
style="transition:none;-ms-transform:translateY(-1400%);-webkit-transform:translateY(-1400%);transform:translateY(-1400%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -1106,9 +1106,9 @@ exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `
|
||||
class="ant-badge ant-badge-not-a-wrapper"
|
||||
>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
class="ant-scroll-number ant-badge-count ant-badge-multiple-words"
|
||||
data-show="true"
|
||||
style="background-color:#87d068;"
|
||||
style="background-color:#52c41a"
|
||||
title="109"
|
||||
>
|
||||
99+
|
||||
@@ -1127,13 +1127,13 @@ exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `
|
||||
href="#"
|
||||
/>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
class="ant-scroll-number ant-badge-count ant-badge-multiple-words"
|
||||
data-show="true"
|
||||
title="99"
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1900%);-webkit-transform:translateY(-1900%);transform:translateY(-1900%);"
|
||||
style="transition:none;-ms-transform:translateY(-1900%);-webkit-transform:translateY(-1900%);transform:translateY(-1900%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -1288,7 +1288,7 @@ exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `
|
||||
</span>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1900%);-webkit-transform:translateY(-1900%);transform:translateY(-1900%);"
|
||||
style="transition:none;-ms-transform:translateY(-1900%);-webkit-transform:translateY(-1900%);transform:translateY(-1900%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
@@ -1451,7 +1451,7 @@ exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `
|
||||
href="#"
|
||||
/>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
class="ant-scroll-number ant-badge-count ant-badge-multiple-words"
|
||||
data-show="true"
|
||||
title="100"
|
||||
>
|
||||
@@ -1466,7 +1466,7 @@ exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `
|
||||
href="#"
|
||||
/>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
class="ant-scroll-number ant-badge-count ant-badge-multiple-words"
|
||||
data-show="true"
|
||||
title="99"
|
||||
>
|
||||
@@ -1481,7 +1481,7 @@ exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `
|
||||
href="#"
|
||||
/>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
class="ant-scroll-number ant-badge-count ant-badge-multiple-words"
|
||||
data-show="true"
|
||||
title="1000"
|
||||
>
|
||||
|
||||
@@ -30,12 +30,12 @@ ReactDOM.render(
|
||||
|
||||
<style>
|
||||
.ant-badge:not(.ant-badge-status) {
|
||||
margin-right: 16px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.head-example {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 6px;
|
||||
border-radius: 4px;
|
||||
background: #eee;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ ReactDOM.render(
|
||||
<div>
|
||||
<Badge count={25} />
|
||||
<Badge count={4} style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset' }} />
|
||||
<Badge count={109} style={{ backgroundColor: '#87d068' }} />
|
||||
<Badge count={109} style={{ backgroundColor: '#52c41a' }} />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -30,3 +30,4 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
|
||||
| showZero | Whether to show badge when `count` is zero | boolean | `false` |
|
||||
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` |
|
||||
| text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` |
|
||||
| offset | set offset of the badge dot, like [x, y] | [number, number] | - |
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Animate from 'rc-animate';
|
||||
import ScrollNumber from './ScrollNumber';
|
||||
import classNames from 'classnames';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
export { ScrollNumberProps } from './ScrollNumber';
|
||||
|
||||
export interface BadgeProps {
|
||||
/** Number to show in badge */
|
||||
@@ -19,6 +20,7 @@ export interface BadgeProps {
|
||||
className?: string;
|
||||
status?: 'success' | 'processing' | 'default' | 'error' | 'warning';
|
||||
text?: string;
|
||||
offset?: [number | string, number | string];
|
||||
}
|
||||
|
||||
export default class Badge extends React.Component<BadgeProps, any> {
|
||||
@@ -54,6 +56,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
dot,
|
||||
status,
|
||||
text,
|
||||
offset,
|
||||
...restProps,
|
||||
} = this.props;
|
||||
const isDot = dot || status;
|
||||
@@ -66,27 +69,29 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
const isZero = displayCount === '0' || displayCount === 0;
|
||||
const isEmpty = displayCount === null || displayCount === undefined || displayCount === '';
|
||||
const hidden = (isEmpty || (isZero && !showZero)) && !isDot;
|
||||
const statusCls = classNames({
|
||||
[`${prefixCls}-status-dot`]: !!status,
|
||||
[`${prefixCls}-status-${status}`]: !!status,
|
||||
});
|
||||
const scrollNumberCls = classNames({
|
||||
[`${prefixCls}-dot`]: isDot,
|
||||
[`${prefixCls}-count`]: !isDot,
|
||||
[`${prefixCls}-multiple-words`]: count && count.toString && count.toString().length > 1,
|
||||
[`${prefixCls}-status-${status}`]: !!status,
|
||||
});
|
||||
const badgeCls = classNames(className, prefixCls, {
|
||||
[`${prefixCls}-status`]: !!status,
|
||||
[`${prefixCls}-not-a-wrapper`]: !children,
|
||||
});
|
||||
|
||||
warning(
|
||||
!(children && status),
|
||||
'`Badge[children]` and `Badge[status]` cannot be used at the same time.',
|
||||
);
|
||||
const styleWithOffset = offset ? {
|
||||
marginTop: offset[0],
|
||||
marginLeft: offset[1],
|
||||
...style,
|
||||
} : style;
|
||||
// <Badge status="success" />
|
||||
if (!children && status) {
|
||||
const statusCls = classNames({
|
||||
[`${prefixCls}-status-dot`]: !!status,
|
||||
[`${prefixCls}-status-${status}`]: true,
|
||||
});
|
||||
return (
|
||||
<span className={badgeCls}>
|
||||
<span className={badgeCls} style={styleWithOffset}>
|
||||
<span className={statusCls} />
|
||||
<span className={`${prefixCls}-status-text`}>{text}</span>
|
||||
</span>
|
||||
@@ -100,7 +105,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
className={scrollNumberCls}
|
||||
count={displayCount}
|
||||
title={count}
|
||||
style={style}
|
||||
style={styleWithOffset}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
@@ -31,3 +31,4 @@ title: Badge
|
||||
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false |
|
||||
| status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' |
|
||||
| offset | 设置状态点的位置偏移,格式为 [x, y] | [number, number] | - |
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@badge-prefix-cls: ~"@{ant-prefix}-badge";
|
||||
@number-prefix-cls: ~"@{ant-prefix}-scroll-number";
|
||||
|
||||
.@{badge-prefix-cls} {
|
||||
.reset-component;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
@@ -24,13 +26,17 @@
|
||||
font-size: @badge-font-size;
|
||||
white-space: nowrap;
|
||||
transform-origin: -10% center;
|
||||
font-family: tahoma;
|
||||
box-shadow: 0 0 0 1px #fff;
|
||||
a,
|
||||
a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&-multiple-words {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
&-dot {
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
@@ -49,16 +55,19 @@
|
||||
vertical-align: baseline;
|
||||
|
||||
&-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
width: @badge-status-size;
|
||||
height: @badge-status-size;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
&-success {
|
||||
background-color: @success-color;
|
||||
}
|
||||
&-processing {
|
||||
background-color: @primary-color;
|
||||
background-color: @processing-color;
|
||||
position: relative;
|
||||
&:after {
|
||||
position: absolute;
|
||||
@@ -67,7 +76,7 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: 1px solid @primary-color;
|
||||
border: 1px solid @processing-color;
|
||||
content: '';
|
||||
animation: antStatusProcessing 1.2s infinite ease-in-out;
|
||||
}
|
||||
@@ -99,7 +108,7 @@
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
&-not-a-wrapper &-count {
|
||||
&-not-a-wrapper .@{ant-prefix}-scroll-number {
|
||||
top: auto;
|
||||
display: block;
|
||||
position: relative;
|
||||
@@ -126,6 +135,7 @@
|
||||
height: @badge-height;
|
||||
> p {
|
||||
height: @badge-height;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { cloneElement } from 'react';
|
||||
import warning from '../_util/warning';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface Route {
|
||||
path: string;
|
||||
breadcrumbName: string;
|
||||
}
|
||||
|
||||
export interface BreadcrumbProps {
|
||||
prefixCls?: string;
|
||||
routes?: Array<any>;
|
||||
params?: Object;
|
||||
routes?: Route[];
|
||||
params?: any;
|
||||
separator?: React.ReactNode;
|
||||
itemRender?: (route: any, params: any, routes: Array<any>, paths: Array<string>) => React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function getBreadcrumbName(route, params) {
|
||||
function getBreadcrumbName(route: Route, params: any) {
|
||||
if (!route.breadcrumbName) {
|
||||
return null;
|
||||
}
|
||||
@@ -27,7 +32,7 @@ function getBreadcrumbName(route, params) {
|
||||
return name;
|
||||
}
|
||||
|
||||
function defaultItemRender(route, params, routes, paths) {
|
||||
function defaultItemRender(route: Route, params: any, routes: Route[], paths: string[]) {
|
||||
const isLastItem = routes.indexOf(route) === routes.length - 1;
|
||||
const name = getBreadcrumbName(route, params);
|
||||
return isLastItem
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export interface BreadcrumbItemProps {
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
import { render } from 'enzyme';
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
import routerDemo from '../demo/router.md';
|
||||
|
||||
demoTest('breadcrumb', { skip: ['router.md', 'router-4.md'] });
|
||||
|
||||
const testMethod = typeof window !== 'undefined' ? test : test.skip;
|
||||
testMethod('renders ./components/breadcrumb/demo/router.md correctly', () => {
|
||||
const wrapper = render(routerDemo);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import Breadcrumb from './Breadcrumb';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
|
||||
export { BreadcrumbProps } from './Breadcrumb';
|
||||
export { BreadcrumbItemProps } from './BreadcrumbItem';
|
||||
|
||||
Breadcrumb.Item = BreadcrumbItem;
|
||||
export default Breadcrumb;
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@breadcrumb-prefix-cls: ~"@{ant-prefix}-breadcrumb";
|
||||
|
||||
.@{breadcrumb-prefix-cls} {
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
.reset-component;
|
||||
color: @text-color-secondary;
|
||||
|
||||
.@{iconfont-css-prefix} {
|
||||
font-size: @font-size-sm;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @text-color;
|
||||
color: @text-color-secondary;
|
||||
transition: color .3s;
|
||||
&:hover {
|
||||
color: @primary-5;
|
||||
@@ -15,7 +20,6 @@
|
||||
}
|
||||
|
||||
& > span:last-child {
|
||||
font-weight: 500;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
@@ -24,8 +28,8 @@
|
||||
}
|
||||
|
||||
&-separator {
|
||||
margin: 0 8px;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
margin: 0 @padding-xs;
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
||||
&-link {
|
||||
|
||||
@@ -54,7 +54,7 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
@@ -97,7 +97,7 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
|
||||
class="ant-btn-group"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
@@ -115,14 +115,6 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
M
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-dashed"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
R
|
||||
@@ -259,7 +251,7 @@ exports[`renders ./components/button/demo/disabled.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/button/demo/ghost.md correctly 1`] = `
|
||||
<div
|
||||
style="background:rgb(190, 200, 200);padding:26px 16px 16px;"
|
||||
style="background:rgb(190, 200, 200);padding:26px 16px 16px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary ant-btn-background-ghost"
|
||||
@@ -465,7 +457,7 @@ exports[`renders ./components/button/demo/multiple.md correctly 1`] = `
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
more
|
||||
Actions
|
||||
</span>
|
||||
<i
|
||||
class="anticon anticon-down"
|
||||
|
||||
@@ -49,3 +49,15 @@ exports[`Button renders correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button should support link button 1`] = `
|
||||
<a
|
||||
class="ant-btn"
|
||||
href="http://ant.design"
|
||||
target="_blank"
|
||||
>
|
||||
<span>
|
||||
link button
|
||||
</span>
|
||||
</a>
|
||||
`;
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('Button', () => {
|
||||
<DefaultButton />
|
||||
);
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(true);
|
||||
expect(wrapper.find('.ant-btn-loading').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should change loading state with delay', () => {
|
||||
@@ -74,4 +74,11 @@ describe('Button', () => {
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(false);
|
||||
});
|
||||
|
||||
it('should support link button', () => {
|
||||
const wrapper = mount(
|
||||
<Button target="_blank" href="http://ant.design">link button</Button>
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export type ButtonSize = 'small' | 'large';
|
||||
import { ButtonSize } from './button';
|
||||
|
||||
export interface ButtonGroupProps {
|
||||
size?: ButtonSize;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
@@ -35,7 +35,7 @@ function insertSpace(child: React.ReactChild, needInserted: boolean) {
|
||||
|
||||
export type ButtonType = 'primary' | 'ghost' | 'dashed' | 'danger';
|
||||
export type ButtonShape = 'circle' | 'circle-outline';
|
||||
export type ButtonSize = 'small' | 'large';
|
||||
export type ButtonSize = 'small' | 'default' | 'large';
|
||||
|
||||
export interface ButtonProps {
|
||||
type?: ButtonType;
|
||||
@@ -52,6 +52,9 @@ export interface ButtonProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
ghost?: boolean;
|
||||
target?: string;
|
||||
href?: string;
|
||||
download?: string;
|
||||
}
|
||||
|
||||
export default class Button extends React.Component<ButtonProps, any> {
|
||||
@@ -95,7 +98,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
}
|
||||
|
||||
if (typeof loading !== 'boolean' && loading && loading.delay) {
|
||||
this.delayTimeout = setTimeout(() => this.setState({ loading }), loading.delay);
|
||||
this.delayTimeout = window.setTimeout(() => this.setState({ loading }), loading.delay);
|
||||
} else {
|
||||
this.setState({ loading });
|
||||
}
|
||||
@@ -114,7 +117,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
// Add click effect
|
||||
this.setState({ clicked: true });
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => this.setState({ clicked: false }), 500);
|
||||
this.timeout = window.setTimeout(() => this.setState({ clicked: false }), 500);
|
||||
|
||||
const onClick = this.props.onClick;
|
||||
if (onClick) {
|
||||
@@ -142,6 +145,8 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
break;
|
||||
}
|
||||
|
||||
const ComponentProp = others.href ? 'a' : 'button';
|
||||
|
||||
const classes = classNames(prefixCls, className, {
|
||||
[`${prefixCls}-${type}`]: type,
|
||||
[`${prefixCls}-${shape}`]: shape,
|
||||
@@ -155,17 +160,17 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
const iconType = loading ? 'loading' : icon;
|
||||
const iconNode = iconType ? <Icon type={iconType} /> : null;
|
||||
const needInserted = React.Children.count(children) === 1 && (!iconType || iconType === 'loading');
|
||||
const kids = React.Children.map(children, child => insertSpace(child, needInserted));
|
||||
const kids = children ? React.Children.map(children, child => insertSpace(child, needInserted)) : null;
|
||||
|
||||
return (
|
||||
<button
|
||||
<ComponentProp
|
||||
{...omit(others, ['loading'])}
|
||||
type={htmlType || 'button'}
|
||||
type={others.href ? undefined : (htmlType || 'button')}
|
||||
className={classes}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
{iconNode}{kids}
|
||||
</button>
|
||||
</ComponentProp>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ ReactDOM.render(
|
||||
<h4>Basic</h4>
|
||||
<ButtonGroup>
|
||||
<Button>Cancel</Button>
|
||||
<Button type="primary">OK</Button>
|
||||
<Button>OK</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<Button disabled>L</Button>
|
||||
@@ -34,10 +34,9 @@ ReactDOM.render(
|
||||
<Button disabled>R</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<Button type="primary">L</Button>
|
||||
<Button>L</Button>
|
||||
<Button>M</Button>
|
||||
<Button>M</Button>
|
||||
<Button type="dashed">R</Button>
|
||||
<Button>R</Button>
|
||||
</ButtonGroup>
|
||||
|
||||
<h4>With Icon</h4>
|
||||
|
||||
@@ -35,7 +35,7 @@ ReactDOM.render(
|
||||
<Button>secondary</Button>
|
||||
<Dropdown overlay={menu}>
|
||||
<Button>
|
||||
more <Icon type="down" />
|
||||
Actions <Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>,
|
||||
|
||||
@@ -24,9 +24,13 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
|
||||
| size | can be set to `small` `large` or omitted | string | `default` |
|
||||
| type | can be set to `primary` `ghost` `dashed` `danger`(added in 2.7) or omitted (meaning `default`) | string | `default` |
|
||||
| onClick | set the handler to handle `click` event | function | - |
|
||||
| href | redirect url of link button | string | - |
|
||||
| target | same as target attribute of a, works when href is specified | string | - |
|
||||
|
||||
`<Button>Hello world!</Button>` will be rendered into `<button><span>Hello world!</span></button>`, and all the properties which are not listed above will be transferred to the `<button>` tag.
|
||||
|
||||
`<Button href="http://example.com">Hello world!</Button>` will be rendered into `<a href="http://example.com"><span>Hello world!</span></a>`.
|
||||
|
||||
<style>
|
||||
[id^=components-button-demo-] .ant-btn {
|
||||
margin-right: 8px;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import Button from './button';
|
||||
import ButtonGroup from './button-group';
|
||||
|
||||
export { ButtonProps, ButtonShape, ButtonSize, ButtonType } from './button';
|
||||
export { ButtonGroupProps } from './button-group';
|
||||
|
||||
Button.Group = ButtonGroup;
|
||||
export default Button;
|
||||
|
||||
@@ -27,9 +27,14 @@ subtitle: 按钮
|
||||
| size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default` |
|
||||
| type | 设置按钮类型,可选值为 `primary` `dashed` `danger`(版本 2.7 中增加) 或者不设 | string | - |
|
||||
| onClick | `click` 事件的 handler | function | - |
|
||||
| href | 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 | string | - |
|
||||
| target | 相当于 a 链接的 target 属性,href 存在时生效 | string | - |
|
||||
|
||||
|
||||
`<Button>Hello world!</Button>` 最终会被渲染为 `<button><span>Hello world!</span></button>`,并且除了上表中的属性,其它属性都会直接传到 `<button></button>`。
|
||||
|
||||
`<Button href="http://example.com">Hello world!</Button>` 则会渲染为 `<a href="http://example.com"><span>Hello world!</span></a>`。
|
||||
|
||||
<style>
|
||||
[id^="components-button-demo-"] .ant-btn {
|
||||
margin-right: 8px;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// Button styles
|
||||
// -----------------------------
|
||||
.@{btn-prefix-cls} {
|
||||
.reset-component;
|
||||
.btn;
|
||||
.btn-default;
|
||||
|
||||
@@ -127,7 +128,7 @@
|
||||
// To ensure that a space will be placed between character and `Icon`.
|
||||
> .@{iconfont-css-prefix} + span,
|
||||
> span + .@{iconfont-css-prefix} {
|
||||
margin-left: 0.5em;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&-clicked:after {
|
||||
@@ -173,3 +174,13 @@
|
||||
border-width: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
a.@{btn-prefix-cls} {
|
||||
line-height: @btn-height-base - 2px;
|
||||
&-lg {
|
||||
line-height: @btn-height-lg - 2px;
|
||||
}
|
||||
&-sm {
|
||||
line-height: @btn-height-sm - 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(@primary-color; @background; @primary-color);
|
||||
.button-color(@primary-5; @background; @primary-5);
|
||||
}
|
||||
|
||||
&:active,
|
||||
@@ -56,12 +56,12 @@
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(@btn-primary-color; @color; @color;);
|
||||
.button-color(@btn-primary-color; ~`colorPalette("@{color}", 5)`; ~`colorPalette("@{color}", 5)`);
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(@btn-primary-color; ~`colorPalette("@{color}", 7)`; ~`colorPalette("@{color}", 7)`;);
|
||||
.button-color(@btn-primary-color; ~`colorPalette("@{color}", 7)`; ~`colorPalette("@{color}", 7)`);
|
||||
}
|
||||
|
||||
.button-disabled();
|
||||
@@ -185,7 +185,7 @@
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; @btn-border-radius-sm);
|
||||
.button-size(@btn-height-sm; @btn-padding-sm; @btn-font-size-sm; @btn-border-radius-sm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,8 +251,6 @@
|
||||
|
||||
.@{btnClassName}:not(:first-child):not(:last-child) {
|
||||
border-radius: 0;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
> .@{btnClassName}:first-child {
|
||||
@@ -260,14 +258,12 @@
|
||||
&:not(:last-child) {
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
padding-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
> .@{btnClassName}:last-child:not(:first-child) {
|
||||
border-bottom-left-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
& > & {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import * as React from 'react';
|
||||
import * as moment from 'moment';
|
||||
import { PREFIX_CLS } from './Constants';
|
||||
import Select from '../select';
|
||||
import { Group, Button } from '../radio';
|
||||
@@ -12,7 +12,7 @@ export interface HeaderProps {
|
||||
yearSelectOffset?: number;
|
||||
yearSelectTotal?: number;
|
||||
type?: string;
|
||||
onValueChange?: (value) => void;
|
||||
onValueChange?: (value: moment.Moment) => void;
|
||||
onTypeChange?: (type: string) => void;
|
||||
value: any;
|
||||
}
|
||||
@@ -24,9 +24,9 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
yearSelectTotal: 20,
|
||||
};
|
||||
|
||||
calenderHeaderNode: any;
|
||||
private calenderHeaderNode: HTMLDivElement;
|
||||
|
||||
getYearSelectElement(year) {
|
||||
getYearSelectElement(year: number) {
|
||||
const { yearSelectOffset, yearSelectTotal, locale, prefixCls, fullscreen } = this.props;
|
||||
const start = year - (yearSelectOffset as number);
|
||||
const end = start + (yearSelectTotal as number);
|
||||
@@ -61,7 +61,7 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
return months;
|
||||
}
|
||||
|
||||
getMonthSelectElement(month, months) {
|
||||
getMonthSelectElement(month: number, months: number[]) {
|
||||
const props = this.props;
|
||||
const { prefixCls, fullscreen } = props;
|
||||
const options: React.ReactElement<any>[] = [];
|
||||
@@ -84,7 +84,7 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
);
|
||||
}
|
||||
|
||||
onYearChange = (year) => {
|
||||
onYearChange = (year: string) => {
|
||||
const newValue = this.props.value.clone();
|
||||
newValue.year(parseInt(year, 10));
|
||||
|
||||
@@ -94,7 +94,7 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
}
|
||||
}
|
||||
|
||||
onMonthChange = (month) => {
|
||||
onMonthChange = (month: string) => {
|
||||
const newValue = this.props.value.clone();
|
||||
newValue.month(parseInt(month, 10));
|
||||
const onValueChange = this.props.onValueChange;
|
||||
@@ -103,14 +103,14 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
}
|
||||
}
|
||||
|
||||
onTypeChange = (e) => {
|
||||
onTypeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const onTypeChange = this.props.onTypeChange;
|
||||
if (onTypeChange) {
|
||||
onTypeChange(e.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
getCalenderHeaderNode = (node) => {
|
||||
getCalenderHeaderNode = (node: HTMLDivElement) => {
|
||||
this.calenderHeaderNode = node;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
title:
|
||||
zh-CN: 卡片模式
|
||||
en-US: Card
|
||||
---
|
||||
@@ -21,7 +21,7 @@ function onPanelChange(value, mode) {
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<div style={{ width: 290, border: '1px solid #d9d9d9', borderRadius: 4 }}>
|
||||
<div style={{ width: 300, border: '1px solid #d9d9d9', borderRadius: 4 }}>
|
||||
<Calendar fullscreen={false} onPanelChange={onPanelChange} />
|
||||
</div>
|
||||
, mountNode);
|
||||
|
||||
@@ -14,7 +14,7 @@ title:
|
||||
This component can be rendered by using `dateCellRender` and `monthCellRender` with the data you need.
|
||||
|
||||
````jsx
|
||||
import { Calendar } from 'antd';
|
||||
import { Calendar, Badge } from 'antd';
|
||||
|
||||
function getListData(value) {
|
||||
let listData;
|
||||
@@ -22,18 +22,18 @@ function getListData(value) {
|
||||
case 8:
|
||||
listData = [
|
||||
{ type: 'warning', content: 'This is warning event.' },
|
||||
{ type: 'normal', content: 'This is usual event.' },
|
||||
{ type: 'success', content: 'This is usual event.' },
|
||||
]; break;
|
||||
case 10:
|
||||
listData = [
|
||||
{ type: 'warning', content: 'This is warning event.' },
|
||||
{ type: 'normal', content: 'This is usual event.' },
|
||||
{ type: 'success', content: 'This is usual event.' },
|
||||
{ type: 'error', content: 'This is error event.' },
|
||||
]; break;
|
||||
case 15:
|
||||
listData = [
|
||||
{ type: 'warning', content: 'This is warning event' },
|
||||
{ type: 'normal', content: 'This is very long usual event。。....' },
|
||||
{ type: 'success', content: 'This is very long usual event。。....' },
|
||||
{ type: 'error', content: 'This is error event 1.' },
|
||||
{ type: 'error', content: 'This is error event 2.' },
|
||||
{ type: 'error', content: 'This is error event 3.' },
|
||||
@@ -51,8 +51,7 @@ function dateCellRender(value) {
|
||||
{
|
||||
listData.map(item => (
|
||||
<li key={item.content}>
|
||||
<span className={`event-${item.type}`}>●</span>
|
||||
{item.content}
|
||||
<Badge status={item.type} text={item.content} />
|
||||
</li>
|
||||
))
|
||||
}
|
||||
@@ -83,42 +82,20 @@ ReactDOM.render(
|
||||
|
||||
````css
|
||||
.events {
|
||||
line-height: 24px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.events li {
|
||||
color: #999;
|
||||
.events .ant-badge-status {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.events li span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.events li span:first-child {
|
||||
font-size: 9px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.event-warning {
|
||||
color: #fac450;
|
||||
}
|
||||
|
||||
.event-normal {
|
||||
color: #108ee9;
|
||||
}
|
||||
|
||||
.event-error {
|
||||
color: #f50;
|
||||
}
|
||||
|
||||
.notes-month {
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
}
|
||||
.notes-month section {
|
||||
font-size: 28px;
|
||||
|
||||
@@ -16,11 +16,10 @@ When data is in the form of dates, such as schedules, timetables, prices calenda
|
||||
**Note:** Part of the Calendar's locale is read from `value`. So, please set the locale of `moment` correctly.
|
||||
|
||||
```jsx
|
||||
import moment from 'moment';
|
||||
|
||||
// It's recommended to set locale in entry file globaly.
|
||||
import 'moment/locale/zh-cn';
|
||||
moment.locale('zh-cn');
|
||||
// The default locale is en-US, if you want to use other locale, just set locale in entry file globaly.
|
||||
// import moment from 'moment';
|
||||
// import 'moment/locale/zh-cn';
|
||||
// moment.locale('zh-cn');
|
||||
|
||||
<Calendar
|
||||
dateCellRender={dateCellRender}
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import * as moment from 'moment';
|
||||
import FullCalendar from 'rc-calendar/lib/FullCalendar';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import { PREFIX_CLS } from './Constants';
|
||||
import Header from './Header';
|
||||
import { getComponentLocale, getLocaleCode } from '../_util/getLocale';
|
||||
import callMoment from '../_util/callMoment';
|
||||
|
||||
declare const require: Function;
|
||||
|
||||
export { HeaderProps } from './Header';
|
||||
|
||||
function noop() { return null; }
|
||||
|
||||
function zerofixed(v) {
|
||||
function zerofixed(v: number) {
|
||||
if (v < 10) {
|
||||
return `0${v}`;
|
||||
}
|
||||
return `${v}`;
|
||||
}
|
||||
|
||||
export interface CalendarContext {
|
||||
antLocale?: {
|
||||
Calendar?: any,
|
||||
};
|
||||
}
|
||||
|
||||
export type CalendarMode = 'month' | 'year';
|
||||
|
||||
export interface CalendarProps {
|
||||
@@ -43,7 +41,7 @@ export interface CalendarProps {
|
||||
}
|
||||
|
||||
export interface CalendarState {
|
||||
value?: moment.Moment;
|
||||
value: moment.Moment;
|
||||
mode?: CalendarMode;
|
||||
}
|
||||
|
||||
@@ -72,18 +70,10 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
onSelect: PropTypes.func,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
antLocale: PropTypes.object,
|
||||
};
|
||||
constructor(props: CalendarProps) {
|
||||
super(props);
|
||||
|
||||
context: CalendarContext;
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
// Make sure that moment locale had be set correctly.
|
||||
getComponentLocale(props, context, 'Calendar', () => require('./locale/zh_CN'));
|
||||
|
||||
const value = props.value || props.defaultValue || moment();
|
||||
const value = props.value || props.defaultValue || callMoment(moment);
|
||||
if (!moment.isMoment(value)) {
|
||||
throw new Error(
|
||||
'The value/defaultValue of Calendar must be a moment object after `antd@2.0`, ' +
|
||||
@@ -99,12 +89,12 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
componentWillReceiveProps(nextProps: CalendarProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({
|
||||
value: nextProps.value,
|
||||
value: nextProps.value!,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
monthCellRender = (value) => {
|
||||
monthCellRender = (value: moment.Moment) => {
|
||||
const { prefixCls, monthCellRender = noop as Function } = this.props;
|
||||
return (
|
||||
<div className={`${prefixCls}-month`}>
|
||||
@@ -118,7 +108,7 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
);
|
||||
}
|
||||
|
||||
dateCellRender = (value) => {
|
||||
dateCellRender = (value: moment.Moment) => {
|
||||
const { prefixCls, dateCellRender = noop as Function } = this.props;
|
||||
return (
|
||||
<div className={`${prefixCls}-date`}>
|
||||
@@ -132,7 +122,12 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
);
|
||||
}
|
||||
|
||||
setValue = (value, way: 'select' | 'changePanel') => {
|
||||
getDefaultLocale() {
|
||||
const locale = require('./locale/en_US');
|
||||
return locale.default || locale;
|
||||
}
|
||||
|
||||
setValue = (value: moment.Moment, way: 'select' | 'changePanel') => {
|
||||
if (!('value' in this.props)) {
|
||||
this.setState({ value });
|
||||
}
|
||||
@@ -145,7 +140,7 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
}
|
||||
}
|
||||
|
||||
setType = (type) => {
|
||||
setType = (type: string) => {
|
||||
const mode = (type === 'date') ? 'month' : 'year';
|
||||
if (this.state.mode !== mode) {
|
||||
this.setState({ mode });
|
||||
@@ -153,35 +148,33 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
}
|
||||
}
|
||||
|
||||
onHeaderValueChange = (value) => {
|
||||
onHeaderValueChange = (value: moment.Moment) => {
|
||||
this.setValue(value, 'changePanel');
|
||||
}
|
||||
|
||||
onHeaderTypeChange = (type) => {
|
||||
onHeaderTypeChange = (type: string) => {
|
||||
this.setType(type);
|
||||
}
|
||||
|
||||
onPanelChange(value, mode) {
|
||||
onPanelChange(value: moment.Moment, mode: CalendarMode | undefined) {
|
||||
const { onPanelChange } = this.props;
|
||||
if (onPanelChange) {
|
||||
onPanelChange(value, mode);
|
||||
}
|
||||
}
|
||||
|
||||
onSelect = (value) => {
|
||||
onSelect = (value: moment.Moment) => {
|
||||
this.setValue(value, 'select');
|
||||
}
|
||||
|
||||
render() {
|
||||
const { state, props, context } = this;
|
||||
renderCalendar = (locale: any, localeCode: string) => {
|
||||
const { state, props } = this;
|
||||
const { value, mode } = state;
|
||||
const localeCode = getLocaleCode(context);
|
||||
if (value && localeCode) {
|
||||
value.locale(localeCode);
|
||||
}
|
||||
const { prefixCls, style, className, fullscreen, dateFullCellRender, monthFullCellRender } = props;
|
||||
const type = (mode === 'year') ? 'month' : 'date';
|
||||
const locale = getComponentLocale(props, context, 'Calendar', () => require('./locale/zh_CN'));
|
||||
|
||||
let cls = className || '';
|
||||
if (fullscreen) {
|
||||
@@ -217,4 +210,15 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<LocaleReceiver
|
||||
componentName="Calendar"
|
||||
defaultLocale={this.getDefaultLocale}
|
||||
>
|
||||
{this.renderCalendar}
|
||||
</LocaleReceiver>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,10 @@ title: Calendar
|
||||
**注意:**Calendar 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。
|
||||
|
||||
```jsx
|
||||
import moment from 'moment';
|
||||
|
||||
// 推荐在入口文件全局设置 locale
|
||||
import 'moment/locale/zh-cn';
|
||||
moment.locale('zh-cn');
|
||||
// 默认语言为 en-US,所以如果需要使用其他语言,推荐在入口文件全局设置 locale
|
||||
// import moment from 'moment';
|
||||
// import 'moment/locale/zh-cn';
|
||||
// moment.locale('zh-cn');
|
||||
|
||||
<Calendar
|
||||
dateCellRender={dateCellRender}
|
||||
|
||||
2
components/calendar/locale/ar_EG.tsx
Normal file
2
components/calendar/locale/ar_EG.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import ar_EG from '../../date-picker/locale/ar_EG';
|
||||
export default ar_EG;
|
||||
2
components/calendar/locale/is_IS.tsx
Normal file
2
components/calendar/locale/is_IS.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import is_IS from '../../date-picker/locale/is_IS';
|
||||
export default is_IS;
|
||||
2
components/calendar/locale/uk_UA.tsx
Normal file
2
components/calendar/locale/uk_UA.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import uk_UA from '../../date-picker/locale/uk_UA';
|
||||
export default uk_UA;
|
||||
@@ -1,10 +1,10 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@full-calendar-prefix-cls: ~"@{ant-prefix}-fullcalendar";
|
||||
|
||||
.@{full-calendar-prefix-cls} {
|
||||
font-size: @font-size-base;
|
||||
line-height: @line-height-base;
|
||||
.reset-component;
|
||||
outline: none;
|
||||
border-top: @border-width-base @border-style-base @border-color-base;
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
}
|
||||
|
||||
&-calendar-body {
|
||||
padding: 8px 8px 14px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
table {
|
||||
@@ -46,7 +46,7 @@
|
||||
max-width: 100%;
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 246px;
|
||||
height: 256px;
|
||||
}
|
||||
|
||||
table,
|
||||
@@ -91,12 +91,12 @@
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
color: @text-color;
|
||||
border-radius: @border-radius-base;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: @border-radius-sm;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
line-height: 22px;
|
||||
line-height: 24px;
|
||||
transition: all .3s;
|
||||
|
||||
&:hover {
|
||||
@@ -116,7 +116,7 @@
|
||||
|
||||
&-today &-value,
|
||||
&-month-panel-current-cell &-value {
|
||||
box-shadow: 0 0 0 1px @primary-color;
|
||||
box-shadow: 0 0 0 1px @primary-color inset;
|
||||
}
|
||||
|
||||
&-selected-day &-value,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface CardGridProps {
|
||||
|
||||
31
components/card/Meta.tsx
Normal file
31
components/card/Meta.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface CardMetaProps {
|
||||
prefixCls?: string;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
avatar?: React.ReactNode;
|
||||
title?: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default (props: CardMetaProps) => {
|
||||
const { prefixCls = 'ant-card', className, avatar, title, description, ...others } = props;
|
||||
const classString = classNames(`${prefixCls}-meta`, className);
|
||||
const avatarDom = avatar ? <div className={`${prefixCls}-meta-avatar`}>{avatar}</div> : null;
|
||||
const titleDom = title ? <div className={`${prefixCls}-meta-title`}>{title}</div> : null;
|
||||
const descriptionDom = description ?
|
||||
<div className={`${prefixCls}-meta-description`}>{description}</div> : null;
|
||||
const MetaDetail = titleDom || descriptionDom ?
|
||||
<div className={`${prefixCls}-meta-detail`}>
|
||||
{titleDom}
|
||||
{descriptionDom}
|
||||
</div> : null;
|
||||
return (
|
||||
<div {...others} className={classString}>
|
||||
{avatarDom}
|
||||
{MetaDetail}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -3,71 +3,123 @@
|
||||
exports[`renders ./components/card/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-bordered"
|
||||
style="width:300px;"
|
||||
style="width:300px"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-extra"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/border-less.md correctly 1`] = `
|
||||
<div
|
||||
style="background:#ECECEC;padding:30px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card"
|
||||
style="width:300px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-extra"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/border-less.md correctly 1`] = `
|
||||
<div
|
||||
style="background:#ECECEC;padding:30px"
|
||||
>
|
||||
<div
|
||||
class="ant-card"
|
||||
style="width:300px"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/flexible-content.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-bordered ant-card-hoverable"
|
||||
style="width:240px"
|
||||
>
|
||||
<div
|
||||
class="ant-card-cover"
|
||||
>
|
||||
<img
|
||||
alt="example"
|
||||
src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-card-meta"
|
||||
>
|
||||
<div
|
||||
class="ant-card-meta-detail"
|
||||
>
|
||||
<div
|
||||
class="ant-card-meta-title"
|
||||
>
|
||||
Europe Street beat
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-meta-description"
|
||||
>
|
||||
www.instagram.com
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,61 +127,67 @@ exports[`renders ./components/card/demo/border-less.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/card/demo/grid-card.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-bordered ant-card-no-hovering ant-card-contain-grid"
|
||||
class="ant-card ant-card-bordered ant-card-contain-grid"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
Card Title
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card Title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center;"
|
||||
>
|
||||
Content
|
||||
<div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-grid"
|
||||
style="width:25%;text-align:center"
|
||||
>
|
||||
Content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,15 +195,15 @@ exports[`renders ./components/card/demo/grid-card.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/card/demo/in-column.md correctly 1`] = `
|
||||
<div
|
||||
style="background:#ECECEC;padding:30px;"
|
||||
style="background:#ECECEC;padding:30px"
|
||||
>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left:-8px;margin-right:-8px;"
|
||||
style="margin-left:-8px;margin-right:-8px"
|
||||
>
|
||||
<div
|
||||
class="ant-col-8"
|
||||
style="padding-left:8px;padding-right:8px;"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-card"
|
||||
@@ -154,21 +212,27 @@ exports[`renders ./components/card/demo/in-column.md correctly 1`] = `
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
Card title
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
Card content
|
||||
<div>
|
||||
Card content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-8"
|
||||
style="padding-left:8px;padding-right:8px;"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-card"
|
||||
@@ -177,21 +241,27 @@ exports[`renders ./components/card/demo/in-column.md correctly 1`] = `
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
Card title
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
Card content
|
||||
<div>
|
||||
Card content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-8"
|
||||
style="padding-left:8px;padding-right:8px;"
|
||||
style="padding-left:8px;padding-right:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-card"
|
||||
@@ -200,15 +270,119 @@ exports[`renders ./components/card/demo/in-column.md correctly 1`] = `
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
Card title
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
Card content
|
||||
<div>
|
||||
Card content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/inner.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-bordered"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
<p
|
||||
style="font-size:14px;color:rgba(0, 0, 0, 0.85);margin-bottom:16px;font-weight:500"
|
||||
>
|
||||
Group title
|
||||
</p>
|
||||
<div
|
||||
class="ant-card ant-card-bordered ant-card-type-inner"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Inner Card title
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-extra"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
Inner Card content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card ant-card-bordered ant-card-type-inner"
|
||||
style="margin-top:16px"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Inner Card title
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-extra"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
Inner Card content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -219,15 +393,19 @@ exports[`renders ./components/card/demo/in-column.md correctly 1`] = `
|
||||
exports[`renders ./components/card/demo/loading.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-loading ant-card-bordered"
|
||||
style="width:34%;"
|
||||
style="width:34%"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
Card title
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -238,50 +416,50 @@ exports[`renders ./components/card/demo/loading.md correctly 1`] = `
|
||||
>
|
||||
<p
|
||||
class="ant-card-loading-block"
|
||||
style="width:94%;"
|
||||
style="width:94%"
|
||||
/>
|
||||
<p>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:28%;"
|
||||
style="width:28%"
|
||||
/>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:62%;"
|
||||
style="width:62%"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:22%;"
|
||||
style="width:22%"
|
||||
/>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:66%;"
|
||||
style="width:66%"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:56%;"
|
||||
style="width:56%"
|
||||
/>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:39%;"
|
||||
style="width:39%"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:21%;"
|
||||
style="width:21%"
|
||||
/>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:15%;"
|
||||
style="width:15%"
|
||||
/>
|
||||
<span
|
||||
class="ant-card-loading-block"
|
||||
style="width:40%;"
|
||||
style="width:40%"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
@@ -289,55 +467,336 @@ exports[`renders ./components/card/demo/loading.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/no-padding.md correctly 1`] = `
|
||||
exports[`renders ./components/card/demo/meta.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-bordered"
|
||||
style="width:240px;"
|
||||
style="width:300px"
|
||||
>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
style="padding:0;"
|
||||
class="ant-card-cover"
|
||||
>
|
||||
<div
|
||||
class="custom-image"
|
||||
>
|
||||
<img
|
||||
alt="example"
|
||||
src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png"
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="custom-card"
|
||||
>
|
||||
<h3>
|
||||
Europe Street beat
|
||||
</h3>
|
||||
<p>
|
||||
www.instagram.com
|
||||
</p>
|
||||
<img
|
||||
alt="example"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-card-meta"
|
||||
>
|
||||
<div
|
||||
class="ant-card-meta-avatar"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-image"
|
||||
>
|
||||
<img
|
||||
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-meta-detail"
|
||||
>
|
||||
<div
|
||||
class="ant-card-meta-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-meta-description"
|
||||
>
|
||||
This is the description
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul
|
||||
class="ant-card-actions"
|
||||
>
|
||||
<li
|
||||
style="width:33.333333333333336%"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-setting"
|
||||
/>
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
style="width:33.333333333333336%"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-edit"
|
||||
/>
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
style="width:33.333333333333336%"
|
||||
>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-ellipsis"
|
||||
/>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/simple.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-bordered"
|
||||
style="width:300px;"
|
||||
style="width:300px"
|
||||
>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<div>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
<p>
|
||||
Card content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-card ant-card-bordered ant-card-contain-tabs"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-title"
|
||||
>
|
||||
Card title
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-extra"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
>
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top ant-card-head-tabs ant-tabs-large ant-tabs-line"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-bar"
|
||||
role="tablist"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-container"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev-icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tabs-tab-next ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-next-icon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ant-tabs-nav-wrap"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-scroll"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
/>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
tab1
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
tab2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-content ant-tabs-content-animated"
|
||||
style="margin-left:0%"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||
role="tabpanel"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-inactive"
|
||||
role="tabpanel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
content1
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<div
|
||||
class="ant-card ant-card-bordered ant-card-contain-tabs"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head"
|
||||
>
|
||||
<div
|
||||
class="ant-card-head-wrapper"
|
||||
/>
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top ant-card-head-tabs ant-tabs-large ant-tabs-line"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-bar"
|
||||
role="tablist"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-container"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev-icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tabs-tab-next ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-next-icon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ant-tabs-nav-wrap"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-scroll"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
/>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
article
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
app
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
project
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-content ant-tabs-content-animated"
|
||||
style="margin-left:0%"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||
role="tabpanel"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-inactive"
|
||||
role="tabpanel"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-inactive"
|
||||
role="tabpanel"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
article content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -2,12 +2,19 @@ import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Card from '../index';
|
||||
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
const testMethod = typeof window !== 'undefined' ? it : xit;
|
||||
|
||||
describe('Card', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
function fakeResizeWindowTo(wrapper, width) {
|
||||
Object.defineProperties(wrapper.node.container, {
|
||||
Object.defineProperties(wrapper.instance().container, {
|
||||
offsetWidth: {
|
||||
get() { return width; },
|
||||
configurable: true,
|
||||
@@ -16,13 +23,15 @@ describe('Card', () => {
|
||||
window.resizeTo(width);
|
||||
}
|
||||
|
||||
testMethod('resize card will trigger different padding', async () => {
|
||||
testMethod('resize card will trigger different padding', () => {
|
||||
const wrapper = mount(<Card title="xxx">xxx</Card>);
|
||||
fakeResizeWindowTo(wrapper, 1000);
|
||||
await delay(0);
|
||||
expect(wrapper.hasClass('ant-card-wider-padding')).toBe(true);
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-card-wider-padding').length).toBe(1);
|
||||
fakeResizeWindowTo(wrapper, 800);
|
||||
await delay(0);
|
||||
expect(wrapper.hasClass('ant-card-wider-padding')).toBe(false);
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-card-wider-padding').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,3 +24,9 @@ ReactDOM.render(
|
||||
</Card>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
.code-box-demo p {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
33
components/card/demo/flexible-content.md
Normal file
33
components/card/demo/flexible-content.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 更灵活的内容展示
|
||||
en-US: Customized content
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以利用 `Card.Meta` 支持更灵活的内容。
|
||||
|
||||
## en-US
|
||||
|
||||
You can use `Card.Meta` to support more flexible content.
|
||||
|
||||
|
||||
````jsx
|
||||
import { Card } from 'antd';
|
||||
const { Meta } = Card;
|
||||
|
||||
ReactDOM.render(
|
||||
<Card
|
||||
hoverable
|
||||
style={{ width: 240 }}
|
||||
cover={<img alt="example" src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png" />}
|
||||
>
|
||||
<Meta
|
||||
title="Europe Street beat"
|
||||
description="www.instagram.com"
|
||||
/>
|
||||
</Card>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -22,7 +22,7 @@ const gridStyle = {
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Card title="Card Title" noHovering>
|
||||
<Card title="Card Title">
|
||||
<Card.Grid style={gridStyle}>Content</Card.Grid>
|
||||
<Card.Grid style={gridStyle}>Content</Card.Grid>
|
||||
<Card.Grid style={gridStyle}>Content</Card.Grid>
|
||||
|
||||
48
components/card/demo/inner.md
Normal file
48
components/card/demo/inner.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
order: 7
|
||||
title:
|
||||
zh-CN: 内部卡片
|
||||
en-US: Inner card
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以放在普通卡片内部,展示多层级结构的信息。
|
||||
|
||||
## en-US
|
||||
|
||||
It can be placed inside the ordinary card to display the information of the multilevel structure.
|
||||
|
||||
````jsx
|
||||
import { Card } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Card title="Card title">
|
||||
<p
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: 'rgba(0, 0, 0, 0.85)',
|
||||
marginBottom: 16,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
Group title
|
||||
</p>
|
||||
<Card
|
||||
type="inner"
|
||||
title="Inner Card title"
|
||||
extra={<a href="#">More</a>}
|
||||
>
|
||||
Inner Card content
|
||||
</Card>
|
||||
<Card
|
||||
style={{ marginTop: 16 }}
|
||||
type="inner"
|
||||
title="Inner Card title"
|
||||
extra={<a href="#">More</a>}
|
||||
>
|
||||
Inner Card content
|
||||
</Card>
|
||||
</Card>
|
||||
, mountNode);
|
||||
````
|
||||
33
components/card/demo/meta.md
Normal file
33
components/card/demo/meta.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
order: 9
|
||||
title:
|
||||
zh-CN: 支持更多内容配置
|
||||
en-US: Support more content configuration
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
一种支持封面、头像、标题和描述信息的卡片。
|
||||
|
||||
## en-US
|
||||
|
||||
A Card that supports `cover`, `avatar`, `title` and `description`.
|
||||
|
||||
````jsx
|
||||
import { Card, Icon, Avatar } from 'antd';
|
||||
const { Meta } = Card;
|
||||
|
||||
ReactDOM.render(
|
||||
<Card
|
||||
style={{ width: 300 }}
|
||||
cover={<img alt="example" src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png" />}
|
||||
actions={[<Icon type="setting" />, <Icon type="edit" />, <Icon type="ellipsis" />]}
|
||||
>
|
||||
<Meta
|
||||
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
|
||||
title="Card title"
|
||||
description="This is the description"
|
||||
/>
|
||||
</Card>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 更灵活的内容展示
|
||||
en-US: Customized content
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以调整默认边距,设定宽度。
|
||||
|
||||
## en-US
|
||||
|
||||
Customizing default width and margin.
|
||||
|
||||
|
||||
````jsx
|
||||
import { Card } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Card style={{ width: 240 }} bodyStyle={{ padding: 0 }}>
|
||||
<div className="custom-image">
|
||||
<img alt="example" width="100%" src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png" />
|
||||
</div>
|
||||
<div className="custom-card">
|
||||
<h3>Europe Street beat</h3>
|
||||
<p>www.instagram.com</p>
|
||||
</div>
|
||||
</Card>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
.custom-image img {
|
||||
display: block;
|
||||
}
|
||||
.custom-card {
|
||||
padding: 10px 16px;
|
||||
}
|
||||
.custom-card p {
|
||||
color: #999;
|
||||
}
|
||||
````
|
||||
86
components/card/demo/tabs.md
Normal file
86
components/card/demo/tabs.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
order: 8
|
||||
title:
|
||||
zh-CN: 带页签的卡片
|
||||
en-US: With tabs
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可承载更多内容。
|
||||
|
||||
## en-US
|
||||
|
||||
More content can be hosted.
|
||||
|
||||
````jsx
|
||||
import { Card } from 'antd';
|
||||
|
||||
const tabList = [{
|
||||
key: 'tab1',
|
||||
tab: 'tab1',
|
||||
}, {
|
||||
key: 'tab2',
|
||||
tab: 'tab2',
|
||||
}];
|
||||
|
||||
const contentList = {
|
||||
tab1: <p>content1</p>,
|
||||
tab2: <p>content2</p>,
|
||||
};
|
||||
|
||||
const tabListNoTitle = [{
|
||||
key: 'article',
|
||||
tab: 'article',
|
||||
}, {
|
||||
key: 'app',
|
||||
tab: 'app',
|
||||
}, {
|
||||
key: 'project',
|
||||
tab: 'project',
|
||||
}];
|
||||
|
||||
const contentListNoTitle = {
|
||||
article: <p>article content</p>,
|
||||
app: <p>app content</p>,
|
||||
project: <p>project content</p>,
|
||||
};
|
||||
|
||||
class TabsCard extends React.Component {
|
||||
state = {
|
||||
key: 'tab1',
|
||||
noTitleKey: 'article',
|
||||
}
|
||||
onTabChange = (key, type) => {
|
||||
console.log(key, type);
|
||||
this.setState({ [type]: key });
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Card
|
||||
style={{ width: '100%' }}
|
||||
title="Card title"
|
||||
extra={<a href="#">More</a>}
|
||||
tabList={tabList}
|
||||
onTabChange={(key) => { this.onTabChange(key, 'key'); }}
|
||||
>
|
||||
{contentList[this.state.key]}
|
||||
</Card>
|
||||
<br /><br />
|
||||
<Card
|
||||
style={{ width: '100%' }}
|
||||
tabList={tabListNoTitle}
|
||||
onTabChange={(key) => { this.onTabChange(key, 'noTitleKey'); }}
|
||||
>
|
||||
{contentListNoTitle[this.state.noTitleKey]}
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<TabsCard />
|
||||
, mountNode);
|
||||
````
|
||||
@@ -21,12 +21,17 @@ A card can be used to display content related to a single subject. The content c
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| actions | The action list, shows at the bottom of the Card. | Array<ReactNode> | - |
|
||||
| bodyStyle | Inline style to apply to the card content | object | - |
|
||||
| bordered | Toggles rendering of the border around the card | boolean | `true` |
|
||||
| cover | Card cover | ReactNode | - |
|
||||
| extra | Content to render in the top-right corner of the card | string\|ReactNode | - |
|
||||
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | `false` |
|
||||
| noHovering | Whether to disable hover effect on mouse over | boolean | `false` |
|
||||
| hoverable | Lift up when hovering card | boolean | false |
|
||||
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false |
|
||||
| tabList | List of TabPane's head. | Array<{key: string, tab: ReactNode}> | - |
|
||||
| title | Card title | string\|ReactNode | - |
|
||||
| type | Card style type, can be set to `inner` or not set | string | - |
|
||||
| onTabChange | Callback when tab is switched | (key) => void | - |
|
||||
|
||||
### Card.Grid
|
||||
|
||||
@@ -34,3 +39,13 @@ A card can be used to display content related to a single subject. The content c
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| className | className of container | string | - |
|
||||
| style | style object of container | object | - |
|
||||
|
||||
### Card.Meta
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| avatar | avatar or icon | ReactNode | - |
|
||||
| className | className of container | string | - |
|
||||
| description | description content | ReactNode | - |
|
||||
| style | style object of container | object | - |
|
||||
| title | title content | ReactNode | - |
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
import React, { Component, Children } from 'react';
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import omit from 'omit.js';
|
||||
import Grid from './Grid';
|
||||
import Meta from './Meta';
|
||||
import Tabs from '../tabs';
|
||||
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
export { CardGridProps } from './Grid';
|
||||
export { CardMetaProps } from './Meta';
|
||||
|
||||
export type CardType = 'inner';
|
||||
|
||||
export interface CardTabListType {
|
||||
key: string;
|
||||
tab: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface CardProps {
|
||||
prefixCls?: string;
|
||||
@@ -13,22 +27,37 @@ export interface CardProps {
|
||||
style?: React.CSSProperties;
|
||||
loading?: boolean;
|
||||
noHovering?: boolean;
|
||||
hoverable?: boolean;
|
||||
children?: React.ReactNode;
|
||||
id?: string;
|
||||
className?: string;
|
||||
type?: CardType;
|
||||
cover?: React.ReactNode;
|
||||
actions?: Array<React.ReactNode>;
|
||||
tabList?: CardTabListType[];
|
||||
onTabChange?: (key: string) => void;
|
||||
}
|
||||
|
||||
export default class Card extends Component<CardProps, {}> {
|
||||
export default class Card extends React.Component<CardProps, {}> {
|
||||
static Grid: typeof Grid = Grid;
|
||||
container: HTMLDivElement;
|
||||
static Meta: typeof Meta = Meta;
|
||||
resizeEvent: any;
|
||||
updateWiderPaddingCalled: boolean;
|
||||
state = {
|
||||
widerPadding: false,
|
||||
};
|
||||
private container: HTMLDivElement;
|
||||
componentDidMount() {
|
||||
this.updateWiderPadding();
|
||||
this.resizeEvent = addEventListener(window, 'resize', this.updateWiderPadding);
|
||||
|
||||
if ('noHovering' in this.props) {
|
||||
warning(
|
||||
!this.props.noHovering,
|
||||
'`noHovering` of Card is deperated, you can remove it safely or use `hoverable` instead.',
|
||||
);
|
||||
warning(!!this.props.noHovering, '`noHovering={false}` of Card is deperated, use `hoverable` instead.');
|
||||
}
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if (this.resizeEvent) {
|
||||
@@ -54,73 +83,117 @@ export default class Card extends Component<CardProps, {}> {
|
||||
});
|
||||
}
|
||||
}
|
||||
onTabChange = (key: string) => {
|
||||
if (this.props.onTabChange) {
|
||||
this.props.onTabChange(key);
|
||||
}
|
||||
}
|
||||
saveRef = (node: HTMLDivElement) => {
|
||||
this.container = node;
|
||||
}
|
||||
isContainGrid() {
|
||||
let containGrid;
|
||||
Children.forEach(this.props.children, (element: JSX.Element) => {
|
||||
React.Children.forEach(this.props.children, (element: JSX.Element) => {
|
||||
if (element && element.type && element.type === Grid) {
|
||||
containGrid = true;
|
||||
}
|
||||
});
|
||||
return containGrid;
|
||||
}
|
||||
getAction(actions: React.ReactNode[]) {
|
||||
if (!actions || !actions.length) {
|
||||
return null;
|
||||
}
|
||||
const actionList = actions.map((action, index) => (
|
||||
<li style={{ width: `${100 / actions.length}%` }} key={`action-${index}`}>
|
||||
<span>{action}</span>
|
||||
</li>
|
||||
),
|
||||
);
|
||||
return actionList;
|
||||
}
|
||||
// For 2.x compatible
|
||||
getCompatibleHoverable() {
|
||||
const { noHovering, hoverable } = this.props;
|
||||
if ('noHovering' in this.props) {
|
||||
return !noHovering || hoverable;
|
||||
}
|
||||
return !!hoverable;
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
prefixCls = 'ant-card', className, extra, bodyStyle, noHovering,
|
||||
title, loading, bordered = true, ...others,
|
||||
prefixCls = 'ant-card', className, extra, bodyStyle, noHovering, hoverable, title, loading,
|
||||
bordered = true, type, cover, actions, tabList, children, ...others,
|
||||
} = this.props;
|
||||
let children = this.props.children;
|
||||
|
||||
const classString = classNames(prefixCls, className, {
|
||||
[`${prefixCls}-loading`]: loading,
|
||||
[`${prefixCls}-bordered`]: bordered,
|
||||
[`${prefixCls}-no-hovering`]: noHovering,
|
||||
[`${prefixCls}-hoverable`]: this.getCompatibleHoverable(),
|
||||
[`${prefixCls}-wider-padding`]: this.state.widerPadding,
|
||||
[`${prefixCls}-padding-transition`]: this.updateWiderPaddingCalled,
|
||||
[`${prefixCls}-contain-grid`]: this.isContainGrid(),
|
||||
[`${prefixCls}-contain-tabs`]: tabList && tabList.length,
|
||||
[`${prefixCls}-type-${type}`]: !!type,
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
children = (
|
||||
<div className={`${prefixCls}-loading-content`}>
|
||||
<p className={`${prefixCls}-loading-block`} style={{ width: '94%' }} />
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '28%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '62%' }} />
|
||||
</p>
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '22%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '66%' }} />
|
||||
</p>
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '56%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '39%' }} />
|
||||
</p>
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '21%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '15%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '40%' }} />
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const loadingBlock = (
|
||||
<div className={`${prefixCls}-loading-content`}>
|
||||
<p className={`${prefixCls}-loading-block`} style={{ width: '94%' }} />
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '28%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '62%' }} />
|
||||
</p>
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '22%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '66%' }} />
|
||||
</p>
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '56%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '39%' }} />
|
||||
</p>
|
||||
<p>
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '21%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '15%' }} />
|
||||
<span className={`${prefixCls}-loading-block`} style={{ width: '40%' }} />
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
let head;
|
||||
if (title || extra) {
|
||||
const tabs = tabList && tabList.length ? (
|
||||
<Tabs className={`${prefixCls}-head-tabs`} size="large" onChange={this.onTabChange}>
|
||||
{tabList.map(item => <Tabs.TabPane tab={item.tab} key={item.key} />)}
|
||||
</Tabs>
|
||||
) : null;
|
||||
if (title || extra || tabs) {
|
||||
head = (
|
||||
<div className={`${prefixCls}-head`}>
|
||||
{title ? <div className={`${prefixCls}-head-title`}>{title}</div> : null}
|
||||
{extra ? <div className={`${prefixCls}-extra`}>{extra}</div> : null}
|
||||
<div className={`${prefixCls}-head-wrapper`}>
|
||||
{title && <div className={`${prefixCls}-head-title`}>{title}</div>}
|
||||
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
|
||||
</div>
|
||||
{tabs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const coverDom = cover ? <div className={`${prefixCls}-cover`}>{cover}</div> : null;
|
||||
const body = (
|
||||
<div className={`${prefixCls}-body`} style={bodyStyle}>
|
||||
{loading ? loadingBlock : <div>{children}</div>}
|
||||
</div>
|
||||
);
|
||||
const actionDom = actions && actions.length ?
|
||||
<ul className={`${prefixCls}-actions`}>{this.getAction(actions)}</ul> : null;
|
||||
const divProps = omit(others, [
|
||||
'onTabChange',
|
||||
]);
|
||||
return (
|
||||
<div {...others} className={classString} ref={this.saveRef}>
|
||||
<div {...divProps} className={classString} ref={this.saveRef}>
|
||||
{head}
|
||||
<div className={`${prefixCls}-body`} style={bodyStyle}>{children}</div>
|
||||
{coverDom}
|
||||
{children ? body : null}
|
||||
{actionDom}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,12 +22,17 @@ cols: 1
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| actions | 卡片操作组,位置在卡片底部 | Array<ReactNode> | - |
|
||||
| bodyStyle | 内容区域自定义样式 | object | - |
|
||||
| bordered | 是否有边框 | boolean | true |
|
||||
| cover | 卡片封面 | ReactNode | - |
|
||||
| extra | 卡片右上角的操作区域 | string\|ReactNode | - |
|
||||
| hoverable | 鼠标移过时可浮起 | boolean | false |
|
||||
| loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false |
|
||||
| noHovering | 取消鼠标移过浮起 | boolean | false |
|
||||
| tabList | 页签标题列表 | Array<{key: string, tab: ReactNode}> | - |
|
||||
| title | 卡片标题 | string\|ReactNode | - |
|
||||
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - |
|
||||
| onTabChange | 页签切换的回调 | (key) => void | - |
|
||||
|
||||
### Card.Grid
|
||||
|
||||
@@ -35,3 +40,13 @@ cols: 1
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| className | 网格容器类名 | string | - |
|
||||
| style | 定义网格容器类名的样式 | object | - |
|
||||
|
||||
### Card.Meta
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| avatar | 头像/图标 | ReactNode | - |
|
||||
| className | 容器类名 | string | - |
|
||||
| description | 描述内容 | ReactNode | - |
|
||||
| style | 定义容器类名的样式 | object | - |
|
||||
| title | 标题内容 | ReactNode | - |
|
||||
|
||||
@@ -2,19 +2,21 @@
|
||||
@import "../../style/mixins/index";
|
||||
|
||||
@card-prefix-cls: ~"@{ant-prefix}-card";
|
||||
@card-padding-base: 24px;
|
||||
@card-padding-wider: 32px;
|
||||
@card-head-height: 48px;
|
||||
|
||||
.@{card-prefix-cls} {
|
||||
.reset-component;
|
||||
background: @component-background;
|
||||
border-radius: @border-radius-sm;
|
||||
font-size: @font-size-base;
|
||||
position: relative;
|
||||
transition: all .3s;
|
||||
|
||||
&:not(&-no-hovering):hover {
|
||||
box-shadow: @box-shadow-base;
|
||||
border-color: @shadow-color;
|
||||
&-hoverable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
box-shadow: @card-shadow;
|
||||
border-color: rgba(0, 0, 0, 0.09);
|
||||
}
|
||||
}
|
||||
|
||||
&-bordered {
|
||||
@@ -22,20 +24,22 @@
|
||||
}
|
||||
|
||||
&-head {
|
||||
height: @card-head-height;
|
||||
line-height: @card-head-height;
|
||||
background: @card-head-background;
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
padding: 0 @card-padding-base;
|
||||
border-radius: @border-radius-sm @border-radius-sm 0 0;
|
||||
.clearfix;
|
||||
margin-bottom: -1px; // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png
|
||||
display: flex;
|
||||
min-height: @card-head-height;
|
||||
|
||||
&-wrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: @font-size-lg;
|
||||
padding: @card-head-padding 0;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
color: @card-head-color;
|
||||
@@ -43,10 +47,20 @@
|
||||
display: inline-block;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.@{ant-prefix}-tabs {
|
||||
margin-bottom: -17px;
|
||||
clear: both;
|
||||
|
||||
&-bar {
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-extra {
|
||||
float: right;
|
||||
padding: @card-head-padding + 1.5px 0;
|
||||
text-align: right;
|
||||
// https://stackoverflow.com/a/22429853/3040605
|
||||
margin-left: auto;
|
||||
@@ -77,6 +91,66 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-contain-tabs &-head-title {
|
||||
padding-bottom: 0;
|
||||
min-height: @card-head-height - @card-head-padding;
|
||||
}
|
||||
|
||||
&-contain-tabs &-extra {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&-cover > * {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-actions {
|
||||
border-top: @border-width-base @border-style-base @border-color-split;
|
||||
background: @card-actions-background;
|
||||
.clearfix;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
& > li {
|
||||
float: left;
|
||||
text-align: center;
|
||||
margin: 12px 0;
|
||||
color: @text-color-secondary;
|
||||
|
||||
& > span {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
line-height: 22px;
|
||||
min-width: 32px;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
transition: color .3s;
|
||||
}
|
||||
|
||||
& > .anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @text-color-secondary;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right: @border-width-base @border-style-base @border-color-split;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-wider-padding &-head {
|
||||
padding: 0 @card-padding-wider;
|
||||
}
|
||||
@@ -85,10 +159,6 @@
|
||||
padding: @card-padding-base @card-padding-wider;
|
||||
}
|
||||
|
||||
&-wider-padding &-extra {
|
||||
right: @card-padding-wider;
|
||||
}
|
||||
|
||||
&-padding-transition &-head,
|
||||
&-padding-transition &-body {
|
||||
transition: padding .3s;
|
||||
@@ -98,6 +168,54 @@
|
||||
transition: right .3s;
|
||||
}
|
||||
|
||||
&-type-inner &-head {
|
||||
padding: 0 @card-padding-base;
|
||||
background: @background-color-light;
|
||||
|
||||
&-title {
|
||||
padding: @card-inner-head-padding 0;
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
}
|
||||
|
||||
&-type-inner &-body {
|
||||
padding: 16px @card-padding-base;
|
||||
}
|
||||
|
||||
&-type-inner &-extra {
|
||||
padding: @card-inner-head-padding + 1.5px 0;
|
||||
}
|
||||
|
||||
&-meta {
|
||||
margin: -4px 0;
|
||||
.clearfix;
|
||||
|
||||
&-avatar {
|
||||
padding-right: 16px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
&-detail {
|
||||
overflow: hidden;
|
||||
> div:not(:last-child) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: @font-size-lg;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
color: @card-head-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&-description {
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
&-loading &-body {
|
||||
user-select: none;
|
||||
padding: 0;
|
||||
@@ -105,11 +223,14 @@
|
||||
|
||||
&-loading-content {
|
||||
padding: @card-padding-base;
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-loading-block {
|
||||
display: inline-block;
|
||||
margin: 5px 1% 0;
|
||||
margin: 5px 2% 0 0;
|
||||
height: 14px;
|
||||
border-radius: @border-radius-sm;
|
||||
background: linear-gradient(90deg, rgba(207, 216, 220, .2), rgba(207, 216, 220, .4), rgba(207, 216, 220, .2));
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
|
||||
// style dependencies
|
||||
import '../../tabs/style';
|
||||
|
||||
@@ -24,7 +24,7 @@ exports[`renders ./components/carousel/demo/autoplay.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-active slick-cloned"
|
||||
data-index="0"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -34,7 +34,7 @@ exports[`renders ./components/carousel/demo/autoplay.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="1"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -44,7 +44,7 @@ exports[`renders ./components/carousel/demo/autoplay.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="2"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -54,7 +54,7 @@ exports[`renders ./components/carousel/demo/autoplay.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="3"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -99,7 +99,7 @@ exports[`renders ./components/carousel/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-active slick-cloned"
|
||||
data-index="0"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -109,7 +109,7 @@ exports[`renders ./components/carousel/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="1"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -119,7 +119,7 @@ exports[`renders ./components/carousel/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="2"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -129,7 +129,7 @@ exports[`renders ./components/carousel/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="3"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -166,7 +166,7 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-active slick-cloned"
|
||||
data-index="0"
|
||||
style="outline:none;position:relative;left:0;opacity:1;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease;"
|
||||
style="outline:none;position:relative;left:0;opacity:1;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -176,7 +176,7 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="1"
|
||||
style="outline:none;position:relative;left:0;opacity:0;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease;"
|
||||
style="outline:none;position:relative;left:0;opacity:0;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -186,7 +186,7 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="2"
|
||||
style="outline:none;position:relative;left:0;opacity:0;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease;"
|
||||
style="outline:none;position:relative;left:0;opacity:0;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -196,7 +196,7 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="3"
|
||||
style="outline:none;position:relative;left:0;opacity:0;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease;"
|
||||
style="outline:none;position:relative;left:0;opacity:0;transition:opacity 500ms ease;-webkit-transition:opacity 500ms ease"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -233,7 +233,7 @@ exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-active slick-cloned"
|
||||
data-index="0"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -243,7 +243,7 @@ exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="1"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -253,7 +253,7 @@ exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="2"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
@@ -263,7 +263,7 @@ exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
|
||||
<div
|
||||
class="slick-slide slick-cloned"
|
||||
data-index="3"
|
||||
style="outline:none;"
|
||||
style="outline:none"
|
||||
tabindex="-1"
|
||||
>
|
||||
<h3>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user