mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-16 14:22:28 +08:00
Compare commits
175 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85615771d5 | ||
|
|
9973e26350 | ||
|
|
6dd3304976 | ||
|
|
8e8c9eda7c | ||
|
|
d8ebd398df | ||
|
|
65bac17e58 | ||
|
|
1e322b4206 | ||
|
|
e93dd1e5af | ||
|
|
0793534665 | ||
|
|
0cd85da2b3 | ||
|
|
11852b815a | ||
|
|
b643aa752f | ||
|
|
ebb3a7937a | ||
|
|
029289c6f5 | ||
|
|
fda4e8414d | ||
|
|
d50085a407 | ||
|
|
73dd2c08bd | ||
|
|
71495e71d2 | ||
|
|
0dc2c1771f | ||
|
|
352e0f7ce4 | ||
|
|
accb6cbfeb | ||
|
|
c5059e5fb7 | ||
|
|
aaf28299ce | ||
|
|
139eedf87c | ||
|
|
3f1714bb0c | ||
|
|
429539ecf4 | ||
|
|
0e806bbec5 | ||
|
|
18d0a4d1fb | ||
|
|
0c63deeefb | ||
|
|
1febbbc2c9 | ||
|
|
1d6ee39baa | ||
|
|
31ec5b7ad3 | ||
|
|
dfc59f344e | ||
|
|
d0c115da5e | ||
|
|
1a8e738142 | ||
|
|
6a76ae6d56 | ||
|
|
32b9d1f231 | ||
|
|
08e0e6bdf6 | ||
|
|
6864fea0cb | ||
|
|
f230f61c23 | ||
|
|
b72626d19c | ||
|
|
290d5d2aac | ||
|
|
e6796eccaf | ||
|
|
70cd87d624 | ||
|
|
4e593c651e | ||
|
|
af313bed9a | ||
|
|
54f5d11206 | ||
|
|
ed434c57e9 | ||
|
|
ec87110482 | ||
|
|
58e521de71 | ||
|
|
58b7662eb9 | ||
|
|
8ec86a6b1f | ||
|
|
8049c75d47 | ||
|
|
30f55b923a | ||
|
|
e70bd5320d | ||
|
|
21763c5da9 | ||
|
|
95c0c591e7 | ||
|
|
92f7df48a8 | ||
|
|
f1781bd10e | ||
|
|
2bba8bee98 | ||
|
|
3499dbc88e | ||
|
|
203fcf1c60 | ||
|
|
b526083fa6 | ||
|
|
cb2460c412 | ||
|
|
e030d10e99 | ||
|
|
ce2fe2aa45 | ||
|
|
fe28e6521e | ||
|
|
5460d29db0 | ||
|
|
3bf3013239 | ||
|
|
0bfb35c562 | ||
|
|
ef27e6d200 | ||
|
|
9414a9cbea | ||
|
|
5ba4014386 | ||
|
|
51f1403e14 | ||
|
|
b8fca87461 | ||
|
|
de8e598ef1 | ||
|
|
dda79aa88e | ||
|
|
aa23606166 | ||
|
|
f77f020517 | ||
|
|
8f7fdb8489 | ||
|
|
bb13746400 | ||
|
|
57674fc778 | ||
|
|
17aa47b8cb | ||
|
|
03c06ae9a2 | ||
|
|
d61b6651bb | ||
|
|
4a20dfcf2f | ||
|
|
65d62cd17c | ||
|
|
84baa310e2 | ||
|
|
50f46d0919 | ||
|
|
2265a49dbf | ||
|
|
035e28f75e | ||
|
|
d6af3a7a1c | ||
|
|
0fd88acc93 | ||
|
|
7e8e883019 | ||
|
|
675e037e7a | ||
|
|
4f89e54cb2 | ||
|
|
66cafb95b0 | ||
|
|
fb278395f3 | ||
|
|
b342dbefa2 | ||
|
|
84d65b3f66 | ||
|
|
03c5689db6 | ||
|
|
59f805d323 | ||
|
|
ae9e02a6c3 | ||
|
|
47589ba92c | ||
|
|
0648172973 | ||
|
|
8c8a1797e9 | ||
|
|
b816ae9cfd | ||
|
|
aa99586f9a | ||
|
|
37744a073d | ||
|
|
15e6133867 | ||
|
|
cb555fc30d | ||
|
|
c004001a5f | ||
|
|
00326db74e | ||
|
|
4393fcf1fe | ||
|
|
6530e76758 | ||
|
|
5de18676db | ||
|
|
8409cff8db | ||
|
|
5a827f174e | ||
|
|
8c1be9c6b6 | ||
|
|
0beb892971 | ||
|
|
f0ec7b749a | ||
|
|
1e83c0c940 | ||
|
|
cdeeb776e0 | ||
|
|
0049fdda23 | ||
|
|
4723173c33 | ||
|
|
cad9edc06c | ||
|
|
23212aea5c | ||
|
|
43b155e7f6 | ||
|
|
ee2f025585 | ||
|
|
041bbee2c0 | ||
|
|
9b8ef5a0b7 | ||
|
|
d0114d8d9f | ||
|
|
8dfdce50f9 | ||
|
|
18fced672a | ||
|
|
1669735b66 | ||
|
|
3f6a4172ce | ||
|
|
8f286d6700 | ||
|
|
0308138974 | ||
|
|
68cdfc550d | ||
|
|
d26554d1e9 | ||
|
|
218a516000 | ||
|
|
901a1e6769 | ||
|
|
4ff6eafe12 | ||
|
|
4f1811a3cc | ||
|
|
77b382fb1c | ||
|
|
9cb7d1338b | ||
|
|
0c58fda707 | ||
|
|
459c3c94f9 | ||
|
|
e410662133 | ||
|
|
849c5fbf75 | ||
|
|
8eb472a466 | ||
|
|
fa590e3506 | ||
|
|
b25a4671ee | ||
|
|
10ad3a0fbd | ||
|
|
0be0843ef0 | ||
|
|
58fbdf3785 | ||
|
|
26c436987f | ||
|
|
b054a0c2b8 | ||
|
|
583ed547e9 | ||
|
|
7696c1cd05 | ||
|
|
82b516c77f | ||
|
|
9a0b9adc1e | ||
|
|
19bebebc60 | ||
|
|
821ca46b50 | ||
|
|
f5350fcd7e | ||
|
|
d24a647392 | ||
|
|
45b0693bae | ||
|
|
5d348ec1b2 | ||
|
|
27b099e58e | ||
|
|
4c8297d39d | ||
|
|
22f5f6a18b | ||
|
|
c097d5a9f5 | ||
|
|
f5da1b6b16 | ||
|
|
6e8e8db248 | ||
|
|
621f44e79c |
37
.github/ISSUE_TEMPLATE.md
vendored
37
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,32 +1,15 @@
|
||||
<!-- Issue Template -->
|
||||
|
||||
<!--
|
||||
1. 官方 issue 用于报告 bug 和需求建议。用法咨询类问题建议到 https://segmentfault.com/t/antd 上提问,目前社区没有足够精力提供此类服务,感谢您的理解。
|
||||
2. 建议使用英文进行提问,这样你的问题可以被更多的人阅读和回答。如果表达上确实较复杂,英文标题加中文描述也是可选的方案。
|
||||
3. 报告 BUG 时请务必按照下列格式书写,并尽可能提供源代码、复现步骤、复现演示、GIF 演示等。我们和你一样都希望尽快解决问题,请不要浪费时间在互相追问上。
|
||||
4. 注意你的 issue 格式,不适合阅读的格式会被忽视或直接关闭。
|
||||
5. 如果需要粘贴源码,尽量避免截图并注意代码格式。关于如何在 Markdown 中书写代码可以参考:https://segmentfault.com/markdown
|
||||
6. 抱怨不能解决问题,通畅有效和心情舒畅的交流才能解决。
|
||||
IMPORTANT: Please use the following link to create a new issue:
|
||||
|
||||
http://new-issue.ant.design
|
||||
|
||||
If your issue was not created using the app above, it will be closed immediately.
|
||||
-->
|
||||
|
||||
#### Environment(required)
|
||||
<!--
|
||||
注意:请使用下面的链接来新建 issue:
|
||||
|
||||
- antd version:
|
||||
- OS and its version:
|
||||
- Browser and its version:
|
||||
http://new-issue.ant.design
|
||||
|
||||
#### What did you do? Please provide steps to re-produce your problem.
|
||||
|
||||
<!-- e.g. I just imported Button from antd -->
|
||||
|
||||
#### What do you expected?
|
||||
|
||||
<!-- e.g. It works fine as official website -->
|
||||
|
||||
#### What happen?
|
||||
|
||||
<!-- e.g. Style is not as expected. (And it will be better to provide screenshot) -->
|
||||
|
||||
#### Re-producible online demo
|
||||
|
||||
<!-- Please fork http://codepen.io/benjycui/pen/KgPZrE?editors=001 to re-produce you issue -->
|
||||
不是用上面的链接创建的 issue 会被立即关闭。
|
||||
-->
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
"\\.md$": "./node_modules/antd-demo-jest"
|
||||
},
|
||||
"testRegex": "demo\\.test\\.js$",
|
||||
"testEnvironment": "node"
|
||||
"testEnvironment": "node",
|
||||
"snapshotSerializers": ["enzyme-to-json/serializer"]
|
||||
}
|
||||
|
||||
@@ -17,6 +17,56 @@ If you want to read change logs before `2.0.0`, please visit [GitHub](https://gi
|
||||
|
||||
---
|
||||
|
||||
## 2.9.1
|
||||
|
||||
`2017-04-09`
|
||||
|
||||
- Step
|
||||
- Add more less variables. [#5624](https://github.com/ant-design/ant-design/pull/5624) [@megawac](https://github.com/megawac)
|
||||
- Fix style issue. [#5623](https://github.com/ant-design/ant-design/issues/5623)
|
||||
- Button won't lose focus after click. [#5597](https://github.com/ant-design/ant-design/pull/5597) [@kenaniah](https://github.com/kenaniah)
|
||||
- Add underline to focused link. [#5587](https://github.com/ant-design/ant-design/pull/5597) [@kenaniah](https://github.com/kenaniah)
|
||||
- Fix Dropdown.Button can't use `placement` issue. [#5594](https://github.com/ant-design/ant-design/issues/5594)
|
||||
- Fix Pagination alignment issue. [#5632](https://github.com/ant-design/ant-design/issues/5632)
|
||||
- Fix AutoComplete style issue when use `allowClear`. [#5634](https://github.com/ant-design/ant-design/issues/5634)
|
||||
- Fix DatePicker style issue when set `showToday` to `false`. [#5620](https://github.com/ant-design/ant-design/issues/5620)
|
||||
- Fix Select shows Chinese defaultly. [#5661](https://github.com/ant-design/ant-design/pull/5661) [@LeeHarlan](https://github.com/LeeHarlan)
|
||||
|
||||
## 2.9.0
|
||||
|
||||
`2017-04-01` 👻
|
||||
|
||||
- Change the default font family to be monospaced for numbers. [b526083](https://github.com/ant-design/ant-design/commit/b526083fa6a619113a3d26c4f4f092a8648f3bd4)
|
||||
- Select
|
||||
- Add `mode` prop, deprecate the `tags|combobox|multiple` properties, replaced by `mode={tags|combobox|multiple}`.
|
||||
- `tags|multiple` now supports `allowClear`. [#4843](https://github.com/ant-design/ant-design/issues/4843)
|
||||
- Add a new type `dashboard` of Progress. [#5225](https://github.com/ant-design/ant-design/issues/5225) [@qiaolb](https://github.com/qiaolb)
|
||||
- Add `showLine` prop of Tree, for connecting line style in tree nodes. [#3854](https://github.com/ant-design/ant-design/issues/3854)
|
||||
- TimePicker now supports 12 hours via `use12Hours`. [#4063](https://github.com/ant-design/ant-design/issues/4063)
|
||||
- Add `column.filterIcon` prop of Table, which can be used to customize filter icon. [#5293](https://github.com/ant-design/ant-design/pull/5293)
|
||||
- Add `wrapperClassName` prop of Spin. [#5425](https://github.com/ant-design/ant-design/pull/5425) [@aaronplanell](https://github.com/aaronplanell)
|
||||
- Add `onPrevClick` `onNextClick` props of Tabs. [#4395](https://github.com/ant-design/ant-design/issues/4395)
|
||||
- Add `parser` prop of InputNumber, to extract value from formatter. [#5178](https://github.com/ant-design/ant-design/pull/5178#issuecomment-284557933)
|
||||
- New locales support:
|
||||
- Japanese [#5529](https://github.com/ant-design/ant-design/pull/5529) [@novi](https://github.com/novi)
|
||||
- Slovak [#5304](https://github.com/ant-design/ant-design/pull/5304) [@Kamahl19](https://github.com/Kamahl19)
|
||||
- Estonian [#5266](https://github.com/ant-design/ant-design/pull/5266) [@madisvain](https://github.com/madisvain)
|
||||
- Turkish [#5536](https://github.com/ant-design/ant-design/pull/5536) [@c0b41](https://github.com/c0b41)
|
||||
- TypeScript
|
||||
- Fix definitions of Carousel following react-slick
|
||||
- Fix some definitions of Form.
|
||||
- Fix `getPopupContainer` definitions.
|
||||
- Allow to disable animation of inkBar and panes of Tabs separately. [#5089](https://github.com/ant-design/ant-design/issues/5089) [@xieguanglei](https://github.com/xieguanglei)
|
||||
- Button `loading` prop now supports like `{ delay: 1000 }`, removed the default loading delay. [#5365](https://github.com/ant-design/ant-design/issues/5365)
|
||||
- Add less variables for Card header. [#5354](https://github.com/ant-design/ant-design/pull/5354) [@kossel](https://github.com/kossel)
|
||||
- Fix extra separator of Breadcrumb without `breadcrumbName`.
|
||||
- Fix `Unknown prop placement` warning of Dropdown.Button. [#5594](https://github.com/ant-design/ant-design/issues/5594)
|
||||
- Fix RangePicker and InputNumber placeholder color.
|
||||
- Fix that Cascader search can't use [Backspace]. [#5340](https://github.com/ant-design/ant-design/issues/5340)
|
||||
- Fix that LocaleProvider can't affect `Modal.confirm` sometimes. [#5493](https://github.com/ant-design/ant-design/issues/5493) [@hargasinski](https://github.com/hargasinski)
|
||||
- Fix scroll animation of BackTop which specifies the `target` prop. [#5564](https://github.com/ant-design/ant-design/issues/5564)
|
||||
- Optimize the block style of Pagination. [#5557](https://github.com/ant-design/ant-design/issues/5557)
|
||||
|
||||
## 2.8.3
|
||||
|
||||
`2017-03-27`
|
||||
@@ -40,7 +90,7 @@ If you want to read change logs before `2.0.0`, please visit [GitHub](https://gi
|
||||
- Fixed Popover will be closed by mistake while using Table in it. [#5407](https://github.com/ant-design/ant-design/issues/5407)
|
||||
- Remove restriction that Radio can only be direct chidlren of Radio.Group. [#5443](https://github.com/ant-design/ant-design/issues/5443)
|
||||
- Fixed warning while using Switch in Form.Item. [#5368](https://github.com/ant-design/ant-design/issues/5368)
|
||||
- Fixed Table cannot use default "Select All" behavior. [#5246](https://github.com/ant-design/ant-design/issues/5246) [@infeng](https://github.com/infeng)
|
||||
- Now we defaultly hide the Table's "Select All" dropdown icon, display it when set `selections` to true. [#5246](https://github.com/ant-design/ant-design/issues/5246) [@infeng](https://github.com/infeng)
|
||||
- New theme variable `@info-color`. [#5442](https://github.com/ant-design/ant-design/issues/5442)
|
||||
- Supporting suppress warning(You are using a whole package of antd...) with `NODE_ENV=test` while testing. [#5345](https://github.com/ant-design/ant-design/issues/5345)
|
||||
- Upgrade moment to `2.18.0`.
|
||||
|
||||
@@ -17,6 +17,56 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 2.9.1
|
||||
|
||||
`2017-04-09`
|
||||
|
||||
- Step
|
||||
- 增加 less 变量。[#5624](https://github.com/ant-design/ant-design/pull/5624) [@megawac](https://github.com/megawac)
|
||||
- 修复样式问题。[#5623](https://github.com/ant-design/ant-design/issues/5623)
|
||||
- Button 点击后不会再失去焦点。[#5597](https://github.com/ant-design/ant-design/pull/5597) [@kenaniah](https://github.com/kenaniah)
|
||||
- 链接获取焦点的时候增加下划线。[#5587](https://github.com/ant-design/ant-design/pull/5597) [@kenaniah](https://github.com/kenaniah)
|
||||
- 修复 Dropdown.Button 不能使用 `placement` 的问题。[#5594](https://github.com/ant-design/ant-design/issues/5594)
|
||||
- 修复 Pagination 不对齐的问题。[#5632](https://github.com/ant-design/ant-design/issues/5632)
|
||||
- 修复 AutoComplete 使用 `allowClear` 时的样式问题。[#5634](https://github.com/ant-design/ant-design/issues/5634)
|
||||
- 修复 DatePicker 设置 `showToday` 为 `false` 时的样式问题。[#5620](https://github.com/ant-design/ant-design/issues/5620)
|
||||
- 修复 Select 搜索无结果时默认显示英文的问题。[#5661](https://github.com/ant-design/ant-design/pull/5661) [@LeeHarlan](https://github.com/LeeHarlan)
|
||||
|
||||
## 2.9.0
|
||||
|
||||
`2017-04-01` 👻
|
||||
|
||||
- 默认字体中数字设为等宽,方便进行纵向比较。[b526083](https://github.com/ant-design/ant-design/commit/b526083fa6a619113a3d26c4f4f092a8648f3bd4)
|
||||
- Select
|
||||
- 新增 `mode` 参数,废弃 `tags|combobox|multiple` 属性,使用 `mode={tags|combobox|multiple}` 来代替。
|
||||
- `tags|multiple` 模式现在支持配置 `allowClear` 清除按钮。[#4843](https://github.com/ant-design/ant-design/issues/4843)
|
||||
- Progress 新增 `dashboard` 仪表盘类型。[#5225](https://github.com/ant-design/ant-design/issues/5225) [@qiaolb](https://github.com/qiaolb)
|
||||
- Tree 新增 `showLine` 属性,支持纵向连接线展示。[#3854](https://github.com/ant-design/ant-design/issues/3854)
|
||||
- TimePicker 支持 12 小时制:`use12Hours`。[#4063](https://github.com/ant-design/ant-design/issues/4063)
|
||||
- Table 支持 `column.filterIcon`,支持使用自定义筛选菜单时自定义图标。[#5293](https://github.com/ant-design/ant-design/pull/5293)
|
||||
- Spin 新增 `wrapperClassName`,方便给包裹形态的加载条增加类名。[#5425](https://github.com/ant-design/ant-design/pull/5425) [@aaronplanell](https://github.com/aaronplanell)
|
||||
- Tabs 新增点击左右切换箭头的回调 `onPrevClick` `onNextClick`。[#4395](https://github.com/ant-design/ant-design/issues/4395)
|
||||
- InputNumber 新增 `parser` 属性,用于有时指定了 `formatter` 时需要解析出数字。[#5178](https://github.com/ant-design/ant-design/pull/5178#issuecomment-284557933)
|
||||
- 国际化
|
||||
- 新增日语。[#5529](https://github.com/ant-design/ant-design/pull/5529) [@novi](https://github.com/novi)
|
||||
- 新增斯洛伐克语。[#5304](https://github.com/ant-design/ant-design/pull/5304) [@Kamahl19](https://github.com/Kamahl19)
|
||||
- 新增爱沙尼亚语。[#5266](https://github.com/ant-design/ant-design/pull/5266) [@madisvain](https://github.com/madisvain)
|
||||
- 新增土耳其语。[#5536](https://github.com/ant-design/ant-design/pull/5536) [@c0b41](https://github.com/c0b41)
|
||||
- TypeScript
|
||||
- 参照 react-slick 补充 Carousel 的定义。
|
||||
- 修复 Form 的部分定义。
|
||||
- 修正 `getPopupContainer` 定义。
|
||||
- 允许分开禁用 Tabs 的高亮条和面板的切换动画。[#5089](https://github.com/ant-design/ant-design/issues/5089) [@xieguanglei](https://github.com/xieguanglei)
|
||||
- Button 的 `loading` 属性支持 `{ delay: 1000 }` 的形式,默认不再延迟切换状态 。[#5365](https://github.com/ant-design/ant-design/issues/5365)
|
||||
- 增加 Card 头部的 less 变量。[#5354](https://github.com/ant-design/ant-design/pull/5354) [@kossel](https://github.com/kossel)
|
||||
- 修复 Breadcrumb 没有设置 `breadcrumbName` 时分隔符多余的问题。
|
||||
- 修复 Dropdown.Button 的 `Unknown prop placement` 警告信息。[#5594](https://github.com/ant-design/ant-design/issues/5594)
|
||||
- 修复 RangePicker 和 InputNumber 的占位文字颜色。
|
||||
- 修复 Cascasder 搜索模式下无法使用退格键的问题。[#5340](https://github.com/ant-design/ant-design/issues/5340)
|
||||
- 修复 LocaleProvider 有时对 `Modal.confirm` 失效的问题。[#5493](https://github.com/ant-design/ant-design/issues/5493) [@hargasinski](https://github.com/hargasinski)
|
||||
- 修复 BackTop 设置了 `target` 时滚动动效消失的问题。[#5564](https://github.com/ant-design/ant-design/issues/5564)
|
||||
- 优化 Pagination 的样式实现。[#5557](https://github.com/ant-design/ant-design/issues/5557)
|
||||
|
||||
## 2.8.3
|
||||
|
||||
`2017-03-27`
|
||||
@@ -40,7 +90,7 @@ timeline: true
|
||||
- 修复 Popover 内使用 Table 时会意外关闭的问题。[#5407](https://github.com/ant-design/ant-design/issues/5407)
|
||||
- 去掉 Radio 只能作为 Radio.Group 的直接后代的限制。[#5443](https://github.com/ant-design/ant-design/issues/5443)
|
||||
- 修复 Switch 在 Form.Item 内使用时的 warning。[#5368](https://github.com/ant-design/ant-design/issues/5368)
|
||||
- 修复 Table 无法使用默认全选功能的问题。[#5246](https://github.com/ant-design/ant-design/issues/5246) [@infeng](https://github.com/infeng)
|
||||
- Table 的选择全部菜单现在默认隐藏,`selections` 设置为 true 时展现。[#5246](https://github.com/ant-design/ant-design/issues/5246) [@infeng](https://github.com/infeng)
|
||||
- 新增 `@info-color` 主题变量。[#5442](https://github.com/ant-design/ant-design/issues/5442)
|
||||
- 现在可以通过 `NODE_ENV=test` 来禁用测试时 antd 全量加载的 warning。[#5345](https://github.com/ant-design/ant-design/issues/5345)
|
||||
- 升级 moment 到 `2.18.0`。
|
||||
|
||||
@@ -97,9 +97,19 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [定制主题](http://ant.design/docs/react/customize-theme-cn)
|
||||
|
||||
## 本地开发
|
||||
|
||||
```bash
|
||||
$ git clone git@github.com:ant-design/ant-design.git
|
||||
$ npm install
|
||||
$ npm start
|
||||
```
|
||||
|
||||
打开浏览器访问 http://127.0.0.1:8001 ,更多本地开发文档参见: https://github.com/ant-design/ant-design/wiki/Development 。
|
||||
|
||||
## 如何贡献
|
||||
|
||||
在任何形式的参与前,请先阅读 [贡献者文档](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md)。如果你希望参与贡献,欢迎 [Pull Request](https://github.com/ant-design/ant-design/pulls),或给我们 [报告 Bug](https://github.com/ant-design/ant-design/issues/new)。
|
||||
在任何形式的参与前,请先阅读 [贡献者文档](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md)。如果你希望参与贡献,欢迎 [Pull Request](https://github.com/ant-design/ant-design/pulls),或给我们 [报告 Bug](http://new-issue.ant.design/)。
|
||||
|
||||
> 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html),更好的问题更容易获得帮助。
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ $ npm install
|
||||
$ npm start
|
||||
```
|
||||
|
||||
Open your browser and visit http://127.0.0.1:8001 .
|
||||
Open your browser and visit http://127.0.0.1:8001 , see more at https://github.com/ant-design/ant-design/wiki/Development .
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Please note that Affix should not cover other content on the page, especially wh
|
||||
|--------------|-----------------------|----------|--------------|
|
||||
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 |
|
||||
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - |
|
||||
| target | specifies the scrollable area dom node | () => HTMLElement | () => window |
|
||||
| onChange | Callback when affix state is changed | Function(affixed) | - |
|
||||
|
||||
**Note:** Children of `Affix` can not be `position: absolute`, but you can set `Affix` as `position: absolute`:
|
||||
|
||||
@@ -19,7 +19,7 @@ title: Affix
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window |
|
||||
| onChange | 固定状态改变时触发的回调函数 | Function(affixed) | 无 |
|
||||
|
||||
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
|
||||
|
||||
@@ -4,13 +4,13 @@ import AnchorHelper, { scrollTo } from './anchorHelper';
|
||||
|
||||
export interface AnchorLinkProps {
|
||||
href: string;
|
||||
onClick: (href: string, component: Element) => void;
|
||||
onClick?: (href: string, component: Element) => void;
|
||||
active?: boolean;
|
||||
prefixCls?: string;
|
||||
children?: any;
|
||||
title?: React.ReactNode;
|
||||
offsetTop: number;
|
||||
bounds: number;
|
||||
title: React.ReactNode;
|
||||
offsetTop?: number;
|
||||
bounds?: number;
|
||||
target?: () => HTMLElement | Window;
|
||||
affix?: boolean;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import Affix from '../affix';
|
||||
import AnchorHelper, { getDefaultTarget } from './anchorHelper';
|
||||
|
||||
export interface AnchorProps {
|
||||
target: () => HTMLElement | Window;
|
||||
children: React.ReactNode;
|
||||
target?: () => HTMLElement | Window;
|
||||
children?: React.ReactNode;
|
||||
prefixCls?: string;
|
||||
offsetTop?: number;
|
||||
bounds?: number;
|
||||
|
||||
19
components/auto-complete/InputElement.tsx
Normal file
19
components/auto-complete/InputElement.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
|
||||
export default class InputElement extends React.Component<any, any> {
|
||||
private ele: HTMLInputElement;
|
||||
|
||||
focus = () => {
|
||||
this.ele.focus ? this.ele.focus() : (findDOMNode(this.ele) as HTMLInputElement).focus();
|
||||
}
|
||||
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 as HTMLInputElement),
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
import React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import Select, { AbstractSelectProps, OptionProps, OptGroupProps } from '../select';
|
||||
import Input from '../input';
|
||||
import { Option, OptGroup } from 'rc-select';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface SelectedValue {
|
||||
key: string;
|
||||
label: React.ReactNode;
|
||||
}
|
||||
import Select, { AbstractSelectProps, SelectValue, OptionProps, OptGroupProps } from '../select';
|
||||
import Input from '../input';
|
||||
import InputElement from './InputElement';
|
||||
|
||||
export interface DataSourceItemObject { value: string; text: string; };
|
||||
export type DataSourceItemType = string | DataSourceItemObject;
|
||||
@@ -24,37 +19,18 @@ export type ValidInputElement =
|
||||
React.ReactElement<InputProps>;
|
||||
|
||||
export interface AutoCompleteProps extends AbstractSelectProps {
|
||||
size?: 'large' | 'small' | 'default';
|
||||
className?: string;
|
||||
notFoundContent?: Element;
|
||||
value?: SelectValue;
|
||||
defaultValue?: SelectValue;
|
||||
dataSource: DataSourceItemType[];
|
||||
defaultValue?: string | Array<any> | SelectedValue | Array<SelectedValue>;
|
||||
value?: string | Array<any> | SelectedValue | Array<SelectedValue>;
|
||||
onChange?: (value: string | Array<any> | SelectedValue | Array<SelectedValue>) => void;
|
||||
onSelect?: (value: string | Array<any> | SelectedValue | Array<SelectedValue>, option: Object) => any;
|
||||
disabled?: boolean;
|
||||
optionLabelProp?: string;
|
||||
filterOption?: boolean | ((inputValue: string, option: Object) => any);
|
||||
onChange?: (value: SelectValue) => void;
|
||||
onSelect?: (value: SelectValue, option: Object) => any;
|
||||
children?: ValidInputElement |
|
||||
React.ReactElement<OptionProps> |
|
||||
Array<React.ReactElement<OptionProps>>;
|
||||
}
|
||||
|
||||
class InputElement extends React.Component<any, any> {
|
||||
private ele: HTMLInputElement;
|
||||
|
||||
focus = () => {
|
||||
this.ele.focus ? this.ele.focus() : (findDOMNode(this.ele) as HTMLInputElement).focus();
|
||||
}
|
||||
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 as HTMLInputElement),
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
function isSelectOptionOrSelectOptGroup(child: any): Boolean {
|
||||
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
|
||||
}
|
||||
@@ -122,8 +98,8 @@ export default class AutoComplete extends React.Component<AutoCompleteProps, any
|
||||
<Select
|
||||
{...this.props}
|
||||
className={cls}
|
||||
mode="combobox"
|
||||
optionLabelProp={optionLabelProp}
|
||||
combobox
|
||||
getInputElement={this.getInputElement}
|
||||
notFoundContent={notFoundContent}
|
||||
>
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
&-selection {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
&--single {
|
||||
height: 100%;
|
||||
}
|
||||
&__rendered {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
@@ -27,6 +24,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-allow-clear {
|
||||
.@{select-prefix-cls}-selection:hover .@{select-prefix-cls}-selection__rendered {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.@{input-prefix-cls} {
|
||||
.input();
|
||||
background: transparent;
|
||||
|
||||
@@ -22,4 +22,4 @@ Property | Description | Type | Default
|
||||
-----|-----|-----|------
|
||||
visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400
|
||||
onClick | a callback function, which can be executed when you click the button | Function | -
|
||||
|
||||
target | specifies the scrollable area dom node | () => HTMLElement | () => window
|
||||
|
||||
@@ -9,10 +9,6 @@ import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
const currentScrollTop = () => {
|
||||
return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
|
||||
};
|
||||
|
||||
const easeInOutCubic = (t, b, c, d) => {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
@@ -53,8 +49,16 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
};
|
||||
}
|
||||
|
||||
getCurrentScrollTop = () => {
|
||||
const targetNode = (this.props.target || getDefaultTarget)();
|
||||
if (targetNode === window) {
|
||||
return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
|
||||
}
|
||||
return (targetNode as HTMLElement).scrollTop;
|
||||
}
|
||||
|
||||
scrollToTop = (e) => {
|
||||
const scrollTop = currentScrollTop();
|
||||
const scrollTop = this.getCurrentScrollTop();
|
||||
const startTime = Date.now();
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
|
||||
@@ -22,3 +22,4 @@ title: BackTop
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 |
|
||||
| onClick | 点击按钮的回调函数 | Function | - |
|
||||
| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |
|
||||
|
||||
@@ -32,11 +32,14 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
|
||||
} else {
|
||||
link = <span className={`${prefixCls}-link`} {...restProps}>{children}</span>;
|
||||
}
|
||||
return (
|
||||
<span>
|
||||
{link}
|
||||
<span className={`${prefixCls}-separator`}>{separator}</span>
|
||||
</span>
|
||||
);
|
||||
if (children) {
|
||||
return (
|
||||
<span>
|
||||
{link}
|
||||
<span className={`${prefixCls}-separator`}>{separator}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { mount, render } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import Breadcrumb from '../index';
|
||||
|
||||
describe('Breadcrumb', () => {
|
||||
@@ -14,7 +13,8 @@ describe('Breadcrumb', () => {
|
||||
errorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('warns on non-Breadcrumb.Item children', () => {
|
||||
// https://github.com/airbnb/enzyme/issues/875
|
||||
xit('warns on non-Breadcrumb.Item children', () => {
|
||||
const MyCom = () => <div>foo</div>;
|
||||
mount(
|
||||
<Breadcrumb>
|
||||
@@ -37,6 +37,18 @@ describe('Breadcrumb', () => {
|
||||
</Breadcrumb>
|
||||
);
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/5542
|
||||
it('should not display Breadcrumb Item when its children is falsy', () => {
|
||||
const wrapper = render(
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item />
|
||||
<Breadcrumb.Item>xxx</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>yyy</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,3 +18,34 @@ exports[`Breadcrumb should allow Breadcrumb.Item is null or undefined 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Breadcrumb should not display Breadcrumb Item when its children is falsy 1`] = `
|
||||
<div
|
||||
class="ant-breadcrumb"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
xxx
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
yyy
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { render } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
import routerDemo from '../demo/router.md';
|
||||
|
||||
@@ -8,5 +7,5 @@ demoTest('breadcrumb', { skip: ['router.md'] });
|
||||
const testMethod = typeof window !== 'undefined' ? test : test.skip;
|
||||
testMethod('renders ./components/breadcrumb/demo/router.md correctly', () => {
|
||||
const wrapper = render(routerDemo);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -422,14 +422,6 @@ exports[`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"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import { render, mount } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import Button from '..';
|
||||
|
||||
describe('Button', () => {
|
||||
@@ -8,14 +7,14 @@ describe('Button', () => {
|
||||
const wrapper = render(
|
||||
<Button>Follow</Button>
|
||||
);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders Chinese characters correctly', () => {
|
||||
const wrapper = render(
|
||||
<Button>按钮</Button>
|
||||
);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('have static perperty for type detecting', () => {
|
||||
@@ -25,4 +24,43 @@ describe('Button', () => {
|
||||
// eslint-disable-next-line
|
||||
expect(wrapper.type().__ANT_BUTTON).toBe(true);
|
||||
});
|
||||
|
||||
it('should change loading state instantly by default', () => {
|
||||
class DefaultButton extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
};
|
||||
enterLoading = () => {
|
||||
this.setState({ loading: true });
|
||||
}
|
||||
render() {
|
||||
return <Button loading={this.state.loading} onClick={this.enterLoading}>Button</Button>;
|
||||
}
|
||||
}
|
||||
const wrapper = mount(
|
||||
<DefaultButton />
|
||||
);
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(true);
|
||||
});
|
||||
|
||||
it('should change loading state with delay', () => {
|
||||
// eslint-disable-next-line
|
||||
class DefaultButton extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
};
|
||||
enterLoading = () => {
|
||||
this.setState({ loading: { delay: 1000 } });
|
||||
}
|
||||
render() {
|
||||
return <Button loading={this.state.loading} onClick={this.enterLoading}>Button</Button>;
|
||||
}
|
||||
}
|
||||
const wrapper = mount(
|
||||
<DefaultButton />
|
||||
);
|
||||
wrapper.simulate('click');
|
||||
expect(wrapper.hasClass('ant-btn-loading')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import Icon from '../icon';
|
||||
import omit from 'omit.js';
|
||||
|
||||
@@ -41,7 +40,7 @@ export interface ButtonProps {
|
||||
size?: ButtonSize;
|
||||
onClick?: React.FormEventHandler<any>;
|
||||
onMouseUp?: React.FormEventHandler<any>;
|
||||
loading?: boolean;
|
||||
loading?: boolean | { delay?: number };
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
@@ -66,7 +65,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
size: React.PropTypes.oneOf(['large', 'default', 'small']),
|
||||
htmlType: React.PropTypes.oneOf(['submit', 'button', 'reset']),
|
||||
onClick: React.PropTypes.func,
|
||||
loading: React.PropTypes.bool,
|
||||
loading: React.PropTypes.oneOfType([React.PropTypes.bool, React.PropTypes.object]),
|
||||
className: React.PropTypes.string,
|
||||
icon: React.PropTypes.string,
|
||||
};
|
||||
@@ -89,8 +88,8 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
clearTimeout(this.delayTimeout);
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
this.delayTimeout = setTimeout(() => this.setState({ loading }), 200);
|
||||
if (loading && loading.delay) {
|
||||
this.delayTimeout = setTimeout(() => this.setState({ loading }), loading.delay);
|
||||
} else {
|
||||
this.setState({ loading });
|
||||
}
|
||||
@@ -119,7 +118,6 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
|
||||
// Handle auto focus when click button in Chrome
|
||||
handleMouseUp = (e) => {
|
||||
(findDOMNode(this) as HTMLElement).blur();
|
||||
if (this.props.onMouseUp) {
|
||||
this.props.onMouseUp(e);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ class App extends React.Component {
|
||||
state = {
|
||||
loading: false,
|
||||
iconLoading: false,
|
||||
delayLoading: false,
|
||||
}
|
||||
|
||||
enterLoading = () => {
|
||||
@@ -30,15 +29,6 @@ class App extends React.Component {
|
||||
enterIconLoading = () => {
|
||||
this.setState({ iconLoading: true });
|
||||
}
|
||||
delayLoading = () => {
|
||||
this.setState({
|
||||
delayLoading: true,
|
||||
});
|
||||
|
||||
setTimeout(() => this.setState({
|
||||
delayLoading: false,
|
||||
}), 150);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
@@ -56,9 +46,6 @@ class App extends React.Component {
|
||||
<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 />
|
||||
|
||||
@@ -21,7 +21,7 @@ htmlType | to set the original `type` of `button`, see: [MDN](https://developer.
|
||||
icon | set the icon of button, see: Icon component | string | -
|
||||
shape | can be set to `circle` or omitted | string | -
|
||||
size | can be set to `small` `large` or omitted | string | `default`
|
||||
loading | to set the loading status of button | boolean | `false`
|
||||
loading | to set the loading status of button | boolean \| { delay: number } | `false`
|
||||
onClick | set the handler to handle `click` event | function | -
|
||||
ghost | make background transparent and invert text and border color, added in 2.7 | boolean | false
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标
|
||||
icon | 设置按钮的图标类型 | string | -
|
||||
shape | 设置按钮形状,可选值为 `circle` 或者不设 | string | -
|
||||
size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default`
|
||||
loading | 设置按钮载入状态 | boolean | `false`
|
||||
loading | 设置按钮载入状态 | boolean \| { delay: number } | `false`
|
||||
onClick | `click` 事件的 handler | function | -
|
||||
ghost | 幽灵属性,使按钮背景透明,版本 2.7 中增加 | boolean | false
|
||||
|
||||
|
||||
@@ -212,6 +212,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
class="ant-fullcalendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -342,6 +343,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -472,6 +474,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -602,7 +605,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-fullcalendar-current-week"
|
||||
class="ant-fullcalendar-current-week ant-fullcalendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -733,6 +736,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -863,6 +867,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1214,6 +1219,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
class="ant-fullcalendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1344,6 +1350,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1474,6 +1481,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1604,7 +1612,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-fullcalendar-current-week"
|
||||
class="ant-fullcalendar-current-week ant-fullcalendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1735,6 +1743,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1865,6 +1874,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2214,6 +2224,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
class="ant-fullcalendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2372,6 +2383,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2572,6 +2584,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2779,7 +2792,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-fullcalendar-current-week"
|
||||
class="ant-fullcalendar-current-week ant-fullcalendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2938,6 +2951,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -3096,6 +3110,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -3528,6 +3543,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
class="ant-fullcalendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -3658,6 +3674,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -3788,6 +3805,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -3918,6 +3936,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -4048,6 +4067,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-fullcalendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -4178,6 +4198,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
|
||||
2
components/calendar/locale/et_EE.tsx
Normal file
2
components/calendar/locale/et_EE.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import et_EE from '../../date-picker/locale/et_EE';
|
||||
export default et_EE;
|
||||
2
components/calendar/locale/ja_JP.tsx
Normal file
2
components/calendar/locale/ja_JP.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import ja_JP from '../../date-picker/locale/ja_JP';
|
||||
export default ja_JP;
|
||||
2
components/calendar/locale/sk_SK.tsx
Normal file
2
components/calendar/locale/sk_SK.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import sk_SK from '../../date-picker/locale/sk_SK';
|
||||
export default sk_SK;
|
||||
2
components/calendar/locale/tr_TR.tsx
Normal file
2
components/calendar/locale/tr_TR.tsx
Normal file
@@ -0,0 +1,2 @@
|
||||
import tr_TR from '../../date-picker/locale/tr_TR';
|
||||
export default tr_TR;
|
||||
@@ -20,8 +20,9 @@
|
||||
}
|
||||
|
||||
&-head {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
height: @card-head-height;
|
||||
line-height: @card-head-height;
|
||||
background: @card-head-background;
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
padding: 0 24px;
|
||||
|
||||
@@ -32,7 +33,7 @@
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
color: @heading-color;
|
||||
color: @card-head-color;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,23 +23,45 @@ import React from 'react';
|
||||
export type CarouselEffect = 'scrollx' | 'fade';
|
||||
// Carousel
|
||||
export interface CarouselProps {
|
||||
/** 动画效果函数,可取 scrollx, fade */
|
||||
effect?: CarouselEffect;
|
||||
/** 是否显示面板指示点 */
|
||||
dots?: boolean;
|
||||
/** 垂直显示 */
|
||||
vertical?: boolean;
|
||||
/** 是否自动切换 */
|
||||
autoplay?: boolean;
|
||||
/** 动画效果 */
|
||||
easing?: string;
|
||||
/** 切换面板的回调 */
|
||||
beforeChange?: (from: number, to: number) => void;
|
||||
/** 切换面板的回调 */
|
||||
afterChange?: (current: number) => void;
|
||||
/** 行内样式 */
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
accessibility?: boolean;
|
||||
nextArrow?: HTMLElement | any;
|
||||
prevArrow?: HTMLElement | any;
|
||||
pauseOnHover?: boolean;
|
||||
className?: string;
|
||||
adaptiveHeight?: boolean;
|
||||
arrows?: boolean;
|
||||
autoplaySpeed?: number;
|
||||
centerMode?: boolean;
|
||||
centerPadding?: string | any;
|
||||
cssEase?: string | any;
|
||||
dotsClass?: string;
|
||||
draggable?: boolean;
|
||||
fade?: boolean;
|
||||
focusOnSelect?: boolean;
|
||||
infinite?: boolean;
|
||||
initialSlide?: number;
|
||||
lazyLoad?: boolean;
|
||||
rtl?: boolean;
|
||||
slide?: string;
|
||||
slidesToShow?: number;
|
||||
slidesToScroll?: number;
|
||||
speed?: number;
|
||||
swipe?: boolean;
|
||||
swipeToSlide?: boolean;
|
||||
touchMove?: boolean;
|
||||
touchThreshold?: number;
|
||||
variableWidth?: boolean;
|
||||
useCSS?: boolean;
|
||||
slickGoTo?: number;
|
||||
}
|
||||
|
||||
export default class Carousel extends React.Component<CarouselProps, any> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render, mount } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
import Cascader from '..';
|
||||
|
||||
const options = [{
|
||||
@@ -32,7 +32,7 @@ describe('Cascader', () => {
|
||||
const wrapper = mount(
|
||||
<Cascader options={options} />
|
||||
);
|
||||
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
|
||||
expect(render(wrapper.find('Trigger').node.getComponent())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('popup correctly when panel is open', () => {
|
||||
@@ -40,7 +40,7 @@ describe('Cascader', () => {
|
||||
<Cascader options={options} />
|
||||
);
|
||||
wrapper.find('input').simulate('click');
|
||||
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
|
||||
expect(render(wrapper.find('Trigger').node.getComponent())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('popup correctly with defaultValue', () => {
|
||||
@@ -48,24 +48,32 @@ describe('Cascader', () => {
|
||||
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />
|
||||
);
|
||||
wrapper.find('input').simulate('click');
|
||||
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
|
||||
expect(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();
|
||||
expect(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();
|
||||
expect(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();
|
||||
expect(render(wrapper.find('Trigger').node.getComponent())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('backspace should work with `Cascader[showSearch]`', () => {
|
||||
const wrapper = mount(<Cascader options={options} showSearch />);
|
||||
wrapper.find('input').simulate('change', { target: { value: '123' } });
|
||||
expect(wrapper.state('inputValue')).toBe('123');
|
||||
wrapper.find('input').simulate('keydown', { keyCode: KeyCode.BACKSPACE });
|
||||
// Simulate onKeyDown will not trigger onChange by default, so the value is still '123'
|
||||
expect(wrapper.state('inputValue')).toBe('123');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,10 +9,14 @@ title:
|
||||
|
||||
可以直接搜索选项并选择。
|
||||
|
||||
> `Cascader[showSearch]` 暂不支持服务端搜索,更多信息见 [#5547](https://github.com/ant-design/ant-design/issues/5547)
|
||||
|
||||
## en-US
|
||||
|
||||
Search and select options directly.
|
||||
|
||||
> Now, `Cascader[showSearch]` doesn't support search on server, more info [#5547](https://github.com/ant-design/ant-design/issues/5547)
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import RcCascader from 'rc-cascader';
|
||||
import arrayTreeFilter from 'array-tree-filter';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
import Input from '../input';
|
||||
import Icon from '../icon';
|
||||
|
||||
@@ -172,6 +173,12 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
if (e.keyCode === KeyCode.BACKSPACE) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
handleInputChange = (e) => {
|
||||
const inputValue = e.target.value;
|
||||
this.setState({ inputValue });
|
||||
@@ -334,6 +341,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
||||
autoComplete="off"
|
||||
onClick={showSearch ? this.handleInputClick : undefined}
|
||||
onBlur={showSearch ? this.handleInputBlur : undefined}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onChange={showSearch ? this.handleInputChange : undefined}
|
||||
/>
|
||||
<span className={`${prefixCls}-picker-label`}>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
position: relative;
|
||||
vertical-align: text-bottom;
|
||||
|
||||
.@{checkbox-prefix-cls}-wrapper:hover &,
|
||||
.@{checkbox-prefix-cls}-wrapper:hover &-inner,
|
||||
&:hover &-inner,
|
||||
&-input:focus + &-inner {
|
||||
border-color: @primary-color;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import { mount, render } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import moment from 'moment';
|
||||
import { RangePicker } from '../';
|
||||
|
||||
describe('RangePicker', () => {
|
||||
it('show month panel according to value', () => {
|
||||
const birthday = moment('2000-01-01', 'YYYY-MM-DD');
|
||||
const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
|
||||
const wrapper = mount(
|
||||
<RangePicker
|
||||
getCalendarContainer={trigger => trigger}
|
||||
@@ -16,12 +15,12 @@ describe('RangePicker', () => {
|
||||
);
|
||||
|
||||
wrapper.setProps({ value: [birthday, birthday] });
|
||||
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent())))
|
||||
expect(render(wrapper.find('Trigger').node.getComponent()))
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('switch to corresponding month panel when click presetted ranges', () => {
|
||||
const birthday = moment('2000-01-01', 'YYYY-MM-DD');
|
||||
const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
|
||||
const wrapper = mount(
|
||||
<RangePicker
|
||||
ranges={{
|
||||
@@ -36,7 +35,7 @@ describe('RangePicker', () => {
|
||||
const rangeCalendarWrapper = mount(wrapper.find('Trigger').node.getComponent());
|
||||
rangeCalendarWrapper.find('.ant-calendar-range-quick-selector a')
|
||||
.simulate('click');
|
||||
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent())))
|
||||
expect(render(wrapper.find('Trigger').node.getComponent()))
|
||||
.toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -65,7 +65,7 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
role="button"
|
||||
title="选择月份"
|
||||
>
|
||||
1月
|
||||
一月
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
@@ -85,78 +85,78 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Sun"
|
||||
title="周一"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Su
|
||||
一
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Mon"
|
||||
title="周二"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Mo
|
||||
二
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Tue"
|
||||
title="周三"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Tu
|
||||
三
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Wed"
|
||||
title="周四"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
We
|
||||
四
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Thu"
|
||||
title="周五"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Th
|
||||
五
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Fri"
|
||||
title="周六"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Fr
|
||||
六
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Sat"
|
||||
title="周日"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Sa
|
||||
日
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
@@ -165,21 +165,9 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
class="ant-calendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class="ant-calendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-last-month-cell"
|
||||
role="gridcell"
|
||||
title="1999-12-26"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-calendar-date"
|
||||
>
|
||||
26
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-last-month-cell"
|
||||
role="gridcell"
|
||||
@@ -258,10 +246,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
1
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -275,6 +259,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
2
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -353,10 +342,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
8
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -370,6 +355,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
9
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -448,10 +438,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
15
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -465,6 +451,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
16
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -543,10 +534,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
22
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -560,6 +547,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
23
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -638,10 +630,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
29
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -655,6 +643,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
30
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -733,6 +726,19 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
5
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-next-month-btn-day"
|
||||
role="gridcell"
|
||||
title="2000-2-6"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-calendar-date"
|
||||
>
|
||||
6
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -784,7 +790,7 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
role="button"
|
||||
title="选择月份"
|
||||
>
|
||||
2月
|
||||
二月
|
||||
</a>
|
||||
</span>
|
||||
<a
|
||||
@@ -812,78 +818,78 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Sun"
|
||||
title="周一"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Su
|
||||
一
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Mon"
|
||||
title="周二"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Mo
|
||||
二
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Tue"
|
||||
title="周三"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Tu
|
||||
三
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Wed"
|
||||
title="周四"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
We
|
||||
四
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Thu"
|
||||
title="周五"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Th
|
||||
五
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Fri"
|
||||
title="周六"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Fr
|
||||
六
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="ant-calendar-column-header"
|
||||
role="columnheader"
|
||||
title="Sat"
|
||||
title="周日"
|
||||
>
|
||||
<span
|
||||
class="ant-calendar-column-header-inner"
|
||||
>
|
||||
Sa
|
||||
日
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
@@ -892,21 +898,9 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
class="ant-calendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-last-month-cell"
|
||||
role="gridcell"
|
||||
title="2000-1-30"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-calendar-date"
|
||||
>
|
||||
30
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-last-month-cell"
|
||||
role="gridcell"
|
||||
@@ -985,10 +979,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
5
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1002,6 +992,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
6
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1080,10 +1075,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
12
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1097,6 +1088,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
13
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1175,10 +1171,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
19
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1192,6 +1184,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
20
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1270,10 +1267,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
26
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1287,6 +1280,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
27
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell"
|
||||
role="gridcell"
|
||||
@@ -1365,10 +1363,6 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
4
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-next-month-btn-day"
|
||||
role="gridcell"
|
||||
@@ -1382,6 +1376,11 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
5
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-next-month-btn-day"
|
||||
role="gridcell"
|
||||
@@ -1460,6 +1459,19 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
11
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-next-month-btn-day"
|
||||
role="gridcell"
|
||||
title="2000-3-12"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-calendar-date"
|
||||
>
|
||||
12
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1558,7 +1570,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
role="button"
|
||||
title="选择月份"
|
||||
>
|
||||
1月
|
||||
一月
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
@@ -1658,6 +1670,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
class="ant-calendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class="ant-calendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1753,6 +1766,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1848,6 +1862,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1943,6 +1958,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2038,6 +2054,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2133,6 +2150,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2277,7 +2295,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
role="button"
|
||||
title="选择月份"
|
||||
>
|
||||
2月
|
||||
二月
|
||||
</a>
|
||||
</span>
|
||||
<a
|
||||
@@ -2385,6 +2403,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
class="ant-calendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2480,6 +2499,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2575,6 +2595,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2670,6 +2691,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2765,6 +2787,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -2860,6 +2883,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface PickerProps {
|
||||
popupStyle?: React.CSSProperties;
|
||||
locale?: any;
|
||||
size?: 'large' | 'small' | 'default';
|
||||
getCalendarContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||
getCalendarContainer?: (triggerNode: Element) => HTMLElement;
|
||||
open?: boolean;
|
||||
onOpenChange?: (status: boolean) => void;
|
||||
disabledDate?: (current: moment.Moment) => boolean;
|
||||
|
||||
17
components/date-picker/locale/et_EE.tsx
Normal file
17
components/date-picker/locale/et_EE.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/et_EE';
|
||||
import TimePickerLocale from '../../time-picker/locale/et_EE';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// 统一合并为完整的 Locale
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: 'Vali kuupäev',
|
||||
rangePlaceholder: ['Algus kuupäev', 'Lõpu kuupäev'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
||||
16
components/date-picker/locale/ja_JP.tsx
Normal file
16
components/date-picker/locale/ja_JP.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/ja_JP';
|
||||
import TimePickerLocale from '../../time-picker/locale/ja_JP';
|
||||
import assign from 'object-assign';
|
||||
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: '日付を選択',
|
||||
rangePlaceholder: ['開始日付', '終了日付'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
||||
17
components/date-picker/locale/sk_SK.tsx
Normal file
17
components/date-picker/locale/sk_SK.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/sk_SK';
|
||||
import TimePickerLocale from '../../time-picker/locale/sk_SK';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// 统一合并为完整的 Locale
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: 'Vybrať dátum',
|
||||
rangePlaceholder: ['Od', 'Do'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
||||
17
components/date-picker/locale/tr_TR.tsx
Normal file
17
components/date-picker/locale/tr_TR.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/en_US';
|
||||
import TimePickerLocale from '../../time-picker/locale/tr_TR';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// Merge into a locale object
|
||||
const locale = {
|
||||
lang: assign({
|
||||
placeholder: 'Tarih Seç',
|
||||
rangePlaceholder: ['Başlangıç Tarihi', 'Bitiş Tarihi'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json
|
||||
|
||||
export default locale;
|
||||
@@ -1,13 +1,13 @@
|
||||
.@{calendar-prefix-cls}-decade-panel {
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: @component-background;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
outline: none;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
background: @component-background;
|
||||
border-radius: @border-radius-base;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-decade-panel-hidden {
|
||||
@@ -18,10 +18,14 @@
|
||||
.calendarPanelHeader(~"@{calendar-prefix-cls}-decade-panel");
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-decade-panel-body {
|
||||
height: ~"calc(100% - 34px)";
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-decade-panel-table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
height: 248px;
|
||||
height: 100%;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
.@{calendar-prefix-cls}-month-panel {
|
||||
left: 0;
|
||||
top: 1px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: @component-background;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
outline: none;
|
||||
top: 1px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
border-radius: @border-radius-base;
|
||||
background: @component-background;
|
||||
outline: none;
|
||||
|
||||
> div { // TODO: this is a useless wrapper, and we need to remove it in rc-calendar
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-month-panel-hidden {
|
||||
@@ -18,10 +22,14 @@
|
||||
.calendarPanelHeader(~"@{calendar-prefix-cls}-month-panel");
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-month-panel-body {
|
||||
height: ~"calc(100% - 34px)";
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-month-panel-table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
height: 248px;
|
||||
height: 100%;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
outline: 0;
|
||||
width: 43%;
|
||||
text-align: center;
|
||||
.placeholder();
|
||||
|
||||
&[disabled] {
|
||||
cursor: not-allowed;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
.@{calendar-prefix-cls}-year-panel {
|
||||
left: 0;
|
||||
top: 1px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: @component-background;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
outline: none;
|
||||
top: 1px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
border-radius: @border-radius-base;
|
||||
background: @component-background;
|
||||
outline: none;
|
||||
|
||||
> div { // TODO: this is a useless wrapper, and we need to remove it in rc-calendar
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-year-panel-hidden {
|
||||
@@ -18,10 +22,14 @@
|
||||
.calendarPanelHeader(~"@{calendar-prefix-cls}-year-panel");
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-year-panel-body {
|
||||
height: ~"calc(100% - 34px)";
|
||||
}
|
||||
|
||||
.@{calendar-prefix-cls}-year-panel-table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
height: 248px;
|
||||
height: 100%;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,19 +18,12 @@ export interface DropdownButtonProps {
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
style?: React.CSSProperties;
|
||||
children?: any;
|
||||
placement?: 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight';
|
||||
}
|
||||
|
||||
export default class DropdownButton extends React.Component<DropdownButtonProps, any> {
|
||||
static defaultProps = {
|
||||
align: {
|
||||
points: ['tr', 'br'],
|
||||
overlay: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
offset: [0, 4],
|
||||
targetOffset: [0, 0],
|
||||
},
|
||||
placement: 'bottomRight',
|
||||
type: 'default',
|
||||
prefixCls: 'ant-dropdown-button',
|
||||
};
|
||||
@@ -38,7 +31,7 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
|
||||
render() {
|
||||
const {
|
||||
type, overlay, trigger, align, children, className, onClick, prefixCls,
|
||||
disabled, visible, onVisibleChange, ...restProps,
|
||||
disabled, visible, onVisibleChange, placement, ...restProps,
|
||||
} = this.props;
|
||||
const cls = classNames(prefixCls, className);
|
||||
|
||||
@@ -47,6 +40,7 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
|
||||
overlay,
|
||||
trigger: disabled ? [] : trigger,
|
||||
onVisibleChange,
|
||||
placement,
|
||||
};
|
||||
|
||||
if ('visible' in this.props) {
|
||||
|
||||
@@ -9,7 +9,7 @@ export interface DropDownProps {
|
||||
onVisibleChange?: (visible?: boolean) => void;
|
||||
visible?: boolean;
|
||||
align?: Object;
|
||||
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||
getPopupContainer?: (triggerNode: Element) => HTMLElement;
|
||||
prefixCls?: string;
|
||||
placement?: 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight';
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ export interface FormProps {
|
||||
hideRequiredMark?: boolean;
|
||||
}
|
||||
|
||||
export type ValidateCallback = (erros: any, values: any) => void;
|
||||
|
||||
// function create
|
||||
export type WrappedFormUtils = {
|
||||
/** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */
|
||||
@@ -40,23 +42,26 @@ export type WrappedFormUtils = {
|
||||
/** 设置一组输入控件的值*/
|
||||
setFields(obj: Object): void;
|
||||
/** 校验并获取一组输入域的值与 Error */
|
||||
validateFields(fieldNames: Array<string>, options: Object, callback: (erros: any, values: any) => void): any;
|
||||
validateFields(fieldNames: Array<string>, callback: (erros: any, values: any) => void): any;
|
||||
validateFields(options: Object, callback: (erros: any, values: any) => void): any;
|
||||
validateFields(callback: (erros: any, values: any) => void): any;
|
||||
validateFields(fieldNames: Array<string>, options: Object, callback: ValidateCallback): any;
|
||||
validateFields(fieldNames: Array<string>, callback: ValidateCallback): any;
|
||||
validateFields(options: Object, callback: ValidateCallback): any;
|
||||
validateFields(callback: ValidateCallback): any;
|
||||
/** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */
|
||||
validateFieldsAndScroll(fieldNames?: Array<string>,
|
||||
options?: Object,
|
||||
callback?: (erros: any, values: any) => void): void;
|
||||
validateFieldsAndScroll(fieldNames?: Array<string>, options?: Object, callback?: ValidateCallback): void;
|
||||
validateFieldsAndScroll(fieldNames?: Array<string>, callback?: ValidateCallback): void;
|
||||
validateFieldsAndScroll(options?: Object, callback?: ValidateCallback): void;
|
||||
validateFieldsAndScroll(callback?: ValidateCallback): void;
|
||||
/** 获取某个输入控件的 Error */
|
||||
getFieldError(name: string): Object[];
|
||||
getFieldsError(names?: Array<string>): Object;
|
||||
/** 判断一个输入控件是否在校验状态*/
|
||||
isFieldValidating(name: string): boolean;
|
||||
isFieldTouched(name: string): boolean;
|
||||
isFieldsTouched(names?: Array<string>): boolean;
|
||||
/** 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 */
|
||||
resetFields(names?: Array<string>): void;
|
||||
|
||||
getFieldDecorator(id: string, options: {
|
||||
getFieldDecorator(id: string, options?: {
|
||||
/** 子节点的值的属性,如 Checkbox 的是 'checked' */
|
||||
valuePropName?: string;
|
||||
/** 子节点的初始值,类型、可选值均由子节点决定 */
|
||||
@@ -78,8 +83,9 @@ export interface FormComponentProps {
|
||||
form: WrappedFormUtils;
|
||||
}
|
||||
|
||||
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/9951
|
||||
export interface ComponentDecorator<TOwnProps> {
|
||||
(component: React.ComponentClass<FormComponentProps & TOwnProps>): React.ComponentClass<TOwnProps>;
|
||||
(component: React.ComponentClass<FormComponentProps & TOwnProps>): any;
|
||||
}
|
||||
|
||||
export default class Form extends React.Component<FormProps, any> {
|
||||
|
||||
@@ -937,6 +937,7 @@ exports[`renders ./components/form/demo/normal-login.md correctly 1`] = `
|
||||
</label>
|
||||
<a
|
||||
class="login-form-forgot"
|
||||
href=""
|
||||
>
|
||||
Forgot password
|
||||
</a>
|
||||
@@ -949,7 +950,9 @@ exports[`renders ./components/form/demo/normal-login.md correctly 1`] = `
|
||||
</span>
|
||||
</button>
|
||||
Or
|
||||
<a>
|
||||
<a
|
||||
href=""
|
||||
>
|
||||
register now!
|
||||
</a>
|
||||
</div>
|
||||
@@ -1289,7 +1292,9 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
</span>
|
||||
<span>
|
||||
I have read the
|
||||
<a>
|
||||
<a
|
||||
href=""
|
||||
>
|
||||
agreement
|
||||
</a>
|
||||
</span>
|
||||
|
||||
@@ -51,11 +51,11 @@ class NormalLoginForm extends React.Component {
|
||||
})(
|
||||
<Checkbox>Remember me</Checkbox>
|
||||
)}
|
||||
<a className="login-form-forgot">Forgot password</a>
|
||||
<a className="login-form-forgot" href="">Forgot password</a>
|
||||
<Button type="primary" htmlType="submit" className="login-form-button">
|
||||
Log in
|
||||
</Button>
|
||||
Or <a>register now!</a>
|
||||
Or <a href="">register now!</a>
|
||||
</FormItem>
|
||||
</Form>
|
||||
);
|
||||
|
||||
@@ -212,7 +212,7 @@ class RegistrationForm extends React.Component {
|
||||
{getFieldDecorator('agreement', {
|
||||
valuePropName: 'checked',
|
||||
})(
|
||||
<Checkbox>I have read the <a>agreement</a></Checkbox>
|
||||
<Checkbox>I have read the <a href="">agreement</a></Checkbox>
|
||||
)}
|
||||
</FormItem>
|
||||
<FormItem {...tailFormItemLayout}>
|
||||
|
||||
@@ -79,7 +79,7 @@ class Demo extends React.Component {
|
||||
{ required: true, message: 'Please select your favourite colors!', type: 'array' },
|
||||
],
|
||||
})(
|
||||
<Select multiple placeholder="Please select favourite colors">
|
||||
<Select mode="multiple" placeholder="Please select favourite colors">
|
||||
<Option value="red">Red</Option>
|
||||
<Option value="green">Green</Option>
|
||||
<Option value="blue">Blue</Option>
|
||||
|
||||
@@ -64,6 +64,12 @@ ReactDOM.render(<IconSet className="icons" catigory="logo" />, mountNode);
|
||||
|
||||
## API
|
||||
|
||||
You can set `style` and `className` for size and color of icons because they are still words in essence.
|
||||
|
||||
```jsx
|
||||
<Icon type="question" style={{ fontSize: 16, color: '#08c' }} />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------|------------------|------- |---------|
|
||||
| type | Type of ant design icons | string | - |
|
||||
|
||||
@@ -65,6 +65,12 @@ ReactDOM.render(<IconSet className="icons" catigory="logo" />, mountNode);
|
||||
|
||||
## API
|
||||
|
||||
由于图标字体本质上还是文字,可以使用 `style` 和 `className` 设置图标的大小和颜色。
|
||||
|
||||
```jsx
|
||||
<Icon type="question" style={{ fontSize: 16, color: '#08c' }} />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------|------------------|----------|--------|
|
||||
| type | 图标类型 | string | - |
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// this file is not used if use https://github.com/ant-design/babel-plugin-import
|
||||
import warning from './_util/warning';
|
||||
|
||||
const ENV = process.env.NODE_ENV;
|
||||
if (ENV !== 'production' && ENV !== 'test') {
|
||||
warning(
|
||||
false,
|
||||
'You are using a whole package of antd,' +
|
||||
if (ENV !== 'production' &&
|
||||
ENV !== 'test' &&
|
||||
typeof console !== 'undefined' &&
|
||||
console.warn &&
|
||||
typeof window !== 'undefined') {
|
||||
console.warn(
|
||||
'You are using a whole package of antd, ' +
|
||||
'please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,3 +23,4 @@ When a numeric value needs to be provided.
|
||||
| disabled | disable the input | boolean | false |
|
||||
| size | width of input box | string | - |
|
||||
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - |
|
||||
| parser | Specifies the value extracted from formatter | function( string): number | - |
|
||||
|
||||
@@ -26,3 +26,4 @@ title: InputNumber
|
||||
| disabled | 禁用 | boolean | false |
|
||||
| size | 输入框大小 | string | 无 |
|
||||
| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - |
|
||||
| parser | 指定从 formatter 里转换回数字的方式,和 formatter 搭配使用 | function( string): number | - |
|
||||
|
||||
@@ -72,13 +72,13 @@
|
||||
text-align: left;
|
||||
outline: 0;
|
||||
-moz-appearance: textfield;
|
||||
line-height: @input-height-base - 2px;
|
||||
height: @input-height-base - 2px;
|
||||
transition: all 0.3s linear;
|
||||
color: @input-color;
|
||||
border: 0;
|
||||
border-radius: @border-radius-base;
|
||||
padding: 0 7px;
|
||||
.placeholder();
|
||||
|
||||
&[disabled] {
|
||||
.disabled();
|
||||
@@ -90,7 +90,6 @@
|
||||
|
||||
input {
|
||||
height: @input-height-lg - 2px;
|
||||
line-height: @input-height-lg - 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +98,6 @@
|
||||
|
||||
input {
|
||||
height: @input-height-sm - 2px;
|
||||
line-height: @input-height-sm - 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -667,6 +667,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
class="ant-fullcalendar-tbody"
|
||||
>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -797,6 +798,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -927,6 +929,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1057,7 +1060,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-fullcalendar-current-week"
|
||||
class="ant-fullcalendar-current-week ant-fullcalendar-active-week"
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1188,6 +1191,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
@@ -1318,6 +1322,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=""
|
||||
role="row"
|
||||
>
|
||||
<td
|
||||
|
||||
@@ -14,6 +14,10 @@ import nlNL from '../nl_NL';
|
||||
import caES from '../ca_ES';
|
||||
import csCZ from '../cs_CZ';
|
||||
import koKR from '../ko_KR';
|
||||
import etEE from '../et_EE';
|
||||
import skSK from '../sk_SK';
|
||||
import jaJP from '../ja_JP';
|
||||
import trTR from '../tr_TR';
|
||||
|
||||
const Option = Select.Option;
|
||||
const RangePicker = DatePicker.RangePicker;
|
||||
@@ -59,7 +63,7 @@ const App = () => (
|
||||
|
||||
describe('Locale Provider', () => {
|
||||
it('should display the text as locale changed', () => {
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR].forEach((locale) => {
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR, etEE, skSK, jaJP, trTR].forEach((locale) => {
|
||||
const wrapper = mount(
|
||||
<LocaleProvider locale={locale}>
|
||||
<App />
|
||||
@@ -69,4 +73,29 @@ describe('Locale Provider', () => {
|
||||
expect(DatePickerPlaceholder).toBe(locale.DatePicker.lang.placeholder);
|
||||
});
|
||||
});
|
||||
|
||||
it('should change locale of Modal.xxx', () => {
|
||||
class ModalDemo extends React.Component {
|
||||
componentDidMount() {
|
||||
Modal.confirm({
|
||||
title: 'Hello World!',
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR, trTR].forEach((locale) => {
|
||||
mount(
|
||||
<LocaleProvider locale={locale}>
|
||||
<ModalDemo />
|
||||
</LocaleProvider>
|
||||
);
|
||||
const currentConfirmNode = document.querySelectorAll('.ant-confirm')[document.querySelectorAll('.ant-confirm').length - 1];
|
||||
const cancelButtonText = currentConfirmNode.querySelectorAll('.ant-btn:not(.ant-btn-primary) span')[0].innerHTML;
|
||||
const okButtonText = currentConfirmNode.querySelectorAll('.ant-btn-primary span')[0].innerHTML;
|
||||
expect(cancelButtonText).toBe(locale.Modal.cancelText);
|
||||
expect(okButtonText).toBe(locale.Modal.okText);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
45
components/locale-provider/et_EE.tsx
Normal file
45
components/locale-provider/et_EE.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('et');
|
||||
|
||||
import DatePicker from '../date-picker/locale/et_EE';
|
||||
import TimePicker from '../time-picker/locale/et_EE';
|
||||
import Calendar from '../calendar/locale/et_EE';
|
||||
|
||||
export default {
|
||||
locale: 'et',
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'Filtri menüü',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'Nulli',
|
||||
emptyText: 'Andmed puuduvad',
|
||||
selectAll: 'Vali kõik',
|
||||
selectInvert: 'Inverteeri valik',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Tühista',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Tühista',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: 'Ei leitud',
|
||||
searchPlaceholder: 'Otsi siit',
|
||||
itemUnit: 'kogus',
|
||||
itemsUnit: 'kogus',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: 'Ei leitud',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Üleslaadimine...',
|
||||
removeFile: 'Eemalda fail',
|
||||
uploadError: 'Üleslaadimise tõrge',
|
||||
previewFile: 'Faili eelvaade',
|
||||
},
|
||||
};
|
||||
@@ -34,7 +34,7 @@ export default class LocaleProvider extends React.Component<LocaleProviderProps,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentWillMount() {
|
||||
this.componentDidUpdate();
|
||||
}
|
||||
|
||||
|
||||
47
components/locale-provider/ja_JP.tsx
Normal file
47
components/locale-provider/ja_JP.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('ja');
|
||||
|
||||
import Pagination from 'rc-pagination/lib/locale/ja_JP';
|
||||
import DatePicker from '../date-picker/locale/ja_JP';
|
||||
import TimePicker from '../time-picker/locale/ja_JP';
|
||||
import Calendar from '../calendar/locale/ja_JP';
|
||||
|
||||
export default {
|
||||
locale: 'ja',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'メニューをフィルター',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'リセット',
|
||||
emptyText: 'データがありません',
|
||||
selectAll: 'すべてを選択',
|
||||
selectInvert: '選択を反転',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'キャンセル',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'キャンセル',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: '結果はありません',
|
||||
searchPlaceholder: 'ここを検索',
|
||||
itemUnit: 'アイテム',
|
||||
itemsUnit: 'アイテム',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: '結果はありません',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'アップロード中...',
|
||||
removeFile: 'ファイルを削除',
|
||||
uploadError: 'アップロードエラー',
|
||||
previewFile: 'ファイルをプレビュー',
|
||||
},
|
||||
};
|
||||
@@ -47,6 +47,6 @@ export default {
|
||||
uploading: 'Закачиваю...',
|
||||
removeFile: 'Удалить файл',
|
||||
uploadError: 'Ошибка при закачке',
|
||||
previewFile: 'Предпросмотр файл',
|
||||
previewFile: 'Предпросмотр файла',
|
||||
},
|
||||
};
|
||||
|
||||
47
components/locale-provider/sk_SK.tsx
Normal file
47
components/locale-provider/sk_SK.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('sk');
|
||||
|
||||
import Pagination from 'rc-pagination/lib/locale/sk_SK';
|
||||
import DatePicker from '../date-picker/locale/sk_SK';
|
||||
import TimePicker from '../time-picker/locale/sk_SK';
|
||||
import Calendar from '../calendar/locale/sk_SK';
|
||||
|
||||
export default {
|
||||
locale: 'sk',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'Filter',
|
||||
filterConfirm: 'OK',
|
||||
filterReset: 'Obnoviť',
|
||||
emptyText: 'Žiadne dáta',
|
||||
selectAll: 'Vybrať všetko',
|
||||
selectInvert: 'Vybrať opačné',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Zrušiť',
|
||||
justOkText: 'OK',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'OK',
|
||||
cancelText: 'Zrušiť',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: 'Nenájdené',
|
||||
searchPlaceholder: 'Vyhľadávanie',
|
||||
itemUnit: 'položka',
|
||||
itemsUnit: 'položiek',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: 'Nenájdené',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Nahrávanie...',
|
||||
removeFile: 'Odstrániť súbor',
|
||||
uploadError: 'Chyba pri nahrávaní',
|
||||
previewFile: 'Zobraziť súbor',
|
||||
},
|
||||
};
|
||||
47
components/locale-provider/tr_TR.tsx
Normal file
47
components/locale-provider/tr_TR.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
moment.locale('tr');
|
||||
|
||||
import Pagination from 'rc-pagination/lib/locale/en_US';
|
||||
import DatePicker from '../date-picker/locale/tr_TR';
|
||||
import TimePicker from '../time-picker/locale/tr_TR';
|
||||
import Calendar from '../calendar/locale/en_US';
|
||||
|
||||
export default {
|
||||
locale: 'tr',
|
||||
Pagination,
|
||||
DatePicker,
|
||||
TimePicker,
|
||||
Calendar,
|
||||
Table: {
|
||||
filterTitle: 'Menü Filtrele',
|
||||
filterConfirm: 'Tamam',
|
||||
filterReset: 'Sıfırla',
|
||||
emptyText: 'Veri Yok',
|
||||
selectAll: 'Hepsini Seç',
|
||||
selectInvert: 'Tersini Seç',
|
||||
},
|
||||
Modal: {
|
||||
okText: 'Tamam',
|
||||
cancelText: 'İptal',
|
||||
justOkText: 'Tamam',
|
||||
},
|
||||
Popconfirm: {
|
||||
okText: 'Tamam',
|
||||
cancelText: 'İptal',
|
||||
},
|
||||
Transfer: {
|
||||
notFoundContent: 'Bulunamadı',
|
||||
searchPlaceholder: 'Arama',
|
||||
itemUnit: 'Öğe',
|
||||
itemsUnit: 'Öğeler',
|
||||
},
|
||||
Select: {
|
||||
notFoundContent: 'Bulunamadı',
|
||||
},
|
||||
Upload: {
|
||||
uploading: 'Yükleniyor...',
|
||||
removeFile: `Dosyayı kaldır`,
|
||||
uploadError: 'Yükleme Hatası',
|
||||
previewFile: `Dosyayı Önizle`,
|
||||
},
|
||||
};
|
||||
@@ -19,7 +19,7 @@ export interface MentionProps {
|
||||
multiLines?: Boolean;
|
||||
prefix?: string;
|
||||
placeholder?: string;
|
||||
getSuggestionContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||
getSuggestionContainer?: (triggerNode: Element) => HTMLElement;
|
||||
onFocus?: Function;
|
||||
onBlur?: Function;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('Menu', () => {
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
});
|
||||
|
||||
it.only('should accept openKeys in mode inline', () => {
|
||||
it('should accept openKeys in mode inline', () => {
|
||||
const wrapper = mount(
|
||||
<Menu openKeys={['1']} mode="inline" openAnimation="">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
|
||||
@@ -30,6 +30,7 @@ More layout and samples: [layout](/docs/spec/layout).
|
||||
|----------|---------------|----------|--------------|
|
||||
| theme | color of the theme | string: `light` `dark` | `light` |
|
||||
| mode | type of the menu; vertical, horizontal, and inline modes are supported | string: vertical horizontal inline | vertical |
|
||||
| selectable | allow selecting menu items | boolean | true |
|
||||
| selectedKeys | array with the keys of currently selected menu items | string[] | |
|
||||
| defaultSelectedKeys | array with the keys of default selected menu items | string[] | |
|
||||
| openKeys | array with the keys of currently opened sub menus | string[] | |
|
||||
@@ -58,7 +59,7 @@ More layout and samples: [layout](/docs/spec/layout).
|
||||
| disabled | disabled or not | boolean | false |
|
||||
| key | unique id of the menu item | string | |
|
||||
| title | title of the sub menu | string\|ReactNode | |
|
||||
| children | sub menus or sub menu items | Arrat<MenuItem\|SubMenu> | |
|
||||
| children | sub menus or sub menu items | Array<MenuItem\|SubMenu> | |
|
||||
| onTitleClick | callback of the clicked sub menu title | Function({ eventKey, domEvent }) | |
|
||||
|
||||
### Menu.ItemGroup props
|
||||
|
||||
@@ -98,8 +98,6 @@
|
||||
|
||||
&-item-selected {
|
||||
color: @primary-color;
|
||||
// fix chrome render bug
|
||||
transform: translateZ(0);
|
||||
> a,
|
||||
> a:hover {
|
||||
color: @primary-color;
|
||||
@@ -120,11 +118,20 @@
|
||||
&-vertical {
|
||||
border-right: @border-width-base @border-style-base @border-color-split;
|
||||
.@{menu-prefix-cls}-item {
|
||||
border-right: 3px @border-style-base transparent;
|
||||
margin-left: -1px;
|
||||
left: 1px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-right: 3px solid @primary-color;
|
||||
transform: scaleY(.0001);
|
||||
transition: all .2s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +141,9 @@
|
||||
border-right: 0;
|
||||
margin-left: 0;
|
||||
left: 0;
|
||||
&:after {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
> .@{menu-prefix-cls}-item:first-child {
|
||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||
@@ -147,8 +157,9 @@
|
||||
&-inline {
|
||||
.@{menu-prefix-cls}-selected,
|
||||
.@{menu-prefix-cls}-item-selected {
|
||||
border-right-color: @primary-color;
|
||||
transform: translateZ(0);
|
||||
&:after {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,6 +404,9 @@
|
||||
border-right: 0;
|
||||
margin-left: 0;
|
||||
left: 0;
|
||||
&:after {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-dark &-item:hover,
|
||||
@@ -412,6 +426,9 @@
|
||||
&-dark &-item-selected {
|
||||
border-right: 0;
|
||||
color: #fff;
|
||||
&:after {
|
||||
border-right: 0;
|
||||
}
|
||||
> a,
|
||||
> a:hover {
|
||||
color: #fff;
|
||||
|
||||
45
components/modal/__tests__/Modal.test.js
Normal file
45
components/modal/__tests__/Modal.test.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Modal from '..';
|
||||
|
||||
class ModalTester extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { visible: false };
|
||||
}
|
||||
componentDidMount() {
|
||||
this.setState({ visible: true }); // eslint-disable-line react/no-did-mount-set-state
|
||||
}
|
||||
saveContainer = (container) => {
|
||||
this.container = container;
|
||||
}
|
||||
getContainer = () => {
|
||||
return this.container;
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div ref={this.saveContainer} />
|
||||
<Modal
|
||||
{...this.props}
|
||||
visible={this.state.visible}
|
||||
getContainer={this.getContainer}
|
||||
>
|
||||
Here is content of Modal
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Modal', () => {
|
||||
it('render correctly', () => {
|
||||
const wrapper = mount(<ModalTester />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render without footer', () => {
|
||||
const wrapper = mount(<ModalTester footer={null} />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
115
components/modal/__tests__/__snapshots__/Modal.test.js.snap
Normal file
115
components/modal/__tests__/__snapshots__/Modal.test.js.snap
Normal file
@@ -0,0 +1,115 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Modal render correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-content"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-modal-body"
|
||||
>
|
||||
Here is content of Modal
|
||||
</div>
|
||||
<div
|
||||
class="ant-modal-footer"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-lg"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
取 消
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary ant-btn-lg"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
确 定
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
>
|
||||
sentinel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Modal render without footer 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-content"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-modal-body"
|
||||
>
|
||||
Here is content of Modal
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
>
|
||||
sentinel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,159 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/modal/demo/async.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open a modal dialog
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open a modal dialog
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/confirm.md correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
confirmation modal dialog
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/confirm-promise.md correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Confirmation modal dialog
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/footer.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open modal dialog
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/info.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Info
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Success
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Error
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Warning
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/locale.md correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Show Modal
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
confirm
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/manual.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Success
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/position.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Display a modal dialog at 20px to Top
|
||||
</span>
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Vertically centered modal dialog
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('modal');
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
&-total-text {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-right: 10px;
|
||||
@@ -32,7 +32,7 @@
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
border: @border-width-base @border-style-base @border-color-base;
|
||||
background-color: @component-background;
|
||||
margin-right: 8px;
|
||||
@@ -117,7 +117,6 @@
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
display: inline-block;
|
||||
@@ -135,7 +134,7 @@
|
||||
.iconfont-size-under-12px(8px);
|
||||
display: block;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
line-height: 27px;
|
||||
font-family: "anticon";
|
||||
text-align: center;
|
||||
}
|
||||
@@ -153,7 +152,6 @@
|
||||
&-prev {
|
||||
a {
|
||||
&:after {
|
||||
margin-top: -.5px;
|
||||
content: "\e620";
|
||||
display: block;
|
||||
}
|
||||
@@ -188,15 +186,15 @@
|
||||
}
|
||||
|
||||
&-options {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
&-size-changer {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&-quick-jumper {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
height: @input-height-base;
|
||||
line-height: @input-height-base;
|
||||
|
||||
@@ -218,7 +216,7 @@
|
||||
}
|
||||
|
||||
&-simple &-simple-pager {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
|
||||
input {
|
||||
|
||||
@@ -21,6 +21,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -31,7 +32,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:73.82742735936014px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:221.48228207808043px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -60,6 +61,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -70,7 +72,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
stroke="#ff5500"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:88.59291283123217px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:206.7167966062084px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -101,6 +103,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -111,7 +114,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
|
||||
stroke="#87d068"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:0px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -147,6 +150,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -157,7 +161,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:295.3097094374406px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:0px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -211,6 +215,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -221,7 +226,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:206.7167966062084px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:88.59291283123217px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -250,6 +255,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -260,7 +266,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
stroke="#ff5500"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:88.59291283123217px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:206.7167966062084px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -291,6 +297,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -301,7 +308,7 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
stroke="#87d068"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:0px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -316,6 +323,49 @@ exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/progress/demo/dashboard.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info"
|
||||
>
|
||||
<div
|
||||
class="ant-progress-inner"
|
||||
style="width:132px;height:132px;font-size:27.12px;"
|
||||
>
|
||||
<svg
|
||||
class="ant-progress-circle "
|
||||
viewbox="0 0 100 100"
|
||||
>
|
||||
<path
|
||||
class="ant-progress-circle-trail"
|
||||
d="M 50,50 m 0,47
|
||||
a 47,47 0 1 1 0,-94
|
||||
a 47,47 0 1 1 0,94"
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:220.30970943744057px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
d="M 50,50 m 0,47
|
||||
a 47,47 0 1 1 0,-94
|
||||
a 47,47 0 1 1 0,94"
|
||||
fill-opacity="0"
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:165.23228207808043px 295.3097094374406px;stroke-dashoffset:-37.5px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
class="ant-progress-text"
|
||||
>
|
||||
75%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/progress/demo/dynamic.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
@@ -385,6 +435,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -395,7 +446,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
stroke="#108ee9"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:73.82742735936014px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:221.48228207808043px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@@ -424,6 +475,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
fill-opacity="0"
|
||||
stroke="#f3f3f3"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
<path
|
||||
class="ant-progress-circle-path"
|
||||
@@ -434,7 +486,7 @@ exports[`renders ./components/progress/demo/format.md correctly 1`] = `
|
||||
stroke="#87d068"
|
||||
stroke-linecap="round"
|
||||
stroke-width="6"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:0px;transition:stroke-dashoffset 0.3s ease 0s, stroke 0.3s ease;"
|
||||
style="stroke-dasharray:295.3097094374406px 295.3097094374406px;stroke-dashoffset:-0px;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s;"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
|
||||
20
components/progress/demo/dashboard.md
Normal file
20
components/progress/demo/dashboard.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
order: 8
|
||||
title:
|
||||
zh-CN: 仪表盘
|
||||
en-US: Dashboard
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
仪表盘样式的进度条。
|
||||
|
||||
## en-US
|
||||
|
||||
A dashboard style of progress.
|
||||
|
||||
````jsx
|
||||
import { Progress } from 'antd';
|
||||
|
||||
ReactDOM.render(<Progress type="dashboard" percent={75} />, mountNode);
|
||||
````
|
||||
@@ -17,7 +17,7 @@ If it will take a long time to complete the operation, you can use `Progress` to
|
||||
|
||||
Property | Description | Type | Default
|
||||
-----|-----|-----|------
|
||||
type | to set the type, options: `line` `circle` | string | line
|
||||
type | to set the type, options: `line` `circle` `dashboard`| string | line
|
||||
percent | to set the completion percentage | number | 0
|
||||
format | template function of the content | function(percent) | `percent => percent + '%'`
|
||||
status | to set the status of the progress, options: `success` `exception` `active` | string | -
|
||||
|
||||
@@ -19,7 +19,7 @@ title: Progress
|
||||
|
||||
| 属性 | 说明 | 类型 | 默认值 |
|
||||
|----------|---------------|----------|---------------|
|
||||
| type | 类型,可选 `line` `circle` | string | line |
|
||||
| type | 类型,可选 `line` `circle` `dashboard` | string | line |
|
||||
| percent | 百分比 | number | 0 |
|
||||
| format | 内容的模板函数 | function(percent) | `percent => percent + '%'` |
|
||||
| status | 状态,可选:`success` `exception` `active` | string | - |
|
||||
|
||||
@@ -12,7 +12,7 @@ const statusColorMap = {
|
||||
export interface ProgressProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
type?: 'line' | 'circle';
|
||||
type?: 'line' | 'circle' | 'dashboard';
|
||||
percent?: number;
|
||||
format?: (percent: number) => string;
|
||||
status?: 'success' | 'active' | 'exception';
|
||||
@@ -21,6 +21,8 @@ export interface ProgressProps {
|
||||
trailColor?: string;
|
||||
width?: number;
|
||||
style?: React.CSSProperties;
|
||||
gapDegree?: number;
|
||||
gapPosition?: 'top' | 'bottom' | 'left' | 'right';
|
||||
}
|
||||
|
||||
export default class Progress extends React.Component<ProgressProps, any> {
|
||||
@@ -37,20 +39,21 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
|
||||
static propTypes = {
|
||||
status: PropTypes.oneOf(['normal', 'exception', 'active', 'success']),
|
||||
type: PropTypes.oneOf(['line', 'circle']),
|
||||
type: PropTypes.oneOf(['line', 'circle', 'dashboard']),
|
||||
showInfo: PropTypes.bool,
|
||||
percent: PropTypes.number,
|
||||
width: PropTypes.number,
|
||||
strokeWidth: PropTypes.number,
|
||||
trailColor: PropTypes.string,
|
||||
format: PropTypes.func,
|
||||
gapDegree: PropTypes.number,
|
||||
};
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const {
|
||||
prefixCls, className, percent = 0, status, format, trailColor,
|
||||
type, strokeWidth, width, showInfo, ...restProps,
|
||||
type, strokeWidth, width, showInfo, gapDegree = 0, gapPosition, ...restProps,
|
||||
} = props;
|
||||
const progressStatus = parseInt(percent.toString(), 10) >= 100 && !('status' in props) ?
|
||||
'success' : (status || 'normal');
|
||||
@@ -60,7 +63,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
|
||||
if (showInfo) {
|
||||
let text;
|
||||
const iconType = type === 'circle' ? '' : '-circle';
|
||||
const iconType = (type === 'circle' || type === 'dashboard') ? '' : '-circle';
|
||||
if (progressStatus === 'exception') {
|
||||
text = format ? textFormatter(percent) : <Icon type={`cross${iconType}`} />;
|
||||
} else if (progressStatus === 'success') {
|
||||
@@ -86,7 +89,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
{progressInfo}
|
||||
</div>
|
||||
);
|
||||
} else if (type === 'circle') {
|
||||
} else if (type === 'circle' || type === 'dashboard') {
|
||||
const circleSize = width || 132;
|
||||
const circleStyle = {
|
||||
width: circleSize,
|
||||
@@ -94,6 +97,8 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
fontSize: circleSize * 0.16 + 6,
|
||||
};
|
||||
const circleWidth = strokeWidth || 6;
|
||||
const gapPos = gapPosition || type === 'dashboard' && 'bottom' || 'top';
|
||||
const gapDeg = gapDegree || type === 'dashboard' && 75;
|
||||
progress = (
|
||||
<div className={`${prefixCls}-inner`} style={circleStyle}>
|
||||
<Circle
|
||||
@@ -103,6 +108,8 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
strokeColor={statusColorMap[progressStatus]}
|
||||
trailColor={trailColor}
|
||||
prefixCls={prefixCls}
|
||||
gapDegree={gapDeg}
|
||||
gapPosition={gapPos}
|
||||
/>
|
||||
{progressInfo}
|
||||
</div>
|
||||
@@ -110,7 +117,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
|
||||
}
|
||||
|
||||
const classString = classNames(prefixCls, {
|
||||
[`${prefixCls}-${type}`]: true,
|
||||
[`${prefixCls}-${type === 'dashboard' && 'circle' || type}`]: true,
|
||||
[`${prefixCls}-status-${progressStatus}`]: true,
|
||||
[`${prefixCls}-show-info`]: showInfo,
|
||||
}, className);
|
||||
|
||||
@@ -493,6 +493,188 @@ exports[`renders ./components/radio/demo/radiogroup-more.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/radio/demo/radiogroup-options.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-radio-group"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio ant-radio-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Pear
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Orange
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-radio-group"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio ant-radio-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Pear
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Orange
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-radio-group"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-wrapper ant-radio-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio ant-radio-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Apple
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Pear
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-input"
|
||||
type="radio"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
Orange
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/radio/demo/size.md correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
|
||||
@@ -16,6 +16,21 @@ describe('Radio', () => {
|
||||
);
|
||||
}
|
||||
|
||||
function createRadioGroupByOption(props) {
|
||||
const options = [
|
||||
{ label: 'A', value: 'A' },
|
||||
{ label: 'B', value: 'B' },
|
||||
{ label: 'C', value: 'C' },
|
||||
];
|
||||
|
||||
return (
|
||||
<RadioGroup
|
||||
{...props}
|
||||
options={options}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
it('responses hover events', () => {
|
||||
const onMouseEnter = jest.fn();
|
||||
const onMouseLeave = jest.fn();
|
||||
@@ -77,4 +92,13 @@ describe('Radio', () => {
|
||||
radios.at(0).simulate('change');
|
||||
expect(onChange.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('optional should correct render', () => {
|
||||
const wrapper = mount(
|
||||
createRadioGroupByOption()
|
||||
);
|
||||
const radios = wrapper.find('input');
|
||||
|
||||
expect(radios.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import { shallow, render } from 'enzyme';
|
||||
import { renderToJson } from 'enzyme-to-json';
|
||||
import Radio from '../radio';
|
||||
|
||||
describe('Radio', () => {
|
||||
it('should render correctly', () => {
|
||||
const wrapper = render(<Radio className="customized">Test</Radio>);
|
||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('responses hover events', () => {
|
||||
|
||||
72
components/radio/demo/radiogroup-options.md
Normal file
72
components/radio/demo/radiogroup-options.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: RadioGroup 组合 - 配置方式
|
||||
en-US: RadioGroup group - optional
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过配置 `options` 参数来渲染单选框。
|
||||
|
||||
> `2.9.0` 之后支持。
|
||||
|
||||
## en-US
|
||||
|
||||
Render radios by configuring `options`.
|
||||
|
||||
> support after `2.9.0`.
|
||||
|
||||
```jsx
|
||||
import { Radio } from 'antd';
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const plainOptions = ['Apple', 'Pear', 'Orange'];
|
||||
const options = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Pear', value: 'Pear' },
|
||||
{ label: 'Orange', value: 'Orange' },
|
||||
];
|
||||
const optionsWithDisabled = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Pear', value: 'Pear' },
|
||||
{ label: 'Orange', value: 'Orange', disabled: false },
|
||||
];
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
value1: 'Apple',
|
||||
value2: 'Apple',
|
||||
value3: 'Apple',
|
||||
}
|
||||
onChange1 = (e) => {
|
||||
console.log('radio1 checked', e.target.value);
|
||||
this.setState({
|
||||
value1: e.target.value,
|
||||
});
|
||||
}
|
||||
onChange2 = (e) => {
|
||||
console.log('radio2 checked', e.target.value);
|
||||
this.setState({
|
||||
value2: e.target.value,
|
||||
});
|
||||
}
|
||||
onChange3 = (e) => {
|
||||
console.log('radio3 checked', e.target.value);
|
||||
this.setState({
|
||||
value3: e.target.value,
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<RadioGroup options={plainOptions} onChange={this.onChange1} value={this.state.value1} />
|
||||
<RadioGroup options={options} onChange={this.onChange2} value={this.state.value2} />
|
||||
<RadioGroup options={optionsWithDisabled} onChange={this.onChange3} value={this.state.value3} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import shallowEqual from 'shallowequal';
|
||||
import Radio from './radio';
|
||||
|
||||
function getCheckedValue(children) {
|
||||
let value = null;
|
||||
@@ -29,6 +30,12 @@ export interface RadioGroupProps {
|
||||
disabled?: boolean;
|
||||
onMouseEnter?: React.FormEventHandler<any>;
|
||||
onMouseLeave?: React.FormEventHandler<any>;
|
||||
/** 以配置的方式设置 Radio 子元素,设置了此参数,会忽略 children */
|
||||
options?: Array<string | {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default class RadioGroup extends React.Component<RadioGroupProps, any> {
|
||||
@@ -83,8 +90,8 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState, nextContext) {
|
||||
return !shallowEqual(this.props, nextProps) ||
|
||||
!shallowEqual(this.state, nextState) ||
|
||||
!shallowEqual(this.context.group, nextContext.group);
|
||||
!shallowEqual(this.state, nextState) ||
|
||||
!shallowEqual(this.context.group, nextContext.group);
|
||||
}
|
||||
|
||||
onRadioChange = (ev) => {
|
||||
@@ -103,10 +110,44 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
|
||||
}
|
||||
render() {
|
||||
const props = this.props;
|
||||
const { prefixCls = 'ant-radio-group', className = '', children } = props;
|
||||
const { prefixCls = 'ant-radio-group', className = '' } = props;
|
||||
const classString = classNames(prefixCls, {
|
||||
[`${prefixCls}-${props.size}`]: props.size,
|
||||
}, className);
|
||||
|
||||
let children: React.ReactChildren[] | React.ReactElement<any>[] | React.ReactNode = props.children;
|
||||
|
||||
// 如果存在 options, 优先使用
|
||||
if (props.options && props.options.length > 0) {
|
||||
children = props.options.map((option, index) => {
|
||||
if (typeof option === 'string') { // 此处类型自动推导为 string
|
||||
return (
|
||||
<Radio
|
||||
key={index}
|
||||
disabled={this.props.disabled}
|
||||
value={option}
|
||||
onChange={this.onRadioChange}
|
||||
checked={this.state.value === option}
|
||||
>
|
||||
{option}
|
||||
</Radio>
|
||||
);
|
||||
} else { // 此处类型自动推导为 { label: string value: string }
|
||||
return (
|
||||
<Radio
|
||||
key={index}
|
||||
disabled={option.disabled || this.props.disabled}
|
||||
value={option.value}
|
||||
onChange={this.onRadioChange}
|
||||
checked={this.state.value === option.value}
|
||||
>
|
||||
{option.label}
|
||||
</Radio>
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classString}
|
||||
|
||||
@@ -31,3 +31,4 @@ radio group,wrap a group of `Radio`。
|
||||
| value | Used for setting the currently selected value. | any | none | none |
|
||||
| defaultValue | Default selected value | any | none | none |
|
||||
| size | Size, only on radio style | string | `large` `default` `small` | `default` |
|
||||
| options | set children optional | string[] \| Array<{ label: string value: string disabled?: boolean }> | 无 | 无 |
|
||||
|
||||
@@ -32,3 +32,4 @@ title: Radio
|
||||
| value | 用于设置当前选中的值 | any | 无 | 无 |
|
||||
| defaultValue | 默认选中的值 | any | 无 | 无 |
|
||||
| size | 大小,只对按钮样式生效 | string | `large` `default` `small` | `default` |
|
||||
| options | 以配置形式设置子元素 | string[] \| Array<{ label: string value: string disabled?: boolean }> | 无 | 无 |
|
||||
|
||||
@@ -28,7 +28,7 @@ function handleChange(value) {
|
||||
|
||||
ReactDOM.render(
|
||||
<Select
|
||||
tags
|
||||
mode="tags"
|
||||
style={{ width: '100%' }}
|
||||
onChange={handleChange}
|
||||
tokenSeparators={[',']}
|
||||
|
||||
@@ -41,7 +41,8 @@ class App extends React.Component {
|
||||
render() {
|
||||
// filterOption needs to be false,as the value is dynamically generated
|
||||
return (
|
||||
<Select combobox
|
||||
<Select
|
||||
mode="combobox"
|
||||
style={{ width: 200 }}
|
||||
onChange={this.handleChange}
|
||||
filterOption={false}
|
||||
|
||||
@@ -28,7 +28,7 @@ function handleChange(value) {
|
||||
|
||||
ReactDOM.render(
|
||||
<Select
|
||||
multiple
|
||||
mode="multiple"
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
|
||||
@@ -67,7 +67,7 @@ class SearchInput extends React.Component {
|
||||
const options = this.state.data.map(d => <Option key={d.value}>{d.text}</Option>);
|
||||
return (
|
||||
<Select
|
||||
combobox
|
||||
mode="combobox"
|
||||
value={this.state.value}
|
||||
placeholder={this.props.placeholder}
|
||||
notFoundContent=""
|
||||
|
||||
@@ -59,7 +59,7 @@ class UserRemoteSelect extends React.Component {
|
||||
const { fetching, data, value } = this.state;
|
||||
return (
|
||||
<Select
|
||||
multiple
|
||||
mode="multiple"
|
||||
labelInValue
|
||||
value={value}
|
||||
placeholder="Select users"
|
||||
|
||||
@@ -55,7 +55,7 @@ class SelectSizesDemo extends React.Component {
|
||||
</Select>
|
||||
<br />
|
||||
<Select
|
||||
combobox
|
||||
mode="combobox"
|
||||
size={size}
|
||||
defaultValue="a1"
|
||||
onChange={handleChange}
|
||||
@@ -65,7 +65,7 @@ class SelectSizesDemo extends React.Component {
|
||||
</Select>
|
||||
<br />
|
||||
<Select
|
||||
multiple
|
||||
mode="multiple"
|
||||
size={size}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
@@ -76,7 +76,7 @@ class SelectSizesDemo extends React.Component {
|
||||
</Select>
|
||||
<br />
|
||||
<Select
|
||||
tags
|
||||
mode="tags"
|
||||
size={size}
|
||||
placeholder="Please select"
|
||||
defaultValue={['a10', 'c12']}
|
||||
|
||||
@@ -27,7 +27,8 @@ function handleChange(value) {
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Select tags
|
||||
<Select
|
||||
mode="tags"
|
||||
style={{ width: '100%' }}
|
||||
searchPlaceholder="标签模式"
|
||||
onChange={handleChange}
|
||||
|
||||
@@ -25,10 +25,12 @@ A Selector similar to Select2.
|
||||
|----------|----------------|----------|--------------|
|
||||
| value | Current selected option. | string\|string[] | - |
|
||||
| defaultValue | Initial selected option. | string\|string[] | - |
|
||||
| multiple | Allow multiple select. | boolean | false |
|
||||
| allowClear | Show clear button, working in single mode only. | boolean | false |
|
||||
| mode | Set mode of Select(Support after 2.9) | 'multiple' \| 'tags' \| 'combobox' | - |
|
||||
| multiple | Allow multiple select(Deprecated after 2.9) | boolean | false |
|
||||
| tags | When tagging is enabled the user can select from pre-existing options or create a new tag by picking the first choice, which is what the user has typed into the search box so far.(Deprecated after 2.9) | boolean |false |
|
||||
| combobox | Enable combobox mode(can not set multiple at the same time).(Deprecated after 2.9) | boolean | false |
|
||||
| allowClear | Show clear button. | boolean | false |
|
||||
| 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 |
|
||||
| tags | When tagging is enabled the user can select from pre-existing options or create a new tag by picking the first choice, which is what the user has typed into the search box so far. | boolean |false |
|
||||
| onSelect | Called when a option is selected, the params are option's value (or key) and option instance. | function(value, option) | - |
|
||||
| onDeselect | Called when a option is deselected, the params are option's value (or key) . only called for multiple or tags, effective in multiple or tags mode only. | function(value) | - |
|
||||
| onChange | Called when select an option or input value change, or value of input is changed in combobox mode | function(value, label) | - |
|
||||
@@ -40,7 +42,6 @@ A Selector similar to Select2.
|
||||
| dropdownMatchSelectWidth | Whether dropdown's with is same with select. | boolean | true |
|
||||
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | value |
|
||||
| optionLabelProp | Which prop value of option will render as content of select. | string | `children` |
|
||||
| combobox | Enable combobox mode(can not set multiple at the same time). | boolean | false |
|
||||
| size | Size of Select input. `large` `small` | string | default |
|
||||
| showSearch | Whether show search input in single mode.| boolean | false |
|
||||
| disabled | Whether disabled select | boolean | false |
|
||||
|
||||
@@ -1,33 +1,39 @@
|
||||
import React from 'react';
|
||||
import { PropTypes } from 'react';
|
||||
import React, { PropTypes } from 'react';
|
||||
import RcSelect, { Option, OptGroup } from 'rc-select';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export type SelectValue = string | any[] | { key: string, label: React.ReactNode } |
|
||||
Array<{ key: string, label: React.ReactNode }>;
|
||||
import warning from '../_util/warning';
|
||||
|
||||
export interface AbstractSelectProps {
|
||||
size?: 'default' | 'large' | 'small';
|
||||
className?: string;
|
||||
notFoundContent?: React.ReactNode | null;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
size?: 'default' | 'large' | 'small';
|
||||
notFoundContent?: React.ReactNode | null;
|
||||
transitionName?: string;
|
||||
optionLabelProp?: string;
|
||||
choiceTransitionName?: string;
|
||||
showSearch?: boolean;
|
||||
allowClear?: boolean;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
placeholder?: string;
|
||||
filterOption?: boolean | ((inputValue: string, option: Object) => any);
|
||||
}
|
||||
|
||||
export interface LabeledValue {
|
||||
key: string;
|
||||
label: React.ReactNode;
|
||||
}
|
||||
|
||||
export type SelectValue = string | any[] | LabeledValue | LabeledValue[];
|
||||
|
||||
export interface SelectProps extends AbstractSelectProps {
|
||||
value?: SelectValue;
|
||||
defaultValue?: SelectValue;
|
||||
combobox?: boolean;
|
||||
mode?: 'default' | 'multiple' | 'tags' | 'combobox';
|
||||
multiple?: boolean;
|
||||
tags?: boolean;
|
||||
combobox?: boolean;
|
||||
optionLabelProp?: string;
|
||||
filterOption?: boolean | ((inputValue: string, option: Object) => any);
|
||||
onChange?: (value: SelectValue) => void;
|
||||
onSelect?: (value: SelectValue, option: Object) => any;
|
||||
onDeselect?: (value: SelectValue) => any;
|
||||
onSearch?: (value: string) => any;
|
||||
@@ -35,10 +41,9 @@ export interface SelectProps extends AbstractSelectProps {
|
||||
optionFilterProp?: string;
|
||||
defaultActiveFirstOption?: boolean;
|
||||
labelInValue?: boolean;
|
||||
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||
getPopupContainer?: (triggerNode: Element) => HTMLElement;
|
||||
dropdownStyle?: React.CSSProperties;
|
||||
dropdownMenuStyle?: React.CSSProperties;
|
||||
onChange?: (value: SelectValue) => void;
|
||||
tokenSeparators?: string[];
|
||||
getInputElement?: () => React.ReactElement<any>;
|
||||
}
|
||||
@@ -84,38 +89,64 @@ export default class Select extends React.Component<SelectProps, any> {
|
||||
choiceTransitionName: PropTypes.string,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
antLocale: React.PropTypes.object,
|
||||
};
|
||||
|
||||
context: SelectContext;
|
||||
|
||||
getLocale() {
|
||||
const { antLocale } = this.context;
|
||||
if (antLocale && antLocale.Select) {
|
||||
return antLocale.Select;
|
||||
}
|
||||
return {
|
||||
notFoundContent: '无匹配结果',
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls,
|
||||
className = '',
|
||||
size,
|
||||
mode,
|
||||
// @deprecated
|
||||
multiple,
|
||||
tags,
|
||||
combobox,
|
||||
...restProps,
|
||||
} = this.props;
|
||||
|
||||
let { notFoundContent = 'Not Found', optionLabelProp } = this.props;
|
||||
warning(
|
||||
!multiple && !tags && !combobox,
|
||||
'`Select[multiple|tags|combobox]` is deprecated, please use `Select[mode]` instead.',
|
||||
);
|
||||
|
||||
const cls = classNames({
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
}, className);
|
||||
|
||||
const { antLocale } = this.context;
|
||||
if (antLocale && antLocale.Select) {
|
||||
notFoundContent = ('notFoundContent' in this.props)
|
||||
? notFoundContent : antLocale.Select.notFoundContent;
|
||||
}
|
||||
|
||||
if (combobox) {
|
||||
const locale = this.getLocale();
|
||||
let { notFoundContent = locale.notFoundContent, optionLabelProp } = this.props;
|
||||
const isCombobox = mode === 'combobox' || combobox;
|
||||
if (isCombobox) {
|
||||
notFoundContent = null;
|
||||
// children 带 dom 结构时,无法填入输入框
|
||||
optionLabelProp = optionLabelProp || 'value';
|
||||
}
|
||||
|
||||
const modeConfig = {
|
||||
multiple: mode === 'multiple' || multiple,
|
||||
tags: mode === 'tags' || tags,
|
||||
combobox: isCombobox,
|
||||
};
|
||||
|
||||
return (
|
||||
<RcSelect
|
||||
{...this.props}
|
||||
{...restProps}
|
||||
{...modeConfig}
|
||||
prefixCls={prefixCls}
|
||||
className={cls}
|
||||
optionLabelProp={optionLabelProp || 'children'}
|
||||
notFoundContent={notFoundContent}
|
||||
|
||||
@@ -26,10 +26,12 @@ title: Select
|
||||
|----------|----------------|----------|--------------|
|
||||
| value | 指定当前选中的条目 | string\|string[] | - |
|
||||
| defaultValue | 指定默认选中的条目 | string\|string[] | - |
|
||||
| multiple | 支持多选 | boolean | false |
|
||||
| allowClear | 支持清除, 单选模式有效 | boolean | false |
|
||||
| mode | 设置 Select 的模式(2.9 之后支持) | 'multiple' \| 'tags' \| 'combobox' | - |
|
||||
| multiple | 支持多选(2.9 之后废弃) | boolean | false |
|
||||
| tags | 可以把随意输入的条目作为 tag,输入项不需要与下拉选项匹配(2.9 之后废弃) | boolean |false |
|
||||
| combobox | 输入框自动提示模式(2.9 之后废弃) | boolean | false |
|
||||
| allowClear | 支持清除 | boolean | false |
|
||||
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true |
|
||||
| tags | 可以把随意输入的条目作为 tag,输入项不需要与下拉选项匹配 | boolean |false |
|
||||
| onSelect | 被选中时调用,参数为选中项的 value (或 key) 值 | function(value, option) | - |
|
||||
| onDeselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(value) | - |
|
||||
| onChange | 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数 | function(value) | - |
|
||||
@@ -41,7 +43,6 @@ title: Select
|
||||
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true |
|
||||
| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索 | string | value |
|
||||
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` (combobox 模式下为 `value`) |
|
||||
| combobox | 输入框自动提示模式 | boolean | false |
|
||||
| size | 选择框大小,可选 `large` `small` | string | default |
|
||||
| showSearch | 在选择框中显示搜索框 | boolean | false |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user