mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 10:59:19 +08:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9368e2df87 | ||
|
|
7f8cb838e3 | ||
|
|
0f7794946f | ||
|
|
f4b8a58480 | ||
|
|
6019245365 | ||
|
|
3fd9397174 | ||
|
|
f1e38a1573 | ||
|
|
013df45a70 | ||
|
|
5ee4d20e2a | ||
|
|
c9017b6c6c | ||
|
|
05e702a2b4 | ||
|
|
8e166915a9 | ||
|
|
9c6fef0604 | ||
|
|
b6f8ab89c7 | ||
|
|
56e3384c6b | ||
|
|
b5a52d26f2 | ||
|
|
70a42545e3 | ||
|
|
fb38e55cc0 | ||
|
|
c7471a4653 | ||
|
|
726f0466bc | ||
|
|
a4261f9344 | ||
|
|
0616b05583 | ||
|
|
d0c3752a4e | ||
|
|
3a5fce7256 | ||
|
|
74e36325a2 | ||
|
|
3a3d550b54 | ||
|
|
013932e6d3 | ||
|
|
cd6ad64cab | ||
|
|
81dd432e31 | ||
|
|
4535e9d4f1 | ||
|
|
4956dd8042 | ||
|
|
548d8c9c51 | ||
|
|
8b64882562 | ||
|
|
6682a56922 | ||
|
|
e97977b891 | ||
|
|
b45146486a | ||
|
|
8b02a21d36 | ||
|
|
be43e56835 | ||
|
|
7f8f89cbff | ||
|
|
a1e186b8a3 | ||
|
|
3d079af7cd | ||
|
|
1f6107e94a | ||
|
|
e40c2a7f45 | ||
|
|
d9053a2526 | ||
|
|
4b1857d587 | ||
|
|
b1c41c665e | ||
|
|
c85758fd01 | ||
|
|
52c8f34a73 | ||
|
|
4ea20e696c | ||
|
|
a268dc8d62 | ||
|
|
262ed8eec3 | ||
|
|
4bc28ac471 | ||
|
|
4101d182e0 | ||
|
|
14dbcb95ed | ||
|
|
14fa376dff | ||
|
|
6a3e6f55cf | ||
|
|
fa5491a390 | ||
|
|
4ad5985df7 | ||
|
|
bb720aaab9 | ||
|
|
8ab4aeb9c4 | ||
|
|
e444dc5e39 | ||
|
|
b9d94971e4 | ||
|
|
d50ec436d5 | ||
|
|
e1c74eb799 | ||
|
|
d016471638 | ||
|
|
754c94c447 | ||
|
|
74d1c5e6b6 | ||
|
|
04a5cc2a8b | ||
|
|
b52053051c | ||
|
|
74d81c2d07 |
14
.github/lock.yml
vendored
Normal file
14
.github/lock.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Configuration for lock-threads - https://github.com/dessant/lock-threads
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 365
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: >
|
||||
This thread has been automatically locked because it has not had recent
|
||||
activity. Please open a new issue for related bugs and link to relevant
|
||||
comments in this thread.
|
||||
# Issues or pull requests with these labels will not be locked
|
||||
# exemptLabels:
|
||||
# - no-locking
|
||||
# Limit to only `issues` or `pulls`
|
||||
only: issues
|
||||
@@ -15,6 +15,65 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.5.0
|
||||
|
||||
`2018-05-04`
|
||||
|
||||
- 🌟 Add `title` prop to `Badge` that shows when hovering it. [74d81c2](https://github.com/ant-design/ant-design/commit/74d81c2d078a3c84b3e44cbfbdd99b8f479ea71d) [@ludwigbacklund](https://github.com/ludwigbacklund)
|
||||
- 🌟 Add `successPercent` as `Progress[format]` argument. [#10096](https://github.com/ant-design/ant-design/issues/10096)
|
||||
- 🌟 Update `rc-notification` to 3.1.0 so that `Notification` support set `maxCount`. [#10161](https://github.com/ant-design/ant-design/pull/10161) [@jzhangs](https://github.com/jzhangs)
|
||||
- 🌟 Update `rc-cascader` to 1.13.0 so that `Cascader` support set `filedNames`. [react-component/cascader#23](https://github.com/react-component/cascader/pull/23) [@405go](https://github.com/405go)
|
||||
- 🌟 Add ability to update `Notification` props by key. [react-component/notification#40](https://github.com/react-component/notification/pull/40) [@yevhen-hryhorevskyi](https://github.com/yevhen-hryhorevskyi)
|
||||
- 🌟 `List` support pagination by default. [#10135](https://github.com/ant-design/ant-design/pull/10135)
|
||||
- Table
|
||||
- 🌟 Column `sorter` function is passed `sortOrder` as param. [#10306](https://github.com/ant-design/ant-design/pull/10306) [@kumarashwin](https://github.com/kumarashwin)
|
||||
- 🐞 Fix merged header cell border. [#10359](https://github.com/ant-design/ant-design/issues/10359)
|
||||
- 🐞 Fix lost of user selection on data updates. [#10332](https://github.com/ant-design/ant-design/pull/10332) [@chrvadala](https://github.com/chrvadala)
|
||||
- `Menu` upgrade `rc-menu` to `7.x` [#10305](https://github.com/ant-design/ant-design/pull/10305)
|
||||
- 🌟 Better aria-* attributes support. [react-component/menu#137](https://github.com/react-component/menu/pull/137)
|
||||
- 🌟 Improve Menu performance by avoiding unnecessary updates. [react-component/menu#133](https://github.com/react-component/menu/pull/133)
|
||||
- 🌟 Support passing props through to MenuItem list item. [react-component/menu#135](https://github.com/react-component/menu/pull/135)
|
||||
- 🐞 Minor key shortcut bug fixes. [react-component/menu#132](https://github.com/react-component/menu/pull/132)
|
||||
- Collapse
|
||||
- 🌟 Support custom `Collapse` styles with less. [#9943](https://github.com/ant-design/ant-design/pull/9943) [@davidhatten](https://github.com/davidhatten)
|
||||
- 🌟 Update `rc-collapse` to 1.9.0 to add `Collapse` keyboard support. [react-component/collapse#84](https://github.com/react-component/collapse/pull/84/) [@kossel](https://github.com/kossel)
|
||||
- Select
|
||||
- 🐞 Fix type for `placeholder`. [#10282](https://github.com/ant-design/ant-design/pull/10282) [@thomasthiebaud](https://github.com/thomasthiebaud)
|
||||
- 🐞 Fix extra space taken up when arrow disabled. [#10296](https://github.com/ant-design/ant-design/pull/10296)
|
||||
- 🐞 Fix property `value` typescript type. [#10336](https://github.com/ant-design/ant-design/pull/10336) [@paranoidjk](https://github.com/paranoidjk)
|
||||
- Input
|
||||
- 🐞 Fix `Input.Search` not disable enter button when disabled prop is true. [#10040](https://github.com/ant-design/ant-design/issues/10040)
|
||||
- 🐞 Fix `Input.Group` align issue in Form. [#10281](https://github.com/ant-design/ant-design/issues/10281)
|
||||
- Form
|
||||
- 🐞 Fix typing for `Form.onValuesChange`. [#10231](https://github.com/ant-design/ant-design/pull/10231) [@whtsky](https://github.com/whtsky)
|
||||
- 🐞 Fix typescript interface `ComponentDecorator`. [#10324](https://github.com/ant-design/ant-design/pull/10324) [@paranoidjk](https://github.com/paranoidjk)
|
||||
- 🐞 Fix dashed `Divider`. [#10216](https://github.com/ant-design/ant-design/issues/10216)
|
||||
- 🐞 Fix `Spin` container interaction. [#10227](https://github.com/ant-design/ant-design/issues/10227)
|
||||
- 🐞 Fix `Notification` icon hover color. [#10272](https://github.com/ant-design/ant-design/issues/10272)
|
||||
- 🐞 Fix `Upload` property `lastModifiedDate` name. [#10315](https://github.com/ant-design/ant-design/pull/10315) [@danielg2002](https://github.com/danielg2002)
|
||||
- 🐞 Fix `Button` props type, use `React.HTMLProps`. [#10229](https://github.com/ant-design/ant-design/pull/10229) [@whtsky](https://github.com/whtsky)
|
||||
- 🐞 Fix less var naming convention. [#10275](https://github.com/ant-design/ant-design/issues/10275)
|
||||
|
||||
## 3.4.5
|
||||
|
||||
`2018-05-03`
|
||||
|
||||
- 🐞 Fix file object is empty and file name not showing in Upload. [#10319](https://github.com/ant-design/ant-design/issues/10319)
|
||||
|
||||
## 3.4.4
|
||||
|
||||
`2018-04-28`
|
||||
|
||||
- 🐞 Fix that Upload file in`onChange({ file })` is not a File instance introduced in `3.4.2`. [#10293](https://github.com/ant-design/ant-design/issues/10293)
|
||||
- 🐞 Fix style lose bug when use tree shaking in webpack@4. [#10217](https://github.com/ant-design/ant-design/pull/10217) [@whtsky](https://github.com/whtsky)
|
||||
|
||||
## 3.4.3
|
||||
|
||||
`2018-04-23`
|
||||
|
||||
- 🐞 Fix style lose bug when use tree shaking in webpack@4. [#10197](https://github.com/ant-design/ant-design/pull/10197) [@Aladdin-ADD](https://github.com/Aladdin-ADD)
|
||||
- 🐞 Fix `Menu` item's clickable region in dark theme. [#10187](https://github.com/ant-design/ant-design/pull/10187) [@dgeibi ](https://github.com/dgeibi )
|
||||
|
||||
## 3.4.2
|
||||
|
||||
`2018-04-22`
|
||||
|
||||
@@ -15,6 +15,65 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.5.0
|
||||
|
||||
`2018-05-04`
|
||||
|
||||
- 🌟 组件 `Badge` 新增 `title` 属性支持鼠标 hover 的时候显示。[74d81c2](https://github.com/ant-design/ant-design/commit/74d81c2d078a3c84b3e44cbfbdd99b8f479ea71d) [@ludwigbacklund](https://github.com/ludwigbacklund)
|
||||
- 🌟 添加 `successPercent` 为 `Progress[format]` 的参数。[#10096](https://github.com/ant-design/ant-design/issues/10096)
|
||||
- 🌟 更新 `rc-notification` 到 3.1.0 来支持组件 `Notification` 的 `maxCount` 属性。[#10161](https://github.com/ant-design/ant-design/pull/10161) [@jzhangs](https://github.com/jzhangs)
|
||||
- 🌟 更新 `rc-cascader` 到 1.13.0 来支持组件 `Cascader` 的 `filedNames` 属性。[react-component/cascader#23](https://github.com/react-component/cascader/pull/23) [@405go](https://github.com/405go)
|
||||
- 🌟 组件 `Notification` 支持通过 key 更新通知属性。 [react-component/notification#40](https://github.com/react-component/notification/pull/40) [@yevhen-hryhorevskyi](https://github.com/yevhen-hryhorevskyi)
|
||||
- 🌟 组件 `List` 支持内置的翻页功能。[#10135](https://github.com/ant-design/ant-design/pull/10135)
|
||||
- Table
|
||||
- 🌟 新增 `sortOrder` 参数传递给列配置中的 `sorter` 方法。[#10306](https://github.com/ant-design/ant-design/pull/10306) [@kumarashwin](https://github.com/kumarashwin)
|
||||
- 🐞 修复头部单元格的边框样式问题。[#10359](https://github.com/ant-design/ant-design/issues/10359)
|
||||
- 🐞 修复当数据变化时用户选择项丢失的问题。[#10332](https://github.com/ant-design/ant-design/pull/10332) [@chrvadala](https://github.com/chrvadala)
|
||||
- `Menu` 升级 `rc-menu` 到 `7.x` [#10305](https://github.com/ant-design/ant-design/pull/10305)
|
||||
- 🌟 更好的 aria-* 属性支持。[react-component/menu#137](https://github.com/react-component/menu/pull/137)
|
||||
- 🌟 一些内部优化提升组件性能。[react-component/menu#133](https://github.com/react-component/menu/pull/133)
|
||||
- 🌟 支持将属性传递到菜单项中。[react-component/menu#135](https://github.com/react-component/menu/pull/135)
|
||||
- 🐞 修复一些快捷键的问题。[react-component/menu#132](https://github.com/react-component/menu/pull/132)
|
||||
- Collapse
|
||||
- 🌟 更新 `rc-collapse` 到 1.9.0 优化键盘支持。[react-component/collapse#84](https://github.com/react-component/collapse/pull/84/) [@kossel](https://github.com/kossel)
|
||||
- 🌟 支持通过 less 定义组件 `Collapse` 的样式。[#9943](https://github.com/ant-design/ant-design/pull/9943) [@davidhatten](https://github.com/davidhatten)
|
||||
- Select
|
||||
- 🐞 修复 `placeholder` 的 ts 类型问题。[#10282](https://github.com/ant-design/ant-design/pull/10282) [@thomasthiebaud](https://github.com/thomasthiebaud)
|
||||
- 🐞 修复不显示箭头时多余的空白。[#10296](https://github.com/ant-design/ant-design/pull/10296)
|
||||
- 🐞 修复属性 `value` 的 typescript 类型错误。[#10336](https://github.com/ant-design/ant-design/pull/10336) [@paranoidjk](https://github.com/paranoidjk)
|
||||
- Input
|
||||
- 🐞 修复 `Input.Search` 当 disabled 为 true 时按钮没有被禁用的问题。[#10040](https://github.com/ant-design/ant-design/issues/10040)
|
||||
- 🐞 修复 `Input.Group` 在表单中对齐的问题。[#10281](https://github.com/ant-design/ant-design/issues/10281)
|
||||
- Form
|
||||
- 🐞 修复 `Form.onValuesChange` 的 ts 类型错误。[#10231](https://github.com/ant-design/ant-design/pull/10231) [@whtsky](https://github.com/whtsky)
|
||||
- 🐞 修复 `ComponentDecorator` typescript 定义的错误。[#10324](https://github.com/ant-design/ant-design/pull/10324) [@paranoidjk](https://github.com/paranoidjk)
|
||||
- 🐞 修复 `Divider` 为 dashed 时的样式问题。[#10216](https://github.com/ant-design/ant-design/issues/10216)
|
||||
- 🐞 修复 `Spin` 覆盖层的展示问题。[#10227](https://github.com/ant-design/ant-design/issues/10227)
|
||||
- 🐞 修复 `Notification` 鼠标 hover 是图标的颜色问题。[#10272](https://github.com/ant-design/ant-design/issues/10272)
|
||||
- 🐞 修复 `Upload` 组件属性 `lastModifiedDate` 的拼写错误。[#10315](https://github.com/ant-design/ant-design/pull/10315) [@danielg2002](https://github.com/danielg2002)
|
||||
- 🐞 修复 `Button` 的属性类型,使用 `React.HTMLProps`。[#10229](https://github.com/ant-design/ant-design/pull/10229) [@whtsky](https://github.com/whtsky)
|
||||
- 🐞 修复 less 命名约定不一致的问题。 [#10275](https://github.com/ant-design/ant-design/issues/10275)
|
||||
|
||||
## 3.4.5
|
||||
|
||||
`2018-05-03`
|
||||
|
||||
- 🐞 修复 Upload 上传文件名不展示(file 对象属性为空)的问题。[#10319](https://github.com/ant-design/ant-design/issues/10319)
|
||||
|
||||
## 3.4.4
|
||||
|
||||
`2018-04-28`
|
||||
|
||||
- 🐞 修复 3.4.2 中引入的 Upload 中 onChange 参数 `{ file }` file 不是 File 实例的问题。[#10293](https://github.com/ant-design/ant-design/issues/10293)
|
||||
- 🐞 修复 webpack@4 下使用 Tree Shaking 样式丢失的问题。[#10217](https://github.com/ant-design/ant-design/pull/10217) [@whtsky](https://github.com/whtsky)
|
||||
|
||||
## 3.4.3
|
||||
|
||||
`2018-04-23`
|
||||
|
||||
- 🐞 修复了 webpack@4 下使用 Tree Shaking 样式丢失的问题。[#10197](https://github.com/ant-design/ant-design/pull/10197) [@Aladdin-ADD](https://github.com/Aladdin-ADD)
|
||||
- 🐞 修复 `Menu` 组件在 `dark` 主题下点击区域的问题。[#10187](https://github.com/ant-design/ant-design/pull/10187) [@dgeibi](https://github.com/dgeibi)
|
||||
|
||||
## 3.4.2
|
||||
|
||||
`2018-04-22`
|
||||
|
||||
@@ -19,7 +19,7 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
@@ -47,7 +47,7 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -78,7 +78,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
@@ -117,7 +117,7 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -166,7 +166,7 @@ exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -193,7 +193,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
try to type \`b\`
|
||||
</div>
|
||||
@@ -221,7 +221,7 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -248,7 +248,7 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
@@ -276,7 +276,7 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -307,7 +307,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
@@ -351,7 +351,7 @@ exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
@@ -1617,3 +1617,177 @@ exports[`renders ./components/badge/demo/status.md correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/badge/demo/title.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="ant-badge"
|
||||
>
|
||||
<a
|
||||
class="head-example"
|
||||
href="#"
|
||||
/>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
data-show="true"
|
||||
title="Custom hover text"
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1500%);-webkit-transform:translateY(-1500%);transform:translateY(-1500%)"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
0
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
1
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
2
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
3
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
4
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
5
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
6
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
7
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
8
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
9
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
0
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
1
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
2
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
3
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
4
|
||||
</p>
|
||||
<p
|
||||
class="current"
|
||||
>
|
||||
5
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
6
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
7
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
8
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
9
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
0
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
1
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
2
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
3
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
4
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
5
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
6
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
7
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
8
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
9
|
||||
</p>
|
||||
</span>
|
||||
</sup>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -7,8 +7,14 @@ describe('Badge', () => {
|
||||
const badge = mount(<Badge count={10} dot />);
|
||||
expect(badge.find('.ant-card-multiple-words').length).toBe(0);
|
||||
});
|
||||
|
||||
test('badge dot not showing count == 0', () => {
|
||||
const badge = mount(<Badge count={0} dot />);
|
||||
expect(badge.find('.ant-badge-dot').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should have an overriden title attribute', () => {
|
||||
const badge = mount(<Badge count={10} title="Custom title" />);
|
||||
expect(badge.find('.ant-scroll-number').getDOMNode().attributes.getNamedItem('title').value).toEqual('Custom title');
|
||||
});
|
||||
});
|
||||
|
||||
39
components/badge/demo/title.md
Normal file
39
components/badge/demo/title.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
order: 7
|
||||
title:
|
||||
zh-CN: 自定义标题
|
||||
en-US: Title
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
设置鼠标放在状态点上时显示的文字
|
||||
|
||||
## en-US
|
||||
|
||||
The badge will display `title` when hovered over, instead of `count`.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Badge count={5} title="Custom hover text">
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
.ant-badge:not(.ant-badge-status) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.head-example {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 4px;
|
||||
background: #eee;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
@@ -31,3 +31,4 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
|
||||
| showZero | Whether to show badge when `count` is zero | boolean | `false` |
|
||||
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` |
|
||||
| text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` |
|
||||
| title | Text to show when hovering over the badge | string | `count` |
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface BadgeProps {
|
||||
status?: 'success' | 'processing' | 'default' | 'error' | 'warning';
|
||||
text?: string;
|
||||
offset?: [number | string, number | string];
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export default class Badge extends React.Component<BadgeProps, any> {
|
||||
@@ -57,6 +58,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
status,
|
||||
text,
|
||||
offset,
|
||||
title,
|
||||
...restProps,
|
||||
} = this.props;
|
||||
let displayCount = (count as number) > (overflowCount as number) ? `${overflowCount}+` : count;
|
||||
@@ -103,7 +105,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
data-show={!hidden}
|
||||
className={scrollNumberCls}
|
||||
count={displayCount}
|
||||
title={count}
|
||||
title={title || count}
|
||||
style={styleWithOffset}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -32,3 +32,4 @@ title: Badge
|
||||
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false |
|
||||
| status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' |
|
||||
| title | 设置鼠标放在状态点上时显示的文字 | string | `count` |
|
||||
|
||||
@@ -66,6 +66,48 @@ exports[`Button renders Chinese characters correctly 3`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button renders Chinese characters correctly 4`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-search"
|
||||
/>
|
||||
<span>
|
||||
按钮
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button renders Chinese characters correctly 5`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-loading"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-spin anticon-loading"
|
||||
/>
|
||||
<span>
|
||||
按钮
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button renders Chinese characters correctly 6`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-loading"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-spin anticon-loading"
|
||||
/>
|
||||
<span>
|
||||
按 钮
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button renders correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn"
|
||||
|
||||
@@ -26,6 +26,21 @@ describe('Button', () => {
|
||||
<Button><Icon type="search" />按钮</Button>
|
||||
);
|
||||
expect(wrapper2).toMatchSnapshot();
|
||||
// should not insert space when there is icon
|
||||
const wrapper3 = render(
|
||||
<Button icon="search">按钮</Button>
|
||||
);
|
||||
expect(wrapper3).toMatchSnapshot();
|
||||
// should not insert space when there is icon while loading
|
||||
const wrapper4 = render(
|
||||
<Button icon="search" loading>按钮</Button>
|
||||
);
|
||||
expect(wrapper4).toMatchSnapshot();
|
||||
// should insert space while loading
|
||||
const wrapper5 = render(
|
||||
<Button loading>按钮</Button>
|
||||
);
|
||||
expect(wrapper5).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders Chinese characters correctly in HOC', () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import Icon from '../icon';
|
||||
import { Omit } from '../_util/type';
|
||||
import Group from './button-group';
|
||||
|
||||
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
|
||||
@@ -38,29 +39,26 @@ export type ButtonType = 'default' | 'primary' | 'ghost' | 'dashed' | 'danger';
|
||||
export type ButtonShape = 'circle' | 'circle-outline';
|
||||
export type ButtonSize = 'small' | 'default' | 'large';
|
||||
|
||||
export interface ButtonProps {
|
||||
export interface BaseButtonProps<T> extends Omit<React.HTMLProps<T>, 'size'> {
|
||||
type?: ButtonType;
|
||||
htmlType?: string;
|
||||
icon?: string;
|
||||
shape?: ButtonShape;
|
||||
size?: ButtonSize;
|
||||
onClick?: React.FormEventHandler<any>;
|
||||
onMouseUp?: React.FormEventHandler<any>;
|
||||
onMouseDown?: React.FormEventHandler<any>;
|
||||
onKeyPress?: React.KeyboardEventHandler<any>;
|
||||
onKeyDown?: React.KeyboardEventHandler<any>;
|
||||
tabIndex?: number;
|
||||
loading?: boolean | { delay?: number };
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
ghost?: boolean;
|
||||
target?: string;
|
||||
href?: string;
|
||||
download?: string;
|
||||
}
|
||||
|
||||
export interface AnchorButtonProps extends BaseButtonProps<HTMLAnchorElement> {
|
||||
href: string;
|
||||
}
|
||||
|
||||
export interface NativeButtonProps extends BaseButtonProps<HTMLButtonElement> {}
|
||||
|
||||
export type ButtonProps = AnchorButtonProps | NativeButtonProps;
|
||||
|
||||
export default class Button extends React.Component<ButtonProps, any> {
|
||||
static Group: typeof Group;
|
||||
static __ANT_BUTTON = true;
|
||||
@@ -143,7 +141,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
}
|
||||
}
|
||||
|
||||
handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
handleClick = (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
|
||||
// Add click effect
|
||||
this.setState({ clicked: true });
|
||||
clearTimeout(this.timeout);
|
||||
@@ -151,14 +149,13 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
|
||||
const onClick = this.props.onClick;
|
||||
if (onClick) {
|
||||
onClick(e);
|
||||
(onClick as (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void)(e);
|
||||
}
|
||||
}
|
||||
|
||||
isNeedInserted() {
|
||||
const { loading, icon, children } = this.props;
|
||||
const iconType = loading ? 'loading' : icon;
|
||||
return React.Children.count(children) === 1 && (!iconType || iconType === 'loading');
|
||||
const { icon, children } = this.props;
|
||||
return React.Children.count(children) === 1 && !icon;
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -181,7 +178,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
break;
|
||||
}
|
||||
|
||||
const ComponentProp = others.href ? 'a' : 'button';
|
||||
const ComponentProp = (others as AnchorButtonProps).href ? 'a' : 'button';
|
||||
|
||||
const classes = classNames(prefixCls, className, {
|
||||
[`${prefixCls}-${type}`]: type,
|
||||
@@ -202,7 +199,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
return (
|
||||
<ComponentProp
|
||||
{...omit(others, ['loading'])}
|
||||
type={others.href ? undefined : (htmlType || 'button')}
|
||||
type={(others as AnchorButtonProps).href ? undefined : (htmlType || 'button')}
|
||||
className={classes}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
|
||||
@@ -33,7 +33,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -65,7 +65,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -1042,7 +1042,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -1074,7 +1074,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -2049,7 +2049,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -2081,7 +2081,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -3466,7 +3466,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -3498,7 +3498,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
152
components/card/__tests__/__snapshots__/index.test.js.snap
Normal file
152
components/card/__tests__/__snapshots__/index.test.js.snap
Normal file
@@ -0,0 +1,152 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Card should still have padding when card which set padding to 0 is loading 1`] = `
|
||||
<div
|
||||
class="ant-card ant-card-loading ant-card-bordered"
|
||||
>
|
||||
<div
|
||||
class="ant-card-body"
|
||||
style="padding: 0px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-content"
|
||||
style="padding: 24px;"
|
||||
>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left: -4px; margin-right: -4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-col-22"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left: -4px; margin-right: -4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-col-8"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-15"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left: -4px; margin-right: -4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-col-6"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-18"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left: -4px; margin-right: -4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-col-13"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-9"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left: -4px; margin-right: -4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-col-4"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-3"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-16"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row"
|
||||
style="margin-left: -4px; margin-right: -4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-col-8"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-6"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col-8"
|
||||
style="padding-left: 4px; padding-right: 4px;"
|
||||
>
|
||||
<div
|
||||
class="ant-card-loading-block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -34,4 +34,9 @@ describe('Card', () => {
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-card-wider-padding').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should still have padding when card which set padding to 0 is loading', () => {
|
||||
const wrapper = mount(<Card loading bodyStyle={{ padding: 0 }}>xxx</Card>);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -133,7 +133,7 @@ export default class Card extends React.Component<CardProps, CardState> {
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
prefixCls = 'ant-card', className, extra, bodyStyle, noHovering, hoverable, title, loading,
|
||||
prefixCls = 'ant-card', className, extra, bodyStyle = {}, noHovering, hoverable, title, loading,
|
||||
bordered = true, type, cover, actions, tabList, children, activeTabKey, defaultActiveTabKey, ...others,
|
||||
} = this.props;
|
||||
|
||||
@@ -148,8 +148,14 @@ export default class Card extends React.Component<CardProps, CardState> {
|
||||
[`${prefixCls}-type-${type}`]: !!type,
|
||||
});
|
||||
|
||||
const loadingBlockStyle = (bodyStyle.padding === 0 || bodyStyle.padding === '0px')
|
||||
? { padding: 24 } : undefined;
|
||||
|
||||
const loadingBlock = (
|
||||
<div className={`${prefixCls}-loading-content`}>
|
||||
<div
|
||||
className={`${prefixCls}-loading-content`}
|
||||
style={loadingBlockStyle}
|
||||
>
|
||||
<Row gutter={8}>
|
||||
<Col span={22}>
|
||||
<div className={`${prefixCls}-loading-block`} />
|
||||
|
||||
@@ -143,6 +143,28 @@ exports[`renders ./components/cascader/demo/disabled-option.md correctly 1`] = `
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/fileds-name.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-cascader-picker"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="ant-cascader-picker-label"
|
||||
/>
|
||||
<input
|
||||
autocomplete="off"
|
||||
class="ant-input ant-cascader-input "
|
||||
placeholder="Please select"
|
||||
readonly=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<i
|
||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
||||
/>
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/hover.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-cascader-picker"
|
||||
|
||||
50
components/cascader/demo/fileds-name.md
Normal file
50
components/cascader/demo/fileds-name.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
order: 10
|
||||
title:
|
||||
zh-CN: 自定义字段名
|
||||
en-US: Custom Filed Names
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
自定义字段名。
|
||||
|
||||
## en-US
|
||||
|
||||
Custom filed names.
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
code: 'zhejiang',
|
||||
name: 'Zhejiang',
|
||||
items: [{
|
||||
code: 'hangzhou',
|
||||
name: 'Hangzhou',
|
||||
items: [{
|
||||
code: 'xihu',
|
||||
name: 'West Lake',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
code: 'jiangsu',
|
||||
name: 'Jiangsu',
|
||||
items: [{
|
||||
code: 'nanjing',
|
||||
name: 'Nanjing',
|
||||
items: [{
|
||||
code: 'zhonghuamen',
|
||||
name: 'Zhong Hua Men',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader filedNames={{ label: 'name', value: 'code', children: 'items' }} options={options} onChange={onChange} placeholder="Please select" />
|
||||
, mountNode);
|
||||
````
|
||||
@@ -42,6 +42,7 @@ Cascade selection box.
|
||||
| value | selected value | string\[] | - |
|
||||
| onChange | callback when finishing cascader select | `(value, selectedOptions) => void` | - |
|
||||
| onPopupVisibleChange | callback when popup shown or hidden | `(value) => void` | - |
|
||||
| filedNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
|
||||
Fields in `showSearch`:
|
||||
|
||||
|
||||
@@ -8,19 +8,37 @@ import Input from '../input';
|
||||
import Icon from '../icon';
|
||||
|
||||
export interface CascaderOptionType {
|
||||
value: string;
|
||||
label: React.ReactNode;
|
||||
value?: string;
|
||||
label?: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
children?: Array<CascaderOptionType>;
|
||||
__IS_FILTERED_OPTION?: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface FiledNamesType {
|
||||
value?: string;
|
||||
label?: string;
|
||||
children?: string;
|
||||
}
|
||||
|
||||
export interface FilledFiledNamesType {
|
||||
value: string;
|
||||
label: string;
|
||||
children: string;
|
||||
}
|
||||
|
||||
export type CascaderExpandTrigger = 'click' | 'hover';
|
||||
|
||||
export interface ShowSearchType {
|
||||
filter?: (inputValue: string, path: CascaderOptionType[]) => boolean;
|
||||
render?: (inputValue: string, path: CascaderOptionType[], prefixCls: string | undefined) => React.ReactNode;
|
||||
sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string) => number;
|
||||
filter?: (inputValue: string, path: CascaderOptionType[], names: FilledFiledNamesType) => boolean;
|
||||
render?: (
|
||||
inputValue: string,
|
||||
path: CascaderOptionType[],
|
||||
prefixCls: string | undefined,
|
||||
names: FilledFiledNamesType,
|
||||
) => React.ReactNode;
|
||||
sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string, names: FilledFiledNamesType) => number;
|
||||
matchInputWidth?: boolean;
|
||||
}
|
||||
|
||||
@@ -64,6 +82,7 @@ export interface CascaderProps {
|
||||
inputPrefixCls?: string;
|
||||
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||
popupVisible?: boolean;
|
||||
filedNames?: FiledNamesType;
|
||||
}
|
||||
|
||||
export interface CascaderState {
|
||||
@@ -82,26 +101,41 @@ function highlightKeyword(str: string, keyword: string, prefixCls: string | unde
|
||||
]);
|
||||
}
|
||||
|
||||
function defaultFilterOption(inputValue: string, path: CascaderOptionType[]) {
|
||||
return path.some(option => (option.label as string).indexOf(inputValue) > -1);
|
||||
function defaultFilterOption(inputValue: string, path: CascaderOptionType[], names: FilledFiledNamesType) {
|
||||
return path.some(option => (option[names.label] as string).indexOf(inputValue) > -1);
|
||||
}
|
||||
|
||||
function defaultRenderFilteredOption(inputValue: string, path: CascaderOptionType[], prefixCls: string | undefined) {
|
||||
return path.map(({ label }, index) => {
|
||||
function defaultRenderFilteredOption(
|
||||
inputValue: string,
|
||||
path: CascaderOptionType[],
|
||||
prefixCls: string | undefined,
|
||||
names: FilledFiledNamesType,
|
||||
) {
|
||||
return path.map((option, index) => {
|
||||
const label = option[names.label];
|
||||
const node = (label as string).indexOf(inputValue) > -1 ?
|
||||
highlightKeyword(label as string, inputValue, prefixCls) : label;
|
||||
return index === 0 ? node : [' / ', node];
|
||||
});
|
||||
}
|
||||
|
||||
function defaultSortFilteredOption(a: any[], b: any[], inputValue: string) {
|
||||
function defaultSortFilteredOption(a: any[], b: any[], inputValue: string, names: FilledFiledNamesType) {
|
||||
function callback(elem: CascaderOptionType) {
|
||||
return (elem.label as string).indexOf(inputValue) > -1;
|
||||
return (elem[names.label] as string).indexOf(inputValue) > -1;
|
||||
}
|
||||
|
||||
return a.findIndex(callback) - b.findIndex(callback);
|
||||
}
|
||||
|
||||
function getFilledFieldNames(filedNames: FiledNamesType = {}) {
|
||||
const names: FilledFiledNamesType = {
|
||||
children: filedNames.children || 'children',
|
||||
label: filedNames.label || 'label',
|
||||
value: filedNames.value || 'value',
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
const defaultDisplayRender = (label: string[]) => label.join(' / ');
|
||||
|
||||
export default class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||
@@ -128,7 +162,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
inputValue: '',
|
||||
inputFocused: false,
|
||||
popupVisible: props.popupVisible,
|
||||
flattenOptions: props.showSearch && this.flattenTree(props.options, props.changeOnSelect),
|
||||
flattenOptions: props.showSearch && this.flattenTree(props.options, props.changeOnSelect, props.filedNames),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -140,7 +174,9 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
this.setState({ popupVisible: nextProps.popupVisible });
|
||||
}
|
||||
if (nextProps.showSearch && this.props.options !== nextProps.options) {
|
||||
this.setState({ flattenOptions: this.flattenTree(nextProps.options, nextProps.changeOnSelect) });
|
||||
this.setState({
|
||||
flattenOptions: this.flattenTree(nextProps.options, nextProps.changeOnSelect, nextProps.filedNames),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,13 +243,14 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
}
|
||||
|
||||
getLabel() {
|
||||
const { options, displayRender = defaultDisplayRender as Function } = this.props;
|
||||
const { options, displayRender = defaultDisplayRender as Function, filedNames } = this.props;
|
||||
const names = getFilledFieldNames(filedNames);
|
||||
const value = this.state.value;
|
||||
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
||||
const selectedOptions: CascaderOptionType[] = arrayTreeFilter(options,
|
||||
(o: CascaderOptionType, level: number) => o.value === unwrappedValue[level],
|
||||
(o: CascaderOptionType, level: number) => o[names.value] === unwrappedValue[level],
|
||||
);
|
||||
const label = selectedOptions.map(o => o.label);
|
||||
const label = selectedOptions.map(o => o[names.label]);
|
||||
return displayRender(label, selectedOptions);
|
||||
}
|
||||
|
||||
@@ -228,43 +265,58 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
}
|
||||
}
|
||||
|
||||
flattenTree(options: CascaderOptionType[], changeOnSelect: boolean | undefined, ancestor: CascaderOptionType[] = []) {
|
||||
flattenTree(
|
||||
options: CascaderOptionType[],
|
||||
changeOnSelect: boolean | undefined,
|
||||
filedNames: FiledNamesType | undefined,
|
||||
ancestor: CascaderOptionType[] = [],
|
||||
) {
|
||||
const names: FiledNamesType = getFilledFieldNames(filedNames);
|
||||
let flattenOptions: any = [];
|
||||
let childrenName: any = names.children;
|
||||
options.forEach((option) => {
|
||||
const path = ancestor.concat(option);
|
||||
if (changeOnSelect || !option.children || !option.children.length) {
|
||||
if (changeOnSelect || !option[childrenName] || !option[childrenName].length) {
|
||||
flattenOptions.push(path);
|
||||
}
|
||||
if (option.children) {
|
||||
flattenOptions = flattenOptions.concat(this.flattenTree(option.children, changeOnSelect, path));
|
||||
if (option[childrenName]) {
|
||||
flattenOptions = flattenOptions.concat(
|
||||
this.flattenTree(
|
||||
option[childrenName],
|
||||
changeOnSelect,
|
||||
filedNames,
|
||||
path,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
return flattenOptions;
|
||||
}
|
||||
|
||||
generateFilteredOptions(prefixCls: string | undefined) {
|
||||
const { showSearch, notFoundContent } = this.props;
|
||||
const { showSearch, notFoundContent, filedNames } = this.props;
|
||||
const names: FilledFiledNamesType = getFilledFieldNames(filedNames);
|
||||
const {
|
||||
filter = defaultFilterOption,
|
||||
render = defaultRenderFilteredOption,
|
||||
sort = defaultSortFilteredOption,
|
||||
} = showSearch as ShowSearchType;
|
||||
const { flattenOptions, inputValue } = this.state;
|
||||
const filtered = flattenOptions.filter((path) => filter(this.state.inputValue, path))
|
||||
.sort((a, b) => sort(a, b, inputValue));
|
||||
const filtered = flattenOptions.filter((path) => filter(this.state.inputValue, path, names))
|
||||
.sort((a, b) => sort(a, b, inputValue, names));
|
||||
|
||||
if (filtered.length > 0) {
|
||||
return filtered.map((path: any) => {
|
||||
return {
|
||||
__IS_FILTERED_OPTION: true,
|
||||
path,
|
||||
label: render(inputValue, path, prefixCls),
|
||||
value: path.map((o: CascaderOptionType) => o.value),
|
||||
[names.label]: render(inputValue, path, prefixCls, names),
|
||||
[names.value]: path.map((o: CascaderOptionType) => o[names.value]),
|
||||
disabled: path.some((o: CascaderOptionType) => o.disabled),
|
||||
} as CascaderOptionType;
|
||||
});
|
||||
}
|
||||
return [{ label: notFoundContent, value: 'ANT_CASCADER_NOT_FOUND', disabled: true }];
|
||||
return [{ [names.label]: notFoundContent, [names.value]: 'ANT_CASCADER_NOT_FOUND', disabled: true }];
|
||||
}
|
||||
|
||||
focus() {
|
||||
@@ -328,6 +380,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
'renderFilteredOption',
|
||||
'sortFilteredOption',
|
||||
'notFoundContent',
|
||||
'filedNames',
|
||||
]);
|
||||
|
||||
let options = props.options;
|
||||
|
||||
@@ -43,6 +43,7 @@ subtitle: 级联选择
|
||||
| value | 指定选中项 | string\[] | - |
|
||||
| onChange | 选择完成后的回调 | `(value, selectedOptions) => void` | - |
|
||||
| onPopupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - |
|
||||
| filedNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
|
||||
`showSearch` 为对象时,其中的字段:
|
||||
|
||||
|
||||
@@ -3,15 +3,16 @@
|
||||
exports[`renders ./components/collapse/demo/accordion.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-collapse"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -21,12 +22,12 @@ exports[`renders ./components/collapse/demo/accordion.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -36,12 +37,12 @@ exports[`renders ./components/collapse/demo/accordion.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -58,12 +59,12 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-item-active"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -72,7 +73,6 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-content ant-collapse-content-active"
|
||||
role="tabpanel"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-content-box"
|
||||
@@ -89,12 +89,12 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -104,12 +104,12 @@ exports[`renders ./components/collapse/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-item-disabled"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -126,12 +126,12 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-item-active"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -140,7 +140,6 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-content ant-collapse-content-active"
|
||||
role="tabpanel"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-content-box"
|
||||
@@ -155,12 +154,12 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -170,12 +169,12 @@ exports[`renders ./components/collapse/demo/borderless.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -192,13 +191,13 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-item-active"
|
||||
role="tablist"
|
||||
style="background:#f7f7f7;border-radius:4px;margin-bottom:24px;border:0;overflow:hidden"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -207,7 +206,6 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-content ant-collapse-content-active"
|
||||
role="tabpanel"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-content-box"
|
||||
@@ -224,13 +222,13 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
style="background:#f7f7f7;border-radius:4px;margin-bottom:24px;border:0;overflow:hidden"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -240,13 +238,13 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
style="background:#f7f7f7;border-radius:4px;margin-bottom:24px;border:0;overflow:hidden"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -263,12 +261,12 @@ exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -278,12 +276,12 @@ exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -293,12 +291,12 @@ exports[`renders ./components/collapse/demo/mix.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -315,12 +313,12 @@ exports[`renders ./components/collapse/demo/noarrow.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-item-active"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="arrow"
|
||||
@@ -329,7 +327,6 @@ exports[`renders ./components/collapse/demo/noarrow.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-content ant-collapse-content-active"
|
||||
role="tabpanel"
|
||||
>
|
||||
<div
|
||||
class="ant-collapse-content-box"
|
||||
@@ -346,12 +343,12 @@ exports[`renders ./components/collapse/demo/noarrow.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-no-arrow"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
class="ant-collapse-header"
|
||||
role="tab"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
This is panel header with no arrow icon
|
||||
</div>
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
@collapse-prefix-cls: ~"@{ant-prefix}-collapse";
|
||||
|
||||
@collapse-header-bg: @background-color-light;
|
||||
@collapse-active-bg: @background-color-base;
|
||||
|
||||
.collapse-close() {
|
||||
transform: rotate(0);
|
||||
}
|
||||
@@ -32,7 +29,7 @@
|
||||
|
||||
> .@{collapse-prefix-cls}-header {
|
||||
line-height: 22px;
|
||||
padding: 12px 0 12px 40px;
|
||||
padding: @collapse-header-padding;
|
||||
color: @heading-color;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
@@ -69,13 +66,11 @@
|
||||
&-content {
|
||||
overflow: hidden;
|
||||
color: @text-color;
|
||||
padding: 0 @padding-md;
|
||||
background-color: @component-background;
|
||||
background-color: @collapse-content-bg;
|
||||
border-top: @border-width-base @border-style-base @border-color-base;
|
||||
|
||||
& > &-box {
|
||||
padding-top: @padding-md;
|
||||
padding-bottom: @padding-md;
|
||||
padding: @collapse-content-padding;
|
||||
}
|
||||
|
||||
&-inactive {
|
||||
|
||||
@@ -51,6 +51,8 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
|
||||
| size | determine the size of the input box, the height of `large` and `small`, are 40px and 24px respectively, while default size is 32px | string | - |
|
||||
| style | to customize the style of the input box | object | {} |
|
||||
| onOpenChange | a callback function, can be executed whether the popup calendar is popped up or closed | function(status) | - |
|
||||
| mode | picker panel mode | `time|date|month|year` | 'date' |
|
||||
| onPanelChange | callback when picker panel mode is changed | function(value, mode) | - |
|
||||
|
||||
### Common Methods
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@ subtitle: 日期选择框
|
||||
| value | 日期 | [moment](http://momentjs.com/) | 无 |
|
||||
| onChange | 时间发生变化的回调 | function(date: moment, dateString: string) | 无 |
|
||||
| onOk | 点击确定按钮的回调 | function() | - |
|
||||
| mode | 日期面板的状态 | `time|date|month|year` | 'date' |
|
||||
| onPanelChange | 日期面板变化时的回调 | function(value, mode) | - |
|
||||
|
||||
### MonthPicker
|
||||
|
||||
|
||||
@@ -120,7 +120,9 @@
|
||||
background: none;
|
||||
border-top: 1px dashed @border-color-split;
|
||||
}
|
||||
&-horizontal&-with-text&-dashed {
|
||||
&-horizontal&-with-text&-dashed,
|
||||
&-horizontal&-with-text-left&-dashed,
|
||||
&-horizontal&-with-text-right&-dashed {
|
||||
border-top: 0;
|
||||
&:before,
|
||||
&:after {
|
||||
|
||||
@@ -9,7 +9,7 @@ const ButtonGroup = Button.Group;
|
||||
export interface DropdownButtonProps extends ButtonGroupProps, DropDownProps {
|
||||
type?: 'primary' | 'ghost' | 'dashed';
|
||||
disabled?: boolean;
|
||||
onClick?: React.MouseEventHandler<any>;
|
||||
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
||||
children?: any;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,12 @@ export default class Dropdown extends React.Component<DropDownProps, any> {
|
||||
disabled,
|
||||
});
|
||||
// menu cannot be selectable in dropdown defaultly
|
||||
const selectable = overlay.props.selectable || false;
|
||||
// menu should be focusable in dropdown defaultly
|
||||
const { selectable = false, focusable = true } = overlay.props;
|
||||
const fixedModeOverlay = React.cloneElement(overlay, {
|
||||
mode: 'vertical',
|
||||
selectable,
|
||||
focusable,
|
||||
});
|
||||
return (
|
||||
<RcDropdown
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Omit } from '../_util/type';
|
||||
|
||||
export interface FormCreateOption<T> {
|
||||
onFieldsChange?: (props: T, fields: Array<any>) => void;
|
||||
onValuesChange?: (props: T, values: any) => void;
|
||||
onValuesChange?: (props: T, changedValues: any, allValues: any) => void;
|
||||
mapPropsToFields?: (props: T) => void;
|
||||
withRef?: boolean;
|
||||
}
|
||||
@@ -115,10 +115,14 @@ export interface FormComponentProps {
|
||||
form: WrappedFormUtils;
|
||||
}
|
||||
|
||||
export interface RcBaseFormProps {
|
||||
wrappedComponentRef?: any;
|
||||
}
|
||||
|
||||
export interface ComponentDecorator {
|
||||
<P extends FormComponentProps>(
|
||||
component: React.ComponentClass<P> | React.SFC<P>,
|
||||
): React.ComponentClass<Omit<P, keyof FormComponentProps>>;
|
||||
): React.ComponentClass<RcBaseFormProps & Omit<P, keyof FormComponentProps>>;
|
||||
}
|
||||
|
||||
export default class Form extends React.Component<FormProps, any> {
|
||||
|
||||
@@ -543,7 +543,7 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Select a option and change input text above
|
||||
</div>
|
||||
@@ -551,7 +551,7 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -649,7 +649,7 @@ exports[`renders ./components/form/demo/customized-form-controls.md correctly 1`
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -1637,7 +1637,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -1698,7 +1698,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
website
|
||||
</div>
|
||||
@@ -1726,7 +1726,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -2263,7 +2263,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Please select a country
|
||||
</div>
|
||||
@@ -2271,7 +2271,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -2321,7 +2321,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Please select favourite colors
|
||||
</div>
|
||||
@@ -3340,7 +3340,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
@@ -56,7 +56,7 @@ The following `options` are available:
|
||||
| mapPropsToFields | Convert props to field value(e.g. reading the values from Redux store). And you must mark returned fields with [`Form.createFormField`](#Form.createFormField) | (props) => Object{ fieldName: FormField { value } } |
|
||||
| validateMessages | Default validate message. And its format is similar with [newMessages](https://github.com/yiminghe/async-validator/blob/master/src/messages.js)'s returned value | Object { [nested.path]: String } |
|
||||
| onFieldsChange | Specify a function that will be called when the value a `Form.Item` gets changed. Usage example: saving the field's value to Redux store. | Function(props, fields) |
|
||||
| onValuesChange | A handler while value of any field is changed | (props, values) => void |
|
||||
| onValuesChange | A handler while value of any field is changed | (props, changedValues, allValues) => void |
|
||||
|
||||
If the form has been decorated by `Form.create` then it has `this.props.form` property. `this.props.form` provides some APIs as follows:
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
||||
| mapPropsToFields | 把父组件的属性映射到表单项上(如:把 Redux store 中的值读出),需要对返回值中的表单域数据用 [`Form.createFormField`](#Form.createFormField) 标记 | (props) => Object{ fieldName: FormField { value } } |
|
||||
| validateMessages | 默认校验信息,可用于把默认错误信息改为中文等,格式与 [newMessages](https://github.com/yiminghe/async-validator/blob/master/src/messages.js) 返回值一致 | Object { [nested.path]: String } |
|
||||
| onFieldsChange | 当 `Form.Item` 子节点的值发生改变时触发,可以把对应的值转存到 Redux store | Function(props, fields) |
|
||||
| onValuesChange | 任一表单域的值发生改变时的回调 | (props, values) => void |
|
||||
| onValuesChange | 任一表单域的值发生改变时的回调 | (props, changedValues, allValues) => void |
|
||||
|
||||
经过 `Form.create` 包装的组件将会自带 `this.props.form` 属性,`this.props.form` 提供的 API 如下:
|
||||
|
||||
|
||||
@@ -251,7 +251,9 @@ form {
|
||||
}
|
||||
|
||||
// fix input with addon position. https://github.com/ant-design/ant-design/issues/8243
|
||||
.@{ant-prefix}-input-group,
|
||||
.@{ant-prefix}-input-group-wrapper {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class Search extends React.Component<SearchProps, any> {
|
||||
}
|
||||
|
||||
getButtonOrIcon() {
|
||||
const { enterButton, prefixCls, size } = this.props;
|
||||
const { enterButton, prefixCls, size, disabled } = this.props;
|
||||
if (!enterButton) {
|
||||
return <Icon className={`${prefixCls}-icon`} type="search" key="searchIcon" />;
|
||||
}
|
||||
@@ -59,6 +59,7 @@ export default class Search extends React.Component<SearchProps, any> {
|
||||
className={`${prefixCls}-button`}
|
||||
type="primary"
|
||||
size={size}
|
||||
disabled={disabled}
|
||||
onClick={this.onSearch}
|
||||
key="enterButton"
|
||||
>
|
||||
|
||||
@@ -20,4 +20,11 @@ describe('Input.Search', () => {
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should disable enter button when disabled prop is true', () => {
|
||||
const wrapper = mount(
|
||||
<Search placeholder="input search text" enterButton disabled />
|
||||
);
|
||||
expect(wrapper.find('.ant-btn-primary[disabled]')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -110,7 +110,7 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -242,7 +242,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -285,7 +285,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -399,7 +399,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -431,7 +431,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -468,7 +468,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -524,7 +524,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -548,7 +548,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Email
|
||||
</div>
|
||||
@@ -576,7 +576,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -614,7 +614,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
@@ -138,13 +138,10 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -157,7 +154,6 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -170,7 +166,6 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -218,28 +213,23 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -322,13 +312,10 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -343,7 +330,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -358,7 +344,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -373,7 +358,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -388,7 +372,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -403,7 +386,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -418,7 +400,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -433,7 +414,6 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -587,13 +567,10 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -608,7 +585,6 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -623,7 +599,6 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -638,7 +613,6 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -698,13 +672,10 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -717,7 +688,6 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -731,11 +701,11 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub1$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -751,14 +721,15 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -774,9 +745,9 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -866,28 +837,23 @@ exports[`renders ./components/layout/demo/top.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -966,28 +932,23 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -1052,14 +1013,13 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
class="ant-layout-sider-children"
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="height:100%"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -1079,13 +1039,11 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1093,7 +1051,6 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
option1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1101,7 +1058,6 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
option2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1109,7 +1065,6 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
option3
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1120,11 +1075,11 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -1138,14 +1093,15 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub3$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -1159,6 +1115,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1191,28 +1148,23 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
class="logo"
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -1231,14 +1183,13 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
class="ant-layout-sider-children"
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="height:100%;border-right:0"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -1258,13 +1209,11 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1272,7 +1221,6 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
option1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1280,7 +1228,6 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
option2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1288,7 +1235,6 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
option3
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -1299,11 +1245,11 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -1317,14 +1263,15 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub3$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -1338,6 +1285,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1168,198 +1168,6 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-extra-wrap"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-main"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-meta"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-meta-avatar"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-image"
|
||||
>
|
||||
<img
|
||||
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item-meta-content"
|
||||
>
|
||||
<h4
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
>
|
||||
ant design part 3
|
||||
</a>
|
||||
</h4>
|
||||
<div
|
||||
class="ant-list-item-meta-description"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item-content"
|
||||
>
|
||||
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
|
||||
</div>
|
||||
<ul
|
||||
class="ant-list-item-action"
|
||||
>
|
||||
<li>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-star-o"
|
||||
style="margin-right:8px"
|
||||
/>
|
||||
156
|
||||
</span>
|
||||
<em
|
||||
class="ant-list-item-action-split"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-like-o"
|
||||
style="margin-right:8px"
|
||||
/>
|
||||
156
|
||||
</span>
|
||||
<em
|
||||
class="ant-list-item-action-split"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-message"
|
||||
style="margin-right:8px"
|
||||
/>
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item-extra"
|
||||
>
|
||||
<img
|
||||
alt="logo"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
|
||||
width="272"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-extra-wrap"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-main"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-meta"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-meta-avatar"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-image"
|
||||
>
|
||||
<img
|
||||
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item-meta-content"
|
||||
>
|
||||
<h4
|
||||
class="ant-list-item-meta-title"
|
||||
>
|
||||
<a
|
||||
href="http://ant.design"
|
||||
>
|
||||
ant design part 4
|
||||
</a>
|
||||
</h4>
|
||||
<div
|
||||
class="ant-list-item-meta-description"
|
||||
>
|
||||
Ant Design, a design language for background applications, is refined by Ant UED Team.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item-content"
|
||||
>
|
||||
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
|
||||
</div>
|
||||
<ul
|
||||
class="ant-list-item-action"
|
||||
>
|
||||
<li>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-star-o"
|
||||
style="margin-right:8px"
|
||||
/>
|
||||
156
|
||||
</span>
|
||||
<em
|
||||
class="ant-list-item-action-split"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-like-o"
|
||||
style="margin-right:8px"
|
||||
/>
|
||||
156
|
||||
</span>
|
||||
<em
|
||||
class="ant-list-item-action-split"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<span>
|
||||
<i
|
||||
class="anticon anticon-message"
|
||||
style="margin-right:8px"
|
||||
/>
|
||||
2
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item-extra"
|
||||
>
|
||||
<img
|
||||
alt="logo"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
|
||||
width="272"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -1398,8 +1206,72 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-disabled ant-pagination-next"
|
||||
class="ant-pagination-item ant-pagination-item-2"
|
||||
tabindex="0"
|
||||
title="2"
|
||||
>
|
||||
<a>
|
||||
2
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-3"
|
||||
tabindex="0"
|
||||
title="3"
|
||||
>
|
||||
<a>
|
||||
3
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-4"
|
||||
tabindex="0"
|
||||
title="4"
|
||||
>
|
||||
<a>
|
||||
4
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-5"
|
||||
tabindex="0"
|
||||
title="5"
|
||||
>
|
||||
<a>
|
||||
5
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-6"
|
||||
tabindex="0"
|
||||
title="6"
|
||||
>
|
||||
<a>
|
||||
6
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-7"
|
||||
tabindex="0"
|
||||
title="7"
|
||||
>
|
||||
<a>
|
||||
7
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-8"
|
||||
tabindex="0"
|
||||
title="8"
|
||||
>
|
||||
<a>
|
||||
8
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="false"
|
||||
class=" ant-pagination-next"
|
||||
tabindex="0"
|
||||
title="Next Page"
|
||||
>
|
||||
<a
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`List.pagination renders pagination correctly 1`] = `
|
||||
<div
|
||||
class="ant-list ant-list-vertical ant-list-split ant-list-something-after-last-item"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-nested-loading"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-container"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-content ant-list-item-content-single"
|
||||
>
|
||||
Jack
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-item"
|
||||
>
|
||||
<div
|
||||
class="ant-list-item-content ant-list-item-content-single"
|
||||
>
|
||||
Lucy
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-list-pagination"
|
||||
>
|
||||
<ul
|
||||
class="ant-pagination my-page"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-disabled ant-pagination-prev"
|
||||
title="Previous Page"
|
||||
>
|
||||
<a
|
||||
class="ant-pagination-item-link"
|
||||
/>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
|
||||
tabindex="0"
|
||||
title="1"
|
||||
>
|
||||
<a>
|
||||
1
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-2"
|
||||
tabindex="0"
|
||||
title="2"
|
||||
>
|
||||
<a>
|
||||
2
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="false"
|
||||
class=" ant-pagination-next"
|
||||
tabindex="0"
|
||||
title="Next Page"
|
||||
>
|
||||
<a
|
||||
class="ant-pagination-item-link"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
129
components/list/__tests__/pagination.test.js
Normal file
129
components/list/__tests__/pagination.test.js
Normal file
@@ -0,0 +1,129 @@
|
||||
import React from 'react';
|
||||
import { render, mount } from 'enzyme';
|
||||
import List from '..';
|
||||
|
||||
describe('List.pagination', () => {
|
||||
const data = [
|
||||
{ key: 0, name: 'Jack' },
|
||||
{ key: 1, name: 'Lucy' },
|
||||
{ key: 2, name: 'Tom' },
|
||||
{ key: 3, name: 'Jerry' },
|
||||
];
|
||||
|
||||
const pagination = { className: 'my-page', pageSize: 2 };
|
||||
|
||||
function createList(props) {
|
||||
return (
|
||||
<List
|
||||
itemLayout="vertical"
|
||||
pagination={pagination}
|
||||
dataSource={data}
|
||||
renderItem={item => (
|
||||
<List.Item key={item.key} >
|
||||
{item.name}
|
||||
</List.Item>
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function renderedNames(wrapper) {
|
||||
return wrapper.find('.ant-list-item-content').map(row => row.text());
|
||||
}
|
||||
|
||||
it('renders pagination correctly', () => {
|
||||
const wrapper = render(createList());
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not show pager if pagination.hideOnSinglePage is true and only 1 page', () => {
|
||||
const wrapper = mount(
|
||||
createList({ pagination: { pageSize: 3, hideOnSinglePage: true } })
|
||||
);
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
wrapper.setProps({ pagination: { pageSize: 3, hideOnSinglePage: false } });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
wrapper.setProps({ pagination: { pageSize: 4, hideOnSinglePage: true } });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(0);
|
||||
wrapper.setProps({ pagination: { pageSize: 4, hideOnSinglePage: false } });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
wrapper.setProps({ pagination: { pageSize: 5, hideOnSinglePage: true } });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(0);
|
||||
wrapper.setProps({ pagination: { pageSize: 5, hideOnSinglePage: false } });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('paginate data', () => {
|
||||
const wrapper = mount(createList());
|
||||
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy']);
|
||||
wrapper
|
||||
.find('Pager')
|
||||
.last()
|
||||
.simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Tom', 'Jerry']);
|
||||
});
|
||||
|
||||
it('repaginates when pageSize change', () => {
|
||||
const wrapper = mount(createList());
|
||||
|
||||
wrapper.setProps({ pagination: { pageSize: 1 } });
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack']);
|
||||
});
|
||||
|
||||
it('fires change event', () => {
|
||||
const handlePaginationChange = jest.fn();
|
||||
const noop = () => {};
|
||||
const wrapper = mount(
|
||||
createList({
|
||||
pagination: {
|
||||
...pagination,
|
||||
onChange: handlePaginationChange,
|
||||
onShowSizeChange: noop,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
wrapper
|
||||
.find('Pager')
|
||||
.last()
|
||||
.simulate('click');
|
||||
|
||||
expect(handlePaginationChange).toBeCalledWith(2, 2);
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/4532
|
||||
// https://codepen.io/afc163/pen/pWVRJV?editors=001
|
||||
it('should display pagination as prop pagination change between true and false', () => {
|
||||
const wrapper = mount(createList());
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
expect(wrapper.find('.ant-pagination-item')).toHaveLength(2);
|
||||
wrapper.setProps({ pagination: false });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(0);
|
||||
wrapper.setProps({ pagination });
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
expect(wrapper.find('.ant-pagination-item')).toHaveLength(2);
|
||||
wrapper.find('.ant-pagination-item-2').simulate('click');
|
||||
expect(renderedNames(wrapper)).toEqual(['Tom', 'Jerry']);
|
||||
wrapper.setProps({ pagination: false });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(0);
|
||||
wrapper.setProps({ pagination: true });
|
||||
expect(wrapper.find('.ant-pagination')).toHaveLength(1);
|
||||
expect(wrapper.find('.ant-pagination-item')).toHaveLength(1); // pageSize will be 10
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/5259
|
||||
it('change to correct page when data source changes', () => {
|
||||
const wrapper = mount(createList({ pagination: { pageSize: 1 } }));
|
||||
wrapper.find('.ant-pagination-item-3').simulate('click');
|
||||
wrapper.setProps({ dataSource: [data[0]] });
|
||||
expect(
|
||||
wrapper
|
||||
.find('.ant-pagination-item-1')
|
||||
.hasClass('ant-pagination-item-active')
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -17,7 +17,7 @@ Setting `itemLayout` property with `vertical` to create a vertical list.
|
||||
import { List, Avatar, Icon } from 'antd';
|
||||
|
||||
const listData = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
for (let i = 0; i < 23; i++) {
|
||||
listData.push({
|
||||
href: 'http://ant.design',
|
||||
title: `ant design part ${i}`,
|
||||
@@ -27,13 +27,6 @@ for (let i = 0; i < 5; i++) {
|
||||
});
|
||||
}
|
||||
|
||||
const pagination = {
|
||||
pageSize: 10,
|
||||
current: 1,
|
||||
total: listData.length,
|
||||
onChange: (() => {}),
|
||||
};
|
||||
|
||||
const IconText = ({ type, text }) => (
|
||||
<span>
|
||||
<Icon type={type} style={{ marginRight: 8 }} />
|
||||
@@ -45,7 +38,12 @@ ReactDOM.render(
|
||||
<List
|
||||
itemLayout="vertical"
|
||||
size="large"
|
||||
pagination={pagination}
|
||||
pagination={{
|
||||
onChange: (page) => {
|
||||
console.log(page);
|
||||
},
|
||||
pageSize: 3,
|
||||
}}
|
||||
dataSource={listData}
|
||||
footer={<div><b>ant design</b> footer part</div>}
|
||||
renderItem={item => (
|
||||
|
||||
@@ -15,7 +15,15 @@ export { ListItemProps, ListItemMetaProps } from './Item';
|
||||
|
||||
export type ColumnCount = 1 | 2 | 3 | 4 | 6 | 8 | 12 | 24;
|
||||
|
||||
export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
|
||||
export type ColumnType =
|
||||
| 'gutter'
|
||||
| 'column'
|
||||
| 'xs'
|
||||
| 'sm'
|
||||
| 'md'
|
||||
| 'lg'
|
||||
| 'xl'
|
||||
| 'xxl';
|
||||
|
||||
export interface ListGridType {
|
||||
gutter?: number;
|
||||
@@ -72,7 +80,26 @@ export default class List extends React.Component<ListProps> {
|
||||
pagination: false,
|
||||
};
|
||||
|
||||
private keys: {[key: string]: string} = {};
|
||||
state = {
|
||||
paginationCurrent: 1,
|
||||
};
|
||||
|
||||
defaultPaginationProps = {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
onChange: (page: number, pageSize: number) => {
|
||||
const { pagination } = this.props;
|
||||
this.setState({
|
||||
paginationCurrent: page,
|
||||
});
|
||||
if (pagination && pagination.onChange) {
|
||||
pagination.onChange(page, pageSize);
|
||||
}
|
||||
},
|
||||
total: 0,
|
||||
};
|
||||
|
||||
private keys: { [key: string]: string } = {};
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
@@ -108,10 +135,15 @@ export default class List extends React.Component<ListProps> {
|
||||
|
||||
renderEmpty = (contextLocale: ListLocale) => {
|
||||
const locale = { ...contextLocale, ...this.props.locale };
|
||||
return <div className={`${this.props.prefixCls}-empty-text`}>{locale.emptyText}</div>;
|
||||
return (
|
||||
<div className={`${this.props.prefixCls}-empty-text`}>
|
||||
{locale.emptyText}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { paginationCurrent } = this.state;
|
||||
const {
|
||||
bordered,
|
||||
split,
|
||||
@@ -139,7 +171,7 @@ export default class List extends React.Component<ListProps> {
|
||||
spinning: loadingProp,
|
||||
};
|
||||
}
|
||||
const isLoading = (loadingProp && loadingProp.spinning);
|
||||
const isLoading = loadingProp && loadingProp.spinning;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
@@ -164,24 +196,57 @@ export default class List extends React.Component<ListProps> {
|
||||
[`${prefixCls}-something-after-last-item`]: this.isSomethingAfterLastItem(),
|
||||
});
|
||||
|
||||
const paginationProps = {
|
||||
...this.defaultPaginationProps,
|
||||
total: dataSource.length,
|
||||
current: paginationCurrent,
|
||||
...pagination,
|
||||
};
|
||||
const largestPage = Math.ceil(
|
||||
paginationProps.total / paginationProps.pageSize,
|
||||
);
|
||||
if (paginationProps.current > largestPage) {
|
||||
paginationProps.current = largestPage;
|
||||
}
|
||||
const paginationContent = pagination ? (
|
||||
<div className={`${prefixCls}-pagination`}>
|
||||
<Pagination {...pagination} />
|
||||
<Pagination
|
||||
{...paginationProps}
|
||||
onChange={this.defaultPaginationProps.onChange}
|
||||
/>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
let splitDataSource = [...dataSource];
|
||||
if (pagination) {
|
||||
if (
|
||||
dataSource.length >
|
||||
(paginationProps.current - 1) * paginationProps.pageSize
|
||||
) {
|
||||
splitDataSource = [...dataSource].splice(
|
||||
(paginationProps.current - 1) * paginationProps.pageSize,
|
||||
paginationProps.pageSize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let childrenContent;
|
||||
childrenContent = isLoading && <div style={{ minHeight: 53 }} />;
|
||||
if (dataSource.length > 0) {
|
||||
const items = dataSource.map((item: any, index: number) => this.renderItem(item, index));
|
||||
const childrenList = React.Children.map(items, (child: any, index) => React.cloneElement(child, {
|
||||
if (splitDataSource.length > 0) {
|
||||
const items = splitDataSource.map((item: any, index: number) =>
|
||||
this.renderItem(item, index),
|
||||
);
|
||||
const childrenList = React.Children.map(items, (child: any, index) =>
|
||||
React.cloneElement(child, {
|
||||
key: this.keys[index],
|
||||
}),
|
||||
);
|
||||
|
||||
childrenContent = grid ? (
|
||||
<Row gutter={grid.gutter}>{childrenList}</Row>
|
||||
) : childrenList;
|
||||
) : (
|
||||
childrenList
|
||||
);
|
||||
} else if (!children && !isLoading) {
|
||||
childrenContent = (
|
||||
<LocaleReceiver
|
||||
|
||||
@@ -156,7 +156,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -207,7 +207,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -500,7 +500,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -532,7 +532,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -1643,7 +1643,7 @@ exports[`renders ./components/locale-provider/demo/basic.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,17 +18,13 @@ class MenuItem extends React.Component<any, any> {
|
||||
render() {
|
||||
const { inlineCollapsed } = this.context;
|
||||
const props = this.props;
|
||||
const item = <Item {...props} ref={this.saveMenuItem} />;
|
||||
if (inlineCollapsed && props.level === 1) {
|
||||
return <Tooltip
|
||||
title={props.children}
|
||||
placement="right"
|
||||
overlayClassName={`${props.rootPrefixCls}-inline-collapsed-tooltip`}
|
||||
>
|
||||
{item}
|
||||
</Tooltip>;
|
||||
}
|
||||
return item;
|
||||
return <Tooltip
|
||||
title={inlineCollapsed && props.level === 1 ? props.children : ''}
|
||||
placement="right"
|
||||
overlayClassName={`${props.rootPrefixCls}-inline-collapsed-tooltip`}
|
||||
>
|
||||
<Item {...props} ref={this.saveMenuItem} />
|
||||
</Tooltip>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -19,7 +16,6 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
aria-selected="false"
|
||||
class="ant-menu-item ant-menu-item-disabled"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -30,11 +26,11 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-horizontal"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="item_2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
>
|
||||
<span>
|
||||
@@ -49,7 +45,6 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -66,14 +61,13 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -95,7 +89,6 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
@@ -113,7 +106,6 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
class="ant-menu-item-group-list"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -121,7 +113,6 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
Option 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -143,7 +134,6 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
class="ant-menu-item-group-list"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -151,7 +141,6 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
Option 3
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -164,11 +153,11 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -184,14 +173,15 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub4$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -207,6 +197,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
@@ -225,13 +216,10 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
/>
|
||||
</button>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -244,7 +232,6 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -257,7 +244,6 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -271,6 +257,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -292,13 +279,11 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -306,7 +291,6 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
Option 5
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -314,7 +298,6 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
Option 6
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -322,7 +305,6 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
Option 7
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -333,11 +315,11 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -353,6 +335,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -360,14 +343,13 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -389,13 +371,11 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -403,7 +383,6 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
Option 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -411,7 +390,6 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
Option 2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -419,7 +397,6 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
Option 3
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -430,11 +407,11 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -450,14 +427,15 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub4$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -473,6 +451,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
@@ -504,14 +483,11 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
<br />
|
||||
<br />
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -522,7 +498,6 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
Navigation One
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
@@ -534,6 +509,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -555,13 +531,11 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -569,7 +543,6 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
Option 3
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -578,11 +551,11 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub1-2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:48px"
|
||||
title="Submenu"
|
||||
@@ -592,16 +565,17 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -617,6 +591,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -638,14 +613,13 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
<br />
|
||||
<br />
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@@ -667,13 +641,11 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -681,7 +653,6 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
Option 1
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -689,7 +660,6 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
Option 2
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -697,7 +667,6 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
Option 3
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-menu-item"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
@@ -708,11 +677,11 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -728,14 +697,15 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub4$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@@ -751,6 +721,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -758,19 +729,17 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
|
||||
exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-vertical"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub1$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
>
|
||||
<span>
|
||||
@@ -788,11 +757,11 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub2$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
>
|
||||
<span>
|
||||
@@ -810,11 +779,11 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="sub4$Menu"
|
||||
class="ant-menu-submenu-title"
|
||||
>
|
||||
<span>
|
||||
|
||||
@@ -133,14 +133,14 @@ describe('Menu', () => {
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
wrapper.setProps({ mode: 'vertical' });
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
wrapper.setProps({ mode: 'inline' });
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
});
|
||||
|
||||
it('should always follow openKeys when mode is switched', () => {
|
||||
it('should always follow openKeys when inlineCollapsed is switched', () => {
|
||||
const wrapper = mount(
|
||||
<Menu defaultOpenKeys={['1']} mode="inline">
|
||||
<Menu.Item key="menu1">
|
||||
@@ -157,24 +157,23 @@ describe('Menu', () => {
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
|
||||
wrapper.setProps({ inlineCollapsed: true });
|
||||
// 动画结束后套样式;
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('.ant-menu').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
expect(wrapper.find('ul.ant-menu-root').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').length).toBe(0);
|
||||
|
||||
wrapper.setProps({ inlineCollapsed: false });
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
});
|
||||
|
||||
it('inlineCollapsed should works well when specify a not existed default openKeys', () => {
|
||||
@@ -203,8 +202,8 @@ describe('Menu', () => {
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-menu-submenu').at(0).hasClass('ant-menu-submenu-vertical')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-submenu').at(0).hasClass('ant-menu-submenu-open')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
});
|
||||
|
||||
describe('open submenu when click submenu title', () => {
|
||||
|
||||
@@ -67,6 +67,7 @@ export default class Menu extends React.Component<MenuProps, MenuState> {
|
||||
prefixCls: 'ant-menu',
|
||||
className: '',
|
||||
theme: 'light' as MenuTheme, // or dark
|
||||
focusable: false,
|
||||
};
|
||||
static childContextTypes = {
|
||||
inlineCollapsed: PropTypes.bool,
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&-dark&-horizontal > &-item > a:before {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&-dark &-item,
|
||||
&-dark &-item-group-title,
|
||||
&-dark &-item > a {
|
||||
|
||||
@@ -277,16 +277,16 @@
|
||||
border-bottom: 2px solid @menu-highlight-color;
|
||||
color: @menu-highlight-color;
|
||||
}
|
||||
}
|
||||
|
||||
> a {
|
||||
display: block;
|
||||
color: @menu-item-color;
|
||||
&:hover {
|
||||
color: @menu-highlight-color;
|
||||
}
|
||||
&:before {
|
||||
bottom: -2px;
|
||||
}
|
||||
> .@{menu-prefix-cls}-item > a {
|
||||
display: block;
|
||||
color: @menu-item-color;
|
||||
&:hover {
|
||||
color: @menu-highlight-color;
|
||||
}
|
||||
&:before {
|
||||
bottom: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,20 @@ describe('message', () => {
|
||||
expect(document.querySelectorAll('.custom-container').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should be able to config maxCount', () => {
|
||||
message.config({
|
||||
maxCount: 5,
|
||||
});
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
message.info('test');
|
||||
}
|
||||
message.info('last');
|
||||
expect(document.querySelectorAll('.ant-message-notice').length).toBe(5);
|
||||
expect(document.querySelectorAll('.ant-message-notice')[4].textContent).toBe('last');
|
||||
jest.runAllTimers();
|
||||
expect(document.querySelectorAll('.ant-message-notice').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should be able to hide manually', () => {
|
||||
const hide1 = message.info('whatever', 0);
|
||||
const hide2 = message.info('whatever', 0);
|
||||
|
||||
@@ -40,6 +40,7 @@ Methods for global configuration and destruction are also provided:
|
||||
message.config({
|
||||
top: 100,
|
||||
duration: 2,
|
||||
maxCount: 3,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -48,3 +49,4 @@ message.config({
|
||||
| duration | time before auto-dismiss, in seconds | number | 1.5 |
|
||||
| getContainer | Return the mount node for Message | () => HTMLElement | () => document.body |
|
||||
| top | distance from top | number | 24px |
|
||||
| maxCount | max message show, drop oldest if exceed limit | number | - |
|
||||
|
||||
@@ -9,6 +9,7 @@ let key = 1;
|
||||
let prefixCls = 'ant-message';
|
||||
let transitionName = 'move-up';
|
||||
let getContainer: () => HTMLElement;
|
||||
let maxCount: number;
|
||||
|
||||
function getMessageInstance(callback: (i: any) => void) {
|
||||
if (messageInstance) {
|
||||
@@ -20,6 +21,7 @@ function getMessageInstance(callback: (i: any) => void) {
|
||||
transitionName,
|
||||
style: { top: defaultTop }, // 覆盖原来的样式
|
||||
getContainer,
|
||||
maxCount,
|
||||
}, (instance: any) => {
|
||||
if (messageInstance) {
|
||||
callback(messageInstance);
|
||||
@@ -83,6 +85,7 @@ export interface ConfigOptions {
|
||||
prefixCls?: string;
|
||||
getContainer?: () => HTMLElement;
|
||||
transitionName?: string;
|
||||
maxCount?: number;
|
||||
}
|
||||
|
||||
export default {
|
||||
@@ -123,6 +126,10 @@ export default {
|
||||
transitionName = options.transitionName;
|
||||
messageInstance = null; // delete messageInstance for new transitionName
|
||||
}
|
||||
if (options.maxCount !== undefined) {
|
||||
maxCount = options.maxCount;
|
||||
messageInstance = null;
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (messageInstance) {
|
||||
|
||||
@@ -41,6 +41,7 @@ title: Message
|
||||
message.config({
|
||||
top: 100,
|
||||
duration: 2,
|
||||
maxCount: 3,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -49,3 +50,4 @@ message.config({
|
||||
| duration | 默认自动关闭延时,单位秒 | number | 3 |
|
||||
| getContainer | 配置渲染节点的输出位置 | () => HTMLElement | () => document.body |
|
||||
| top | 消息距离顶部的位置 | number | 24px |
|
||||
| maxCount | 最大显示数, 超过限制时,最早的消息会被自动关闭 | number | - |
|
||||
|
||||
@@ -73,7 +73,7 @@ exports[`renders ./components/notification/demo/placement.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -90,6 +90,17 @@ exports[`renders ./components/notification/demo/placement.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/notification/demo/update.md correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open the notification box
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/notification/demo/with-btn.md correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
|
||||
39
components/notification/demo/update.md
Normal file
39
components/notification/demo/update.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
order: 7
|
||||
title:
|
||||
zh-CN: 更新消息内容
|
||||
en-US: Update Message Content
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以通过唯一的 key 来更新内容。
|
||||
|
||||
## en-US
|
||||
|
||||
Update content with unique key.
|
||||
|
||||
````jsx
|
||||
import { Button, notification } from 'antd';
|
||||
|
||||
const key = 'updatable';
|
||||
|
||||
const openNotification = () => {
|
||||
notification.open({
|
||||
key,
|
||||
message: 'Notification Title',
|
||||
description: 'description.',
|
||||
});
|
||||
setTimeout(() => {
|
||||
notification.open({
|
||||
key,
|
||||
message: 'New Title',
|
||||
description: 'New description.',
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Button type="primary" onClick={openNotification}>Open the notification box</Button>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -118,7 +118,7 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #404040;
|
||||
color: shade(@text-color-secondary, 40%);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ exports[`renders ./components/pagination/demo/changer.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -634,7 +634,7 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
@@ -11,7 +11,7 @@ title:
|
||||
|
||||
## en-US
|
||||
|
||||
Set `okText` and `cancelText` props to customise the button's labels.
|
||||
Set `okText` and `cancelText` props to customize the button's labels.
|
||||
|
||||
````jsx
|
||||
import { Popconfirm } from 'antd';
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Progress render format 1`] = `
|
||||
<div
|
||||
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-progress-outer"
|
||||
>
|
||||
<div
|
||||
class="ant-progress-inner"
|
||||
>
|
||||
<div
|
||||
class="ant-progress-bg"
|
||||
style="width: 50%; height: 8px;"
|
||||
/>
|
||||
<div
|
||||
class="ant-progress-success-bg"
|
||||
style="width: 10%; height: 8px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-progress-text"
|
||||
>
|
||||
50 10
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Progress render negetive progress 1`] = `
|
||||
<div
|
||||
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { mount } from 'enzyme';
|
||||
import Progress from '..';
|
||||
|
||||
describe('Progress', () => {
|
||||
it('successPercent should decide the progress status when it exists', async () => {
|
||||
it('successPercent should decide the progress status when it exists', () => {
|
||||
const wrapper = mount(<Progress percent={100} successPercent={50} />);
|
||||
expect(wrapper.find('.ant-progress-status-success')).toHaveLength(0);
|
||||
|
||||
@@ -11,23 +11,34 @@ describe('Progress', () => {
|
||||
expect(wrapper.find('.ant-progress-status-success')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('render out-of-range progress', async () => {
|
||||
it('render out-of-range progress', () => {
|
||||
const wrapper = mount(<Progress percent={120} />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render out-of-range progress with info', async () => {
|
||||
it('render out-of-range progress with info', () => {
|
||||
const wrapper = mount(<Progress percent={120} showInfo />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render negetive progress', async () => {
|
||||
it('render negetive progress', () => {
|
||||
const wrapper = mount(<Progress percent={-20} />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render negetive successPercent', async () => {
|
||||
it('render negetive successPercent', () => {
|
||||
const wrapper = mount(<Progress percent={50} successPercent={-20} />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('render format', () => {
|
||||
const wrapper = mount(
|
||||
<Progress
|
||||
percent={50}
|
||||
successPercent={10}
|
||||
format={(percent, successPercent) => `${percent} ${successPercent}`}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ If it will take a long time to complete an operation, you can use `Progress` to
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| format | template function of the content | function(percent) | `percent => percent + '%'` |
|
||||
| format | template function of the content | function(percent, successPercent) | `percent => percent + '%'` |
|
||||
| gapDegree `(type=circle)` | the gap degree of half circle, 0 ~ 360 | number | 0 |
|
||||
| gapPosition `(type=circle)` | the gap position, options: `top` `bottom` `left` `right` | string | `top` |
|
||||
| percent | to set the completion percentage | number | 0 |
|
||||
|
||||
@@ -18,7 +18,7 @@ title: Progress
|
||||
|
||||
| 属性 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| format | 内容的模板函数 | function(percent) | `percent => percent + '%'` |
|
||||
| format | 内容的模板函数 | function(percent, successPercent) | `percent => percent + '%'` |
|
||||
| gapDegree `(type=circle)` | 圆形进度条缺口角度,可取值 0 ~ 360 | number | 0 |
|
||||
| gapPosition `(type=circle)` | 圆形进度条缺口位置 | Enum{ 'top', 'bottom', 'left', 'right' } | `top` |
|
||||
| percent | 百分比 | number | 0 |
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface ProgressProps {
|
||||
type?: ProgressType;
|
||||
percent?: number;
|
||||
successPercent?: number;
|
||||
format?: (percent: number) => string;
|
||||
format?: (percent?: number, successPercent?: number) => string;
|
||||
status?: 'success' | 'active' | 'exception';
|
||||
showInfo?: boolean;
|
||||
strokeWidth?: number;
|
||||
@@ -81,12 +81,12 @@ export default class Progress extends React.Component<ProgressProps, {}> {
|
||||
if (showInfo) {
|
||||
let text;
|
||||
const iconType = (type === 'circle' || type === 'dashboard') ? '' : '-circle';
|
||||
if (progressStatus === 'exception') {
|
||||
text = format ? textFormatter(validProgress(percent)) : <Icon type={`cross${iconType}`} />;
|
||||
if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) {
|
||||
text = textFormatter(validProgress(percent), validProgress(successPercent));
|
||||
} else if (progressStatus === 'exception') {
|
||||
text = <Icon type={`cross${iconType}`} />;
|
||||
} else if (progressStatus === 'success') {
|
||||
text = format ? textFormatter(validProgress(percent)) : <Icon type={`check${iconType}`} />;
|
||||
} else {
|
||||
text = textFormatter(validProgress(percent));
|
||||
text = <Icon type={`check${iconType}`} />;
|
||||
}
|
||||
progressInfo = <span className={`${prefixCls}-text`}>{text}</span>;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
height: @radio-dot-size;
|
||||
left: (@radio-size - @radio-dot-size) / 2 - 1px;
|
||||
top: (@radio-size - @radio-dot-size) / 2 - 1px;
|
||||
border-radius: @border-radius-base;
|
||||
border-radius: @radio-dot-size;
|
||||
display: table;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
|
||||
@@ -70,7 +70,7 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -103,12 +103,12 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-selection__clear"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
/>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -136,7 +136,7 @@ exports[`renders ./components/select/demo/combobox.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Enter the account name
|
||||
</div>
|
||||
@@ -164,7 +164,7 @@ exports[`renders ./components/select/demo/combobox.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -201,7 +201,7 @@ exports[`renders ./components/select/demo/coordinate.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -234,7 +234,7 @@ exports[`renders ./components/select/demo/coordinate.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -271,7 +271,7 @@ exports[`renders ./components/select/demo/label-in-value.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -298,7 +298,7 @@ exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:none;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Please select
|
||||
</div>
|
||||
@@ -307,7 +307,7 @@ exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
|
||||
class="ant-select-selection__choice"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
title="a10"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__choice__content"
|
||||
@@ -322,7 +322,7 @@ exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
|
||||
class="ant-select-selection__choice"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
title="c12"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__choice__content"
|
||||
@@ -385,7 +385,7 @@ exports[`renders ./components/select/demo/optgroup.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -413,7 +413,7 @@ exports[`renders ./components/select/demo/search.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Select a person
|
||||
</div>
|
||||
@@ -440,7 +440,7 @@ exports[`renders ./components/select/demo/search.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -467,7 +467,7 @@ exports[`renders ./components/select/demo/search-box.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
input search text
|
||||
</div>
|
||||
@@ -515,7 +515,7 @@ exports[`renders ./components/select/demo/select-users.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Select users
|
||||
</div>
|
||||
@@ -637,7 +637,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -683,7 +683,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
@@ -708,7 +708,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:none;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Please select
|
||||
</div>
|
||||
@@ -717,7 +717,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
class="ant-select-selection__choice"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
title="a10"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__choice__content"
|
||||
@@ -732,7 +732,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
class="ant-select-selection__choice"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
title="c12"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__choice__content"
|
||||
@@ -784,7 +784,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:none;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Please select
|
||||
</div>
|
||||
@@ -793,7 +793,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
class="ant-select-selection__choice"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
title="a10"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__choice__content"
|
||||
@@ -808,7 +808,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
|
||||
class="ant-select-selection__choice"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
title="c12"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__choice__content"
|
||||
@@ -863,7 +863,7 @@ exports[`renders ./components/select/demo/tags.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
Tags Mode
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@ export interface AbstractSelectProps {
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
tabIndex?: number;
|
||||
placeholder?: string;
|
||||
placeholder?: string | React.ReactNode;
|
||||
defaultActiveFirstOption?: boolean;
|
||||
dropdownClassName?: string;
|
||||
dropdownStyle?: React.CSSProperties;
|
||||
@@ -31,7 +31,7 @@ export interface LabeledValue {
|
||||
label: React.ReactNode;
|
||||
}
|
||||
|
||||
export type SelectValue = string | any[] | LabeledValue | LabeledValue[];
|
||||
export type SelectValue = string | string[] | number | number[] | LabeledValue | LabeledValue[];
|
||||
|
||||
export interface SelectProps extends AbstractSelectProps {
|
||||
value?: SelectValue;
|
||||
@@ -58,7 +58,7 @@ export interface SelectProps extends AbstractSelectProps {
|
||||
|
||||
export interface OptionProps {
|
||||
disabled?: boolean;
|
||||
value?: any;
|
||||
value?: string | number;
|
||||
title?: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,6 @@
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,6 +370,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-allow-clear &-selection--single &-selection-selected-value {
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
&-allow-clear &-selection--multiple &-selection__rendered {
|
||||
margin-right: 20px; // In case that clear button will overlap content
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
}
|
||||
|
||||
&-blur {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
opacity: 0.7;
|
||||
-webkit-filter: blur(0.5px);
|
||||
|
||||
@@ -322,6 +322,8 @@
|
||||
@menu-dark-arrow-color: #fff;
|
||||
@menu-dark-submenu-bg: #000c17;
|
||||
@menu-dark-highlight-color: #fff;
|
||||
@menu-dark-item-active-bg: @primary-color;
|
||||
// same as @menu-dark-item-active-bg, for naming downgrade compatible, should be deleted in next majoy version
|
||||
@menu-dark-item-selected-bg: @primary-color;
|
||||
|
||||
// Spin
|
||||
@@ -461,3 +463,10 @@
|
||||
@slider-dot-border-color-active: tint(@primary-color, 50%);
|
||||
@slider-disabled-color: @disabled-color;
|
||||
@slider-disabled-background-color: @component-background;
|
||||
|
||||
// Collapse
|
||||
// ---
|
||||
@collapse-header-padding: 12px 0 12px 40px;
|
||||
@collapse-header-bg: @background-color-light;
|
||||
@collapse-content-padding: @padding-md;
|
||||
@collapse-content-bg: @component-background;
|
||||
|
||||
@@ -333,7 +333,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
}
|
||||
|
||||
return (a: T, b: T) => {
|
||||
const result = (sortColumn!.sorter as CompareFn<T>)(a, b);
|
||||
const result = (sortColumn!.sorter as CompareFn<T>)(a, b, sortOrder);
|
||||
if (result !== 0) {
|
||||
return (sortOrder === 'descend') ? -result : result;
|
||||
}
|
||||
@@ -341,7 +341,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
};
|
||||
}
|
||||
|
||||
toggleSortOrder(order: string, column: ColumnProps<T>) {
|
||||
toggleSortOrder(order: 'ascend'|'descend', column: ColumnProps<T>) {
|
||||
let { sortColumn, sortOrder } = this.state;
|
||||
// 只同时允许一列进行排序,否则会导致排序顺序的逻辑问题
|
||||
let isSortColumn = this.isSortColumn(column);
|
||||
@@ -350,7 +350,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
|
||||
sortColumn = column;
|
||||
} else { // 当前列已排序
|
||||
if (sortOrder === order) { // 切换为未排序状态
|
||||
sortOrder = '';
|
||||
sortOrder = undefined;
|
||||
sortColumn = null;
|
||||
} else { // 切换为排序状态
|
||||
sortOrder = order;
|
||||
|
||||
@@ -106,6 +106,22 @@ describe('Table.filter', () => {
|
||||
expect(dropdown.props().visible).toBe(false);
|
||||
});
|
||||
|
||||
it('if the filter is visible it should ignore the selectedKeys changes', () => {
|
||||
const wrapper = mount(createTable({
|
||||
columns: [{
|
||||
...column,
|
||||
filterDropdownVisible: true,
|
||||
}],
|
||||
}));
|
||||
|
||||
const filterMenu = wrapper.find('FilterMenu').instance();
|
||||
expect(filterMenu.state.selectedKeys).toEqual([]);
|
||||
wrapper.find('FilterMenu').find('input[type="checkbox"]').first().simulate('click');
|
||||
expect(filterMenu.state.selectedKeys).toEqual(['boy']);
|
||||
wrapper.setProps({ dataSource: [...data, { key: 999, name: 'Chris' }] });
|
||||
expect(filterMenu.state.selectedKeys).toEqual(['boy']);
|
||||
});
|
||||
|
||||
it('fires change event when visible change', () => {
|
||||
const handleChange = jest.fn();
|
||||
const wrapper = mount(createTable({
|
||||
|
||||
@@ -74,6 +74,20 @@ describe('Table.sorter', () => {
|
||||
expect(renderedNames(wrapper)).toEqual(['Jack', 'Jerry', 'Lucy', 'Tom']);
|
||||
});
|
||||
|
||||
it('provides sortOrder in the sorterFn', () => {
|
||||
let actualSortOrder;
|
||||
mount(createTable({ },
|
||||
{
|
||||
sortOrder: 'ascend',
|
||||
sorter: (a, b, sortOrder) => {
|
||||
actualSortOrder = sortOrder;
|
||||
return sorterFn(a, b);
|
||||
},
|
||||
},
|
||||
));
|
||||
expect(actualSortOrder).toEqual('ascend');
|
||||
});
|
||||
|
||||
it('fires change event', () => {
|
||||
const handleChange = jest.fn();
|
||||
const wrapper = mount(createTable({ onChange: handleChange }));
|
||||
|
||||
@@ -132,13 +132,11 @@ exports[`Table.filter renders menu correctly 1`] = `
|
||||
class="ant-table-filter-dropdown"
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-dropdown-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -162,7 +160,6 @@ exports[`Table.filter renders menu correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-dropdown-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -187,11 +184,11 @@ exports[`Table.filter renders menu correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="title$Menu"
|
||||
class="ant-dropdown-menu-submenu-title"
|
||||
title="Title"
|
||||
>
|
||||
@@ -230,13 +227,11 @@ exports[`Table.filter renders radio filter correctly 1`] = `
|
||||
class="ant-table-filter-dropdown"
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-dropdown-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -260,7 +255,6 @@ exports[`Table.filter renders radio filter correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-dropdown-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -285,11 +279,11 @@ exports[`Table.filter renders radio filter correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||
role="menuitem"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-owns="title$Menu"
|
||||
class="ant-dropdown-menu-submenu-title"
|
||||
title="Title"
|
||||
>
|
||||
|
||||
@@ -410,13 +410,10 @@ exports[`Table.rowSelection render with default selection correctly 1`] = `
|
||||
class="ant-dropdown ant-dropdown-placement-bottomLeft ant-dropdown-hidden"
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-dropdown-menu ant-table-selection-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-dropdown-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
@@ -425,7 +422,6 @@ exports[`Table.rowSelection render with default selection correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-selected="false"
|
||||
class="ant-dropdown-menu-item"
|
||||
role="menuitem"
|
||||
>
|
||||
|
||||
@@ -17,10 +17,12 @@ title:
|
||||
|
||||
Use `filters` to generate filter menu in columns, `onFilter` to determine filtered result, and `filterMultiple` to indicate whether it's multiple or single selection.
|
||||
|
||||
Use `sorter` to make a column sortable. `sorter` can be a function `function(a, b) { ... }` for sorting data locally.
|
||||
Use `sorter` to make a column sortable. `sorter` can be a function of the type `function(a, b) { ... }` for sorting data locally.
|
||||
|
||||
Uses `defaultSortOrder` to make a column sorted by default.
|
||||
|
||||
If a `sortOrder` or `defaultSortOrder` is specified with the value `ascend` or `descend`, you can access this value from within the function passed to the `sorter` as explained above. Such a function can take the form: `function(a, b, sortOrder) { ... }`.
|
||||
|
||||
````jsx
|
||||
import { Table } from 'antd';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title:
|
||||
|
||||
Using JSX style API (introduced in 2.5.0)
|
||||
|
||||
> Since this is just a syntax sugar for the prop `columns`, so that you can't compose `Column` and `ColumnGroup` with other Components.
|
||||
> Since this is just a syntax sugar for the prop `columns`, you can't compose `Column` and `ColumnGroup` with other Components.
|
||||
|
||||
````jsx
|
||||
import { Table, Icon, Divider } from 'antd';
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as ReactDOM from 'react-dom';
|
||||
import Menu, { SubMenu, Item as MenuItem } from 'rc-menu';
|
||||
import closest from 'dom-closest';
|
||||
import classNames from 'classnames';
|
||||
import shallowequal from 'shallowequal';
|
||||
import Dropdown from '../dropdown';
|
||||
import Icon from '../icon';
|
||||
import Checkbox from '../checkbox';
|
||||
@@ -43,7 +44,15 @@ export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, F
|
||||
selectedKeys: string[];
|
||||
visible: boolean;
|
||||
};
|
||||
if ('selectedKeys' in nextProps) {
|
||||
|
||||
/**
|
||||
* if the state is visible the component should ignore updates on selectedKeys prop to avoid
|
||||
* that the user selection is lost
|
||||
* this happens frequently when a table is connected on some sort of realtime data
|
||||
* Fixes https://github.com/ant-design/ant-design/issues/10289 and
|
||||
* https://github.com/ant-design/ant-design/issues/10209
|
||||
*/
|
||||
if ('selectedKeys' in nextProps && !shallowequal(this.props.selectedKeys, nextProps.selectedKeys)) {
|
||||
newState.selectedKeys = nextProps.selectedKeys;
|
||||
}
|
||||
if ('filterDropdownVisible' in column) {
|
||||
@@ -145,7 +154,7 @@ export default class FilterMenu<T> extends React.Component<FilterMenuProps<T>, F
|
||||
}
|
||||
|
||||
handleMenuItemClick = (info: { keyPath: string, key: string }) => {
|
||||
if (info.keyPath.length <= 1) {
|
||||
if (!info.keyPath || info.keyPath.length <= 1) {
|
||||
return;
|
||||
}
|
||||
const keyPathOfSelectedItem = this.state.keyPathOfSelectedItem;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Store } from './createStore';
|
||||
import { RadioChangeEvent } from '../radio';
|
||||
import { CheckboxChangeEvent } from '../checkbox';
|
||||
|
||||
export type CompareFn<T> = ((a: T, b: T) => number);
|
||||
export type CompareFn<T> = ((a: T, b: T, sortOrder?: 'ascend' | 'descend') => number);
|
||||
export type ColumnFilterItem = { text: string; value: string, children?: ColumnFilterItem[] };
|
||||
|
||||
export interface ColumnProps<T> {
|
||||
@@ -28,7 +28,7 @@ export interface ColumnProps<T> {
|
||||
fixed?: boolean | ('left' | 'right');
|
||||
filterIcon?: React.ReactNode;
|
||||
filteredValue?: any[];
|
||||
sortOrder?: boolean | ('ascend' | 'descend');
|
||||
sortOrder?: 'ascend' | 'descend';
|
||||
children?: ColumnProps<T>[];
|
||||
onCellClick?: (record: T, event: any) => void;
|
||||
onCell?: (record: T) => any;
|
||||
@@ -127,7 +127,7 @@ export interface TableState<T> {
|
||||
pagination: TablePaginationConfig;
|
||||
filters: TableStateFilters;
|
||||
sortColumn: ColumnProps<T> | null;
|
||||
sortOrder: string;
|
||||
sortOrder: 'ascend' | 'descend' | undefined;
|
||||
}
|
||||
|
||||
export type SelectionItemSelectFn = (key: string[]) => any;
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
&[colspan] {
|
||||
text-align: center;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.@{iconfont-css-prefix}-filter,
|
||||
@@ -79,6 +78,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-thead > tr:not(:last-child) > th {
|
||||
&[colspan] {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-tbody > tr > td {
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
transition: all .3s;
|
||||
@@ -272,14 +277,15 @@
|
||||
height: 4px;
|
||||
transition: all .3s;
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-down {
|
||||
margin-top: 1.5px;
|
||||
}
|
||||
|
||||
.@{iconfont-css-prefix}-caret-down {
|
||||
top: -1.5px;
|
||||
.@{iconfont-css-prefix}-caret-up {
|
||||
margin-top: 0.5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +326,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.@{table-prefix-cls}-thead > tr > th {
|
||||
.@{table-prefix-cls}-thead > tr:not(:last-child) > th {
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
}
|
||||
|
||||
|
||||
@@ -837,7 +837,7 @@ exports[`renders ./components/tabs/demo/position.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
unselectable="on"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
|
||||
@@ -10,28 +10,30 @@ export interface TimelineProps {
|
||||
pending?: React.ReactNode;
|
||||
pendingDot?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
reverse?: boolean;
|
||||
}
|
||||
|
||||
export default class Timeline extends React.Component<TimelineProps, any> {
|
||||
static Item = TimelineItem as React.ClassicComponentClass<TimeLineItemProps>;
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-timeline',
|
||||
reverse: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { prefixCls, children, pending, pendingDot, className, ...restProps } = this.props;
|
||||
const {
|
||||
prefixCls,
|
||||
pending = null, pendingDot,
|
||||
children, className, reverse,
|
||||
...restProps,
|
||||
} = this.props;
|
||||
const pendingNode = typeof pending === 'boolean' ? null : pending;
|
||||
const classString = classNames(prefixCls, {
|
||||
[`${prefixCls}-pending`]: !!pending,
|
||||
[`${prefixCls}-reverse`]: !!reverse,
|
||||
}, className);
|
||||
// Remove falsy items
|
||||
const falsylessItems = React.Children.toArray(children).filter(item => !!item);
|
||||
const items = React.Children.map(falsylessItems, (ele: React.ReactElement<any>, idx) =>
|
||||
React.cloneElement(ele, {
|
||||
last: idx === (React.Children.count(falsylessItems) - 1),
|
||||
}),
|
||||
);
|
||||
const pendingItem = (!!pending) ? (
|
||||
|
||||
const pendingItem = !!pending ? (
|
||||
<TimelineItem
|
||||
pending={!!pending}
|
||||
dot={pendingDot || <Icon type="loading" />}
|
||||
@@ -39,10 +41,29 @@ export default class Timeline extends React.Component<TimelineProps, any> {
|
||||
{pendingNode}
|
||||
</TimelineItem>
|
||||
) : null;
|
||||
|
||||
const timeLineItems = !!reverse
|
||||
? [pendingItem, ...React.Children.toArray(children).reverse()]
|
||||
: [...React.Children.toArray(children), pendingItem];
|
||||
|
||||
// Remove falsy items
|
||||
const truthyItems = timeLineItems.filter(item => !!item);
|
||||
const itemsCount = React.Children.count(truthyItems);
|
||||
const lastCls = `${prefixCls}-item-last`;
|
||||
const items = React.Children.map(truthyItems, (ele: React.ReactElement<any>, idx) =>
|
||||
React.cloneElement(ele, {
|
||||
className: classNames([
|
||||
ele.props.className,
|
||||
(!reverse && !!pending)
|
||||
? (idx === itemsCount - 2) ? lastCls : ''
|
||||
: (idx === itemsCount - 1) ? lastCls : '',
|
||||
]),
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<ul {...restProps} className={classString}>
|
||||
{items}
|
||||
{pendingItem}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ export interface TimeLineItemProps {
|
||||
color?: string;
|
||||
dot?: React.ReactNode;
|
||||
pending?: boolean;
|
||||
last?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
@@ -15,16 +14,14 @@ export default class TimelineItem extends React.Component<TimeLineItemProps, any
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-timeline',
|
||||
color: 'blue',
|
||||
last: false,
|
||||
pending: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { prefixCls, className, color = '', last, children, pending, dot, ...restProps } = this.props;
|
||||
const { prefixCls, className, color = '', children, pending, dot, ...restProps } = this.props;
|
||||
|
||||
const itemClassName = classNames({
|
||||
[`${prefixCls}-item`]: true,
|
||||
[`${prefixCls}-item-last`]: last,
|
||||
[`${prefixCls}-item-pending`]: pending,
|
||||
}, className);
|
||||
|
||||
|
||||
@@ -223,72 +223,83 @@ exports[`renders ./components/timeline/demo/custom.md correctly 1`] = `
|
||||
`;
|
||||
|
||||
exports[`renders ./components/timeline/demo/pending.md correctly 1`] = `
|
||||
<ul
|
||||
class="ant-timeline ant-timeline-pending"
|
||||
>
|
||||
<li
|
||||
class="ant-timeline-item"
|
||||
<div>
|
||||
<ul
|
||||
class="ant-timeline ant-timeline-pending"
|
||||
>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-blue"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
<li
|
||||
class="ant-timeline-item"
|
||||
>
|
||||
Create a services site 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-timeline-item"
|
||||
>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-blue"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
>
|
||||
Solve initial network problems 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-timeline-item ant-timeline-item-last"
|
||||
>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-blue"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
>
|
||||
Technical testing 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-timeline-item ant-timeline-item-pending"
|
||||
>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-spin anticon-loading"
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-blue"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
>
|
||||
Create a services site 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-timeline-item"
|
||||
>
|
||||
Recording...
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-blue"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
>
|
||||
Solve initial network problems 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-timeline-item ant-timeline-item-last"
|
||||
>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-blue"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
>
|
||||
Technical testing 2015-09-01
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-timeline-item ant-timeline-item-pending"
|
||||
>
|
||||
<div
|
||||
class="ant-timeline-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-timeline-item-head ant-timeline-item-head-custom ant-timeline-item-head-blue"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-spin anticon-loading"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-timeline-item-content"
|
||||
>
|
||||
Recording...
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
style="margin-top:16px"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Toggle Reverse
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
103
components/timeline/__tests__/index.test.js
Normal file
103
components/timeline/__tests__/index.test.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import TimeLine from '..';
|
||||
|
||||
const { Item } = TimeLine;
|
||||
|
||||
const wrapperFactory = (timeLineProps = {}) => mount(
|
||||
<TimeLine type="editable-card" {...timeLineProps}>
|
||||
<Item key="1">foo</Item>
|
||||
<Item key="2">bar</Item>
|
||||
<Item key="3">baz</Item>
|
||||
</TimeLine>
|
||||
);
|
||||
|
||||
describe('TimeLine', () => {
|
||||
describe('renders items without passing any props correctly', () => {
|
||||
const wrapper = wrapperFactory();
|
||||
|
||||
it('has 3 timeline item', () => {
|
||||
expect(wrapper.find('li.ant-timeline-item')).toHaveLength(3);
|
||||
});
|
||||
|
||||
it('has only 1 timeline item is marked as the last item', () => {
|
||||
expect(wrapper.find('li.ant-timeline-item-last')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('its last item is marked as the last item', () => {
|
||||
expect(wrapper.find('li.ant-timeline-item').last().hasClass('ant-timeline-item-last')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('renders pending item', () => {
|
||||
const pending = <div>pending...</div>;
|
||||
const pendingDot = <i>dot</i>;
|
||||
|
||||
it('has one extra timeline item', () => {
|
||||
const wrapper = wrapperFactory({ pending });
|
||||
expect(wrapper.find('li.ant-timeline-item')).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('has extra pending timeline item', () => {
|
||||
const wrapper = wrapperFactory({ pending });
|
||||
expect(wrapper.find('li.ant-timeline-item-pending')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('renders the pending timeline item as long as it receive a truthy prop value to \'pending\'', () => {
|
||||
const wrapper = wrapperFactory({ pending: true });
|
||||
expect(wrapper.find('li.ant-timeline-item-pending')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('its last item is marked as the pending item', () => {
|
||||
const wrapper = wrapperFactory({ pending });
|
||||
expect(wrapper.find('li.ant-timeline-item').last().hasClass('ant-timeline-item-pending')).toBe(true);
|
||||
});
|
||||
|
||||
it('its second to last item is marked as the last item', () => {
|
||||
const wrapper = wrapperFactory({ pending });
|
||||
const items = wrapper.find('li.ant-timeline-item');
|
||||
expect(items.at(items.length - 2).hasClass('ant-timeline-item-last')).toBe(true);
|
||||
});
|
||||
|
||||
it('has the correct pending node', () => {
|
||||
const wrapper = wrapperFactory({ pending });
|
||||
expect(wrapper.find('li.ant-timeline-item-pending').contains(pending)).toBe(true);
|
||||
});
|
||||
|
||||
it('has the correct pending dot node', () => {
|
||||
const wrapper = wrapperFactory({ pending, pendingDot });
|
||||
expect(wrapper.find('li.ant-timeline-item-pending').contains(pendingDot)).toBe(true);
|
||||
});
|
||||
|
||||
it('has no pending dot if without passing a truthy \'pending\' prop', () => {
|
||||
const wrapper = wrapperFactory({ pendingDot });
|
||||
expect(wrapper.find('li.ant-timeline-item-pending').contains(pendingDot)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the item rendering sequence is controlled by reverse', () => {
|
||||
it('items is in order when prop reverse is false', () => {
|
||||
const wrapper = wrapperFactory({ reverse: false });
|
||||
expect(wrapper.find('.ant-timeline-item-content').map(w => w.text())).toEqual(['foo', 'bar', 'baz']);
|
||||
});
|
||||
|
||||
it('items is reversed when prop reverse is true', () => {
|
||||
const wrapper = wrapperFactory({ reverse: true });
|
||||
expect(wrapper.find('.ant-timeline-item-content').map(w => w.text())).toEqual(['baz', 'bar', 'foo']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('renders items reversely and with pending item', () => {
|
||||
const pending = <div>pending...</div>;
|
||||
|
||||
it('its last item is marked as the last item', () => {
|
||||
const wrapper = wrapperFactory({ pending, reverse: true });
|
||||
expect(wrapper.find('li.ant-timeline-item').last().hasClass('ant-timeline-item-last')).toBe(true);
|
||||
});
|
||||
|
||||
it('its first item is marked as the pending item', () => {
|
||||
const wrapper = wrapperFactory({ pending, reverse: true });
|
||||
expect(wrapper.find('li.ant-timeline-item').first().hasClass('ant-timeline-item-pending')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,26 +1,44 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 最后一个
|
||||
en-US: Last node
|
||||
zh-CN: 最后一个及排序
|
||||
en-US: Last node and Reversing
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
当任务状态正在发生,还在记录过程中,可用幽灵节点来表示当前的时间节点(用于时间正序排列)。当 pending 值为 false ,可用定制元件替换默认时间图点。
|
||||
当任务状态正在发生,还在记录过程中,可用幽灵节点来表示当前的时间节点,当 pending 为真值时展示幽灵节点,如果 pending 是 React 元素可用于定制该节点内容,同时 pendingDot 将可以用于定制其轴点。reverse 属性用于控制节点排序,为 false 时按正序排列,为 true 时按倒序排列。
|
||||
|
||||
## en-US
|
||||
|
||||
When the timeline is incomplete and ongoing, put a ghost node at last. set `pending={true}` or `pending={a React Element}`. Used in ascend chronological order. When `pending` is not false, set `pendingDot={a React Element}` to replace the default pending dot.
|
||||
When the timeline is incomplete and ongoing, put a ghost node at last. Set `pending` as truthy value to enable displaying pending item. You can customize the pending content by passing a React Element. Meanwhile, `pendingDot={a React Element}` is used to customize the dot of the pending item.
|
||||
`reverse={true}` is used for reversing nodes.
|
||||
|
||||
````jsx
|
||||
import { Timeline } from 'antd';
|
||||
import { Timeline, Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Timeline pending="Recording...">
|
||||
<Timeline.Item>Create a services site 2015-09-01</Timeline.Item>
|
||||
<Timeline.Item>Solve initial network problems 2015-09-01</Timeline.Item>
|
||||
<Timeline.Item>Technical testing 2015-09-01</Timeline.Item>
|
||||
</Timeline>
|
||||
, mountNode);
|
||||
class PendingTimeLine extends React.Component {
|
||||
state = {
|
||||
reverse: false,
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.setState({ reverse: !this.state.reverse });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Timeline pending="Recording..." reverse={this.state.reverse}>
|
||||
<Timeline.Item>Create a services site 2015-09-01</Timeline.Item>
|
||||
<Timeline.Item>Solve initial network problems 2015-09-01</Timeline.Item>
|
||||
<Timeline.Item>Technical testing 2015-09-01</Timeline.Item>
|
||||
</Timeline>
|
||||
<Button type="primary" style={{ marginTop: 16 }} onClick={this.handleClick}>Toggle Reverse</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<PendingTimeLine />, mountNode);
|
||||
````
|
||||
|
||||
@@ -30,6 +30,7 @@ Timeline
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| pending | Set the last ghost node's existence or its content | boolean\|string\|ReactNode | `false` |
|
||||
| pendingDot | Set the dot of the last ghost node when pending is true | \|string\|ReactNode | `<Icon type="loading" />` |
|
||||
| reverse | reverse nodes or not | boolean | false |
|
||||
|
||||
### Timeline.Item
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ title: Timeline
|
||||
| --- | --- | --- | --- |
|
||||
| pending | 指定最后一个幽灵节点是否存在或内容 | boolean\|string\|ReactNode | false |
|
||||
| pendingDot | 当最后一个幽灵节点存在時,指定其时间图点 | \|string\|ReactNode | `<Icon type="loading" />` |
|
||||
| reverse | 节点排序 | boolean | false |
|
||||
|
||||
### Timeline.Item
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@
|
||||
|
||||
&-last {
|
||||
.@{timeline-prefix-cls}-item-tail {
|
||||
border-left: 2px dotted @timeline-color;
|
||||
display: none;
|
||||
}
|
||||
.@{timeline-prefix-cls}-item-content {
|
||||
@@ -88,6 +87,21 @@
|
||||
}
|
||||
|
||||
&&-pending &-item-last &-item-tail {
|
||||
border-left: 2px dotted @timeline-color;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&&-reverse &-item-last &-item-tail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&&-reverse &-item-pending {
|
||||
.@{timeline-prefix-cls}-item-tail {
|
||||
border-left: 2px dotted @timeline-color;
|
||||
display: block;
|
||||
}
|
||||
.@{timeline-prefix-cls}-item-content {
|
||||
min-height: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@ export interface TooltipProps extends AbstractTooltipProps {
|
||||
|
||||
const splitObject = (obj: any, keys: string[]) => {
|
||||
const picked: any = {};
|
||||
const omited: any = { ...obj };
|
||||
const omitted: any = { ...obj };
|
||||
keys.forEach(key => {
|
||||
if (obj && key in obj) {
|
||||
picked[key] = obj[key];
|
||||
delete omited[key];
|
||||
delete omitted[key];
|
||||
}
|
||||
});
|
||||
return { picked, omited };
|
||||
return { picked, omitted };
|
||||
};
|
||||
|
||||
export default class Tooltip extends React.Component<TooltipProps, any> {
|
||||
@@ -125,7 +125,7 @@ export default class Tooltip extends React.Component<TooltipProps, any> {
|
||||
element.props.disabled && this.isHoverTrigger()) {
|
||||
// Pick some layout related style properties up to span
|
||||
// Prevent layout bugs like https://github.com/ant-design/ant-design/issues/5254
|
||||
const { picked, omited } = splitObject(
|
||||
const { picked, omitted } = splitObject(
|
||||
element.props.style,
|
||||
['position', 'left', 'right', 'top', 'bottom', 'float', 'display', 'zIndex'],
|
||||
);
|
||||
@@ -135,7 +135,7 @@ export default class Tooltip extends React.Component<TooltipProps, any> {
|
||||
cursor: 'not-allowed',
|
||||
};
|
||||
const buttonStyle = {
|
||||
...omited,
|
||||
...omitted,
|
||||
pointerEvents: 'none',
|
||||
};
|
||||
const child = cloneElement(element, {
|
||||
|
||||
@@ -8,8 +8,8 @@ export interface TransferOperationProps {
|
||||
className?: string;
|
||||
leftArrowText?: string;
|
||||
rightArrowText?: string;
|
||||
moveToLeft?: React.FormEventHandler<any>;
|
||||
moveToRight?: React.FormEventHandler<any>;
|
||||
moveToLeft?: React.FormEventHandler<HTMLButtonElement>;
|
||||
moveToRight?: React.FormEventHandler<HTMLButtonElement>;
|
||||
leftActive?: boolean;
|
||||
rightActive?: boolean;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ Any data whose entries are defined in a hierarchical manner is fit to use this c
|
||||
| size | To set the size of the select input, options: `large` `small` | string | 'default' |
|
||||
| treeCheckable | Whether to show checkbox on the treeNodes | boolean | false |
|
||||
| treeCheckStrictly | Whether to check nodes precisely (in the `checkable` mode), means parent and child nodes are not associated, and it will make `labelInValue` be true | boolean | false |
|
||||
| treeData | Data of the treeNodes, manual construction work is no longer needed if this property has been set(ensure the Uniqueness of each value) | array<{ value, label, children, [disabled, disableCheckbox, selectable] }> | \[] |
|
||||
| treeData | Data of the treeNodes, manual construction work is no longer needed if this property has been set(ensure the Uniqueness of each value) | array<{ value, label, children, [disabled, disableCheckbox, selectable] }>(when title is defined,label's value will be covered) | \[] |
|
||||
| treeDataSimpleMode | Enable simple mode of treeData.(treeData should like this: [{id:1, pId:0, value:'1', label:"test1",...},...], pId is parent node's id) | false\|Array<{ id: string, pId: string, rootPId: null }> | false |
|
||||
| treeDefaultExpandAll | Whether to expand all treeNodes by default | boolean | false |
|
||||
| treeDefaultExpandedKeys | Default expanded treeNodes | string\[] | - |
|
||||
|
||||
@@ -35,7 +35,7 @@ title: TreeSelect
|
||||
| size | 选择框大小,可选 `large` `small` | string | 'default' |
|
||||
| treeCheckable | 显示 checkbox | boolean | false |
|
||||
| treeCheckStrictly | checkable 状态下节点选择完全受控(父子节点选中状态不再关联),会使得 `labelInValue` 强制为 true | boolean | false |
|
||||
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(value 在整个树范围内唯一) | array<{value, label, children, [disabled, disableCheckbox, selectable]}> | \[] |
|
||||
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(value 在整个树范围内唯一) | array<{value, label, children, [disabled, disableCheckbox, selectable]}>(如果定义了title,label会被title覆盖) | \[] |
|
||||
| treeDataSimpleMode | 使用简单格式的 treeData,具体设置参考可设置的类型 (此时 treeData 应变为这样的数据结构: [{id:1, pId:0, value:'1', label:"test1",...},...], `pId` 是父节点的 id) | false\|Array<{ id: string, pId: string, rootPId: null }> | false |
|
||||
| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false |
|
||||
| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] | - |
|
||||
|
||||
@@ -195,7 +195,7 @@ export default class Upload extends React.Component<UploadProps, UploadState> {
|
||||
const result = this.props.beforeUpload(file, fileList);
|
||||
if (result === false) {
|
||||
this.onChange({
|
||||
file: fileToObject(file),
|
||||
file,
|
||||
fileList: uniqBy(fileList.map(fileToObject).concat(this.state.fileList), (item: UploadFile) => item.uid),
|
||||
});
|
||||
return false;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Upload from '..';
|
||||
import { fileToObject } from '../utils';
|
||||
|
||||
describe('Upload', () => {
|
||||
// https://github.com/react-component/upload/issues/36
|
||||
@@ -54,13 +55,17 @@ describe('Upload', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not stop upload when return value of beforeUpload is not false', (done) => {
|
||||
it('should not stop upload when return value of beforeUpload is false', (done) => {
|
||||
const mockFile = new File(['foo'], 'foo.png', {
|
||||
type: 'image/png',
|
||||
});
|
||||
const data = jest.fn();
|
||||
const props = {
|
||||
action: 'http://upload.com',
|
||||
beforeUpload: () => false,
|
||||
data,
|
||||
onChange: () => {
|
||||
onChange: ({ file }) => {
|
||||
expect(file instanceof File).toBe(true);
|
||||
expect(data).not.toBeCalled();
|
||||
done();
|
||||
},
|
||||
@@ -75,7 +80,7 @@ describe('Upload', () => {
|
||||
wrapper.find('input').simulate('change', {
|
||||
target: {
|
||||
files: [
|
||||
{ file: 'foo.png' },
|
||||
mockFile,
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -107,4 +112,14 @@ describe('Upload', () => {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe('util', () => {
|
||||
it('should be able to copy file instance', () => {
|
||||
const file = new File([], 'aaa.zip');
|
||||
const copiedFile = fileToObject(file);
|
||||
['uid', 'lastModified', 'lastModifiedDate', 'name', 'size', 'type'].forEach((key) => {
|
||||
expect(key in copiedFile).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,13 +8,14 @@ export function T() {
|
||||
// via coping a new Object
|
||||
export function fileToObject(file: RcFile): UploadFile {
|
||||
return {
|
||||
...file,
|
||||
lastModified: file.lastModified,
|
||||
lastModifiedDate: file.lastModifiedDate,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
percent: 0,
|
||||
uid: file.uid,
|
||||
percent: 0,
|
||||
originFileObj: file,
|
||||
} as UploadFile;
|
||||
}
|
||||
|
||||
@@ -215,8 +215,8 @@ $ yarn add react-app-rewire-less --dev
|
||||
|
||||
你也可以根据 [在 create-react-app 中使用](/docs/react/use-with-create-react-app.zh-CN.md) 的介绍使用 [react-app-rewire-typescript][https://github.com/lwd-technology/react-app-rewire-typescript] 自己来配置 TypeScript 的开发环境。
|
||||
|
||||
此外,还可以选择 [react-scripts-ts-antd](https://www.npmjs.com/package/react-scripts-ts-antd),其中已经配置好了 ts-import-plugin、react-app-rewired、scss、less 等常用功能。只需一条命令即可生成一个免配置的 TypeScript 项目.
|
||||
```bash
|
||||
此外,还可以选择 [react-scripts-ts-antd](https://www.npmjs.com/package/react-scripts-ts-antd),其中已经配置好了 ts-import-plugin、react-app-rewired、scss、less 等常用功能。只需一条命令即可生成一个免配置的 TypeScript 项目.
|
||||
```bash
|
||||
$ create-react-app my-project --scripts-version=react-scripts-ts-antd
|
||||
```
|
||||
|
||||
|
||||
20
package.json
20
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "3.4.2",
|
||||
"version": "3.5.0",
|
||||
"title": "Ant Design",
|
||||
"description": "An enterprise-class UI design language and React-based implementation",
|
||||
"homepage": "http://ant.design/",
|
||||
@@ -52,20 +52,20 @@
|
||||
"prop-types": "^15.5.7",
|
||||
"rc-animate": "^2.4.1",
|
||||
"rc-calendar": "~9.6.0",
|
||||
"rc-cascader": "~0.12.0",
|
||||
"rc-cascader": "~0.13.0",
|
||||
"rc-checkbox": "~2.1.5",
|
||||
"rc-collapse": "~1.8.0",
|
||||
"rc-collapse": "~1.9.0",
|
||||
"rc-dialog": "~7.1.0",
|
||||
"rc-dropdown": "~2.1.0",
|
||||
"rc-editor-mention": "^1.0.2",
|
||||
"rc-form": "^2.1.0",
|
||||
"rc-input-number": "~4.0.0",
|
||||
"rc-menu": "~6.2.0",
|
||||
"rc-notification": "~3.0.0",
|
||||
"rc-menu": "~7.0.2",
|
||||
"rc-notification": "~3.1.1",
|
||||
"rc-pagination": "~1.16.1",
|
||||
"rc-progress": "~2.2.2",
|
||||
"rc-rate": "~2.4.0",
|
||||
"rc-select": "~7.7.0",
|
||||
"rc-select": "~8.0.1",
|
||||
"rc-slider": "~8.6.0",
|
||||
"rc-steps": "~3.1.0",
|
||||
"rc-switch": "~1.6.0",
|
||||
@@ -83,6 +83,7 @@
|
||||
"warning": "~3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/types": "7.0.0-beta.44",
|
||||
"@types/react": "^16.0.0",
|
||||
"@types/react-dom": "^16.0.0",
|
||||
"ansi-styles": "^3.2.0",
|
||||
@@ -128,7 +129,7 @@
|
||||
"jsonml.js": "^0.1.0",
|
||||
"lint-staged": "^7.0.0",
|
||||
"lz-string": "^1.4.4",
|
||||
"majo": "^0.5.1",
|
||||
"majo": "^0.6.2",
|
||||
"mockdate": "^2.0.1",
|
||||
"moment-timezone": "^0.5.5",
|
||||
"pre-commit": "^1.2.2",
|
||||
@@ -211,5 +212,8 @@
|
||||
"pre-commit": [
|
||||
"lint-staged"
|
||||
],
|
||||
"sideEffects": false
|
||||
"sideEffects": [
|
||||
"es/**/style/*",
|
||||
"lib/**/style/*"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,13 +9,23 @@
|
||||
&-pick {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
margin-bottom: 8px;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
&-picker {
|
||||
margin: 12px 0 24px;
|
||||
margin: 24px 0;
|
||||
&-value {
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
font-family: Consolas;
|
||||
margin-left: 16px;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
&-validation {
|
||||
font-size: 13px;
|
||||
color: @error-color;
|
||||
margin-left: 16px;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user