Compare commits

...

309 Commits
3.4.2 ... 3.6.3

Author SHA1 Message Date
afc163
d6ee287924 bump 3.6.3 2018-06-19 15:15:11 +08:00
afc163
919e25d6d9 english changelog 2018-06-19 15:14:21 +08:00
afc163
39b4ff438f more changes 2018-06-19 15:14:21 +08:00
afc163
be8520de3c Add changelog for 3.6.3 2018-06-19 15:14:21 +08:00
afc163
8e8b991ba7 demo: fix table rowKey warning 2018-06-19 10:37:37 +08:00
afc163
b1d60f5ce1 Fix filterIcon className of Table, close #10937 2018-06-19 10:26:44 +08:00
愚道
5903fdb19f fix: Affix does not refix on offset prop changes 2018-06-19 10:04:15 +08:00
Alberto Gimeno
4b5d54671a Update App.tsx example to fix tslint errors
There were a few tslint errors and also the extension of the file name was `.js` instead of `.tsx`
2018-06-19 10:03:39 +08:00
Wei Zhu
5ab265a009 Fix small size fixed column table border
Close #9754
2018-06-15 17:40:32 +08:00
afc163
c540ceb8eb Fix fixed element in spin
close #10196
2018-06-15 14:09:51 +08:00
sliwey
450a497412 fix: upload preview can't show image when the image file use uppercase extension
1.fix: upload preview can't show image when the image file use uppercase extension.
	2.improve: remove unnecessary escape character.
