mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 10:59:19 +08:00
Compare commits
166 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4036d3cae | ||
|
|
a60eec0e35 | ||
|
|
1763fa168c | ||
|
|
8b539c4971 | ||
|
|
40b30d8ef9 | ||
|
|
d99778b605 | ||
|
|
00fac07d9e | ||
|
|
a9599b802c | ||
|
|
3818f59a97 | ||
|
|
30f2a1ed94 | ||
|
|
05b20c6a9f | ||
|
|
c31ebaad90 | ||
|
|
0f6d1db614 | ||
|
|
d44a0ece3f | ||
|
|
e8cf22ad0e | ||
|
|
14d380f0f9 | ||
|
|
4650d20abf | ||
|
|
cf4ad5ddb8 | ||
|
|
a5f136f334 | ||
|
|
917ec5606e | ||
|
|
511db23fcd | ||
|
|
68fde63ef7 | ||
|
|
d2e178d215 | ||
|
|
c78d3032f5 | ||
|
|
f6715df3b5 | ||
|
|
6ea75c4d85 | ||
|
|
5076b6045c | ||
|
|
139d95022c | ||
|
|
85ca5ed5ea | ||
|
|
0cbe319839 | ||
|
|
2bf6e22653 | ||
|
|
d0db3ce426 | ||
|
|
4bde2917d2 | ||
|
|
c163232deb | ||
|
|
9c3268dcbc | ||
|
|
55fca5cee4 | ||
|
|
70ec413537 | ||
|
|
edaad09b67 | ||
|
|
3aac9adc40 | ||
|
|
e07cdf5387 | ||
|
|
88100a29a3 | ||
|
|
6df92ce16f | ||
|
|
e72d93edfe | ||
|
|
19c11dd173 | ||
|
|
4e59e9e769 | ||
|
|
7deab1beec | ||
|
|
411f352690 | ||
|
|
f53d0b7646 | ||
|
|
1f844c1048 | ||
|
|
1c837963e2 | ||
|
|
ce0d4c39f2 | ||
|
|
dded4bcde4 | ||
|
|
6fdb39038b | ||
|
|
9d0a06b657 | ||
|
|
9c6a6d6175 | ||
|
|
5068343b0c | ||
|
|
a7c6c027ce | ||
|
|
0f46eed370 | ||
|
|
922a57dfde | ||
|
|
29ebf22529 | ||
|
|
ec9fed3f04 | ||
|
|
52bfb8069a | ||
|
|
5fbc007ff7 | ||
|
|
27717483a7 | ||
|
|
d8fb282088 | ||
|
|
9228e7a01b | ||
|
|
39fd6b6a36 | ||
|
|
ff2d69ad21 | ||
|
|
1c4407b60c | ||
|
|
cdf786676c | ||
|
|
5b20a5fc3e | ||
|
|
7181e3c9e8 | ||
|
|
61a3d66a02 | ||
|
|
e4d9e5af54 | ||
|
|
d9ec4bf732 | ||
|
|
fbeccb7be5 | ||
|
|
c2217f666c | ||
|
|
32150a15a4 | ||
|
|
90699b0c42 | ||
|
|
0caefc8137 | ||
|
|
ef0b7087f6 | ||
|
|
9bb7e3d10c | ||
|
|
f0a4afd388 | ||
|
|
7d982ddfd4 | ||
|
|
79f222b86c | ||
|
|
2fb0fb08d9 | ||
|
|
030127e93c | ||
|
|
9fff177bbc | ||
|
|
54dde4f5bc | ||
|
|
fbb6cb007f | ||
|
|
7f404f1e20 | ||
|
|
68f3641a90 | ||
|
|
760a5ffc90 | ||
|
|
21a0779692 | ||
|
|
205ace69ba | ||
|
|
c3748a60f4 | ||
|
|
921f71a8bc | ||
|
|
c4a67a1bf5 | ||
|
|
b839c624e8 | ||
|
|
d19453c4c3 | ||
|
|
c30878d38f | ||
|
|
580389ac15 | ||
|
|
d576abc7b0 | ||
|
|
6455bdf6e1 | ||
|
|
e68b54f902 | ||
|
|
176b9f9083 | ||
|
|
c28020708f | ||
|
|
a6547a392b | ||
|
|
f27041342d | ||
|
|
c8e49995cb | ||
|
|
18203972a1 | ||
|
|
5e0f5e1902 | ||
|
|
3884ee3c5a | ||
|
|
c440a4d2b2 | ||
|
|
f2d12306bd | ||
|
|
2da59c3679 | ||
|
|
ce877707bd | ||
|
|
d7694d4c3b | ||
|
|
6b4ca79359 | ||
|
|
23cb11fef3 | ||
|
|
01086d56e5 | ||
|
|
6c5ae559b3 | ||
|
|
254bbcd6a5 | ||
|
|
38c8360d1f | ||
|
|
3485529307 | ||
|
|
ec34c2b351 | ||
|
|
5303bd0a38 | ||
|
|
47dc4a81e4 | ||
|
|
62e80928d5 | ||
|
|
3308bce9b9 | ||
|
|
c1f3b58b28 | ||
|
|
626e0c9d1e | ||
|
|
b7519a65c0 | ||
|
|
e85c8a25f6 | ||
|
|
1c2c93fa81 | ||
|
|
6eca407711 | ||
|
|
0d2da7ad3b | ||
|
|
7a4080ec40 | ||
|
|
b90237ee6f | ||
|
|
6bcd88f5c0 | ||
|
|
a4acf1f66e | ||
|
|
c10b051a92 | ||
|
|
eabe261648 | ||
|
|
a69a52f8b8 | ||
|
|
c9064fc494 | ||
|
|
fcf9bafb18 | ||
|
|
1fc8990531 | ||
|
|
eb29fdada3 | ||
|
|
ae67f5cc20 | ||
|
|
18ec5933b7 | ||
|
|
173b8c46ad | ||
|
|
f5b0536d42 | ||
|
|
e289ce8b31 | ||
|
|
673969d0ba | ||
|
|
6e4fae0e29 | ||
|
|
b34557ef17 | ||
|
|
b427adec21 | ||
|
|
90daeb9a2b | ||
|
|
e71807b732 | ||
|
|
2512e6b5b5 | ||
|
|
8194793f9b | ||
|
|
86981114a7 | ||
|
|
8283a36b2e | ||
|
|
ddcc284b43 | ||
|
|
bd6bc70302 | ||
|
|
8dc73f4601 |
@@ -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,
|
||||
});
|
||||
|
||||
10
.github/ISSUE_TEMPLATE.md
vendored
10
.github/ISSUE_TEMPLATE.md
vendored
@@ -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)
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -28,7 +28,7 @@ An enterprise-class UI design language and React-based implementation.
|
||||
|
||||
## Let's build a better antd together [](http://makeapullrequest.com)
|
||||
|
||||
`antd` is an open source project, improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22).
|
||||
`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
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ export default function getRequestAnimationFrame() {
|
||||
}
|
||||
|
||||
export function cancelRequestAnimationFrame(id) {
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
````
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 />` |
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
`;
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic Usage
|
||||
---
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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't show loading
|
||||
</Button>
|
||||
<br />
|
||||
<Button shape="circle" loading />
|
||||
<Button type="primary" shape="circle" loading />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
````
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
179
components/cascader/__tests__/__snapshots__/index.test.js.snap
Normal file
179
components/cascader/__tests__/__snapshots__/index.test.js.snap
Normal 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>
|
||||
`;
|
||||
71
components/cascader/__tests__/index.test.js
Normal file
71
components/cascader/__tests__/index.test.js
Normal 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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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} />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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) ?
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -48,6 +48,7 @@ moment.locale('zh-cn');
|
||||
| open | 控制弹层是否展开 | boolean | - |
|
||||
| onOpenChange | 弹出日历和关闭日历的回调 | function(status) | 无 |
|
||||
| placeholder | 输入框提示文字 | string\|RangePicker[] | - |
|
||||
| onOk | 点击确定按钮的回调 | function() | - |
|
||||
|
||||
### DatePicker
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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: '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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`).
|
||||
|
||||
@@ -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` 的部分)。
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 | 无 |
|
||||
|
||||
@@ -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="" />
|
||||
`;
|
||||
|
||||
@@ -11,7 +11,7 @@ title:
|
||||
|
||||
## en-US
|
||||
|
||||
Basic usage example
|
||||
Basic usage example.
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
````
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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)问题。
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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);
|
||||
````
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user