Compare commits

...

166 Commits
2.7.2 ... 2.7.3

Author SHA1 Message Date
afc163
d4036d3cae fix button unknown prop 2017-02-27 11:18:48 +08:00
偏右
a60eec0e35 Add changelog for 2.7.3 (#5049) 2017-02-27 11:10:55 +08:00
Benjy Cui
1763fa168c docs: update link, close: #5051 2017-02-27 10:43:13 +08:00
Benjy Cui
8b539c4971 chore: update type definition 2017-02-27 10:20:46 +08:00
afc163
40b30d8ef9 site: fix markdown list style 2017-02-26 22:56:58 +08:00
afc163
d99778b605 Fix clicked effect when switch loading state 2017-02-26 19:21:22 +08:00
afc163
00fac07d9e refactor requestAnimationFrame 2017-02-26 19:08:36 +08:00
afc163
a9599b802c when labelCol is 24, it is a vertical form 2017-02-26 18:09:41 +08:00
afc163
3818f59a97 fix test case 2017-02-26 17:52:26 +08:00
afc163
30f2a1ed94 Add popup node snapshot test for Cascader 2017-02-26 16:48:42 +08:00
afc163
05b20c6a9f fix stylelint problems of site 2017-02-26 15:41:50 +08:00
afc163
c31ebaad90 site: fix responsive design 2017-02-26 15:25:26 +08:00
afc163
0f6d1db614 fix lint 2017-02-26 15:20:12 +08:00
afc163
d44a0ece3f site: improve styles 2017-02-26 15:09:52 +08:00
YuyingWu
e8cf22ad0e site: fix locale switch
* antD首页从英文切换到中文时,replace导致链接错误

首页从英文转到中文,点击header上的“中文”时,链接会跳到 https://ant.design/index-cn/ant.design/ (Chrome)或者 https://index-cn/ant.design/ (Safari)

bug来自handleLangChange函数下,最后对location.href.replace操作时出错,原因来自replace匹配到location.href的第一个/
('https://ant.design/').replace('/', '/index-cn') 的运行结果是 https:/index-cn/ant.design/ 

为了避免replace匹配到location.href的第一个/,我建议的方案是使用 location.origin + location.pathname.replace

最后,感谢antD团队开发出那么棒的UI~

* 英转中,url替换(带hash、query)

英转中URL问题,上一版使用了location.origin + location.pathname,会丢失query和hash。此版本原理还是用location.href做replace,鉴于首页pathname可能是/会在替换中匹配到https:后的第一个/,所以先把href的protocol部分提取出来,再做replace,最后再拼回去做跳转。
2017-02-26 14:50:12 +08:00
afc163
14d380f0f9 use old button animation 2017-02-26 02:18:20 +08:00
偏右
4650d20abf Update colorPalette.less 2017-02-26 00:35:02 +08:00
afc163
cf4ad5ddb8 fix test case 2017-02-26 00:23:46 +08:00
YuyingWu
a5f136f334 antD首页从英文切换到中文时,replace导致链接错误 (#5050)
首页从英文转到中文,点击header上的“中文”时,链接会跳到 https://ant.design/index-cn/ant.design/ (Chrome)或者 https://index-cn/ant.design/ (Safari)

bug来自handleLangChange函数下,最后对location.href.replace操作时出错,原因来自replace匹配到location.href的第一个/
('https://ant.design/').replace('/', '/index-cn') 的运行结果是 https:/index-cn/ant.design/ 

为了避免replace匹配到location.href的第一个/,我建议的方案是使用 location.origin + location.pathname.replace

最后,感谢antD团队开发出那么棒的UI~
2017-02-26 00:23:04 +08:00
afc163
917ec5606e Tweak tree style 2017-02-25 19:17:54 +08:00
afc163
511db23fcd Add default title for form item label 2017-02-25 18:48:44 +08:00
afc163
68fde63ef7 refactor renderLabel 2017-02-25 18:47:40 +08:00
afc163
d2e178d215 update doc 2017-02-25 18:37:25 +08:00
afc163
c78d3032f5 site: fix aside menu 2017-02-25 15:10:23 +08:00
afc163
f6715df3b5 closest => dom-closest, fix ssr 2017-02-25 02:09:18 +08:00
afc163
6ea75c4d85 Filter dropdown menu inside scroll body should never be shown, close #5010 2017-02-25 01:36:45 +08:00
afc163
5076b6045c fix snap 2017-02-25 00:17:44 +08:00
afc163
139d95022c prefer stateless function 2017-02-24 20:29:24 +08:00
tianli.zhao
85ca5ed5ea [WIP] filter the disabled options (#4981)
filter the disabled options
2017-02-24 19:08:02 +08:00
afc163
0cbe319839 Add copied message 2017-02-24 19:05:26 +08:00
afc163
2bf6e22653 fix documentation for onOk, close #5044 2017-02-24 18:08:35 +08:00
ddcat1115
d0db3ce426 fix menu icon not centered in Layout.Sidere (#5039) 2017-02-24 18:04:16 +08:00
afc163
4bde2917d2 fix internal links 2017-02-24 18:02:47 +08:00
afc163
c163232deb fix snap 2017-02-24 17:43:40 +08:00
afc163
9c3268dcbc continue to fix #4935 2017-02-24 17:36:16 +08:00
乐仪
55fca5cee4 Merge branch 'master' of https://github.com/ant-design/ant-design 2017-02-24 16:36:02 +08:00
乐仪
70ec413537 fix Layout demo, update documentation. 2017-02-24 16:34:10 +08:00
afc163
edaad09b67 update grid document for media queries rule, close #5030 2017-02-24 16:25:27 +08:00
Benjy Cui
3aac9adc40 docs: remove some demo 2017-02-24 16:17:52 +08:00
ddcat1115
e07cdf5387 add left out event parameters for Modal[onOk] Popconfirm[onConfirm] Popconfirm[onCancel] (#5042) 2017-02-24 16:07:39 +08:00
feng zhi hao
88100a29a3 chore: fix ts definition of Upload (#5041) 2017-02-24 16:06:57 +08:00
偏右
6df92ce16f Fix staged lint (#5037)
* revert lint-staged

* remove git add

* fix lint-staged:demo typo

* fix: cnpm can not find tslint error
2017-02-24 12:54:13 +08:00
Benjy Cui
e72d93edfe site: add copy button to demo, close: #4563 2017-02-24 11:55:24 +08:00
Graeme Yeates
19c11dd173 chore: RangePicker TimePicker component locking background to white (#5031) 2017-02-24 10:42:45 +08:00
Benjy Cui
4e59e9e769 docs: recommend to use LocaleProvider, ref: #5017 2017-02-24 10:22:21 +08:00
afc163
7deab1beec do not autofix lint when commit, ref #4941 2017-02-23 22:28:21 +08:00
411f352690 [WIP] Refactor lint-flow (#5014)
* refactor: lint-flow #4941

* chore: rename lint to lint-all #4941

* Revert "chore: rename lint to lint-all #4941"

This reverts commit 8e4e2b6da3289b62fa85354bee3068fe35836f3d.
2017-02-23 22:12:52 +08:00
afc163
f53d0b7646 upgrade rc-input-number for #5012 2017-02-23 21:15:32 +08:00
Benjy Cui
1f844c1048 fix: Slider's Tooltip should not blink, close: #5003 2017-02-23 17:03:18 +08:00
Benjy Cui
1c837963e2 chore: add warning for deprecated API 2017-02-23 16:04:27 +08:00
Benjy Cui
ce0d4c39f2 docs: add missing info in Calendar, close: #5017 2017-02-23 15:58:02 +08:00
afc163
dded4bcde4 fix snap for rc-table@5.2.12 2017-02-23 14:57:48 +08:00
afc163
6fdb39038b Fix selected style of Dropdown menu, close #5013 2017-02-23 13:48:38 +08:00
afc163
9d0a06b657 add snap file 2017-02-23 13:45:16 +08:00
afc163
9c6a6d6175 Fix Breadcrumb falsy children, close #5015 2017-02-23 13:43:50 +08:00
afc163
5068343b0c fix tslint 2017-02-23 13:18:06 +08:00
afc163
a7c6c027ce Fix ts definition of Table & RangePicker
close https://segmentfault.com/q/1010000008423156
2017-02-23 12:51:40 +08:00
afc163
0f46eed370 fix lint 2017-02-23 11:45:48 +08:00
afc163
922a57dfde fix snap for react-component/table#125 2017-02-23 11:30:54 +08:00
Benjy Cui
29ebf22529 docs: update docs for AutoComplete, close: #5006 2017-02-23 10:02:10 +08:00
偏右
ec9fed3f04 Update ISSUE_TEMPLATE.md 2017-02-23 01:04:22 +08:00
afc163
52bfb8069a site: fix link 2017-02-23 00:36:02 +08:00
afc163
5fbc007ff7 site: fix link 2017-02-23 00:35:16 +08:00
afc163
27717483a7 should be only working on input ref, #4987 2017-02-22 21:28:53 +08:00
afc163
d8fb282088 Adjust checkbox and radio vertical, close #5001 2017-02-22 21:22:42 +08:00
afc163
9228e7a01b update snap 2017-02-22 19:34:44 +08:00
afc163
39fd6b6a36 Define circle progress theme by css, close #5002 2017-02-22 19:33:15 +08:00
afc163
ff2d69ad21 update progress demo 2017-02-22 19:31:50 +08:00
afc163
1c4407b60c fix popup menu z-index problem 2017-02-22 18:30:50 +08:00
afc163
cdf786676c Fix popconfirm missing button styles 2017-02-22 18:10:02 +08:00
afc163
5b20a5fc3e Fix slight vertical position difference in chrome, close #4987 2017-02-22 17:48:58 +08:00
afc163
7181e3c9e8 revert d9ec4bf and ef0b708, close #4997 2017-02-22 16:50:24 +08:00
afc163
61a3d66a02 Add test case for upload 2017-02-22 16:07:31 +08:00
Benjy Cui
e4d9e5af54 test: update snapshot 2017-02-22 15:52:43 +08:00
Benjy Cui
d9ec4bf732 fix: RangePicker style 2017-02-22 15:33:21 +08:00
afc163
fbeccb7be5 fix inline submenu open style 2017-02-22 14:47:01 +08:00
afc163
c2217f666c site: fix infinte redirect loop 2017-02-22 14:26:48 +08:00
afc163
32150a15a4 update document 2017-02-22 14:04:40 +08:00
afc163
90699b0c42 clean up document 2017-02-22 12:33:23 +08:00
Benjy Cui
0caefc8137 docs: update migration guides 2017-02-22 11:31:13 +08:00
afc163
ef0b7087f6 Fix slight difference placeholder between Input and Select
close #4987
2017-02-21 23:34:23 +08:00
afc163
9bb7e3d10c site: improve responsive layout 2017-02-21 23:26:10 +08:00
afc163
f0a4afd388 Fix slight difference placeholder between Input and Select
close #4987
2017-02-21 22:45:56 +08:00
陆离
7d982ddfd4 Calc width of Affix using getBoundingClientRect (#4989)
+ close #4986
2017-02-21 22:17:48 +08:00
afc163
79f222b86c fix snap, seems to be a jsdom bugfix 2017-02-21 22:17:35 +08:00
afc163
2fb0fb08d9 Fix Carousel autoplay not working after resizing, close #4984 & #2550 2017-02-21 22:12:11 +08:00
乔奕轩
030127e93c fix: Affix should not pass onChange to div (#4982) 2017-02-21 18:07:58 +08:00
afc163
9fff177bbc update table fixed column demo description 2017-02-21 17:11:30 +08:00
afc163
54dde4f5bc Hide yellow tag for no compatible with WCAG 2.0 on contrast ratio 2017-02-21 16:19:56 +08:00
afc163
fbb6cb007f max-height should not work on submenu filter, close #4975, ref #4916 2017-02-21 15:54:14 +08:00
afc163
7f404f1e20 Fix styoe of spin inside spin, close #4971 2017-02-21 15:15:30 +08:00
afc163
68f3641a90 update less code style 2017-02-21 15:15:29 +08:00
Benjy Cui
760a5ffc90 fix: add .focus for TimePicker, ref: #3790 2017-02-21 15:10:28 +08:00
陆离
21a0779692 Better loading of Button (#4964)
*  Better loading of Button

 + close #4925
 + add a default delay timer (200ms)

* update snapshot

* escape
2017-02-21 14:44:08 +08:00
afc163
205ace69ba Fix bug of switch language in iOS 2017-02-21 13:36:17 +08:00
afc163
c3748a60f4 site: improve responsive design 2017-02-21 12:07:28 +08:00
afc163
921f71a8bc revert fix ant-col-xx-0 not disappear as expected 2017-02-21 11:56:51 +08:00
afc163
c4a67a1bf5 fix ant-col-xx-0 not disappear as expected 2017-02-21 11:51:17 +08:00
afc163
b839c624e8 fix slider demo 2017-02-20 22:31:43 +08:00
afc163
d19453c4c3 fix lint 2017-02-20 22:21:14 +08:00
afc163
c30878d38f rewrite Slider demos to es6 component, #4878 2017-02-20 22:19:59 +08:00
afc163
580389ac15 rewrite Spin demos to es6 component, #4878 2017-02-20 22:16:57 +08:00
afc163
d576abc7b0 rewrite Switch demos to es6 component, #4878 2017-02-20 22:15:52 +08:00
afc163
6455bdf6e1 rewrite Pagination demos to es6 component, #4878 2017-02-20 22:14:47 +08:00
afc163
e68b54f902 rewrite Popconfirm demos to es6 component, #4878 2017-02-20 22:13:19 +08:00
afc163
176b9f9083 fix typo 2017-02-20 22:11:39 +08:00
afc163
c28020708f fix typo 2017-02-20 22:09:13 +08:00
afc163
a6547a392b rewrite Progress demos to es6 component, #4878 2017-02-20 22:07:45 +08:00
afc163
f27041342d rewrite Popover demos to es6 component, #4878 2017-02-20 22:06:12 +08:00
afc163
c8e49995cb rewrite Rate demos to es6 component, #4878 2017-02-20 22:05:06 +08:00
afc163
18203972a1 rewrite Radio demos to es6 component, #4878 2017-02-20 22:04:17 +08:00
afc163
5e0f5e1902 rewrite Modal demos to es6 component, #4878 2017-02-20 22:02:12 +08:00
afc163
3884ee3c5a rewrite Select demos to es6 component, #4878 2017-02-20 21:54:23 +08:00
afc163
c440a4d2b2 rewrite Menu demos to es6 component, #4878 2017-02-20 21:51:23 +08:00
afc163
f2d12306bd improve demo es6 class code style 2017-02-20 21:47:57 +08:00
afc163
2da59c3679 fix mention demo 2017-02-20 21:40:24 +08:00
afc163
ce877707bd rewrite LocaleProvider and Mention demos to es6 component, #4878 2017-02-20 21:39:07 +08:00
afc163
d7694d4c3b prefer es6 class code in demo 2017-02-20 21:21:54 +08:00
afc163
6b4ca79359 update documentation 2017-02-20 20:29:30 +08:00
afc163
23cb11fef3 update document, ref #4965 2017-02-20 17:58:51 +08:00
陆离
01086d56e5 shoud not have border around button (#4967) 2017-02-20 17:47:26 +08:00
afc163
6c5ae559b3 Add typescript as devDeps 2017-02-20 17:33:42 +08:00
afc163
254bbcd6a5 use tsc replace compile to speed up lint check, #4941 2017-02-20 17:04:10 +08:00
afc163
38c8360d1f Improve Menu[inline] and Collapse animation, ref #4898 2017-02-20 15:34:16 +08:00
afc163
3485529307 adjust message disappear animation setting 2017-02-20 14:44:27 +08:00
Benjy Cui
ec34c2b351 docs: update README.md 2017-02-20 14:19:51 +08:00
feng zhi hao
5303bd0a38 docs: rewrite Table demos to ES6 component (#4954) 2017-02-20 14:04:36 +08:00
feng zhi hao
47dc4a81e4 docs: rewrite InputNumber demos to ES6 component (#4950) 2017-02-20 12:27:13 +08:00
feng zhi hao
62e80928d5 docs: rewrite Form demos to ES6 component (#4949) 2017-02-20 11:50:57 +08:00
afc163
3308bce9b9 fix snapshot test 2017-02-20 11:36:57 +08:00
afc163
c1f3b58b28 Fix table wrapper float layout, close #4945 2017-02-20 11:36:56 +08:00
afc163
626e0c9d1e Fix DatePicker default width, close #4947, ref #4920 2017-02-20 11:36:19 +08:00
Benjy Cui
b7519a65c0 fix: should clear float, close: #4945 2017-02-20 11:31:51 +08:00
feng zhi hao
e85c8a25f6 docs: rewrite Dropdown demos to ES6 component (#4946) 2017-02-20 10:35:47 +08:00
偏右
1c2c93fa81 fix: show muliple messages in vertical direction, close #3543 (#4939) 2017-02-20 10:30:24 +08:00
feng zhi hao
6eca407711 docs: rewrite Checkbox demos to ES6 component (#4944) 2017-02-20 10:09:37 +08:00
feng zhi hao
0d2da7ad3b docs: Rewrite Cascader demos to ES6 component (#4943) 2017-02-20 09:45:23 +08:00
陆离
7a4080ec40 Fix some problems of AutoCompelete demo (#4942)
+ close #4912
2017-02-20 00:09:07 +08:00
bang
b90237ee6f fix: Tabs snapshot tests 2017-02-19 21:23:31 +07:00
bang
6bcd88f5c0 docs: Rewrite Tabs demos to ES6 component 2017-02-19 21:07:45 +07:00
bang
a4acf1f66e docs: Rewrite Upload demos to ES6 component 2017-02-19 20:50:06 +07:00
bang
c10b051a92 docs: Rewrite TreeSelect demos to ES6 component 2017-02-19 20:41:54 +07:00
bang
eabe261648 docs: Rewrite Tree demos to ES6 component 2017-02-19 20:23:38 +07:00
Wei Zhu
a69a52f8b8 docs: Rewrite Button demos to ES6 component 2017-02-19 21:03:44 +08:00
bang
c9064fc494 Merge branches 'master' and 'master' of github.com:ant-design/ant-design
* 'master' of github.com:ant-design/ant-design:
  docs: Rewrite Badge demos to ES6 component

* 'master' of github.com:ant-design/ant-design:
  docs: Rewrite Badge demos to ES6 component
2017-02-19 19:54:32 +07:00
bang
fcf9bafb18 docs: Rewrite Transfer demos to ES6 component 2017-02-19 19:51:40 +07:00
Wei Zhu
1fc8990531 docs: Rewrite Badge demos to ES6 component 2017-02-19 20:27:06 +08:00
Wei Zhu
eb29fdada3 docs: Rewrite AutoComplete demos to ES6 component 2017-02-19 20:12:41 +08:00
afc163
ae67f5cc20 update doc 2017-02-19 18:20:56 +08:00
afc163
18ec5933b7 fix old react documentation links 2017-02-19 17:02:58 +08:00
afc163
173b8c46ad Fix input demo tooltip 2017-02-19 15:21:46 +08:00
afc163
f5b0536d42 improve demo code style 2017-02-19 15:06:37 +08:00
afc163
e289ce8b31 Fix Table fixed column z-index issue, close #4937 2017-02-19 14:26:30 +08:00
afc163
673969d0ba fix table snapshot for react-component/table#121 2017-02-19 14:04:22 +08:00
afc163
6e4fae0e29 remove onChange functions in Table.onChange(pagination) 2017-02-19 13:55:36 +08:00
afc163
b34557ef17 Fix Table pagination.onChange arguments
react-component/pagination#58
2017-02-19 13:50:20 +08:00
afc163
b427adec21 docs: add instrunction about footer={null} 2017-02-19 01:42:58 +08:00
afc163
90daeb9a2b Adjust upload demo 2017-02-19 01:39:41 +08:00
afc163
e71807b732 Improve pagination demo 2017-02-18 18:12:38 +08:00
afc163
2512e6b5b5 site: update toc width 2017-02-18 17:19:17 +08:00
afc163
8194793f9b Update demo documentation 2017-02-18 16:49:34 +08:00
afc163
86981114a7 give up #4637 and fix #4936 2017-02-18 15:50:42 +08:00
afc163
8283a36b2e Fix version definition error, close #4935 2017-02-18 15:29:56 +08:00
afc163
ddcc284b43 Fix dark theme menu style of Dropdown, close #4903 2017-02-18 15:24:25 +08:00
afc163
bd6bc70302 Rollback #4869 for better loading animation, close #4934 2017-02-18 14:58:47 +08:00
afc163
8dc73f4601 Fix shake bug fo Button loading with icon, close #4913 2017-02-18 00:22:38 +08:00
233 changed files with 6227 additions and 6608 deletions

View File

@@ -36,7 +36,6 @@ const eslintrc = {
'consistent-return': 0,
'no-redeclare': 0,
'react/require-extension': 0,
'react/jsx-indent': 0,
'jsx-a11y/no-static-element-interactions': 0,
'jsx-a11y/anchor-has-content': 0,
'react/no-danger': 0,
@@ -57,7 +56,6 @@ if (process.env.RUN_ENV === 'DEMO') {
'eol-last': 0,
'prefer-rest-params': 0,
'react/no-multi-comp': 0,
'react/prefer-es6-class': 0,
'jsx-a11y/href-no-hash': 0,
'import/newline-after-import': 0,
});

View File

@@ -1,12 +1,12 @@
<!-- Issue Template -->
<!--
antd 的用法咨询,建议通过以下渠道,官方 issues 目前没有足够精力提供此类咨询服务
亲爱的中文用户请注意
1. [Stack Overflow](http://stackoverflow.com/questions/tagged/antd)
2. [Segment Fault](https://segmentfault.com/t/antd)(中文)
如果是报告 bug请按照下列格式书写并务必提供复现步骤否则恕难解决感谢您的支持。
1. 官方 issue 用于报告 bug 和讨论需求。用法咨询类问题建议到 https://segmentfault.com/t/antd 上提问,目前社区没有足够精力提供此类服务,感谢您的理解。
2. 建议使用英文进行提问,这样你的问题可以被更多的人阅读和回答。如果表达上较复杂,英文标题加中文描述也是可选的方案。
3. 报告 BUG 时请务必按照下列格式书写并尽可能提供源代码、复现步骤、复现演示、GIF 演示等。我们和你一样都希望尽快解决问题,请不要浪费时间在互相追问上。
4. 如果需要粘贴源码,尽量避免截图并注意代码格式。关于如何在 Markdown 中书写代码可以参考https://segmentfault.com/markdown
-->
#### Environment(required)

View File

@@ -17,6 +17,41 @@ If you want to read change logs before `2.0.0`, please visit [GitHub](https://gi
---
## 2.7.3
`2017-02-25`
- Unify demo code to ES6 class. [#4878](https://github.com/ant-design/ant-design/issues/4878)
- TypeScript
- Fix that `Cannot find module '../../package.json'` error. [#4935](https://github.com/ant-design/ant-design/issues/4935)
- Fix definitions of Table, RangePicker and Upload.
- Fix lack of event argument for Modal `onOk` `afterClose` and Popconfirm `onConfirm` `onCancel`. [#4787](https://github.com/ant-design/ant-design/issues/4787)
- Improve animation of Menu[inline] and Collapse.
- Improve Checkbox and Radio vertical align style.
- Table
- Fix misplace header when fix column. [#4936](https://github.com/ant-design/ant-design/issues/4936)
- Fix not clearing float issue. [#4945](https://github.com/ant-design/ant-design/issues/4945)
- Fix submenu of filter. [#4975](https://github.com/ant-design/ant-design/issues/4975)
- Fix that filterDropdown of fixed column cannot be interacted with. [#5010](https://github.com/ant-design/ant-design/issues/5010)
- Fix that arguments of `pagination.onChange` do not match Pagination `onChange`.
- Fix that table loading animation is not smoothing. [#4934](https://github.com/ant-design/ant-design/issues/4934)
- Improve multiple message display. [#3543](https://github.com/ant-design/ant-design/issues/3543)
- Fix Carousel autoplay not working after resize window. [#2550](https://github.com/ant-design/ant-design/issues/2550)
- Fix that controlled InputNumber cannot input number like `1.01` `1.001`. [#5012](https://github.com/ant-design/ant-design/issues/5012)
- Improve Button loading switching.[#4913](https://github.com/ant-design/ant-design/issues/4913)
- Fix Dropdown selected menu style and `Menu[theme="dark"]` style. [#5013](https://github.com/ant-design/ant-design/issues/5013) [#4903](https://github.com/ant-design/ant-design/issues/4903)
- Fix Menu submenu `z-index` issue. [#4937](https://github.com/ant-design/ant-design/issues/4937)
- Fix that DatePicker and RangePicker width cannot be reset below `300px` issue. [#4920](https://github.com/ant-design/ant-design/issues/4920)
- Fix style of Spin nested in Spin. [#4971](https://github.com/ant-design/ant-design/issues/4971)
- Fix that lack of Button style when import Popconfirm by babel-plugin-import.
- Fix that less variables cannot work on circle Progress. [#5002](https://github.com/ant-design/ant-design/issues/5002)
- Fix falsy children of Breadcrumb. [#5015](https://github.com/ant-design/ant-design/issues/5015)
- Fix blinking tooltip of Slider. [#5003](https://github.com/ant-design/ant-design/issues/5003)
- Fix that Transfer disabled option can be moved. [#4981](https://github.com/ant-design/ant-design/pull/4981) [@tianlizhao](https://github.com/tianlizhao)
- Documentation
- Fix and improve site for mobile devices.
- Improve 1.x to 2.x compatibility instruction.
## 2.7.2
`2017-02-17`

View File

@@ -17,6 +17,41 @@ timeline: true
---
## 2.7.3
`2017-02-25`
- 演示代码统一为 ES6 class 的写法。[#4878](https://github.com/ant-design/ant-design/issues/4878)
- TypeScript
- 修复 `Cannot find module '../../package.json'` 的问题。[#4935](https://github.com/ant-design/ant-design/issues/4935)
- 补充了 Table、RangePicker 和 Upload 的部分属性定义。
- 修复了 Modal `onOk` `afterClose` 和 Popconfirm `onConfirm` `onCancel` 缺少点击 event 参数的问题。 [#4787](https://github.com/ant-design/ant-design/issues/4787)
- 优化 Menu[inline] 和 Collapse 的折叠动画效果。
- 优化了 Checkbox 和 Radio 的垂直对齐样式。
- Table
- 修复固定列时列头样式错位的问题。[#4936](https://github.com/ant-design/ant-design/issues/4936)
- 修复未清除浮动导致排版错位的问题。[#4945](https://github.com/ant-design/ant-design/issues/4945)
- 修复筛选子菜单无法显示的问题。[#4975](https://github.com/ant-design/ant-design/issues/4975)
- 修复固定列上的自定义筛选菜单无法交互的问题。[#5010](https://github.com/ant-design/ant-design/issues/5010)
- 修正 `pagination.onChange` 和 Pagination 的 `onChange` 参数不一致的问题。
- 修复加载状态切换不柔和的问题。[#4934](https://github.com/ant-design/ant-design/issues/4934)
- 优化多个 message 展示重叠的问题。[#3543](https://github.com/ant-design/ant-design/issues/3543)
- 修复 Carousel 在改变浏览器窗口大小后 autoplay 会失效的问题。[#2550](https://github.com/ant-design/ant-design/issues/2550)
- 修复了 InputNumber 在受控模式Form 表单内)无法输入 `1.01` `1.001` 等数字的问题。[#5012](https://github.com/ant-design/ant-design/issues/5012)
- 优化 Button 加载状态切换时的宽度抖动问题。[#4913](https://github.com/ant-design/ant-design/issues/4913)
- 修复 Dropdown 的菜单选中样式和 `Menu[theme="dark"]` 样式无效的问题。[#5013](https://github.com/ant-design/ant-design/issues/5013) [#4903](https://github.com/ant-design/ant-design/issues/4903)
- 修复 Menu 的弹出菜单的 `z-index` 问题。[#4937](https://github.com/ant-design/ant-design/issues/4937)
- 修复 DatePicker 和 RangePicker 无法设置小于 300px 的宽度的问题。[#4920](https://github.com/ant-design/ant-design/issues/4920)
- 修复 Spin 内嵌 Spin 的样式问题。[#4971](https://github.com/ant-design/ant-design/issues/4971)
- 修复了使用 babel-plugin-import 引入 Popconfirm 时,未引入 Button 样式的问题。
- 修复了样式变量在 Progress `type="circle"` 上未生效的问题。[#5002](https://github.com/ant-design/ant-design/issues/5002)
- 修复了 Breadcrumb 的 chilren 为 `null``undefined` 时报错的问题。[#5015](https://github.com/ant-design/ant-design/issues/5015)
- 修复 Slider 的 tooltip 闪烁的问题。[#5003](https://github.com/ant-design/ant-design/issues/5003)
- 修复了 Transfer 中 disabled 选项仍然可以被移动的问题。[#4981](https://github.com/ant-design/ant-design/pull/4981) [@tianlizhao](https://github.com/tianlizhao)
- 文档
- 修复和优化了移动端的展现。
- 优化了 1.x 升级到 2.x 的不兼容改动文档。
## 2.7.2
`2017-02-17`
@@ -139,10 +174,10 @@ timeline: true
`2017-01-14`
* 新增社区精选组件页面。[链接](/docs/react/recommendation-cn)
* 新增社区精选组件页面。[链接](/docs/react/recommendation)
* 修复一个内容过长导致 Layout 侧边布局错位的问题。[#4459](https://github.com/ant-design/ant-design/issues/4459)
* 修复 Input.Search 输入框和图标错位的问题。[#4540](https://github.com/ant-design/ant-design/issues/4540)
* 补充了一个自定义灰底样式的 Collapse 折叠面板的例子。[链接](/components/collapse-cn/#components-collapse-demo-custom)
* 补充了一个自定义灰底样式的 Collapse 折叠面板的例子。[链接](/components/collapse/#components-collapse-demo-custom)
* Table
* 调大了 Table 选择框和展开按钮的列宽度。
* 修复 `pagination` 属性切换后分页不可用的问题。[#4532](https://github.com/ant-design/ant-design/issues/4532)
@@ -498,9 +533,11 @@ timeline: true
> 建议从 `1.x` 升级时,直接升级到 `2.x` 的最新版本。
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。
> 建议在升级 antd 的过程中,每做完一次合理的修改并 review 和测试之后,就 git commit 一次,这样在误操作时能随时回滚到之前的版本
* 时间类组件的 `value``defaultValue` 不再支持 `String/Date` 类型,请使用 [moment](http://momentjs.com/)
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。另外由于人肉查找代码中的废弃用法过于低效,所以我们提供了 [antd-migration-helper](https://github.com/ant-design/antd-migration-helper) 用于扫描代码中的废弃用法
* 时间类组件的 `value``defaultValue` 不再支持 `String/Date` 类型,请使用 [moment](http://momentjs.com/)。需要对代码进行如下修改,可人手修改也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#time-related-value-to-moment) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
```diff
- <TimePicker defaultValue="12:08:23" />
+ <TimePicker defaultValue={moment('12:08:23', 'HH:mm:ss')} />
@@ -511,9 +548,16 @@ timeline: true
- <Calendar defaultValue={new Date('2010-10-10')} />
+ <Calendar defaultValue={moment('2010-10-10', 'YYYY-MM-DD')} />
```
* 时间类组件的 `onChange` 和 `onPanelChange` 及其他回调函数中为 `Date/GregorianCalendar` 类型的参数,均修改为 moment 类型,两者 API 有所不同,但功能基本一致,请对照 [moment 的 API 文档](http://momentjs.com/docs/) 和 [gregorian-calendar 的文档](https://github.com/yiminghe/gregorian-calendar) 进行修改。你也可以参考这个 [commit](https://github.com/ant-design/ant-design/commit/4026221d451b246956983bb42140142d4a48b7d7) 来进行修改。
由于 `JSON.stringify(date: moment)` 返回的值会丢失时区设置,所以要先使用 `.format` 把日期转成字符串,相关 issue 见 [#3082](https://github.com/ant-design/ant-design/issues/3082)
* 时间类组件的 `onChange` 和 `onPanelChange` 及其他回调函数中为 `Date/GregorianCalendar` 类型的参数,均修改为 moment 类型,两者 API 有所不同,但功能基本一致,请对照 [moment 的 API 文档](http://momentjs.com/docs/) 和 [gregorian-calendar 的文档](https://github.com/yiminghe/gregorian-calendar) 进行修改。
1. 也可以参考这个 [commit](https://github.com/ant-design/ant-design/commit/4026221d451b246956983bb42140142d4a48b7d7) 来进行修改。
1. 也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#gergoriancalendar-to-moment) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
```diff
function disabledDate(date) {
- console.log(date.getTime());
+ console.log(date.valueOf());
}
```
* 由于 `JSON.stringify(date: moment)` 返回的值会丢失时区设置,所以在提交前要先使用 `.format` 把日期转成字符串,相关 issue 见 [#3082](https://github.com/ant-design/ant-design/issues/3082)
```js
handleSubmit() {
const values = this.props.form.getFieldsValue();
@@ -522,9 +566,17 @@ timeline: true
// 发送 data 到服务器
}
```
* 时间类组件与表单校验一起使用时,`type: 'date'` 改为 `type: 'object'`。
* 时间类组件的 `format` 属性也发生了变化,从 [gregorian-calendar-format 的格式](https://github.com/yiminghe/gregorian-calendar-format#api) 变化为与 [moment 的格式](http://momentjs.com/docs/#/parsing/string-format/),例如原来的 `yyyy-MM-dd` 将变为 `YYYY-MM-DD`。
```diff
getFieldDecorator('time', {
rules: [{
required: true,
- type: 'date',
+ type: 'object',
}],
})(...)
```
* 时间类组件的 `format` 属性也发生了变化,从 [gregorian-calendar-format 的格式](https://github.com/yiminghe/gregorian-calendar-format#api) 变化为与 [moment 的格式](http://momentjs.com/docs/#/parsing/string-format/),例如原来的 `yyyy-MM-dd` 将变为 `YYYY-MM-DD`。可人手修改也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#time-related-value-to-moment) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
* Breadcrumb 移除 `linkRender` 和 `nameRender`,请使用 `itemRender`。
* Menu 移除 `onClose` `onOpen`,请使用 `onOpenChange`。API 差异较大,请先研究 [demo](http://beta.ant.design/components/menu/#components-menu-demo-sider-current)。
* Table 移除列分页功能,请使用 [固定列](http://ant.design/components/table/#components-table-demo-fixed-columns)。
@@ -532,7 +584,7 @@ timeline: true
以下变化升级后旧代码仍然能正常运行,但是控制台会出现警告提示,建议按提示进行修改。
* Form 废弃 `getFieldProps`,请使用 `getFieldDecorator`
* Form 废弃 `getFieldProps`,请使用 `getFieldDecorator`。可人手修改也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#getfieldprops-to-getfielddecorator) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
```diff
- <Input placeholder="text" {...getFieldProps('userName', { ... })} />
@@ -552,6 +604,8 @@ timeline: true
}
```
最后,由于时间类组件修改比较复杂,可能还需要深入业务逻辑,所以在项目比较赶的情况下,可以考虑使用 [antd-adapter](https://github.com/ant-design/antd-adapter) 适配为 `antd@1.x` 里面的用法,但不建议。
### 2.x Bug 修复
* 修复 Dropdown.Button `disabled` 属性无效的问题。[#3070](https://github.com/ant-design/ant-design/issues/3070)

View File

@@ -28,7 +28,7 @@ An enterprise-class UI design language and React-based implementation.
## Let's build a better antd together [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
`antd` is an open source project, improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22).
`antd` is an open source project, improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22). Actually, there are [many ways](https://opensource.guide/how-to-contribute/) to contribute.
## Install

View File

@@ -27,7 +27,6 @@ export default function getRequestAnimationFrame() {
}
export function cancelRequestAnimationFrame(id) {
if (typeof window === 'undefined') {
return null;
}

View File

@@ -1,21 +1,37 @@
import cssAnimation from 'css-animation';
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from './getRequestAnimationFrame';
const reqAnimFrame = getRequestAnimationFrame();
function animate(node, show, done) {
let height;
let requestAnimationFrameId;
return cssAnimation(node, 'ant-motion-collapse', {
start() {
if (!show) {
node.style.height = `${node.offsetHeight}px`;
node.style.opacity = 1;
} else {
height = node.offsetHeight;
node.style.height = 0;
node.style.opacity = 0;
}
},
active() {
node.style.height = `${show ? height : 0}px`;
if (requestAnimationFrameId) {
cancelRequestAnimationFrame(requestAnimationFrameId);
}
requestAnimationFrameId = reqAnimFrame(() => {
node.style.height = `${show ? height : 0}px`;
node.style.opacity = show ? 1 : 0;
});
},
end() {
if (requestAnimationFrameId) {
cancelRequestAnimationFrame(requestAnimationFrameId);
}
node.style.height = '';
node.style.opacity = '';
done();
},
});

View File

@@ -29,6 +29,8 @@ function getOffset(element: HTMLElement, target) {
scrollTop - clientTop,
left: elemRect.left - targetRect.left +
scrollLeft - clientLeft,
width: elemRect.width,
height: elemRect.height,
};
}
@@ -138,14 +140,15 @@ export default class Affix extends React.Component<AffixProps, any> {
(targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight;
if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) {
// Fixed Top
const width = elemOffset.width;
this.setAffixStyle(e, {
position: 'fixed',
top: targetRect.top + offsetTop,
left: targetRect.left + elemOffset.left,
width: affixNode.offsetWidth,
width,
});
this.setPlaceholderStyle({
width: affixNode.offsetWidth,
width,
height: affixNode.offsetHeight,
});
} else if (
@@ -154,14 +157,15 @@ export default class Affix extends React.Component<AffixProps, any> {
) {
// Fixed Bottom
const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom);
const width = elemOffset.width;
this.setAffixStyle(e, {
position: 'fixed',
bottom: targetBottomOffet + offsetBottom,
left: targetRect.left + elemOffset.left,
width: affixNode.offsetWidth,
width,
});
this.setPlaceholderStyle({
width: affixNode.offsetWidth,
width,
height: affixNode.offsetHeight,
});
} else {
@@ -222,7 +226,7 @@ export default class Affix extends React.Component<AffixProps, any> {
[this.props.prefixCls || 'ant-affix']: this.state.affixStyle,
});
const props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target']);
const props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target', 'onChange']);
const placeholderStyle = { ...this.state.placeholderStyle, ...this.props.style };
return (
<div {...props} style={placeholderStyle}>

View File

@@ -20,13 +20,12 @@ function onSelect(value) {
console.log('onSelect', value);
}
const Complete = React.createClass({
getInitialState() {
return {
dataSource: [],
};
},
handleChange(value) {
class Complete extends React.Component {
state = {
dataSource: [],
}
handleChange = (value) => {
this.setState({
dataSource: !value ? [] : [
value,
@@ -34,10 +33,12 @@ const Complete = React.createClass({
value + value + value,
],
});
},
handleKeyPress(ev) {
}
handleKeyPress = (ev) => {
console.log('handleKeyPress', ev);
},
}
render() {
const { dataSource } = this.state;
return (
@@ -51,8 +52,8 @@ const Complete = React.createClass({
<textarea onKeyPress={this.handleKeyPress} style={{ height: 50 }} />
</AutoComplete>
);
},
});
}
}
ReactDOM.render(<Complete />, mountNode);
````

View File

@@ -20,13 +20,12 @@ function onSelect(value) {
console.log('onSelect', value);
}
const Complete = React.createClass({
getInitialState() {
return {
dataSource: [],
};
},
handleChange(value) {
class Complete extends React.Component {
state = {
dataSource: [],
}
handleChange = (value) => {
this.setState({
dataSource: !value ? [] : [
value,
@@ -34,7 +33,8 @@ const Complete = React.createClass({
value + value + value,
],
});
},
}
render() {
const { dataSource } = this.state;
return (
@@ -46,8 +46,8 @@ const Complete = React.createClass({
placeholder="input here"
/>
);
},
});
}
}
ReactDOM.render(<Complete />, mountNode);
````

View File

@@ -19,12 +19,14 @@ import { AutoComplete } from 'antd';
const dataSource = ['Burns Bay Road', 'Downing Street', 'Wall Street'];
function Complete() {
return (<AutoComplete
style={{ width: 200 }}
dataSource={dataSource}
placeholder="try to type `b`"
filterOption={(inputValue, option) => option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1}
/>);
return (
<AutoComplete
style={{ width: 200 }}
dataSource={dataSource}
placeholder="try to type `b`"
filterOption={(inputValue, option) => option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1}
/>
);
}
ReactDOM.render(<Complete />, mountNode);

View File

@@ -18,13 +18,12 @@ import { AutoComplete } from 'antd';
const Option = AutoComplete.Option;
const Complete = React.createClass({
getInitialState() {
return {
result: [],
};
},
handleChange(value) {
class Complete extends React.Component {
state = {
result: [],
}
handleChange = (value) => {
let result;
if (!value || value.indexOf('@') >= 0) {
result = [];
@@ -32,7 +31,8 @@ const Complete = React.createClass({
result = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
}
this.setState({ result });
},
}
render() {
const { result } = this.state;
const children = result.map((email) => {
@@ -47,8 +47,8 @@ const Complete = React.createClass({
{children}
</AutoComplete>
);
},
});
}
}
ReactDOM.render(<Complete />, mountNode);
````

View File

@@ -47,24 +47,24 @@ function renderOption(item) {
{item.category}
</a>
区块中
<span style={{ float: 'right' }}>约 {item.count} 个结果</span>
<span className="global-search-item-count">约 {item.count} 个结果</span>
</Option>
);
}
const Complete = React.createClass({
getInitialState() {
return {
dataSource: [],
};
},
handleChange(value) {
class Complete extends React.Component {
state = {
dataSource: [],
}
handleChange = (value) => {
if (value) {
this.setState({
dataSource: searchResult(value),
});
}
},
}
render() {
const { dataSource } = this.state;
return (
@@ -89,8 +89,8 @@ const Complete = React.createClass({
</AutoComplete>
</div>
);
},
});
}
}
ReactDOM.render(<Complete />, mountNode);
````
@@ -132,7 +132,14 @@ ReactDOM.render(<Complete />, mountNode);
}
.global-search.ant-select-auto-complete .ant-input-preSuffix-wrapper .ant-input-suffix button {
padding-top: 5px;
padding-bottom: 6px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.global-search-item-count {
position: absolute;
right: 16px;
}
````

View File

@@ -1,7 +1,7 @@
---
category: Components
type: Data Entry
cols: 1
cols: 2
title: AutoComplete
---
@@ -27,7 +27,8 @@ const dataSource = ['12345', '23456', '34567'];
| onChange | Called when select an option or input value change, or value of input is changed | function(value, label) | - |
| onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - |
| disabled | Whether disabled select | boolean | false |
| defaultActiveFirstOption | Whether active first option by default | boolean | true |
| placeholder | placeholder of input | string | - |
| children (for dataSource) | Data source for autocomplet | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
| children (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true |

View File

@@ -39,17 +39,18 @@ export interface AutoCompleteProps extends AbstractSelectProps {
}
class InputElement extends React.Component<any, any> {
private ele: Element;
private ele: HTMLInputElement;
focus = () => {
(findDOMNode(this.ele) as HTMLInputElement).focus();
this.ele.focus ? this.ele.focus() : (findDOMNode(this.ele) as HTMLInputElement).focus();
}
blur = () => {
(findDOMNode(this.ele) as HTMLInputElement).blur();
this.ele.blur ? this.ele.blur() : (findDOMNode(this.ele) as HTMLInputElement).blur();
}
render() {
return React.cloneElement(this.props.children, {
...this.props,
ref: ele => this.ele = ele,
ref: ele => this.ele = (ele as HTMLInputElement),
}, null);
}
}

View File

@@ -28,6 +28,7 @@ const dataSource = ['12345', '23456', '34567'];
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |
| disabled | 是否禁用 | boolean | false |
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true
| placeholder | 输入框提示 | string | - |
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |

View File

@@ -17,27 +17,29 @@ The count will be animated as it changes.
import { Badge, Button, Icon, Switch } from 'antd';
const ButtonGroup = Button.Group;
const Test = React.createClass({
getInitialState() {
return {
count: 5,
show: true,
};
},
increase() {
class Demo extends React.Component {
state = {
count: 5,
show: true,
}
increase = () => {
const count = this.state.count + 1;
this.setState({ count });
},
decline() {
}
decline = () => {
let count = this.state.count - 1;
if (count < 0) {
count = 0;
}
this.setState({ count });
},
onChange(show) {
}
onChange = (show) => {
this.setState({ show });
},
}
render() {
return (
<div>
@@ -62,8 +64,8 @@ const Test = React.createClass({
</div>
</div>
);
},
});
}
}
ReactDOM.render(<Test />, mountNode);
ReactDOM.render(<Demo />, mountNode);
````

View File

@@ -16,14 +16,16 @@ This will simply display a red badge, without a specific count.
````jsx
import { Badge, Icon } from 'antd';
ReactDOM.render(<div>
<Badge dot>
<Icon type="notification" />
</Badge>
<Badge dot>
<a href="#">Link something</a>
</Badge>
</div>, mountNode);
ReactDOM.render(
<div>
<Badge dot>
<Icon type="notification" />
</Badge>
<Badge dot>
<a href="#">Link something</a>
</Badge>
</div>
, mountNode);
````
<style>

View File

@@ -18,9 +18,11 @@ Used in standalone when children is empty.
````jsx
import { Badge } from 'antd';
ReactDOM.render(<div>
<Badge count={25} />
<Badge count={4} style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset' }} />
<Badge count={109} style={{ backgroundColor: '#87d068' }} />
</div>, mountNode);
ReactDOM.render(
<div>
<Badge count={25} />
<Badge count={4} style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset' }} />
<Badge count={109} style={{ backgroundColor: '#87d068' }} />
</div>
, mountNode);
````

View File

@@ -16,18 +16,20 @@ title:
````jsx
import { Badge } from 'antd';
ReactDOM.render(<div>
<Badge count={99}>
<a href="#" className="head-example" />
</Badge>
<Badge count={100}>
<a href="#" className="head-example" />
</Badge>
<Badge count={99} overflowCount={10}>
<a href="#" className="head-example" />
</Badge>
<Badge count={1000} overflowCount={999}>
<a href="#" className="head-example" />
</Badge>
</div>, mountNode);
ReactDOM.render(
<div>
<Badge count={99}>
<a href="#" className="head-example" />
</Badge>
<Badge count={100}>
<a href="#" className="head-example" />
</Badge>
<Badge count={99} overflowCount={10}>
<a href="#" className="head-example" />
</Badge>
<Badge count={1000} overflowCount={999}>
<a href="#" className="head-example" />
</Badge>
</div>
, mountNode);
````

View File

@@ -88,8 +88,11 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
});
} else if (children) {
crumbs = React.Children.map(children, (element: any, index) => {
if (!element) {
return element;
}
warning(
element && element.type.__ANT_BREADCRUMB_ITEM,
element.type && element.type.__ANT_BREADCRUMB_ITEM,
'Breadcrumb only accetps Breadcrumb.Item as it\'s children'
);
return cloneElement(element, {

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { mount } from 'enzyme';
import Breadcrumb from '../Breadcrumb';
import { mount, render } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Breadcrumb from '../index';
describe('Breadcrumb', () => {
it('warns on non-Breadcrumb.Item children', () => {
@@ -18,4 +19,18 @@ describe('Breadcrumb', () => {
'Breadcrumb only accetps Breadcrumb.Item as it\'s children'
);
});
// https://github.com/ant-design/ant-design/issues/5015
it('should allow Breadcrumb.Item is null or undefined', () => {
const wrapper = render(
<Breadcrumb>
{null}
<Breadcrumb.Item>Home</Breadcrumb.Item>
{undefined}
</Breadcrumb>
);
// eslint-disable-next-line
expect(console.error.calls).toBe(undefined);
expect(renderToJson(wrapper)).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,15 @@
exports[`Breadcrumb should allow Breadcrumb.Item is null or undefined 1`] = `
<div
class="ant-breadcrumb">
<span>
<span
class="ant-breadcrumb-link">
Home
</span>
<span
class="ant-breadcrumb-separator">
/
</span>
</span>
</div>
`;

View File

@@ -1,6 +1,6 @@
---
order: 0
title:
title:
zh-CN: 基本
en-US: Basic Usage
---

View File

@@ -351,6 +351,13 @@ exports[`test renders ./components/button/demo/loading.md correctly 1`] = `
Click me!
</span>
</button>
<button
class="ant-btn ant-btn-primary"
type="button">
<span>
Won\'t show loading
</span>
</button>
<br />
<button
class="ant-btn ant-btn-circle ant-btn-loading"

View File

@@ -2,6 +2,7 @@ import React from 'react';
import classNames from 'classnames';
import { findDOMNode } from 'react-dom';
import Icon from '../icon';
import omit from 'omit.js';
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
@@ -51,6 +52,7 @@ export default class Button extends React.Component<ButtonProps, any> {
static defaultProps = {
prefixCls: 'ant-btn',
loading: false,
clicked: false,
ghost: false,
};
@@ -65,29 +67,45 @@ export default class Button extends React.Component<ButtonProps, any> {
icon: React.PropTypes.string,
};
timeout: any;
clickedTimeout: any;
timeout: number;
delayTimeout: number;
componentWillUnmount() {
if (this.clickedTimeout) {
clearTimeout(this.clickedTimeout);
constructor(props) {
super(props);
this.state = {
loading: props.loading,
};
}
componentWillReceiveProps(nextProps) {
const currentLoading = this.props.loading;
const loading = nextProps.loading;
if (currentLoading) {
clearTimeout(this.delayTimeout);
}
if (this.timeout) {
clearTimeout(this.timeout);
if (loading) {
this.delayTimeout = setTimeout(() => this.setState({ loading }), 200);
} else {
this.setState({ loading });
}
}
clearButton = (button) => {
button.className = button.className.replace(` ${this.props.prefixCls}-clicked`, '');
componentWillUnmount() {
if (this.timeout) {
clearTimeout(this.timeout);
}
if (this.delayTimeout) {
clearTimeout(this.delayTimeout);
}
}
handleClick = (e) => {
// Add click effect
const buttonNode = findDOMNode(this);
this.clearButton(buttonNode);
this.clickedTimeout = setTimeout(() => buttonNode.className += ` ${this.props.prefixCls}-clicked`, 10);
this.setState({ clicked: true });
clearTimeout(this.timeout);
this.timeout = setTimeout(() => this.clearButton(buttonNode), 500);
this.timeout = setTimeout(() => this.setState({ clicked: false }), 500);
const onClick = this.props.onClick;
if (onClick) {
@@ -105,9 +123,10 @@ export default class Button extends React.Component<ButtonProps, any> {
render() {
const {
type, shape, size = '', className, htmlType, children, icon, loading, prefixCls, ghost, ...others,
type, shape, size = '', className, htmlType, children, icon, prefixCls, ghost, ...others,
} = this.props;
const { loading, clicked } = this.state;
// large => lg
// small => sm
const sizeCls = ({
@@ -121,6 +140,7 @@ export default class Button extends React.Component<ButtonProps, any> {
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-icon-only`]: !children && icon,
[`${prefixCls}-loading`]: loading,
[`${prefixCls}-clicked`]: clicked,
[`${prefixCls}-background-ghost`]: ghost,
}, className);
@@ -130,7 +150,7 @@ export default class Button extends React.Component<ButtonProps, any> {
return (
<button
{...others}
{...omit(others, ['loading', 'clicked'])}
type={htmlType || 'button'}
className={classes}
onMouseUp={this.handleMouseUp}

View File

@@ -16,19 +16,30 @@ A loading indicator can be added to a button by setting the `loading` property o
````jsx
import { Button } from 'antd';
const App = React.createClass({
getInitialState() {
return {
loading: false,
iconLoading: false,
};
},
enterLoading() {
class App extends React.Component {
state = {
loading: false,
iconLoading: false,
delayLoading: false,
}
enterLoading = () => {
this.setState({ loading: true });
},
enterIconLoading() {
}
enterIconLoading = () => {
this.setState({ iconLoading: true });
},
}
delayLoading = () => {
this.setState({
delayLoading: true,
});
setTimeout(() => this.setState({
delayLoading: false,
}), 150);
}
render() {
return (
<div>
@@ -45,13 +56,16 @@ const App = React.createClass({
<Button type="primary" icon="poweroff" loading={this.state.iconLoading} onClick={this.enterIconLoading}>
Click me!
</Button>
<Button type="primary" loading={this.state.delayLoading} onClick={this.delayLoading}>
Won&apos;t show loading
</Button>
<br />
<Button shape="circle" loading />
<Button type="primary" shape="circle" loading />
</div>
);
},
});
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -82,13 +82,16 @@
display: block;
}
.@{iconfont-css-prefix} {
transition: all .3s @ease-in-out;
}
&&-loading:not(&-circle):not(&-circle-outline) {
padding-left: 29px;
pointer-events: none;
position: relative;
.@{iconfont-css-prefix} {
margin-left: -14px;
transition: all .3s @ease-in-out;
}
}
@@ -122,9 +125,9 @@
bottom: -1px;
right: -1px;
border-radius: inherit;
border: 1.5px solid @primary-color;
border: 0 solid @primary-color;
opacity: 0.4;
animation: buttonEffect 0.4s ease-in-out forwards;
animation: buttonEffect .4s;
display: block;
}
@@ -150,5 +153,6 @@
left: -6px;
bottom: -6px;
right: -6px;
border-width: 6px;
}
}

View File

@@ -1569,790 +1569,6 @@ exports[`test renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
`;
exports[`test renders ./components/calendar/demo/locale.md correctly 1`] = `
<div
class=" ant-fullcalendar-fullscreen">
<div
class="ant-fullcalendar-header">
<div
class="ant-fullcalendar-year-select ant-select ant-select-enabled">
<div
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
role="combobox"
tabindex="0">
<div
class="ant-select-selection__rendered">
<div
class="ant-select-selection-selected-value"
style="display:block;opacity:1;"
title="2016">
2016
</div>
</div>
<span
class="ant-select-arrow"
style="user-select:none;-webkit-user-select:none;"
unselectable="unselectable">
<b />
</span>
</div>
</div>
<div
class="ant-fullcalendar-month-select ant-select ant-select-enabled">
<div
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
role="combobox"
tabindex="0">
<div
class="ant-select-selection__rendered">
<div
class="ant-select-selection-selected-value"
style="display:block;opacity:1;"
title="Nov">
Nov
</div>
</div>
<span
class="ant-select-arrow"
style="user-select:none;-webkit-user-select:none;"
unselectable="unselectable">
<b />
</span>
</div>
</div>
<div
class="ant-radio-group ant-radio-group-default">
<label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked">
<span
class="ant-radio-button ant-radio-button-checked ant-radio-button ant-radio-button-checked ant-radio-button-checked-1">
<span
class="ant-radio-button-inner" />
<input
checked=""
class="ant-radio-button-input"
type="radio" />
</span>
<span>
Month
</span>
</label>
<label
class="ant-radio-button-wrapper">
<span
class="ant-radio-button">
<span
class="ant-radio-button-inner" />
<input
class="ant-radio-button-input"
type="radio" />
</span>
<span>
Year
</span>
</label>
</div>
</div>
<div
class="ant-fullcalendar ant-fullcalendar-full ant-fullcalendar-fullscreen"
tabindex="0">
<div
class="ant-fullcalendar-calendar-body">
<table
cellspacing="0"
class="ant-fullcalendar-table"
role="grid">
<thead>
<tr
role="row">
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Sun">
<span
class="ant-fullcalendar-column-header-inner">
Su
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Mon">
<span
class="ant-fullcalendar-column-header-inner">
Mo
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Tue">
<span
class="ant-fullcalendar-column-header-inner">
Tu
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Wed">
<span
class="ant-fullcalendar-column-header-inner">
We
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Thu">
<span
class="ant-fullcalendar-column-header-inner">
Th
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Fri">
<span
class="ant-fullcalendar-column-header-inner">
Fr
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Sat">
<span
class="ant-fullcalendar-column-header-inner">
Sa
</span>
</th>
</tr>
</thead>
<tbody
class="ant-fullcalendar-tbody">
<tr
role="row">
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
role="gridcell"
title="2016-10-30">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
30
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
role="gridcell"
title="2016-10-31">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
31
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-1">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
01
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-2">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
02
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-3">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
03
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-4">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
04
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-5">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
05
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-6">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
06
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-7">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
07
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-8">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
08
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-9">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
09
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-10">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
10
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-11">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
11
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-12">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
12
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-13">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
13
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-14">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
14
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-15">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
15
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-16">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
16
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-17">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
17
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-18">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
18
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-19">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
19
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-20">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
20
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-21">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
21
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-today ant-fullcalendar-selected-day"
role="gridcell"
title="2016-11-22">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
22
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-23">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
23
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-24">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
24
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-25">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
25
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-26">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
26
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-27">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
27
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-28">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
28
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-29">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
29
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-30">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
30
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-1">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
01
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-2">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
02
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-3">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
03
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-4">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
04
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-5">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
05
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-6">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
06
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-7">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
07
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-8">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
08
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-9">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
09
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-10">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
10
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`test renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
<div
class=" ant-fullcalendar-fullscreen">

View File

@@ -1,30 +0,0 @@
---
order: 3
title:
zh-CN: 国际化
en-US: locale
---
## zh-CN
通过 `locale` 配置语言, 默认支持 en_US, zh_CN
## en-US
To set the language. en_US, zh_CN are supported by default.
````jsx
import { Calendar } from 'antd';
import enUS from 'antd/lib/calendar/locale/en_US';
import moment from 'moment';
// It's recommended to set moment locale globally, otherwise, you need to set it by `value` or `defaultValue`
// moment.locale('en');
function onPanelChange(value, mode) {
console.log(value, mode);
}
ReactDOM.render(
<Calendar defaultValue={moment().locale('en')} onPanelChange={onPanelChange} locale={enUS} />
, mountNode);
````

View File

@@ -13,7 +13,15 @@ When data is in the form of date, such as schedule, timetable, prices calendar,
## API
```html
**Note:** Part of locale of Calendar is read from value. So, please set the locale of moment correctly.
```jsx
import moment from 'moment';
// It's recommended to set locale in entry file globaly.
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
<Calendar
dateCellRender={dateCellRender}
monthCellRender={monthCellRender}

View File

@@ -15,7 +15,15 @@ title: Calendar
## API
```html
**注意:**Calendar 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。
```jsx
import moment from 'moment';
// 推荐在入口文件全局设置 locale
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
<Calendar
dateCellRender={dateCellRender}
monthCellRender={monthCellRender}

View File

@@ -1,6 +1,8 @@
// matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82
import assign from 'object-assign';
import debounce from 'lodash.debounce';
if (typeof window !== 'undefined') {
const matchMediaPolyfill = function matchMediaPolyfill(mediaQuery: string): MediaQueryList {
return {
@@ -48,6 +50,41 @@ export default class Carousel extends React.Component<CarouselProps, any> {
draggable: false,
};
refs: {
slick: any,
};
constructor() {
super();
this.onWindowResized = debounce(this.onWindowResized, 500, {
leading: false,
});
}
componentDidMount() {
const { autoplay } = this.props;
if (autoplay) {
window.addEventListener('resize', this.onWindowResized);
}
}
componentWillUnmount() {
const { autoplay } = this.props;
if (autoplay) {
window.removeEventListener('resize', this.onWindowResized);
(this.onWindowResized as any).cancel();
}
}
onWindowResized = () => {
// Fix https://github.com/ant-design/ant-design/issues/2550
const { slick } = this.refs;
const { autoplay } = this.props;
if (autoplay && slick && slick.innerSlider && slick.innerSlider.autoPlay) {
slick.innerSlider.autoPlay();
}
}
render() {
let props = assign({}, this.props);

View File

@@ -0,0 +1,179 @@
exports[`Cascader can be selected 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Hangzhou">
Hangzhou
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader can be selected 2`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Hangzhou">
Hangzhou
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item"
title="West Lake">
West Lake
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader can be selected 3`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ant-cascader-menus-hidden">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Hangzhou">
Hangzhou
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-active"
title="West Lake">
West Lake
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader popup correctly when panel is hidden 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-empty ant-cascader-menus-placement-bottomLeft ant-cascader-menus-hidden">
<div />
</div>
</div>
`;
exports[`Cascader popup correctly when panel is open 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader popup correctly with defaultValue 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Hangzhou">
Hangzhou
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item"
title="West Lake">
West Lake
</li>
</ul>
</div>
</div>
</div>
`;

View File

@@ -0,0 +1,71 @@
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Cascader from '..';
const options = [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}];
describe('Cascader', () => {
it('popup correctly when panel is hidden', () => {
const wrapper = mount(
<Cascader options={options} />
);
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('popup correctly when panel is open', () => {
const wrapper = mount(
<Cascader options={options} />
);
wrapper.find('input').simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('popup correctly with defaultValue', () => {
const wrapper = mount(
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />
);
wrapper.find('input').simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('can be selected', () => {
const wrapper = mount(<Cascader options={options} />);
wrapper.find('input').simulate('click');
let popupWrapper = mount(wrapper.find('Trigger').node.getComponent());
popupWrapper.find('.ant-cascader-menu').at(0).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
popupWrapper = mount(wrapper.find('Trigger').node.getComponent());
popupWrapper.find('.ant-cascader-menu').at(1).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
popupWrapper = mount(wrapper.find('Trigger').node.getComponent());
popupWrapper.find('.ant-cascader-menu').at(2).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
});

View File

@@ -32,17 +32,16 @@ const options = [{
}],
}];
const CitySwitcher = React.createClass({
getInitialState() {
return {
text: 'Unselect',
};
},
onChange(value, selectedOptions) {
class CitySwitcher extends React.Component {
state = {
text: 'Unselect',
};
onChange = (value, selectedOptions) => {
this.setState({
text: selectedOptions.map(o => o.label).join(', '),
});
},
}
render() {
return (
<span>
@@ -53,8 +52,8 @@ const CitySwitcher = React.createClass({
</Cascader>
</span>
);
},
});
}
}
ReactDOM.render(<CitySwitcher />, mountNode);
````

View File

@@ -20,14 +20,12 @@ const CheckboxGroup = Checkbox.Group;
const plainOptions = ['Apple', 'Pear', 'Orange'];
const defaultCheckedList = ['Apple', 'Orange'];
const App = React.createClass({
getInitialState() {
return {
checkedList: defaultCheckedList,
indeterminate: true,
checkAll: false,
};
},
class App extends React.Component {
state = {
checkedList: defaultCheckedList,
indeterminate: true,
checkAll: false,
};
render() {
return (
<div>
@@ -44,22 +42,22 @@ const App = React.createClass({
<CheckboxGroup options={plainOptions} value={this.state.checkedList} onChange={this.onChange} />
</div>
);
},
onChange(checkedList) {
}
onChange = (checkedList) => {
this.setState({
checkedList,
indeterminate: !!checkedList.length && (checkedList.length < plainOptions.length),
checkAll: checkedList.length === plainOptions.length,
});
},
onCheckAllChange(e) {
}
onCheckAllChange = (e) => {
this.setState({
checkedList: e.target.checked ? plainOptions : [],
indeterminate: false,
checkAll: e.target.checked,
});
},
});
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -16,13 +16,11 @@ Communicated with other components.
````jsx
import { Checkbox, Button } from 'antd';
const App = React.createClass({
getInitialState() {
return {
checked: true,
disabled: false,
};
},
class App extends React.Component {
state = {
checked: true,
disabled: false,
};
render() {
const label = `${this.state.checked ? 'Checked' : 'Unchecked'}-${this.state.disabled ? 'Disabled' : 'Enabled'}`;
return (
@@ -50,20 +48,20 @@ const App = React.createClass({
</p>
</div>
);
},
toggleChecked() {
}
toggleChecked = () => {
this.setState({ checked: !this.state.checked });
},
toggleDisable() {
}
toggleDisable = () => {
this.setState({ disabled: !this.state.disabled });
},
onChange(e) {
}
onChange = (e) => {
console.log('checked = ', e.target.checked);
this.setState({
checked: e.target.checked,
});
},
});
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -16,9 +16,11 @@ Disabled checkbox.
````jsx
import { Checkbox } from 'antd';
ReactDOM.render(<div>
<Checkbox defaultChecked={false} disabled />
<br />
<Checkbox defaultChecked disabled />
</div>, mountNode);
ReactDOM.render(
<div>
<Checkbox defaultChecked={false} disabled />
<br />
<Checkbox defaultChecked disabled />
</div>
, mountNode);
````

View File

@@ -24,7 +24,7 @@
position: relative;
top: 0;
left: 0;
display: inline-block;
display: block;
width: 14px;
height: 14px;
border: @border-width-base @border-style-base @border-color-base;
@@ -133,6 +133,7 @@
.@{checkbox-prefix-cls} + span {
padding-left: 8px;
padding-right: 8px;
vertical-align: middle;
}
.@{checkbox-prefix-cls}-group {

View File

@@ -1,6 +1,7 @@
import React from 'react';
import RcCollapse from 'rc-collapse';
import classNames from 'classnames';
import animation from '../_util/openAnimation';
export interface CollapseProps {
activeKey?: Array<string> | string;
@@ -30,6 +31,7 @@ export default class Collapse extends React.Component<CollapseProps, any> {
static defaultProps = {
prefixCls: 'ant-collapse',
bordered: true,
openAnimation: { ...animation, appear() {} },
};
render() {

View File

@@ -1,6 +1,7 @@
import React from 'react';
import CalendarLocale from 'rc-calendar/lib/locale/zh_CN';
import RcCalendar from 'rc-calendar';
import warning from 'warning';
export default class Calendar extends React.Component<any, any> {
static defaultProps = {
@@ -9,6 +10,7 @@ export default class Calendar extends React.Component<any, any> {
};
render() {
warning(false, 'DatePicker.Calendar is deprecated, use Calendar instead.');
return <RcCalendar {...this.props} />;
}
}

View File

@@ -113,7 +113,7 @@ exports[`test renders ./components/date-picker/demo/disabled-date.md correctly 1
<div>
<span
class="ant-calendar-picker"
style="min-width:154px;">
style="width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input"
@@ -210,24 +210,6 @@ exports[`test renders ./components/date-picker/demo/format.md correctly 1`] = `
</div>
`;
exports[`test renders ./components/date-picker/demo/locale.md correctly 1`] = `
<span
class="ant-calendar-picker"
style="min-width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input"
placeholder="Select date"
readonly=""
value="2016-11-22" />
<i
class="anticon anticon-cross-circle ant-calendar-picker-clear" />
<span
class="ant-calendar-picker-icon" />
</span>
</span>
`;
exports[`test renders ./components/date-picker/demo/presetted-ranges.md correctly 1`] = `
<div>
<span
@@ -384,7 +366,7 @@ exports[`test renders ./components/date-picker/demo/start-end.md correctly 1`] =
<div>
<span
class="ant-calendar-picker"
style="min-width:154px;">
style="width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input"
@@ -397,7 +379,7 @@ exports[`test renders ./components/date-picker/demo/start-end.md correctly 1`] =
</span>
<span
class="ant-calendar-picker"
style="min-width:154px;">
style="width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input"
@@ -415,7 +397,7 @@ exports[`test renders ./components/date-picker/demo/time.md correctly 1`] = `
<div>
<span
class="ant-calendar-picker"
style="min-width:154px;">
style="width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input"

View File

@@ -1,14 +1,3 @@
import { render } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import MockDate from 'mockdate';
import demoTest from '../../../tests/shared/demoTest';
demoTest('date-picker', { skip: ['locale.md'] });
test('renders ./components/date-picker/demo/locale.md correctly', () => {
MockDate.set(new Date('2016-11-22').getTime());
const LocaleDemo = require('../demo/locale'); // eslint-disable-line global-require
const wrapper = render(LocaleDemo);
expect(renderToJson(wrapper)).toMatchSnapshot();
MockDate.reset();
});

View File

@@ -143,7 +143,7 @@ export default function createPicker(TheCalendar) {
// default width for showTime
const pickerStyle = {} as any;
if (props.showTime) {
pickerStyle.minWidth = 154;
pickerStyle.width = (props.style && props.style.width) || 154;
}
const clearIcon = (!props.disabled && props.allowClear && value) ?

View File

@@ -1,44 +0,0 @@
---
order: 7
title:
zh-CN: 国际化
en-US: Locale
---
## zh-CN
通过 `locale` 设置语言, 默认支持 `en_US``zh_CN`
moment 会自动使用当前时区,如果需要使用别的时区,则需要自行设置,设置方法请参考示例代码中的注释。
## en-US
Use locale to set the language. `en_US`, `zh_CN` are supported by default.
moment will use your time zone automatically. If you want to set other time zone, please set it by yourself.
````jsx
import { DatePicker } from 'antd';
import enUS from 'antd/lib/date-picker/locale/en_US';
import moment from 'moment-timezone/moment-timezone';
// It's recommended to set moment locale and time zone globally in entry file,
// otherwise, you need to set it by `value` or `defaultValue`.
// moment.locale('en');
// The following data is copied from https://github.com/moment/moment-timezone/blob/develop/data/packed/latest.json
// moment.tz.add('Europe/London|GMT BST BDST|0 -10 -20|0101010101010101010101010101010101010101010101010121212121210101210101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2axa0 Rc0 1fA0 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 2Rz0 Dc0 1zc0 Oo0 1zc0 Rc0 1wo0 17c0 1iM0 FA0 xB0 1fA0 1a00 14o0 bb0 LA0 xB0 Rc0 1wo0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1a00 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1tA0 IM0 90o0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|10e6');
// moment.tz.setDefault('Europe/London')
const log = console.log.bind(console);
ReactDOM.render(
<DatePicker
defaultValue={moment().locale('en').utcOffset(0)}
locale={enUS}
showTime
onChange={log}
/>
, mountNode);
````

View File

@@ -59,6 +59,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker.
| showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showToday | whether to show "Today" button | boolean | true |
| disabledTime | to specify the time that cannot be selected | function(date) | - |
| onOk | callback when click ok button | function() | - |
### MonthPicker

View File

@@ -22,6 +22,7 @@ export interface PickerProps {
getCalendarContainer?: (trigger: any) => React.ReactNode;
open?: boolean;
onOpenChange?: (status: boolean) => void;
disabledDate?: (current: moment.Moment) => boolean;
}
export interface SinglePickerProps {
@@ -36,14 +37,17 @@ export interface DatePickerProps extends PickerProps, SinglePickerProps {
showToday?: boolean;
open?: boolean;
toggleOpen?: (e: {open: boolean}) => void;
disabledDate?: (current: moment.Moment) => boolean;
disabledTime?: (current: moment.Moment) => {
disabledHours?: () => [number, number],
disabledMinutes?: () => [number, number],
disabledSeconds?: () => [number, number],
};
onOpenChange?: (status: boolean) => void;
placeholder?: string;
}
const DatePicker = wrapPicker(createPicker(RcCalendar)) as React.ClassicComponentClass<DatePickerProps>;
export interface MonthPickerProps extends PickerProps, SinglePickerProps {
disabledDate?: (current: moment.Moment) => boolean;
placeholder?: string;
}
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'YYYY-MM');
@@ -57,6 +61,12 @@ export interface RangePickerProps extends PickerProps {
ranges?: {
[range: string]: moment.Moment[],
};
placeholder?: [string, string];
disabledTime?: (current: moment.Moment, type: string) => {
disabledHours?: () => [number, number],
disabledMinutes?: () => [number, number],
disabledSeconds?: () => [number, number],
};
}
assign(DatePicker, {

View File

@@ -48,6 +48,7 @@ moment.locale('zh-cn');
| open | 控制弹层是否展开 | boolean | - |
| onOpenChange | 弹出日历和关闭日历的回调 | function(status) | 无 |
| placeholder | 输入框提示文字 | string\|RangePicker[] | - |
| onOk | 点击确定按钮的回调 | function() | - |
### DatePicker

View File

@@ -191,7 +191,7 @@
&-combobox {
display: inline-block;
height: 100%;
background-color: white;
background-color: @component-background;
border-top: @border-width-base @border-style-base @border-color-split;
}
&-select {

View File

@@ -16,20 +16,18 @@ The default is to close the menu when you click on menu items, this feature can
````jsx
import { Menu, Dropdown, Icon } from 'antd';
const OverlayVisible = React.createClass({
getInitialState() {
return {
visible: false,
};
},
handleMenuClick(e) {
class OverlayVisible extends React.Component {
state = {
visible: false,
};
handleMenuClick = (e) => {
if (e.key === '3') {
this.setState({ visible: false });
}
},
handleVisibleChange(flag) {
}
handleVisibleChange = (flag) => {
this.setState({ visible: flag });
},
}
render() {
const menu = (
<Menu onClick={this.handleMenuClick}>
@@ -48,8 +46,8 @@ const OverlayVisible = React.createClass({
</a>
</Dropdown>
);
},
});
}
}
ReactDOM.render(<OverlayVisible />, mountNode);
````

View File

@@ -58,13 +58,20 @@
color: @text-color;
white-space: nowrap;
cursor: pointer;
transition: background 0.3s ease;
transition: all .3s;
> a {
color: @text-color;
display: block;
padding: 7px 16px;
margin: -7px -16px;
transition: all .3s;
}
&-selected,
&-selected > a {
color: @primary-color;
background-color: @primary-1;
}
&:hover {
@@ -83,15 +90,18 @@
}
}
&:first-child {
&:first-child,
&:first-child > a {
border-radius: @border-radius-base @border-radius-base 0 0;
}
&:last-child {
&:last-child,
&:last-child > a {
border-radius: 0 0 @border-radius-base @border-radius-base;
}
&:only-child {
&:only-child,
&:only-child > a {
border-radius: @border-radius-base;
}
@@ -182,3 +192,31 @@
.iconfont-size-under-12px(10px);
}
}
// https://github.com/ant-design/ant-design/issues/4903
.@{dropdown-prefix-cls}-menu-dark {
&,
.@{dropdown-prefix-cls}-menu {
background: @menu-dark-bg;
}
.@{dropdown-prefix-cls}-menu-item,
.@{dropdown-prefix-cls}-menu-submenu-title,
.@{dropdown-prefix-cls}-menu-item > a {
color: @text-color-secondary-dark;
&:after {
color: @text-color-secondary-dark;
}
&:hover {
color: #fff;
background: transparent;
}
}
.@{dropdown-prefix-cls}-menu-item-selected {
&,
&:hover,
> a {
background: @primary-color;
color: #fff;
}
}
}

View File

@@ -19,7 +19,7 @@ export interface FormItemProps {
labelCol?: FormItemLabelColOption;
wrapperCol?: FormItemLabelColOption;
help?: React.ReactNode;
extra?: string;
extra?: React.ReactNode;
validateStatus?: 'success' | 'warning' | 'error' | 'validating';
hasFeedback?: boolean;
className?: string;
@@ -213,27 +213,30 @@ export default class FormItem extends React.Component<FormItemProps, any> {
}
renderLabel() {
const props = this.props;
const { label, labelCol, prefixCls, colon, id } = this.props;
const context = this.context;
const labelCol = props.labelCol;
const required = this.isRequired();
const className = classNames({
[`${props.prefixCls}-item-required`]: required,
[`${prefixCls}-item-required`]: required,
});
let label = props.label;
let labelChildren = label;
// Keep label is original where there should have no colon
const haveColon = props.colon && !context.vertical;
const haveColon = colon && !context.vertical;
// Remove duplicated user input colon
if (haveColon && typeof label === 'string' && (label as string).trim() !== '') {
label = (props.label as string).replace(/[|:]\s*$/, '');
labelChildren = (label as string).replace(/[|:]\s*$/, '');
}
return props.label ? (
<Col {...labelCol} key="label" className={`${props.prefixCls}-item-label`}>
<label htmlFor={props.id || this.getId()} className={className}>
{label}
return label ? (
<Col {...labelCol} key="label" className={`${prefixCls}-item-label`}>
<label
htmlFor={id || this.getId()}
className={className}
title={typeof label === 'string' ? label : ''}
>
{labelChildren}
</label>
</Col>
) : null;

View File

@@ -14,7 +14,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label">
<label
class=""
for="field-0">
for="field-0"
title="Field 0">
Field 0
</label>
</div>
@@ -42,7 +43,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label">
<label
class=""
for="field-1">
for="field-1"
title="Field 1">
Field 1
</label>
</div>
@@ -70,7 +72,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label">
<label
class=""
for="field-2">
for="field-2"
title="Field 2">
Field 2
</label>
</div>
@@ -98,7 +101,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label">
<label
class=""
for="field-3">
for="field-3"
title="Field 3">
Field 3
</label>
</div>
@@ -126,7 +130,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label">
<label
class=""
for="field-4">
for="field-4"
title="Field 4">
Field 4
</label>
</div>
@@ -154,7 +159,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label">
<label
class=""
for="field-5">
for="field-5"
title="Field 5">
Field 5
</label>
</div>
@@ -219,7 +225,8 @@ exports[`test renders ./components/form/demo/coordinated.md correctly 1`] = `
class="ant-col-4 ant-form-item-label">
<label
class="ant-form-item-required"
for="note">
for="note"
title="Note">
Note
</label>
</div>
@@ -242,7 +249,8 @@ exports[`test renders ./components/form/demo/coordinated.md correctly 1`] = `
class="ant-col-4 ant-form-item-label">
<label
class="ant-form-item-required"
for="gender">
for="gender"
title="Gender">
Gender
</label>
</div>
@@ -308,7 +316,8 @@ exports[`test renders ./components/form/demo/customized-form-controls.md correct
class="ant-form-item-label">
<label
class=""
for="price">
for="price"
title="Price">
Price
</label>
</div>
@@ -436,7 +445,8 @@ exports[`test renders ./components/form/demo/global-state.md correctly 1`] = `
class="ant-form-item-label">
<label
class="ant-form-item-required"
for="username">
for="username"
title="Username">
Username
</label>
</div>
@@ -544,7 +554,8 @@ exports[`test renders ./components/form/demo/layout.md correctly 1`] = `
<div
class="ant-col-4 ant-form-item-label">
<label
class="">
class=""
title="Form Layout">
Form Layout
</label>
</div>
@@ -606,7 +617,8 @@ exports[`test renders ./components/form/demo/layout.md correctly 1`] = `
<div
class="ant-col-4 ant-form-item-label">
<label
class="">
class=""
title="Field A">
Field A
</label>
</div>
@@ -626,7 +638,8 @@ exports[`test renders ./components/form/demo/layout.md correctly 1`] = `
<div
class="ant-col-4 ant-form-item-label">
<label
class="">
class=""
title="Field B">
Field B
</label>
</div>
@@ -763,7 +776,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="email">
for="email"
title="E-mail">
E-mail
</label>
</div>
@@ -786,7 +800,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="password">
for="password"
title="Password">
Password
</label>
</div>
@@ -809,7 +824,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="confirm">
for="confirm"
title="Confirm Password">
Confirm Password
</label>
</div>
@@ -832,7 +848,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="nickname">
for="nickname"
title="">
<span>
Nickname 
<i
@@ -859,7 +876,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="residence">
for="residence"
title="Habitual Residence">
Habitual Residence
</label>
</div>
@@ -896,7 +914,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="phone">
for="phone"
title="Phone Number">
Phone Number
</label>
</div>
@@ -952,7 +971,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="captcha">
for="captcha"
title="Captcha">
Captcha
</label>
</div>
@@ -1047,7 +1067,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label">
<label
class="ant-form-item-required"
for="date-picker">
for="date-picker"
title="DatePicker">
DatePicker
</label>
</div>
@@ -1076,7 +1097,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label">
<label
class="ant-form-item-required"
for="date-time-picker">
for="date-time-picker"
title="DatePicker[showTime]">
DatePicker[showTime]
</label>
</div>
@@ -1086,7 +1108,7 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-form-item-control ">
<span
class="ant-calendar-picker"
style="min-width:154px;">
style="width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input ant-input-lg"
@@ -1106,7 +1128,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label">
<label
class="ant-form-item-required"
for="month-picker">
for="month-picker"
title="MonthPicker">
MonthPicker
</label>
</div>
@@ -1135,7 +1158,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label">
<label
class="ant-form-item-required"
for="range-picker">
for="range-picker"
title="RangePicker">
RangePicker
</label>
</div>
@@ -1174,7 +1198,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label">
<label
class="ant-form-item-required"
for="range-time-picker">
for="range-time-picker"
title="RangePicker[showTime]">
RangePicker[showTime]
</label>
</div>
@@ -1214,7 +1239,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label">
<label
class="ant-form-item-required"
for="time-picker">
for="time-picker"
title="TimePicker">
TimePicker
</label>
</div>
@@ -1263,7 +1289,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
<div
class="ant-col-6 ant-form-item-label">
<label
class="">
class=""
title="Nation">
Nation
</label>
</div>
@@ -1284,7 +1311,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="select">
for="select"
title="Select">
Select
</label>
</div>
@@ -1328,7 +1356,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class="ant-form-item-required"
for="select-multiple">
for="select-multiple"
title="Select[multiple]">
Select[multiple]
</label>
</div>
@@ -1378,7 +1407,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class=""
for="input-number">
for="input-number"
title="InputNumber">
InputNumber
</label>
</div>
@@ -1428,7 +1458,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class=""
for="switch">
for="switch"
title="Switch">
Switch
</label>
</div>
@@ -1453,7 +1484,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class=""
for="slider">
for="slider"
title="Slider">
Slider
</label>
</div>
@@ -1535,7 +1567,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class=""
for="radio-group">
for="radio-group"
title="Radio.Group">
Radio.Group
</label>
</div>
@@ -1597,7 +1630,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class=""
for="radio-button">
for="radio-button"
title="Radio.Button">
Radio.Button
</label>
</div>
@@ -1659,7 +1693,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label">
<label
class=""
for="upload">
for="upload"
title="Upload">
Upload
</label>
</div>
@@ -1709,7 +1744,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="Fail">
Fail
</label>
</div>
@@ -1734,7 +1770,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="Warning">
Warning
</label>
</div>
@@ -1755,7 +1792,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="Validating">
Validating
</label>
</div>
@@ -1780,7 +1818,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="Success">
Success
</label>
</div>
@@ -1801,7 +1840,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="Warning">
Warning
</label>
</div>
@@ -1822,7 +1862,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="Fail">
Fail
</label>
</div>
@@ -1847,7 +1888,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div
class="ant-col-5 ant-form-item-label">
<label
class="">
class=""
title="inline">
inline
</label>
</div>
@@ -1930,7 +1972,8 @@ exports[`test renders ./components/form/demo/without-form-create.md correctly 1`
<div
class="ant-col-7 ant-form-item-label">
<label
class="">
class=""
title="Prime between 8 & 12">
Prime between 8 & 12
</label>
</div>

View File

@@ -18,21 +18,21 @@ import { Form, Select, Input, Button } from 'antd';
const FormItem = Form.Item;
const Option = Select.Option;
const App = Form.create()(React.createClass({
handleSubmit(e) {
class App extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
},
handleSelectChange(value) {
}
handleSelectChange = (value) => {
console.log(value);
this.props.form.setFieldsValue({
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
});
},
}
render() {
const { getFieldDecorator } = this.props.form;
return (
@@ -70,8 +70,10 @@ const App = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<App />, mountNode);
const WrappedApp = Form.create()(App);
ReactDOM.render(<WrappedApp />, mountNode);
````

View File

@@ -23,22 +23,24 @@ import { Form, Input, Select, Button } from 'antd';
const FormItem = Form.Item;
const Option = Select.Option;
const PriceInput = React.createClass({
getInitialState() {
class PriceInput extends React.Component {
constructor(props) {
super(props);
const value = this.props.value || {};
return {
this.state = {
number: value.number || 0,
currency: value.currency || 'rmb',
};
},
}
componentWillReceiveProps(nextProps) {
// Should be a controlled component.
if ('value' in nextProps) {
const value = nextProps.value;
this.setState(value);
}
},
handleNumberChange(e) {
}
handleNumberChange = (e) => {
const number = parseInt(e.target.value || 0, 10);
if (isNaN(number)) {
return;
@@ -47,20 +49,20 @@ const PriceInput = React.createClass({
this.setState({ number });
}
this.triggerChange({ number });
},
handleCurrencyChange(currency) {
}
handleCurrencyChange = (currency) => {
if (!('value' in this.props)) {
this.setState({ currency });
}
this.triggerChange({ currency });
},
triggerChange(changedValue) {
}
triggerChange = (changedValue) => {
// Should provide an event to pass value to Form.
const onChange = this.props.onChange;
if (onChange) {
onChange(Object.assign({}, this.state, changedValue));
}
},
}
render() {
const { size } = this.props;
const state = this.state;
@@ -84,25 +86,25 @@ const PriceInput = React.createClass({
</Select>
</span>
);
},
});
}
}
const Demo = Form.create()(React.createClass({
handleSubmit(e) {
class Demo extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
},
checkPrice(rule, value, callback) {
}
checkPrice = (rule, value, callback) => {
if (value.number > 0) {
callback();
return;
}
callback('Price must greater than zero!');
},
}
render() {
const { getFieldDecorator } = this.props.form;
return (
@@ -118,8 +120,10 @@ const Demo = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<Demo />, mountNode);
const WrappedDemo = Form.create()(Demo);
ReactDOM.render(<WrappedDemo />, mountNode);
````

View File

@@ -56,17 +56,17 @@ const CollectionCreateForm = Form.create()(
}
);
const CollectionsPage = React.createClass({
getInitialState() {
return { visible: false };
},
showModal() {
class CollectionsPage extends React.Component {
state = {
visible: false,
};
showModal = () => {
this.setState({ visible: true });
},
handleCancel() {
}
handleCancel = () => {
this.setState({ visible: false });
},
handleCreate() {
}
handleCreate = () => {
const form = this.form;
form.validateFields((err, values) => {
if (err) {
@@ -77,10 +77,10 @@ const CollectionsPage = React.createClass({
form.resetFields();
this.setState({ visible: false });
});
},
saveFormRef(form) {
}
saveFormRef = (form) => {
this.form = form;
},
}
render() {
return (
<div>
@@ -93,8 +93,8 @@ const CollectionsPage = React.createClass({
/>
</div>
);
},
});
}
}
ReactDOM.render(<CollectionsPage />, mountNode);
````

View File

@@ -45,21 +45,19 @@ const CustomizedForm = Form.create({
);
});
const Demo = React.createClass({
getInitialState() {
return {
fields: {
username: {
value: 'benjycui',
},
class Demo extends React.Component {
state = {
fields: {
username: {
value: 'benjycui',
},
};
},
handleFormChange(changedFields) {
},
};
handleFormChange = (changedFields) => {
this.setState({
fields: { ...this.state.fields, ...changedFields },
});
},
}
render() {
const fields = this.state.fields;
return (
@@ -70,8 +68,8 @@ const Demo = React.createClass({
</pre>
</div>
);
},
});
}
}
ReactDOM.render(<Demo />, mountNode);
````

View File

@@ -21,19 +21,19 @@ function hasErrors(fieldsError) {
return Object.keys(fieldsError).some(field => fieldsError[field]);
}
const HorizontalLoginForm = Form.create()(React.createClass({
class HorizontalLoginForm extends React.Component {
componentDidMount() {
// To disabled submit button at the beginning.
this.props.form.validateFields();
},
handleSubmit(e) {
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
},
}
render() {
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
@@ -73,8 +73,10 @@ const HorizontalLoginForm = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<HorizontalLoginForm />, mountNode);
const WrappedHorizontalLoginForm = Form.create()(HorizontalLoginForm);
ReactDOM.render(<WrappedHorizontalLoginForm />, mountNode);
````

View File

@@ -17,15 +17,15 @@ Normal login form which can contain more elements.
import { Form, Icon, Input, Button, Checkbox } from 'antd';
const FormItem = Form.Item;
const NormalLoginForm = Form.create()(React.createClass({
handleSubmit(e) {
class NormalLoginForm extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
},
}
render() {
const { getFieldDecorator } = this.props.form;
return (
@@ -59,10 +59,12 @@ const NormalLoginForm = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<NormalLoginForm />, mountNode);
const WrappedNormalLoginForm = Form.create()(NormalLoginForm);
ReactDOM.render(<WrappedNormalLoginForm />, mountNode);
````
```css

View File

@@ -42,39 +42,37 @@ const residences = [{
}],
}];
const RegistrationForm = Form.create()(React.createClass({
getInitialState() {
return {
passwordDirty: false,
};
},
handleSubmit(e) {
class RegistrationForm extends React.Component {
state = {
passwordDirty: false,
};
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
},
handlePasswordBlur(e) {
}
handlePasswordBlur = (e) => {
const value = e.target.value;
this.setState({ passwordDirty: this.state.passwordDirty || !!value });
},
checkPassword(rule, value, callback) {
}
checkPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!');
} else {
callback();
}
},
checkConfirm(rule, value, callback) {
}
checkConfirm = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.passwordDirty) {
form.validateFields(['confirm'], { force: true });
}
callback();
},
}
render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
@@ -210,10 +208,12 @@ const RegistrationForm = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<RegistrationForm />, mountNode);
const WrappedRegistrationForm = Form.create()(RegistrationForm);
ReactDOM.render(<WrappedRegistrationForm />, mountNode);
````
````css

View File

@@ -19,8 +19,8 @@ const FormItem = Form.Item;
const MonthPicker = DatePicker.MonthPicker;
const RangePicker = DatePicker.RangePicker;
const TimeRelatedForm = Form.create()(React.createClass({
handleSubmit(e) {
class TimeRelatedForm extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, fieldsValue) => {
@@ -45,7 +45,7 @@ const TimeRelatedForm = Form.create()(React.createClass({
};
console.log('Received values of form: ', values);
});
},
}
render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
@@ -72,7 +72,7 @@ const TimeRelatedForm = Form.create()(React.createClass({
{...formItemLayout}
label="DatePicker[showTime]"
>
{getFieldDecorator('date-time-picker', config)(
{getFieldDecorator('date-time-picker', config)(
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" />
)}
</FormItem>
@@ -80,7 +80,7 @@ const TimeRelatedForm = Form.create()(React.createClass({
{...formItemLayout}
label="MonthPicker"
>
{getFieldDecorator('month-picker', config)(
{getFieldDecorator('month-picker', config)(
<MonthPicker />
)}
</FormItem>
@@ -88,7 +88,7 @@ const TimeRelatedForm = Form.create()(React.createClass({
{...formItemLayout}
label="RangePicker"
>
{getFieldDecorator('range-picker', rangeConfig)(
{getFieldDecorator('range-picker', rangeConfig)(
<RangePicker />
)}
</FormItem>
@@ -96,7 +96,7 @@ const TimeRelatedForm = Form.create()(React.createClass({
{...formItemLayout}
label="RangePicker[showTime]"
>
{getFieldDecorator('range-time-picker', rangeConfig)(
{getFieldDecorator('range-time-picker', rangeConfig)(
<RangePicker showTime format="YYYY-MM-DD HH:mm:ss" />
)}
</FormItem>
@@ -104,7 +104,7 @@ const TimeRelatedForm = Form.create()(React.createClass({
{...formItemLayout}
label="TimePicker"
>
{getFieldDecorator('time-picker', config)(
{getFieldDecorator('time-picker', config)(
<TimePicker />
)}
</FormItem>
@@ -113,8 +113,10 @@ const TimeRelatedForm = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<TimeRelatedForm />, mountNode);
const WrappedTimeRelatedForm = Form.create()(TimeRelatedForm);
ReactDOM.render(<WrappedTimeRelatedForm />, mountNode);
````

View File

@@ -23,23 +23,21 @@ const Option = Select.Option;
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;
const Demo = Form.create()(React.createClass({
handleSubmit(e) {
class Demo extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
},
normFile(e) {
}
normFile = (e) => {
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
},
}
render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
@@ -164,8 +162,10 @@ const Demo = Form.create()(React.createClass({
</FormItem>
</Form>
);
},
}));
}
}
ReactDOM.render(<Demo />, mountNode);
const WrappedDemo = Form.create()(Demo);
ReactDOM.render(<WrappedDemo />, mountNode);
````

View File

@@ -36,7 +36,6 @@ class RawForm extends React.Component {
value: 11,
},
};
handleNumberChange = (value) => {
this.setState({
number: {
@@ -45,7 +44,6 @@ class RawForm extends React.Component {
},
});
}
render() {
const formItemLayout = {
labelCol: { span: 7 },

View File

@@ -249,15 +249,14 @@ form {
// Form layout
//== Vertical Form
.@{form-prefix-cls}-vertical {
.@{form-prefix-cls}-item-label {
padding: 0 0 8px;
display: block;
text-align: left;
.@{form-prefix-cls}-vertical .@{form-prefix-cls}-item-label,
.@{ant-prefix}-col-24.@{form-prefix-cls}-item-label { // when labelCol is 24, it is a vertical form
padding: 0 0 8px;
display: block;
text-align: left;
label:after {
content: '';
}
label:after {
content: '';
}
}

View File

@@ -104,7 +104,9 @@ Ant Design layout component if it can not meet your needs, you can use the excel
| offset | the number of cells to the left of the grid spacing, no cell in grid spacing | number | 0 |
| push | the number of cells that raster move to the right | number | 0 |
| pull | the number of cells that raster move to the left | number | 0 |
| xs | `<768px`, could be a `span` value or a object contain above props | number\|object | - |
| xs | `<768px` and also default setting, could be a `span` value or a object contain above props | number\|object | - |
| sm | `≥768px`, could be a `span` value or a object contain above props | number\|object | - |
| md | `≥992px`, could be a `span` value or a object contain above props | number\|object | - |
| lg | `≥1200px`, could be a `span` value or a object contain above props | number\|object | - |
The breakpoints of responsive grid follow [BootStrap 3 media queries rules](http://getbootstrap.com/css/#grid-media-queries)(not contain `occasionally part`).

View File

@@ -107,3 +107,5 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用
| sm | `≥768px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - |
| md | `≥992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - |
| lg | `≥1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - |
响应式栅格的断点遵循了 [BootStrap 3 的规则](http://getbootstrap.com/css/#grid-media-queries)(不包含链接里 `occasionally` 的部分)。

View File

@@ -16,17 +16,15 @@ Click the button to toggle between available and disabled states.
````jsx
import { InputNumber, Button } from 'antd';
const Test = React.createClass({
getInitialState() {
return {
disabled: true,
};
},
toggle() {
class App extends React.Component {
state = {
disabled: true,
};
toggle = () => {
this.setState({
disabled: !this.state.disabled,
});
},
}
render() {
return (
<div>
@@ -36,8 +34,8 @@ const Test = React.createClass({
</div>
</div>
);
},
});
}
}
ReactDOM.render(<Test />, mountNode);
ReactDOM.render(<App />, mountNode);
````

View File

@@ -19,6 +19,6 @@ When a numeric value needs to be provided.
| value | current value | number | |
| step | The number to which the current value is increased or decreased. It can be an integer or decimal. | number\|string | 1 |
| defaultValue | initial value | number | |
| onChange | The callback triggered when the value is changed. | Function(value) | |
| onChange | The callback triggered when the value is changed. | Function(value: number | string) | |
| disabled | disable the input | boolean | false |
| size | width of input box | string | none |

View File

@@ -22,6 +22,6 @@ title: InputNumber
| value | 当前值 | number | |
| step | 每次改变步数,可以为小数 | number\|string | 1 |
| defaultValue | 初始值 | number | |
| onChange | 变化回调 | Function(value) | |
| onChange | 变化回调 | Function(value: number | string) | |
| disabled | 禁用 | boolean | false |
| size | 输入框大小 | string | 无 |

View File

@@ -405,15 +405,11 @@ exports[`test renders ./components/input/demo/textarea.md correctly 1`] = `
`;
exports[`test renders ./components/input/demo/tooltip.md correctly 1`] = `
<div
class="numeric-input-demo">
<div>
<input
class="ant-input"
maxlength="25"
placeholder="input a number"
type="text"
value="" />
</div>
</div>
<input
class="ant-input"
maxlength="25"
placeholder="Input a number"
style="width:120px;"
type="text"
value="" />
`;

View File

@@ -11,7 +11,7 @@ title:
## en-US
Basic usage example
Basic usage example.
````jsx
import { Input } from 'antd';

View File

@@ -40,41 +40,38 @@ class NumericInput extends React.Component {
this.props.onChange(value);
}
}
// '.' at the end or only '-' in the input box.
onBlur = () => {
const { value } = this.props;
const { value, onBlur, onChange } = this.props;
if (value.charAt(value.length - 1) === '.' || value === '-') {
this.props.onChange({ value: value.slice(0, -1) });
onChange({ value: value.slice(0, -1) });
}
if (this.props.onBlur) {
this.props.onBlur();
if (onBlur) {
onBlur();
}
}
render() {
const { value } = this.props;
const title = (value ?
(<span className="numeric-input-title">
const title = value ? (
<span className="numeric-input-title">
{value !== '-' ? formatNumber(value) : '-'}
</span>) : '');
</span>
) : 'Input a number';
return (
<div>
<Tooltip
trigger={['focus']}
title={title}
placement="topLeft"
overlayClassName="numeric-input"
>
<Input
{...this.props}
onChange={this.onChange}
onBlur={this.onBlur}
placeholder="input a number"
maxLength="25"
/>
</Tooltip>
</div>
<Tooltip
trigger={['focus']}
title={title}
placement="topLeft"
overlayClassName="numeric-input"
>
<Input
{...this.props}
onChange={this.onChange}
onBlur={this.onBlur}
placeholder="Input a number"
maxLength="25"
/>
</Tooltip>
);
}
}
@@ -88,12 +85,7 @@ class NumericInputDemo extends React.Component {
this.setState({ value });
}
render() {
const { value } = this.state;
return (
<div className="numeric-input-demo">
<NumericInput value={value} onChange={this.onChange} />
</div>
);
return <NumericInput style={{ width: 120 }} value={this.state.value} onChange={this.onChange} />;
}
}
@@ -111,8 +103,4 @@ or the height is not enough when content is empty */
.numeric-input .numeric-input-title {
font-size: 14px;
}
.numeric-input-demo {
width: 120px;
}
````

View File

@@ -17,3 +17,10 @@
.@{ant-prefix}-input-preSuffix-wrapper {
.input-preSuffix-wrapper(~"@{ant-prefix}-input");
}
// chrome only hack, fix https://github.com/ant-design/ant-design/issues/4987
@media all and (-webkit-min-device-pixel-ratio: 0) and (min-resolution: .001dpcm) {
input.@{ant-prefix}-input {
line-height: inherit;
}
}

View File

@@ -69,7 +69,7 @@ exports[`test renders ./components/layout/demo/basic.md correctly 1`] = `
Sider
</div>
<div
class="ant-layout-content">
class="ant-layout">
<div
class="ant-layout-header">
Header

View File

@@ -18,40 +18,40 @@ import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
ReactDOM.render(
<div>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<div>
<Layout>
<Sider>Sider</Sider>
<Content>Content</Content>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Content>Content</Content>
<Sider>Sider</Sider>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Sider>Sider</Sider>
<Content>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Content>
</Layout>
</div>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Sider>Sider</Sider>
<Content>Content</Content>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Content>Content</Content>
<Sider>Sider</Sider>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Sider>Sider</Sider>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
</Layout>
</div>
, mountNode);
````

View File

@@ -96,6 +96,7 @@ ReactDOM.render(<SiderDemo />, mountNode);
#components-layout-demo-side .ant-layout-sider-collapsed .anticon {
font-size: 16px;
margin-left: 8px;
}
#components-layout-demo-side .ant-layout-sider-collapsed .nav-text {
@@ -104,5 +105,5 @@ ReactDOM.render(<SiderDemo />, mountNode);
#components-layout-demo-side .ant-layout-sider-collapsed .ant-menu-submenu-vertical > .ant-menu-submenu-title:after {
display: none;
}
}
````

View File

@@ -9,11 +9,11 @@ When you are handling the overall layout of a page, this component might be help
## Overview
- `Layout`: The layout wrapper, in which `Header` `Sider` `Content` `Footer` or `Layout` itself can be nested.
- `Header`: The top layout with default style.
- `Sider`: The sidebar with default style and basic functions.
- `Content`: The content layout with default style.
- `Footer`: The bottom layout with default style.
- `Layout`: The layout wrapper, in which `Header` `Sider` `Content` `Footer` or `Layout` itself can be nested, and can be placed in any parent container.
- `Header`: The top layout with default style, in which any element can be nested, and must be placed in `Layout`.
- `Sider`: The sidebar with default style and basic functions, in which any element can be nested, and must be placed in `Layout`.
- `Content`: The content layout with default style, in which any element can be nested, and must be placed in `Layout`.
- `Footer`: The bottom layout with default style, in which any element can be nested, and must be placed in `Layout`.
> Base on `flex layout`, please pay attention to the [compatibility](http://caniuse.com/#search=flex).

View File

@@ -10,11 +10,11 @@ title: Layout
## 概述
- `Layout`:布局容器,其下可嵌套 `Header` `Sider` `Content` `Footer``Layout` 本身。
- `Header`:顶部布局,自带默认样式。
- `Sider`:侧边栏,自带默认样式及基本功能。
- `Content`:内容部分,自带默认样式。
- `Footer`:底部布局,自带默认样式。
- `Layout`:布局容器,其下可嵌套 `Header` `Sider` `Content` `Footer``Layout` 本身,可以放在任何父容器中
- `Header`:顶部布局,自带默认样式,其下可嵌套任何元素,只能放在 `Layout`
- `Sider`:侧边栏,自带默认样式及基本功能,其下可嵌套任何元素,只能放在 `Layout`
- `Content`:内容部分,自带默认样式,其下可嵌套任何元素,只能放在 `Layout`
- `Footer`:底部布局,自带默认样式,其下可嵌套任何元素,只能放在 `Layout`
> 注意:采用 flex 布局实现,请注意[浏览器兼容性](http://caniuse.com/#search=flex)问题。

View File

@@ -1146,14 +1146,15 @@ exports[`test renders ./components/locale-provider/demo/all.md correctly 1`] = `
<div
class="example">
<div
class="">
class="ant-table-wrapper">
<div
class="ant-table ant-table-large ant-table-empty ant-table-scroll-position-left">
class="ant-spin-nested-loading">
<div
class="ant-table-content">
class="ant-spin-container">
<div
class="">
<span>
class="ant-table ant-table-large ant-table-empty ant-table-scroll-position-left">
<div
class="ant-table-content">
<div
class="ant-table-body">
<table
@@ -1186,10 +1187,10 @@ exports[`test renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-table-tbody" />
</table>
</div>
</span>
<div
class="ant-table-placeholder">
No Data
<div
class="ant-table-placeholder">
No Data
</div>
</div>
</div>
</div>

View File

@@ -36,18 +36,16 @@ const columns = [{
dataIndex: 'age',
}];
const Page = React.createClass({
getInitialState() {
return {
visible: false,
};
},
showModal() {
class Page extends React.Component {
state = {
visible: false,
}
showModal = () => {
this.setState({ visible: true });
},
hideModal() {
}
hideModal = () => {
this.setState({ visible: false });
},
}
render() {
const info = () => {
Modal.info({
@@ -102,16 +100,17 @@ const Page = React.createClass({
</Modal>
</div>
);
},
});
}
}
const App = React.createClass({
getInitialState() {
return {
class App extends React.Component {
constructor() {
super();
this.state = {
locale: enUS,
};
},
changeLocale(e) {
}
changeLocale = (e) => {
const localeValue = e.target.value;
this.setState({ locale: localeValue });
if (!localeValue) {
@@ -119,7 +118,7 @@ const App = React.createClass({
} else {
moment.locale('en');
}
},
}
render() {
return (
<div>
@@ -133,8 +132,8 @@ const App = React.createClass({
<LocaleProvider locale={this.state.locale}><Page /></LocaleProvider>
</div>
);
},
});
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -17,13 +17,11 @@ Wrap your app with `LocaleProvider`, and apply the corresponding language packag
import { Pagination, LocaleProvider } from 'antd';
import enUS from 'antd/lib/locale-provider/en_US';
function App() {
return (
<div>
<Pagination defaultCurrent={1} total={50} showSizeChanger />
</div>
);
}
const App = () => (
<div>
<Pagination defaultCurrent={1} total={50} showSizeChanger />
</div>
);
ReactDOM.render(
<LocaleProvider locale={enUS}>

View File

@@ -1,6 +1,6 @@
---
order: 1
title:
title:
zh-CN: 异步加载
en-US: Asynchronous loading
---
@@ -17,19 +17,18 @@ async
import { Mention } from 'antd';
const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
const AsyncMention = React.createClass({
getInitialState() {
return {
suggestions: [],
loading: false,
};
},
fetchSuggestions(value, callback) {
class AsyncMention extends React.Component {
state = {
suggestions: [],
loading: false,
}
fetchSuggestions = (value, callback) => {
setTimeout(() => {
callback(users.filter(item => item.indexOf(value) !== -1));
}, 500);
},
onSearchChange(value) {
}
onSearchChange = (value) => {
this.fetchSuggestions(value, (suggestions) => {
this.setState({
suggestions,
@@ -39,7 +38,7 @@ const AsyncMention = React.createClass({
this.setState({
loading: true,
});
},
}
render() {
const { suggestions, loading } = this.state;
return (
@@ -50,11 +49,8 @@ const AsyncMention = React.createClass({
onSearchChange={this.onSearchChange}
/>
);
},
});
}
}
ReactDOM.render(
<AsyncMention />,
mountNode
);
ReactDOM.render(<AsyncMention />, mountNode);
````

View File

@@ -1,6 +1,6 @@
---
order: 3
title:
title:
zh-CN: 头像
en-US: Icon Image
---
@@ -26,18 +26,15 @@ const webFrameworks = [
{ name: 'Flask', type: 'Python', icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png' },
];
const CustomNavMention = React.createClass({
getInitialState() {
return {
suggestions: [],
};
},
onSearchChange(value) {
class CustomNavMention extends React.Component {
state = {
suggestions: [],
}
onSearchChange = (value) => {
const searchValue = value.toLowerCase();
const filtered = webFrameworks.filter(item =>
item.name.toLowerCase().indexOf(searchValue) !== -1
);
const suggestions = filtered.map(suggestion =>
<Nav value={suggestion.name} data={suggestion} disabled={suggestion.disabled}>
<span>
@@ -45,10 +42,8 @@ const CustomNavMention = React.createClass({
{suggestion.name} - {suggestion.type}
</span>
</Nav>);
this.setState({
suggestions,
});
},
this.setState({ suggestions });
}
render() {
const { suggestions } = this.state;
return (
@@ -58,11 +53,8 @@ const CustomNavMention = React.createClass({
onSearchChange={this.onSearchChange}
/>
);
},
});
}
}
ReactDOM.render(
<CustomNavMention />,
mountNode
);
ReactDOM.render(<CustomNavMention />, mountNode);
````

View File

@@ -17,25 +17,25 @@ Controlled mode.
import { Mention } from 'antd';
const { toEditorState } = Mention;
const App = React.createClass({
getInitialState() {
return {
value: toEditorState('@afc163'),
};
},
handleChange(editorState) {
class App extends React.Component {
state = {
value: toEditorState('@afc163'),
}
handleChange = (editorState) => {
this.setState({
value: editorState,
});
},
}
render() {
return (<Mention
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
value={this.state.value}
onChange={this.handleChange}
/>);
},
});
return (
<Mention
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
value={this.state.value}
onChange={this.handleChange}
/>
);
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -7,28 +7,26 @@ title:
## zh-CN
受控模式,例如配合 Form 使用
受控模式,例如配合 Form 使用
## en-US
Controlled mode, for example, to work with `Form` .
Controlled mode, for example, to work with `Form`.
````jsx
import { Mention, Form, Button } from 'antd';
const { toEditorState, getMentions } = Mention;
const FormItem = Form.Item;
let App = React.createClass({
getInitialState() {
return {
initValue: toEditorState('@afc163'),
};
},
handleReset(e) {
class App extends React.Component {
state = {
initValue: toEditorState('@afc163'),
}
handleReset = (e) => {
e.preventDefault();
this.props.form.resetFields();
},
handleSubmit(e) {
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((errors, values) => {
if (errors) {
@@ -38,8 +36,8 @@ let App = React.createClass({
console.log('Submit!!!');
console.log(values);
});
},
checkMention(rule, value, callback) {
}
checkMention = (rule, value, callback) => {
const { getFieldValue } = this.props.form;
const mentions = getMentions(getFieldValue('mention'));
if (mentions.length < 2) {
@@ -47,7 +45,7 @@ let App = React.createClass({
} else {
callback();
}
},
}
render() {
const { getFieldDecorator, getFieldValue } = this.props.form;
console.log('>> render', getFieldValue('mention') === this.state.initValue);
@@ -77,10 +75,10 @@ let App = React.createClass({
</FormItem>
</Form>
);
},
});
}
}
App = Form.create()(App);
const FormDemo = Form.create()(App);
ReactDOM.render(<App />, mountNode);
ReactDOM.render(<FormDemo />, mountNode);
````

View File

@@ -1,6 +1,6 @@
---
order: 2
title:
title:
zh-CN: 自定义建议
en-US: Customize Suggestion
---
@@ -30,23 +30,22 @@ const webFrameworks = [
function onSelect(suggestion, data) {
console.log('onSelect', suggestion, data);
}
const CustomNavMention = React.createClass({
getInitialState() {
return {
suggestions: [],
};
},
onSearchChange(value) {
class CustomNavMention extends React.Component {
state = {
suggestions: [],
}
onSearchChange = (value) => {
const searchValue = value.toLowerCase();
const filtered = webFrameworks.filter(item =>
item.name.toLowerCase().indexOf(searchValue) !== -1
);
const suggestions = filtered.map(suggestion =>
<Nav value={suggestion.name} data={suggestion}>
<span>{suggestion.name} - {suggestion.type} </span>
<span>{suggestion.name} - {suggestion.type}</span>
</Nav>);
this.setState({ suggestions });
},
}
render() {
const { suggestions } = this.state;
return (
@@ -58,11 +57,8 @@ const CustomNavMention = React.createClass({
onSelect={onSelect}
/>
);
},
});
}
}
ReactDOM.render(
<CustomNavMention />,
mountNode
);
ReactDOM.render(<CustomNavMention />, mountNode);
````

View File

@@ -25,23 +25,28 @@ function onSelect(suggestion) {
console.log('onSelect', suggestion);
}
const PopoverContainer = React.createClass({
getSuggestionContainer() {
class PopoverContainer extends React.Component {
getSuggestionContainer = () => {
return this.popover.getPopupDomNode();
},
}
render() {
const mention = (<Mention
style={{ width: '100%', height: 100 }}
onChange={onChange}
defaultValue={toEditorState('@afc163')}
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
onSelect={onSelect}
getSuggestionContainer={this.getSuggestionContainer}
/>);
return (<Popover trigger="click" content={mention} title="Title" ref={popover => this.popover = popover}>
<Button type="primary">Click Me</Button>
</Popover>);
},
});
const mention = (
<Mention
style={{ width: '100%', height: 100 }}
onChange={onChange}
defaultValue={toEditorState('@afc163')}
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
onSelect={onSelect}
getSuggestionContainer={this.getSuggestionContainer}
/>
);
return (
<Popover trigger="click" content={mention} title="Title" ref={popover => this.popover = popover}>
<Button type="primary">Click Me</Button>
</Popover>
);
}
}
ReactDOM.render(<PopoverContainer />, mountNode);
````

View File

@@ -18,18 +18,16 @@ import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;
const App = React.createClass({
getInitialState() {
return {
current: 'mail',
};
},
handleClick(e) {
class App extends React.Component {
state = {
current: 'mail',
}
handleClick = (e) => {
console.log('click ', e);
this.setState({
current: e.key,
});
},
}
render() {
return (
<Menu
@@ -58,8 +56,8 @@ const App = React.createClass({
</Menu.Item>
</Menu>
);
},
});
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -21,18 +21,16 @@ Click the menu and you will see that all the other menus gets collapsed to keep
import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu;
const Sider = React.createClass({
getInitialState() {
return {
current: '1',
openKeys: [],
};
},
handleClick(e) {
class Sider extends React.Component {
state = {
current: '1',
openKeys: [],
}
handleClick = (e) => {
console.log('Clicked: ', e);
this.setState({ current: e.key });
},
onOpenChange(openKeys) {
}
onOpenChange = (openKeys) => {
const state = this.state;
const latestOpenKey = openKeys.find(key => !(state.openKeys.indexOf(key) > -1));
const latestCloseKey = state.openKeys.find(key => !(openKeys.indexOf(key) > -1));
@@ -45,13 +43,13 @@ const Sider = React.createClass({
nextOpenKeys = this.getAncestorKeys(latestCloseKey);
}
this.setState({ openKeys: nextOpenKeys });
},
getAncestorKeys(key) {
}
getAncestorKeys = (key) => {
const map = {
sub3: ['sub2'],
};
return map[key] || [];
},
}
render() {
return (
<Menu
@@ -84,7 +82,8 @@ const Sider = React.createClass({
</SubMenu>
</Menu>
);
},
});
}
}
ReactDOM.render(<Sider />, mountNode);
````

View File

@@ -18,10 +18,10 @@ import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;
const Sider = React.createClass({
handleClick(e) {
class Sider extends React.Component {
handleClick = (e) => {
console.log('click ', e);
},
}
render() {
return (
<Menu
@@ -57,8 +57,8 @@ const Sider = React.createClass({
</SubMenu>
</Menu>
);
},
});
}
}
ReactDOM.render(<Sider />, mountNode);
````

View File

@@ -18,17 +18,15 @@ import { Menu, Icon, Switch } from 'antd';
const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup;
const Sider = React.createClass({
getInitialState() {
return {
mode: 'inline',
};
},
changeMode(value) {
class Sider extends React.Component {
state = {
mode: 'inline',
}
changeMode = (value) => {
this.setState({
mode: value ? 'vertical' : 'inline',
});
},
}
render() {
return (
<div>
@@ -67,8 +65,8 @@ const Sider = React.createClass({
</Menu>
</div>
);
},
});
}
}
ReactDOM.render(<Sider />, mountNode);
````

View File

@@ -17,24 +17,22 @@ There are two built-in themes: 'light' and 'dark'. The default value is 'light'.
import { Menu, Icon, Switch } from 'antd';
const SubMenu = Menu.SubMenu;
const Sider = React.createClass({
getInitialState() {
return {
theme: 'dark',
current: '1',
};
},
changeTheme(value) {
class Sider extends React.Component {
state = {
theme: 'dark',
current: '1',
}
changeTheme = (value) => {
this.setState({
theme: value ? 'dark' : 'light',
});
},
handleClick(e) {
}
handleClick = (e) => {
console.log('click ', e);
this.setState({
current: e.key,
});
},
}
render() {
return (
<div>
@@ -77,7 +75,8 @@ const Sider = React.createClass({
</Menu>
</div>
);
},
});
}
}
ReactDOM.render(<Sider />, mountNode);
````

View File

@@ -75,12 +75,16 @@
&-item:hover,
&-item-active,
&-submenu-open,
&:not(&-inline) &-submenu-open,
&-submenu-active,
&-submenu-title:hover {
color: @primary-color;
}
&:not(&-inline) &-submenu-open {
z-index: @zindex-dropdown;
}
&-horizontal &-item,
&-horizontal &-submenu {
margin-top: -1px;
@@ -395,7 +399,7 @@
&-dark &-item:hover,
&-dark &-item-active,
&-dark &-submenu-active,
&-dark &-submenu-open,
&-dark:not(&-inline) &-submenu-open,
&-dark &-submenu-selected,
&-dark &-submenu:hover,
&-dark &-submenu-title:hover {

View File

@@ -9,22 +9,23 @@
width: 100%;
top: 16px;
left: 0;
pointer-events: none;
&-notice {
width: auto;
vertical-align: middle;
position: absolute;
left: 50%;
padding: 8px;
text-align: center;
&:first-child {
margin-top: -8px;
}
}
&-notice-content {
position: relative;
right: 50%;
padding: 8px 16px;
border-radius: @border-radius-base;
box-shadow: @shadow-2;
background: @component-background;
display: block;
display: inline-block;
pointer-events: all;
}
&-success .@{iconfont-css-prefix} {
@@ -50,4 +51,23 @@
top: 1px;
position: relative;
}
&-notice.move-up-leave.move-up-leave-active {
animation-name: MessageMoveOut;
overflow: hidden;
animation-duration: .3s;
}
}
@keyframes MessageMoveOut {
0% {
opacity: 1;
max-height: 150px;
padding: 8px;
}
100% {
opacity: 0;
max-height: 0;
padding: 0;
}
}

View File

@@ -17,7 +17,7 @@ export interface ModalProps {
/** 是否显示右上角的关闭按钮*/
closable?: boolean;
/** 点击确定回调*/
onOk?: () => void;
onOk?: (e: React.MouseEvent<any>) => void;
/** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/
onCancel?: (e: React.MouseEvent<any>) => void;
afterClose?: () => void;
@@ -89,10 +89,10 @@ export default class Modal extends React.Component<ModalProps, any> {
}
}
handleOk = () => {
handleOk = (e) => {
const onOk = this.props.onOk;
if (onOk) {
onOk();
onOk(e);
}
}

View File

@@ -1,6 +1,6 @@
---
order: 1
title:
title:
zh-CN: 异步关闭
en-US: Asynchronously close
---
@@ -17,19 +17,17 @@ you can use this pattern when you submit a form.
````jsx
import { Modal, Button } from 'antd';
const Test = React.createClass({
getInitialState() {
return {
ModalText: 'Content of the modal dialog',
visible: false,
};
},
showModal() {
class App extends React.Component {
state = {
ModalText: 'Content of the modal dialog',
visible: false,
}
showModal = () => {
this.setState({
visible: true,
});
},
handleOk() {
}
handleOk = () => {
this.setState({
ModalText: 'The modal dialog will be closed after two seconds',
confirmLoading: true,
@@ -40,13 +38,13 @@ const Test = React.createClass({
confirmLoading: false,
});
}, 2000);
},
handleCancel() {
}
handleCancel = () => {
console.log('Clicked cancel button');
this.setState({
visible: false,
});
},
}
render() {
return (
<div>
@@ -61,8 +59,8 @@ const Test = React.createClass({
</Modal>
</div>
);
},
});
}
}
ReactDOM.render(<Test />, mountNode);
ReactDOM.render(<App />, mountNode);
````

View File

@@ -16,27 +16,25 @@ Basic modal dialog.
````jsx
import { Modal, Button } from 'antd';
const App = React.createClass({
getInitialState() {
return { visible: false };
},
showModal() {
class App extends React.Component {
state = { visible: false }
showModal = () => {
this.setState({
visible: true,
});
},
handleOk() {
console.log('Clicked OK');
this.setState({
visible: false,
});
},
handleCancel(e) {
}
handleOk = (e) => {
console.log(e);
this.setState({
visible: false,
});
},
}
handleCancel = (e) => {
console.log(e);
this.setState({
visible: false,
});
}
render() {
return (
<div>
@@ -50,8 +48,8 @@ const App = React.createClass({
</Modal>
</div>
);
},
});
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@@ -2,43 +2,45 @@
order: 2
title:
zh-CN: 自定义页脚
en-US: Customized footer
en-US: Customized Footer
---
## zh-CN
更复杂的例子,自定义了页脚的按钮,点击提交后进入 loading 状态,完成后关闭。
不需要默认确定取消按钮时,你可以把 `footer` 设为 `null`
## en-US
A more complex example, as illustrated in this example, we define a customized footer button bar,
the dialog will change to loading state after clicking submit button , when the loading is over,
A more complex example which define a customized footer button bar,
the dialog will change to loading state after clicking submit button, when the loading is over,
the modal dialog will be closed.
You could set `footer` to `null` if you don't need default footer buttons.
````jsx
import { Modal, Button } from 'antd';
const Test = React.createClass({
getInitialState() {
return {
loading: false,
visible: false,
};
},
showModal() {
class App extends React.Component {
state = {
loading: false,
visible: false,
}
showModal = () => {
this.setState({
visible: true,
});
},
handleOk() {
}
handleOk = () => {
this.setState({ loading: true });
setTimeout(() => {
this.setState({ loading: false, visible: false });
}, 3000);
},
handleCancel() {
}
handleCancel = () => {
this.setState({ visible: false });
},
}
render() {
return (
<div>
@@ -65,8 +67,8 @@ const Test = React.createClass({
</Modal>
</div>
);
},
});
}
}
ReactDOM.render(<Test />, mountNode);
ReactDOM.render(<App />, mountNode);
````

View File

@@ -1,6 +1,6 @@
---
order: 6
title:
title:
zh-CN: 国际化
en-US: Internationalization
---
@@ -16,25 +16,23 @@ To customize the text of the buttons, you need to set `okText` and `cancelText`
````jsx
import { Modal, Button } from 'antd';
const LocalizedModal = React.createClass({
getInitialState() {
return { visible: false };
},
showModal() {
class LocalizedModal extends React.Component {
state = { visible: false }
showModal = () => {
this.setState({
visible: true,
});
},
handleOk() {
}
handleOk = () => {
this.setState({
visible: false,
});
},
handleCancel() {
}
handleCancel = () => {
this.setState({
visible: false,
});
},
}
render() {
return (
<div>
@@ -49,8 +47,8 @@ const LocalizedModal = React.createClass({
</Modal>
</div>
);
},
});
}
}
function confirm() {
Modal.confirm({
@@ -67,4 +65,3 @@ ReactDOM.render(<div>
<Button onClick={confirm}>confirm</Button>
</div>, mountNode);
````

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