2018-06-15 13:52:14 +08:00
ryannz
a5ff8e5de0 fix(AutoComplete): add missing backfill prop in type 2018-06-15 10:29:12 +08:00
hehe
07e06709f8 docs: fix typo 2018-06-15 10:25:17 +08:00
Zheeeng
980e2b1427 Update button signature (#10877) 2018-06-14 10:53:14 +08:00
afc163
713a0bcdc5 update snapshot 2018-06-13 20:21:52 +08:00
afc163
37ec04b21a Fix InputNumber style when zoom to 90% or below
close #10562
2018-06-13 17:31:26 +08:00
dependabot[bot]
01460c0297 Update rc-tween-one requirement to ^2.0.1
Updates the requirements on [rc-tween-one](https://github.com/react-component/tween-one) to permit the latest version.
- [Release notes](https://github.com/react-component/tween-one/releases)
- [Changelog](https://github.com/react-component/tween-one/blob/master/HISTORY.md)
- [Commits](https://github.com/react-component/tween-one/commits/2.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-06-12 22:33:14 +08:00
Lyndon001
f44584845b Update work-with-us.zh-CN.md 2018-06-12 17:22:16 +08:00
Lyndon001
f883a6f351 Update work-with-us.zh-CN.md 2018-06-12 17:20:55 +08:00
afc163
b3ed289904 chore: fix arrow position in Firefox 2018-06-12 16:27:46 +08:00
Zheeeng
f36c6195b8 Fix typo (#10878)
First of all, thank you for your contribution! :-)

Please makes sure that these checkboxes are checked before submitting your PR, thank you!

* [x] Make sure that you propose PR to right branch: bugfix for `master`, feature for latest active branch `feature-x.x`.
* [x] Make sure that you follow antd's [code convention](https://github.com/ant-design/ant-design/wiki/Code-convention-for-antd).
* [x] Run `npm run lint` and fix those errors before submitting in order to keep consistent code style.
* [x] Rebase before creating a PR to keep commit history clear.
* [ ] Add some descriptions and refer relative issues for you PR.

Extra checklist:

**if** *isBugFix* **:**

  * [ ] Make sure that you add at least one unit test for the bug which you had fixed.

**elif** *isNewFeature* **:**

  * [ ] Update API docs for the component.
  * [ ] Update/Add demo to demonstrate new feature.
  * [ ] Update TypeScript definition for the component.
  * [ ] Add unit tests for the feature.
2018-06-12 14:36:08 +08:00
Sebastian Busch
ee0a7ce3bb Form: add missing type definition for form create option validateMessages
(Docs for validateMessages had been added in rev 16133aac65 )
2018-06-12 14:32:08 +08:00
Sebastian Busch
619b0ed628 add type definition for missing third parameter "allFields" to onFieldsChange (introduced
(_Implementation_ of this parameter had been added in 16133aac65 )
2018-06-12 14:32:08 +08:00
Wei Zhu
99cad890ef Fix Tree types, TreeNode is a ComponentClass
Close #10868
2018-06-12 10:57:19 +08:00
afc163
7e2ba7e6d3 site: fix code demo icon style in IE 2018-06-10 23:03:07 +08:00
Wei Zhu
c3769e3b96 Bump 3.6.2 2018-06-10 12:04:00 +08:00
Wei Zhu
f597c32aa6 Add 3.6.2 changelog (#10856) 2018-06-10 11:53:50 +08:00
Wei Zhu
4d6f8e96b9 Improve AutoComplete types
close #10619
2018-06-09 16:01:18 +08:00
dependabot[bot]
ae6de361e2 Update eslint-plugin-react requirement to 7.9.1 (#10760)
Updates the requirements on [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) to permit the latest version.
<details>
<summary>Release notes</summary>

*Sourced from [eslint-plugin-react's releases](https://github.com/yannickcr/eslint-plugin-react/releases).*

> ## v7.9.1
> Nothing was fixed; this is a republish with some updated deps. ([#1804](https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1804) [**ljharb**](https://github.com/ljharb))
</details>
<details>
<summary>Changelog</summary>

*Sourced from [eslint-plugin-react's changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md).*

> ## [7.9.1] - 2018-06-03
> * Nothing was fixed; this is a republish with some updated deps. ([#1804][] [**ljharb**](https://github.com/ljharb))
> 
> [#1804]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1804
> 
> ## [7.9.0] - 2018-06-03
> ### Added
> * Add [`jsx-props-no-multi-spaces`][] rule ([#1755][] [**ThiefMaster**](https://github.com/ThiefMaster))
> * Add `first` option to [`jsx-indent-props`][] ([#398][] [**ThiefMaster**](https://github.com/ThiefMaster))
> * Add `enforceDynamicLinks` option to [`jsx-no-target-blank`][] ([#1737][] [**kenearley**](https://github.com/kenearley))
> 
> ### Fixed
> * Fix static lifecycle methods validation in [`sort-comp`][] ([#1793][] [**lynxtaa**](https://github.com/lynxtaa))
> * Fix crash in [`no-typos`][] when encountering anonymous react imports ([#1796][] [**jsg2021**](https://github.com/jsg2021))
> * Fix ESLint 3 support ([#1779][])
> 
> ### Changed
> * Documentation improvements ([#1794][] [**lencioni**](https://github.com/lencioni))
> * Update Travis CI configuration to test on multiple ESLint verions
> 
> [7.9.0]: https://github.com/yannickcr/eslint-plugin-react/compare/v7.8.2...v7.9.0
> [#1755]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/pull/1755
> [#398]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/398
> [#1737]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1737
> [#1793]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1793
> [#1796]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/pull/1796
> [#1779]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1779
> [#1794]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/pull/1794
> 
> ## [7.8.2] - 2018-05-13
> ### Fixed
> * Fix crash in [`boolean-prop-naming`][] when encountering a required shape prop type ([#1791][] [**pcorpet**](https://github.com/pcorpet))
> 
> [7.8.2]: https://github.com/yannickcr/eslint-plugin-react/compare/v7.8.1...v7.8.2
> [#1791]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1791
> 
> ## [7.8.1] - 2018-05-12
> ### Fixed
> * Fix crash in [`no-deprecated`][] when encountering a class constructor ([#1785][] [**taddei**](https://github.com/taddei))
> 
> [7.8.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v7.8.0...v7.8.1
> [#1785]: https://github-redirect.dependabot.com/yannickcr/eslint-plugin-react/issues/1785
> 
> ## [7.8.0] - 2018-05-11
> ### Added
> * Add support for fragments to [`react-in-jsx-scope`][] ([#1758][])
> * Add support for Flow generic PropType to [`require-default-props`][] ([#1724][] [**Miziak**](https://github.com/Miziak))
> * Add component whitelist option to [`forbid-component-props`][] ([#1732][] [**ThiefMaster**](https://github.com/ThiefMaster))
> * Add support for React 16.3 lifecycle methods to [`no-unused-prop-types`][] ([#1681][] [**bvaughn**](https://github.com/bvaughn))
> * Add support for React 16.3 lifecycle methods to [`sort-comp`][] ([#1767][] [**joe-denea**](https://github.com/joe-denea))
></table> ... (truncated)
</details>
<details>
<summary>Commits</summary>

- See full diff in [compare view](https://github.com/yannickcr/eslint-plugin-react/commits/v7.9.1)
</details>
<br />

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot ignore this [patch|minor|major] version` will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use (this|these) label[s]` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use (this|these) reviewer[s]` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use (this|these) assignee[s]` will set the current assignees as the default for future PRs for this repo and language

Additionally, you can set the following in your Dependabot [dashboard](https://app.dependabot.com):
- Update frequency (including time of day and day of week)
- Automerge options (never/patch/minor, and dev/runtime dependencies)
- Pull request limits (per update run and/or open at any time)
- Out-of-range updates (receive only lockfile updates, if desired)
- Security updates (receive only security updates, if desired)

Finally, you can contact us by mentioning @dependabot.

</details>
2018-06-09 14:51:15 +08:00
Wei Zhu
1a9456f03a Add boolean to CheckboxValueType
Close #10677
2018-06-09 14:39:42 +08:00
Wei Zhu
05c5115991 site: fix lint 2018-06-08 23:21:25 +08:00
bLue
8e26b6823a Fix spin delay issue if mounts with spinning=true (#10727)
* Fix spin delay issue if mounts with spinning=true

* Add test for spin delay issue

* Update spin lifecycle method
2018-06-08 23:13:47 +08:00
Wei Zhu
5174801b95 Revert "Upgrade react-dnd"
This reverts commit 71d2a991ed.
2018-06-08 19:01:54 +08:00
Wei Zhu
ac0b4bacc5 Revert "Update snapshot"
This reverts commit e7cd474894.
2018-06-08 19:01:34 +08:00
Wei Zhu
e7cd474894 Update snapshot 2018-06-08 18:13:51 +08:00
陈帅
789b54905c fix #10842 Badge status does not change with themes 2018-06-08 17:59:31 +08:00
Wei Zhu
71d2a991ed Upgrade react-dnd 2018-06-08 17:22:55 +08:00
picodoth
8610eb054f docs: remove changlog info for 3.6.1 2018-06-08 16:58:08 +08:00
afc163
71d3af310a Fix missing border in Button.Group
https://gw.alipayobjects.com/zos/rmsportal/hKuBQeoCgjruYXCGnrDt.png
2018-06-08 15:08:04 +08:00
Wei Zhu
89228118af docs: update moment locale usage 2018-06-08 12:22:22 +08:00
Kirill Alexander Khalitov
0ca1a990be Makes TreeNode component more type safe
Makes TreeNode component more type safe
2018-06-08 10:32:00 +08:00
Kirill Alexander Khalitov
74755fef99 Fix #10838
Fix [#10838](https://github.com/ant-design/ant-design/issues/10838)
2018-06-08 10:32:00 +08:00
Wei Zhu
396f81dbab Update cases.zh-CN.md 2018-06-07 11:58:16 +08:00
Wei Zhu
a4a3b5e12d Update cases.en-US.md 2018-06-07 11:57:11 +08:00
zombiej
78adc05973 close #10745, move dropdownMatchSelectWidth into AbstractSelectProps 2018-06-07 10:24:12 +08:00
zombiej
b524e1fe7e adjust defaultProps def 2018-06-07 00:33:52 +08:00
zombiej
8444ad209d close #10786, spin icon css for adjust font size 2018-06-06 19:53:50 +08:00
杨小事er
ad52250256 fix(calendar): fix fullcalendar content 2px overflow 2018-06-06 16:59:42 +08:00
Junbin Huang
e1ba74e5fc fix: still keep order when upload fails (#10794) 2018-06-06 12:13:06 +08:00
afc163
6602df16e6 Fix extra border style in Button.Group 2018-06-06 11:33:13 +08:00
afc163
17b158c091 Fix CheckboxAll status when remove data and selectedKeys
close #10629
2018-06-05 20:45:19 +08:00
Wei Zhu
c2d94ad84d Don't cache badge since they don't allow cor 2018-06-04 16:24:49 +08:00
Wei Zhu
57a01e1b9f Update offline-plugin 2018-06-04 15:00:43 +08:00
wangshantao
cdc571b17e 图片描述与内容不符 (#10755) 2018-06-04 10:41:47 +08:00
Junbin Huang
d69610a17f docs: update changelog for 3.6.1 (#10753) 2018-06-04 00:02:32 +08:00
Lyndon001
e13c1a678d Update introduce.zh-CN.md 2018-06-03 22:58:59 +08:00
afc163
248dbc2429 docs: update checkbox api 2018-06-03 16:28:20 +08:00
Junbin Huang
37d5f895d2 docs: clean up changelog (#10746) 2018-06-03 00:49:51 +08:00
picodoth
70ca0281ed 3.6.1 2018-06-02 20:41:59 +08:00
Junbin Huang
bbf5cb75c3 chore: update typescript@~2.9.1 (#10748) 2018-06-02 20:12:09 +08:00
Junbin Huang
30eacdfb1b chore: fix lint (#10747) 2018-06-02 18:49:39 +08:00
picodoth
f8314a6b1e docs: add author link correctly in changelog 2018-06-02 16:16:26 +08:00
picodoth
0ea890a0a4 docs: fix changelog typo 2018-06-02 16:02:43 +08:00
picodoth
0fdd13e5d6 chore: update change log for 3.6.0 2018-06-02 15:52:52 +08:00
picodoth
15637c885b 3.6.0 2018-06-02 15:52:52 +08:00
Jack Works
163ec46cbb Fix #9859, #9858 (#10294)
First of all, thank you for your contribution! :-)

Please makes sure that these checkboxes are checked before submitting your PR, thank you!

* [x] Make sure that you propose PR to right branch: bugfix for `master`, feature for latest active branch `feature-x.x`.
* [x] Make sure that you follow antd's [code convention](https://github.com/ant-design/ant-design/wiki/Code-convention-for-antd).
* [x] Run `npm run lint` and fix those errors before submitting in order to keep consistent code style.
* [x] Rebase before creating a PR to keep commit history clear.
* [x] Add some descriptions and refer relative issues for you PR.

Extra checklist:

**if** *isBugFix* **:**

  * [-] Make sure that you add at least one unit test for the bug which you had fixed.
2018-06-02 15:49:11 +08:00
Wei Zhu
2b5abd6dec Use forked offline-plugin 2018-06-02 14:20:03 +08:00
picodoth
e25323882a Merge branch 'feature-3.6.0' 2018-06-02 13:36:05 +08:00
afc163
e124cabc5b update badge snapshot test 2018-06-02 13:18:25 +08:00
Wei Zhu
7149d1fdff Add offline support (#10738)
* site: add offline support

* test update

* Revert "test update"

This reverts commit e1cb2fba80.

* use reduce
2018-06-02 12:46:09 +08:00
hank
5be1b9c33c Fix issue #8666 (#10739)
* fix issue #8666

* add issue #8666 test
2018-06-01 18:09:11 +08:00
Karol Majewski
7c273912fd Fix #10729 (#10730)
* Lift the requirement of the omitted keys being of string type

* Remove unused Diff mapped type
2018-06-01 16:58:15 +08:00
Wei Zhu
87163dfcd6 tests: mock xhr request
Close #10342
2018-05-31 22:37:09 +08:00
Wei Zhu
05251682f1 Remove window reference 2018-05-30 18:13:22 +08:00
Wei Zhu
31be3717ad Upgrade react-dnd 2018-05-30 17:56:56 +08:00
zombiej
ca7ed4c07d clean up 3.5.5 since warning 4.0.1 already fixed 2018-05-30 17:12:18 +08:00
dependabot[bot]
64a29dfd1a Update warning requirement to ~4.0.1
Updates the requirements on [warning](https://github.com/BerkeleyTrue/warning) to permit the latest version.
- [Release notes](https://github.com/BerkeleyTrue/warning/releases)
- [Changelog](https://github.com/BerkeleyTrue/warning/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BerkeleyTrue/warning/commits/v4.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-30 15:18:58 +08:00
afc163
b5c5f0b5d4 update snapshot 2018-05-29 23:50:49 +08:00
Wu Haotian
4f91fe61bf add z-index for fixed header demo
#10693
2018-05-29 23:49:09 +08:00
Eduardo Ludi
7f16ded760 Updates test for Transfer (removes snapshot) 2018-05-29 17:54:31 +08:00
Eduardo Ludi
9bc98b6471 Adds some tests for Transfer custom styles. 2018-05-29 17:54:31 +08:00
Eduardo Ludi
e8351b8104 Adds style prop to Transfer operation. 2018-05-29 17:54:31 +08:00
Eduardo Ludi
6d610de157 Adds support for custom styles in Transfer and Transfer operation. 2018-05-29 17:54:31 +08:00
Oleg Kuzava
be7f540fba Fix breakpoint for mobile view 2018-05-29 14:05:40 +08:00
afc163
814ee7365a tweak popover arrow style detail 2018-05-28 23:29:04 +08:00
afc163
5fd4139661 Fix Affix offsetBottom not working, close #10674 2018-05-28 17:49:11 +08:00
zombiej
e14928b4f9 update doc 2018-05-28 17:09:49 +08:00
zombiej
19a04e52f4 update change log 2018-05-28 15:34:04 +08:00
afc163
21ca50fca1 Merge branch 'master' into feature-3.6.0 2018-05-28 14:41:02 +08:00
afc163
38f94990f8 Merge branch 'feature-3.6.0' of github.com:ant-design/ant-design into feature-3.6.0 2018-05-28 14:40:58 +08:00
zombiej
d18f100721 Bump 3.5.5 2018-05-28 14:37:57 +08:00
Wu Haotian
b10e7c4e82 downgrade warning to 3.0.0 2018-05-28 14:00:29 +08:00
zombiej
9552f80cde update change-log 2018-05-27 10:39:03 +08:00
zombiej
ad0108dfd5 bump 3.5.4, update change log 2018-05-26 23:59:18 +08:00
zombiej
a6e2037c06 update test case 2018-05-26 23:18:18 +08:00
afc163
ac4a9086a0 test: press enter to search 2018-05-26 17:03:07 +08:00
afc163
12d0aedeca docs: make markdown format 2018-05-26 16:57:52 +08:00
afc163
36ffe7e1dc Search icon could be clicked, close #10634 2018-05-26 16:52:33 +08:00
Eric Celeste
b86f4eeaad improve english 2018-05-26 13:26:11 +08:00
afc163
3ceb619b92 Fix and optimize table demo, close #10639 2018-05-26 00:54:30 +08:00
clinyong
baa78bfa5f Change default word-break to break-word 2018-05-26 00:22:03 +08:00
afc163
8c2f99fd3e test alert 2018-05-25 21:56:57 +08:00
afc163
50057739bf Add test cases for Anchor 2018-05-25 21:43:21 +08:00
afc163
3a445f3e75 more test cases 2018-05-25 21:43:21 +08:00
afc163
be13326a1b Fix typo 2018-05-25 21:43:21 +08:00
afc163
93b14da4a6 improve test code 2018-05-25 21:43:21 +08:00
afc163
21db29bd53 Add test cases for Badge 2018-05-25 21:43:21 +08:00
afc163
d58c0780f9 test Popconfirm 2018-05-25 21:43:21 +08:00
afc163
042c014a38 test => it 2018-05-25 21:43:21 +08:00
afc163
aff9d8fc62 fix lint 2018-05-25 21:43:21 +08:00
afc163
b7b12b657c test: test carousel 2018-05-25 21:43:21 +08:00
afc163
0feaf95629 Fix breadcrumb test case 2018-05-25 21:43:21 +08:00
afc163
076540c83e test: breadcrumd work with react-router 2018-05-25 21:43:21 +08:00
afc163
3db0610d52 Add test case for Cascader 2018-05-25 21:43:21 +08:00
afc163
7222944347 test babel-plugin-import warning 2018-05-25 21:43:21 +08:00
afc163
322ebf0039 fix badge snapshot 2018-05-25 21:43:21 +08:00
Jinxuan Zhu
c2519e776b Add promise-like interface (#10470)
* Add promise-like interface

* Keep hide interface

* Shorten

* Test Promise

* Update document

* Update demo: 2.5 second is insignificant with the default 3s hiding

* Update demo: then  interface

* Fix line break

* Chainable

* Thenable demo

* Thenable test

* Fix tsc error

* Fix tsc error

* Better document

* Revert change in loading.md

* Change snapshot
2018-05-25 20:41:07 +08:00
Winter Zhong
33b604f7a8 Fix issue #10635 Parent element set text-align break Spin (#10643)
* fix the issue when settingthe  parent ele text-align center, the spin is on the right

* put the display in the proper place
2018-05-25 20:40:17 +08:00
dependabot[bot]
4c101275a5 Update jest requirement to ^23.0.0 (#10653)
Updates the requirements on [jest](https://github.com/facebook/jest) to permit the latest version.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/commits/v23.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-25 16:31:51 +08:00
dependabot[bot]
4c1b2369d7 Update warning requirement to ~4.0.0 (#10654)
Updates the requirements on [warning](https://github.com/BerkeleyTrue/warning) to permit the latest version.
- [Release notes](https://github.com/BerkeleyTrue/warning/releases)
- [Changelog](https://github.com/BerkeleyTrue/warning/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BerkeleyTrue/warning/commits/v4.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-25 16:31:34 +08:00
afc163
cbff10db15 test: update snapshots 2018-05-25 14:25:26 +08:00
afc163
b7cf33d1eb Fix test case temporarily 2018-05-24 21:45:40 +08:00
afc163
b828a599fb Fix test case temporarily 2018-05-24 21:40:56 +08:00
Rongjian Zhang
f3869270ae Fix #10142: Add theme props to Layout.Sider (#10631)
* Fix #10142: Add `theme` props to `Layout.Sider`

* Update documentation of Layout.Sider for new theme props

* Fix snapshot tests

* Add unit test for sider theme
2018-05-23 23:46:28 +08:00
afc163
2989e8dba0 docs: update API 2018-05-23 22:36:06 +08:00
afc163
6d8df2ac25 test: improve affix test case 2018-05-23 21:03:32 +08:00
Dmitry Snegirev
fd96b4a784 Added missing prop firstActiveValue in Select component (#10636) 2018-05-23 19:13:11 +08:00
jim
af8f4dc5c3 Merge branch 'master' into feature-3.6.0 2018-05-23 16:34:59 +08:00
afc163
8da79f4b34 Badge[status] should work with Tooltip
close #10626
2018-05-23 13:11:49 +08:00
afc163
247d78990e demo: improve editable row demo 2018-05-23 11:32:23 +08:00
Douglas Mason
acb56281f8 fix: update "from" to "form" in code example (#10628)
update `save` method parameter from `from` to `form` in code example
2018-05-23 10:55:20 +08:00
afc163
fafd83cadc Fix mention test case in react 15 2018-05-22 23:29:09 +08:00
afc163
7e96ae1a6a add jest.runAllTimers 2018-05-22 23:29:09 +08:00
afc163
3c381c6dd1 fix test case skip 2018-05-22 23:29:09 +08:00
afc163
292a91a777 Add test cases for Mention 2018-05-22 23:29:09 +08:00
afc163
89ed0dcb35 fix autoUpdateProgress percent and add test case 2018-05-22 23:29:09 +08:00
afc163
77301c378f skip mention test when test dist file 2018-05-22 23:29:09 +08:00
afc163
22d2f9eb01 update snapshot 2018-05-22 23:29:09 +08:00
afc163
3078819535 jest mock generateRandomKey for ssr test
facebook/draft-js#702
2018-05-22 23:29:09 +08:00
afc163
6471e5d4f0 write snapshot files 2018-05-22 23:29:09 +08:00
afc163
1e585135aa Try test mention to see what the problem is 2018-05-22 23:29:09 +08:00
Shun
6057821f39 Change order of loader option in docs (#10627) 2018-05-22 23:08:44 +08:00
Ivan Trofimov
33c58a8ef6 Update ru_RU.tsx (#10616)
* Update locale-provider ru_RU and tests

* Update locale-provider ru_RU and tests: patch-2
2018-05-22 16:31:12 +08:00
paranoidjk
b09e03d82a doc(Input): fix wrong desc about input size in form. 2018-05-22 06:50:14 +00:00
偏右
a2e0e40caa [WIP] Use raf to replace getRequestAnimationFrame (#10614)
* use raf to replace getRequestAnimationFrame

* remove isCssAnimationSupported
2018-05-22 13:01:28 +08:00
dependabot[bot]
f409df8d84 Update react-virtualized requirement to ~9.19.0 (#10552)
Updates the requirements on [react-virtualized](https://github.com/bvaughn/react-virtualized) to permit the latest version.
- [Release notes](https://github.com/bvaughn/react-virtualized/releases)
- [Changelog](https://github.com/bvaughn/react-virtualized/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bvaughn/react-virtualized/commits/9.19.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-22 11:26:32 +08:00
afc163
a148bc7b79 doc: update dependencies check badages 2018-05-22 11:26:12 +08:00
Walter Barbagallo
4077ffb58c Enhanced InputNumber props with HTMLInputElement attributes. (#10608)
* Enhanced InputNumber props with HTMLInputElement attributes.

It is possibile to use additional props supported by the inner input
element:

```
const inputEl = <InputNumber autoFocus />
```

Before this commit the type checker did not recognize the `autoFocus`
prop.

Some attributes must be omitted because they conflict with props
defined on `InputNumberProps` interface

* Renamed type

Probably they conflicts with a reserved name?
@see https://travis-ci.org/ant-design/ant-design/jobs/381668406
> components/input-number/index.tsx(9,93): error TS4022: 'extends' clause of exported interface 'InputNumberProps' has or is using private name 'OmitAttributes'.

* Replace InputNumber onKeyDown typing with the typed one.

Extending HTMLInputElement attributes the `onKeyDown` props now have a
better typing.

For example before this commit accessing to the event `key` attribute resulted
in a type error.
@see https://reactjs.org/docs/events.html#keyboard-events

* Exporting type OmitAttrs on InputNumber component.

This is an attempt to solve the ci error:
> components/input-number/index.tsx(9,93): error TS4022: 'extends' clause of exported
> interface 'InputNumberProps' has or is using private name 'OmitAttrs'.

@see https://travis-ci.org/ant-design/ant-design/jobs/381678316
2018-05-22 10:46:20 +08:00
Ezekiel Keator
bb4bc61556 Added missing API documentation (#10611)
* Added missing API documentation

Added missing Divider API documentation.

* Corrected styling

Corrected styling on dash to match other documentation pages.
2018-05-22 10:46:01 +08:00
afc163
0fc5a0ece5 site: add alt to images 2018-05-21 23:47:22 +08:00
afc163
6458280cb3 site: add alt to images 2018-05-21 23:42:57 +08:00
afc163
0f73b5d3f7 site: upgrade analytics code 2018-05-21 23:27:26 +08:00
afc163
14beee1fe1 site: add baidu tongji 2018-05-21 22:58:12 +08:00
dependabot[bot]
e0312f65ee Update stylelint requirement to 9.2.1 (#10553)
Updates the requirements on [stylelint](https://github.com/stylelint/stylelint) to permit the latest version.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/commits/9.2.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-21 22:33:53 +08:00
Zheeeng
389c7c4f10 DRY the styles writing for maintenance (#10220) 2018-05-21 21:53:20 +08:00
Zheeeng
59fe98a194 Add position config for List pagination (#10581) 2018-05-21 21:52:18 +08:00
Jamie.LiuMJ
2955600642 fix clearfix (#10563) 2018-05-21 21:52:15 +08:00
sosohime
d4ed303bcd doc: Update DatePicker document about locale (#10598) 2018-05-21 21:51:39 +08:00
Wei Zhu
ff458a2c3f Improve Input type definitions
Close #10166
2018-05-21 21:31:59 +08:00
zombiej
06ffd9ca04 Adjust Tree icon vertical-align, fix #10603 2018-05-21 21:24:16 +08:00
afc163
251d882101 fix dropdown any type 2018-05-21 21:02:03 +08:00
afc163
129baddc44 Remove some typescript any types of cascader 2018-05-21 20:35:14 +08:00
afc163
968488a2fa fix: Cascader showSearch not working bug, close #10599 2018-05-21 18:07:56 +08:00
afc163
00d710cef0 demo: fix select demo order 2018-05-21 17:07:39 +08:00
afc163
ddc242a9cb Merge branch 'master' into feature-3.6.0 2018-05-21 16:11:57 +08:00
jim
d6a554823f Rollback ci modification 2018-05-20 21:38:29 +08:00
jim
fd1d9661c0 update snap fix ci 2018-05-20 15:49:56 +08:00
jim
07b24f4edd fix doc 2018-05-20 14:57:52 +08:00
jim
dbd2bd1866 release 3.5.3 2018-05-20 14:57:52 +08:00
Zheeeng
8b420c41bb Fix typo (#10582)
* Fix typo: splited -> separated

* Fix typo: splited -> separated
2018-05-20 00:50:19 +08:00
方剑成
96d53aefb8 Remove redundant icons (#10583) 2018-05-20 00:49:48 +08:00
afc163
8e2f72ffe0 tweak dropdown menu item padding 2018-05-19 20:34:19 +08:00
afc163
29229ebee7 fix: input onDoubleClick type, close #10518 2018-05-19 20:01:47 +08:00
afc163
e1ad91119a change deps badges 2018-05-18 23:59:42 +08:00
dependabot[bot]
76bf36a79b Update eslint-plugin-react requirement to 7.8.2 (#10493)
Updates the requirements on [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) to permit the latest version.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/commits/v7.8.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-18 23:43:37 +08:00
Wei Zhu
aa87fcb01e Update snapshot 2018-05-18 18:53:26 +08:00
Wei Zhu
1ed9fed2cf Improve Button and Tag types 2018-05-18 18:22:33 +08:00
afc163
7c4f6e8b2a fix: Revert checkbox z-index
fix #10480

ref #10452

reverted for #10385
2018-05-18 15:36:54 +08:00
Zohaib Ijaz
df7ef9a833 site: Repalced generateColorLess script with antd-theme-generator
* Repalced generateColorLess script with antd-theme-generator which allows to dynamically change theme for all color variables

* Updated antd-theme-generator version

* Updated Ant styles directory path
2018-05-18 12:01:32 +08:00
afc163
9b17a943f5 site: use correct locale for component 2018-05-18 11:34:26 +08:00
qhxin
7404b7f36c fix Affix/index.tsx while offsetTop === 0 and offsetBottom is numberic (#10566)
* Update index.tsx

Fix: if offsetTop === 0, it will get undefined, if offsetBottom is type of number, offsetMode will be { top: false, ... }

* Update index.tsx
2018-05-18 10:18:19 +08:00
Walter Barbagallo
963120f702 Improved Form component typings (#10564)
* Improved Form component typings

With this fix you can use HTMLFormElement attributes on Form component
without getting TypeScript errors.

For example this code does not longer produce error for the additional
`autoComplete` prop:

```
const myForm = (
  <Form autoComplete="off">
    ...
  </Form>
)
```

* Fix onBlur / onChange typings with Input component

This improvement fix a typing issue incompatibility with
`react-final-form`
The incompatibility involve [this
line](https://github.com/final-form/react-final-form/blob/v3.4.2/src/index.d.ts#L20)
where the handler argument is a more specific SyntheticEvent
2018-05-17 23:45:13 +08:00
Wei Zhu
b7d508e166 Fix Row gutter type 2018-05-17 21:47:09 +08:00
afc163
cafeb8e3eb fix button group split border color 2018-05-17 21:36:05 +08:00
afc163
99dca86904 update button disable demo 2018-05-17 21:23:36 +08:00
afc163
09d5e36cfa style: fix hightlight link color in menu item 2018-05-17 21:17:20 +08:00
afc163
6e0865f691 fix less compile error 2018-05-17 17:20:47 +08:00
afc163
eb17aae25c Fix less import error again 2018-05-17 15:21:31 +08:00
afc163
593435ce65 fix import path 2018-05-17 14:39:33 +08:00
afc163
c4f58e7027 fix import path 2018-05-17 11:04:14 +08:00
afc163
b76910f63f fix typo 2018-05-16 11:49:35 +08:00
afc163
12d3046687 style: unify the less vars naming 2018-05-15 17:02:01 +08:00
afc163
d5d0501ac7 site: change footer ui 2018-05-15 12:40:15 +08:00
Wei Zhu
c7c85e3d5d docs: Revert unexpected modify 2018-05-15 12:11:21 +08:00
Wei Zhu
78af67a057 docs: fix table custom search panel demo
close #10494
2018-05-15 11:58:02 +08:00
Reed Sun
604584931e fix text error (#10510)
回掉 => 回调
2018-05-15 11:22:29 +08:00
afc163
77e21d33ea site: fix link 2018-05-14 21:25:38 +08:00
afc163
bdb4483ef5 site: add kitchen link in footer 2018-05-14 19:52:51 +08:00
Andreas Cederström
97c2d58d15 remove bundle size warning in test env (#10363) 2018-05-14 17:13:27 +08:00
Winter Zhong
f09c799bba add the border-right-width to fix the Input.Group component covered box-shadow effect (#10492) 2018-05-14 17:11:11 +08:00
afc163
bc8353729c site: add kitchen homepage 2018-05-14 13:58:54 +08:00
Wei Zhu
bf03d954d4 docs: Fix indent 2018-05-14 12:29:04 +08:00
Xiping.wang
413479a5b9 修改案例title值,原title值容易产生误导
修改案例title值,原title值容易产生误导
2018-05-14 12:08:50 +08:00
afc163
5e0b8df412 site: fix button align of home page 2018-05-14 00:07:39 +08:00
afc163
3413774ae5 update changelog 2018-05-14 00:06:06 +08:00
valleykid
41b9a79edb release 3.5.2 2018-05-13 22:51:50 +08:00
afc163
35b751da15 site: better responsive 2018-05-12 14:02:34 +08:00
afc163
f3545ccdc7 Merge branch 'master' into feature-3.6.0 2018-05-12 13:49:33 +08:00
Oleg Kuzava
71abb96de7 Allow to use any CSS units for layout width (#10479)
* Allow to use any CSS units for layout width

* Fix ts issues

* Fix parseFloat type check

* add tests for width in Sider

* clean up
2018-05-12 02:30:33 +08:00
dependabot[bot]
dd7fb9d351 Update unified requirement to ^7.0.0 (#10474)
Updates the requirements on [unified](https://github.com/unifiedjs/unified) to permit the latest version.
- [Release notes](https://github.com/unifiedjs/unified/releases)
- [Commits](https://github.com/unifiedjs/unified/commits/7.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-11 16:02:36 +08:00
tangjinzhou
4adf0b2571 docs: add vue-antd-ui link (#10463) 2018-05-10 23:56:22 +08:00
jiang
9e01b24272 fix 10445 (#10457)
* fix 10445

* re help anim timing

* refactor

* use this.helpShow

* is show no set state

* remove state.helpShow
2018-05-10 21:48:11 +08:00
jiang
1b8030ec59 Update customize-theme.zh-CN.md 2018-05-10 19:56:38 +08:00
jiang
2747aa341d Update customize-theme.en-US.md 2018-05-10 19:56:18 +08:00
picodoth
030c745e1b fix: checkbox trigger twice
regression introduced from d93cfde
2018-05-10 19:04:37 +08:00
Christopher Deutsch
dd0d4214d1 Omit 'ref' from ButtonProps otherwise typing conflicts occur. (#10426)
Fixes #10405
2018-05-10 11:21:07 +08:00
afc163
6eef4d0a42 chore: code style 2018-05-10 11:01:58 +08:00
afc163
6e6b1ccdec chore: code style 2018-05-10 10:59:33 +08:00
Jinxuan Zhu
832c524b32 Use local tslint config; simplify editor configuration (#10450) 2018-05-10 00:36:19 +08:00
afc163
bc4143f8a3 Fix Cascader displayRender z-index issue, close #10433 2018-05-09 18:16:08 +08:00
afc163
be31f17bca Change Dropdown.Button default icon to ellipsis 2018-05-09 18:01:07 +08:00
Lyndon001
dcb75a789d Update work-with-us.zh-CN.md 2018-05-09 17:56:19 +08:00
afc163
ffc182f4eb release 3.5.1 2018-05-09 16:35:18 +08:00
afc163
fbf09e86af site: show version info in home page 2018-05-09 10:45:45 +08:00
Xiaoming
7f2159e928 Message doc update & change variable statement (#10420)
* eslint disallow use of chained assignment expressions

eslint disallow use of chained assignment expressions

* revert

* message-doc-update

1.If a variable is never reassigned, using the const declaration is
better.
2.Defaultvalue’s type must be ‘number’ depend on type
2018-05-08 21:59:28 +08:00
Wei Zhu
04ee8526ab Revert "Fix table scroll x (#9704)"
This reverts commit 0d9dcb1714.
2018-05-08 16:23:10 +08:00
konakona
6c0d6d302a Add feature: can use type ReactNode for message of rules (#10136) (#10395)
* Add feature: can use type ReactNode for message of rules (#10136)

* fix: Replace React.Fragment to span

* Add unit test for Form (Not passed)

* fix: unit test of Form

* fix: unit test of Form & remove demo

* fix: update unit test for Form

* Refine code for Form

* Add error check for getHelpMessage
2018-05-08 14:00:00 +08:00
konakona
06f205874f Add missing semicolon (#10410)
* Add missing semicolon

* Remove semicolon for custom-typings.d.ts
2018-05-08 13:03:27 +08:00
afc163
20495dd5ba Fix monospaced number font weight issue
http://codesandbox.io/s/w705jk5wz7
2018-05-07 21:19:16 +08:00
陈帅
d5c5219111 new edit Table demo (#10119)
* new edit Table demo

* fix test error

* fix ci

* typo

* Skip edit-row test for React 15

* Set column width

* Update snapshot
2018-05-07 20:50:43 +08:00
afc163
5e99a93930 Fix collapse focused style 2018-05-07 17:57:49 +08:00
Zohaib Ijaz
bd81877cf8 #10007: Dynamic/Runtime Theme (#10384)
- Added links  to related articles
2018-05-07 16:12:28 +08:00
Wei Zhu
8a6d9b92b7 Improve table types
Fix #10374
2018-05-07 12:32:26 +08:00
afc163
d93cfdef09 clean up unnecessary z-index
close #9840

close #10385
2018-05-06 21:50:50 +08:00
afc163
e86f17186b Fix select test snapshot 2018-05-06 14:58:05 +08:00
afc163
6d91a3eb4a Fix select arrow overlap bug, close #10383
introduced by #10092, this commit also fix #10092
2018-05-06 14:54:27 +08:00
afc163
d95379cfa5 Fix broken style of Input with addons, close #10371 2018-05-05 19:50:48 +08:00
afc163
dbde26e560 docs: add disabled prop doc for Button, close #10373 2018-05-05 13:18:50 +08:00
Karol Majewski
1479726932 Use exact type for Breadcrumb.Item (#10372)
Using "any" breaks the build for TSLint users having the "no-unsafe-any" rule enabled.

See https://palantir.github.io/tslint/rules/no-unsafe-any/
2018-05-05 00:47:44 +08:00
愚指导
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
265 changed files with 8716 additions and 2406 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,165 @@ timeline: true
---
## 3.6.3
`2018-06-17`
- 🐞 Fixed that capitalized extension of Upload image url couldn't be recognaized. [#10928](https://github.com/ant-design/ant-design/pull/10928) [@sliwey](https://github.com/sliwey)
- 🐞 Fixed missing border of InputNumber when browser is zoomed in. [#10562](https://github.com/ant-design/ant-design/issues/10562)
- 🐞 Fixed that fixed element inside Spin cannot be fixed. [#10196](https://github.com/ant-design/ant-design/issues/10196)
- 🐞 Fixed broken border style of small table. [#9754](https://github.com/ant-design/ant-design/issues/9754)
- 🐞 Fixed missing `className` prop of Table's `filterIcon`. [#10937](https://github.com/ant-design/ant-design/issues/10937)
- 🐞 Fixed that Affix `offsetTop` and `offsetBottom` cannot be updated. [#10874](https://github.com/ant-design/ant-design/issues/10874)
- TypeScript
- 🐞 Fixed TreeSelect `TS2339` error. [#10868](https://github.com/ant-design/ant-design/issues/10868)
- 🌟 Added Form arguments definitions of `validateMessages` and `onFieldsChange`.
- 🌟 Improved Button prop definitions. [#10877](https://github.com/ant-design/ant-design/pull/10877) [@zheeeng](https://github.com/zheeeng)
- 🌟 Added `backfill` prop for AutoComplete. [#10909](https://github.com/ant-design/ant-design/pull/10909) [@zhanba](https://github.com/zhanba)
## 3.6.2
`2018-06-09`
- 🐞 Fix the wrong status of check all checkbox in Table when data change. [#10629](https://github.com/ant-design/ant-design/issues/10629)
- 🐞 Fix border style of Button.Group.
- 🐞 Fix file list being reversed when `beforeUpload` returns `false` in Upload component. [#10681](https://github.com/ant-design/ant-design/issues/10681)
- 🐞 Fix overflow of cell content in Calendar. [#10808](https://github.com/ant-design/ant-design/pull/10808) [@Yangzhedi](https://github.com/ant-design/Yangzhedi)
- 🐞 Fix the processing color of Badge not follows the `primary-color`.
- Spin
- 🐞 Fix custom icon does not follow the value of `size`. [#10786](https://github.com/ant-design/ant-design/issues/10786)
- 🐞 Fix no `delay` issue when sets `spinning` to `true` as default.[#10727](https://github.com/ant-design/ant-design/pull/10727) [@dreamerblue](https://github.com/dreamerblue)
- TypeScript
- 🐞 Fix Menu type definition. [#10773](https://github.com/ant-design/ant-design/issues/10773)
- 🐞 Fix AutoComplete type definition. [#10745](https://github.com/ant-design/ant-design/issues/10745) [#10619](https://github.com/ant-design/ant-design/issues/10619)
- 🐞 Fix Tree type definition. [#10841](https://github.com/ant-design/ant-design/pull/10841) [@Voronar](https://github.com/Voronar)
- 🐞 Fix Checkbox.Group definition. [#10677](https://github.com/ant-design/ant-design/pull/10677)
## 3.6.0
`2018-06-02`
* 🌟 `Form`'s error message now can be customized with ReactNode. [#10136](https://github.com/ant-design/ant-design/issues/10136) [@lovekonakona](https://github.com/lovekonakona)
* 🌟 `List` support customized configuration for position of pagination. [#10581](https://github.com/ant-design/ant-design/pull/10581) [@zheeeng](https://github.com/zheeeng)
* 🌟 `Layout.Sider` now can be configured with `light` or `dark` theme. [#10142](https://github.com/ant-design/ant-design/issues/10142) [@pd4d10](https://github.com/pd4d10)
* 🌟 Ant Design official site now supports offline mode. [#10625](https://github.com/ant-design/ant-design/issues/10625)
* 🌟 `Transfer` adding `style` and `operationStyle` props for further customization. [@eduludi](https://github.com/eduludi)
* 🌟 `Message` adds a promisfied interface to handle callback. [#10421](https://github.com/ant-design/ant-design/issues/10421) [@zhujinxuan](https://github.com/zhujinxuan)
* 🐞 Fix compilation issue with typescript@v2.9.1 . [#10729](https://github.com/ant-design/ant-design/issues/10729) [@karol-majewski](https://github.com/karol-majewski)
* 🐞 Fix a bug in `Menu` where outer menu item not highlighting while inner item is selected. [#8666](https://github.com/ant-design/ant-design/issues/8666) [@stonehank](https://github.com/stonehank)
* 🐞 Affix `offsetBottom` not working. [#10674](https://github.com/ant-design/ant-design/issues/10674)
## 3.5.4
`2018-05-26`
- 🐞 Fix `showSearch` on `Cascader` not working.[968488a2](https://github.com/ant-design/ant-design/commit/968488a2fac9bcb16bee9f0c248f49bca00dbec6)
- 🐞 `Badge[status]` support `Tooltip`.[#10626](https://github.com/ant-design/ant-design/issues/10626)
- 🐞 Fix `text-align` on parent element affects `Spin`.[#10643](https://github.com/ant-design/ant-design/pull/10643) [@wmzhong](https://github.com/wmzhong)
- 💄 `Table` break line style change from `break-all` to `break-word`.[#10655](https://github.com/ant-design/ant-design/pull/10655) [@clinyong](https://github.com/clinyong)
- 🌟 When `Search` not define `enterButton`, click search icon will trigger `onSearch`. [36ffe7e1](https://github.com/ant-design/ant-design/commit/36ffe7e1dc9d9473c8c68168ab79b7a03a604702)
## 3.5.3
`2018-05-20`
- 🐞 Fix `Affix` with offsetTop === 0, value becomes `undefined` problem [#10566](https://github.com/ant-design/ant-design/pull/10566)
- 🐞 Fixed issue with shaded `Input.Group` component shadows[#10230](https://github.com/ant-design/ant-design/issues/10230)
- 🐞 Fixed issue where the `Transfer` component checkbox event fired twice [#10480](https://github.com/ant-design/ant-design/issues/10480)
- 💄 Unifying the name of the variable [12d3046](https://github.com/ant-design/ant-design/commit/12d3046687a0dcdb51fece08dd2bea64f185cc40)
- 💄 Fine-tuned the style of `Dropdown` [8e2f72f](https://github.com/ant-design/ant-design/commit/8e2f72ffe0eb300f5997296726b02246bf990c8f)
- 💄 The components of the Chinese document will now be demonstrated using Chinese language packages. [9b17a94](https://github.com/ant-design/ant-design/commit/9b17a943f5d57d40d65041b7b0c247add09d2851)
- 💄 The main theme switch was changed to `antd-theme-generato`, thanks to the work of [@mzohaibqc](https://github.com/mzohaibqc).
- TypeScript
- 🐞 Fixed an issue with the type of gutter attribute in `Row` [b7d508e](https://github.com/ant-design/ant-design/commit/b7d508e1662bf20a0cacbe6440a2ce31a65a8a59)
- 💄 Improved the `Form` component type [#10564](https://github.com/ant-design/ant-design/pull/10564)
- 💄 Improved the `Button` and `Tag` types[1ed9fed](https://github.com/ant-design/ant-design/commit/1ed9fed2cf1c99b947359fafb101b2e58213cb48)
## 3.5.2
`2018-05-13`
- 🐞 Fixed `Table` filter doesn't work when click checkbox. [#10452](https://github.com/ant-design/ant-design/issues/10452)
- 🐞 Fixed `Cascader` displayRender z-index issue. [#10433](https://github.com/ant-design/ant-design/issues/10433)
- 🐞 Fixed `Button` Types of property 'ref' are incompatible. [#10405](https://github.com/ant-design/ant-design/issues/10405)
- 🐞 Fixed the height of `Form` item when checks position is dithered. [#10445](https://github.com/ant-design/ant-design/issues/10445)
- 🌟 Allow to use any CSS units for `Layout` width. [#10479](https://github.com/ant-design/ant-design/pull/10479)
## 3.5.1
`2018-05-09`
- 🐞 Fixed broken style of Input.Group under Form. [#10371](https://github.com/ant-design/ant-design/issues/10371)
- 🐞 Fixed overlay style of Select. [#10383](https://github.com/ant-design/ant-design/issues/10383)
- 🐞 Remove focused style of Collapse.
- 🐞 Remove unnecessary `z-index` of Input.Group and Checkbox. [#9840](https://github.com/ant-design/ant-design/issues/9840) [#10385](https://github.com/ant-design/ant-design/issues/10385)
- 🐞 Fixed that monospaced font family can't be bold.
- Table
- 💄 Rewrited the editable table demo. [#10119](https://github.com/ant-design/ant-design/pull/10119)
- 🐞 Fixed that table column overlay each other. [#9822](https://github.com/ant-design/ant-design/issues/9822)
- TypeScript
- 🐞 Fixed Breadcrumb.Item type. [#10372](https://github.com/ant-design/ant-design/pull/10372) [@karol-majewski](https://github.com/karol-majewski)
- 🐞 Fixed Table `rowSelection` type。[#10374](https://github.com/ant-design/ant-design/issues/10374)
## 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`
@@ -356,7 +515,7 @@ Happy 2018 !~ 2018 2018 2018 coming!~~~
`2017-12-04`
Learn more in the [Ant Design 3.0 announcement post](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)!
Learn more in the [Ant Design 3.0 announcement post](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c).
### Major Changes

View File

@@ -15,6 +15,166 @@ timeline: true
---
## 3.6.3
`2018-06-17`
- 🐞 修复 Upload 图片文件后缀名为大写时无法正确识别的问题。[#10928](https://github.com/ant-design/ant-design/pull/10928) [@sliwey](https://github.com/sliwey)
- 🐞 修复 InputNumber 在浏览器缩放时边框样式丢失的问题。[#10562](https://github.com/ant-design/ant-design/issues/10562)
- 🐞 修复 Spin 内使用 `position: fixed` 的元素无法固定的问题。[#10196](https://github.com/ant-design/ant-design/issues/10196)
- 🐞 修复小号表格下固定列的边框样式问题。[#9754](https://github.com/ant-design/ant-design/issues/9754)
- 🐞 修复 Table `filterIcon``className` 属性失效的问题。[#10937](https://github.com/ant-design/ant-design/issues/10937)
- 🐞 修复 Affix 的 `offsetTop``offsetBottom` 无法动态修改的问题。[#10874](https://github.com/ant-design/ant-design/issues/10874)
- TypeScript
- 🐞 修复 TreeSelect `TS2339` 错误。[#10868](https://github.com/ant-design/ant-design/issues/10868)
- 🌟 补充 Form 的 `validateMessages``onFieldsChange` 参数的定义。
- 🌟 优化 Button 的属性定义。[#10877](https://github.com/ant-design/ant-design/pull/10877) [@zheeeng](https://github.com/zheeeng)
- 🌟 补充 AutoComplete 的 `backfill` 属性定义。[#10909](https://github.com/ant-design/ant-design/pull/10909) [@zhanba](https://github.com/zhanba)
## 3.6.2
`2018-06-09`
- 🐞 修复 Table 数据变化时全选勾选框状态显示不正确的问题。[#10629](https://github.com/ant-design/ant-design/issues/10629)
- 🐞 修复 Button.Group 中使用 disabled 按钮时缺失边框。
- 🐞 修复 Upload 中 `beforeUpload` 返回 `false` 时,文件列表排序会被反转的问题。[#10681](https://github.com/ant-design/ant-design/issues/10681)
- 🐞 修复 Calendar 表格中内容溢出的问题。[#10808](https://github.com/ant-design/ant-design/pull/10808) [@Yangzhedi](https://github.com/ant-design/Yangzhedi)
- Spin
- 🐞 修复使用图标时不能按照 `size` 正确显示大小的问题。[#10786](https://github.com/ant-design/ant-design/issues/10786)
- 🐞 修复默认旋转时 `delay` 不生效的问题。[#10727](https://github.com/ant-design/ant-design/pull/10727) [@dreamerblue](https://github.com/dreamerblue)
- 修复 Badge 的状态色不跟主题色变化的问题。
- TypeScript
- 🐞 修复 Menu 类型定义。[#10773](https://github.com/ant-design/ant-design/issues/10773)
- 🐞 修复 AutoComplete 类型定义。[#10745](https://github.com/ant-design/ant-design/issues/10745) [#10619](https://github.com/ant-design/ant-design/issues/10619)
- 🐞 修复 Tree 类型定义。[#10841](https://github.com/ant-design/ant-design/pull/10841) [@Voronar](https://github.com/Voronar)
- 🐞 修复 Checkbox.Group 的类型定义。[#10677](https://github.com/ant-design/ant-design/pull/10677)
## 3.6.0
`2018-06-02`
* 🌟 `Form` 表单错误信息展示支持传入 ReactNode。 [#10136](https://github.com/ant-design/ant-design/issues/10136) [@lovekonakona](https://github.com/lovekonakona)
* 🌟 `List` 组件支持指定分页器的位置。 [#10581](https://github.com/ant-design/ant-design/pull/10581) [@zheeeng](https://github.com/zheeeng)
* 🌟 `Layout.Sider` 支持 dark/light 主题定制。 [#10142](https://github.com/ant-design/ant-design/issues/10142) [@pd4d10](https://github.com/pd4d10)
* 🌟 支持 Ant Design 站点的离线模式。 [#10625](https://github.com/ant-design/ant-design/issues/10625)
* 🌟 `Transfer` 新增 `style` 以及 `operationStyle` 属性配置样式。 [@eduludi](https://github.com/eduludi)
* 🌟 `Message` 增加 promise 化的回调接口。 [#10421](https://github.com/ant-design/ant-design/issues/10421) [@zhujinxuan](https://github.com/zhujinxuan)
* 🐞 修复编译时 typescript v2.9.1兼容性问题。 [#10729](https://github.com/ant-design/ant-design/issues/10729) [@karol-majewski](https://github.com/karol-majewski)
* 🐞 修复 `Menu` 嵌套超过两层时选中最里层后对应最外层没有亮起问题。 [#8666](https://github.com/ant-design/ant-design/issues/8666) [@stonehank](https://github.com/stonehank)
* 🐞 修复 `Affix` 组件 offsetBottom 无效问题。 [#10674](https://github.com/ant-design/ant-design/issues/10674)
## 3.5.4
`2018-05-26`
- 🐞 修复 `Cascader``showSearch` 无效问题。[968488a2](https://github.com/ant-design/ant-design/commit/968488a2fac9bcb16bee9f0c248f49bca00dbec6)
- 🐞 使 `Badge[status]` 支持 `Tooltip`。[#10626](https://github.com/ant-design/ant-design/issues/10626)
- 🐞 修复父元素使用 `text-align` 会影响 `Spin` 的问题。[#10643](https://github.com/ant-design/ant-design/pull/10643) [@wmzhong](https://github.com/wmzhong)
- 💄 `Table` 换行从 `break-all` 改为 `break-word`。[#10655](https://github.com/ant-design/ant-design/pull/10655) [@clinyong](https://github.com/clinyong)
- 🌟 `Search` 在未定义 `enterButton` 时,点击搜索图标将触发 `onSearch`。 [36ffe7e1](https://github.com/ant-design/ant-design/commit/36ffe7e1dc9d9473c8c68168ab79b7a03a604702)
## 3.5.3
`2018-05-20`
- 🐞 修复了 `Affix``offsetTop === 0`, 值将变为 `undefined` 的问题 [#10566](https://github.com/ant-design/ant-design/pull/10566)
- 🐞 修复了 `Menu` item 中的高亮链接颜色问题 [09d5e36](https://github.com/ant-design/ant-design/commit/09d5e36cfa27e371a7b4d4e68276a279698ea901)
- 🐞 修复了 `Input.Group` 组件阴影被遮盖的问题 [#10230](https://github.com/ant-design/ant-design/issues/10230)
- 🐞 修复了 `Transfer` 组件 checkbox 事件触发两次的问题 [`#10480`](https://github.com/ant-design/ant-design/issues/10480)
- 💄 统一 less 的变量命名 [12d3046](https://github.com/ant-design/ant-design/commit/12d3046687a0dcdb51fece08dd2bea64f185cc40)
- 💄 微调了 `Dropdown` 的样式 [8e2f72f](https://github.com/ant-design/ant-design/commit/8e2f72ffe0eb300f5997296726b02246bf990c8f)
- 💄 现在中文文档的组件会用中文语言包进行演示。[9b17a94](https://github.com/ant-design/ant-design/commit/9b17a943f5d57d40d65041b7b0c247add09d2851)
- 💄 主站主题切换 修改为 `antd-theme-generato` ,感谢 [@mzohaibqc](https://github.com/mzohaibqc) 的工作.
- TypeScript
- 🐞 修复了 `Row` 中 gutter 属性的类型问题 [b7d508e](https://github.com/ant-design/ant-design/commit/b7d508e1662bf20a0cacbe6440a2ce31a65a8a59)
- 💄 改进了 `Form` 组件类型 [#10564](https://github.com/ant-design/ant-design/pull/10564)
- 💄 改进了 `Button``Tag` 类型 [1ed9fed](https://github.com/ant-design/ant-design/commit/1ed9fed2cf1c99b947359fafb101b2e58213cb48)
## 3.5.2
`2018-05-13`
- 🐞 修复 `Table` 过滤器和 `Transfer` 复选框无法点击的问题。[#10452](https://github.com/ant-design/ant-design/issues/10452)
- 🐞 修复 `Cascader` `displayRender` 里的链接无法点击的问题。[#10433](https://github.com/ant-design/ant-design/issues/10433)
- 🐞 修复 `Button` ref 不兼容问题。[#10405](https://github.com/ant-design/ant-design/issues/10405)
- 🐞 修复 `Form` 表单项校验位置高度时出现抖动问题。[#10445](https://github.com/ant-design/ant-design/issues/10445)
- 🌟 设置 `Layout` 宽度时,允许使用任何的 CSS 单位。 [#10479](https://github.com/ant-design/ant-design/pull/10479)
## 3.5.1
`2018-05-09`
- 🐞 修复 Input.Group 在 Form 下样式错位的问题。[#10371](https://github.com/ant-design/ant-design/issues/10371)
- 🐞 修复 Select 箭头和内容重叠的问题。[#10383](https://github.com/ant-design/ant-design/issues/10383)
- 🐞 移除 Collapse 点击时的 focus 样式。
- 🐞 移除 Input.Group 和 Checkbox 不必要的 `z-index`。[#9840](https://github.com/ant-design/ant-design/issues/9840) [#10385](https://github.com/ant-design/ant-design/issues/10385)
- 🐞 修复一个数字等宽字体没有加粗的问题。
- Table
- 💄 重写了可编辑表格的演示。[#10119](https://github.com/ant-design/ant-design/pull/10119)
- 🐞 修复一个表格列内容互相重叠的问题。[#9822](https://github.com/ant-design/ant-design/issues/9822)
- TypeScript
- 🐞 调整 Breadcrumb.Item 的类型。[#10372](https://github.com/ant-design/ant-design/pull/10372) [@karol-majewski](https://github.com/karol-majewski)
- 🐞 修复 Table 的 `rowSelection` 的类型。[#10374](https://github.com/ant-design/ant-design/issues/10374)
## 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`
@@ -357,11 +517,11 @@ timeline: true
`2017-12-04`
更多内容见 [Ant Design 3.0 发布公告](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)
更多内容见 [Ant Design 3.0 发布公告](https://medium.com/ant-design/announcing-ant-design-3-0-70e3e65eca0c)
### 主要变化
- 全新的[色彩系统](https://ant.design/docs/spec/colors-cn#Color-Palettes),组件主色由 `#108EE9` 改为 `#1890FF`』,新主色我们称之为『拂晓蓝』。
- 全新的[色彩系统](https://ant.design/docs/spec/colors-cn#Color-Palettes),组件主色由『`#108EE9`』改为『`#1890FF`』,新主色我们称之为『拂晓蓝』。
- 全新的视觉样式和组件尺寸,更现代更美观。
- 基础字体大小由 `12px` 增大到 `14px`
- 默认语言由中文改为英文。
@@ -373,6 +533,8 @@ timeline: true
### 不兼容改动
> 如果你从 2.x 升级到 3.x建议直接升级到 3.x 的最新版本。
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。另外由于人肉查找代码中的废弃用法过于低效,所以我们提供了 [antd-migration-helper](https://github.com/ant-design/antd-migration-helper) 用于扫描代码中的废弃用法。
- Card 的 `noHovering` 属性重命名为 `hoverable`,且默认值改为 `true`
@@ -419,7 +581,7 @@ timeline: true
- Form 下的表单控件不再默认为 `size="large"`。
- `Input.Search` 默认的 🔍 图标只作为装饰,不再响应用户交互。需要添加可交互按钮请使用 `enterButton`。
- UMD 版本的 `dist/antd.js` 不再包含 moment使用的时候需要自己引入 moment。
- UMD 版本的 `dist/antd.js` 不再包含 moment使用的时候需要自己引入 moment。
```diff
<html>
<head>

View File

@@ -8,7 +8,8 @@
[![](https://img.shields.io/travis/ant-design/ant-design.svg?style=flat-square)](https://travis-ci.org/ant-design/ant-design)
[![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master)
[![Dependency Status](https://img.shields.io/gemnasium/react-component/trigger.svg?style=flat-square)](https://gemnasium.com/ant-design/ant-design)
[![bitHound [![Dependencies](https://img.shields.io/david/ant-design/ant-design.svg)](https://david-dm.org/ant-design/ant-design)
[![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design.svg)](https://david-dm.org/ant-design/ant-design#info=devDependencies&view=list)
[![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd)
[![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://www.npmtrends.com/antd)

View File

@@ -8,7 +8,8 @@
[![](https://img.shields.io/travis/ant-design/ant-design.svg?style=flat-square)](https://travis-ci.org/ant-design/ant-design)
[![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master)
[![Dependency Status](https://img.shields.io/gemnasium/react-component/trigger.svg?style=flat-square)](https://gemnasium.com/ant-design/ant-design)
[![Dependencies](https://img.shields.io/david/ant-design/ant-design.svg)](https://david-dm.org/ant-design/ant-design)
[![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design.svg)](https://david-dm.org/ant-design/ant-design#info=devDependencies&view=list)
[![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd)
[![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://www.npmtrends.com/antd)

View File

@@ -1,12 +1,18 @@
const OLD_NODE_ENV = process.env.NODE_ENV;
process.env.NODE_ENV = 'development';
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
const antd = require('..');
describe('antd', () => {
afterAll(() => {
process.env.NODE_ENV = OLD_NODE_ENV;
});
it('exports modules correctly', () => {
expect(Object.keys(antd)).toMatchSnapshot();
});
it('should hint when import all components', () => {
it('should hint when import all components in dev mode', () => {
expect(warnSpy).toBeCalledWith(
'You are using a whole package of antd, please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.'
);

View File

@@ -1,46 +0,0 @@
const availablePrefixs = ['moz', 'ms', 'webkit'];
function requestAnimationFramePolyfill() {
let lastTime = 0;
return function(callback: (n: number) => void) {
const currTime = new Date().getTime();
const timeToCall = Math.max(0, 16 - (currTime - lastTime));
const id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
export default function getRequestAnimationFrame() {
if (typeof window === 'undefined') {
return () => {};
}
if (window.requestAnimationFrame) {
// https://github.com/vuejs/vue/issues/4465
return window.requestAnimationFrame.bind(window);
}
const prefix = availablePrefixs.filter(key => `${key}RequestAnimationFrame` in window)[0];
return prefix
? (window as any)[`${prefix}RequestAnimationFrame`]
: requestAnimationFramePolyfill();
}
export function cancelRequestAnimationFrame(id: number) {
if (typeof window === 'undefined') {
return null;
}
if (window.cancelAnimationFrame) {
return window.cancelAnimationFrame(id);
}
const prefix = availablePrefixs.filter(key =>
`${key}CancelAnimationFrame` in window || `${key}CancelRequestAnimationFrame` in window,
)[0];
return prefix ?
(
(window as any)[`${prefix}CancelAnimationFrame`] ||
(window as any)[`${prefix}CancelRequestAnimationFrame`]
).call(this, id) : clearTimeout(id);
}

View File

@@ -1,24 +0,0 @@
let animation: boolean;
function isCssAnimationSupported() {
if (animation !== undefined) {
return animation;
}
const domPrefixes = 'Webkit Moz O ms Khtml'.split(' ');
const elm = document.createElement('div');
if (elm.style.animationName !== undefined) {
animation = true;
}
if (animation !== undefined) {
for (let i = 0; i < domPrefixes.length; i++) {
if ((elm.style as any)[`${domPrefixes[i]}AnimationName`] !== undefined) {
animation = true;
break;
}
}
}
animation = animation || false;
return animation;
}
export default isCssAnimationSupported;

View File

@@ -1,7 +1,5 @@
import cssAnimation from 'css-animation';
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from './getRequestAnimationFrame';
const reqAnimFrame = getRequestAnimationFrame();
import raf from 'raf';
function animate(node: HTMLElement, show: boolean, done: () => void) {
let height: number;
@@ -19,16 +17,16 @@ function animate(node: HTMLElement, show: boolean, done: () => void) {
},
active() {
if (requestAnimationFrameId) {
cancelRequestAnimationFrame(requestAnimationFrameId);
raf.cancel(requestAnimationFrameId);
}
requestAnimationFrameId = reqAnimFrame(() => {
requestAnimationFrameId = raf(() => {
node.style.height = `${show ? height : 0}px`;
node.style.opacity = show ? '1' : '0';
});
},
end() {
if (requestAnimationFrameId) {
cancelRequestAnimationFrame(requestAnimationFrameId);
raf.cancel(requestAnimationFrameId);
}
node.style.height = '';
node.style.opacity = '';

View File

@@ -1,6 +1,4 @@
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from '../_util/getRequestAnimationFrame';
const reqAnimFrame = getRequestAnimationFrame();
import raf from 'raf';
export default function throttleByAnimationFrame(fn: (...args: any[]) => void) {
let requestId: number | null;
@@ -12,11 +10,11 @@ export default function throttleByAnimationFrame(fn: (...args: any[]) => void) {
const throttled = (...args: any[]) => {
if (requestId == null) {
requestId = reqAnimFrame(later(args));
requestId = raf(later(args));
}
};
(throttled as any).cancel = () => cancelRequestAnimationFrame(requestId!);
(throttled as any).cancel = () => raf.cancel(requestId!);
return throttled;
}

View File

@@ -1,3 +1 @@
export type Diff<T extends string, U extends string> = ({ [P in T]: P } &
{ [P in U]: never } & { [x: string]: never })[T];
export type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

View File

@@ -7,7 +7,6 @@ const events = {};
class AffixMounter extends React.Component {
componentDidMount() {
this.container.scrollTop = 100;
this.container.addEventListener = jest.fn().mockImplementation((event, cb) => {
events[event] = cb;
});
@@ -34,6 +33,7 @@ class AffixMounter extends React.Component {
<Affix
target={() => this.container}
ref={ele => this.affix = ele}
{...this.props}
>
<Button type="primary" >
Fixed at the top of container
@@ -46,6 +46,8 @@ class AffixMounter extends React.Component {
}
describe('Affix Render', () => {
let wrapper;
beforeAll(() => {
jest.useFakeTimers();
});
@@ -54,23 +56,63 @@ describe('Affix Render', () => {
jest.useRealTimers();
});
it('Anchor render perfectly', () => {
document.body.innerHTML = '<div id="mounter" />';
const wrapper = mount(<AffixMounter />, { attachTo: document.getElementById('mounter') });
jest.runAllTimers();
const scrollTo = (top) => {
wrapper.instance().affix.fixedNode.parentNode.getBoundingClientRect = jest.fn(() => {
return {
bottom: 100, height: 28, left: 0, right: 0, top: -50, width: 195,
bottom: 100, height: 28, left: 0, right: 0, top: 50 - top, width: 195,
};
});
wrapper.instance().container.scrollTop = top;
events.scroll({
type: 'scroll',
});
jest.runAllTimers();
};
it('Anchor render perfectly', () => {
document.body.innerHTML = '<div id="mounter" />';
wrapper = mount(<AffixMounter />, { attachTo: document.getElementById('mounter') });
jest.runAllTimers();
scrollTo(0);
expect(wrapper.instance().affix.state.affixStyle).toBe(null);
scrollTo(100);
expect(wrapper.instance().affix.state.affixStyle).not.toBe(null);
scrollTo(0);
expect(wrapper.instance().affix.state.affixStyle).toBe(null);
});
it('support offsetBottom', () => {
document.body.innerHTML = '<div id="mounter" />';
wrapper = mount(<AffixMounter offsetBottom={0} />, { attachTo: document.getElementById('mounter') });
jest.runAllTimers();
scrollTo(0);
expect(wrapper.instance().affix.state.affixStyle).not.toBe(null);
scrollTo(100);
expect(wrapper.instance().affix.state.affixStyle).toBe(null);
scrollTo(0);
expect(wrapper.instance().affix.state.affixStyle).not.toBe(null);
});
it('updatePosition when offsetTop changed', () => {
document.body.innerHTML = '<div id="mounter" />';
wrapper = mount(<AffixMounter offsetTop={0} />, { attachTo: document.getElementById('mounter') });
jest.runAllTimers();
scrollTo(100);
expect(wrapper.instance().affix.state.affixStyle.top).toBe(0);
wrapper.setProps({
offsetTop: 10,
});
jest.runAllTimers();
expect(wrapper.instance().affix.state.affixStyle.top).toBe(10);
});
});

View File

@@ -16,16 +16,46 @@ The simplest usage.
````jsx
import { Affix, Button } from 'antd';
class Demo extends React.Component {
state = {
top: 10,
bottom: 10,
}
render() {
return (
<div>
<Affix offsetTop={this.state.top}>
<Button
type="primary"
onClick={() => {
this.setState({
top: this.state.top + 10,
});
}}
>
Affix top
</Button>
</Affix>
<br />
<Affix offsetBottom={this.state.bottom}>
<Button
type="primary"
onClick={() => {
this.setState({
bottom: this.state.bottom + 10,
});
}}
>
Affix bottom
</Button>
</Affix>
</div>
);
}
}
ReactDOM.render(
<div>
<Affix>
<Button type="primary">Affix top</Button>
</Affix>
<br />
<Affix offsetBottom={0}>
<Button type="primary">Affix bottom</Button>
</Affix>
</div>,
<Demo />,
mountNode
);
````

View File

@@ -38,8 +38,7 @@ function getOffset(element: HTMLElement, target: HTMLElement | Window | null) {
function noop() {}
function getDefaultTarget() {
return typeof window !== 'undefined' ?
window : null;
return typeof window !== 'undefined' ? window : null;
}
// Affix
@@ -145,7 +144,9 @@ export default class Affix extends React.Component<AffixProps, AffixState> {
const targetNode = target();
// Backwards support
offsetTop = offsetTop || offset;
// Fix: if offsetTop === 0, it will get undefined,
// if offsetBottom is type of number, offsetMode will be { top: false, ... }
offsetTop = typeof offsetTop === 'undefined' ? offset : offsetTop;
const scrollTop = getScroll(targetNode, true);
const affixNode = ReactDOM.findDOMNode(this) as HTMLElement;
const elemOffset = getOffset(affixNode, targetNode);
@@ -232,6 +233,12 @@ export default class Affix extends React.Component<AffixProps, AffixState> {
// Mock Event object.
this.updatePosition({});
}
if (
this.props.offsetTop !== nextProps.offsetTop ||
this.props.offsetBottom !== nextProps.offsetBottom
) {
this.updatePosition({});
}
}
componentWillUnmount() {

View File

@@ -0,0 +1,31 @@
import React from 'react';
import { mount } from 'enzyme';
import Alert from '..';
describe('Alert', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
it('could be closed', () => {
const onClose = jest.fn();
const afterClose = jest.fn();
const wrapper = mount(
<Alert
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
type="warning"
closable
onClose={onClose}
afterClose={afterClose}
/>
);
wrapper.find('.ant-alert-close-icon').simulate('click');
expect(onClose).toBeCalled();
jest.runAllTimers();
expect(afterClose).toBeCalled();
});
});

View File

@@ -16,7 +16,7 @@ title: Alert
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| afterClose | 关闭动画结束后的回掉 | () => void | - |
| afterClose | 关闭动画结束后触发的回调函数 | () => void | - |
| banner | 是否用作顶部公告 | boolean | false |
| closable | 默认不显示关闭按钮 | boolean | 无 |
| closeText | 自定义关闭按钮 | string\|ReactNode | 无 |

View File

@@ -6,7 +6,7 @@ import addEventListener from 'rc-util/lib/Dom/addEventListener';
import Affix from '../affix';
import AnchorLink from './AnchorLink';
import getScroll from '../_util/getScroll';
import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
import raf from 'raf';
function getDefaultContainer() {
return window;
@@ -43,7 +43,6 @@ function easeInOutCubic(t: number, b: number, c: number, d: number) {
return cc / 2 * ((t -= 2) * t * t + 2) + b;
}
const reqAnimFrame = getRequestAnimationFrame();
const sharpMatcherRegx = /#([^#]+)$/;
function scrollTo(href: string, offsetTop = 0, getContainer: () => AnchorContainer, callback = () => { }) {
const container = getContainer();
@@ -67,12 +66,12 @@ function scrollTo(href: string, offsetTop = 0, getContainer: () => AnchorContain
(container as HTMLElement).scrollTop = nextScrollTop;
}
if (time < 450) {
reqAnimFrame(frameFunc);
raf(frameFunc);
} else {
callback();
}
};
reqAnimFrame(frameFunc);
raf(frameFunc);
history.pushState(null, '', href);
}

View File

@@ -28,7 +28,7 @@ describe('Anchor Render', () => {
expect(wrapper.instance().state.activeLink).toBe('http://www.example.com/#API');
});
it('Anchor render perfectly for complete href - scoll', () => {
it('Anchor render perfectly for complete href - scroll', () => {
let root = document.getElementById('root');
if (!root) {
root = document.createElement('div', { id: 'root' });
@@ -45,7 +45,8 @@ describe('Anchor Render', () => {
expect(wrapper.instance().state.activeLink).toBe('http://www.example.com/#API');
});
it('Anchor render perfectly for complete href - scollTo', () => {
it('Anchor render perfectly for complete href - scrollTo', async () => {
const scrollToSpy = jest.spyOn(window, 'scrollTo');
let root = document.getElementById('root');
if (!root) {
root = document.createElement('div', { id: 'root' });
@@ -60,5 +61,33 @@ describe('Anchor Render', () => {
);
wrapper.instance().handleScrollTo('##API');
expect(wrapper.instance().state.activeLink).toBe('##API');
expect(scrollToSpy).not.toHaveBeenCalled();
await new Promise(resolve => setTimeout(resolve, 50));
expect(scrollToSpy).toHaveBeenCalled();
expect(wrapper.instance().animating).toBe(true);
await new Promise(resolve => setTimeout(resolve, 500));
expect(wrapper.instance().animating).toBe(false);
});
it('should remove listener when unmount', async () => {
const wrapper = mount(
<Anchor>
<Link href="#API" title="API" />
</Anchor>
);
const removeListenerSpy = jest.spyOn(wrapper.instance().scrollEvent, 'remove');
wrapper.unmount();
expect(removeListenerSpy).toHaveBeenCalled();
});
it('should unregister link when unmount children', async () => {
const wrapper = mount(
<Anchor>
<Link href="#API" title="API" />
</Anchor>
);
expect(wrapper.instance().links).toEqual(['#API']);
wrapper.setProps({ children: null });
expect(wrapper.instance().links).toEqual([]);
});
});

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

@@ -6,7 +6,11 @@ import Input from '../input';
import InputElement from './InputElement';
export interface DataSourceItemObject { value: string; text: string; }
export type DataSourceItemType = string | DataSourceItemObject;
export type DataSourceItemType =
string |
DataSourceItemObject |
React.ReactElement<OptionProps> |
React.ReactElement<OptGroupProps>;
export interface AutoCompleteInputProps {
onChange?: React.FormEventHandler<any>;
@@ -22,6 +26,7 @@ export interface AutoCompleteProps extends AbstractSelectProps {
value?: SelectValue;
defaultValue?: SelectValue;
dataSource?: DataSourceItemType[];
backfill?: boolean;
optionLabelProp?: string;
onChange?: (value: SelectValue) => void;
onSelect?: (value: SelectValue, option: Object) => any;

View File

@@ -75,7 +75,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
render() {
const {
prefixCls, shape, size, src, icon, className, ...others,
prefixCls, shape, size, src, icon, className, ...others
} = this.props;
const sizeCls = classNames({

View File

@@ -4,9 +4,7 @@ import addEventListener from 'rc-util/lib/Dom/addEventListener';
import classNames from 'classnames';
import omit from 'omit.js';
import getScroll from '../_util/getScroll';
import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
const reqAnimFrame = getRequestAnimationFrame();
import raf from 'raf';
const easeInOutCubic = (t: number, b: number, c: number, d: number) => {
const cc = c - b;
@@ -64,10 +62,10 @@ export default class BackTop extends React.Component<BackTopProps, any> {
const time = timestamp - startTime;
this.setScrollTop(easeInOutCubic(time, scrollTop, 0, 450));
if (time < 450) {
reqAnimFrame(frameFunc);
raf(frameFunc);
}
};
reqAnimFrame(frameFunc);
raf(frameFunc);
(this.props.onClick || noop)(e);
}

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,65 @@
import React from 'react';
import { mount } from 'enzyme';
import { mount, render } from 'enzyme';
import Badge from '../index';
import Tooltip from '../../tooltip';
describe('Badge', () => {
test('badge dot not scaling count > 9', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('badge dot not scaling count > 9', () => {
const badge = mount(<Badge count={10} dot />);
expect(badge.find('.ant-card-multiple-words').length).toBe(0);
});
test('badge dot not showing count == 0', () => {
it('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');
});
// https://github.com/ant-design/ant-design/issues/10626
it('should be composable with Tooltip', () => {
const wrapper = mount(
<Tooltip title="Fix the error">
<Badge status="error" />
</Tooltip>
);
wrapper.find('Badge').simulate('mouseenter');
jest.runAllTimers();
expect(wrapper.instance().tooltip.props.visible).toBe(true);
});
it('should render when count is changed', () => {
const wrapper = mount(<Badge count={9} />);
wrapper.setProps({ count: 10 });
jest.runAllTimers();
expect(wrapper).toMatchSnapshot();
wrapper.setProps({ count: 11 });
jest.runAllTimers();
expect(wrapper).toMatchSnapshot();
wrapper.setProps({ count: 11 });
jest.runAllTimers();
expect(wrapper).toMatchSnapshot();
wrapper.setProps({ count: 10 });
jest.runAllTimers();
expect(wrapper).toMatchSnapshot();
jest.runAllTimers();
wrapper.setProps({ count: 9 });
expect(wrapper).toMatchSnapshot();
});
it('should be compatible with borderColor style', () => {
const wrapper = render(<Badge count={4} style={{ backgroundColor: '#fff', color: '#999', borderColor: '#d9d9d9' }} />);
expect(wrapper).toMatchSnapshot();
});
});

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,7 +58,8 @@ export default class Badge extends React.Component<BadgeProps, any> {
status,
text,
offset,
...restProps,
title,
...restProps
} = this.props;
let displayCount = (count as number) > (overflowCount as number) ? `${overflowCount}+` : count;
const isZero = displayCount === '0' || displayCount === 0;
@@ -90,7 +92,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
// <Badge status="success" />
if (!children && status) {
return (
<span className={badgeCls} style={styleWithOffset}>
<span {...restProps} className={badgeCls} style={styleWithOffset}>
<span className={statusCls} />
<span className={`${prefixCls}-status-text`}>{text}</span>
</span>
@@ -103,8 +105,9 @@ export default class Badge extends React.Component<BadgeProps, any> {
data-show={!hidden}
className={scrollNumberCls}
count={displayCount}
title={count}
title={title || count}
style={styleWithOffset}
key="scrollNumber"
/>
);

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

@@ -41,7 +41,7 @@ function defaultItemRender(route: Route, params: any, routes: Route[], paths: st
}
export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
static Item: any;
static Item: typeof BreadcrumbItem;
static defaultProps = {
prefixCls: 'ant-breadcrumb',

View File

@@ -0,0 +1,170 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`react router react router 3 1`] = `
<Breadcrumb
params={
Object {
"id": 1,
}
}
prefixCls="ant-breadcrumb"
routes={
Array [
Object {
"breadcrumbName": "Home",
"childRoutes": Array [
Object {
"breadcrumbName": "Application List",
"childRoutes": Array [
Object {
"breadcrumbName": "Application:id",
"childRoutes": Array [
Object {
"breadcrumbName": "Detail",
"name": "detail",
"path": "detail",
},
],
"name": "app",
"path": ":id",
},
],
"name": "apps",
"path": "apps",
},
],
"name": "home",
"path": "/",
},
Object {
"breadcrumbName": "Application List",
"childRoutes": Array [
Object {
"breadcrumbName": "Application:id",
"childRoutes": Array [
Object {
"breadcrumbName": "Detail",
"name": "detail",
"path": "detail",
},
],
"name": "app",
"path": ":id",
},
],
"name": "apps",
"path": "apps",
},
Object {
"breadcrumbName": "Application:id",
"childRoutes": Array [
Object {
"breadcrumbName": "Detail",
"name": "detail",
"path": "detail",
},
],
"name": "app",
"path": ":id",
},
Object {
"breadcrumbName": "Detail",
"name": "detail",
"path": "detail",
},
]
}
separator="/"
>
<div
className="ant-breadcrumb"
>
<BreadcrumbItem
key="Home"
prefixCls="ant-breadcrumb"
separator="/"
>
<span>
<span
className="ant-breadcrumb-link"
>
<a
href="#/"
>
Home
</a>
</span>
<span
className="ant-breadcrumb-separator"
>
/
</span>
</span>
</BreadcrumbItem>
<BreadcrumbItem
key="Application List"
prefixCls="ant-breadcrumb"
separator="/"
>
<span>
<span
className="ant-breadcrumb-link"
>
<a
href="#/apps"
>
Application List
</a>
</span>
<span
className="ant-breadcrumb-separator"
>
/
</span>
</span>
</BreadcrumbItem>
<BreadcrumbItem
key="Application:id"
prefixCls="ant-breadcrumb"
separator="/"
>
<span>
<span
className="ant-breadcrumb-link"
>
<a
href="#/apps/1"
>
Application1
</a>
</span>
<span
className="ant-breadcrumb-separator"
>
/
</span>
</span>
</BreadcrumbItem>
<BreadcrumbItem
key="Detail"
prefixCls="ant-breadcrumb"
separator="/"
>
<span>
<span
className="ant-breadcrumb-link"
>
<span>
Detail
</span>
</span>
<span
className="ant-breadcrumb-separator"
>
/
</span>
</span>
</BreadcrumbItem>
</div>
</Breadcrumb>
`;

View File

@@ -0,0 +1,150 @@
import React from 'react';
import { Route, Switch, Link, withRouter, MemoryRouter } from 'react-router-dom';
import { mount } from 'enzyme';
import Breadcrumb from '../index';
const Apps = () => (
<ul className="app-list">
<li>
<Link to="/apps/1">Application1</Link><Link to="/apps/1/detail">Detail</Link>
</li>
<li>
<Link to="/apps/2">Application2</Link><Link to="/apps/2/detail">Detail</Link>
</li>
</ul>
);
const breadcrumbNameMap = {
'/apps': 'Application List',
'/apps/1': 'Application1',
'/apps/2': 'Application2',
'/apps/1/detail': 'Detail',
'/apps/2/detail': 'Detail',
};
const Home = withRouter((props) => {
const { location, history } = props;
const pathSnippets = location.pathname.split('/').filter(i => i);
const extraBreadcrumbItems = pathSnippets.map((_, index) => {
const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
return (
<Breadcrumb.Item key={url}>
<Link to={url}>
{breadcrumbNameMap[url]}
</Link>
</Breadcrumb.Item>
);
});
const breadcrumbItems = [(
<Breadcrumb.Item key="home">
<Link to="/">Home</Link>
</Breadcrumb.Item>
)].concat(extraBreadcrumbItems);
return (
<div className="demo">
<div className="demo-nav">
<a onClick={() => history.push('/')}>Home</a>
<a onClick={() => history.push('/apps')}>Application List</a>
</div>
<Switch>
<Route path="/apps" component={Apps} />
<Route render={() => <span>Home Page</span>} />
</Switch>
<Breadcrumb>
{breadcrumbItems}
</Breadcrumb>
</div>
);
});
describe('react router', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
// https://github.com/airbnb/enzyme/issues/875
it('react router 4', () => {
const wrapper = mount(
<MemoryRouter initialEntries={['/']} initialIndex={0}>
<Home />
</MemoryRouter>
);
expect(wrapper.find('BreadcrumbItem').length).toBe(1);
expect(wrapper.find('BreadcrumbItem .ant-breadcrumb-link').at(0).text()).toBe('Home');
wrapper.find('.demo-nav a').at(1).simulate('click');
expect(wrapper.find('BreadcrumbItem').length).toBe(2);
expect(wrapper.find('BreadcrumbItem .ant-breadcrumb-link').at(1).text()).toBe('Application List');
});
it('react router 3', () => {
const routes = [{
name: 'home',
breadcrumbName: 'Home',
path: '/',
childRoutes: [
{
name: 'apps',
breadcrumbName: 'Application List',
path: 'apps',
childRoutes: [
{
name: 'app',
breadcrumbName: 'Application:id',
path: ':id',
childRoutes: [
{
name: 'detail',
breadcrumbName: 'Detail',
path: 'detail',
},
],
},
],
},
],
},
{
name: 'apps',
breadcrumbName: 'Application List',
path: 'apps',
childRoutes: [
{
name: 'app',
breadcrumbName: 'Application:id',
path: ':id',
childRoutes: [
{
name: 'detail',
breadcrumbName: 'Detail',
path: 'detail',
},
],
},
],
},
{
name: 'app',
breadcrumbName: 'Application:id',
path: ':id',
childRoutes: [
{
name: 'detail',
breadcrumbName: 'Detail',
path: 'detail',
},
],
},
{
name: 'detail',
breadcrumbName: 'Detail',
path: 'detail',
}];
const wrapper = mount(
<Breadcrumb routes={routes} params={{ id: 1 }} />
);
expect(wrapper).toMatchSnapshot();
});
});

View File

@@ -211,24 +211,6 @@ exports[`renders ./components/button/demo/disabled.md correctly 1`] = `
</span>
</button>
<br />
<button
class="ant-btn ant-btn-background-ghost"
type="button"
>
<span>
Ghost
</span>
</button>
<button
class="ant-btn ant-btn-background-ghost"
disabled=""
type="button"
>
<span>
Ghost(disabled)
</span>
</button>
<br />
<button
class="ant-btn ant-btn-dashed"
type="button"
@@ -246,6 +228,27 @@ exports[`renders ./components/button/demo/disabled.md correctly 1`] = `
Dashed(disabled)
</span>
</button>
<div
style="padding:8px 8px 0 8px;background:rgb(190, 200, 200)"
>
<button
class="ant-btn ant-btn-background-ghost"
type="button"
>
<span>
Ghost
</span>
</button>
<button
class="ant-btn ant-btn-background-ghost"
disabled=""
type="button"
>
<span>
Ghost(disabled)
</span>
</button>
</div>
</div>
`;

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', () => {
@@ -46,7 +61,7 @@ describe('Button', () => {
expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true);
});
it('have static perperty for type detecting', () => {
it('have static property for type detecting', () => {
const wrapper = mount(
<Button>Button Text</Button>
);

View File

@@ -2,7 +2,6 @@ import * as React from 'react';
import { findDOMNode } from 'react-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import omit from 'omit.js';
import Icon from '../icon';
import Group from './button-group';
@@ -37,30 +36,32 @@ function insertSpace(child: React.ReactChild, needInserted: boolean) {
export type ButtonType = 'default' | 'primary' | 'ghost' | 'dashed' | 'danger';
export type ButtonShape = 'circle' | 'circle-outline';
export type ButtonSize = 'small' | 'default' | 'large';
export type ButtonHTMLType = 'submit' | 'button' | 'reset';
export interface ButtonProps {
export interface BaseButtonProps {
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 type AnchorButtonProps = {
href: string;
target?: string;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
} & BaseButtonProps & React.AnchorHTMLAttributes<HTMLAnchorElement>;
export type NativeButtonProps = {
htmlType?: ButtonHTMLType;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
} & BaseButtonProps & React.ButtonHTMLAttributes<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 +144,7 @@ export default class Button extends React.Component<ButtonProps, any> {
}
}
handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
// Add click effect
this.setState({ clicked: true });
clearTimeout(this.timeout);
@@ -151,19 +152,18 @@ export default class Button extends React.Component<ButtonProps, any> {
const onClick = this.props.onClick;
if (onClick) {
onClick(e);
(onClick as React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>)(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() {
const {
type, shape, size, className, htmlType, children, icon, prefixCls, ghost, ...others,
type, shape, size, className, children, icon, prefixCls, ghost, loading: _loadingProp, ...rest
} = this.props;
const { loading, clicked, hasTwoCNChar } = this.state;
@@ -181,8 +181,6 @@ export default class Button extends React.Component<ButtonProps, any> {
break;
}
const ComponentProp = others.href ? 'a' : 'button';
const classes = classNames(prefixCls, className, {
[`${prefixCls}-${type}`]: type,
[`${prefixCls}-${shape}`]: shape,
@@ -199,15 +197,30 @@ export default class Button extends React.Component<ButtonProps, any> {
const kids = (children || children === 0)
? React.Children.map(children, child => insertSpace(child, this.isNeedInserted())) : null;
return (
<ComponentProp
{...omit(others, ['loading'])}
type={others.href ? undefined : (htmlType || 'button')}
className={classes}
onClick={this.handleClick}
>
{iconNode}{kids}
</ComponentProp>
);
if ('href' in rest) {
return (
<a
{...rest}
className={classes}
onClick={this.handleClick}
>
{iconNode}{kids}
</a>
);
} else {
// React does not recognize the `htmlType` prop on a DOM element. Here we pick it out of `rest`.
const { htmlType, ...otherProps } = rest;
return (
<button
{...otherProps}
type={htmlType || 'button'}
className={classes}
onClick={this.handleClick}
>
{iconNode}{kids}
</button>
);
}
}
}

View File

@@ -24,11 +24,12 @@ ReactDOM.render(
<Button>Default</Button>
<Button disabled>Default(disabled)</Button>
<br />
<Button ghost>Ghost</Button>
<Button ghost disabled>Ghost(disabled)</Button>
<br />
<Button type="dashed">Dashed</Button>
<Button type="dashed" disabled>Dashed(disabled)</Button>
<div style={{ padding: '8px 8px 0 8px', background: 'rgb(190, 200, 200)' }}>
<Button ghost>Ghost</Button>
<Button ghost disabled>Ghost(disabled)</Button>
</div>
</div>,
mountNode
);

View File

@@ -21,6 +21,7 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
| htmlType | set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` |
| icon | set the icon of button, see: Icon component | string | - |
| loading | set the loading status of button | boolean \| { delay: number } | false |
| disabled | disabled state of button | boolean | `false` |
| shape | can be set to `circle` or omitted | string | - |
| size | can be set to `small` `large` or omitted | string | `default` |
| target | same as target attribute of a, works when href is specified | string | - |

View File

@@ -24,6 +24,7 @@ subtitle: 按钮
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` |
| icon | 设置按钮的图标类型 | string | - |
| loading | 设置按钮载入状态 | boolean \| { delay: number } | `false` |
| disabled | 按钮失效状态 | boolean | `false` |
| shape | 设置按钮形状,可选值为 `circle` 或者不设 | string | - |
| size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default` |
| target | 相当于 a 链接的 target 属性href 存在时生效 | string | - |

View File

@@ -250,11 +250,16 @@
.@{btnClassName} + &,
span + .@{btnClassName},
.@{btnClassName} + span,
> span + span,
& + .@{btnClassName},
& + & {
margin-left: -1px;
}
.@{btnClassName}-primary + .@{btnClassName}:not(.@{btnClassName}-primary):not([disabled]) {
border-left-color: transparent;
}
.@{btnClassName}:not(:first-child):not(:last-child) {
border-radius: 0;
}

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>
@@ -236,7 +236,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="October 31, 2016"
>
@@ -796,7 +796,7 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="November 30, 2016"
>
@@ -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>
@@ -1245,7 +1245,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="October 31, 2016"
>
@@ -1805,7 +1805,7 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="November 30, 2016"
>
@@ -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>
@@ -2256,7 +2256,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="October 31, 2016"
>
@@ -3093,7 +3093,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="November 30, 2016"
>
@@ -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>
@@ -4211,7 +4211,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</td>
<td
class="ant-fullcalendar-cell"
class="ant-fullcalendar-cell ant-fullcalendar-last-day-of-month"
role="gridcell"
title="January 31, 2017"
>

View File

@@ -235,7 +235,7 @@
}
&-fullscreen &-content {
height: 90px;
height: 88px;
overflow-y: auto;
position: static;
width: auto;

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,8 +133,8 @@ export default class Card extends React.Component<CardProps, CardState> {
}
render() {
const {
prefixCls = 'ant-card', className, extra, bodyStyle, noHovering, hoverable, title, loading,
bordered = true, type, cover, actions, tabList, children, activeTabKey, defaultActiveTabKey, ...others,
prefixCls = 'ant-card', className, extra, bodyStyle = {}, noHovering, hoverable, title, loading,
bordered = true, type, cover, actions, tabList, children, activeTabKey, defaultActiveTabKey, ...others
} = this.props;
const classString = classNames(prefixCls, className, {
@@ -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

@@ -3,6 +3,14 @@ import { mount } from 'enzyme';
import Carousel from '..';
describe('Carousel', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
it('should has innerSlider', () => {
const wrapper = mount(<Carousel><div /></Carousel>);
const { innerSlider } = wrapper.instance();
@@ -10,4 +18,42 @@ describe('Carousel', () => {
expect(innerSlider).toBe(innerSliderFromRefs);
expect(typeof innerSlider.slickNext).toBe('function');
});
it('should has prev, next and go function', () => {
const wrapper = mount(<Carousel><div>1</div><div>2</div><div>3</div></Carousel>);
const { prev, next, goTo } = wrapper.instance();
expect(typeof prev).toBe('function');
expect(typeof next).toBe('function');
expect(typeof goTo).toBe('function');
expect(wrapper.instance().slick.innerSlider.state.currentSlide).toBe(0);
wrapper.instance().goTo(2);
jest.runAllTimers();
expect(wrapper.instance().slick.innerSlider.state.currentSlide).toBe(2);
wrapper.instance().prev();
jest.runAllTimers();
expect(wrapper.instance().slick.innerSlider.state.currentSlide).toBe(1);
wrapper.instance().next();
jest.runAllTimers();
expect(wrapper.instance().slick.innerSlider.state.currentSlide).toBe(2);
});
it('should trigger autoPlay after window resize', async () => {
jest.useRealTimers();
const wrapper = mount(<Carousel autoplay><div>1</div><div>2</div><div>3</div></Carousel>);
const spy = jest.spyOn(wrapper.instance().slick.innerSlider, 'autoPlay');
window.resizeTo(1000);
expect(spy).not.toBeCalled();
await new Promise(resolve => setTimeout(resolve, 500));
expect(spy).toBeCalled();
});
it('cancel resize listener when unmount', async () => {
const wrapper = mount(<Carousel autoplay><div>1</div><div>2</div><div>3</div></Carousel>);
const onWindowResized = wrapper.instance().onWindowResized;
const spy = jest.spyOn(wrapper.instance().onWindowResized, 'cancel');
const spy2 = jest.spyOn(window, 'removeEventListener');
wrapper.unmount();
expect(spy).toBeCalled();
expect(spy2).toBeCalledWith('resize', onWindowResized);
});
});

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"
@@ -189,7 +211,7 @@ exports[`renders ./components/cascader/demo/lazy.md correctly 1`] = `
exports[`renders ./components/cascader/demo/search.md correctly 1`] = `
<span
class="ant-cascader-picker"
class="ant-cascader-picker ant-cascader-picker-show-search"
tabindex="0"
>
<span

View File

@@ -215,6 +215,632 @@ exports[`Cascader popup correctly with defaultValue 1`] = `
</div>
`;
exports[`Cascader should highlight keyword and filter when search in Cascader 1`] = `
<Popup
action={
Array [
"click",
]
}
align={
Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tl",
"bl",
],
}
}
className=""
destroyPopupOnHide={false}
getClassNameFromAlign={[Function]}
getRootDomNode={[Function]}
mask={false}
onAlign={[Function]}
prefixCls="ant-cascader-menus"
style={Object {}}
transitionName="slide-up"
visible={true}
>
<div>
<Animate
animation={Object {}}
component=""
componentProps={Object {}}
exclusive={true}
onAppear={[Function]}
onEnd={[Function]}
onEnter={[Function]}
onLeave={[Function]}
showProp="xVisible"
transitionAppear={true}
transitionEnter={true}
transitionLeave={true}
transitionName="slide-up"
>
<AnimateChild
animation={Object {}}
key="popup"
transitionAppear={true}
transitionEnter={true}
transitionLeave={true}
transitionName="slide-up"
>
<Align
align={
Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tl",
"bl",
],
}
}
childrenProps={
Object {
"visible": "xVisible",
}
}
disabled={false}
key="popup"
monitorBufferTime={50}
monitorWindowResize={true}
onAlign={[Function]}
target={[Function]}
xVisible={true}
>
<PopupInner
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
hiddenClassName="ant-cascader-menus-hidden"
prefixCls="ant-cascader-menus"
style={Object {}}
visible={true}
>
<div
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
style={Object {}}
>
<LazyRenderBox
className="ant-cascader-menus-content"
visible={true}
>
<Menus
activeValue={Array []}
allowClear={true}
builtinPlacements={
Object {
"bottomLeft": Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tl",
"bl",
],
},
"bottomRight": Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tr",
"br",
],
},
"topLeft": Object {
"offset": Array [
0,
-4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"bl",
"tl",
],
},
"topRight": Object {
"offset": Array [
0,
-4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"br",
"tr",
],
},
}
}
defaultFiledNames={
Object {
"children": "children",
"label": "label",
"value": "value",
}
}
disabled={false}
dropdownMenuColumnStyle={
Object {
"width": 0,
}
}
expandTrigger="click"
filedNames={
Object {
"children": "children",
"label": "label",
"value": "value",
}
}
inputPrefixCls="ant-input"
notFoundContent="Not Found"
onChange={[Function]}
onPopupVisibleChange={[Function]}
onSelect={[Function]}
options={
Array [
Object {
"__IS_FILTERED_OPTION": true,
"disabled": false,
"label": Array [
"Jiangsu",
Array [
" / ",
"Nanjing",
],
Array [
" / ",
"Zhong Hua Men",
],
],
"path": Array [
Object {
"children": Array [
Object {
"children": Array [
Object {
"label": "Zhong Hua Men",
"value": "zhonghuamen",
},
],
"label": "Nanjing",
"value": "nanjing",
},
],
"label": "Jiangsu",
"value": "jiangsu",
},
Object {
"children": Array [
Object {
"label": "Zhong Hua Men",
"value": "zhonghuamen",
},
],
"label": "Nanjing",
"value": "nanjing",
},
Object {
"label": "Zhong Hua Men",
"value": "zhonghuamen",
},
],
"value": Array [
"jiangsu",
"nanjing",
"zhonghuamen",
],
},
Object {
"__IS_FILTERED_OPTION": true,
"disabled": false,
"label": Array [
"Zhejiang",
Array [
" / ",
Array [
"Hang",
Array [
<span
className="ant-cascader-menu-item-keyword"
>
z
</span>,
"hou",
],
],
],
Array [
" / ",
"West Lake",
],
],
"path": Array [
Object {
"children": Array [
Object {
"children": Array [
Object {
"label": "West Lake",
"value": "xihu",
},
],
"label": "Hangzhou",
"value": "hangzhou",
},
],
"label": "Zhejiang",
"value": "zhejiang",
},
Object {
"children": Array [
Object {
"label": "West Lake",
"value": "xihu",
},
],
"label": "Hangzhou",
"value": "hangzhou",
},
Object {
"label": "West Lake",
"value": "xihu",
},
],
"value": Array [
"zhejiang",
"hangzhou",
"xihu",
],
},
]
}
placeholder="Please select"
popupClassName=""
popupPlacement="bottomLeft"
popupVisible={true}
prefixCls="ant-cascader"
showSearch={
Object {
"filter": [Function],
}
}
transitionName="slide-up"
value={Array []}
visible={true}
>
<div>
<ul
className="ant-cascader-menu"
key="0"
style={
Object {
"width": 0,
}
}
>
<li
className="ant-cascader-menu-item"
key="jiangsu,nanjing,zhonghuamen"
onClick={[Function]}
title=""
>
Jiangsu
/
Nanjing
/
Zhong Hua Men
</li>
<li
className="ant-cascader-menu-item"
key="zhejiang,hangzhou,xihu"
onClick={[Function]}
title=""
>
Zhejiang
/
Hang
<span
className="ant-cascader-menu-item-keyword"
key="seperator"
>
z
</span>
hou
/
West Lake
</li>
</ul>
</div>
</Menus>
</LazyRenderBox>
</div>
</PopupInner>
</Align>
</AnimateChild>
</Animate>
</div>
</Popup>
`;
exports[`Cascader should render not found content 1`] = `
<Popup
action={
Array [
"click",
]
}
align={
Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tl",
"bl",
],
}
}
className=""
destroyPopupOnHide={false}
getClassNameFromAlign={[Function]}
getRootDomNode={[Function]}
mask={false}
onAlign={[Function]}
prefixCls="ant-cascader-menus"
style={Object {}}
transitionName="slide-up"
visible={true}
>
<div>
<Animate
animation={Object {}}
component=""
componentProps={Object {}}
exclusive={true}
onAppear={[Function]}
onEnd={[Function]}
onEnter={[Function]}
onLeave={[Function]}
showProp="xVisible"
transitionAppear={true}
transitionEnter={true}
transitionLeave={true}
transitionName="slide-up"
>
<AnimateChild
animation={Object {}}
key="popup"
transitionAppear={true}
transitionEnter={true}
transitionLeave={true}
transitionName="slide-up"
>
<Align
align={
Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tl",
"bl",
],
}
}
childrenProps={
Object {
"visible": "xVisible",
}
}
disabled={false}
key="popup"
monitorBufferTime={50}
monitorWindowResize={true}
onAlign={[Function]}
target={[Function]}
xVisible={true}
>
<PopupInner
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
hiddenClassName="ant-cascader-menus-hidden"
prefixCls="ant-cascader-menus"
style={Object {}}
visible={true}
>
<div
className="ant-cascader-menus ant-cascader-menus-placement-bottomLeft "
style={Object {}}
>
<LazyRenderBox
className="ant-cascader-menus-content"
visible={true}
>
<Menus
activeValue={Array []}
allowClear={true}
builtinPlacements={
Object {
"bottomLeft": Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tl",
"bl",
],
},
"bottomRight": Object {
"offset": Array [
0,
4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"tr",
"br",
],
},
"topLeft": Object {
"offset": Array [
0,
-4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"bl",
"tl",
],
},
"topRight": Object {
"offset": Array [
0,
-4,
],
"overflow": Object {
"adjustX": 1,
"adjustY": 1,
},
"points": Array [
"br",
"tr",
],
},
}
}
defaultFiledNames={
Object {
"children": "children",
"label": "label",
"value": "value",
}
}
disabled={false}
dropdownMenuColumnStyle={
Object {
"height": "auto",
"width": 0,
}
}
expandTrigger="click"
filedNames={
Object {
"children": "children",
"label": "label",
"value": "value",
}
}
inputPrefixCls="ant-input"
notFoundContent="Not Found"
onChange={[Function]}
onPopupVisibleChange={[Function]}
onSelect={[Function]}
options={
Array [
Object {
"disabled": true,
"label": "Not Found",
"value": "ANT_CASCADER_NOT_FOUND",
},
]
}
placeholder="Please select"
popupClassName=""
popupPlacement="bottomLeft"
popupVisible={true}
prefixCls="ant-cascader"
showSearch={
Object {
"filter": [Function],
}
}
transitionName="slide-up"
value={Array []}
visible={true}
>
<div>
<ul
className="ant-cascader-menu"
key="0"
style={
Object {
"height": "auto",
"width": 0,
}
}
>
<li
className="ant-cascader-menu-item ant-cascader-menu-item-disabled"
key="ANT_CASCADER_NOT_FOUND"
onClick={[Function]}
title="Not Found"
>
Not Found
</li>
</ul>
</div>
</Menus>
</LazyRenderBox>
</div>
</PopupInner>
</Align>
</AnimateChild>
</Animate>
</div>
</Popup>
`;
exports[`Cascader support controlled mode 1`] = `
<span
class="ant-cascader-picker"

View File

@@ -28,6 +28,10 @@ const options = [{
}],
}];
function filter(inputValue, path) {
return path.some(option => (option.label).toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
}
describe('Cascader', () => {
focusTest(Cascader);
@@ -39,11 +43,13 @@ describe('Cascader', () => {
});
it('popup correctly when panel is open', () => {
const onPopupVisibleChange = jest.fn();
const wrapper = mount(
<Cascader options={options} />
<Cascader options={options} onPopupVisibleChange={onPopupVisibleChange} />
);
wrapper.find('input').simulate('click');
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
expect(onPopupVisibleChange).toHaveBeenCalledWith(true);
});
it('support controlled mode', () => {
@@ -64,8 +70,18 @@ describe('Cascader', () => {
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
});
it('should support popupVisible', () => {
const wrapper = mount(
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />
);
expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(false);
wrapper.setProps({ popupVisible: true });
expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(true);
});
it('can be selected', () => {
const wrapper = mount(<Cascader options={options} />);
const onChange = jest.fn();
const wrapper = mount(<Cascader options={options} onChange={onChange} />);
wrapper.find('input').simulate('click');
let popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
popupWrapper.find('.ant-cascader-menu').at(0).find('.ant-cascader-menu-item').at(0)
@@ -79,6 +95,7 @@ describe('Cascader', () => {
popupWrapper.find('.ant-cascader-menu').at(2).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
});
it('backspace should work with `Cascader[showSearch]`', () => {
@@ -89,4 +106,88 @@ describe('Cascader', () => {
// Simulate onKeyDown will not trigger onChange by default, so the value is still '123'
expect(wrapper.state('inputValue')).toBe('123');
});
it('should highlight keyword and filter when search in Cascader', () => {
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
wrapper.find('input').simulate('click');
wrapper.find('input').simulate('change', { target: { value: 'z' } });
expect(wrapper.state('inputValue')).toBe('z');
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(popupWrapper).toMatchSnapshot();
});
it('should render not found content', () => {
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
wrapper.find('input').simulate('click');
wrapper.find('input').simulate('change', { target: { value: '__notfoundkeyword__' } });
expect(wrapper.state('inputValue')).toBe('__notfoundkeyword__');
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(popupWrapper).toMatchSnapshot();
});
it('should support to clear selection', () => {
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('Zhejiang / Hangzhou');
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('');
});
it('should close popup when clear selection', () => {
const onPopupVisibleChange = jest.fn();
const wrapper = mount(
<Cascader
options={options}
popupVisible
defaultValue={['zhejiang', 'hangzhou']}
onPopupVisibleChange={onPopupVisibleChange}
/>
);
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
expect(onPopupVisibleChange).toHaveBeenCalledWith(false);
});
it('should clear search input when clear selection', () => {
const wrapper = mount(
<Cascader
options={options}
defaultValue={['zhejiang', 'hangzhou']}
showSearch
/>
);
wrapper.find('input').simulate('click');
wrapper.find('input').simulate('change', { target: { value: 'xxx' } });
expect(wrapper.state('inputValue')).toBe('xxx');
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
expect(wrapper.state('inputValue')).toBe('');
});
it('should not trigger visible change when click search input', () => {
const onPopupVisibleChange = jest.fn();
const wrapper = mount(
<Cascader
options={options}
showSearch
onPopupVisibleChange={onPopupVisibleChange}
/>
);
wrapper.find('input').simulate('focus');
expect(onPopupVisibleChange).toHaveBeenCalledTimes(0);
wrapper.find('input').simulate('click');
expect(onPopupVisibleChange).toHaveBeenCalledTimes(1);
wrapper.find('input').simulate('click');
expect(onPopupVisibleChange).toHaveBeenCalledTimes(1);
wrapper.find('input').simulate('blur');
wrapper.setState({ popupVisible: false });
wrapper.find('input').simulate('click');
expect(onPopupVisibleChange).toHaveBeenCalledTimes(2);
});
it('should change filtered item when options are changed', () => {
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
wrapper.find('input').simulate('click');
wrapper.find('input').simulate('change', { target: { value: 'a' } });
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
wrapper.setProps({ options: [options[0]] });
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1);
});
});

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,36 @@ 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 +81,7 @@ export interface CascaderProps {
inputPrefixCls?: string;
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
popupVisible?: boolean;
filedNames?: FiledNamesType;
}
export interface CascaderState {
@@ -71,7 +89,7 @@ export interface CascaderState {
inputValue: string;
value: string[];
popupVisible: boolean | undefined;
flattenOptions: CascaderOptionType[][];
flattenOptions: CascaderOptionType[][] | undefined;
}
function highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
@@ -82,26 +100,43 @@ 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: CascaderOptionType[], b: CascaderOptionType[], 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 +163,8 @@ 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) : undefined,
};
}
@@ -140,11 +176,13 @@ 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),
});
}
}
handleChange = (value: any, selectedOptions: any[]) => {
handleChange = (value: any, selectedOptions: CascaderOptionType[]) => {
this.setState({ inputValue: '' });
if (selectedOptions[0].__IS_FILTERED_OPTION) {
const unwrappedValue = value[0];
@@ -181,7 +219,9 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
// Prevent `Trigger` behaviour.
if (inputFocused || popupVisible) {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
if (e.nativeEvent.stopImmediatePropagation) {
e.nativeEvent.stopImmediatePropagation();
}
}
}
@@ -196,7 +236,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
this.setState({ inputValue });
}
setValue = (value: string[], selectedOptions: any[] = []) => {
setValue = (value: string[], selectedOptions: CascaderOptionType[] = []) => {
if (!('value' in this.props)) {
this.setState({ value });
}
@@ -207,13 +247,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 +269,58 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
}
}
flattenTree(options: CascaderOptionType[], changeOnSelect: boolean | undefined, ancestor: CascaderOptionType[] = []) {
let flattenOptions: any = [];
flattenTree(
options: CascaderOptionType[],
changeOnSelect: boolean | undefined,
filedNames: FiledNamesType | undefined,
ancestor: CascaderOptionType[] = [],
) {
const names: FilledFiledNamesType = getFilledFieldNames(filedNames);
let flattenOptions = [] as CascaderOptionType[][];
let childrenName = 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 { flattenOptions = [], inputValue } = this.state;
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 filtered.map((path: CascaderOptionType[]) => {
return {
__IS_FILTERED_OPTION: true,
path,
label: render(inputValue, path, prefixCls),
value: path.map((o: CascaderOptionType) => o.value),
disabled: path.some((o: CascaderOptionType) => o.disabled),
[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() {
@@ -283,7 +339,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
const { props, state } = this;
const {
prefixCls, inputPrefixCls, children, placeholder, size, disabled,
className, style, allowClear, showSearch = false, ...otherProps,
className, style, allowClear, showSearch = false, ...otherProps
} = props;
const value = state.value;
@@ -307,6 +363,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
[`${prefixCls}-picker-with-value`]: state.inputValue,
[`${prefixCls}-picker-disabled`]: disabled,
[`${prefixCls}-picker-${size}`]: !!size,
[`${prefixCls}-picker-show-search`]: !!showSearch,
});
// Fix bug of https://github.com/facebook/react/pull/5004
@@ -328,6 +385,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

@@ -14,6 +14,11 @@
cursor: pointer;
width: 100%;
display: block;
position: static;
}
&-picker-show-search &-input.@{ant-prefix}-input {
position: relative;
}
&-picker {

View File

@@ -35,7 +35,7 @@ export interface CheckboxChangeEvent {
target: CheckboxChangeEventTarget;
stopPropagation: () => void;
preventDefault: () => void;
nativeEvent: MouseEvent;
nativeEvent: Event;
}
export default class Checkbox extends React.Component<CheckboxProps, {}> {
@@ -79,7 +79,7 @@ export default class Checkbox extends React.Component<CheckboxProps, {}> {
style,
onMouseEnter,
onMouseLeave,
...restProps,
...restProps
} = props;
const { checkboxGroup } = context;
let checkboxProps: CheckboxProps = { ...restProps };

View File

@@ -4,7 +4,7 @@ import classNames from 'classnames';
import shallowEqual from 'shallowequal';
import Checkbox from './Checkbox';
export type CheckboxValueType = string | number;
export type CheckboxValueType = string | number | boolean;
export interface CheckboxOptionType {
label: string;
@@ -121,7 +121,7 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
children = this.getOptions().map(option => (
<Checkbox
prefixCls={prefixCls}
key={option.value}
key={option.value.toString()}
disabled={'disabled' in option ? option.disabled : props.disabled}
value={option.value}
checked={state.value.indexOf(option.value) !== -1}

View File

@@ -13,7 +13,9 @@ Checkbox.
## API
### Checkbox
### Props
#### Checkbox
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
@@ -21,9 +23,10 @@ Checkbox.
| checked | Specifies whether the checkbox is selected. | boolean | false |
| defaultChecked | Specifies the initial state: whether or not the checkbox is selected. | boolean | false |
| disabled | Disable checkbox | boolean | false |
| indeterminate | indeterminate checked state of checkbox | boolean | false |
| onChange | The callback function that is triggered when the state changes. | Function(e:Event) | - |
### Checkbox Group
#### Checkbox Group
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
@@ -33,11 +36,11 @@ Checkbox.
| value | Used for setting the currently selected value. | string\[] | \[] |
| onChange | The callback function that is triggered when the state changes. | Function(checkedValue) | - |
## Methods
### Methods
### Checkbox
#### Checkbox
| Name | Description |
| ---- | ----------- |
| blur() | remove focus |
| focus() | get focus |
| blur() | remove focus |

View File

@@ -14,30 +14,34 @@ title: Checkbox
## API
### Checkbox
### 属性
#### Checkbox
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| autoFocus | 自动获取焦点 | boolean | false |
| checked | 指定当前是否选中 | boolean | false |
| defaultChecked | 初始是否选中 | boolean | false |
| disabled | 失效状态 | boolean | false |
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false |
| onChange | 变化时回调函数 | Function(e:Event) | - |
### Checkbox Group
#### Checkbox Group
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| defaultValue | 默认选中的选项 | string\[] | \[] |
| disabled | 整组失效 | boolean | false |
| options | 指定可选项 | string\[] | \[] |
| value | 指定选中的选项 | string\[] | \[] |
| onChange | 变化时回调函数 | Function(checkedValue) | - |
## 方法
### 方法
### Checkbox
#### Checkbox
| 名称 | 描述 |
| --- | --- |
| blur() | 移除焦点 |
| focus() | 获取焦点 |
| blur() | 移除焦点 |

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;
@@ -53,6 +50,10 @@
content: "\E61F";
}
}
&:focus {
outline: none;
}
}
&.@{collapse-prefix-cls}-no-arrow {
@@ -69,13 +70,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

@@ -261,7 +261,7 @@ exports[`DatePicker prop locale should works 1`] = `
</div>
</td>
<td
class="ant-calendar-cell ant-calendar-last-month-cell"
class="ant-calendar-cell ant-calendar-last-month-cell ant-calendar-last-day-of-month"
role="gridcell"
title="December 31, 1999"
>
@@ -689,7 +689,7 @@ exports[`DatePicker prop locale should works 1`] = `
</div>
</td>
<td
class="ant-calendar-cell"
class="ant-calendar-cell ant-calendar-last-day-of-month"
role="gridcell"
title="January 31, 2000"
>

View File

@@ -221,7 +221,7 @@ exports[`RangePicker show month panel according to value 1`] = `
</div>
</td>
<td
class="ant-calendar-cell ant-calendar-last-month-cell"
class="ant-calendar-cell ant-calendar-last-month-cell ant-calendar-last-day-of-month"
role="gridcell"
title="1999年12月31日"
>
@@ -649,7 +649,7 @@ exports[`RangePicker show month panel according to value 1`] = `
role="row"
>
<td
class="ant-calendar-cell"
class="ant-calendar-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年1月31日"
>
@@ -902,7 +902,7 @@ exports[`RangePicker show month panel according to value 1`] = `
role="row"
>
<td
class="ant-calendar-cell ant-calendar-last-month-cell"
class="ant-calendar-cell ant-calendar-last-month-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年1月31日"
>
@@ -1299,7 +1299,7 @@ exports[`RangePicker show month panel according to value 1`] = `
</div>
</td>
<td
class="ant-calendar-cell"
class="ant-calendar-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年2月29日"
>
@@ -1489,7 +1489,7 @@ exports[`RangePicker show month panel according to value 1`] = `
class="ant-calendar-time-picker-btn"
role="button"
>
Select time
select time
</a>
<a
class="ant-calendar-ok-btn"
@@ -1726,7 +1726,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
</div>
</td>
<td
class="ant-calendar-cell ant-calendar-last-month-cell"
class="ant-calendar-cell ant-calendar-last-month-cell ant-calendar-last-day-of-month"
role="gridcell"
title="1999年12月31日"
>
@@ -2154,7 +2154,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
role="row"
>
<td
class="ant-calendar-cell"
class="ant-calendar-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年1月31日"
>
@@ -2407,7 +2407,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
role="row"
>
<td
class="ant-calendar-cell ant-calendar-last-month-cell"
class="ant-calendar-cell ant-calendar-last-month-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年1月31日"
>
@@ -2804,7 +2804,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
</div>
</td>
<td
class="ant-calendar-cell"
class="ant-calendar-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年2月29日"
>
@@ -3001,7 +3001,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
class="ant-calendar-time-picker-btn"
role="button"
>
Select time
select time
</a>
<a
class="ant-calendar-ok-btn"

View File

@@ -482,7 +482,7 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
</div>
</td>
<td
class="ant-calendar-cell ant-calendar-last-month-cell"
class="ant-calendar-cell ant-calendar-last-month-cell ant-calendar-last-day-of-month"
role="gridcell"
title="1999年12月31日"
>
@@ -886,7 +886,7 @@ exports[`MonthPicker and WeekPicker render WeekPicker 1`] = `
5
</td>
<td
class="ant-calendar-cell"
class="ant-calendar-cell ant-calendar-last-day-of-month"
role="gridcell"
title="2000年1月31日"
>

View File

@@ -19,13 +19,25 @@ There are four kinds of picker:
- RangePicker
- WeekPicker
### Localization
The default locale is en-US, if you need to use other languages, recommend to use internationalized components provided by us at the entrance. Look at: [LocaleProvider](http://ant.design/components/locale-provider/).
If there are special needs (only modifying single component language), Please use the property: local. Example: [default](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json).
```jsx
import locale from 'antd/lib/date-picker/locale/zh_CN';
<DatePicker locale={locale} />
```
**Note:** Part of locale of DatePicker, MonthPicker, RangePicker, WeekPicker is read from value. So, please set the locale of moment correctly.
```jsx
// The default locale is en-US, if you want to use other locale, just set locale in entry file globaly.
// import moment from 'moment';
// import 'moment/locale/zh-cn';
// moment.locale('zh-cn');
import moment from 'moment';
import 'moment/src/locale/zh-cn';
// import 'moment/locale/zh-cn'; if you are using webpack 1
<DatePicker defaultValue={moment('2015-01-01', 'YYYY-MM-DD')} />
```
@@ -51,6 +63,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

@@ -20,13 +20,25 @@ subtitle: 日期选择框
- RangePicker
- WeekPicker
### 国际化配置
默认配置为 en-US如果你需要设置其他语言推荐在入口处使用我们提供的国际化组件,详见:[LocaleProvider国际化](http://ant.design/components/locale-provider-cn/)。
如有特殊需求(仅修改单一组件的语言),请使用 locale 参数,参考:[默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json)。
```jsx
import locale from 'antd/lib/date-picker/locale/zh_CN';
<DatePicker locale={locale} />
```
**注意:**DatePicker、MonthPicker、RangePicker、WeekPicker 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。
```jsx
// 默认语言为 en-US如果你需要设置其他语言推荐在入口文件全局设置 locale
// import moment from 'moment';
// import 'moment/locale/zh-cn';
// moment.locale('zh-cn');
import moment from 'moment';
import 'moment/src/locale/zh-cn';
// import 'moment/locale/zh-cn'; if you are using webpack 1
<DatePicker defaultValue={moment('2015-01-01', 'YYYY-MM-DD')} />
```
@@ -74,6 +86,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

@@ -18,6 +18,8 @@ A divider line separates different content.
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| dashed | whether line is dashed | Boolean | false |
| dashed | whether line is dashed | boolean | false |
| type | direction type of divider | enum: `horizontal` `vertical` | `horizontal` |
| orientation | position of title inside divider | enum: `left` `right` `center` | `center` |
| className | className of container | string | - |
| style | style object of container | object | - |

View File

@@ -18,7 +18,7 @@ export default function Divider({
className,
children,
dashed,
...restProps,
...restProps
}: DividerProps) {
const orientationPrefix = (orientation.length > 0) ? '-' + orientation : orientation;
const classString = classNames(

View File

@@ -16,6 +16,8 @@ subtitle: 分割线
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| dashed | 是否虚线 | Boolean | false |
| dashed | 是否虚线 | boolean | false |
| type | 水平还是垂直类型 | enum: `horizontal` `vertical` | `horizontal` |
| orientation | 分割线标题的位置 | enum: `left` `right` | `center` |
| className | 分割线样式类 | string | - |
| style | 分割线样式对象 | object | - |

View File

@@ -24,7 +24,10 @@
margin: 24px 0;
clear: both;
}
&-horizontal&-with-text {
&-horizontal&-with-text,
&-horizontal&-with-text-left,
&-horizontal&-with-text-right {
display: table;
white-space: nowrap;
text-align: center;
@@ -33,7 +36,6 @@
color: @heading-color;
font-size: @font-size-lg;
margin: 16px 0;
&:before,
&:after {
content: '';
@@ -45,82 +47,50 @@
transform: translateY(50%);
}
}
&-inner-text {
display: inline-block;
padding: 0 24px;
}
&-horizontal&-with-text-left {
display: table;
white-space: nowrap;
text-align: center;
background: transparent;
font-weight: 500;
color: @heading-color;
font-size: @font-size-base;
margin: 16px 0;
&:before {
content: '';
display: table-cell;
position: relative;
top: 50%;
width: 5%;
border-top: 1px solid @border-color-split;
transform: translateY(50%);
}
&:after {
content: '';
display: table-cell;
position: relative;
top: 50%;
width: 95%;
border-top: 1px solid @border-color-split;
transform: translateY(50%);
}
&-inner-text {
&-horizontal&-with-text-left,
&-horizontal&-with-text-right {
font-size: @font-size-base;
.@{divider-prefix-cls}-inner-text {
display: inline-block;
padding: 0 10px;
}
}
&-horizontal&-with-text-left {
&:before {
top: 50%;
width: 5%;
}
&:after {
top: 50%;
width: 95%;
}
}
&-horizontal&-with-text-right {
display: table;
white-space: nowrap;
text-align: center;
background: transparent;
font-weight: 500;
color: @heading-color;
font-size: @font-size-base;
margin: 16px 0;
&:before {
content: '';
display: table-cell;
position: relative;
top: 50%;
width: 95%;
border-top: 1px solid @border-color-split;
transform: translateY(50%);
}
&:after {
content: '';
display: table-cell;
position: relative;
top: 50%;
width: 5%;
border-top: 1px solid @border-color-split;
transform: translateY(50%);
}
&-inner-text {
display: inline-block;
padding: 0 10px;
}
}
&-inner-text {
display: inline-block;
padding: 0 24px;
}
&-dashed {
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

@@ -35,11 +35,11 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
</span>
</button>
<button
class="ant-btn ant-dropdown-trigger ant-btn-default"
class="ant-btn ant-dropdown-trigger ant-btn-default ant-btn-icon-only"
type="button"
>
<i
class="anticon anticon-down"
class="anticon anticon-ellipsis"
/>
</button>
</div>
@@ -57,12 +57,12 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
</span>
</button>
<button
class="ant-btn ant-dropdown-trigger ant-btn-default"
class="ant-btn ant-dropdown-trigger ant-btn-default ant-btn-icon-only"
disabled=""
type="button"
>
<i
class="anticon anticon-down"
class="anticon anticon-ellipsis"
/>
</button>
</div>

View File

@@ -1,7 +1,6 @@
import * as React from 'react';
import Button from '../button';
import { ButtonGroupProps } from '../button/button-group';
import Icon from '../icon';
import Dropdown, { DropDownProps } from './dropdown';
import classNames from 'classnames';
const ButtonGroup = Button.Group;
@@ -9,7 +8,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;
}
@@ -25,7 +24,7 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
type, disabled, onClick, children,
prefixCls, className, overlay, trigger, align,
visible, onVisibleChange, placement, getPopupContainer,
...restProps,
...restProps
} = this.props;
const dropdownProps = {
@@ -36,9 +35,9 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
onVisibleChange,
placement,
getPopupContainer,
};
} as DropDownProps;
if ('visible' in this.props) {
(dropdownProps as any).visible = visible;
dropdownProps.visible = visible;
}
return (
@@ -54,9 +53,7 @@ export default class DropdownButton extends React.Component<DropdownButtonProps,
{children}
</Button>
<Dropdown {...dropdownProps}>
<Button type={type}>
<Icon type="down" />
</Button>
<Button type={type} icon="ellipsis" />
</Dropdown>
</ButtonGroup>
);

View File

@@ -41,11 +41,13 @@ export default class Dropdown extends React.Component<DropDownProps, any> {
componentDidMount() {
const { overlay } = this.props;
const overlayProps = (overlay as any).props as any;
warning(
!overlayProps.mode || overlayProps.mode === 'vertical',
`mode="${overlayProps.mode}" is not supported for Dropdown\'s Menu.`,
);
if (overlay) {
const overlayProps = (overlay as React.ReactElement<any>).props;
warning(
!overlayProps.mode || overlayProps.mode === 'vertical',
`mode="${overlayProps.mode}" is not supported for Dropdown\'s Menu.`,
);
}
}
render() {
@@ -59,10 +61,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

@@ -38,7 +38,7 @@
outline: none;
position: relative;
list-style-type: none;
padding: 0;
padding: 4px 0;
margin: 0;
text-align: left;
background-color: @component-background;
@@ -102,26 +102,12 @@
}
}
&:first-child,
&:first-child > a {
border-radius: @border-radius-base @border-radius-base 0 0;
}
&:last-child,
&:last-child > a {
border-radius: 0 0 @border-radius-base @border-radius-base;
}
&:only-child,
&:only-child > a {
border-radius: @border-radius-base;
}
&-divider {
height: 1px;
overflow: hidden;
background-color: @border-color-split;
line-height: 0;
margin: 4px 0;
}
.@{dropdown-prefix-cls}-menu-submenu-arrow {
position: absolute;
@@ -138,10 +124,6 @@
&-submenu-title {
padding-right: 26px;
&:first-child,
&:last-child {
border-radius: 0;
}
}
&-submenu-vertical {
@@ -163,13 +145,6 @@
color: @disabled-color;
}
}
&-submenu:first-child &-submenu-title {
border-radius: @border-radius-base @border-radius-base 0 0;
}
&-submenu:last-child &-submenu-title {
border-radius: 0 0 @border-radius-base @border-radius-base;
}
}
&.slide-down-enter.slide-down-enter-active&-placement-bottomLeft,
@@ -208,6 +183,9 @@
.@{iconfont-css-prefix}-down {
.iconfont-size-under-12px(10px);
}
.@{iconfont-css-prefix}-ellipsis {
text-shadow: 0 0 currentColor;
}
}
.@{dropdown-prefix-cls}-button {

View File

@@ -9,16 +9,26 @@ import FormItem from './FormItem';
import { FIELD_META_PROP, FIELD_DATA_PROP } from './constants';
import { Omit } from '../_util/type';
type FormCreateOptionMessagesCallback = (...args: any[]) => string;
interface FormCreateOptionMessages {
[messageId: string]:
| string
| FormCreateOptionMessagesCallback
| FormCreateOptionMessages;
}
export interface FormCreateOption<T> {
onFieldsChange?: (props: T, fields: Array<any>) => void;
onValuesChange?: (props: T, values: any) => void;
onFieldsChange?: (props: T, fields: Array<any>, allFields: any, add: string) => void;
onValuesChange?: (props: T, changedValues: any, allValues: any) => void;
mapPropsToFields?: (props: T) => void;
validateMessages?: FormCreateOptionMessages;
withRef?: boolean;
}
export type FormLayout = 'horizontal' | 'inline' | 'vertical';
export interface FormProps {
export interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
layout?: FormLayout;
form?: WrappedFormUtils;
onSubmit?: React.FormEventHandler<any>;
@@ -115,10 +125,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

@@ -2,6 +2,7 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import intersperse from 'intersperse';
import Animate from 'rc-animate';
import Row from '../grid/row';
import Col, { ColProps } from '../grid/col';
@@ -55,7 +56,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
context: FormItemContext;
state = { helpShow: false };
helpShow = false;
componentDidMount() {
warning(
@@ -65,15 +66,20 @@ export default class FormItem extends React.Component<FormItemProps, any> {
);
}
getHelpMsg() {
const props = this.props;
const onlyControl = this.getOnlyControl();
if (props.help === undefined && onlyControl) {
getHelpMessage() {
const { help } = this.props;
if (help === undefined && this.getOnlyControl()) {
const errors = this.getField().errors;
return errors ? errors.map((e: any) => e.message).join(', ') : '';
if (errors) {
return intersperse(errors.map((e: any, index: number) => (
React.isValidElement(e.message)
? React.cloneElement(e.message, { key: index })
: e.message
)), ' ');
}
return '';
}
return props.help;
return help;
}
getControls(children: React.ReactNode, recursively: boolean) {
@@ -124,17 +130,23 @@ export default class FormItem extends React.Component<FormItemProps, any> {
}
onHelpAnimEnd = (_key: string, helpShow: boolean) => {
this.setState({ helpShow });
this.helpShow = helpShow;
if (!helpShow) {
this.setState({});
}
}
renderHelp() {
const prefixCls = this.props.prefixCls;
const help = this.getHelpMsg();
const help = this.getHelpMessage();
const children = help ? (
<div className={`${prefixCls}-explain`} key="help">
{help}
</div>
) : null;
if (children) {
this.helpShow = !!children;
}
return (
<Animate
transitionName="show-help"
@@ -306,11 +318,10 @@ export default class FormItem extends React.Component<FormItemProps, any> {
const style = props.style;
const itemClassName = {
[`${prefixCls}-item`]: true,
[`${prefixCls}-item-with-help`]: !!this.getHelpMsg() || this.state.helpShow,
[`${prefixCls}-item-with-help`]: this.helpShow,
[`${prefixCls}-item-no-colon`]: !props.colon,
[`${props.className}`]: !!props.className,
};
return (
<Row className={classNames(itemClassName)} style={style}>
{children}

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>
@@ -2417,6 +2417,8 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
<input
autocomplete="off"
class="ant-input-number-input"
data-__field="[object Object]"
data-__meta="[object Object]"
id="input-number"
max="10"
min="1"
@@ -3340,7 +3342,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

@@ -0,0 +1,100 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Form should display custom message 1`] = `
<form
class="ant-form ant-form-horizontal"
>
<div
class="ant-row ant-form-item ant-form-item-with-help"
>
<div
class="ant-form-item-label"
>
<label
class=""
for="account"
title="Account"
>
Account
</label>
</div>
<div
class="ant-form-item-control-wrapper"
>
<div
class="ant-form-item-control has-error"
>
<span
class="ant-form-item-children"
>
<input
data-__field="[object Object]"
data-__meta="[object Object]"
id="account"
value="antd"
/>
</span>
<div
class="ant-form-explain show-help-enter"
>
<span>
Account does not exist,
<a
href="https://www.alipay.com/"
rel="noopener noreferrer"
target="_blank"
>
Forgot account?
</a>
</span>
</div>
</div>
</div>
</div>
</form>
`;
exports[`Form should display two message 1`] = `
<form
class="ant-form ant-form-horizontal"
>
<div
class="ant-row ant-form-item ant-form-item-with-help"
>
<div
class="ant-form-item-label"
>
<label
class=""
for="account"
title="Account"
>
Account
</label>
</div>
<div
class="ant-form-item-control-wrapper"
>
<div
class="ant-form-item-control has-error"
>
<span
class="ant-form-item-children"
>
<input
data-__field="[object Object]"
data-__meta="[object Object]"
id="account"
value="+=-/"
/>
</span>
<div
class="ant-form-explain show-help-enter"
>
Error message 1 Error message 2
</div>
</div>
</div>
</div>
</form>
`;

View File

@@ -0,0 +1,56 @@
import React from 'react';
import { mount } from 'enzyme';
import Form from '..';
describe('Form', () => {
it('should display two message', () => {
const rules = [{
pattern: /^\w+$/,
message: 'Error message 1',
}, {
pattern: /^\w+$/,
message: 'Error message 2',
}];
let myForm;
const Form1 = Form.create()(({ form }) => {
myForm = form;
return (
<Form>
<Form.Item label="Account">
{form.getFieldDecorator('account', { initialValue: '+=-/', rules })(<input />)}
</Form.Item>
</Form>
);
});
const wrapper = mount(<Form1 />);
myForm.validateFields();
wrapper.update();
expect(wrapper.render()).toMatchSnapshot();
});
it('should display custom message', () => {
const rules = [{
pattern: /^$/,
message: (<span>Account does not exist, <a rel="noopener noreferrer" href="https://www.alipay.com/" target="_blank">Forgot account?</a></span>),
}];
let myForm;
const Form1 = Form.create()(({ form }) => {
myForm = form;
return (
<Form>
<Form.Item label="Account">
{form.getFieldDecorator('account', { initialValue: 'antd', rules })(<input />)}
</Form.Item>
</Form>
);
});
const wrapper = mount(<Form1 />);
myForm.validateFields();
wrapper.update();
expect(wrapper.render()).toMatchSnapshot();
});
});

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:
@@ -147,7 +147,7 @@ Note:
| enum | validate a value from a list of possible values | string | - |
| len | validate an exact length of a field | number | - |
| max | validate a max length of a field | number | - |
| message | validation error message | string | - |
| message | validation error message | string\|ReactNode | - |
| min | validate a min length of a field | number | - |
| pattern | validate from a regular expression | RegExp | - |
| required | indicates whether field is required | boolean | `false` |

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 如下:
@@ -148,7 +148,7 @@ CustomizedForm = Form.create({})(CustomizedForm);
| enum | 枚举类型 | string | - |
| len | 字段长度 | number | - |
| max | 最大长度 | number | - |
| message | 校验文案 | string | - |
| message | 校验文案 | string\|ReactNode | - |
| min | 最小长度 | number | - |
| pattern | 正则表达式校验 | RegExp | - |
| required | 是否必选 | boolean | `false` |

View File

@@ -132,8 +132,9 @@ input[type="checkbox"] {
.@{form-prefix-cls}-extra {
color: @text-color-secondary;
line-height: @line-height-base;
transition: color .15s @ease-out;
transition: color .3s @ease-out; // sync input color transition
margin-top: @form-help-margin-top;
clear: both;
}
.@{form-prefix-cls}-extra {
@@ -251,7 +252,9 @@ form {
}
// fix input with addon position. https://github.com/ant-design/ant-design/issues/8243
:not(.@{ant-prefix}-input-group-wrapper) > .@{ant-prefix}-input-group,
.@{ant-prefix}-input-group-wrapper {
display: inline-block;
vertical-align: middle;
position: relative;
top: -1px;
@@ -574,7 +577,7 @@ form {
}
}
.show-help-motion(show-help, antShowHelp, 0.15s);
.show-help-motion(show-help, antShowHelp, 0.3s);
@keyframes antShowHelpIn {
0% {

View File

@@ -22,17 +22,10 @@ import classNames from 'classnames';
import PropTypes from 'prop-types';
export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
export type BreakpointMap = {
xs?: string;
sm?: string;
md?: string;
lg?: string;
xl?: string;
xxl?: string
};
export type BreakpointMap = Partial<Record<Breakpoint, string>>;
export interface RowProps extends React.HTMLAttributes<HTMLDivElement> {
gutter?: number | BreakpointMap;
gutter?: number | Partial<Record<Breakpoint, number>>;
type?: 'flex';
align?: 'top' | 'middle' | 'bottom';
justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between';
@@ -122,7 +115,7 @@ export default class Row extends React.Component<RowProps, RowState> {
render() {
const {
type, justify, align, className, style, children,
prefixCls = 'ant-row', ...others,
prefixCls = 'ant-row', ...others
} = this.props;
const gutter = this.getGutter();
const classes = classNames({

View File

@@ -2,6 +2,7 @@
// this file is not used if use https://github.com/ant-design/babel-plugin-import
const ENV = process.env.NODE_ENV;
if (ENV !== 'production' &&
ENV !== 'test' &&
typeof console !== 'undefined' &&
console.warn &&
typeof window !== 'undefined') {

View File

@@ -2,7 +2,12 @@ import * as React from 'react';
import classNames from 'classnames';
import RcInputNumber from 'rc-input-number';
export interface InputNumberProps {
import { Omit } from '../_util/type';
// omitting this attrs because they conflicts with the ones defined in InputNumberProps
export type OmitAttrs = 'defaultValue' | 'onChange' | 'size';
export interface InputNumberProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, OmitAttrs> {
prefixCls?: string;
min?: number;
max?: number;
@@ -10,7 +15,6 @@ export interface InputNumberProps {
step?: number | string;
defaultValue?: number;
tabIndex?: number;
onKeyDown?: React.FormEventHandler<any>;
onChange?: (value: number | string | undefined) => void;
disabled?: boolean;
size?: 'large' | 'small' | 'default';

View File

@@ -60,7 +60,6 @@
.disabled();
.@{input-number-prefix-cls}-input {
cursor: not-allowed;
background-color: @disabled-bg;
}
.@{input-number-prefix-cls}-handler-wrap {
display: none;
@@ -74,17 +73,12 @@
-moz-appearance: textfield;
height: @input-height-base - 2px;
transition: all 0.3s linear;
color: @input-color;
background-color: @input-bg;
background-color: transparent;
border: 0;
border-radius: @border-radius-base;
padding: 0 @control-padding-horizontal - 1px;
display: block;
.placeholder();
&[disabled] {
.disabled();
}
}
&-lg {
@@ -109,7 +103,7 @@
border-left: @border-width-base @border-style-base @border-color-base;
width: 22px;
height: 100%;
background: @component-background;
background: transparent;
position: absolute;
top: 0;
right: 0;

View File

@@ -5,46 +5,23 @@ import omit from 'omit.js';
import Group from './Group';
import Search from './Search';
import TextArea from './TextArea';
import { Omit } from '../_util/type';
function fixControlledValue(value: undefined | null | string) {
function fixControlledValue<T>(value: T) {
if (typeof value === 'undefined' || value === null) {
return '';
}
return value;
}
export interface AbstractInputProps {
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {
prefixCls?: string;
className?: string;
defaultValue?: any;
value?: any;
tabIndex?: number;
style?: React.CSSProperties;
}
export interface InputProps extends AbstractInputProps {
placeholder?: string;
type?: string;
id?: number | string;
name?: string;
size?: 'large' | 'default' | 'small';
maxLength?: number | string;
disabled?: boolean;
readOnly?: boolean;
onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;
addonBefore?: React.ReactNode;
addonAfter?: React.ReactNode;
onPressEnter?: React.FormEventHandler<HTMLInputElement>;
onKeyDown?: React.FormEventHandler<HTMLInputElement>;
onKeyUp?: React.FormEventHandler<HTMLInputElement>;
onChange?: React.ChangeEventHandler<HTMLInputElement>;
onClick?: React.FormEventHandler<HTMLInputElement>;
onFocus?: React.FormEventHandler<HTMLInputElement>;
onBlur?: React.FormEventHandler<HTMLInputElement>;
autoComplete?: string;
prefix?: React.ReactNode;
suffix?: React.ReactNode;
spellCheck?: boolean;
autoFocus?: boolean;
}
export default class Input extends React.Component<InputProps, any> {

View File

@@ -40,31 +40,32 @@ export default class Search extends React.Component<SearchProps, any> {
}
getButtonOrIcon() {
const { enterButton, prefixCls, size } = this.props;
if (!enterButton) {
return <Icon className={`${prefixCls}-icon`} type="search" key="searchIcon" />;
}
const { enterButton, prefixCls, size, disabled } = this.props;
const enterButtonAsElement = enterButton as React.ReactElement<any>;
if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
return React.cloneElement(enterButtonAsElement, enterButtonAsElement.type === Button ? {
let node;
if (!enterButton) {
node = <Icon className={`${prefixCls}-icon`} type="search" key="searchIcon" />;
} else if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
node = React.cloneElement(enterButtonAsElement, enterButtonAsElement.type === Button ? {
className: `${prefixCls}-button`,
size,
onClick: this.onSearch,
} : {
onClick: this.onSearch,
});
} : {});
} else {
node = (
<Button
className={`${prefixCls}-button`}
type="primary"
size={size}
disabled={disabled}
key="enterButton"
>
{enterButton === true ? <Icon type="search" /> : enterButton}
</Button>
);
}
return (
<Button
className={`${prefixCls}-button`}
type="primary"
size={size}
onClick={this.onSearch}
key="enterButton"
>
{enterButton === true ? <Icon type="search" /> : enterButton}
</Button>
);
return React.cloneElement(node, {
onClick: this.onSearch,
});
}
render() {

View File

@@ -1,7 +1,6 @@
import * as React from 'react';
import omit from 'omit.js';
import classNames from 'classnames';
import { AbstractInputProps } from './Input';
import calculateNodeHeight from './calculateNodeHeight';
function onNextFrame(cb: () => void) {
@@ -24,9 +23,10 @@ export interface AutoSizeType {
maxRows?: number;
}
export interface TextAreaProps extends AbstractInputProps {
export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
prefixCls?: string;
autosize?: boolean | AutoSizeType;
onPressEnter?: React.FormEventHandler<any>;
onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;
}
export interface TextAreaState {

View File

@@ -20,4 +20,71 @@ 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);
});
it('should trigger onSearch when click search icon', () => {
const onSearch = jest.fn();
const wrapper = mount(
<Search defaultValue="search text" onSearch={onSearch} />
);
wrapper.find('Icon').simulate('click');
expect(onSearch).toHaveBeenCalledTimes(1);
expect(onSearch).toBeCalledWith('search text');
});
it('should trigger onSearch when click search button', () => {
const onSearch = jest.fn();
const wrapper = mount(
<Search defaultValue="search text" enterButton onSearch={onSearch} />
);
wrapper.find('Button').simulate('click');
expect(onSearch).toHaveBeenCalledTimes(1);
expect(onSearch).toBeCalledWith('search text');
});
it('should trigger onSearch when click search button with text', () => {
const onSearch = jest.fn();
const wrapper = mount(
<Search defaultValue="search text" enterButton="button text" onSearch={onSearch} />
);
wrapper.find('Button').simulate('click');
expect(onSearch).toHaveBeenCalledTimes(1);
expect(onSearch).toBeCalledWith('search text');
});
it('should trigger onSearch when click search button with customize button', () => {
const onSearch = jest.fn();
const wrapper = mount(
<Search defaultValue="search text" enterButton={<Button>antd button</Button>} onSearch={onSearch} />
);
wrapper.find('Button').simulate('click');
expect(onSearch).toHaveBeenCalledTimes(1);
expect(onSearch).toBeCalledWith('search text');
});
it('should trigger onSearch when click search button of native', () => {
const onSearch = jest.fn();
const wrapper = mount(
<Search defaultValue="search text" enterButton={<button>antd button</button>} onSearch={onSearch} />
);
wrapper.find('button').simulate('click');
expect(onSearch).toHaveBeenCalledTimes(1);
expect(onSearch).toBeCalledWith('search text');
});
it('should trigger onSearch when press enter', () => {
const onSearch = jest.fn();
const wrapper = mount(
<Search defaultValue="search text" onSearch={onSearch} />
);
wrapper.find('input').simulate('keydown', { key: 'Enter', keyCode: 13 });
expect(onSearch).toHaveBeenCalledTimes(1);
expect(onSearch).toBeCalledWith('search text');
});
});

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

@@ -34,6 +34,7 @@ exports[`Input.Search should support suffix 1`] = `
"suffix",
<Icon
className="ant-input-search-icon"
onClick={[Function]}
type="search"
/>,
]
@@ -57,10 +58,12 @@ exports[`Input.Search should support suffix 1`] = `
<Icon
className="ant-input-search-icon"
key="searchIcon"
onClick={[Function]}
type="search"
>
<i
className="anticon anticon-search ant-input-search-icon"
onClick={[Function]}
/>
</Icon>
</span>

View File

@@ -31,7 +31,12 @@ ReactDOM.render(
enterButton
/>
<br /><br />
<Search placeholder="input search text" enterButton="Search" size="large" />
<Search
placeholder="input search text"
enterButton="Search"
size="large"
onSearch={value => console.log(value)}
/>
</div>
, mountNode);
````

View File

@@ -9,13 +9,11 @@ title:
我们为 `<Input />` 输入框定义了三种尺寸(大、默认、小),高度分别为 `40px``32px``24px`
注意: 在表单里面,我们只使用大尺寸的输入框。
## en-US
There are three sizes of an Input box: `large` (40px)、`default` (32px) and `small` (24px).
Note: Inside of forms, only the large size is used.
````jsx
import { Input } from 'antd';

View File

@@ -21,11 +21,13 @@
border-color: ~`colorPalette("@{color}", 5)`;
outline: 0;
box-shadow: 0 0 @outline-blur-size @outline-width fade(@color, 20%);
border-right-width: 1px !important;
}
// == when hoverd
.hover(@color: @input-hover-border-color) {
border-color: ~`colorPalette("@{color}", 5)`;
border-right-width: 1px !important;
}
.disabled() {
@@ -135,6 +137,11 @@
margin-bottom: 0;
&:focus {
z-index: 1; // Fix https://gw.alipayobjects.com/zos/rmsportal/DHNpoqfMXSfrSnlZvhsJ.png
border-right-width: 1px;
}
&:hover {
z-index: 1;
border-right-width: 1px;
}
}
@@ -267,7 +274,6 @@
// Undo float for .ant-input-group .ant-input
.@{inputClass} {
float: none;
z-index: auto;
}
// reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker
@@ -311,20 +317,19 @@
display: inline-block;
width: 100%;
.@{inputClass} {
z-index: 1;
}
&:hover .@{inputClass}:not(.@{inputClass}-disabled) {
.hover();
}
.@{inputClass} {
position: static;
}
.@{inputClass}-prefix,
.@{inputClass}-suffix {
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 2;
line-height: 0;
color: @input-color;
:not(.anticon) {

View File

@@ -7,8 +7,12 @@
.@{search-prefix} {
&-icon {
pointer-events: none;
color: @text-color-secondary;
cursor: pointer;
transition: all .3s;
&:hover {
color: #333;
}
}
&:not(&-small) > .@{ant-prefix}-input-suffix {

View File

@@ -31,6 +31,8 @@ const dimensionMap = {
export type CollapseType = 'clickTrigger' | 'responsive';
export type SiderTheme = 'light' | 'dark';
export interface SiderProps extends React.HTMLAttributes<HTMLDivElement> {
prefixCls?: string;
collapsible?: boolean;
@@ -42,6 +44,7 @@ export interface SiderProps extends React.HTMLAttributes<HTMLDivElement> {
width?: number | string;
collapsedWidth?: number | string;
breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
theme?: SiderTheme;
}
export interface SiderState {
@@ -73,6 +76,7 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
width: 200,
collapsedWidth: 80,
style: {},
theme: 'dark' as SiderTheme,
};
static childContextTypes = {
@@ -174,15 +178,17 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
}
render() {
const { prefixCls, className,
const { prefixCls, className, theme,
collapsible, reverseArrow, trigger, style, width, collapsedWidth,
...others,
...others
} = this.props;
const divProps = omit(others, ['collapsed',
'defaultCollapsed', 'onCollapse', 'breakpoint']);
const siderWidth = this.state.collapsed ? collapsedWidth : width;
const rawWidth = this.state.collapsed ? collapsedWidth : width;
// use "px" as fallback unit for width
const siderWidth = typeof rawWidth === 'number' ? `${rawWidth}px` : String(rawWidth || 0);
// special trigger when collapsedWidth == 0
const zeroWidthTrigger = collapsedWidth === 0 || collapsedWidth === '0' || collapsedWidth === '0px' ? (
const zeroWidthTrigger = parseFloat(String(collapsedWidth || 0)) === 0 ? (
<span onClick={this.toggle} className={`${prefixCls}-zero-width-trigger`}>
<Icon type="bars" />
</span>
@@ -201,21 +207,18 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
</div>
) : null
);
// For collapsedWidth="40px"
// https://github.com/ant-design/ant-design/issues/10140
const siderWidthNumber = (siderWidth || 0).toString().replace(/px$/, '');
const divStyle = {
...style,
flex: `0 0 ${siderWidthNumber}px`,
maxWidth: `${siderWidthNumber}px`, // Fix width transition bug in IE11
minWidth: `${siderWidthNumber}px`, // https://github.com/ant-design/ant-design/issues/6349
width: `${siderWidthNumber}px`,
flex: `0 0 ${siderWidth}`,
maxWidth: siderWidth, // Fix width transition bug in IE11
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
width: siderWidth,
};
const siderCls = classNames(className, prefixCls, {
const siderCls = classNames(className, prefixCls, `${prefixCls}-${theme}`, {
[`${prefixCls}-collapsed`]: !!this.state.collapsed,
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
[`${prefixCls}-below`]: !!this.state.below,
[`${prefixCls}-zero-width`]: siderWidth === 0 || siderWidth === '0' || siderWidth === '0px',
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
});
return (
<div className={siderCls} {...divProps} style={divStyle}>

View File

@@ -33,7 +33,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
class="ant-layout"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -71,7 +71,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
Content
</div>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -91,7 +91,7 @@ exports[`renders ./components/layout/demo/basic.md correctly 1`] = `
class="ant-layout"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -128,7 +128,7 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
class="ant-layout"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -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"
@@ -212,34 +207,29 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
>
<div
class="ant-layout-header"
style="position:fixed;width:100%"
style="position:fixed;z-index:1;width:100%"
>
<div
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"
>
@@ -312,7 +302,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
class="ant-layout"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="overflow:auto;height:100vh;position:fixed;left:0;flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -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"
@@ -577,7 +557,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
class="ant-layout"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -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"
@@ -688,7 +662,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
style="min-height:100vh"
>
<div
class="ant-layout-sider ant-layout-sider-has-trigger"
class="ant-layout-sider ant-layout-sider-dark ant-layout-sider-has-trigger"
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
@@ -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"
>
@@ -1045,21 +1006,20 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
style="padding:24px 0;background:#fff"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="background:#fff;flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
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"
>
@@ -1224,21 +1176,20 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
class="ant-layout"
>
<div
class="ant-layout-sider"
class="ant-layout-sider ant-layout-sider-dark"
style="background:#fff;flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
>
<div
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

@@ -34,4 +34,39 @@ describe('Layout', () => {
);
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-has-trigger')).toBe(true);
});
it('should have 50% width of sidebar', async () => {
const wrapper = mount(
<Layout>
<div><Sider width="50%">Sider</Sider></div>
<Content>Content</Content>
</Layout>
);
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').width).toBe('50%');
expect(wrapper.find('.ant-layout-sider').at(0).prop('style').flex).toBe('0 0 50%');
});
it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => {
const wrapper = mount(
<Layout>
<div><Sider width="0%">Sider</Sider></div>
<Content>Content</Content>
</Layout>
);
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-zero-width')).toBe(true);
});
it('detect ant-layout-sider-dark as default theme', async () => {
const wrapper = mount(
<Sider>Sider</Sider>
);
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-dark'));
});
it('detect ant-layout-sider-light when set light theme', async () => {
const wrapper = mount(
<Sider theme="light">Sider</Sider>
);
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-light'));
});
});

View File

@@ -20,7 +20,7 @@ const { Header, Content, Footer } = Layout;
ReactDOM.render(
<Layout>
<Header style={{ position: 'fixed', width: '100%' }}>
<Header style={{ position: 'fixed', zIndex: 1, width: '100%' }}>
<div className="logo" />
<Menu
theme="dark"

View File

@@ -98,6 +98,7 @@ The sidebar.
| trigger | specify the customized trigger, set to null to hide the trigger | string\|ReactNode | - |
| width | width of the sidebar | number\|string | 200 |
| onCollapse | the callback function, executed by clicking the trigger or activating the responsive layout | (collapsed, type) => {} | - |
| theme | color theme of the sidebar | string: `light` `dark` | `dark` |
#### breakpoint width

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