Compare commits

...

70 Commits
3.4.2 ... 3.5.0

Author SHA1 Message Date
愚指导
9368e2df87 Bump 3.5.0 (#10297) 2018-05-04 18:15:28 +08:00
Zheeeng
7f8cb838e3 Remove the side effects in render method (#10357) 2018-05-04 17:37:31 +08:00
愚指导
0f7794946f upgrade rc-cascader to 1.13.0 for support filedNames (#10365) 2018-05-04 17:27:34 +08:00
Christian
f4b8a58480 fixes #10289 and #10209: lost of user selection on table data updates (#10332)
* fixes #10289 and #10209: lost of user selection on table data updates

* adds shallowequal check
2018-05-04 14:51:15 +08:00
Wu Haotian
6019245365 fix(button): use React.HTMLProps for button's props (#10229) 2018-05-04 14:48:41 +08:00
Wei Zhu
3fd9397174 Keep text align center
Fix prev commit
2018-05-04 14:33:06 +08:00
Wei Zhu
f1e38a1573 Fix table merged header cell border
Fix #10359
2018-05-04 14:30:21 +08:00
愚道
013df45a70 merge https://github.com/ant-design/ant-design/pull/10306 from feature-3.5.0 2018-05-03 16:58:50 +08:00
afc163
5ee4d20e2a should still have padding when card which set padding to 0 is loading 2018-05-03 15:17:04 +08:00
afc163
c9017b6c6c release 3.4.5 2018-05-03 14:27:37 +08:00
Michael Wang
05e702a2b4 Remove useless characters in doc (#10340) 2018-05-03 11:52:50 +08:00
paranoidjk
8e166915a9 fix(Select): value tsd (#10336) 2018-05-03 11:28:30 +08:00
Xiaoming
9c6fef0604 treeSelect doc (#10302)
TreeSelect implement Tree as popup panel which use title as the display
text.
To follow the Select definition (label as display text), TreeSelect
internal convert the prop label into title to the Tree component (but
will follow if title is set).
ref:
https://github.com/react-component/tree-select/blob/master/src/Select.js
x#L44
2018-05-03 11:26:59 +08:00
paranoidjk
b6f8ab89c7 Fix: Form tsd (#10324)
* Fix(form): wrappedComponentRef interface

- ref: https://github.com/react-component/form/blob/master/src/createBaseForm.js#L499

* refactor: use ts conditional type

* fix: merge

* Revert "refactor: use ts conditional type"

This reverts commit ab3035da83.
2018-05-02 18:24:51 +08:00
Wei Zhu
56e3384c6b Revert "MenuItem: avoid rendering Tooltip unless necessary (#9636)"
This reverts commit 0754845aff.

Conditional rendering will break the transition animation,
since React will create new DOM node when inlineCollapsed changges.

Fix https://github.com/react-component/menu/issues/139
2018-05-02 14:49:20 +08:00
afc163
b5a52d26f2 fix snapshot 2018-05-02 14:28:16 +08:00
afc163
70a42545e3 fix fileToObject, close #10319 2018-05-02 13:56:54 +08:00
afc163
fb38e55cc0 more test about button text 2018-05-01 19:36:11 +08:00
afc163
c7471a4653 tweak insert space logic of loading button 2018-05-01 19:33:38 +08:00
afc163
726f0466bc menu should be unfocusable defaultly 2018-05-01 18:53:44 +08:00
Wei Zhu
a4261f9344 Only lock issues 2018-05-01 18:32:48 +08:00
Wei Zhu
0616b05583 Add lock threads robot 2018-05-01 13:56:25 +08:00
afc163
d0c3752a4e we can remove @types/node now 2018-05-01 13:49:37 +08:00
Daniel Gomez
3a5fce7256 Fix UploadFile's lastModifiedDate property name (#10315) 2018-05-01 00:11:18 +08:00
afc163
74e36325a2 site: tweak style 2018-04-29 23:02:07 +08:00
Junbin Huang
3a3d550b54 chore: upgrade menu (#10305)
* chore: upgrade menu and select

* Add test case for coverage percent
2018-04-29 23:01:58 +08:00
Ash Kumar
013932e6d3 Feature: (Issue 10213): Column 'sorter' function is passed 'sortOrder' as param (#10306)
* Table Column's sorter prop can now be provided a fn to which 'sortOrder' is passed as param

* head.md: added documentation for new use of 'sorter' prop function
2018-04-29 22:08:28 +08:00
Benjy Cui
cd6ad64cab chore: remove advertisement for yuque (#10299) 2018-04-29 10:42:45 +08:00
afc163
81dd432e31 update select demo 2018-04-28 23:56:38 +08:00
afc163
4535e9d4f1 Fix Select extra space taken up when arrow disabled
close #10092
2018-04-28 23:38:05 +08:00
偏右
4956dd8042 Release 3.4.4 (#10296)
* add `lib/**/style/*` as sideEffects (#10217)

* Fix upload onChange arg type when beforeUpload return false, close #10293

* 3.4.4

* Fix ts error temporarily, DefinitelyTyped/DefinitelyTyped#25342
2018-04-28 15:36:19 +08:00
guifu
548d8c9c51 chore: update menu to ~6.3.0 2018-04-28 14:12:37 +08:00
愚道
8b64882562 Merge branch 'master' of github.com:ant-design/ant-design 2018-04-28 11:10:54 +08:00
愚道
6682a56922 fix snapshot ci 2018-04-28 11:09:15 +08:00
afc163
e97977b891 Fix upload onChange arg type when beforeUpload return false, close #10293 2018-04-28 11:06:32 +08:00
愚道
b45146486a merge feature-3.5.0 2018-04-28 11:04:10 +08:00
afc163
8b02a21d36 site: valid primary color range 2018-04-27 22:09:49 +08:00
afc163
be43e56835 site: fix color tool, close #10265 2018-04-27 21:23:51 +08:00
afc163
7f8f89cbff doc: Add mode and onPanelChange in API document, close #9785 2018-04-27 20:17:39 +08:00
Thiebaud Thomas
a1e186b8a3 Fix type for placeholder in select component (#10282) 2018-04-27 18:22:10 +08:00
afc163
3d079af7cd Fix Input.Group align issue in Form, close #10281 2018-04-27 15:57:27 +08:00
afc163
1f6107e94a Fix naming convention, close #10275 2018-04-27 13:21:51 +08:00
afc163
e40c2a7f45 Fix notification icon hover color, close #10272 2018-04-27 10:48:40 +08:00
afc163
d9053a2526 Tweak sort position again 2018-04-26 16:15:04 +08:00
afc163
4b1857d587 fix spin loading 2018-04-26 16:06:18 +08:00
Marcela Bomfim
b1c41c665e Fix typo (#10250)
Fix typo
2018-04-25 21:59:14 +08:00
afc163
c85758fd01 Fix spin container interaction, close #10227 2018-04-25 14:55:16 +08:00
afc163
52c8f34a73 Fix radio border radius 2018-04-25 11:08:21 +08:00
Wu Haotian
4ea20e696c fix(form): fix typing for Form.onValuesChange (#10231) 2018-04-24 23:33:58 +08:00
afc163
a268dc8d62 Fix dashed Divider, close #10216 2018-04-24 20:17:48 +08:00
Wu Haotian
262ed8eec3 add lib/**/style/* as sideEffects (#10217) 2018-04-24 14:03:32 +08:00
Samuel Gaus
4bc28ac471 Update jsx.md (#10203)
Made it clear that you can't use components other than Column or ColumnGroup as children to Table.
2018-04-23 21:57:43 +08:00
愚指导
4101d182e0 Bump 3.4.3 (#10198) 2018-04-23 17:23:35 +08:00
薛定谔的猫
14dbcb95ed fix: sideEffects: false cause css file not bundled (fixes #10190) (#10197) 2018-04-23 17:08:24 +08:00
dependabot[bot]
14fa376dff Update majo requirement to ^0.6.2 (#10195)
Updates the requirements on [majo](https://github.com/egoist/majo) to permit the latest version.
- [Release notes](https://github.com/egoist/majo/releases)
- [Commits](https://github.com/egoist/majo/commits/v0.6.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-04-23 16:00:37 +08:00
Zheeeng
6a3e6f55cf Fix typo (#10193) 2018-04-23 16:00:24 +08:00
Wei Zhu
fa5491a390 Add @babel/types@7.0.0-beta.44 as devDependencies 2018-04-23 15:03:17 +08:00
Zheeeng
4ad5985df7 Prefer using 'truthy' over 'falsyless' (#10191) 2018-04-23 11:23:25 +08:00
Jiabin Peng
bb720aaab9 Fix menu item's clickable region in dark theme (#10187)
* remove redundant style for submenu

* Fix menu item's clickable region in dark theme
2018-04-23 00:31:36 +08:00
afc163
8ab4aeb9c4 site: fix ad flush 2018-04-22 22:37:58 +08:00
Benjy Cui
e444dc5e39 chore: add ad for yuque (#10182) 2018-04-22 18:58:40 +08:00
afc163
b9d94971e4 Add successPercent as Progress[format] argument, close #10096 2018-04-22 14:00:49 +08:00
niko
d50ec436d5 List integrate pagination functional fixed: #9303 (#10135) 2018-04-20 15:41:40 +08:00
Jin ZHANG
e1c74eb799 add maxCount config to message (#10169) 2018-04-20 15:40:43 +08:00
Zheeeng
d016471638 Feature 3.5.0 time line reverse api (#10057)
* Add reverse api for TimeLine

* Update TimeLine test snapshot

* Add specifications for reverse api and pending api
2018-04-20 11:23:37 +08:00
Yevhen Hryhorevskyi
754c94c447 Bump up rc-notification version to 3.1.0 (#10161)
Bump up `rc-notification` version to 3.1.0 that supports notification update by key
2018-04-19 21:18:09 +08:00
davidhatten
74d1c5e6b6 Add collapse styles to default.less (#9943)
* push collapse styling into overridable defaults

* Changes to ensure backwards compatibiliy, switch bg-color to be based on default style

* change background-color to bg in style names

* simplify and consolodate content-padding

* I figured out why the styling is split across content and box like that

The collapse/show animation doesn't work right without the padding set up across the two elements like this. From an end-user point of view, I think this is the easiest thing.

* pushing all padding styling on to the box instead of the content, keeping var name the same because the end user doesn't need to know the difference

* Pushing header-bg-color back up to the top of the component heirarchy

* shorten content padding
2018-04-19 11:36:53 +08:00
afc163
04a5cc2a8b Merge branch 'master' into feature-3.5.0 2018-04-15 19:52:24 +08:00
诸岳
b52053051c Input.Search should disable enter button when disabled prop is true (#10051)
* Input Search should disable enter button when disabled prop is true, close #10040

* test: Add test case for commit bd21722
2018-04-15 13:14:26 +08:00
Ludwig Bäcklund
74d81c2d07 Add title prop to Badge that shows when hovering it 2018-04-12 11:53:32 +08:00
105 changed files with 2032 additions and 871 deletions

14
.github/lock.yml vendored Normal file
View 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

View File

@@ -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`

View File

@@ -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`

View File

@@ -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>

View File

@@ -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>
`;

View File

@@ -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');
});
});

View 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>

View File

@@ -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` |

View File

@@ -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}
/>
);

View File

@@ -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` |

View File

@@ -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"

View File

@@ -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', () => {

View File

@@ -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}
>

View File

@@ -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>

View 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>
`;

View File

@@ -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();
});
});

View File

@@ -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`} />

View File

@@ -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"

View 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);
````

View File

@@ -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`:

View File

@@ -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;

View File

@@ -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` 为对象时,其中的字段:

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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> {

View File

@@ -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>

View File

@@ -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]&#x3A; 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:

View File

@@ -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]&#x3A; 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 如下:

View File

@@ -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;

View File

@@ -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"
>

View File

@@ -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);
});
});

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>
`;

View 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);
});
});

View File

@@ -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 => (

View File

@@ -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

View File

@@ -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>

View File

@@ -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>;
}
}

View File

@@ -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>

View File

@@ -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', () => {

View File

@@ -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,

View File

@@ -33,6 +33,10 @@
border-bottom: 0;
}
&-dark&-horizontal > &-item > a:before {
bottom: 0;
}
&-dark &-item,
&-dark &-item-group-title,
&-dark &-item > a {

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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 | - |

View File

@@ -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) {

View File

@@ -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 | - |

View File

@@ -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"

View 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);
````

View File

@@ -118,7 +118,7 @@
}
&:hover {
color: #404040;
color: shade(@text-color-secondary, 40%);
}
}

View File

@@ -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>

View File

@@ -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';

View File

@@ -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"

View File

@@ -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();
});
});

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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>;
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -77,6 +77,8 @@
}
&-blur {
pointer-events: none;
user-select: none;
overflow: hidden;
opacity: 0.7;
-webkit-filter: blur(0.5px);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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({

View File

@@ -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 }));

View File

@@ -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"
>

View File

@@ -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"
>

View File

@@ -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';

View File

@@ -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';

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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>
);
}

View File

@@ -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);

View File

@@ -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>
`;

View 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);
});
});
});

View File

@@ -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);
````

View File

@@ -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

View File

@@ -31,6 +31,7 @@ title: Timeline
| --- | --- | --- | --- |
| pending | 指定最后一个幽灵节点是否存在或内容 | boolean\|string\|ReactNode | false |
| pendingDot | 当最后一个幽灵节点存在時,指定其时间图点 | \|string\|ReactNode | `<Icon type="loading" />` |
| reverse | 节点排序 | boolean | false |
### Timeline.Item

View File

@@ -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;
}
}
}

View File

@@ -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, {

View File

@@ -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;
}

View File

@@ -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&lt;{ 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&lt;{ 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&lt;{ id: string, pId: string, rootPId: null }> | false |
| treeDefaultExpandAll | Whether to expand all treeNodes by default | boolean | false |
| treeDefaultExpandedKeys | Default expanded treeNodes | string\[] | - |

View File

@@ -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&lt;{value, label, children, [disabled, disableCheckbox, selectable]}> | \[] |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点value 在整个树范围内唯一) | array&lt;{value, label, children, [disabled, disableCheckbox, selectable]}>(如果定义了titlelabel会被title覆盖) | \[] |
| treeDataSimpleMode | 使用简单格式的 treeData具体设置参考可设置的类型 (此时 treeData 应变为这样的数据结构: [{id:1, pId:0, value:'1', label:"test1",...},...], `pId` 是父节点的 id) | false\|Array&lt;{ id: string, pId: string, rootPId: null }> | false |
| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false |
| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] | - |

View File

@@ -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;

View File

@@ -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);
});
});
});
});

View File

@@ -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;
}

View File

@@ -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
```

View File

@@ -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/*"
]
}

View File

@@ -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