mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 10:59:19 +08:00
Compare commits
542 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d151514e3 | ||
|
|
d68f36a422 | ||
|
|
5a207d3291 | ||
|
|
fe750d365d | ||
|
|
58a32455d3 | ||
|
|
c91bf93a38 | ||
|
|
079f2a657d | ||
|
|
3ba79342d5 | ||
|
|
38606552d4 | ||
|
|
4b0968714a | ||
|
|
79e319908a | ||
|
|
f25ac2feac | ||
|
|
2dd781edb3 | ||
|
|
a058ebc372 | ||
|
|
9b09e54df5 | ||
|
|
8070e05de1 | ||
|
|
d618691bc1 | ||
|
|
f9aed15464 | ||
|
|
82fff19ab8 | ||
|
|
3738eb3b73 | ||
|
|
e8ce54f864 | ||
|
|
218b7bb39c | ||
|
|
4381de2e11 | ||
|
|
0b2e7a6926 | ||
|
|
991eb76953 | ||
|
|
ca2fca024a | ||
|
|
7ce38e39b6 | ||
|
|
e1a5c20d26 | ||
|
|
05d38115d8 | ||
|
|
0edd5ada9a | ||
|
|
67305505c2 | ||
|
|
5f8baf1bfd | ||
|
|
86b5c6eecc | ||
|
|
4953653947 | ||
|
|
052d0ac122 | ||
|
|
870b7ade34 | ||
|
|
d2cf85b87b | ||
|
|
7ea67b6e37 | ||
|
|
1e26289da7 | ||
|
|
17b9d85f44 | ||
|
|
8fff871a7c | ||
|
|
5cf7c592e1 | ||
|
|
4bcbf6ba06 | ||
|
|
3ab72afc44 | ||
|
|
ed9fc679b8 | ||
|
|
85afd74c35 | ||
|
|
ce11c258b3 | ||
|
|
ab67c71939 | ||
|
|
9fc3f51d68 | ||
|
|
c61d31f4d1 | ||
|
|
6d7f571c1d | ||
|
|
38a4436599 | ||
|
|
b3340c6b6b | ||
|
|
cdbac65dbc | ||
|
|
d62c87d036 | ||
|
|
33dd8b971d | ||
|
|
d84c52fda8 | ||
|
|
9991e96a9d | ||
|
|
dc0629ca82 | ||
|
|
ad07fd923b | ||
|
|
8467ebe7fa | ||
|
|
8fb56286fb | ||
|
|
ce9166d9c1 | ||
|
|
90ea1cef3f | ||
|
|
0da08295a4 | ||
|
|
353601ca0c | ||
|
|
48900ed7f8 | ||
|
|
06591077d3 | ||
|
|
4ed16b3d5c | ||
|
|
b347e6c384 | ||
|
|
caacdc5a93 | ||
|
|
a33f332ac4 | ||
|
|
80baae87cd | ||
|
|
4446e73fda | ||
|
|
aa16f6c398 | ||
|
|
9523ade542 | ||
|
|
ca74e17b7b | ||
|
|
1ef95ec1ec | ||
|
|
09c99e7470 | ||
|
|
c63a752de8 | ||
|
|
be3ed10e6c | ||
|
|
c3014c26a1 | ||
|
|
19c5b29c07 | ||
|
|
a2ec91a545 | ||
|
|
86f36af78e | ||
|
|
95242534e0 | ||
|
|
991ef07cf2 | ||
|
|
222ebd01f3 | ||
|
|
08e04e0b14 | ||
|
|
7668473f17 | ||
|
|
ac5693599c | ||
|
|
774f5b9ced | ||
|
|
203cdd9c35 | ||
|
|
2e516f3864 | ||
|
|
be3a90fbc6 | ||
|
|
a567faeafb | ||
|
|
f982f19d32 | ||
|
|
09589a8eb5 | ||
|
|
c1659c2ce3 | ||
|
|
77ba9a609e | ||
|
|
4a50b31d23 | ||
|
|
bcb9c2d133 | ||
|
|
941f44440a | ||
|
|
c63f0b8060 | ||
|
|
e539e08f4e | ||
|
|
5a032af8e9 | ||
|
|
8736b0a17e | ||
|
|
89d990c2e2 | ||
|
|
efd768bf07 | ||
|
|
21b3368d4e | ||
|
|
8ab6159bb8 | ||
|
|
01d6df7de0 | ||
|
|
812225ea41 | ||
|
|
c1bd0098d2 | ||
|
|
2ec38b1072 | ||
|
|
8a8a33fb01 | ||
|
|
d3122af409 | ||
|
|
d9f066e080 | ||
|
|
cd5e0e0595 | ||
|
|
e71d562ce5 | ||
|
|
15473fbc99 | ||
|
|
8e2ddeab80 | ||
|
|
d9780cd28e | ||
|
|
561388cf15 | ||
|
|
9be57b915d | ||
|
|
893248dec7 | ||
|
|
698ebb13b3 | ||
|
|
72d077be1f | ||
|
|
5c22e32db8 | ||
|
|
a0c01b54e8 | ||
|
|
e44a9423a5 | ||
|
|
29825f20c8 | ||
|
|
0df30b49a4 | ||
|
|
6c4998621e | ||
|
|
d596934985 | ||
|
|
99fbd06ae5 | ||
|
|
9d022ff84c | ||
|
|
9f6a211fde | ||
|
|
293c012712 | ||
|
|
0efb81b290 | ||
|
|
415a3d995b | ||
|
|
b33e21abb9 | ||
|
|
c8015c88c3 | ||
|
|
7b608fe1e7 | ||
|
|
ceac176270 | ||
|
|
0851c37a40 | ||
|
|
8726ebfdb6 | ||
|
|
55cc3c57e4 | ||
|
|
2e839a42fa | ||
|
|
4c21a1ac56 | ||
|
|
949f6f1a12 | ||
|
|
7c7e8beed2 | ||
|
|
0bdeb3aa87 | ||
|
|
51742d3ebd | ||
|
|
ed3ba953f2 | ||
|
|
621198c1f6 | ||
|
|
d799721f7e | ||
|
|
32f55e88ff | ||
|
|
9a7bf3aa14 | ||
|
|
a9954dce8b | ||
|
|
411f529242 | ||
|
|
f4e4eae47b | ||
|
|
c0154d3e47 | ||
|
|
b4c997f016 | ||
|
|
a9701e3002 | ||
|
|
51c33b9c51 | ||
|
|
fdb4abb52a | ||
|
|
b42fb9f189 | ||
|
|
ce9e377a38 | ||
|
|
6f20df5d5b | ||
|
|
e044041305 | ||
|
|
800dd50702 | ||
|
|
a92bfa7ac8 | ||
|
|
11f6582235 | ||
|
|
e5108f6b00 | ||
|
|
6f2e7d7d3e | ||
|
|
900e031fd8 | ||
|
|
6700dbba2a | ||
|
|
df1b174583 | ||
|
|
d61a2c981d | ||
|
|
4339bef78c | ||
|
|
588914ecd7 | ||
|
|
151708910e | ||
|
|
3dfe1b7525 | ||
|
|
104d9cc95e | ||
|
|
17bca7547c | ||
|
|
9171c51fbe | ||
|
|
4393caa267 | ||
|
|
c1f68f13f1 | ||
|
|
8a5ad542a6 | ||
|
|
51d1537cbc | ||
|
|
3eaf146612 | ||
|
|
d037290eab | ||
|
|
01d7bc45ac | ||
|
|
9a0a6cec44 | ||
|
|
0587f2ef59 | ||
|
|
62eecdd935 | ||
|
|
5c978ac1bd | ||
|
|
b1780a0947 | ||
|
|
ab40314d51 | ||
|
|
2d9b2fa56e | ||
|
|
e5b023a7ac | ||
|
|
6327220266 | ||
|
|
d65e995648 | ||
|
|
271aaf29e1 | ||
|
|
d3ff6abfc8 | ||
|
|
5c72336705 | ||
|
|
1f83809d25 | ||
|
|
97894e9c80 | ||
|
|
512941c65b | ||
|
|
4e13bee52a | ||
|
|
b67c2f7bc0 | ||
|
|
ba78fbf034 | ||
|
|
ee15ea073e | ||
|
|
798d15b4f0 | ||
|
|
50c28aee45 | ||
|
|
a1751b5f55 | ||
|
|
ed2e038250 | ||
|
|
21eac259b6 | ||
|
|
4fb1e60c02 | ||
|
|
da3fdcc5d1 | ||
|
|
affec24940 | ||
|
|
01ca45b90c | ||
|
|
79d1fd4043 | ||
|
|
a3ea23e5cc | ||
|
|
4ace891cd6 | ||
|
|
e3fc0bcab2 | ||
|
|
f5cb207e7c | ||
|
|
ff3215882e | ||
|
|
89a807b5ef | ||
|
|
eee8dd9f48 | ||
|
|
2e0da6d4ce | ||
|
|
f71db391e6 | ||
|
|
0ca97b07d3 | ||
|
|
be1bad307b | ||
|
|
646c224db0 | ||
|
|
78d3653620 | ||
|
|
ffd8b8a7b9 | ||
|
|
e00caff86e | ||
|
|
f3a9050d3c | ||
|
|
e719e7db87 | ||
|
|
48433b5c93 | ||
|
|
9ed1f665a3 | ||
|
|
9319f7296e | ||
|
|
e6092ef09d | ||
|
|
f8fe0b27ec | ||
|
|
68b51e298d | ||
|
|
cd1391e6a2 | ||
|
|
79aa53ce51 | ||
|
|
9d6ddd727d | ||
|
|
1fdf5c3539 | ||
|
|
31ae114a19 | ||
|
|
9c36b900bf | ||
|
|
f540b1c201 | ||
|
|
3958b2e640 | ||
|
|
dc1e05f9e9 | ||
|
|
df326bea67 | ||
|
|
bf7caf9dda | ||
|
|
821013ee47 | ||
|
|
d06935528e | ||
|
|
1e42ee95b7 | ||
|
|
62dbc54eb2 | ||
|
|
d010b7957c | ||
|
|
5602d90f12 | ||
|
|
0635877a51 | ||
|
|
a75dfe8fd6 | ||
|
|
5719a83f36 | ||
|
|
7e7925484a | ||
|
|
fa806b1612 | ||
|
|
65b338de2b | ||
|
|
d1fdf38e7d | ||
|
|
4d84706d7f | ||
|
|
f559dfbbb7 | ||
|
|
02c3a18f79 | ||
|
|
08c080948e | ||
|
|
d6ba326433 | ||
|
|
5a0f033159 | ||
|
|
0c7feaaa1f | ||
|
|
a35c027551 | ||
|
|
60a77bdccf | ||
|
|
cf25379010 | ||
|
|
d064e122b3 | ||
|
|
c6e39ee5ac | ||
|
|
cf077230d7 | ||
|
|
28966a4dcd | ||
|
|
a8826667d0 | ||
|
|
4a565107bc | ||
|
|
a88c62f190 | ||
|
|
65875d9afe | ||
|
|
61df1eb1dc | ||
|
|
5fdb2109f4 | ||
|
|
35997f0256 | ||
|
|
fcbd6015bd | ||
|
|
5b3eb0e5f7 | ||
|
|
c56583b6a6 | ||
|
|
65f0d1733b | ||
|
|
9b13c34889 | ||
|
|
7e7b4b2cf7 | ||
|
|
0be6682252 | ||
|
|
0cd7acb59d | ||
|
|
366edc023a | ||
|
|
ecc2b6fe8c | ||
|
|
dbe6d3ab4c | ||
|
|
ffbd9d91f1 | ||
|
|
368ee9422f | ||
|
|
aebe2fac95 | ||
|
|
fdd8dbf5e5 | ||
|
|
e0925a20a8 | ||
|
|
d1b06abdf5 | ||
|
|
3962d6e472 | ||
|
|
cb6224df4b | ||
|
|
fc5883d7ec | ||
|
|
c75492ffe2 | ||
|
|
7bfbf0aae0 | ||
|
|
96d99e6c0a | ||
|
|
66b7ee81ad | ||
|
|
5d9978e6bb | ||
|
|
37b2569038 | ||
|
|
0265e3eb6e | ||
|
|
7e187485ea | ||
|
|
a4204a3d1f | ||
|
|
cba0e82c7d | ||
|
|
7bf9fa6347 | ||
|
|
d745644d83 | ||
|
|
1749f5838c | ||
|
|
62d61ada74 | ||
|
|
d8201c2752 | ||
|
|
422b0d19f7 | ||
|
|
3e12f86dcd | ||
|
|
d2acc97493 | ||
|
|
0a4758acf4 | ||
|
|
cfc141b1c7 | ||
|
|
bbe758b0eb | ||
|
|
69935c5bbf | ||
|
|
8cbc4aea41 | ||
|
|
eb8a524a29 | ||
|
|
b9dfe0b37a | ||
|
|
1244e31313 | ||
|
|
62d751ba0c | ||
|
|
6908d35db5 | ||
|
|
ae1cdbbb93 | ||
|
|
e765b4bcee | ||
|
|
4b6e374e53 | ||
|
|
59aaacaeba | ||
|
|
4bbe1c0008 | ||
|
|
b1191a5c06 | ||
|
|
74fea6a911 | ||
|
|
f91b2a3950 | ||
|
|
c7a5a6a1c9 | ||
|
|
a5c20a9d11 | ||
|
|
cc73030560 | ||
|
|
d9f289be97 | ||
|
|
e44bcaa7e4 | ||
|
|
0d00aaf011 | ||
|
|
b855525615 | ||
|
|
9fdf0d501d | ||
|
|
40c98fe4d0 | ||
|
|
5cd7959d9e | ||
|
|
9f8f7dcf7d | ||
|
|
40bb200589 | ||
|
|
d5dbb2e592 | ||
|
|
3eb57c1888 | ||
|
|
3e94a89004 | ||
|
|
57ff27f382 | ||
|
|
1ce3bb3e8d | ||
|
|
7445b57807 | ||
|
|
c5a8e37ce6 | ||
|
|
afabf00b5d | ||
|
|
73596f0ba8 | ||
|
|
4d228baa57 | ||
|
|
75cc1466c2 | ||
|
|
0df8baefce | ||
|
|
e8f0081a46 | ||
|
|
4f8777546a | ||
|
|
26ff2defe7 | ||
|
|
0c70f7e7e8 | ||
|
|
1b0842743c | ||
|
|
3337e6072b | ||
|
|
2c8eabf99b | ||
|
|
9f5725d4e7 | ||
|
|
ad8974472d | ||
|
|
27975606f1 | ||
|
|
58e784e7f9 | ||
|
|
f8ef94c7e3 | ||
|
|
f3170e7aad | ||
|
|
902d3f3287 | ||
|
|
f4a7ed76f5 | ||
|
|
57c23a30db | ||
|
|
66bebf66fb | ||
|
|
0e5187daf6 | ||
|
|
e779feb1cb | ||
|
|
57783a3951 | ||
|
|
b9131c3b94 | ||
|
|
5896850b5b | ||
|
|
14447cb6ae | ||
|
|
c114879df1 | ||
|
|
07cfe19095 | ||
|
|
3b6dfc891f | ||
|
|
d9eb022e3d | ||
|
|
af0bb31c6a | ||
|
|
9225bc30b5 | ||
|
|
617c0e4618 | ||
|
|
88f040c429 | ||
|
|
7404e759a9 | ||
|
|
5851bab344 | ||
|
|
f8d6de2095 | ||
|
|
c99d1f1000 | ||
|
|
bfb15c9776 | ||
|
|
64d5f8eafa | ||
|
|
e5f7c8b432 | ||
|
|
222edae961 | ||
|
|
64d96f071f | ||
|
|
4b5e09de8d | ||
|
|
4d58dfe421 | ||
|
|
f178e9aa61 | ||
|
|
f4dad67454 | ||
|
|
fa7bc2629d | ||
|
|
341ad18eb6 | ||
|
|
c28f73b647 | ||
|
|
7f5735b968 | ||
|
|
97be25e89a | ||
|
|
98627f6d46 | ||
|
|
17ebf07ad3 | ||
|
|
4bd34c4500 | ||
|
|
b619f01809 | ||
|
|
71a76806d2 | ||
|
|
5d2d5b2604 | ||
|
|
12c792147e | ||
|
|
3ed9ce3cb5 | ||
|
|
a6f68b2d37 | ||
|
|
4d0e873c88 | ||
|
|
a681ea9eb9 | ||
|
|
06abba27a9 | ||
|
|
d29ce1d174 | ||
|
|
f743aa009b | ||
|
|
543e0fbd24 | ||
|
|
dab82feb78 | ||
|
|
1514d28dc4 | ||
|
|
71c84a2a44 | ||
|
|
45d692d7dd | ||
|
|
229b0de3c6 | ||
|
|
bdf819bea3 | ||
|
|
e924c57296 | ||
|
|
c65400c586 | ||
|
|
e91b630e8a | ||
|
|
4669c67bc4 | ||
|
|
6a6cc8228a | ||
|
|
1afb9b543d | ||
|
|
dc3b34510b | ||
|
|
a145a3ec32 | ||
|
|
41ed04e977 | ||
|
|
dde03eaec4 | ||
|
|
772eea09c7 | ||
|
|
fd1312803f | ||
|
|
efcc8c5cb2 | ||
|
|
d271e92b8e | ||
|
|
413e816c98 | ||
|
|
1405600919 | ||
|
|
f22eeb179b | ||
|
|
db2ef44617 | ||
|
|
7aad7ba116 | ||
|
|
f6b4991374 | ||
|
|
2e26942ecd | ||
|
|
696b3438b8 | ||
|
|
2e3ccfb345 | ||
|
|
a16903009e | ||
|
|
eb45d197ea | ||
|
|
c732855902 | ||
|
|
8cd0a08946 | ||
|
|
0f72c80e79 | ||
|
|
02f15e6b92 | ||
|
|
7189020e53 | ||
|
|
cf92a79529 | ||
|
|
1ca51cbd5c | ||
|
|
502ae06f9d | ||
|
|
9fd07f814d | ||
|
|
9f847ac4bf | ||
|
|
7f394da335 | ||
|
|
aa5c4f9595 | ||
|
|
b0ed0fb0ec | ||
|
|
632cd36e63 | ||
|
|
b72d18fd44 | ||
|
|
209170e813 | ||
|
|
711d2d7413 | ||
|
|
1e001d2d82 | ||
|
|
e3f0b2c6f5 | ||
|
|
a222b3898b | ||
|
|
27a773031c | ||
|
|
44110dbc79 | ||
|
|
0c9afc8561 | ||
|
|
6e84d677e6 | ||
|
|
3b724b39aa | ||
|
|
40a7cbf96f | ||
|
|
68443b61c0 | ||
|
|
a7b2c2e348 | ||
|
|
695f4fc374 | ||
|
|
3e81ed7740 | ||
|
|
ef576ed5b1 | ||
|
|
105130ddb8 | ||
|
|
c8038fde32 | ||
|
|
af07048c27 | ||
|
|
3b8ed6ec96 | ||
|
|
d6b639b288 | ||
|
|
a5efd5d028 | ||
|
|
c8bb01c76d | ||
|
|
92c56889a3 | ||
|
|
7be38406da | ||
|
|
3df3e8ebd1 | ||
|
|
78a6a8e8aa | ||
|
|
e2144a1d67 | ||
|
|
14d9e7ce80 | ||
|
|
553fb4d05c | ||
|
|
d37bcfa82f | ||
|
|
a4a235cd67 | ||
|
|
057eae84c5 | ||
|
|
461495d46d | ||
|
|
096c7d58d1 | ||
|
|
ca840b2220 | ||
|
|
9ee150b359 | ||
|
|
c09332ce1d | ||
|
|
59b999c9ed | ||
|
|
77a59bbd76 | ||
|
|
4b3ee16bff | ||
|
|
7851c6bc05 | ||
|
|
ef54d487d0 | ||
|
|
6967fe1066 | ||
|
|
650184dc0d | ||
|
|
f0b4a173a5 | ||
|
|
f40d5ff36b | ||
|
|
6102acb9af | ||
|
|
122f969462 | ||
|
|
7051b2c786 | ||
|
|
aa27737d24 | ||
|
|
5f0aecfd5e | ||
|
|
fcba79f070 | ||
|
|
a1743d7e58 | ||
|
|
20ce55933e | ||
|
|
564c425ad7 | ||
|
|
16d6ec150d | ||
|
|
edad25b8f6 | ||
|
|
fb111e585a | ||
|
|
35ef2b0b2d |
45
.eslintrc
45
.eslintrc
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"extends": ["eslint-config-airbnb"],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"jest": true,
|
||||
"es6": true
|
||||
},
|
||||
"ecmaFeatures": {
|
||||
"jsx": true,
|
||||
"experimentalObjectRestSpread": true
|
||||
},
|
||||
"plugins": [
|
||||
"markdown-antd",
|
||||
"react",
|
||||
"babel"
|
||||
],
|
||||
"rules": {
|
||||
"constructor-super": 2,
|
||||
"comma-dangle": 0,
|
||||
"func-names": 0,
|
||||
"guard-for-in": 0,
|
||||
"one-var": [2, { "initialized": "never" }],
|
||||
"prefer-const": 0,
|
||||
"key-spacing": 0,
|
||||
"no-eq-null": 0,
|
||||
"no-else-return": 0,
|
||||
"no-param-reassign": 0,
|
||||
"no-this-before-super": 2,
|
||||
"no-undef": 2,
|
||||
"babel/object-shorthand": 0,
|
||||
"react/jsx-no-duplicate-props": 2,
|
||||
"react/sort-comp": 0,
|
||||
"react/wrap-multilines": 0,
|
||||
"react/no-multi-comp": 0,
|
||||
"react/prop-types": 0,
|
||||
"space-after-keywords": 0,
|
||||
"space-before-blocks": 0,
|
||||
"space-before-function-paren": 0,
|
||||
"spaced-comment": 0,
|
||||
"vars-on-top": 0,
|
||||
"id-length": 0
|
||||
}
|
||||
}
|
||||
38
.eslintrc.json
Normal file
38
.eslintrc.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"extends": ["eslint-config-airbnb"],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"jest": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaFeatures": {
|
||||
"jsx": true,
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"markdown",
|
||||
"react",
|
||||
"babel"
|
||||
],
|
||||
"rules": {
|
||||
"comma-dangle": 0,
|
||||
"func-names": 0,
|
||||
"prefer-const": 0,
|
||||
"arrow-body-style": 0,
|
||||
"react/sort-comp": 0,
|
||||
"react/no-multi-comp": 0,
|
||||
"react/prop-types": 0,
|
||||
"react/prefer-es6-class": 0,
|
||||
"react/jsx-closing-bracket-location": 0,
|
||||
"react/jsx-no-bind": 0,
|
||||
"no-param-reassign": 0,
|
||||
"no-return-assign": 0,
|
||||
"max-len": 0,
|
||||
"consistent-return": 0
|
||||
}
|
||||
}
|
||||
10
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
10
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
@@ -13,7 +13,7 @@ The following guidelines are about *How to avoid Homework Questions*.
|
||||
|
||||
### 1. Read the documentation.
|
||||
|
||||
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 [JSFiddle](http://jsfiddle.net/9zrstuto/70/). It's helpful to understand our documentation.
|
||||
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/anon/pen/pgdXYp?editors=001). It's helpful to understand our documentation.
|
||||
|
||||
Tips: choose the corresponding documentation with versions selector which in the bottom-right corner.
|
||||
|
||||
@@ -26,13 +26,17 @@ Someone may think all of the questions that he/she meets in developing are about
|
||||
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.
|
||||
|
||||
P.S.
|
||||
|
||||
1. [FAQ](https://github.com/ant-design/ant-design/wiki/FAQ)
|
||||
1. [Issues list](https://github.com/ant-design/ant-design/issues)
|
||||
|
||||
## Close your issue if it's solved
|
||||
|
||||
It is a good habit which will save maintainers' time. Thank you!
|
||||
|
||||
## Providing a demo while reporting a bug
|
||||
|
||||
It would be helpful to provide a demo which can re-produce the bug 100%. Please fork this [Fiddle](http://jsfiddle.net/0dso5y0x/) and re-produce the bug you met. Then, create an issue like this [example](https://github.com/ant-design/ant-design/issues/new?title=%E8%AF%B7%E5%A1%AB%E5%86%99%E7%AE%80%E6%B4%81%E6%9C%89%E6%95%88%E7%9A%84%E6%A0%87%E9%A2%98&body=**%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0**%0A%0A%EF%BC%88%E6%8F%8F%E8%BF%B0%E4%B8%80%E4%B8%8B%E9%97%AE%E9%A2%98%EF%BC%89%0A%0A**%E5%8F%91%E7%94%9F%E7%8E%AF%E5%A2%83**%0A%0A-%20antd%20%E7%89%88%E6%9C%AC%EF%BC%9A%0A-%20%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%8F%8A%E7%89%88%E6%9C%AC%EF%BC%9A%0A-%20%E6%B5%8F%E8%A7%88%E5%99%A8%E5%8F%8A%E7%89%88%E6%9C%AC%EF%BC%9A%0A-%20%E5%9C%A8%E7%BA%BF%E6%BC%94%E7%A4%BA%E5%9C%B0%E5%9D%80%EF%BC%9A%0A%0A**%E9%87%8D%E7%8E%B0%E6%AD%A5%E9%AA%A4**%0A%0A1.%20...%0A2.%20...%0A). The most important thing is: double check before claiming that you have found a bug.
|
||||
It would be helpful to provide a demo which can re-produce the bug 100%. Please fork this [CodePen](http://codepen.io/anon/pen/pgdXYp?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.
|
||||
|
||||
|
||||
## Tips about Feature Request
|
||||
@@ -46,7 +50,7 @@ If you believe that Ant Design should provide some features, but it does not. Yo
|
||||
|
||||
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 disscuss whether the feature is necessary before you implement it.
|
||||
1. It is a good habit to create a feature request issue to disscuss 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 documentaion, 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.
|
||||
25
.github/ISSUE_TEMPLATE.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
If you want to ask a question, please read [some tips](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md#do-your-homework-before-asking-a-question) first :-)
|
||||
|
||||
If you are going to report a bug, please answer the following questions, thank you!
|
||||
|
||||
## What you did
|
||||
|
||||
(e.g. I ate a hamburger)
|
||||
|
||||
## What you would like to happen
|
||||
|
||||
(e.g. I should be full)
|
||||
|
||||
## What actually happened
|
||||
|
||||
(e.g. But I am still hungry now T_T)
|
||||
|
||||
## Online demo
|
||||
|
||||
(e.g. http://codepen.io/anon/pen/pgdXYp?editors=001)
|
||||
|
||||
## Environment Information
|
||||
|
||||
- The version of antd(e.g. 0.12.0):
|
||||
- Your operating system and it's version(e.g. OSX 10.11.0):
|
||||
- Your browser and it's version(e.g. Chrome 48.0.0.0(64-bit)):
|
||||
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
First of all, thanks for your contribution! :-)
|
||||
|
||||
Please makes sure these boxes are checked before submitting your PR, thank you!
|
||||
|
||||
[ ] Run `npm run lint` and fix those errors before submitting in order to keep consistent code style.
|
||||
[ ] Rebase before creating a PR to keep commit history clear.
|
||||
[ ] Add some descriptions and refer relative issues for you PR.
|
||||
6
.si.yml
6
.si.yml
@@ -1,6 +0,0 @@
|
||||
before_deploy:
|
||||
- tnpm install && tnpm update
|
||||
- tnpm run just-deploy
|
||||
options:
|
||||
branch: 'master'
|
||||
dist: '_site'
|
||||
151
CHANGELOG.md
151
CHANGELOG.md
@@ -4,13 +4,158 @@
|
||||
|
||||
---
|
||||
|
||||
## 0.11.3 `fixing`
|
||||
## 0.12.7
|
||||
|
||||
`2016-03-03`
|
||||
|
||||
- 修正 Table 的 `rowSelect.onSelectAll` 的第三个参数 `deselectedRows` 为 `changeRows`,记录每次变化的列。
|
||||
|
||||
## 0.12.6
|
||||
|
||||
`2016-03-02`
|
||||
|
||||
- 优化 Table 本地排序在 Chrome 下的稳定性问题。
|
||||
- 修正 Pagination 的 pageSize 属性为受控属性,并补充了 `defaultPageSize` 属性。[#1087](https://github.com/ant-design/ant-design/issues/1087)
|
||||
- 优化 Select 的 combobox 模式的交互体验。
|
||||
- 升级 react-slick 依赖到 `0.11`,修复自动播放有时会失效的问题。[#1009](https://github.com/ant-design/ant-design/issues/1009)
|
||||
- 修复 TreeSelect 的 allowClear 属性失效的问题。[#1084](https://github.com/ant-design/ant-design/issues/1084)
|
||||
- 修复 Input 组件的 className 属性失效的问题。[#1103](https://github.com/ant-design/ant-design/issues/1103)
|
||||
- 修复 Dropdown 的 onClick 属性失效的问题。[#1097](https://github.com/ant-design/ant-design/issues/1097)
|
||||
- 修复多个 CheckboxGroup 选项互相影响的问题。[#1101](https://github.com/ant-design/ant-design/pull/1101)
|
||||
- 修复 FormItem 的子元素为 `null` 时报错的问题。
|
||||
- 修复 Table 组件的选择功能和展开功能配合使用的问题。[#1102](https://github.com/ant-design/ant-design/issues/1102)
|
||||
- 增加了一个搜索框和提示功能结合的 [例子](http://ant.design/components/select/#demo-search-box)。
|
||||
- 允许可编辑的 Tabs 删除最后一个页签。[#1071](https://github.com/ant-design/ant-design/issues/1071)
|
||||
- Table 的 `rowSelect.onSelectAll` 补充了第三个参数 `deselectedRows`, `rowSelect.onChange` 补充了第二个参数 `selectedRows`。[#1105](https://github.com/ant-design/ant-design/issues/1105)
|
||||
- 修复了部分组件样式的小问题。
|
||||
|
||||
## 0.12.5
|
||||
|
||||
`2016-02-25`
|
||||
|
||||
- Pagination 支持 `showTotal` 属性。[#1077](https://github.com/ant-design/ant-design/pull/1077)
|
||||
- Cascader 添加 `allowClear` 属性,允许隐藏清除按钮。
|
||||
- 补充了一个带图标的搜索建议框的例子。[#1067](https://github.com/ant-design/ant-design/issues/1067)
|
||||
- 修复 Transfer 在不支持 Object.assign 的浏览器上报错的问题。
|
||||
- 修复 Cascader 在 Safari 下错位的问题。[#1066](https://github.com/ant-design/ant-design/issues/1066)
|
||||
- 移除对 Button 圆角的降级方案。
|
||||
- 修复了部分组件样式的小问题。
|
||||
|
||||
## 0.12.4
|
||||
|
||||
`2016-02-22`
|
||||
|
||||
- Radio 的 value 支持更多类型。[#1043](https://github.com/ant-design/ant-design/pull/1043)
|
||||
- 修复 Spin 组件的大小、居中等样式问题。
|
||||
- FormItem 补充 extra 属性的文档。[#931](https://github.com/ant-design/ant-design/issues/931)
|
||||
- 修复的 Table 下树形数据和选择框配合时的样式问题。
|
||||
- 修复一个水平表单的错误提示的样式错位问题。[#1040](https://github.com/ant-design/ant-design/issues/1040)
|
||||
- 添加了一个轻微的 Button 点击动效。
|
||||
|
||||
## 0.12.3
|
||||
|
||||
`2016-02-19`
|
||||
|
||||
- DatePicker 补充 allowClear 属性,支持单选的清空。
|
||||
- 修复显示时间的 DatePicker 的清空按钮失效的问题。
|
||||
- 优化 DatePicker 的 `确定` 按钮失效样式。
|
||||
|
||||
## 0.12.2
|
||||
|
||||
`2016-02-19`
|
||||
|
||||
- DatePicker 如果有 `确定` 按钮,现在只有点击 `确定` 按钮才会触发 onChange 事件。
|
||||
- 修复带时间选择的 DatePicker 日期格式缺少时间部分的问题。[#1005](https://github.com/ant-design/ant-design/issues/1005)
|
||||
- 修复 DatePicker 内输入框多余的时间展示的问题。[#953](https://github.com/ant-design/ant-design/issues/953)
|
||||
- 升级依赖 react-slick 到 `0.10`。
|
||||
- 支持表单校验错误时自动滚动到第一个错误项。[#993](https://github.com/ant-design/ant-design/issues/993)
|
||||
- 优化了 Select 和 TreeSelect 多选禁用的样式。
|
||||
- Upload 列表项支持链接展现形式。[#1013](https://github.com/ant-design/ant-design/issues/1013)
|
||||
- 修复 Safari 下的样式警告信息。[#999](https://github.com/ant-design/ant-design/issues/999)
|
||||
- Cascader 支持 popupPlacement 位置配置。
|
||||
|
||||
## 0.12.1
|
||||
|
||||
`2016-02-03`
|
||||
|
||||
- 依赖升级到 `rc-pagination@1.4`、`rc-menu@4.10`、`rc-form@0.12`。
|
||||
- 修复 TreeSelect 的不可用样式。
|
||||
- DatePicker 补充 `getCalendarContainer` 属性,用于解决问题 [#991](https://github.com/ant-design/ant-design/issues/991)。
|
||||
- 修正 Modal `onCancel` 的参数为点击事件。[#980](https://github.com/ant-design/ant-design/issues/980)
|
||||
- 修复一个 Tooltip 内嵌套 Popconfirm 的问题。[#977](https://github.com/ant-design/ant-design/issues/977)
|
||||
- 修复 DatePicker 和 RangePicker 的 `onOk` 一直不可用的问题。
|
||||
- 修复一个 Badge 的 count 无法切换的问题。[#983](https://github.com/ant-design/ant-design/issues/983)
|
||||
|
||||
## 0.12.0
|
||||
|
||||
`2016-02-01`
|
||||
|
||||
- 新增 [级联选择(Cascader)](http://ant.design/components/cascader/) 组件。
|
||||
- 新增 [树选择控件(TreeSelect)](http://ant.design/components/tree-select/) 组件。
|
||||
- Form 自身支持校验功能,废弃 Validation。[演示](http://ant.design/components/form/#demo-validate-basic)
|
||||
- Tabs
|
||||
- `activeKey` 修正为受控属性。
|
||||
- 当前项现在会始终显示。[#815](https://github.com/ant-design/ant-design/issues/815)
|
||||
- Modal 可以配置右上关闭按钮是否显示。
|
||||
- Select
|
||||
- 打开选项菜单时,自动滚动到选中项。
|
||||
- `combobox` 模式时,可配置是否默认选中第一项。[rc-select#38](https://github.com/react-component/select/issues/38)
|
||||
- Table
|
||||
- filter 支持层级选择。
|
||||
- 支持行点击事件 `onRowClick`。
|
||||
- 支持多列的横向切换。[演示](http://ant.design/components/table/#demo-paging-columns)
|
||||
- 更换 `dataSource` 和变换页面时不再默认清除选择数据,你可以用 `selectedRowKeys` 手动控制。`原来默认清除的行为会触发一个数据更新的死循环,而且难以实现跨页选择。`
|
||||
- 支持固定表头。[演示](http://ant.design/components/table/#demo-fixed-header)
|
||||
- Tag 去除 `href` 属性,默认标签名从 `a` 改为 `span`。
|
||||
- Timeline 支持指定 pending 节点的内容。
|
||||
- Tree
|
||||
- 节点支持拖拽。
|
||||
- 支持动态控制节点展开与否。[演示](http://ant.design/components/tree/#demo-basic-controlled)
|
||||
- 可以监听节点展开/关闭事件 `onExpand`。
|
||||
- `onCheck` `onSelect` 参数调整。
|
||||
- `onDataLoaded` 改为 `loadData`。
|
||||
- 新增 drag&drop 相关属性:
|
||||
- `onDragStart`
|
||||
- `onDragEnter`
|
||||
- `onDragOver`
|
||||
- `onDragLeave`
|
||||
- `onDrop`
|
||||
- 新增 TreeNode 节点属性:
|
||||
- `disableCheckbox`
|
||||
- `isLeaf`
|
||||
- Transfer 给 `onChange` 增加参数。[#972](https://github.com/ant-design/ant-design/issues/972)
|
||||
- DatePicker
|
||||
- 修复 RangePicker 开始结束日期相同的 bug。[#822](https://github.com/ant-design/ant-design/issues/822)
|
||||
- 修复 `format` 对浮层不生效问题。[#917](https://github.com/ant-design/ant-design/issues/917)
|
||||
- TimePicker 修复一个 `value` 为 `null` 时没有进入受控模式的问题。
|
||||
- Upload
|
||||
- 可以用 `headers` 设置上传头部。
|
||||
- 新增上传图片卡片样式。[演示](http://ant.design/components/upload/#demo-picture-card)
|
||||
- Radio
|
||||
- 更换 Radio.Button 的展现样式。
|
||||
- 可以设置 Radio.Button 的大小。
|
||||
- Progress
|
||||
- `format` 属性现在支持自定义 function 的方式进行定义。[#893](https://github.com/ant-design/ant-design/issues/893)
|
||||
- `format` 指定 string 和 React.Node 的方式被废弃。
|
||||
- 支持 `style` 属性。[#895](https://github.com/ant-design/ant-design/issues/895)
|
||||
- message && notification 现在可以销毁。
|
||||
- Button
|
||||
- 小号 Button 的圆角调整为 `4px`。
|
||||
- 修复 Button.Group disabled 后的样式问题。[#926](https://github.com/ant-design/ant-design/issues/926)
|
||||
- BreadCrumb
|
||||
- 移除 `router` 属性,无需设置。
|
||||
- 修复一个链接参数不对的问题。
|
||||
|
||||
## 0.11.3
|
||||
|
||||
`2016-01-19`
|
||||
|
||||
- 修复 TimePicker 受控模式点选即关闭面板的问题。[#818](https://github.com/ant-design/ant-design/issues/818)
|
||||
- 修复一个两栏的 TimePicker 点击右边空白处无法关闭面板的问题。[#826](https://github.com/ant-design/ant-design/issues/826)
|
||||
- 修复 Table `pagination.onChange` 指定无效的问题。[#824](https://github.com/ant-design/ant-design/issues/824)
|
||||
- 修复 Transfer 搜索功能失效的问题。
|
||||
- 修复 DatePicker 的 MonthPicker 样式错乱的问题。
|
||||
- 修复 RangePicker 时区无法设置的问题。[#837](https://github.com/ant-design/ant-design/issues/837)
|
||||
- 修复二维码图标,新增一个扫描图标。[#772](https://github.com/ant-design/ant-design/issues/772)
|
||||
|
||||
## 0.11.2
|
||||
@@ -114,7 +259,7 @@
|
||||
- 新增 babel 插件 [babel-plugin-antd](https://github.com/ant-design/babel-plugin-antd),转换 `import {Button} from 'antd'` 为 `import Button from 'antd/lib/button'`。
|
||||
- 发布了 `antd-init@0.6.x`,支持以上改动。
|
||||
|
||||
> [0.11 升级指南](http://ant.design/docs/upgrade-notes#0-10-gt-0-11)
|
||||
> [0.11 升级指南](http://ant.design/docs/react/upgrade-notes#0-10-gt-0-11)
|
||||
|
||||
---
|
||||
|
||||
@@ -240,7 +385,7 @@
|
||||
> 备注:
|
||||
>
|
||||
> - [计划和推进 issue](https://github.com/ant-design/ant-design/issues/276)
|
||||
> - [0.10 升级指南](http://ant.design/docs/upgrade-notes#0-0-gt-0-10)
|
||||
> - [0.10 升级指南](http://010x.ant.design/docs/upgrade-to-0.10)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Ant Design [](https://travis-ci.org/ant-design/ant-design) [](https://www.npmjs.org/package/antd) [](https://npmjs.org/package/antd) [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# Ant Design [](https://travis-ci.org/ant-design/ant-design) [](https://www.npmjs.org/package/antd) [](https://npmjs.org/package/antd) [](https://david-dm.org/ant-design/ant-design) [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
一套企业级的 UI 设计语言和 React 实现。
|
||||
|
||||
@@ -41,13 +41,15 @@ import 'antd/lib/index.css'; // or 'antd/style/index.less'
|
||||
|
||||
现代浏览器和 IE8 及以上。
|
||||
|
||||
> [IE8 issues](https://github.com/xcatliu/react-ie8)
|
||||
|
||||
## 链接
|
||||
|
||||
- [首页](http://ant.design/)
|
||||
- [React UI 库](http://ant.design/docs/react/introduce)
|
||||
- [修改记录](CHANGELOG.md)
|
||||
- [开发脚手架](https://github.com/ant-design/antd-init/)
|
||||
- [本地调试工具集](https://github.com/dora-js/dora/)
|
||||
- [开发工具文档](http://ant-tool.github.io/)
|
||||
- [React 组件](http://react-component.github.io/)
|
||||
- [React 代码规范](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-code-style.md)
|
||||
- [组件设计原则](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-design.md)
|
||||
|
||||
10
README.md
10
README.md
@@ -4,15 +4,15 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Ant Design [](https://travis-ci.org/ant-design/ant-design) [](https://www.npmjs.org/package/antd) [](https://npmjs.org/package/antd) [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# Ant Design [](https://travis-ci.org/ant-design/ant-design) [](https://www.npmjs.org/package/antd) [](https://npmjs.org/package/antd) [](https://david-dm.org/ant-design/ant-design) [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
An enterprise-class UI design language and React-based implementation.
|
||||
|
||||
## Features
|
||||
|
||||
- An enterprise-class graphical design language and framework for financial applications.
|
||||
- An enterprise-class design language and high quality UI style.
|
||||
- Rich library of UI components base on [React Component](http://react-component.github.io/badgeboard/).
|
||||
- A npm + webpack + babel workflow, supporting ES2015.
|
||||
- A npm + webpack + babel + dora [workflow](http://ant-tool.github.io/index.html).
|
||||
|
||||
## Install
|
||||
|
||||
@@ -40,6 +40,7 @@ Use components on demand by writing as `import DatePicker from 'antd/lib/date-pi
|
||||
|
||||
Normal browsers and Internet Explorer 8+.
|
||||
|
||||
> [IE8 issues](https://github.com/xcatliu/react-ie8)
|
||||
|
||||
## Links
|
||||
|
||||
@@ -47,12 +48,13 @@ Normal browsers and Internet Explorer 8+.
|
||||
- [React UI library](http://ant.design/docs/react/introduce)
|
||||
- [ChangeLog](CHANGELOG.md)
|
||||
- [Scaffold tool](https://github.com/ant-design/antd-init/)
|
||||
- [Debug tools set](https://github.com/dora-js/dora)
|
||||
- [Development tool](http://ant-tool.github.io/)
|
||||
- [React components](http://react-component.github.io/)
|
||||
- [React style guide](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-code-style.md)
|
||||
- [React component design guide](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-design.md)
|
||||
- [Developer Instruction](https://github.com/ant-design/ant-design/wiki/%E7%BD%91%E7%AB%99%E5%92%8C%E7%BB%84%E4%BB%B6%E5%BC%80%E5%8F%91%E8%AF%B4%E6%98%8E)
|
||||
- [Versioning Release Note](https://github.com/ant-design/ant-design/wiki/%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)
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -4,14 +4,14 @@ import rcUtil from 'rc-util';
|
||||
import classNames from 'classnames';
|
||||
|
||||
function getScroll(w, top) {
|
||||
let ret = w['page' + (top ? 'Y' : 'X') + 'Offset'];
|
||||
let method = 'scroll' + (top ? 'Top' : 'Left');
|
||||
let ret = w[`page${top ? 'Y' : 'X'}Offset`];
|
||||
let method = `scroll${top ? 'Top' : 'Left'}`;
|
||||
if (typeof ret !== 'number') {
|
||||
let d = w.document;
|
||||
//ie6,7,8 standard mode
|
||||
// ie6,7,8 standard mode
|
||||
ret = d.documentElement[method];
|
||||
if (typeof ret !== 'number') {
|
||||
//quirks mode
|
||||
// quirks mode
|
||||
ret = d.body[method];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
const onClose = function(e) {
|
||||
const onClose = function (e) {
|
||||
console.log(e, '我要被关闭啦!');
|
||||
};
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ export default React.createClass({
|
||||
handleClose(e) {
|
||||
e.preventDefault();
|
||||
let dom = ReactDOM.findDOMNode(this);
|
||||
dom.style.height = dom.offsetHeight + 'px';
|
||||
dom.style.height = `${dom.offsetHeight}px`;
|
||||
// Magic code
|
||||
// 重复一次后才能正确设置 height
|
||||
dom.style.height = dom.offsetHeight + 'px';
|
||||
dom.style.height = `${dom.offsetHeight}px`;
|
||||
|
||||
this.setState({
|
||||
closing: false
|
||||
@@ -44,20 +44,20 @@ export default React.createClass({
|
||||
|
||||
let iconType = '';
|
||||
switch (type) {
|
||||
case 'success':
|
||||
iconType = 'check-circle';
|
||||
break;
|
||||
case 'info':
|
||||
iconType = 'info-circle';
|
||||
break;
|
||||
case 'error':
|
||||
iconType = 'exclamation-circle';
|
||||
break;
|
||||
case 'warn':
|
||||
iconType = 'exclamation-circle';
|
||||
break;
|
||||
default:
|
||||
iconType = 'default';
|
||||
case 'success':
|
||||
iconType = 'check-circle';
|
||||
break;
|
||||
case 'info':
|
||||
iconType = 'info-circle';
|
||||
break;
|
||||
case 'error':
|
||||
iconType = 'exclamation-circle';
|
||||
break;
|
||||
case 'warn':
|
||||
iconType = 'exclamation-circle';
|
||||
break;
|
||||
default:
|
||||
iconType = 'default';
|
||||
}
|
||||
|
||||
// use outline icon in alert with description
|
||||
@@ -67,10 +67,10 @@ export default React.createClass({
|
||||
|
||||
let alertCls = classNames({
|
||||
[prefixCls]: true,
|
||||
[prefixCls + '-' + type]: true,
|
||||
[prefixCls + '-close']: !this.state.closing,
|
||||
[prefixCls + '-with-description']: !!description,
|
||||
[prefixCls + '-no-icon']: !showIcon,
|
||||
[`${prefixCls}-${type}`]: true,
|
||||
[`${prefixCls}-close`]: !this.state.closing,
|
||||
[`${prefixCls}-with-description`]: !!description,
|
||||
[`${prefixCls}-no-icon`]: !showIcon,
|
||||
});
|
||||
|
||||
// closeable when closeText is assigned
|
||||
@@ -80,14 +80,14 @@ export default React.createClass({
|
||||
|
||||
return this.state.closed ? null : (
|
||||
<Animate component=""
|
||||
showProp="data-show"
|
||||
transitionName="slide-up"
|
||||
onEnd={this.animationEnd}>
|
||||
showProp="data-show"
|
||||
transitionName="slide-up"
|
||||
onEnd={this.animationEnd}>
|
||||
<div data-show={this.state.closing} className={alertCls}>
|
||||
{showIcon ? <Icon className="ant-alert-icon" type={iconType} /> : null}
|
||||
<span className={prefixCls + '-message'}>{message}</span>
|
||||
<span className={prefixCls + '-description'}>{description}</span>
|
||||
{closable ? <a onClick={this.handleClose} className={prefixCls + '-close-icon'}>
|
||||
<span className={`${prefixCls}-message`}>{message}</span>
|
||||
<span className={`${prefixCls}-description`}>{description}</span>
|
||||
{closable ? <a onClick={this.handleClose} className={`${prefixCls}-close-icon`}>
|
||||
{closeText || <Icon type="cross" />}
|
||||
</a> : null}
|
||||
</div>
|
||||
|
||||
@@ -26,21 +26,18 @@ class AntScrollNumber extends React.Component {
|
||||
if (this.state.count > this.lastCount) {
|
||||
if (currentDigit >= lastDigit) {
|
||||
return 10 + num;
|
||||
} else {
|
||||
return 20 + num;
|
||||
}
|
||||
} else {
|
||||
if (currentDigit <= lastDigit) {
|
||||
return 10 + num;
|
||||
} else {
|
||||
return num;
|
||||
}
|
||||
return 20 + num;
|
||||
}
|
||||
if (currentDigit <= lastDigit) {
|
||||
return 10 + num;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('count' in nextProps && nextProps.count) {
|
||||
if (this.lastCount === this.state.count) {
|
||||
if ('count' in nextProps) {
|
||||
if (this.state.count === nextProps.count) {
|
||||
return;
|
||||
}
|
||||
this.lastCount = this.state.count;
|
||||
@@ -79,8 +76,8 @@ class AntScrollNumber extends React.Component {
|
||||
className: `${this.props.prefixCls}-only`,
|
||||
style: {
|
||||
transition: removeTransition && 'none',
|
||||
transform: 'translate3d(0, ' + (-position * height) + 'px, 0)',
|
||||
height: height,
|
||||
transform: `translate3d(0, ${-position * height}px, 0)`,
|
||||
height,
|
||||
},
|
||||
key: i,
|
||||
}, this.renderNumberList());
|
||||
@@ -106,13 +103,12 @@ class AntScrollNumber extends React.Component {
|
||||
props,
|
||||
this.renderNumberElement()
|
||||
);
|
||||
} else {
|
||||
return createElement(
|
||||
this.props.component,
|
||||
props,
|
||||
props.count
|
||||
);
|
||||
}
|
||||
return createElement(
|
||||
this.props.component,
|
||||
props,
|
||||
props.count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +116,7 @@ AntScrollNumber.defaultProps = {
|
||||
prefixCls: 'ant-scroll-number',
|
||||
count: null,
|
||||
component: 'sup',
|
||||
onAnimated: function() {},
|
||||
onAnimated() {},
|
||||
height: 18,
|
||||
};
|
||||
|
||||
|
||||
@@ -30,40 +30,33 @@ const Test = React.createClass({
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show
|
||||
});
|
||||
},
|
||||
onNumberClick() {
|
||||
const count = this.state.count;
|
||||
this.setState({
|
||||
count: count ? 0 : 5
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<Badge count={this.state.count}>
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<Badge dot={this.state.show}>
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<Button type="ghost" onClick={this.onNumberClick} style={{marginRight: 6}}>
|
||||
切换数字显隐
|
||||
</Button>
|
||||
<Button type="ghost" onClick={this.onClick} style={{marginRight: 6}}>
|
||||
切换红点显隐
|
||||
</Button>
|
||||
<ButtonGroup>
|
||||
<Button type="ghost" onClick={this.decline}>
|
||||
<Icon type="minus" />
|
||||
return (
|
||||
<div>
|
||||
<Badge count={this.state.count}>
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<Badge dot={this.state.show}>
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<ButtonGroup>
|
||||
<Button type="ghost" onClick={this.decline}>
|
||||
<Icon type="minus" />
|
||||
</Button>
|
||||
<Button type="ghost" onClick={this.increase}>
|
||||
<Icon type="plus" />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<Button type="ghost" onClick={this.onClick} style={{ marginLeft: 8 }}>
|
||||
切换红点显隐
|
||||
</Button>
|
||||
<Button type="ghost" onClick={this.increase}>
|
||||
<Icon type="plus" />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Badge count={25} />
|
||||
<Badge count={4} style={{backgroundColor: '#fff', color: '#999', borderColor: '#d9d9d9'}} />
|
||||
<Badge count={109} style={{backgroundColor: '#87d068'}} />
|
||||
<Badge count={4} style={{ backgroundColor: '#fff', color: '#999', borderColor: '#d9d9d9' }} />
|
||||
<Badge count={109} style={{ backgroundColor: '#87d068' }} />
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -4,10 +4,6 @@ import ScrollNumber from './ScrollNumber';
|
||||
import classNames from 'classnames';
|
||||
|
||||
class AntBadge extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
let { count, prefixCls, overflowCount, className, style, children } = this.props;
|
||||
const dot = this.props.dot;
|
||||
@@ -33,7 +29,7 @@ class AntBadge extends React.Component {
|
||||
{children}
|
||||
<Animate component=""
|
||||
showProp="data-show"
|
||||
transitionName={prefixCls + '-zoom'}
|
||||
transitionName={`${prefixCls}-zoom`}
|
||||
transitionAppear>
|
||||
{
|
||||
hidden ? null :
|
||||
|
||||
@@ -2,52 +2,64 @@
|
||||
|
||||
- order: 2
|
||||
|
||||
和 `react-router@1.x` 进行结合使用。
|
||||
和 `react-router@2.x` 进行结合使用。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
const ReactRouter = require('react-router');
|
||||
let { Router, Route, Link } = ReactRouter;
|
||||
let { Router, Route, Link, hashHistory } = ReactRouter;
|
||||
import { Breadcrumb } from 'antd';
|
||||
|
||||
const Apps = React.createClass({
|
||||
render() {
|
||||
return <ul className="app-list">
|
||||
<li><Link to="/apps/1">应用1</Link></li>
|
||||
<li><Link to="/apps/2">应用2</Link></li>
|
||||
</ul>;
|
||||
return (
|
||||
<ul className="app-list">
|
||||
<li>
|
||||
<Link to="/apps/1">应用1</Link>:<Link to="/apps/1/detail">详情</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/apps/2">应用2</Link>:<Link to="/apps/2/detail">详情</Link>
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const Home = React.createClass({
|
||||
render() {
|
||||
return (<div>
|
||||
<div className="demo-nav">
|
||||
<Link to="/">首页</Link>
|
||||
<Link to="/apps">应用列表</Link>
|
||||
return (
|
||||
<div>
|
||||
<div className="demo-nav">
|
||||
<Link to="/">首页</Link>
|
||||
<Link to="/apps">应用列表</Link>
|
||||
</div>
|
||||
{this.props.children || 'Home'}
|
||||
<div style={{
|
||||
marginBottom: 15,
|
||||
marginTop: 15,
|
||||
paddingBottom: 15,
|
||||
borderBottom: '1px dashed #ccc'
|
||||
}}>
|
||||
点击上面的导航切换页面,面包屑在下面:
|
||||
</div>
|
||||
<Breadcrumb {...this.props} />
|
||||
</div>
|
||||
{this.props.children || 'Home'}
|
||||
<div style={{
|
||||
marginBottom: 15,
|
||||
marginTop: 15,
|
||||
paddingBottom: 15,
|
||||
borderBottom: '1px dashed #ccc'
|
||||
}}>点击上面的导航切换页面,面包屑在下面:</div>
|
||||
<Breadcrumb {...this.props} router={ReactRouter} />
|
||||
</div>);
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render((
|
||||
<Router>
|
||||
ReactDOM.render(
|
||||
<Router history={hashHistory}>
|
||||
<Route name="home" breadcrumbName="首页" path="/" component={Home}>
|
||||
<Route name="apps" breadcrumbName="应用列表" path="apps" component={Apps}>
|
||||
<Route name="app" breadcrumbName="应用:id" path=":id" />
|
||||
<Route name="app" breadcrumbName="应用:id" path=":id">
|
||||
<Route name="detail" breadcrumbName="详情" path="detail" />
|
||||
</Route>
|
||||
</Route>
|
||||
</Route>
|
||||
</Router>
|
||||
), mountNode);
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
|
||||
@@ -17,14 +17,16 @@ const BreadcrumbItem = React.createClass({
|
||||
},
|
||||
render() {
|
||||
const { prefixCls, separator, children } = this.props;
|
||||
let link = <a className={prefixCls + '-link'} {...this.props}>{children}</a>;
|
||||
let link = <a className={`${prefixCls}-link`} {...this.props}>{children}</a>;
|
||||
if (typeof this.props.href === 'undefined') {
|
||||
link = <span className={prefixCls + '-link'} {...this.props}>{children}</span>;
|
||||
link = <span className={`${prefixCls}-link`} {...this.props}>{children}</span>;
|
||||
}
|
||||
return <span>
|
||||
{link}
|
||||
<span className={prefixCls + '-separator'}>{separator}</span>
|
||||
</span>;
|
||||
return (
|
||||
<span>
|
||||
{link}
|
||||
<span className={`${prefixCls}-separator`}>{separator}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -41,29 +43,35 @@ const Breadcrumb = React.createClass({
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element,
|
||||
]),
|
||||
router: React.PropTypes.object,
|
||||
routes: React.PropTypes.array,
|
||||
params: React.PropTypes.object
|
||||
params: React.PropTypes.object,
|
||||
},
|
||||
render() {
|
||||
let crumbs;
|
||||
const { separator, prefixCls, router, routes, params, children } = this.props;
|
||||
const ReactRouter = router;
|
||||
if (routes && routes.length > 0 && ReactRouter) {
|
||||
let Link = ReactRouter.Link;
|
||||
crumbs = routes.map(function(route, i) {
|
||||
const { separator, prefixCls, routes, params, children } = this.props;
|
||||
if (routes && routes.length > 0) {
|
||||
const paths = [];
|
||||
crumbs = routes.map((route, i) => {
|
||||
if (!route.breadcrumbName) {
|
||||
return null;
|
||||
}
|
||||
const name = route.breadcrumbName.replace(/\:(.*)/g, function(replacement, key) {
|
||||
const name = route.breadcrumbName.replace(/\:(.*)/g, (replacement, key) => {
|
||||
return params[key] || replacement;
|
||||
});
|
||||
|
||||
let link;
|
||||
const path = route.path.indexOf('/') === 0 ? route.path : ('/' + route.path);
|
||||
let path = route.path.replace(/^\//, '');
|
||||
Object.keys(params).forEach(key => {
|
||||
path = path.replace(`:${key}`, params[key]);
|
||||
});
|
||||
if (path) {
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
if (i === routes.length - 1) {
|
||||
link = <span>{name}</span>;
|
||||
} else {
|
||||
link = <Link to={path} params={params}>{name}</Link>;
|
||||
link = <a href={`#/${paths.join('/')}`}>{name}</a>;
|
||||
}
|
||||
return <BreadcrumbItem separator={separator} key={name}>{link}</BreadcrumbItem>;
|
||||
});
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|-----------|-----------------------------------|-------------------|---------|--------|
|
||||
| router | 可传入 react-router 的实例 | Object | | - |
|
||||
| routes | router 的路由栈信息 | Array | | - |
|
||||
| params | 路由的参数 | Object | | - |
|
||||
| separator | 分隔符自定义 | String or Element | | '/' |
|
||||
|
||||
@@ -5,13 +5,13 @@ const prefix = 'ant-btn-group-';
|
||||
|
||||
export default class ButtonGroup extends React.Component {
|
||||
render() {
|
||||
const {size, className, ...others} = this.props;
|
||||
const { size, className, ...others } = this.props;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
const sizeCls = ({
|
||||
'large': 'lg',
|
||||
'small': 'sm'
|
||||
large: 'lg',
|
||||
small: 'sm',
|
||||
})[size] || '';
|
||||
|
||||
const classes = classNames({
|
||||
|
||||
@@ -25,20 +25,23 @@ function insertSpace(child) {
|
||||
}
|
||||
|
||||
export default class Button extends React.Component {
|
||||
componentDidMount() {
|
||||
if (window && window.PIE) {
|
||||
window.PIE.attach(findDOMNode(this));
|
||||
}
|
||||
handleClick(...args) {
|
||||
const buttonNode = findDOMNode(this);
|
||||
buttonNode.className = buttonNode.className.replace(`${prefix}clicked`, '');
|
||||
setTimeout(() => {
|
||||
buttonNode.className += ` ${prefix}clicked`;
|
||||
}, 10);
|
||||
this.props.onClick(...args);
|
||||
}
|
||||
render() {
|
||||
const props = this.props;
|
||||
const {type, shape, size, onClick, className, htmlType, children, ...others} = props;
|
||||
const { type, shape, size, className, htmlType, children, ...others } = props;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
const sizeCls = ({
|
||||
'large': 'lg',
|
||||
'small': 'sm'
|
||||
large: 'lg',
|
||||
small: 'sm',
|
||||
})[size] || '';
|
||||
|
||||
const classes = classNames({
|
||||
@@ -46,15 +49,17 @@ export default class Button extends React.Component {
|
||||
[prefix + type]: type,
|
||||
[prefix + shape]: shape,
|
||||
[prefix + sizeCls]: sizeCls,
|
||||
[prefix + 'loading']: ('loading' in props && props.loading !== false),
|
||||
[`${prefix}loading`]: ('loading' in props && props.loading !== false),
|
||||
[className]: className
|
||||
});
|
||||
|
||||
const kids = React.Children.map(children, insertSpace);
|
||||
|
||||
return <button {...others} type={htmlType || 'button'} className={classes} onClick={onClick}>
|
||||
{kids}
|
||||
</button>;
|
||||
return (
|
||||
<button {...others} type={htmlType || 'button'} className={classes} onClick={this.handleClick.bind(this)}>
|
||||
{kids}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ ReactDOM.render(<div>
|
||||
<Button type="primary">取消</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<Button>左</Button>
|
||||
<Button>中</Button>
|
||||
<Button>右</Button>
|
||||
<Button disabled>左</Button>
|
||||
<Button disabled>中</Button>
|
||||
<Button disabled>右</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup>
|
||||
<Button type="primary">左</Button>
|
||||
|
||||
@@ -23,24 +23,26 @@ const App = React.createClass({
|
||||
this.setState({ iconLoading: true });
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<Button type="primary" size="large" loading>
|
||||
加载中
|
||||
</Button>
|
||||
<Button type="primary" loading>
|
||||
加载中
|
||||
</Button>
|
||||
<Button type="primary" size="small" loading>
|
||||
加载中
|
||||
</Button>
|
||||
<br />
|
||||
<Button type="primary" loading={this.state.loading} onClick={this.enterLoading}>
|
||||
点击变加载
|
||||
</Button>
|
||||
<Button type="primary" loading={this.state.iconLoading} onClick={this.enterIconLoading}>
|
||||
<Icon type="poweroff" />点击变加载
|
||||
</Button>
|
||||
</div>;
|
||||
return (
|
||||
<div>
|
||||
<Button type="primary" size="large" loading>
|
||||
加载中
|
||||
</Button>
|
||||
<Button type="primary" loading>
|
||||
加载中
|
||||
</Button>
|
||||
<Button type="primary" size="small" loading>
|
||||
加载中
|
||||
</Button>
|
||||
<br />
|
||||
<Button type="primary" loading={this.state.loading} onClick={this.enterLoading}>
|
||||
点击变加载
|
||||
</Button>
|
||||
<Button type="primary" loading={this.state.iconLoading} onClick={this.enterIconLoading}>
|
||||
<Icon type="poweroff" />点击变加载
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -21,25 +21,11 @@
|
||||
|
||||
属性 | 说明 | 类型 | 默认值
|
||||
-----|-----|-----|------
|
||||
type | 设置按钮类型,可选值为 `primary` `ghost` 或者不设 | Enum | undefined
|
||||
htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 HTML标准 | Enum | `button`
|
||||
shape | 设置按钮形状,可选值为 `circle` `circle-outline` 或者不设 | Enum | undefined
|
||||
size | 设置按钮大小,可选值为 `small` `large` 或者不设 | Enum | undefined
|
||||
loading | 设置按钮载入状态,存在为 `true`,不存在为 `false`,或直接设置值,如:`loading="true"` | Bool | false
|
||||
onClick | `click` 事件的 handler | Function | `function() {}`
|
||||
type | 设置按钮类型,可选值为 `primary` `ghost` 或者不设 | string | -
|
||||
htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 HTML标准 | string | `button`
|
||||
shape | 设置按钮形状,可选值为 `circle` `circle-outline` 或者不设 | string | 无
|
||||
size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default`
|
||||
loading | 设置按钮载入状态 | boolean | false
|
||||
onClick | `click` 事件的 handler | function | `function() {}`
|
||||
|
||||
- `<Button>Hello world!</Button>` 最终会被渲染为 `<button>Hello world!</button>`,并且除了上表中的属性,其它属性都会直接传到 `<button></button>`
|
||||
|
||||
|
||||
### IE8 border radius support
|
||||
|
||||
Ant Design 视觉上采用渐进降级的方案,在 IE8 下圆角按钮将降级为直角。
|
||||
如果强烈需要圆角按钮,我们提供了 [css3pie](http://css3pie.com/) 的兼容方案。
|
||||
|
||||
使用时只需在 html 头部加入以下代码即可。
|
||||
|
||||
```html
|
||||
<!--[if IE 8]>
|
||||
<script src="https://t.alipayobjects.com/images/rmsweb/T1q8JiXftaXXXXXXXX.js"></script>
|
||||
<![endif]-->
|
||||
```
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import React, {PropTypes, Component} from 'react';
|
||||
import {PREFIX_CLS} from './Constants';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { PREFIX_CLS } from './Constants';
|
||||
import Select from '../select';
|
||||
import {Group, Button} from '../radio';
|
||||
import { Group, Button } from '../radio';
|
||||
|
||||
function noop() {}
|
||||
|
||||
class Header extends Component {
|
||||
getYearSelectElement(year) {
|
||||
const {yearSelectOffset, yearSelectTotal, locale, prefixCls, fullscreen} = this.props;
|
||||
const { yearSelectOffset, yearSelectTotal, locale, prefixCls, fullscreen } = this.props;
|
||||
const start = year - yearSelectOffset;
|
||||
const end = start + yearSelectTotal;
|
||||
const suffix = locale.year === '年' ? '年' : '';
|
||||
|
||||
const options = [];
|
||||
for (let index = start; index < end; index++) {
|
||||
options.push(<Option key={`${index}`}>{index + suffix}</Option> );
|
||||
options.push(<Option key={`${index}`}>{index + suffix}</Option>);
|
||||
}
|
||||
return (
|
||||
<Select
|
||||
@@ -32,7 +32,7 @@ class Header extends Component {
|
||||
getMonthSelectElement(month) {
|
||||
const props = this.props;
|
||||
const months = props.locale.format.months;
|
||||
const {prefixCls, fullscreen} = props;
|
||||
const { prefixCls, fullscreen } = props;
|
||||
const options = [];
|
||||
|
||||
for (let index = 0; index < 12; index++) {
|
||||
@@ -67,12 +67,9 @@ class Header extends Component {
|
||||
this.props.onTypeChange(e.target.value);
|
||||
}
|
||||
render() {
|
||||
const {type, value, prefixCls, locale} = this.props;
|
||||
|
||||
const { type, value, prefixCls, locale } = this.props;
|
||||
const yearSelect = this.getYearSelectElement(value.getYear());
|
||||
|
||||
const monthSelect = type === 'date' ? this.getMonthSelectElement(value.getMonth()) : null;
|
||||
|
||||
const typeSwitch = (
|
||||
<Group onChange={this.onTypeChange.bind(this)} value={type}>
|
||||
<Button value="date">{locale.month}</Button>
|
||||
|
||||
@@ -19,6 +19,6 @@ function monthCellRender(value) {
|
||||
|
||||
ReactDOM.render(
|
||||
<Calendar defaultValue={new Date('2010-10-10')}
|
||||
dateCellRender={dateCellRender} monthCellRender={monthCellRender} />
|
||||
dateCellRender={dateCellRender} monthCellRender={monthCellRender} />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -15,6 +15,6 @@ function onPanelChange(value, mode) {
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Calendar onPanelChange={onPanelChange} locale={enUS}/>
|
||||
<Calendar onPanelChange={onPanelChange} locale={enUS} />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -12,41 +12,45 @@ import { Calendar } from 'antd';
|
||||
function getListData(value) {
|
||||
let listData;
|
||||
switch (value.getDayOfMonth()) {
|
||||
case 8:
|
||||
listData = [
|
||||
{ type: 'warn', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项.' }
|
||||
]; break;
|
||||
case 10:
|
||||
listData = [
|
||||
{ type: 'warn', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' }
|
||||
]; break;
|
||||
case 15:
|
||||
listData = [
|
||||
{ type: 'warn', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项好长啊。。....' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' }
|
||||
]; break;
|
||||
default:
|
||||
case 8:
|
||||
listData = [
|
||||
{ type: 'warn', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项.' }
|
||||
]; break;
|
||||
case 10:
|
||||
listData = [
|
||||
{ type: 'warn', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' }
|
||||
]; break;
|
||||
case 15:
|
||||
listData = [
|
||||
{ type: 'warn', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项好长啊。。....' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' }
|
||||
]; break;
|
||||
default:
|
||||
}
|
||||
return listData || [];
|
||||
}
|
||||
|
||||
function dateCellRender(value) {
|
||||
let listData = getListData(value);
|
||||
return <ul className="events">
|
||||
{listData.map((item, index) =>
|
||||
<li key={index}>
|
||||
<span className={`event-${item.type}`}>●</span>
|
||||
{item.content}
|
||||
</li>
|
||||
)}
|
||||
</ul>;
|
||||
return (
|
||||
<ul className="events">
|
||||
{
|
||||
listData.map((item, index) =>
|
||||
<li key={index}>
|
||||
<span className={`event-${item.type}`}>●</span>
|
||||
{item.content}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, {PropTypes, Component} from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import GregorianCalendar from 'gregorian-calendar';
|
||||
import zhCN from './locale/zh_CN';
|
||||
import FullCalendar from 'rc-calendar/lib/FullCalendar';
|
||||
import {PREFIX_CLS} from './Constants';
|
||||
import { PREFIX_CLS } from './Constants';
|
||||
import Header from './Header';
|
||||
|
||||
function noop () { return null; }
|
||||
function noop() { return null; }
|
||||
|
||||
function zerofixed (v) {
|
||||
if (v < 10) return '0' + v;
|
||||
return v + '';
|
||||
function zerofixed(v) {
|
||||
if (v < 10) return `0${v}`;
|
||||
return `${v}`;
|
||||
}
|
||||
|
||||
class Calendar extends Component {
|
||||
@@ -35,25 +35,29 @@ class Calendar extends Component {
|
||||
monthCellRender(value, locale) {
|
||||
const prefixCls = this.props.prefixCls;
|
||||
const month = value.getMonth();
|
||||
return <div className={`${prefixCls}-month`}>
|
||||
<div className={`${prefixCls}-value`}>
|
||||
{locale.format.shortMonths[month]}
|
||||
return (
|
||||
<div className={`${prefixCls}-month`}>
|
||||
<div className={`${prefixCls}-value`}>
|
||||
{locale.format.shortMonths[month]}
|
||||
</div>
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{this.props.monthCellRender(value)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{this.props.monthCellRender(value)}
|
||||
</div>
|
||||
</div>;
|
||||
);
|
||||
}
|
||||
dateCellRender(value) {
|
||||
const prefixCls = this.props.prefixCls;
|
||||
return <div className={`${prefixCls}-date`}>
|
||||
<div className={`${prefixCls}-value`}>
|
||||
{zerofixed(value.getDayOfMonth())}
|
||||
return (
|
||||
<div className={`${prefixCls}-date`}>
|
||||
<div className={`${prefixCls}-value`}>
|
||||
{zerofixed(value.getDayOfMonth())}
|
||||
</div>
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{this.props.dateCellRender(value)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{this.props.dateCellRender(value)}
|
||||
</div>
|
||||
</div>;
|
||||
);
|
||||
}
|
||||
setValue(value) {
|
||||
if (!('value' in this.props) && this.state.value !== value) {
|
||||
@@ -70,13 +74,13 @@ class Calendar extends Component {
|
||||
}
|
||||
render() {
|
||||
const props = this.props;
|
||||
const {value, mode} = this.state;
|
||||
const {locale, prefixCls, style, className, fullscreen} = props;
|
||||
const { value, mode } = this.state;
|
||||
const { locale, prefixCls, style, className, fullscreen } = props;
|
||||
const type = (mode === 'year') ? 'month' : 'date';
|
||||
|
||||
let cls = className || '';
|
||||
if (fullscreen) {
|
||||
cls += (' ' + prefixCls + '-fullscreen');
|
||||
cls += (` ${prefixCls}-fullscreen`);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -88,7 +92,7 @@ class Calendar extends Component {
|
||||
locale={locale.lang}
|
||||
prefixCls={prefixCls}
|
||||
onTypeChange={this.setType.bind(this)}
|
||||
onValueChange={this.setValue.bind(this)}/>
|
||||
onValueChange={this.setValue.bind(this)} />
|
||||
<FullCalendar
|
||||
{...props}
|
||||
Select={noop}
|
||||
|
||||
@@ -4,10 +4,10 @@ if (typeof window !== 'undefined') {
|
||||
const matchMediaPolyfill = function matchMediaPolyfill() {
|
||||
return {
|
||||
matches: false,
|
||||
addListener: function () {
|
||||
addListener() {
|
||||
},
|
||||
removeListener() {
|
||||
},
|
||||
removeListener: function () {
|
||||
}
|
||||
};
|
||||
};
|
||||
window.matchMedia = window.matchMedia || matchMediaPolyfill;
|
||||
@@ -21,7 +21,7 @@ const AntCarousel = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
dots: true,
|
||||
arrows: false
|
||||
arrows: false,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
@@ -34,7 +34,7 @@ const AntCarousel = React.createClass({
|
||||
|
||||
let className = 'ant-carousel';
|
||||
if (props.vertical) {
|
||||
className = className + ' ant-carousel-vertical';
|
||||
className = `${className} ant-carousel-vertical`;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
43
components/cascader/demo/basic.md
Normal file
43
components/cascader/demo/basic.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 基本
|
||||
|
||||
- order: 0
|
||||
|
||||
省市区级联。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader options={options} onChange={onChange} />
|
||||
, mountNode);
|
||||
````
|
||||
43
components/cascader/demo/change-on-select.md
Normal file
43
components/cascader/demo/change-on-select.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 选择即改变
|
||||
|
||||
- order: 5
|
||||
|
||||
这种交互允许只选中父级选项。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader options={options} onChange={onChange} changeOnSelect />
|
||||
, mountNode);
|
||||
````
|
||||
53
components/cascader/demo/custom-trigger.md
Normal file
53
components/cascader/demo/custom-trigger.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 可以自定义显示
|
||||
|
||||
- order: 1
|
||||
|
||||
切换按钮和结果分开。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
}],
|
||||
}];
|
||||
|
||||
const CitySwitcher = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
text: '未选择',
|
||||
};
|
||||
},
|
||||
onChange(value, selectedOptions) {
|
||||
this.setState({
|
||||
text: selectedOptions.map(o => o.label).join(', '),
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<span>
|
||||
{this.state.text}
|
||||
|
||||
<Cascader options={options} onChange={this.onChange}>
|
||||
<a href="#">切换城市</a>
|
||||
</Cascader>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<CitySwitcher />, mountNode);
|
||||
````
|
||||
43
components/cascader/demo/default-value.md
Normal file
43
components/cascader/demo/default-value.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 默认值
|
||||
|
||||
- order: 0
|
||||
|
||||
默认值通过数组的方式指定。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader defaultValue={['zhejiang', 'hangzhou', 'xihu']} options={options} onChange={onChange} />
|
||||
, mountNode);
|
||||
````
|
||||
44
components/cascader/demo/disabled-option.md
Normal file
44
components/cascader/demo/disabled-option.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# 禁用选项
|
||||
|
||||
- order: 4
|
||||
|
||||
通过指定 options 里的 `disabled` 字段。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
disabled: true,
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader options={options} onChange={onChange} />
|
||||
, mountNode);
|
||||
````
|
||||
49
components/cascader/demo/hover.md
Normal file
49
components/cascader/demo/hover.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 移入展开
|
||||
|
||||
- order: 2
|
||||
|
||||
通过移入展开下级菜单,点击完成选择。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
// 只展示最后一项
|
||||
function displayRender(label) {
|
||||
return label[label.length - 1];
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader options={options} expandTrigger="hover"
|
||||
displayRender={displayRender} onChange={onChange} />
|
||||
, mountNode);
|
||||
````
|
||||
47
components/cascader/demo/size.md
Normal file
47
components/cascader/demo/size.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 大小
|
||||
|
||||
- order: 7
|
||||
|
||||
不同大小的级联选择器。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Cascader size="large" options={options} onChange={onChange} /><br /><br />
|
||||
<Cascader options={options} onChange={onChange} /><br /><br />
|
||||
<Cascader size="small" options={options} onChange={onChange} /><br /><br />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
114
components/cascader/index.jsx
Normal file
114
components/cascader/index.jsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
import Cascader from 'rc-cascader';
|
||||
import Input from '../input';
|
||||
import Icon from '../icon';
|
||||
import arrayTreeFilter from 'array-tree-filter';
|
||||
import classNames from 'classnames';
|
||||
|
||||
class AntCascader extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: props.value || props.defaultValue || [],
|
||||
popupVisible: false,
|
||||
};
|
||||
[
|
||||
'handleChange',
|
||||
'handlePopupVisibleChange',
|
||||
'setValue',
|
||||
'getLabel',
|
||||
'clearSelection',
|
||||
].forEach((method) => this[method] = this[method].bind(this));
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({ value: nextProps.value || [] });
|
||||
}
|
||||
}
|
||||
handleChange(value, selectedOptions) {
|
||||
this.setValue(value, selectedOptions);
|
||||
}
|
||||
handlePopupVisibleChange(popupVisible) {
|
||||
this.setState({ popupVisible });
|
||||
this.props.onPopupVisibleChange(popupVisible);
|
||||
}
|
||||
setValue(value, selectedOptions = []) {
|
||||
if (!('value' in this.props)) {
|
||||
this.setState({ value });
|
||||
}
|
||||
this.props.onChange(value, selectedOptions);
|
||||
}
|
||||
getLabel() {
|
||||
const { options, displayRender } = this.props;
|
||||
const label = arrayTreeFilter(options, (o, level) => o.value === this.state.value[level])
|
||||
.map(o => o.label);
|
||||
return displayRender(label);
|
||||
}
|
||||
clearSelection(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.setValue([]);
|
||||
this.setState({ popupVisible: false });
|
||||
}
|
||||
render() {
|
||||
const { prefixCls, children, placeholder, size, disabled,
|
||||
className, style, allowClear, ...otherProps } = this.props;
|
||||
const sizeCls = classNames({
|
||||
'ant-input-lg': size === 'large',
|
||||
'ant-input-sm': size === 'small',
|
||||
});
|
||||
const clearIcon = (allowClear && !disabled && this.state.value.length > 0) ?
|
||||
<Icon type="cross-circle"
|
||||
className={`${prefixCls}-picker-clear`}
|
||||
onClick={this.clearSelection} /> : null;
|
||||
const arrowCls = classNames({
|
||||
[`${prefixCls}-picker-arrow`]: true,
|
||||
[`${prefixCls}-picker-arrow-expand`]: this.state.popupVisible,
|
||||
});
|
||||
const pickerCls = classNames({
|
||||
[className]: !!className,
|
||||
[`${prefixCls}-picker`]: true,
|
||||
[`${prefixCls}-picker-disabled`]: disabled,
|
||||
});
|
||||
return (
|
||||
<Cascader {...this.props}
|
||||
value={this.state.value}
|
||||
popupVisible={this.state.popupVisible}
|
||||
onPopupVisibleChange={this.handlePopupVisibleChange}
|
||||
onChange={this.handleChange}>
|
||||
{children ||
|
||||
<span
|
||||
style={style}
|
||||
className={pickerCls}>
|
||||
<Input {...otherProps}
|
||||
placeholder={placeholder}
|
||||
className={`${prefixCls}-input ant-input ${sizeCls}`}
|
||||
style={{ width: '100%' }}
|
||||
value={this.getLabel()}
|
||||
disabled={disabled}
|
||||
readOnly />
|
||||
{clearIcon}
|
||||
<Icon type="down" className={arrowCls} />
|
||||
</span>
|
||||
}
|
||||
</Cascader>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AntCascader.defaultProps = {
|
||||
prefixCls: 'ant-cascader',
|
||||
placeholder: '请选择',
|
||||
transitionName: 'slide-up',
|
||||
popupPlacement: 'bottomLeft',
|
||||
onChange() {},
|
||||
options: [],
|
||||
displayRender(label) {
|
||||
return label.join(' / ');
|
||||
},
|
||||
disabled: false,
|
||||
allowClear: true,
|
||||
onPopupVisibleChange() {},
|
||||
};
|
||||
|
||||
export default AntCascader;
|
||||
38
components/cascader/index.md
Normal file
38
components/cascader/index.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Cascader
|
||||
|
||||
- category: Components
|
||||
- chinese: 级联选择
|
||||
- type: 表单
|
||||
|
||||
---
|
||||
|
||||
级联选择框。
|
||||
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。
|
||||
- 从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。
|
||||
- 比起 Select 组件,可以在同一个浮层中完成选择,有较好的体验。
|
||||
|
||||
## API
|
||||
|
||||
```html
|
||||
<Cascader options={options} onChange={onChange} />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| options | 可选项数据源 | object | - |
|
||||
| defaultValue | 默认的选中项 | array |[] |
|
||||
| value | 指定选中项 | array | - |
|
||||
| onChange | 选择完成后的回调 | `function(value, selectedOptions)` | - |
|
||||
| displayRender | 选择后展示的渲染函数 | `function(label)`` | `function(label) { return label.join(' / ') }` |
|
||||
| style | 自定义样式 | string | - |
|
||||
| className | 自定义类名 | string | - |
|
||||
| popupClassName | 自定义浮层类名 | string | - |
|
||||
| popupPlacement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` |
|
||||
| placeholder | 输入框占位文本 | string | '请选择' |
|
||||
| size | 输入框大小,可选 `large` `default` `small` | string | `default` |
|
||||
| disabled | 禁用 | boolean | false |
|
||||
| allowClear | 是否支持清除 | boolean | true |
|
||||
@@ -5,6 +5,7 @@ export default React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
options: [],
|
||||
defaultValue: [],
|
||||
onChange() {},
|
||||
};
|
||||
},
|
||||
@@ -15,21 +16,25 @@ export default React.createClass({
|
||||
onChange: React.PropTypes.func,
|
||||
},
|
||||
getInitialState() {
|
||||
const { value, defaultValue } = this.props;
|
||||
return {
|
||||
value: value || defaultValue || [],
|
||||
};
|
||||
const props = this.props;
|
||||
let value;
|
||||
if ('value' in props) {
|
||||
value = props.value;
|
||||
} else if ('defaultValue' in props) {
|
||||
value = props.defaultValue;
|
||||
}
|
||||
return { value };
|
||||
},
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({
|
||||
value: nextProps.value,
|
||||
value: nextProps.value || [],
|
||||
});
|
||||
}
|
||||
},
|
||||
toggleOption(option) {
|
||||
const optionIndex = this.state.value.indexOf(option);
|
||||
const value = this.state.value;
|
||||
const value = [...this.state.value];
|
||||
if (optionIndex === - 1) {
|
||||
value.push(option);
|
||||
} else {
|
||||
@@ -42,17 +47,19 @@ export default React.createClass({
|
||||
},
|
||||
render() {
|
||||
const options = this.props.options;
|
||||
return <div className="ant-checkbox-group">
|
||||
{
|
||||
options.map(option =>
|
||||
<label className="ant-checkbox-group-item" key={option}>
|
||||
<Checkbox disabled={this.props.disabled}
|
||||
checked={this.state.value.indexOf(option) !== -1}
|
||||
onChange={this.toggleOption.bind(this, option)} />
|
||||
{option}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
</div>;
|
||||
return (
|
||||
<div className="ant-checkbox-group">
|
||||
{
|
||||
options.map(option =>
|
||||
<label className="ant-checkbox-group-item" key={option}>
|
||||
<Checkbox disabled={this.props.disabled}
|
||||
checked={this.state.value.indexOf(option) !== -1}
|
||||
onChange={this.toggleOption.bind(this, option)} />
|
||||
{option}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import { Checkbox } from 'antd';
|
||||
|
||||
function onChange(e) {
|
||||
console.log('checked = ' + e.target.checked);
|
||||
console.log(`checked = ${e.target.checked}`);
|
||||
}
|
||||
|
||||
ReactDOM.render(<label>
|
||||
|
||||
@@ -17,35 +17,36 @@ const App = React.createClass({
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const label = (this.state.checked ? '选中' : '取消') + '-' +
|
||||
(this.state.disabled ? '不可用' : '可用');
|
||||
return <div>
|
||||
<p style={{marginBottom: '20px'}}>
|
||||
<label>
|
||||
<Checkbox checked={this.state.checked}
|
||||
disabled={this.state.disabled}
|
||||
onChange={this.onChange} />
|
||||
{label}
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<Button type="primary" size="small"
|
||||
onClick={this.toggleChecked}>
|
||||
{!this.state.checked ? '选中' : '取消'}
|
||||
</Button>
|
||||
<Button style={{marginLeft: '10px'}}
|
||||
type="primary" size="small"
|
||||
onClick={this.toggleDisable}>
|
||||
{!this.state.disabled ? '不可用' : '可用'}
|
||||
</Button>
|
||||
</p>
|
||||
</div>;
|
||||
const label = `${this.state.checked ? '选中' : '取消'}-${this.state.disabled ? '不可用' : '可用'}`;
|
||||
return (
|
||||
<div>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
<label>
|
||||
<Checkbox checked={this.state.checked}
|
||||
disabled={this.state.disabled}
|
||||
onChange={this.onChange} />
|
||||
{label}
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<Button type="primary" size="small"
|
||||
onClick={this.toggleChecked}>
|
||||
{!this.state.checked ? '选中' : '取消'}
|
||||
</Button>
|
||||
<Button style={{ marginLeft: '10px' }}
|
||||
type="primary" size="small"
|
||||
onClick={this.toggleDisable}>
|
||||
{!this.state.disabled ? '不可用' : '可用'}
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
toggleChecked() {
|
||||
this.setState({checked: !this.state.checked});
|
||||
this.setState({ checked: !this.state.checked });
|
||||
},
|
||||
toggleDisable() {
|
||||
this.setState({disabled: !this.state.disabled});
|
||||
this.setState({ disabled: !this.state.disabled });
|
||||
},
|
||||
onChange(e) {
|
||||
console.log('checked = ', e.target.checked);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
- order: 3
|
||||
|
||||
方便的生成一个 Checkbox 组。
|
||||
方便的从数组生成 Checkbox 组。若需要 label 和 value 分离请直接使用 Checkbox。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ const text = `
|
||||
|
||||
ReactDOM.render(
|
||||
<Collapse accordion>
|
||||
<Panel header={`This is panel header 1`} key="1">
|
||||
<Panel header={'This is panel header 1'} key="1">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
<Panel header={`This is panel header 2`} key="2">
|
||||
<Panel header={'This is panel header 2'} key="2">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
<Panel header={`This is panel header 3`} key="3">
|
||||
<Panel header={'This is panel header 3'} key="3">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
|
||||
@@ -22,17 +22,17 @@ const text = `
|
||||
|
||||
ReactDOM.render(
|
||||
<Collapse onChange={callback} accordion>
|
||||
<Panel header={`This is panel header 1`} key="1">
|
||||
<Panel header={'This is panel header 1'} key="1">
|
||||
<Collapse defaultActiveKey="1">
|
||||
<Panel header={`This is panel nest panel`} key="1">
|
||||
<Panel header={'This is panel nest panel'} key="1">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
</Panel>
|
||||
<Panel header={`This is panel header 2`} key="2">
|
||||
<Panel header={'This is panel header 2'} key="2">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
<Panel header={`This is panel header 3`} key="3">
|
||||
<Panel header={'This is panel header 3'} key="3">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Collapse from 'rc-collapse';
|
||||
import React from 'react';
|
||||
const prefixCls = 'ant-collapse';
|
||||
|
||||
class AntCollapse extends React.Component {
|
||||
render() {
|
||||
@@ -9,7 +8,7 @@ class AntCollapse extends React.Component {
|
||||
}
|
||||
|
||||
AntCollapse.defaultProps = {
|
||||
prefixCls: prefixCls
|
||||
prefixCls: 'ant-collapse',
|
||||
};
|
||||
|
||||
AntCollapse.Panel = Collapse.Panel;
|
||||
|
||||
@@ -14,10 +14,12 @@ function animate(node, show, transitionName, done) {
|
||||
}
|
||||
|
||||
// Fix safari flash bug
|
||||
/*eslint-disable */
|
||||
node.style.display = show ? 'block' : 'none';
|
||||
/*eslint-enable */
|
||||
velocity(node, transitionName, {
|
||||
duration: 240,
|
||||
complete: complete,
|
||||
complete,
|
||||
easing: 'easeInOutQuad'
|
||||
});
|
||||
return {
|
||||
|
||||
@@ -13,7 +13,7 @@ export default {
|
||||
|
||||
getFormatter() {
|
||||
const formats = this.formats = this.formats || {};
|
||||
const format = this.props.format;
|
||||
let format = this.props.format;
|
||||
if (formats[format]) {
|
||||
return formats[format];
|
||||
}
|
||||
@@ -24,21 +24,20 @@ export default {
|
||||
parseDateFromValue(value) {
|
||||
if (value) {
|
||||
if (typeof value === 'string') {
|
||||
return this.getFormatter().parse(value, {locale: this.getLocale()});
|
||||
return this.getFormatter().parse(value, { locale: this.getLocale() });
|
||||
} else if (value instanceof Date) {
|
||||
let date = new GregorianCalendar(this.getLocale());
|
||||
date.setTime(+value);
|
||||
return date;
|
||||
}
|
||||
} else if (value === null) {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
return value;
|
||||
},
|
||||
|
||||
// remove input readonly warning
|
||||
handleInputChange() {
|
||||
},
|
||||
|
||||
toggleOpen(e) {
|
||||
this.setState({
|
||||
open: e.open
|
||||
|
||||
@@ -16,7 +16,9 @@ export default React.createClass({
|
||||
transitionName: 'slide-up',
|
||||
popupStyle: {},
|
||||
onChange() {
|
||||
}, // onChange 可用于 Validator
|
||||
},
|
||||
onOk() {
|
||||
},
|
||||
locale: {},
|
||||
align: {
|
||||
offset: [0, -9],
|
||||
@@ -25,7 +27,7 @@ export default React.createClass({
|
||||
};
|
||||
},
|
||||
getInitialState() {
|
||||
const {value, defaultValue} = this.props;
|
||||
const { value, defaultValue } = this.props;
|
||||
const start = (value && value[0]) || defaultValue[0];
|
||||
const end = (value && value[1]) || defaultValue[1];
|
||||
return {
|
||||
@@ -35,11 +37,12 @@ export default React.createClass({
|
||||
]
|
||||
};
|
||||
},
|
||||
mixins: [ PickerMixin ],
|
||||
mixins: [PickerMixin],
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('value' in nextProps) {
|
||||
const start = this.parseDateFromValue(nextProps.value[0]);
|
||||
const end = this.parseDateFromValue(nextProps.value[1]);
|
||||
const value = nextProps.value || [];
|
||||
const start = this.parseDateFromValue(value[0]);
|
||||
const end = this.parseDateFromValue(value[1]);
|
||||
this.setState({
|
||||
value: [start, end]
|
||||
});
|
||||
@@ -61,28 +64,55 @@ export default React.createClass({
|
||||
let defaultCalendarValue = new GregorianCalendar(locale);
|
||||
defaultCalendarValue.setTime(Date.now());
|
||||
|
||||
const {disabledDate, showTime, size, startPlaceholder, endPlaceholder,
|
||||
transitionName, disabled, popupStyle, align, style} = this.props;
|
||||
const { disabledDate, showTime, size, startPlaceholder, endPlaceholder, getCalendarContainer,
|
||||
transitionName, disabled, popupStyle, align, style, onOk } = this.props;
|
||||
const state = this.state;
|
||||
|
||||
const timePicker = showTime
|
||||
? <TimePicker prefixCls="ant-time-picker"
|
||||
placeholder={locale.lang.timePlaceholder}
|
||||
transitionName="slide-up" />
|
||||
: null;
|
||||
let timePicker = null;
|
||||
|
||||
if (showTime) {
|
||||
timePicker = (<TimePicker
|
||||
prefixCls="ant-time-picker"
|
||||
placeholder={locale.lang.timePlaceholder}
|
||||
transitionName="slide-up" />);
|
||||
}
|
||||
|
||||
const calendarClassName = classNames({
|
||||
['ant-calendar-time']: this.props.showTime,
|
||||
});
|
||||
|
||||
const calendar = <RangeCalendar prefixCls="ant-calendar"
|
||||
className={calendarClassName}
|
||||
timePicker={timePicker}
|
||||
disabledDate={disabledDate}
|
||||
dateInputPlaceholder={[startPlaceholder, endPlaceholder]}
|
||||
locale={locale.lang}
|
||||
defaultValue={defaultCalendarValue}
|
||||
showClear />;
|
||||
let pickerChangeHandler = {
|
||||
onChange: this.handleChange,
|
||||
};
|
||||
|
||||
let calendarHandler = {
|
||||
onOk: this.handleChange,
|
||||
};
|
||||
|
||||
if (timePicker) {
|
||||
pickerChangeHandler.onChange = (value) => {
|
||||
// Click clear button
|
||||
if (value === null || value.length === 0) {
|
||||
this.handleChange(value);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
calendarHandler = {};
|
||||
}
|
||||
|
||||
const calendar = (
|
||||
<RangeCalendar
|
||||
prefixCls="ant-calendar"
|
||||
className={calendarClassName}
|
||||
timePicker={timePicker}
|
||||
disabledDate={disabledDate}
|
||||
dateInputPlaceholder={[startPlaceholder, endPlaceholder]}
|
||||
locale={locale.lang}
|
||||
onOk={onOk}
|
||||
defaultValue={[defaultCalendarValue, defaultCalendarValue]}
|
||||
{...calendarHandler}
|
||||
/>
|
||||
);
|
||||
|
||||
const pickerClass = classNames({
|
||||
'ant-calendar-picker': true,
|
||||
@@ -105,22 +135,26 @@ export default React.createClass({
|
||||
prefixCls="ant-calendar-picker-container"
|
||||
style={popupStyle}
|
||||
align={align}
|
||||
getCalendarContainer={getCalendarContainer}
|
||||
onOpen={this.toggleOpen}
|
||||
onClose={this.toggleOpen}
|
||||
onChange={this.handleChange}>
|
||||
{...pickerChangeHandler}
|
||||
>
|
||||
{
|
||||
({value}) => {
|
||||
({ value }) => {
|
||||
const start = value[0];
|
||||
const end = value[1];
|
||||
return (
|
||||
<span className={pickerInputClass} disabled={disabled}>
|
||||
<input disabled={disabled}
|
||||
<input
|
||||
disabled={disabled}
|
||||
onChange={this.handleInputChange}
|
||||
value={start && this.getFormatter().format(start)}
|
||||
placeholder={startPlaceholder}
|
||||
className="ant-calendar-range-picker-input" />
|
||||
<span className="ant-calendar-range-picker-separator"> ~ </span>
|
||||
<input disabled={disabled}
|
||||
<input
|
||||
disabled={disabled}
|
||||
onChange={this.handleInputChange}
|
||||
value={end && this.getFormatter().format(end)}
|
||||
placeholder={endPlaceholder}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
````jsx
|
||||
import { DatePicker } from 'antd';
|
||||
|
||||
const disabledDate = function(current) {
|
||||
const disabledDate = function (current) {
|
||||
// can not select days after today
|
||||
return current && current.getTime() > Date.now();
|
||||
};
|
||||
|
||||
@@ -14,8 +14,8 @@ function onChange(value) {
|
||||
console.log('From: ', value[0], ', to: ', value[1]);
|
||||
}
|
||||
ReactDOM.render(<div>
|
||||
<RangePicker style={{width: 184}} onChange={onChange} />
|
||||
<RangePicker style={{ width: 184 }} onChange={onChange} />
|
||||
<br />
|
||||
<RangePicker showTime format="yyyy-MM-dd HH:mm:ss" onChange={onChange} />
|
||||
<RangePicker showTime format="yyyy/MM/dd HH:mm:ss" onChange={onChange} />
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -35,16 +35,18 @@ const DateRange = React.createClass({
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<DatePicker disabledDate={this.disabledStartDate}
|
||||
value={this.state.startValue}
|
||||
placeholder="开始日期"
|
||||
onChange={this.onChange.bind(this, 'startValue')} />
|
||||
<DatePicker disabledDate={this.disabledEndDate}
|
||||
value={this.state.endValue}
|
||||
placeholder="结束日期"
|
||||
onChange={this.onChange.bind(this, 'endValue')} />
|
||||
</div>;
|
||||
return (
|
||||
<div>
|
||||
<DatePicker disabledDate={this.disabledStartDate}
|
||||
value={this.state.startValue}
|
||||
placeholder="开始日期"
|
||||
onChange={this.onChange.bind(this, 'startValue')} />
|
||||
<DatePicker disabledDate={this.disabledEndDate}
|
||||
value={this.state.endValue}
|
||||
placeholder="结束日期"
|
||||
onChange={this.onChange.bind(this, 'endValue')} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
- order: 4
|
||||
|
||||
增加选择时间功能。
|
||||
增加选择时间功能。不要修改时间的格式 `HH:mm:ss`。
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,6 @@ function onChange(value) {
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<DatePicker showTime format="yyyy-MM-dd HH:mm:ss" onChange={onChange} style={{width: 160}} />
|
||||
<DatePicker showTime format="yyyy-MM-dd HH:mm:ss" placeholder="请选择时间" onChange={onChange} style={{ width: 160 }} />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
- order: 4
|
||||
- hidden: true
|
||||
|
||||
和 [时间选择框](/components/timepicer) 配合使用。
|
||||
和 [时间选择框](/components/time-picker) 配合使用。
|
||||
|
||||
---
|
||||
|
||||
@@ -37,10 +37,12 @@ const DateTimePicker = React.createClass({
|
||||
}
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<DatePicker onChange={this.handleChange.bind(null, 'date')} />
|
||||
<TimePicker onChange={this.handleChange.bind(null, 'time')} />
|
||||
</div>;
|
||||
return (
|
||||
<div>
|
||||
<DatePicker onChange={this.handleChange.bind(null, 'date')} />
|
||||
<TimePicker onChange={this.handleChange.bind(null, 'time')} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -17,12 +17,14 @@ function createPicker(TheCalendar, defaultFormat) {
|
||||
transitionName: 'slide-up',
|
||||
popupStyle: {},
|
||||
onChange() {
|
||||
}, // onChange 可用于 Validator
|
||||
},
|
||||
onOk() {
|
||||
},
|
||||
locale: {},
|
||||
align: {
|
||||
offset: [0, -9],
|
||||
},
|
||||
open: false
|
||||
open: false,
|
||||
};
|
||||
},
|
||||
getInitialState() {
|
||||
@@ -30,7 +32,7 @@ function createPicker(TheCalendar, defaultFormat) {
|
||||
value: this.parseDateFromValue(this.props.value || this.props.defaultValue)
|
||||
};
|
||||
},
|
||||
mixins: [ PickerMixin ],
|
||||
mixins: [PickerMixin],
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({
|
||||
@@ -56,28 +58,49 @@ function createPicker(TheCalendar, defaultFormat) {
|
||||
const placeholder = ('placeholder' in this.props)
|
||||
? this.props.placeholder : locale.lang.placeholder;
|
||||
|
||||
const timePicker = this.props.showTime
|
||||
? <TimePicker prefixCls="ant-time-picker"
|
||||
placeholder={locale.lang.timePlaceholder}
|
||||
transitionName="slide-up" />
|
||||
const timePicker = this.props.showTime ? (<TimePicker
|
||||
prefixCls="ant-time-picker"
|
||||
placeholder={locale.lang.timePlaceholder}
|
||||
transitionName="slide-up" />)
|
||||
: null;
|
||||
|
||||
const disabledTime = this.props.showTime ? this.props.disabledTime : null;
|
||||
|
||||
const calendarClassName = classNames({
|
||||
['ant-calendar-time']: this.props.showTime,
|
||||
['ant-calendar-month']: MonthCalendar === TheCalendar,
|
||||
});
|
||||
|
||||
let pickerChangeHandler = {
|
||||
onChange: this.handleChange,
|
||||
};
|
||||
|
||||
let calendarHandler = {
|
||||
onOk: this.handleChange,
|
||||
};
|
||||
|
||||
if (this.props.showTime) {
|
||||
pickerChangeHandler.onChange = (value) => {
|
||||
// Click clear button
|
||||
if (value === null) {
|
||||
this.handleChange(value);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
calendarHandler = {};
|
||||
}
|
||||
|
||||
const calendar = (
|
||||
<TheCalendar
|
||||
disabledDate={this.props.disabledDate}
|
||||
disabledTime={disabledTime}
|
||||
locale={locale.lang}
|
||||
timePicker={timePicker}
|
||||
defaultValue={defaultCalendarValue}
|
||||
dateInputPlaceholder={placeholder}
|
||||
prefixCls="ant-calendar"
|
||||
className={calendarClassName}
|
||||
showOk={this.props.showTime}
|
||||
showClear />
|
||||
{...calendarHandler} />
|
||||
);
|
||||
|
||||
let sizeClass = '';
|
||||
@@ -91,36 +114,40 @@ function createPicker(TheCalendar, defaultFormat) {
|
||||
if (this.state.open) {
|
||||
pickerClass += ' ant-calendar-picker-open';
|
||||
}
|
||||
|
||||
return <span className={pickerClass}>
|
||||
<DatePicker
|
||||
transitionName={this.props.transitionName}
|
||||
disabled={this.props.disabled}
|
||||
calendar={calendar}
|
||||
value={this.state.value}
|
||||
prefixCls="ant-calendar-picker-container"
|
||||
style={this.props.popupStyle}
|
||||
align={this.props.align}
|
||||
onOpen={this.toggleOpen}
|
||||
onClose={this.toggleOpen}
|
||||
onChange={this.handleChange}>
|
||||
{
|
||||
({value}) => {
|
||||
return (
|
||||
<span>
|
||||
<input disabled={this.props.disabled}
|
||||
onChange={this.handleInputChange}
|
||||
value={value && this.getFormatter().format(value)}
|
||||
placeholder={placeholder}
|
||||
style={this.props.style}
|
||||
className={'ant-calendar-picker-input ant-input' + sizeClass}/>
|
||||
<span className="ant-calendar-picker-icon"/>
|
||||
</span>
|
||||
);
|
||||
return (
|
||||
<span className={pickerClass}>
|
||||
<DatePicker
|
||||
transitionName={this.props.transitionName}
|
||||
disabled={this.props.disabled}
|
||||
calendar={calendar}
|
||||
value={this.state.value}
|
||||
prefixCls="ant-calendar-picker-container"
|
||||
style={this.props.popupStyle}
|
||||
align={this.props.align}
|
||||
getCalendarContainer={this.props.getCalendarContainer}
|
||||
onOpen={this.toggleOpen}
|
||||
onClose={this.toggleOpen}
|
||||
{...pickerChangeHandler}
|
||||
>
|
||||
{
|
||||
({ value }) => {
|
||||
return (
|
||||
<span>
|
||||
<input
|
||||
disabled={this.props.disabled}
|
||||
onChange={this.handleInputChange}
|
||||
value={value && this.getFormatter().format(value)}
|
||||
placeholder={placeholder}
|
||||
style={this.props.style}
|
||||
className={`ant-calendar-picker-input ant-input${sizeClass}`} />
|
||||
<span className="ant-calendar-picker-icon" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
</DatePicker>
|
||||
</span>;
|
||||
</DatePicker>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|--------------|----------------|----------|--------------|
|
||||
| value | 日期 | string | 无 |
|
||||
| defaultValue | 默认日期 | string | 无 |
|
||||
| format | 展示的日期格式 | string | "yyyy-MM-dd" |
|
||||
| value | 日期 | string or Date | 无 |
|
||||
| defaultValue | 默认日期 | string or Date | 无 |
|
||||
| format | 展示的日期格式,配置参考 [GregorianCalendarFormat](https://github.com/yiminghe/gregorian-calendar-format) | string | "yyyy-MM-dd" |
|
||||
| disabledDate | 不可选择的日期 | function | 无 |
|
||||
| onChange | 时间发生变化的回调,发生在用户选择时间时 | function(Date value) | 无 |
|
||||
| disabled | 禁用 | bool | false |
|
||||
@@ -36,18 +36,19 @@
|
||||
| size | 输入框大小,`large` 高度为 32px,`small` 为 22px,默认是 28px | string | 无 |
|
||||
| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/issues/424) |
|
||||
| showTime | 增加时间选择功能 | bool | false |
|
||||
| onOk | 点击确定按钮的回调 | function | 无 |
|
||||
| onOk | 点击确定按钮的回调 | function(Date value) | 无 |
|
||||
| getCalendarContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | 无 |
|
||||
|
||||
### RangePicker
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|--------------|----------------|----------|--------------|
|
||||
| value | 日期 | [string, string] | 无 |
|
||||
| defaultValue | 默认日期 | [string, string] | 无 |
|
||||
| value | 日期 | [string/Date, string/Date] | 无 |
|
||||
| defaultValue | 默认日期 | [string/Date, string/Date] | 无 |
|
||||
| format | 展示的日期格式 | string | "yyyy-MM-dd HH:mm:ss" |
|
||||
| onChange | 时间发生变化的回调,发生在用户选择时间时 | function([Date start, Date end]) | 无 |
|
||||
|
||||
`disabled` `style` `popupStyle` `size` `locale` `showTime` `onOk` 属性与 DatePicker 的一致。
|
||||
`disabled` `style` `popupStyle` `size` `locale` `showTime` `onOk` `getCalendarContainer` 属性与 DatePicker 的一致。
|
||||
|
||||
<style>
|
||||
.code-box-demo .ant-calendar-picker {
|
||||
|
||||
@@ -9,17 +9,19 @@
|
||||
````jsx
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
|
||||
const menu = <Menu>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.tmall.com/">第三个菜单项</a>
|
||||
</Menu.Item>
|
||||
</Menu>;
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.tmall.com/">第三个菜单项</a>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<Dropdown overlay={menu}>
|
||||
|
||||
@@ -10,21 +10,25 @@
|
||||
import { Menu, Dropdown } from 'antd';
|
||||
const DropdownButton = Dropdown.Button;
|
||||
|
||||
const menu = <Menu>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.tmall.com/">第三个菜单项</a>
|
||||
</Menu.Item>
|
||||
</Menu>;
|
||||
function handleButtonClick() {
|
||||
console.log('click button');
|
||||
}
|
||||
|
||||
function handleMenuClick(e) {
|
||||
console.log('click', e);
|
||||
}
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={handleMenuClick}>
|
||||
<Menu.Item key="1">第一个菜单项</Menu.Item>
|
||||
<Menu.Item key="2">第二个菜单项</Menu.Item>
|
||||
<Menu.Item key="3">第三个菜单项</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<DropdownButton overlay={menu} type="primary">
|
||||
某功能按钮
|
||||
</DropdownButton>
|
||||
<DropdownButton onClick={handleButtonClick} overlay={menu} type="primary">
|
||||
某功能按钮
|
||||
</DropdownButton>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -8,15 +8,17 @@
|
||||
|
||||
````jsx
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
const onClick = function({key}) {
|
||||
console.log('点击了菜单' + key);
|
||||
const onClick = function ({ key }) {
|
||||
console.log(`点击了菜单${key}`);
|
||||
};
|
||||
|
||||
const menu = <Menu onClick={onClick}>
|
||||
<Menu.Item key="1">第一个菜单项</Menu.Item>
|
||||
<Menu.Item key="2">第二个菜单项</Menu.Item>
|
||||
<Menu.Item key="3">第三个菜单项</Menu.Item>
|
||||
</Menu>;
|
||||
const menu = (
|
||||
<Menu onClick={onClick}>
|
||||
<Menu.Item key="1">第一个菜单项</Menu.Item>
|
||||
<Menu.Item key="2">第二个菜单项</Menu.Item>
|
||||
<Menu.Item key="3">第三个菜单项</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<Dropdown overlay={menu}>
|
||||
|
||||
@@ -9,16 +9,18 @@
|
||||
````jsx
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
|
||||
const menu = <Menu>
|
||||
<Menu.Item key="0">
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="1">
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Divider/>
|
||||
<Menu.Item key="3" disabled>第三个菜单项(不可用)</Menu.Item>
|
||||
</Menu>;
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="0">
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="1">
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item key="3" disabled>第三个菜单项(不可用)</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<Dropdown overlay={menu}>
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
const SubMenu = Menu.SubMenu;
|
||||
|
||||
const menu = <Menu>
|
||||
<Menu.Item>第一个菜单项</Menu.Item>
|
||||
<Menu.Item>第二个菜单项</Menu.Item>
|
||||
<SubMenu title="子菜单">
|
||||
<Menu.Item>第三个菜单项</Menu.Item>
|
||||
<Menu.Item>第四个菜单项</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>;
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>第一个菜单项</Menu.Item>
|
||||
<Menu.Item>第二个菜单项</Menu.Item>
|
||||
<SubMenu title="子菜单">
|
||||
<Menu.Item>第三个菜单项</Menu.Item>
|
||||
<Menu.Item>第四个菜单项</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<Dropdown overlay={menu}>
|
||||
|
||||
@@ -9,16 +9,18 @@
|
||||
````jsx
|
||||
import { Menu, Dropdown, Icon } from 'antd';
|
||||
|
||||
const menu = <Menu>
|
||||
<Menu.Item key="0">
|
||||
<a href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="1">
|
||||
<a href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Divider/>
|
||||
<Menu.Item key="3">第三个菜单项</Menu.Item>
|
||||
</Menu>;
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="0">
|
||||
<a href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="1">
|
||||
<a href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item key="3">第三个菜单项</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Dropdown overlay={menu} trigger={['click']}>
|
||||
|
||||
@@ -3,34 +3,38 @@ import Button from '../button';
|
||||
import Icon from '../icon';
|
||||
import Dropdown from './dropdown';
|
||||
const ButtonGroup = Button.Group;
|
||||
|
||||
const align = {
|
||||
points: ['tr', 'br'],
|
||||
overlay: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
offset: [0, 3],
|
||||
targetOffset: [0, 0],
|
||||
};
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
align: align,
|
||||
align: {
|
||||
points: ['tr', 'br'],
|
||||
overlay: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
offset: [0, 4],
|
||||
targetOffset: [0, 0],
|
||||
},
|
||||
type: 'default',
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return <ButtonGroup className="ant-dropdown-button">
|
||||
<Button type={this.props.type}>
|
||||
{this.props.children}
|
||||
</Button>
|
||||
<Dropdown {...this.props}>
|
||||
<Button type={this.props.type}>
|
||||
<Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</ButtonGroup>;
|
||||
const { type, overlay, trigger, align, children, className, ...restProps } = this.props;
|
||||
const cls = classNames({
|
||||
'ant-dropdown-button': true,
|
||||
className: !!className,
|
||||
});
|
||||
return (
|
||||
<ButtonGroup {...restProps} className={cls}>
|
||||
<Button type={type}>{children}</Button>
|
||||
<Dropdown align={align} overlay={overlay} trigger={trigger}>
|
||||
<Button type={type}>
|
||||
<Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,13 +2,13 @@ import React from 'react';
|
||||
import Dropdown from 'rc-dropdown';
|
||||
|
||||
export default React.createClass({
|
||||
getDefaultProps: function () {
|
||||
getDefaultProps() {
|
||||
return {
|
||||
transitionName: 'slide-up',
|
||||
prefixCls: 'ant-dropdown',
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
render() {
|
||||
const { overlay, ...otherProps } = this.props;
|
||||
const menu = React.cloneElement(overlay, {
|
||||
openTransitionName: 'zoom-big',
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 |
|
||||
|-------------|------------------|--------------------|--------------|
|
||||
| trigger | 触发下拉的行为 | "click" or "hover" | hover |
|
||||
| trigger | 触发下拉的行为 | ['click'] or ['hover'] | ['hover'] |
|
||||
| overlay | 菜单节点 | [Menu](/components/menu) | 无 |
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,12 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
class Form extends React.Component {
|
||||
getChildContext() {
|
||||
return {
|
||||
form: this.props.form,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, className } = this.props;
|
||||
const formClassName = classNames({
|
||||
@@ -22,6 +28,7 @@ Form.propTypes = {
|
||||
prefixCls: React.PropTypes.string,
|
||||
horizontal: React.PropTypes.bool,
|
||||
inline: React.PropTypes.bool,
|
||||
form: React.PropTypes.object,
|
||||
children: React.PropTypes.any,
|
||||
onSubmit: React.PropTypes.func,
|
||||
};
|
||||
@@ -30,4 +37,8 @@ Form.defaultProps = {
|
||||
prefixCls: 'ant-form',
|
||||
};
|
||||
|
||||
Form.childContextTypes = {
|
||||
form: React.PropTypes.object,
|
||||
};
|
||||
|
||||
module.exports = Form;
|
||||
|
||||
@@ -2,8 +2,8 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
function prefixClsFn(prefixCls, ...args) {
|
||||
return args.map((s)=> {
|
||||
return prefixCls + '-' + s;
|
||||
return args.map((s) => {
|
||||
return `${prefixCls}-${s}`;
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
@@ -12,37 +12,78 @@ class FormItem extends React.Component {
|
||||
if (!colDef) {
|
||||
return '';
|
||||
}
|
||||
const {span, offset} = colDef;
|
||||
const col = span ? 'col-' + span : '';
|
||||
const offsetCol = offset ? ' col-offset-' + offset : '';
|
||||
const { span, offset } = colDef;
|
||||
const col = span ? `col-${span}` : '';
|
||||
const offsetCol = offset ? ` col-offset-${offset}` : '';
|
||||
return col + offsetCol;
|
||||
}
|
||||
|
||||
getHelpMsg() {
|
||||
const context = this.context;
|
||||
const props = this.props;
|
||||
if (props.help === undefined && context.form) {
|
||||
return (context.form.getFieldError(this.getId()) || []).join(', ');
|
||||
}
|
||||
|
||||
return props.help;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.props.children.props && this.props.children.props.id;
|
||||
}
|
||||
|
||||
getMeta() {
|
||||
return this.props.children.props && this.props.children.props.__meta;
|
||||
}
|
||||
|
||||
renderHelp() {
|
||||
const prefixCls = this.props.prefixCls;
|
||||
const props = this.props;
|
||||
const prefixCls = props.prefixCls;
|
||||
const help = this.getHelpMsg();
|
||||
return (
|
||||
<div className={this.props.help ? prefixClsFn(prefixCls, 'explain') : ''} key="help">
|
||||
{this.props.help}
|
||||
<div className={!!help ? prefixClsFn(prefixCls, 'explain') : ''} key="help">
|
||||
{ help }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderValidateWrapper(c1, c2) {
|
||||
getValidateStatus() {
|
||||
const { isFieldValidating, getFieldError, getFieldValue } = this.context.form;
|
||||
const field = this.getId();
|
||||
|
||||
if (isFieldValidating(field)) {
|
||||
return 'validating';
|
||||
} else if (!!getFieldError(field)) {
|
||||
return 'error';
|
||||
} else if (getFieldValue(field) !== undefined) {
|
||||
return 'success';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
renderValidateWrapper(c1, c2, c3) {
|
||||
let classes = '';
|
||||
if (this.props.validateStatus) {
|
||||
const form = this.context.form;
|
||||
const props = this.props;
|
||||
const validateStatus = (props.validateStatus === undefined && form) ?
|
||||
this.getValidateStatus() :
|
||||
props.validateStatus;
|
||||
|
||||
if (validateStatus) {
|
||||
classes = classNames(
|
||||
{
|
||||
'has-feedback': this.props.hasFeedback,
|
||||
'has-success': this.props.validateStatus === 'success',
|
||||
'has-warning': this.props.validateStatus === 'warning',
|
||||
'has-error': this.props.validateStatus === 'error',
|
||||
'is-validating': this.props.validateStatus === 'validating',
|
||||
'has-feedback': props.hasFeedback,
|
||||
'has-success': validateStatus === 'success',
|
||||
'has-warning': validateStatus === 'warning',
|
||||
'has-error': validateStatus === 'error',
|
||||
'is-validating': validateStatus === 'validating',
|
||||
}
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className={classes}>
|
||||
{c1} {c2}
|
||||
<div className={`${this.props.prefixCls}-item-control ${classes}`}>
|
||||
{c1}{c2}{c3}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -56,59 +97,64 @@ class FormItem extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderLabel() {
|
||||
const labelCol = this.props.labelCol;
|
||||
const required = this.props.required ? 'required' : '';
|
||||
isRequired() {
|
||||
if (this.context.form) {
|
||||
const meta = this.getMeta() || {};
|
||||
const validate = (meta.validate || []);
|
||||
|
||||
return this.props.label ? (
|
||||
<label htmlFor={this.props.id} className={this._getLayoutClass(labelCol)} required={required} key="label">
|
||||
{this.props.label}
|
||||
return validate.filter((item) => !!item.rules).some((item) => {
|
||||
return item.rules.some((rule) => rule.required);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
renderLabel() {
|
||||
const props = this.props;
|
||||
const labelCol = props.labelCol;
|
||||
const required = props.required === undefined ?
|
||||
this.isRequired() :
|
||||
props.required;
|
||||
|
||||
const className = classNames({
|
||||
[this._getLayoutClass(labelCol)]: true,
|
||||
[`${props.prefixCls}-item-required`]: required,
|
||||
});
|
||||
|
||||
return props.label ? (
|
||||
<label htmlFor={props.id || this.getId()} className={className} key="label">
|
||||
{props.label}
|
||||
</label>
|
||||
) : null;
|
||||
}
|
||||
|
||||
renderChildren() {
|
||||
const props = this.props;
|
||||
const children = React.Children.map(props.children, (child) => {
|
||||
if (child && typeof child.type === 'function' && !child.props.size) {
|
||||
return React.cloneElement(child, { size: 'large' });
|
||||
}
|
||||
return child;
|
||||
});
|
||||
return [
|
||||
this.renderLabel(),
|
||||
this.renderWrapper(
|
||||
this.renderValidateWrapper(
|
||||
this.props.children,
|
||||
this.renderHelp()
|
||||
children,
|
||||
this.renderHelp(),
|
||||
props.extra
|
||||
)
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
// 判断是否要 `.ant-form-item-compact` 样式类
|
||||
_isCompact(children) {
|
||||
const compactControls = ['checkbox', 'radio', 'radio-group', 'static', 'file'];
|
||||
let isCompact = false;
|
||||
|
||||
if (!Array.isArray(children)) {
|
||||
children = [children];
|
||||
}
|
||||
children.map((child) => {
|
||||
const type = child.props && child.props.type;
|
||||
let prefixCls = child.props && child.props.prefixCls;
|
||||
prefixCls = prefixCls ? prefixCls.substring(prefixCls.indexOf('-') + 1) : '';
|
||||
|
||||
if ((type && compactControls.indexOf(type) > -1) || (prefixCls && compactControls.indexOf(prefixCls) > -1)) {
|
||||
isCompact = true;
|
||||
} else if (child.props && typeof child.props.children === 'object') {
|
||||
isCompact = this._isCompact(child.props.children);
|
||||
}
|
||||
});
|
||||
|
||||
return isCompact;
|
||||
}
|
||||
|
||||
renderFormItem(children) {
|
||||
const props = this.props;
|
||||
const prefixCls = props.prefixCls;
|
||||
const itemClassName = {
|
||||
[`${prefixCls}-item`]: true,
|
||||
[`${prefixCls}-item-compact`]: this._isCompact(props.children),
|
||||
[`${prefixCls}-item-with-help`]: !!props.help,
|
||||
[`${prefixCls}-item-with-help`]: !!this.getHelpMsg(),
|
||||
[`${props.className}`]: !!props.className,
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -128,18 +174,22 @@ FormItem.propTypes = {
|
||||
prefixCls: React.PropTypes.string,
|
||||
label: React.PropTypes.node,
|
||||
labelCol: React.PropTypes.object,
|
||||
help: React.PropTypes.node,
|
||||
help: React.PropTypes.oneOfType([React.PropTypes.node, React.PropTypes.bool]),
|
||||
validateStatus: React.PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
|
||||
hasFeedback: React.PropTypes.bool,
|
||||
wrapperCol: React.PropTypes.object,
|
||||
className: React.PropTypes.string,
|
||||
id: React.PropTypes.string,
|
||||
children: React.PropTypes.node,
|
||||
};
|
||||
|
||||
FormItem.defaultProps = {
|
||||
hasFeedback: false,
|
||||
required: false,
|
||||
prefixCls: 'ant-form',
|
||||
};
|
||||
|
||||
FormItem.contextTypes = {
|
||||
form: React.PropTypes.object,
|
||||
};
|
||||
|
||||
module.exports = FormItem;
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
function merge() {
|
||||
const ret = {};
|
||||
const args = [].slice.call(arguments, 0);
|
||||
args.forEach((a)=> {
|
||||
Object.keys(a).forEach((k)=> {
|
||||
ret[k] = a[k];
|
||||
});
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
const ValueMixin = {
|
||||
setValue(field, e) {
|
||||
let v = e;
|
||||
const target = e && e.target;
|
||||
if (target) {
|
||||
if ((target.nodeName + '').toLowerCase() === 'input' &&
|
||||
if ((`${target.nodeName}`).toLowerCase() === 'input' &&
|
||||
target.type === 'checkbox') {
|
||||
v = target.checked;
|
||||
} else {
|
||||
@@ -24,7 +13,10 @@ const ValueMixin = {
|
||||
const newFormData = {};
|
||||
newFormData[field] = v;
|
||||
this.setState({
|
||||
formData: merge(this.state.formData, newFormData),
|
||||
formData: {
|
||||
...this.state.formData,
|
||||
...newFormData,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -18,66 +18,66 @@ ReactDOM.render(
|
||||
<Col span="8">
|
||||
<FormItem
|
||||
label="搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="较长搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="8">
|
||||
<FormItem
|
||||
label="搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="较长搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="8">
|
||||
<FormItem
|
||||
label="搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="较长搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="搜索名称:"
|
||||
labelCol={{span: 10}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 10 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input placeholder="请输入搜索名称" />
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span="8" offset="16" style={{textAlign: 'right'}}>
|
||||
<Col span="8" offset="16" style={{ textAlign: 'right' }}>
|
||||
<Button type="primary" htmlType="submit">搜索</Button>
|
||||
<Button type="ghost">清除条件</Button>
|
||||
</Col>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# 禁用状态
|
||||
|
||||
- order: 7
|
||||
|
||||
1) 单独为输入控件设置 `disabled` 属性;
|
||||
|
||||
2) 为 `<fieldset>` 设置 `disabled` 属性,可以禁用 `<fieldset>` 中包含的所有控件。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import {Row, Col, Button, Input, Form} from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
|
||||
ReactDOM.render(
|
||||
<Form horizontal>
|
||||
<FormItem
|
||||
label="单独禁用输入框:"
|
||||
labelCol={{span:5}}
|
||||
wrapperCol={{span:12}}>
|
||||
<Input defaultValue="我是禁用的" disabled />
|
||||
</FormItem>
|
||||
|
||||
<fieldset disabled>
|
||||
<legend>禁用的 fieldset</legend>
|
||||
<FormItem
|
||||
id="userName"
|
||||
label="用户名:"
|
||||
labelCol={{span:5}}
|
||||
wrapperCol={{span:12}}
|
||||
required>
|
||||
<p className="ant-form-text">大眼萌 minion</p>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
id="password"
|
||||
label="密码:"
|
||||
labelCol={{span:5}}
|
||||
wrapperCol={{span:12}}
|
||||
required>
|
||||
<Input type="password" defaultValue="123456" id="password" />
|
||||
</FormItem>
|
||||
<Row>
|
||||
<Col span="12" offset="5">
|
||||
<Button htmlType="submit" type="primary">确定</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</fieldset>
|
||||
</Form>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -9,13 +9,13 @@
|
||||
---
|
||||
|
||||
````jsx
|
||||
import {Form, Input, Select, Checkbox, Radio} from 'antd';
|
||||
import { Form, Input, Select, Checkbox, Radio } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
function handleSelectChange(value) {
|
||||
console.log('selected ' + value);
|
||||
console.log(`selected ${value}`);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
@@ -23,25 +23,25 @@ ReactDOM.render(
|
||||
<FormItem
|
||||
id="control-input"
|
||||
label="输入框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input id="control-input" placeholder="Please enter..." />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
id="control-textarea"
|
||||
label="文本域:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 14}}>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Input type="textarea" id="control-textarea" rows="3" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
id="select"
|
||||
label="Select 选择器:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 14}}>
|
||||
<Select id="select" size="large" defaultValue="lucy" style={{width:200}} onChange={handleSelectChange}>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 14 }}>
|
||||
<Select id="select" size="large" defaultValue="lucy" style={{ width: 200 }} onChange={handleSelectChange}>
|
||||
<Option value="jack">jack</Option>
|
||||
<Option value="lucy">lucy</Option>
|
||||
<Option value="disabled" disabled>disabled</Option>
|
||||
@@ -51,8 +51,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="Checkbox 多选框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 18}} >
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }} >
|
||||
<label className="ant-checkbox-vertical">
|
||||
<Checkbox />选项一
|
||||
</label>
|
||||
@@ -66,8 +66,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="Checkbox 多选框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 18}} >
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }} >
|
||||
<label className="ant-checkbox-inline">
|
||||
<Checkbox />选项一
|
||||
</label>
|
||||
@@ -81,8 +81,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="Radio 单选框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 18}} >
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }} >
|
||||
<RadioGroup value="b">
|
||||
<Radio value="a">A</Radio>
|
||||
<Radio value="b">B</Radio>
|
||||
|
||||
@@ -1,85 +1,59 @@
|
||||
# 水平排列的表单
|
||||
# 典型表单
|
||||
|
||||
- order: 2
|
||||
|
||||
示例展示了如何通过使用 `Form.ValueMixin` 来获取和更新表单提交的数值。
|
||||
|
||||
**注意:** 1)需要为每个输入控件声明 `name` 属性;2)ES6 语法 [不支持 `mixins`](https://facebook.github.io/react/docs/reusable-components.html#no-mixins);
|
||||
示例展示了如何通过使用 `Form.create` 来获取和更新表单提交的数值。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import {Form, Input, Button, Checkbox, Radio, Row, Col, message} from 'antd';
|
||||
import { Form, Input, Button, Checkbox, Radio, Row, Col, Tooltip, Icon } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const Demo = React.createClass({
|
||||
mixins: [Form.ValueMixin],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
formData: {
|
||||
userName: '大眼萌 minion',
|
||||
password: undefined,
|
||||
gender: 'male',
|
||||
remark: undefined,
|
||||
agreement: undefined,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
let Demo = React.createClass({
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
message.success('收到表单值~~~ :' + JSON.stringify(this.state.formData, function(k, v) {
|
||||
if (typeof v === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
return v;
|
||||
}));
|
||||
console.log('收到表单值:', this.props.form.getFieldsValue());
|
||||
},
|
||||
|
||||
render() {
|
||||
const formData = this.state.formData;
|
||||
const { getFieldProps } = this.props.form;
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 14 },
|
||||
};
|
||||
return (
|
||||
<Form horizontal onSubmit={this.handleSubmit}>
|
||||
<FormItem
|
||||
label="用户名:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 6}}
|
||||
required>
|
||||
{...formItemLayout}
|
||||
label="用户名:">
|
||||
<p className="ant-form-text" id="userName" name="userName">大眼萌 minion</p>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
id="password"
|
||||
label="密码:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 14}}
|
||||
required>
|
||||
<Input type="password" id="password" name="password" placeholder="请输入密码" value={formData.password} onChange={this.setValue.bind(this, 'password')} />
|
||||
{...formItemLayout}
|
||||
label="密码:">
|
||||
<Input type="password" {...getFieldProps('pass')} placeholder="请输入密码" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="您的性别:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 14}}
|
||||
required>
|
||||
<RadioGroup name="gender" value={formData.gender} onChange={this.setValue.bind(this, 'gender')} >
|
||||
<Radio value="male">男的</Radio>
|
||||
<Radio value="female">女的</Radio>
|
||||
</RadioGroup>
|
||||
{...formItemLayout}
|
||||
label="您的性别:">
|
||||
<RadioGroup {...getFieldProps('gender', { initialValue: 'female' })}>
|
||||
<Radio value="male">男的</Radio>
|
||||
<Radio value="female">女的</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
id="remark"
|
||||
{...formItemLayout}
|
||||
label="备注:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 14}}
|
||||
required
|
||||
help="随便写点什么">
|
||||
<Input type="textarea" placeholder="随便写" id="remark" name="remark" value={formData.remark} onChange={this.setValue.bind(this, 'remark')} />
|
||||
<Input type="textarea" placeholder="随便写" {...getFieldProps('remark')} />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
wrapperCol={{span: 14, offset: 6}} >
|
||||
{...formItemLayout}
|
||||
label={<span>卖身华府 <Tooltip title="我为秋香"><Icon type="question-circle-o" /></Tooltip> :</span>}>
|
||||
<label>
|
||||
<Checkbox name="agreement" value={formData.agreement} onChange={this.setValue.bind(this, 'agreement')} /> 同意
|
||||
<Checkbox {...getFieldProps('agreement')} />同意
|
||||
</label>
|
||||
</FormItem>
|
||||
<Row>
|
||||
@@ -92,5 +66,7 @@ const Demo = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
Demo = Form.create()(Demo);
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
@@ -7,49 +7,33 @@
|
||||
---
|
||||
|
||||
````jsx
|
||||
import {Form, Input, Button, Checkbox, message} from 'antd';
|
||||
import { Form, Input, Button, Checkbox } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const Demo = React.createClass({
|
||||
mixins: [Form.ValueMixin],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
formData: {
|
||||
userName: undefined,
|
||||
password: undefined,
|
||||
agreement: undefined,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
let Demo = React.createClass({
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
message.success('收到表单值~~~ :' + JSON.stringify(this.state.formData, function(k, v) {
|
||||
if (typeof v === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
return v;
|
||||
}));
|
||||
console.log('收到表单值:', this.props.form.getFieldsValue());
|
||||
},
|
||||
|
||||
render() {
|
||||
const formData = this.state.formData;
|
||||
const { getFieldProps } = this.props.form;
|
||||
return (
|
||||
<Form inline onSubmit={this.handleSubmit}>
|
||||
<FormItem
|
||||
id="userName"
|
||||
label="账户:">
|
||||
<Input placeholder="请输入账户名" id="userName" name="userName" onChange={this.setValue.bind(this, 'userName')} value={formData.userName} />
|
||||
<Input placeholder="请输入账户名"
|
||||
{...getFieldProps('userName')} />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
id="password"
|
||||
label="密码:">
|
||||
<Input type="password" placeholder="请输入密码" id="password" name="password" onChange={this.setValue.bind(this, 'password')} value={formData.password} />
|
||||
<Input type="password" placeholder="请输入密码"
|
||||
{...getFieldProps('password')} />
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<label className="ant-checkbox-inline">
|
||||
<Checkbox name="agreement" value={formData.agreement} onChange={this.setValue.bind(this, 'agreement')} /> 记住我
|
||||
<Checkbox
|
||||
{...getFieldProps('agreement')} />记住我
|
||||
</label>
|
||||
</FormItem>
|
||||
<Button type="primary" htmlType="submit">登录</Button>
|
||||
@@ -58,5 +42,7 @@ const Demo = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
Demo = Form.create()(Demo);
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
---
|
||||
|
||||
````jsx
|
||||
import {Form, Input, Select, Row, Col} from 'antd';
|
||||
import { Form, Input, Select, Row, Col } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
const InputGroup = Input.Group;
|
||||
const Option = Select.Option;
|
||||
@@ -16,26 +16,26 @@ ReactDOM.render(
|
||||
<Form horizontal>
|
||||
<FormItem
|
||||
label="标签输入框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 16}}>
|
||||
<Input addonBefore="Http://" defaultValue="mysite.com" id="site1"/>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 16 }}>
|
||||
<Input addonBefore="Http://" defaultValue="mysite.com" id="site1" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="标签输入框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 16}}>
|
||||
<Input addonBefore="Http://" addonAfter=".com" defaultValue="mysite" id="site2"/>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 16 }}>
|
||||
<Input addonBefore="Http://" addonAfter=".com" defaultValue="mysite" id="site2" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="select 标签输入框:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 16}}>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 16 }}>
|
||||
<InputGroup>
|
||||
<Input id="site4" placeholder="www.mysite" />
|
||||
<div className="ant-input-group-wrap">
|
||||
<Select defaultValue=".com" style={{width:70}}>
|
||||
<Select defaultValue=".com" style={{ width: 70 }}>
|
||||
<Option value=".com">.com</Option>
|
||||
<Option value=".jp">.jp</Option>
|
||||
<Option value=".cn">.cn</Option>
|
||||
@@ -47,8 +47,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="输入身份证:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 16}}>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 16 }}>
|
||||
<InputGroup>
|
||||
<Col span="6">
|
||||
<Input id="certNo1" />
|
||||
@@ -67,8 +67,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="电话号码:"
|
||||
labelCol={{span: 6}}
|
||||
wrapperCol={{span: 16}}>
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 16 }}>
|
||||
<Row>
|
||||
<Col span="4">
|
||||
<Input id="tel1" defaultValue="086" />
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
````jsx
|
||||
import {Row, Col, Input} from 'antd';
|
||||
import { Row, Col, Input } from 'antd';
|
||||
const InputGroup = Input.Group;
|
||||
|
||||
ReactDOM.render(
|
||||
|
||||
@@ -7,67 +7,43 @@
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Form, Select, InputNumber, DatePicker, Switch,
|
||||
Slider, Button, message, Row, Col, Upload, Icon } from 'antd';
|
||||
import { Form, Select, InputNumber, DatePicker, TimePicker, Switch, Radio,
|
||||
Slider, Button, Row, Col, Upload, Icon } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
const RadioButton = Radio.Button;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const Demo = React.createClass({
|
||||
mixins: [Form.ValueMixin],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
formData: {
|
||||
inputNumber: undefined,
|
||||
static: '唧唧复唧唧木兰当户织呀',
|
||||
switch: undefined,
|
||||
slider: undefined,
|
||||
select: undefined,
|
||||
startDate: undefined,
|
||||
endDate: undefined,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
handleUpload(info) {
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
message.success(info.file.name + ' 上传成功。');
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(info.file.name + ' 上传失败。');
|
||||
}
|
||||
},
|
||||
|
||||
let Demo = React.createClass({
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
message.success('收到表单值~~~ :' + JSON.stringify(this.state.formData, function(k, v) {
|
||||
if (typeof v === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
return v;
|
||||
}));
|
||||
console.log('收到表单值:', this.props.form.getFieldsValue());
|
||||
},
|
||||
|
||||
normFile(e) {
|
||||
if (Array.isArray(e)) {
|
||||
return e;
|
||||
}
|
||||
return e && e.fileList;
|
||||
},
|
||||
|
||||
render() {
|
||||
const formData = this.state.formData;
|
||||
const { getFieldProps } = this.props.form;
|
||||
return (
|
||||
<Form horizontal onSubmit={this.handleSubmit} >
|
||||
<FormItem
|
||||
label="InputNumber 数字输入框:"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 10}}
|
||||
required>
|
||||
<InputNumber size="large" min={1} max={10} style={{width:100}} defaultValue={3} name="inputNumber" onChange={this.setValue.bind(this, 'inputNumber')} value={formData.inputNumber} />
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 10 }}>
|
||||
<InputNumber min={1} max={10} style={{ width: 100 }}
|
||||
{...getFieldProps('inputNumber', { initialValue: 3 })} />
|
||||
<span className="ant-form-text"> 台机器</span>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="我是标题:"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 10}}
|
||||
required>
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 10 }}>
|
||||
<p className="ant-form-text" id="static" name="static">唧唧复唧唧木兰当户织呀</p>
|
||||
<p className="ant-form-text">
|
||||
<a href="#">链接文字</a>
|
||||
@@ -76,26 +52,27 @@ const Demo = React.createClass({
|
||||
|
||||
<FormItem
|
||||
label="Switch 开关:"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 10}}
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 10 }}
|
||||
required>
|
||||
<Switch name="switch" onChange={this.setValue.bind(this, 'switch')} value={formData.switch} />
|
||||
<Switch {...getFieldProps('switch')} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Slider 滑动输入条:"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 10}}
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 10 }}
|
||||
required>
|
||||
<Slider marks={['A', 'B', 'C', 'D', 'E', 'F', 'G']} name="slider" onChange={this.setValue.bind(this, 'slider')} />
|
||||
<Slider marks={['A', 'B', 'C', 'D', 'E', 'F', 'G']} {...getFieldProps('slider')} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Select 选择器:"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 16}}
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
required>
|
||||
<Select size="large" defaultValue="lucy" style={{width:200}} name="select" onChange={this.setValue.bind(this, 'select')} value={formData.select}>
|
||||
<Select style={{ width: 200 }}
|
||||
{...getFieldProps('select')}>
|
||||
<Option value="jack">jack</Option>
|
||||
<Option value="lucy">lucy</Option>
|
||||
<Option value="disabled" disabled>disabled</Option>
|
||||
@@ -105,30 +82,54 @@ const Demo = React.createClass({
|
||||
|
||||
<FormItem
|
||||
label="DatePicker 日期选择框:"
|
||||
labelCol={{span: 8}}
|
||||
labelCol={{ span: 8 }}
|
||||
required>
|
||||
<Col span="6">
|
||||
<DatePicker name="startDate" onChange={this.setValue.bind(this, 'startDate')} value={formData.startDate} />
|
||||
<DatePicker {...getFieldProps('startDate')} />
|
||||
</Col>
|
||||
<Col span="1">
|
||||
<p className="ant-form-split">-</p>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
<DatePicker name="endDate" onChange={this.setValue.bind(this, 'endDate')} value={formData.endDate} />
|
||||
<DatePicker {...getFieldProps('endDate')} />
|
||||
</Col>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="TimePicker 时间选择器:"
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
required>
|
||||
<TimePicker {...getFieldProps('time')} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="选项:"
|
||||
labelCol={{ span: 8 }}>
|
||||
<RadioGroup {...getFieldProps('rg')}>
|
||||
<RadioButton value="a">选项一</RadioButton>
|
||||
<RadioButton value="b">选项二</RadioButton>
|
||||
<RadioButton value="c">选项三</RadioButton>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="logo图:"
|
||||
labelCol={{span: 8}}
|
||||
wrapperCol={{span: 16}}
|
||||
help="提示信息要长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长">
|
||||
<Upload name="logo" action="/upload.do" listType="picture" onChange={this.handleUpload}>
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
help="提示信息要长长长长长长长长长长长长长长">
|
||||
<Upload name="logo" action="/upload.do" listType="picture" onChange={this.handleUpload}
|
||||
{...getFieldProps('upload', {
|
||||
valuePropName: 'fileList',
|
||||
normalize: this.normFile
|
||||
})}
|
||||
>
|
||||
<Button type="ghost">
|
||||
<Icon type="upload" /> 点击上传
|
||||
</Button>
|
||||
</Upload>
|
||||
</FormItem>
|
||||
<Row>
|
||||
<Row style={{ marginTop: 24 }}>
|
||||
<Col span="16" offset="8">
|
||||
<Button type="primary" htmlType="submit">确定</Button>
|
||||
</Col>
|
||||
@@ -138,5 +139,7 @@ const Demo = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
Demo = Form.create()(Demo);
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
@@ -43,19 +43,21 @@ const SearchInput = React.createClass({
|
||||
'ant-search-input': true,
|
||||
'ant-search-input-focus': this.state.focus,
|
||||
});
|
||||
return <InputGroup className={searchCls} style={this.props.style}>
|
||||
<Input {...this.props} value={this.state.value} onChange={this.handleInputChange}
|
||||
onFocus={this.handleFocusBlur} onBlur={this.handleFocusBlur} />
|
||||
<div className="ant-input-group-wrap">
|
||||
<Button className={btnCls} onClick={this.handleSearch}>
|
||||
<Icon type="search" />
|
||||
</Button>
|
||||
</div>
|
||||
</InputGroup>;
|
||||
return (
|
||||
<InputGroup className={searchCls} style={this.props.style}>
|
||||
<Input {...this.props} value={this.state.value} onChange={this.handleInputChange}
|
||||
onFocus={this.handleFocusBlur} onBlur={this.handleFocusBlur} />
|
||||
<div className="ant-input-group-wrap">
|
||||
<Button className={btnCls} onClick={this.handleSearch}>
|
||||
<Icon type="search" />
|
||||
</Button>
|
||||
</div>
|
||||
</InputGroup>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(
|
||||
<SearchInput placeholder="input search text" style={{width: 200}} />
|
||||
<SearchInput placeholder="input search text" style={{ width: 200 }} />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
176
components/form/demo/validate-basic.md
Normal file
176
components/form/demo/validate-basic.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# 表单校验
|
||||
|
||||
- order: 11
|
||||
|
||||
基本的表单校验例子。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Button, Form, Input } from 'antd';
|
||||
const createForm = Form.create;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
function noop() {
|
||||
return false;
|
||||
}
|
||||
|
||||
class BasicDemo extends React.Component {
|
||||
getValidateStatus(field) {
|
||||
const { isFieldValidating, getFieldError, getFieldValue } = this.props.form;
|
||||
|
||||
if (isFieldValidating(field)) {
|
||||
return 'validating';
|
||||
} else if (!!getFieldError(field)) {
|
||||
return 'error';
|
||||
} else if (getFieldValue(field)) {
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
|
||||
handleReset(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.resetFields();
|
||||
}
|
||||
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((errors, values) => {
|
||||
if (!!errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
console.log('Submit!!!');
|
||||
console.log(values);
|
||||
});
|
||||
}
|
||||
|
||||
userExists(rule, value, callback) {
|
||||
if (!value) {
|
||||
callback();
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
if (value === 'JasonWood') {
|
||||
callback([new Error('抱歉,该用户名已被占用。')]);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}, 800);
|
||||
}
|
||||
}
|
||||
|
||||
checkPass(rule, value, callback) {
|
||||
const { validateFields } = this.props.form;
|
||||
if (value) {
|
||||
validateFields(['rePasswd']);
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
checkPass2(rule, value, callback) {
|
||||
const { getFieldValue } = this.props.form;
|
||||
if (value && value !== getFieldValue('passwd')) {
|
||||
callback('两次输入密码不一致!');
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { getFieldProps, getFieldError, isFieldValidating } = this.props.form;
|
||||
const nameProps = getFieldProps('name', {
|
||||
rules: [
|
||||
{ required: true, min: 5, message: '用户名至少为 5 个字符' },
|
||||
{ validator: this.userExists },
|
||||
],
|
||||
});
|
||||
const emailProps = getFieldProps('email', {
|
||||
validate: [{
|
||||
rules: [
|
||||
{ required: true },
|
||||
],
|
||||
trigger: 'onBlur',
|
||||
}, {
|
||||
rules: [
|
||||
{ type: 'email', message: '请输入正确的邮箱地址' },
|
||||
],
|
||||
trigger: ['onBlur', 'onChange'],
|
||||
}]
|
||||
});
|
||||
const passwdProps = getFieldProps('passwd', {
|
||||
rules: [
|
||||
{ required: true, whitespace: true, message: '请填写密码' },
|
||||
{ validator: this.checkPass.bind(this) },
|
||||
],
|
||||
});
|
||||
const rePasswdProps = getFieldProps('rePasswd', {
|
||||
rules: [{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
message: '请再次输入密码',
|
||||
}, {
|
||||
validator: this.checkPass2.bind(this),
|
||||
}],
|
||||
});
|
||||
const textareaProps = getFieldProps('textarea', {
|
||||
rules: [
|
||||
{ required: true, message: '真的不打算写点什么吗?' },
|
||||
],
|
||||
});
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 7 },
|
||||
wrapperCol: { span: 12 },
|
||||
};
|
||||
return (
|
||||
<Form horizontal form={this.props.form}>
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="用户名:"
|
||||
hasFeedback
|
||||
help={isFieldValidating('name') ? '校验中...' : (getFieldError('name') || []).join(', ')}>
|
||||
<Input {...nameProps} placeholder="实时校验,输入 JasonWood 看看" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="邮箱:"
|
||||
hasFeedback>
|
||||
<Input {...emailProps} type="email" placeholder="onBlur 与 onChange 相结合" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="密码:"
|
||||
hasFeedback>
|
||||
<Input {...passwdProps} type="password" autoComplete="off"
|
||||
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="确认密码:"
|
||||
hasFeedback>
|
||||
<Input {...rePasswdProps} type="password" autoComplete="off" placeholder="两次输入密码保持一致"
|
||||
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="备注:">
|
||||
<Input {...textareaProps} type="textarea" placeholder="随便写" id="textarea" name="textarea" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem wrapperCol={{ span: 12, offset: 7 }}>
|
||||
<Button type="primary" onClick={this.handleSubmit.bind(this)}>确定</Button>
|
||||
|
||||
<Button type="ghost" onClick={this.handleReset.bind(this)}>重置</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BasicDemo = createForm()(BasicDemo);
|
||||
|
||||
ReactDOM.render(<BasicDemo />, mountNode);
|
||||
````
|
||||
244
components/form/demo/validate-customized.md
Normal file
244
components/form/demo/validate-customized.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# 自定义校验规则
|
||||
|
||||
- order: 13
|
||||
|
||||
密码校验实例。
|
||||
|
||||
这里使用了 `this.props.form.validateFields` 方法,在对第一次输入的密码进行校验时会触发二次密码的校验。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Button, Form, Input, Row, Col, Modal } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
const createForm = Form.create;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
function noop() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let Demo = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
passBarShow: false, // 是否显示密码强度提示条
|
||||
rePassBarShow: false,
|
||||
passStrength: 'L', // 密码强度
|
||||
rePassStrength: 'L',
|
||||
visible: false,
|
||||
};
|
||||
},
|
||||
|
||||
handleSubmit() {
|
||||
this.props.form.validateFields((errors, values) => {
|
||||
if (!!errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
console.log('Submit!!!');
|
||||
console.log(values);
|
||||
this.setState({ visible: false });
|
||||
});
|
||||
},
|
||||
|
||||
getPassStrenth(value, type) {
|
||||
if (value) {
|
||||
let strength;
|
||||
// 密码强度的校验规则自定义,这里只是做个简单的示例
|
||||
if (value.length < 6) {
|
||||
strength = 'L';
|
||||
} else if (value.length <= 9) {
|
||||
strength = 'M';
|
||||
} else {
|
||||
strength = 'H';
|
||||
}
|
||||
if (type === 'pass') {
|
||||
this.setState({ passBarShow: true, passStrength: strength });
|
||||
} else {
|
||||
this.setState({ rePassBarShow: true, rePassStrength: strength });
|
||||
}
|
||||
} else {
|
||||
if (type === 'pass') {
|
||||
this.setState({ passBarShow: false });
|
||||
} else {
|
||||
this.setState({ rePassBarShow: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showModal() {
|
||||
this.setState({ visible: true });
|
||||
},
|
||||
|
||||
hideModal() {
|
||||
this.setState({ visible: false });
|
||||
},
|
||||
|
||||
checkPass(rule, value, callback) {
|
||||
const form = this.props.form;
|
||||
this.getPassStrenth(value, 'pass');
|
||||
|
||||
if (form.getFieldValue('pass')) {
|
||||
form.validateFields(['rePass'], { force: true });
|
||||
}
|
||||
|
||||
callback();
|
||||
},
|
||||
|
||||
checkPass2(rule, value, callback) {
|
||||
const form = this.props.form;
|
||||
this.getPassStrenth(value, 'rePass');
|
||||
|
||||
if (value && value !== form.getFieldValue('pass')) {
|
||||
callback('两次输入密码不一致!');
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
renderPassStrengthBar(type) {
|
||||
const strength = type === 'pass' ? this.state.passStrength : this.state.rePassStrength;
|
||||
const classSet = classNames({
|
||||
'ant-pwd-strength': true,
|
||||
'ant-pwd-strength-low': strength === 'L',
|
||||
'ant-pwd-strength-medium': strength === 'M',
|
||||
'ant-pwd-strength-high': strength === 'H'
|
||||
});
|
||||
const level = {
|
||||
L: '低',
|
||||
M: '中',
|
||||
H: '高'
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul className={classSet}>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-1"></li>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-2"></li>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-3"></li>
|
||||
<span className="ant-form-text">
|
||||
{level[strength]}
|
||||
</span>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
render() {
|
||||
const { getFieldProps } = this.props.form;
|
||||
|
||||
// 如果觉得在 JSX 中写 `getFieldProps` 会影响阅读,可以先用变量保存 `getFieldProps` 的返回值。
|
||||
const passProps = getFieldProps('pass', {
|
||||
rules: [
|
||||
{ required: true, whitespace: true, message: '请填写密码' },
|
||||
{ validator: this.checkPass }
|
||||
]
|
||||
});
|
||||
const rePassProps = getFieldProps('rePass', {
|
||||
rules: [{
|
||||
required: true,
|
||||
whitespace: true,
|
||||
message: '请再次输入密码',
|
||||
}, {
|
||||
validator: this.checkPass2,
|
||||
}],
|
||||
});
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 18 },
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<Button type="primary" onClick={this.showModal}>修改密码</Button>
|
||||
<Modal title="修改密码" visible={this.state.visible} onOk={this.handleSubmit} onCancel={this.hideModal}>
|
||||
<Form horizontal form={this.props.form}>
|
||||
<Row>
|
||||
<Col span="18">
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="密码:">
|
||||
<Input {...passProps} type="password"
|
||||
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop}
|
||||
autoComplete="off" id="pass" />
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
{this.state.passBarShow ? this.renderPassStrengthBar('pass') : null}
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col span="18">
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="确认密码:">
|
||||
<Input {...rePassProps} type="password"
|
||||
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop}
|
||||
autoComplete="off" id="rePass" />
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
{this.state.rePassBarShow ? this.renderPassStrengthBar('rePass') : null}
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Demo = createForm()(Demo);
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
.ant-pwd-strength {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ant-pwd-strength-item {
|
||||
float: left;
|
||||
margin-right: 1px;
|
||||
margin-top: 12px;
|
||||
width: 19px;
|
||||
height: 8px;
|
||||
line-height: 8px;
|
||||
list-style: none;
|
||||
background-color: #f3f3f3;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
|
||||
.ant-pwd-strength-item-1 {
|
||||
border-top-left-radius: 6px;
|
||||
border-bottom-left-radius: 6px;
|
||||
}
|
||||
|
||||
.ant-pwd-strength-item-2 {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.ant-pwd-strength-item-3 {
|
||||
border-top-right-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.ant-pwd-strength-low .ant-pwd-strength-item-1, .ant-pwd-strength-medium .ant-pwd-strength-item-1, .ant-pwd-strength-high .ant-pwd-strength-item-1 {
|
||||
background-color: #FAC450;
|
||||
}
|
||||
|
||||
.ant-pwd-strength-medium .ant-pwd-strength-item-2, .ant-pwd-strength-high .ant-pwd-strength-item-2 {
|
||||
background-color: rgba(135, 208, 104, .6);
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#9987D068,endColorstr=#9987D068);
|
||||
}
|
||||
|
||||
.ant-pwd-strength-high .ant-pwd-strength-item-3 {
|
||||
background-color: #87D068;
|
||||
}
|
||||
````
|
||||
184
components/form/demo/validate-other.md
Normal file
184
components/form/demo/validate-other.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# 校验其他组件
|
||||
|
||||
- order: 12
|
||||
|
||||
提供以下组件表单域的校验:`Select` `Radio` `DatePicker` `InputNumber` `Cascader`。在 submit 时使用 `validateFieldsAndScroll`,进行校验,可以自动把不在可见范围内的校验不通过的菜单域滚动进可见范围。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Select, Radio, Checkbox, Button, DatePicker, InputNumber, Form, Cascader } from 'antd';
|
||||
const Option = Select.Option;
|
||||
const RadioGroup = Radio.Group;
|
||||
const createForm = Form.create;
|
||||
const FormItem = Form.Item;
|
||||
|
||||
let Demo = React.createClass({
|
||||
componentDidMount() {
|
||||
this.props.form.setFieldsValue({
|
||||
eat: true,
|
||||
sleep: true,
|
||||
beat: true,
|
||||
});
|
||||
},
|
||||
|
||||
handleReset(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.resetFields();
|
||||
},
|
||||
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFieldsAndScroll((errors, values) => {
|
||||
if (!!errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
console.log('Submit!!!');
|
||||
console.log(values);
|
||||
});
|
||||
},
|
||||
|
||||
checkBirthday(rule, value, callback) {
|
||||
if (value && value.getTime() >= Date.now()) {
|
||||
callback(new Error('你不可能在未来出生吧!'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
checkPrime(rule, value, callback) {
|
||||
if (value !== 11) {
|
||||
callback(new Error('8~12之间的质数明明是11啊!'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const address = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
}],
|
||||
}];
|
||||
const { getFieldProps } = this.props.form;
|
||||
const selectProps = getFieldProps('select', {
|
||||
rules: [
|
||||
{ required: true, message: '请选择您的国籍' }
|
||||
],
|
||||
});
|
||||
const multiSelectProps = getFieldProps('multiSelect', {
|
||||
rules: [
|
||||
{ required: true, message: '请选择您喜欢的颜色', type: 'array' },
|
||||
]
|
||||
});
|
||||
const radioProps = getFieldProps('radio', {
|
||||
rules: [
|
||||
{ required: true, message: '请选择您的性别' }
|
||||
]
|
||||
});
|
||||
const birthdayProps = getFieldProps('birthday', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
type: 'date',
|
||||
message: '你的生日是什么呢?',
|
||||
}, {
|
||||
validator: this.checkBirthday,
|
||||
}
|
||||
]
|
||||
});
|
||||
const primeNumberProps = getFieldProps('primeNumber', {
|
||||
rules: [{ validator: this.checkPrime }],
|
||||
});
|
||||
const addressProps = getFieldProps('address', {
|
||||
rules: [{ required: true, type: 'array' }],
|
||||
});
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 7 },
|
||||
wrapperCol: { span: 12 },
|
||||
};
|
||||
return (
|
||||
<Form horizontal form={this.props.form}>
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="国籍:">
|
||||
<Select {...selectProps} placeholder="请选择国家" style={{ width: '100%' }}>
|
||||
<Option value="china">中国</Option>
|
||||
<Option value="use">美国</Option>
|
||||
<Option value="japan">日本</Option>
|
||||
<Option value="korean">韩国</Option>
|
||||
<Option value="Thailand">泰国</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="喜欢的颜色:">
|
||||
<Select {...multiSelectProps} multiple placeholder="请选择颜色" style={{ width: '100%' }}>
|
||||
<Option value="red">红色</Option>
|
||||
<Option value="orange">橙色</Option>
|
||||
<Option value="yellow">黄色</Option>
|
||||
<Option value="green">绿色</Option>
|
||||
<Option value="blue">蓝色</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="性别:">
|
||||
<RadioGroup {...radioProps}>
|
||||
<Radio value="male">男</Radio>
|
||||
<Radio value="female">女</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="兴趣爱好:">
|
||||
<Checkbox {...getFieldProps('eat', {
|
||||
valuePropName: 'checked',
|
||||
})} />吃饭饭
|
||||
<Checkbox {...getFieldProps('sleep', {
|
||||
valuePropName: 'checked',
|
||||
})} />睡觉觉
|
||||
<Checkbox {...getFieldProps('beat', {
|
||||
valuePropName: 'checked',
|
||||
})} />打豆豆
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="生日:">
|
||||
<DatePicker {...birthdayProps} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="8~12间的质数:">
|
||||
<InputNumber {...primeNumberProps} min={8} max={12} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label="选择地址:">
|
||||
<Cascader {...addressProps} options={address} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
wrapperCol={{ span: 12, offset: 7 }} >
|
||||
<Button type="primary" onClick={this.handleSubmit}>确定</Button>
|
||||
|
||||
<Button type="ghost" onClick={this.handleReset}>重置</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Demo = createForm()(Demo);
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
@@ -20,8 +20,8 @@ ReactDOM.render(
|
||||
<Form horizontal>
|
||||
<FormItem
|
||||
label="失败校验:"
|
||||
labelCol={{span: 5}}
|
||||
wrapperCol={{span: 12}}
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 12 }}
|
||||
validateStatus="error"
|
||||
help="请输入数字和字母组合">
|
||||
<Input defaultValue="无效选择" id="error" />
|
||||
@@ -29,16 +29,16 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="警告校验:"
|
||||
labelCol={{span: 5}}
|
||||
wrapperCol={{span: 12}}
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 12 }}
|
||||
validateStatus="warning">
|
||||
<Input defaultValue="前方高能预警" id="warning" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="校验中:"
|
||||
labelCol={{span: 5}}
|
||||
wrapperCol={{span: 12}}
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 12 }}
|
||||
hasFeedback
|
||||
validateStatus="validating"
|
||||
help="信息审核中...">
|
||||
@@ -47,8 +47,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="成功校验:"
|
||||
labelCol={{span: 5}}
|
||||
wrapperCol={{span: 12}}
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 12 }}
|
||||
hasFeedback
|
||||
validateStatus="success">
|
||||
<Input defaultValue="我是正文" id="success" />
|
||||
@@ -56,8 +56,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="警告校验:"
|
||||
labelCol={{span: 5}}
|
||||
wrapperCol={{span: 12}}
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 12 }}
|
||||
hasFeedback
|
||||
validateStatus="warning">
|
||||
<Input defaultValue="前方高能预警" id="warning" />
|
||||
@@ -65,8 +65,8 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="失败校验:"
|
||||
labelCol={{span: 5}}
|
||||
wrapperCol={{span: 12}}
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 12 }}
|
||||
hasFeedback
|
||||
validateStatus="error"
|
||||
help="请输入数字和字母组合">
|
||||
@@ -75,7 +75,26 @@ ReactDOM.render(
|
||||
|
||||
<FormItem
|
||||
label="Datepicker:"
|
||||
labelCol={{span: 5}}
|
||||
labelCol={{ span: 5 }}
|
||||
help>
|
||||
<Col span="6">
|
||||
<FormItem validateStatus="error" help="请选择正确日期">
|
||||
<DatePicker />
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="1">
|
||||
<p className="ant-form-split">-</p>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
<FormItem>
|
||||
<DatePicker />
|
||||
</FormItem>
|
||||
</Col>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Datepicker:"
|
||||
labelCol={{ span: 5 }}
|
||||
validateStatus="error"
|
||||
help>
|
||||
<Col span="6">
|
||||
@@ -88,26 +107,7 @@ ReactDOM.render(
|
||||
<DatePicker />
|
||||
</Col>
|
||||
<Col span="19" offset="5">
|
||||
<p className="ant-form-explain">请输入正确选项</p>
|
||||
</Col>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Datepicker:"
|
||||
labelCol={{span: 5}}>
|
||||
<Col span="6">
|
||||
<FormItem validateStatus="error">
|
||||
<DatePicker />
|
||||
<p className="ant-form-explain">请输入正确选项</p>
|
||||
</FormItem>
|
||||
</Col>
|
||||
<Col span="1">
|
||||
<p className="ant-form-split">-</p>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
<FormItem>
|
||||
<DatePicker />
|
||||
</FormItem>
|
||||
<p className="ant-form-explain">请选择正确日期</p>
|
||||
</Col>
|
||||
</FormItem>
|
||||
</Form>
|
||||
@@ -2,8 +2,20 @@ import Form from './Form';
|
||||
import FormItem from './FormItem';
|
||||
import ValueMixin from './ValueMixin';
|
||||
import Input from '../input';
|
||||
import createDOMForm from 'rc-form/lib/createDOMForm';
|
||||
|
||||
Form.create = (o = {}) => {
|
||||
const options = {
|
||||
...o,
|
||||
fieldNameProp: 'id',
|
||||
fieldMetaProp: '__meta',
|
||||
};
|
||||
|
||||
return createDOMForm(options);
|
||||
};
|
||||
Form.Item = FormItem;
|
||||
|
||||
// @Deprecated
|
||||
Form.ValueMixin = ValueMixin;
|
||||
|
||||
// 对于 import { Form, Input } from 'antd/lib/form/';
|
||||
|
||||
@@ -35,17 +35,66 @@
|
||||
<Input {...props} />
|
||||
```
|
||||
|
||||
> 注:标准表单中一律使用大号控件。
|
||||
|
||||
## API
|
||||
|
||||
### Form
|
||||
|
||||
更多示例参考 [rc-form](http://react-component.github.io/form/)。
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|
||||
|-----------|------------------------------------------|------------|-------|--------|
|
||||
| form | 经 `Form.create()` 包装过的组件会自带 `this.props.form` 属性,直接传给 Form 即可 | object | | 无 |
|
||||
| horizontal | 水平排列布局 | boolean | | false |
|
||||
| inline | 行内排列布局 | boolean | | false |
|
||||
| onSubmit | 数据验证成功后回调事件 | Function(e:Event) | | |
|
||||
| prefixCls | 样式类名,默认为 ant-form,通常您不需要设置 | string | | 'ant-form' |
|
||||
|
||||
### Form.create(options)
|
||||
|
||||
使用方式如下:
|
||||
|
||||
```jsx
|
||||
class CustomizedForm extends React.Component {}
|
||||
|
||||
CustomizedForm = Form.create({})(CustomizedForm);
|
||||
```
|
||||
|
||||
`options` 的配置项如下。
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|
||||
|-----------|------------------------------------------|------------|-------|--------|
|
||||
| onFieldsChange | 当 `Form.Item` 子节点的值发生改变时触发,可以把对应的值转存到 Redux store | Function(props, fields) | | |
|
||||
| mapPropsToFields | 把 props 转为对应的值,可用于把 Redux store 中的值读出 | Function(props) | | | |
|
||||
|
||||
经过 `Form.create` 包装的组件将会自带 `this.props.form` 属性,`this.props.form` 提供的 API 如下:
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|
||||
|-----------|------------------------------------------|------------|-------|--------|
|
||||
| getFieldsValue | 获取一组输入控件的值,如不传入参数,则获取全部组件的值 | Function([fieldNames: string[]]) | | |
|
||||
| getFieldValue | 获取一个输入控件的值 | Function(fieldName: string) | | |
|
||||
| setFieldsValue | 设置一组输入控件的值 | Function(obj: object) | | |
|
||||
| setFields | 设置一组输入控件的值与 Error | Function(obj: object) | | |
|
||||
| validateFields | 校验并获取一组输入域的值与 Error | Function([fieldNames: string[]], [options: object], callback: Function(errors, values)) | | |
|
||||
| validateFieldsAndScroll | 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 | 参考 `validateFields` | | |
|
||||
| getFieldError | 获取某个输入控件的 Error | Function(name) | | |
|
||||
| isFieldValidating | 判断一个输入控件是否在校验状态 | Function(name) | | |
|
||||
| resetFields | 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 | Function([names: string[]]) | | |
|
||||
| getFieldProps 详见下面描述 | | | | |
|
||||
|
||||
#### this.props.form.getFieldProps(id, options)
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|
||||
|-----------|------------------------------------------|------------|-------|--------|
|
||||
| options.id | 必填输入控件唯一标志 | string | | |
|
||||
| options.valuePropName | 子节点的值的属性,如 Checkbox 的是 'checked' | string | | 'value' |
|
||||
| options.initialValue | 子节点的初始值,类型、可选值均由子节点决定 | | | |
|
||||
| options.trigger | 收集子节点的值的时机 | string | | 'onChange' |
|
||||
| options.validateTrigger | 校验子节点值的时机 | string | | 'onChange' |
|
||||
| options.rules | 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) | array | | | |
|
||||
|
||||
|
||||
### Form.Item
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|
||||
@@ -53,32 +102,29 @@
|
||||
| label | label 标签的文本 | string | | |
|
||||
| labelCol | label 标签布局,通 `<Col>` 组件,设置 `span` `offset` 值,如 `{span: 3, offset: 12}` | object | | |
|
||||
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | object | | |
|
||||
| help | 提示信息 | string | | |
|
||||
| required | 是否必填 | bool | | false |
|
||||
| validateStatus | 校验状态 | string | 'success' 'warning' 'error' 'validating' | |
|
||||
| help | 提示信息,如不设置,则会根据校验规则自动生成 | string | | |
|
||||
| extra | 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 | string | | |
|
||||
| required | 是否必填,如不设置,则会根据校验规则自动生成 | bool | | false |
|
||||
| validateStatus | 校验状态,如不设置,则会根据校验规则自动生成 | string | 'success' 'warning' 'error' 'validating' | |
|
||||
| hasFeedback | 配合 validateStatus 属性使用,是否展示校验状态图标 | bool | | false |
|
||||
| prefixCls | 样式类名,默认为 ant-form,通常您不需要设置 | string | | 'ant-form' |
|
||||
|
||||
### Form.ValueMixin
|
||||
|
||||
Mixin:当表单控件的输入值改变时,更新 formData。
|
||||
|
||||
**你需要为每个输入控件声明 `name` 属性**
|
||||
|
||||
### Input
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|
||||
|-----------|------------------------------------------|------------|-------|--------|
|
||||
| type | 【必须】声明 input 类型,同原生 input 标签的 type 属性 | string | | 'text' |
|
||||
| value | value 值 | any | | |
|
||||
| id | id | number 或 string | | |
|
||||
| size | 控件大小,默认值为 default 。注:标准表单内的输入框大小限制为 large。 | string | {'large','default','small'} | 'default' |
|
||||
| value | value 值 | any | | |
|
||||
| defaultValue | 设置初始默认值 | any | | |
|
||||
| size | 控件大小,默认值为 default 。注:标准表单内的输入框大小限制为 large。 | string | {'large','default','small'} | 'default' |
|
||||
| disabled | 是否禁用状态,默认为 false | bool | | false |
|
||||
| addonBefore | 带标签的 input,设置前置标签 | node | | |
|
||||
| addonAfter | 带标签的 input,设置后置标签 | node | | |
|
||||
| prefixCls | 样式类名前缀,默认是 ant,通常您不需要设置 | string | | 'ant' |
|
||||
|
||||
> 如果 `Input` 在 `Form.Item` 内,并且 `Form.Item` 设置了 `id` 和 `options` 属性,则 `value` `defaultValue` 和 `id` 属性会被自动设置。
|
||||
|
||||
#### Input.Group
|
||||
|
||||
```html
|
||||
|
||||
@@ -120,7 +120,7 @@ const CopyableIcon = React.createClass({
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const text = '<Icon type="' + this.props.type + '" />';
|
||||
const text = '<Icon type="' + this.props.type + '" />';
|
||||
return (
|
||||
<CopyToClipboard text={text} onCopy={this.onCopied}>
|
||||
<li className={this.state.justCopied ? 'copied' : ''}>
|
||||
|
||||
@@ -21,12 +21,14 @@ const Test = React.createClass({
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<InputNumber min={1} max={10} disabled={this.state.disabled} defaultValue={3} />
|
||||
<div style={{marginTop: 20}}>
|
||||
<Button onClick={this.toggle} type="primary">Toggle disabled</Button>
|
||||
return (
|
||||
<div>
|
||||
<InputNumber min={1} max={10} disabled={this.state.disabled} defaultValue={3} />
|
||||
<div style={{ marginTop: 20 }}>
|
||||
<Button onClick={this.toggle} type="primary">Toggle disabled</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export default React.createClass({
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const {className, size, ...other} = this.props;
|
||||
const { className, size, ...other } = this.props;
|
||||
const inputNumberClass = classNames({
|
||||
'ant-input-number-lg': size === 'large',
|
||||
'ant-input-number-sm': size === 'small',
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import React from 'react';
|
||||
import assign from 'object-assign';
|
||||
|
||||
function prefixClsFn(prefixCls, ...args) {
|
||||
return args.map((s)=> {
|
||||
return prefixCls + '-' + s;
|
||||
}).join(' ');
|
||||
}
|
||||
import classNames from 'classnames';
|
||||
|
||||
function ieGT9() {
|
||||
if (typeof document === undefined) {
|
||||
@@ -24,10 +19,12 @@ function fixControlledValue(value) {
|
||||
|
||||
class Group extends React.Component {
|
||||
render() {
|
||||
const className = 'ant-input-group ' + (this.props.className || '');
|
||||
const className = classNames({
|
||||
'ant-input-group': true,
|
||||
[this.props.className]: !!this.props.className,
|
||||
});
|
||||
return (
|
||||
<span className={className}
|
||||
style={this.props.style}>
|
||||
<span className={className} style={this.props.style}>
|
||||
{this.props.children}
|
||||
</span>
|
||||
);
|
||||
@@ -41,8 +38,8 @@ Group.propTypes = {
|
||||
class Input extends React.Component {
|
||||
renderLabledInput(children) {
|
||||
const props = this.props;
|
||||
const wrapperClassName = prefixClsFn(props.prefixCls, 'input-group');
|
||||
const addonClassName = prefixClsFn(wrapperClassName, 'addon');
|
||||
const wrapperClassName = `${props.prefixCls}-group`;
|
||||
const addonClassName = `${wrapperClassName}-addon`;
|
||||
const addonBefore = props.addonBefore ? (
|
||||
<span className={addonClassName}>
|
||||
{props.addonBefore}
|
||||
@@ -55,8 +52,13 @@ class Input extends React.Component {
|
||||
</span>
|
||||
) : null;
|
||||
|
||||
const className = classNames({
|
||||
[`${props.prefixCls}-wrapper`]: true,
|
||||
[wrapperClassName]: (addonBefore || addonAfter),
|
||||
});
|
||||
|
||||
return (
|
||||
<span className={(addonBefore || addonAfter) ? wrapperClassName : ''}>
|
||||
<span className={className}>
|
||||
{addonBefore}
|
||||
{children}
|
||||
{addonAfter}
|
||||
@@ -67,29 +69,29 @@ class Input extends React.Component {
|
||||
renderInput() {
|
||||
const props = assign({}, this.props);
|
||||
const prefixCls = props.prefixCls;
|
||||
let inputClassName = prefixClsFn(prefixCls, 'input');
|
||||
if (!props.type) {
|
||||
return props.children;
|
||||
}
|
||||
|
||||
switch (props.size) {
|
||||
case 'small': inputClassName = prefixClsFn(prefixCls, 'input', 'input-sm'); break;
|
||||
case 'large': inputClassName = prefixClsFn(prefixCls, 'input', 'input-lg'); break;
|
||||
default:
|
||||
}
|
||||
const inputClassName = classNames({
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-sm`]: props.size === 'small',
|
||||
[`${prefixCls}-lg`]: props.size === 'large',
|
||||
[props.className]: !!props.className,
|
||||
});
|
||||
|
||||
let placeholder = props.placeholder;
|
||||
if(placeholder && ieGT9()){
|
||||
if (placeholder && ieGT9()) {
|
||||
placeholder = null;
|
||||
}
|
||||
if ('value' in props) {
|
||||
props.value = fixControlledValue(props.value);
|
||||
}
|
||||
switch (props.type) {
|
||||
case 'textarea':
|
||||
return <textarea {...props} placeholder={placeholder} className={inputClassName} ref="input" />;
|
||||
default:
|
||||
inputClassName = props.className ? props.className : inputClassName;
|
||||
return <input {...props} placeholder={placeholder} className={inputClassName} ref="input"/>;
|
||||
case 'textarea':
|
||||
return <textarea {...props} placeholder={placeholder} className={inputClassName} ref="input" />;
|
||||
default:
|
||||
return <input {...props} placeholder={placeholder} className={inputClassName} ref="input" />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +119,7 @@ Input.propTypes = {
|
||||
Input.defaultProps = {
|
||||
defaultValue: '',
|
||||
disabled: false,
|
||||
prefixCls: 'ant',
|
||||
prefixCls: 'ant-input',
|
||||
type: 'text',
|
||||
};
|
||||
|
||||
|
||||
@@ -12,13 +12,13 @@ const Col = React.createClass({
|
||||
children: React.PropTypes.node,
|
||||
},
|
||||
render() {
|
||||
const {span, order, offset, push, pull, className, ...others} = this.props;
|
||||
const { span, order, offset, push, pull, className, ...others } = this.props;
|
||||
const classes = classNames({
|
||||
['col-' + span]: span,
|
||||
['col-order-' + order]: order,
|
||||
['col-offset-' + offset]: offset,
|
||||
['col-push-' + push]: push,
|
||||
['col-pull-' + pull]: pull,
|
||||
[`col-${span}`]: span,
|
||||
[`col-order-${order}`]: order,
|
||||
[`col-offset-${offset}`]: offset,
|
||||
[`col-push-${push}`]: push,
|
||||
[`col-pull-${pull}`]: pull,
|
||||
[className]: className,
|
||||
});
|
||||
return <div {...others} className={classes}>{ this.props.children }</div>;
|
||||
|
||||
@@ -12,10 +12,10 @@ const Row = React.createClass({
|
||||
render() {
|
||||
const { type, justify, align, className, ...others } = this.props;
|
||||
const classes = classNames({
|
||||
'row': true,
|
||||
['row-' + type]: type,
|
||||
['row-' + type + '-' + justify]: justify,
|
||||
['row-' + type + '-' + align]: align,
|
||||
row: true,
|
||||
[`row-${type}`]: type,
|
||||
[`row-${type}-${justify}`]: justify,
|
||||
[`row-${type}-${align}`]: align,
|
||||
[className]: className,
|
||||
});
|
||||
return <div {...others} className={classes}>{ this.props.children }</div>;
|
||||
|
||||
@@ -30,34 +30,36 @@ const Sider = React.createClass({
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <Menu onClick={this.handleClick}
|
||||
style={{width:240}}
|
||||
openKeys={this.state.openKeys}
|
||||
onOpen={this.onToggle}
|
||||
onClose={this.onToggle}
|
||||
selectedKeys={[this.state.current]}
|
||||
mode="inline">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
return (
|
||||
<Menu onClick={this.handleClick}
|
||||
style={{ width: 240 }}
|
||||
openKeys={this.state.openKeys}
|
||||
onOpen={this.onToggle}
|
||||
onClose={this.onToggle}
|
||||
selectedKeys={[this.state.current]}
|
||||
mode="inline">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>;
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
});
|
||||
ReactDOM.render(<Sider />, mountNode);
|
||||
|
||||
@@ -24,36 +24,38 @@ const Sider = React.createClass({
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <Menu onClick={this.handleClick}
|
||||
style={{width:240}}
|
||||
defaultOpenKeys={['sub1']}
|
||||
selectedKeys={[this.state.current]}
|
||||
mode="inline">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<MenuItemGroup title="分组1">
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup title="分组2">
|
||||
<Menu.Item key="3"><a href="#">选项3</a></Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
return (
|
||||
<Menu onClick={this.handleClick}
|
||||
style={{ width: 240 }}
|
||||
defaultOpenKeys={['sub1']}
|
||||
selectedKeys={[this.state.current]}
|
||||
mode="inline">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<MenuItemGroup title="分组1">
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup title="分组2">
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>;
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
});
|
||||
ReactDOM.render(<Sider />, mountNode);
|
||||
|
||||
@@ -28,38 +28,40 @@ const Sider = React.createClass({
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return <div>
|
||||
<Switch onChange={this.changeTheme} checkedChildren="暗" unCheckedChildren="亮" />
|
||||
<br />
|
||||
<br />
|
||||
<Menu theme={this.state.theme}
|
||||
onClick={this.handleClick}
|
||||
style={{width:240}}
|
||||
defaultOpenKeys={['sub1']}
|
||||
selectedKeys={[this.state.current]}
|
||||
mode="inline">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
return (
|
||||
<div>
|
||||
<Switch onChange={this.changeTheme} checkedChildren="暗" unCheckedChildren="亮" />
|
||||
<br />
|
||||
<br />
|
||||
<Menu theme={this.state.theme}
|
||||
onClick={this.handleClick}
|
||||
style={{ width: 240 }}
|
||||
defaultOpenKeys={['sub1']}
|
||||
selectedKeys={[this.state.current]}
|
||||
mode="inline">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
</div>;
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><Icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
ReactDOM.render(<Sider />, mountNode);
|
||||
|
||||
@@ -15,31 +15,32 @@ function handleClick(e) {
|
||||
console.log('click', e);
|
||||
}
|
||||
|
||||
ReactDOM.render(<Menu onClick={handleClick} style={{width:240}} mode="vertical">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<MenuItemGroup title="分组1">
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup title="分组2">
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
ReactDOM.render(
|
||||
<Menu onClick={handleClick} style={{ width: 240 }} mode="vertical">
|
||||
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>导航一</span></span>}>
|
||||
<MenuItemGroup title="分组1">
|
||||
<Menu.Item key="1">选项1</Menu.Item>
|
||||
<Menu.Item key="2">选项2</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
<MenuItemGroup title="分组2">
|
||||
<Menu.Item key="3">选项3</Menu.Item>
|
||||
<Menu.Item key="4">选项4</Menu.Item>
|
||||
</MenuItemGroup>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
<SubMenu key="sub2" title={<span><Icon type="appstore" /><span>导航二</span></span>}>
|
||||
<Menu.Item key="5">选项5</Menu.Item>
|
||||
<Menu.Item key="6">选项6</Menu.Item>
|
||||
<SubMenu key="sub3" title="三级导航">
|
||||
<Menu.Item key="7">选项7</Menu.Item>
|
||||
<Menu.Item key="8">选项8</Menu.Item>
|
||||
</SubMenu>
|
||||
</SubMenu>
|
||||
<SubMenu key="sub4" title={<span><icon type="setting" /><span>导航三</span></span>}>
|
||||
<Menu.Item key="9">选项9</Menu.Item>
|
||||
<Menu.Item key="10">选项10</Menu.Item>
|
||||
<Menu.Item key="11">选项11</Menu.Item>
|
||||
<Menu.Item key="12">选项12</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import Menu from 'rc-menu';
|
||||
import Menu, { Item, Divider, SubMenu, ItemGroup } from 'rc-menu';
|
||||
import animation from '../common/openAnimation';
|
||||
|
||||
function noop() {
|
||||
@@ -43,21 +43,21 @@ const AntMenu = React.createClass({
|
||||
let openAnimation = this.props.openAnimation || this.props.openTransitionName;
|
||||
if (!openAnimation) {
|
||||
switch (this.props.mode) {
|
||||
case 'horizontal':
|
||||
openAnimation = 'slide-up';
|
||||
break;
|
||||
case 'vertical':
|
||||
openAnimation = 'zoom-big';
|
||||
break;
|
||||
case 'inline':
|
||||
openAnimation = animation;
|
||||
break;
|
||||
default:
|
||||
case 'horizontal':
|
||||
openAnimation = 'slide-up';
|
||||
break;
|
||||
case 'vertical':
|
||||
openAnimation = 'zoom-big';
|
||||
break;
|
||||
case 'inline':
|
||||
openAnimation = animation;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
let props = {};
|
||||
const className = this.props.className + ' ' + this.props.prefixCls + '-' + this.props.theme;
|
||||
const className = `${this.props.className} ${this.props.prefixCls}-${this.props.theme}`;
|
||||
if (this.props.mode !== 'inline') {
|
||||
// 这组属性的目的是
|
||||
// 弹出型的菜单需要点击后立即关闭
|
||||
@@ -80,9 +80,9 @@ const AntMenu = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
AntMenu.Divider = Menu.Divider;
|
||||
AntMenu.Item = Menu.Item;
|
||||
AntMenu.SubMenu = Menu.SubMenu;
|
||||
AntMenu.ItemGroup = Menu.ItemGroup;
|
||||
AntMenu.Divider = Divider;
|
||||
AntMenu.Item = Item;
|
||||
AntMenu.SubMenu = SubMenu;
|
||||
AntMenu.ItemGroup = ItemGroup;
|
||||
|
||||
export default AntMenu;
|
||||
|
||||
@@ -9,11 +9,10 @@
|
||||
````jsx
|
||||
import { message, Button } from 'antd';
|
||||
|
||||
const success = function() {
|
||||
const success = function () {
|
||||
message.success('这是一条成功的提示,并将于10秒后消失', 10);
|
||||
};
|
||||
|
||||
ReactDOM.render(<Button onClick={success}>自定义时长提示</Button>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
````jsx
|
||||
import { message, Button } from 'antd';
|
||||
|
||||
const info = function() {
|
||||
const info = function () {
|
||||
message.info('这是一条普通的提醒');
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
````jsx
|
||||
import { message, Button } from 'antd';
|
||||
|
||||
const success = function() {
|
||||
const success = function () {
|
||||
let hide = message.loading('正在执行中...', 0);
|
||||
// 异步手动移除
|
||||
setTimeout(hide, 2500);
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
````jsx
|
||||
import { message, Button } from 'antd';
|
||||
|
||||
const success = function() {
|
||||
const success = function () {
|
||||
message.success('这是一条成功提示');
|
||||
};
|
||||
|
||||
const error = function() {
|
||||
const error = function () {
|
||||
message.error('这是一条报错提示');
|
||||
};
|
||||
|
||||
const warn = function() {
|
||||
const warn = function () {
|
||||
message.warn('这是一条警告提示');
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ function getMessageInstance() {
|
||||
prefixCls: 'ant-message',
|
||||
transitionName: 'move-up',
|
||||
style: {
|
||||
top: top
|
||||
top,
|
||||
} // 覆盖原来的样式
|
||||
});
|
||||
return messageInstance;
|
||||
@@ -20,38 +20,38 @@ function getMessageInstance() {
|
||||
|
||||
function notice(content, duration = defaultDuration, type, onClose) {
|
||||
let iconClass = ({
|
||||
'info': 'ant-message-info',
|
||||
'success': 'ant-message-success',
|
||||
'error': 'ant-message-error',
|
||||
'warn': 'ant-message-warn',
|
||||
'loading': 'ant-message-loading'
|
||||
info: 'ant-message-info',
|
||||
success: 'ant-message-success',
|
||||
error: 'ant-message-error',
|
||||
warn: 'ant-message-warn',
|
||||
loading: 'ant-message-loading'
|
||||
})[type];
|
||||
|
||||
let iconType = ({
|
||||
'info': 'info-circle',
|
||||
'success': 'check-circle',
|
||||
'error': 'exclamation-circle',
|
||||
'warn': 'exclamation-circle',
|
||||
'loading': 'loading'
|
||||
info: 'info-circle',
|
||||
success: 'check-circle',
|
||||
error: 'exclamation-circle',
|
||||
warn: 'exclamation-circle',
|
||||
loading: 'loading'
|
||||
})[type];
|
||||
|
||||
let instance = getMessageInstance();
|
||||
instance.notice({
|
||||
key: key,
|
||||
duration: duration,
|
||||
key,
|
||||
duration,
|
||||
style: {},
|
||||
content: <div className={'ant-message-custom-content ' + iconClass}>
|
||||
content: <div className={`ant-message-custom-content ${iconClass}`}>
|
||||
<Icon className={iconClass} type={iconType} />
|
||||
<span>{content}</span>
|
||||
</div>,
|
||||
onClose: onClose
|
||||
onClose
|
||||
});
|
||||
return (function() {
|
||||
return (function () {
|
||||
let target = key++;
|
||||
return function() {
|
||||
return function () {
|
||||
instance.removeNotice(target);
|
||||
};
|
||||
})();
|
||||
}());
|
||||
}
|
||||
|
||||
export default {
|
||||
@@ -74,5 +74,11 @@ export default {
|
||||
if (options.top) {
|
||||
top = options.top;
|
||||
}
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (messageInstance) {
|
||||
messageInstance.destroy();
|
||||
messageInstance = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
- `message.info(content, duration)`
|
||||
- `message.loading(content, duration)`
|
||||
|
||||
组件提供了三个静态方法,参数如下:
|
||||
组件提供了四个静态方法,参数如下:
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------------|----------------|----------------------------|--------------|
|
||||
@@ -29,9 +29,10 @@
|
||||
| duration | 自动关闭的延时 | number | 1.5 |
|
||||
|
||||
|
||||
还提供了一个全局配置方法:
|
||||
还提供了全局配置和全局销毁方法:
|
||||
|
||||
- `message.config(options)`
|
||||
- `message.destroy()`
|
||||
|
||||
```js
|
||||
message.config({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user