mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 10:59:19 +08:00
Compare commits
182 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a52d694a2f | ||
|
|
0ab7096a2d | ||
|
|
adb66f0172 | ||
|
|
4622dce879 | ||
|
|
838be31543 | ||
|
|
958e8ebc4b | ||
|
|
55d43eb13b | ||
|
|
ec6d88f407 | ||
|
|
45ac4872b2 | ||
|
|
004d786cb4 | ||
|
|
9555626898 | ||
|
|
3ba45845ad | ||
|
|
84119d8959 | ||
|
|
b126b23b2d | ||
|
|
89a1dc5125 | ||
|
|
8d873785a7 | ||
|
|
e107b03cc7 | ||
|
|
be74114d22 | ||
|
|
755132cc26 | ||
|
|
838abbd358 | ||
|
|
bf2490c45f | ||
|
|
f1649efebb | ||
|
|
799c7be17e | ||
|
|
754a22ca24 | ||
|
|
589415ed95 | ||
|
|
4d7f1b191f | ||
|
|
7b719ce457 | ||
|
|
9cf6ae6010 | ||
|
|
d8fd521f92 | ||
|
|
fbab93fbd6 | ||
|
|
0e2c58e42e | ||
|
|
6203298f32 | ||
|
|
8a9fbcb5e4 | ||
|
|
94c4dc293e | ||
|
|
debee2edcb | ||
|
|
a14e476eeb | ||
|
|
859c18f7dd | ||
|
|
c2319f0998 | ||
|
|
f2ce60cb6c | ||
|
|
2c4c5fc6e3 | ||
|
|
583abe8dbb | ||
|
|
7f78cc9753 | ||
|
|
52cb4fe9cb | ||
|
|
b4d95f7e20 | ||
|
|
45fb83d64c | ||
|
|
070e340958 | ||
|
|
e2534681c4 | ||
|
|
5b37e09ea1 | ||
|
|
363a29c942 | ||
|
|
5d206f4ecb | ||
|
|
a270597d63 | ||
|
|
287d08890a | ||
|
|
064bfaf554 | ||
|
|
d2100bc3e3 | ||
|
|
257f3ec35d | ||
|
|
ecbd3d2d40 | ||
|
|
c3326a5bff | ||
|
|
b6e9646a6a | ||
|
|
36fc837f02 | ||
|
|
80f82674fb | ||
|
|
a0a5641c79 | ||
|
|
76afe5037d | ||
|
|
1b3d063990 | ||
|
|
a728081d0f | ||
|
|
cda29f231e | ||
|
|
928b747d6c | ||
|
|
a130bcf4db | ||
|
|
2226a40c74 | ||
|
|
32c03d2e04 | ||
|
|
bead75021b | ||
|
|
3fbcb73a2a | ||
|
|
f78a78e03b | ||
|
|
510add6305 | ||
|
|
5cac2fab4a | ||
|
|
e450ab64fa | ||
|
|
80a4581a79 | ||
|
|
2b72149a50 | ||
|
|
afeda4fe70 | ||
|
|
268a1817b7 | ||
|
|
cc6e1ba9d7 | ||
|
|
1cea1793e8 | ||
|
|
43abea3212 | ||
|
|
aa2b1a4352 | ||
|
|
9b150d9246 | ||
|
|
b9c248f313 | ||
|
|
a14ba62a07 | ||
|
|
0f9da43522 | ||
|
|
bb29c46cda | ||
|
|
57646f24db | ||
|
|
0587804fb1 | ||
|
|
e397c094bb | ||
|
|
7ec566928d | ||
|
|
8dad311df0 | ||
|
|
471f9409f9 | ||
|
|
f01d436dd5 | ||
|
|
ed66395a12 | ||
|
|
10f1c6ceaa | ||
|
|
ac924d9443 | ||
|
|
c31371e5a6 | ||
|
|
2f81349c21 | ||
|
|
a06afee8b6 | ||
|
|
2e6a94a4de | ||
|
|
eab74fa693 | ||
|
|
a3a0fb0aff | ||
|
|
f4d631ddc2 | ||
|
|
73d708f1fa | ||
|
|
4ab281a494 | ||
|
|
dd3f520129 | ||
|
|
04a1808fc3 | ||
|
|
121efd1f4c | ||
|
|
6a28b44eca | ||
|
|
f14e207912 | ||
|
|
45e9b2a937 | ||
|
|
ef31697d26 | ||
|
|
d7a9783299 | ||
|
|
b5ed207902 | ||
|
|
8fab1e1d1b | ||
|
|
5536a4ca3b | ||
|
|
9742be40a7 | ||
|
|
623cf1eaff | ||
|
|
aa6b55be7e | ||
|
|
a3d821a534 | ||
|
|
0156fef165 | ||
|
|
7c43bc553f | ||
|
|
6606aad391 | ||
|
|
c849a73f4e | ||
|
|
56fa8629b5 | ||
|
|
92dc0dc2b0 | ||
|
|
d7ca64b95c | ||
|
|
05ca7a559a | ||
|
|
a5ee1c4899 | ||
|
|
1aa368d3e2 | ||
|
|
6617f785fd | ||
|
|
b8b9aeb1ce | ||
|
|
17b82a251a | ||
|
|
8eff14aebe | ||
|
|
a654d86d65 | ||
|
|
42efc2927d | ||
|
|
a3a2bf9c7d | ||
|
|
51d32baa62 | ||
|
|
bd6ad1c19a | ||
|
|
f62dc47ae7 | ||
|
|
636c343b16 | ||
|
|
af03ae67f9 | ||
|
|
af4ed3988a | ||
|
|
e75bd0aa5b | ||
|
|
97bf63086e | ||
|
|
068dc8ec38 | ||
|
|
522aee18c3 | ||
|
|
84e995ff63 | ||
|
|
6804094fa2 | ||
|
|
86398d910a | ||
|
|
d0ca9ae05e | ||
|
|
8ee70e84b6 | ||
|
|
da92bfeba2 | ||
|
|
186496d840 | ||
|
|
6cecc9a0ea | ||
|
|
7d46cabb17 | ||
|
|
4a906137b8 | ||
|
|
855b613ce9 | ||
|
|
d1ba62e50b | ||
|
|
b23d742f1b | ||
|
|
c6518b92aa | ||
|
|
1bbf59bb1d | ||
|
|
68ce09be4e | ||
|
|
5ca7d75c0d | ||
|
|
ce24f278cf | ||
|
|
6ae02a9ab7 | ||
|
|
a0a0d88b78 | ||
|
|
2e7d08e98f | ||
|
|
45f1ff5bf7 | ||
|
|
fd06d7b8b1 | ||
|
|
6199340b5f | ||
|
|
08e83193f2 | ||
|
|
ecff4997d9 | ||
|
|
a88a320694 | ||
|
|
5dc31a4d2a | ||
|
|
418fb21f7e | ||
|
|
cc00ebe5e1 | ||
|
|
76741d026f | ||
|
|
bfd0a77781 | ||
|
|
8496e8f687 |
@@ -21,6 +21,52 @@ references:
|
||||
environment:
|
||||
REACT: 16
|
||||
|
||||
workflow: &workflow
|
||||
jobs:
|
||||
- setup:
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- dist:
|
||||
requires:
|
||||
- setup
|
||||
- compile:
|
||||
requires:
|
||||
- setup
|
||||
- lint:
|
||||
requires:
|
||||
- setup
|
||||
- test_dist:
|
||||
requires:
|
||||
- dist
|
||||
- test_lib:
|
||||
requires:
|
||||
- compile
|
||||
- test_es:
|
||||
requires:
|
||||
- compile
|
||||
- test_dom:
|
||||
requires:
|
||||
- setup
|
||||
- test_node:
|
||||
requires:
|
||||
- setup
|
||||
- test_dist_15:
|
||||
requires:
|
||||
- dist
|
||||
- test_lib_15:
|
||||
requires:
|
||||
- compile
|
||||
- test_es_15:
|
||||
requires:
|
||||
- compile
|
||||
- test_dom_15:
|
||||
requires:
|
||||
- setup
|
||||
- test_node_15:
|
||||
requires:
|
||||
- setup
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
<<: *container_config
|
||||
@@ -78,7 +124,7 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- run:
|
||||
command: npm test -- -w 2
|
||||
command: npm test -- -w 1
|
||||
environment:
|
||||
LIB_DIR: dist
|
||||
|
||||
@@ -89,7 +135,7 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- run:
|
||||
command: npm test -- -w 2
|
||||
command: npm test -- -w 1
|
||||
environment:
|
||||
LIB_DIR: lib
|
||||
|
||||
@@ -100,7 +146,7 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- run:
|
||||
command: npm test -- -w 2
|
||||
command: npm test -- -w 1
|
||||
environment:
|
||||
LIB_DIR: es
|
||||
|
||||
@@ -110,7 +156,7 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- run: npm test -- -w 2 --coverage
|
||||
- run: npm test -- -w 1 --coverage
|
||||
- run: bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
test_node:
|
||||
@@ -119,7 +165,7 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- run: npm run test-node -- -w 2
|
||||
- run: npm run test-node -- -w 1
|
||||
|
||||
test_dist_15:
|
||||
<<: *container_config
|
||||
@@ -129,7 +175,7 @@ jobs:
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run:
|
||||
command: npm test -- -w 2 -u
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
LIB_DIR: dist
|
||||
|
||||
@@ -141,7 +187,7 @@ jobs:
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run:
|
||||
command: npm test -- -w 2 -u
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
LIB_DIR: lib
|
||||
|
||||
@@ -153,7 +199,7 @@ jobs:
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run:
|
||||
command: npm test -- -w 2 -u
|
||||
command: npm test -- -w 1 -u
|
||||
environment:
|
||||
LIB_DIR: es
|
||||
|
||||
@@ -164,7 +210,7 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run: npm test -- -w 2 -u
|
||||
- run: npm test -- -w 1 -u
|
||||
|
||||
test_node_15:
|
||||
<<: *container_config
|
||||
@@ -173,49 +219,18 @@ jobs:
|
||||
- checkout
|
||||
- *attach_workspace
|
||||
- *install_react
|
||||
- run: npm run test-node -- -w 2 -u
|
||||
- run: npm run test-node -- -w 1 -u
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-test:
|
||||
jobs:
|
||||
- setup
|
||||
- dist:
|
||||
requires:
|
||||
- setup
|
||||
- compile:
|
||||
requires:
|
||||
- setup
|
||||
- lint:
|
||||
requires:
|
||||
- setup
|
||||
- test_dist:
|
||||
requires:
|
||||
- dist
|
||||
- test_lib:
|
||||
requires:
|
||||
- compile
|
||||
- test_es:
|
||||
requires:
|
||||
- compile
|
||||
- test_dom:
|
||||
requires:
|
||||
- setup
|
||||
- test_node:
|
||||
requires:
|
||||
- setup
|
||||
- test_dist_15:
|
||||
requires:
|
||||
- dist
|
||||
- test_lib_15:
|
||||
requires:
|
||||
- compile
|
||||
- test_es_15:
|
||||
requires:
|
||||
- compile
|
||||
- test_dom_15:
|
||||
requires:
|
||||
- setup
|
||||
- test_node_15:
|
||||
requires:
|
||||
- setup
|
||||
build_test:
|
||||
<<: *workflow
|
||||
nightly:
|
||||
<<: *workflow
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 0 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
components/**/*.js
|
||||
components/**/*.jsx
|
||||
components/*/__tests__/type.tsx
|
||||
!.eslintrc.js
|
||||
!components/*/__tests__/**/*.js
|
||||
!components/*/demo/*
|
||||
!.*.js
|
||||
|
||||
6
.jest.js
6
.jest.js
@@ -2,10 +2,11 @@ const libDir = process.env.LIB_DIR;
|
||||
|
||||
const transformIgnorePatterns = [
|
||||
'/dist/',
|
||||
'node_modules\/[^/]+?\/(?!(es|node_modules)\/)', // Ignore modules without es dir
|
||||
'node_modules/[^/]+?/(?!(es|node_modules)/)', // Ignore modules without es dir
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
verbose: true,
|
||||
setupFiles: [
|
||||
'./tests/setup.js',
|
||||
],
|
||||
@@ -46,6 +47,7 @@ module.exports = {
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfigFile: './tsconfig.test.json',
|
||||
}
|
||||
},
|
||||
},
|
||||
testURL: 'http://localhost',
|
||||
};
|
||||
|
||||
@@ -16,11 +16,11 @@ module.exports = {
|
||||
testRegex: 'demo\\.test\\.js$',
|
||||
testEnvironment: 'node',
|
||||
snapshotSerializers: [
|
||||
'enzyme-to-json/serializer'
|
||||
'enzyme-to-json/serializer',
|
||||
],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsConfigFile: './tsconfig.test.json',
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -67,6 +67,7 @@ Eden Wang <Eden.Wang@Akmii.com>
|
||||
Eden Wang <yociduo@vip.qq.com>
|
||||
Egor Yurtaev <yurtaev.egor@gmail.com>
|
||||
Eli White <github@eli-white.com>
|
||||
Emerson Laurentino <emersonlaurentino@hotmail.com>
|
||||
Emma <sima.zhang1990@gmail.com>
|
||||
Eric <84263800@qq.com>
|
||||
Erwann Mest <m+github@kud.io>
|
||||
@@ -453,4 +454,4 @@ zuiidea <zuiiidea@gmail.com>
|
||||
超能刚哥 <margox@foxmail.com>
|
||||
马金花儿 <o.o@mug.dog>
|
||||
रोहन मल्होत्रा <rohan.malhotra@adwyze.com>
|
||||
白羊座小葛 <abeyuhang@gmail.com>
|
||||
白羊座小葛 <abeyuhang@gmail.com>
|
||||
@@ -14,6 +14,89 @@ timeline: true
|
||||
* Major version release is not included in this schedule for breaking change and new features.
|
||||
|
||||
---
|
||||
## 3.8.2
|
||||
|
||||
`2018-8-18`
|
||||
|
||||
- 🐞 Fixed Tag still visible when initially setting `visible` prop to false. [#11757](https://github.com/ant-design/ant-design/issues/11757)
|
||||
- 🐞 Fixed Modal text got selected when opened by double click. [#11777](https://github.com/ant-design/ant-design/issues/11777)
|
||||
- 🐞 Fixed style of Rate component while getting clicked. [#11736](https://github.com/ant-design/ant-design/issues/11736)
|
||||
- 🐞 Fixed style of Badge component when its children is `display:block`. [#84119d8](https://github.com/ant-design/ant-design/commit/84119d8959d55edf535a9cac5ff532e61b6ee698)
|
||||
- Drawer
|
||||
- 🐞 Fixed Drawer not compatible with IE10 and IE9. [#11583](https://github.com/ant-design/ant-design/issues/11583)
|
||||
- 🐞 Fixed Drawer not being able to be scrolled vertically on mobile device. [#11443](https://github.com/ant-design/ant-design/issues/11443)
|
||||
- TypeScript
|
||||
- 🐞 Fixed `selectable` prop is missing in TreeNode props. [#11604](https://github.com/ant-design/ant-design/issues/11604) [@apieceofbart](https://github.com/apieceofbart)
|
||||
- 🐞 Fixed `autosize` prop is missing in Input props. [#11697](https://github.com/ant-design/ant-design/issues/11697)
|
||||
|
||||
|
||||
## 3.8.1
|
||||
|
||||
`2018-08-12`
|
||||
|
||||
- 🐞 Fixed TimePicker unexpected long width. [80f8267](https://github.com/ant-design/ant-design/commit/80f82674fb63b068d047651ccba772999139f1b7)
|
||||
- 🐞 Fixed Tabs that focusable element in inactive panel cause tabs disappear. [#11261](https://github.com/ant-design/ant-design/issues/11261)
|
||||
- 🐞 Fixed Badge `offset` x y axis order error. [#11648](https://github.com/ant-design/ant-design/pull/11648) [@tangjinzhou](https://github.com/tangjinzhou)
|
||||
- Upload
|
||||
- 🐞 Fixed detete button missing in Upload. [#10454](https://github.com/ant-design/ant-design/issues/10454)
|
||||
- 🐞 Fixed Upload thumbnail which url has no extension. [#11684](https://github.com/ant-design/ant-design/pull/11684) [@elantion](https://github.com/elantion)
|
||||
- 🐞 Fixed Anchor with `affix=true` doesn't work inside inner scrollable. [#11688](https://github.com/ant-design/ant-design/pull/11688) [@vitaliymaz](https://github.com/vitaliymaz)
|
||||
- 🐞 Fixed card width in List.Grid. [!11712](https://github.com/ant-design/ant-design/issues/11712)
|
||||
- 🐞 Fixed Radio align problem in safari. [754a22c](https://github.com/ant-design/ant-design/commit/754a22ca24dee685666554778f53a5fe700959ff)
|
||||
- 💄 Apply wave click animation to components Switch, Radio.Button and Tag. [9cf6ae6](https://github.com/ant-design/ant-design/commit/9cf6ae601010acbf665d575d34c0cc0918e604e7)
|
||||
- TypeScript
|
||||
- 🐞 Fixed missing prop signature `destroyInactivePanel` of Collapse. [#11646](https://github.com/ant-design/ant-design/pull/11646) [@zheeeng](https://github.com/zheeeng)
|
||||
- 🐞 Fixed missing prop `getPopupContainer` signature of AutoComplete. [#11690](https://github.com/ant-design/ant-design/pull/11690) [@Huanghuiying0624](https://github.com/Huanghuiying0624)
|
||||
- 🐞 Fixed Upload `lastModifiedDate` signature. [#11709](https://github.com/ant-design/ant-design/pull/11709) [@andycall](https://github.com/andycall)
|
||||
- 💄 Migrate to new lifecycle methods, include components TimePicker, Upload, CheckboxGroup, Layout.Sider, Tooltip, Popconfirm. [#11666](https://github.com/ant-design/ant-design/pull/11666) [@dancerphil](https://github.com/dancerphil) [#11682](https://github.com/ant-design/ant-design/pull/11682) [@dancerphil](https://github.com/dancerphil)
|
||||
|
||||
## 3.8.0
|
||||
|
||||
`2018-08-05`
|
||||
|
||||
Thanks to 24 contributors who send pull request to 3.8.0!
|
||||
|
||||
- 💄 Support TypeScript 3 and improve lots of definitions.
|
||||
- 💄 Use [tabular-nums font variant](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-numeric) instead of monospaced numberic font family Tahoma. [#11567](https://github.com/ant-design/ant-design/pull/11567) [@tibdex](https://github.com/tibdex)
|
||||
- 🌟 Timeline support `mode="left|right|alternate"` now. [#11490](https://github.com/ant-design/ant-design/pull/11490) [@jrvboesch](https://github.com/jrvboesch)
|
||||
- 🌟 Button added `block` prop which allow to fit parent container. [#11500](https://github.com/ant-design/ant-design/pull/11500) [@ilanus](https://github.com/ilanus)
|
||||
- Tree
|
||||
- 💄 Better accessibility support.
|
||||
- 🐞 Fixed that some tree nodes disapear after dragged. [#11492](https://github.com/ant-design/ant-design/issues/11492)
|
||||
- 🐞 Fixed a vertical align style issue of draggable tree. [#11458](https://github.com/ant-design/ant-design/issues/11458)
|
||||
- Table
|
||||
- 🌟 Added `rowSelection.columnTitle` to customize selection column title. [#11042](https://github.com/ant-design/ant-design/issues/11042) [@littleLane](https://github.com/littleLane)
|
||||
- 💄 Added demo of [resizable columns](/components/table/#components-table-demo-resizable-column)。
|
||||
- 💄 Support to select multiple rows when pressing `shift`. [#11404](https://github.com/ant-design/ant-design/issues/11404) [@RaphaelChauveau](https://github.com/RaphaelChauveau)
|
||||
- Avatar
|
||||
- 🌟 Added `onError` prop that is callback when image loading fail. [#11285](https://github.com/ant-design/ant-design/pull/11285/) [@paranoidjk](https://github.com/paranoidjk)
|
||||
- 🌟 Added `size` prop for customize size of Avatar. [#11256](https://github.com/ant-design/ant-design/issues/11256) [@emersonlaurentino](https://github.com/emersonlaurentino)
|
||||
- 🌟 Card added `headStyle` prop. [#11407](https://github.com/ant-design/ant-design/pull/11407) [@emersonlaurentino](https://github.com/emersonlaurentino)
|
||||
- 🐞 Fixed that Tooltip not working with DatePicker. [#11451](https://github.com/ant-design/ant-design/issues/11451) [@yociduo](https://github.com/yociduo)
|
||||
- 🐞 Fixed that Tooltip not working with Input.Group. [#11532](https://github.com/ant-design/ant-design/issues/11532) [@yociduo](https://github.com/yociduo)
|
||||
- 🐞 Fixed that DatePicker time panel text jumping when hovering. [#11460](https://github.com/ant-design/ant-design/issues/11460)
|
||||
- 🐞 Fixed Tabs display issue when switch focus elements bettween panels. [#11261](https://github.com/ant-design/ant-design/issues/11261)
|
||||
- Select
|
||||
- 💄 Support `data-*` attributes.
|
||||
- 🐞 Fixed that selected item don't display correct position in dropdown menu items. [#11268](https://github.com/ant-design/ant-design/issues/11268)
|
||||
- 🌟 Calendar added `onChange` prop. [#11476](https://github.com/ant-design/ant-design/pull/11476) [@tangjinzhou](https://github.com/tangjinzhou)
|
||||
- 🌟 Popconfirm added `icon` prop. [#11191](https://github.com/ant-design/ant-design/pull/11191) [@nuintun](https://github.com/nuintun)
|
||||
- Modal
|
||||
- 🌟 Added `centered` prop to set vertical center position of modal. [#11537](https://github.com/ant-design/ant-design/pull/11537) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fixed that closing all modals when pressing `ESC` once, now they will be closed one by one. [#11394](https://github.com/ant-design/ant-design/issues/11394) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fixed issue resulting title of Model.confirm shows scrollbar again. [#11568](https://github.com/ant-design/ant-design/pull/11568) [@cheshireoctopus](https://github.com/cheshireoctopus)
|
||||
- 🌟 Progress added `strokeLinecap` to customize shape of edge. [#11547](https://github.com/ant-design/ant-design/pull/11547) [@blatinier](https://github.com/blatinier)
|
||||
- 🌟 Drawer added `className` and deprecated `wrapClassName`. [#11609](https://github.com/ant-design/ant-design/pull/11609) [@fergiar](https://github.com/fergiar)
|
||||
|
||||
## 3.7.3
|
||||
|
||||
`2018-07-28`
|
||||
|
||||
- 🐞 Fix issue resulting in title not vertical align with icon when setting `labelPlacement` to `vertical` in Steps. [#11426](https://github.com/ant-design/ant-design/pull/11426) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 Fix issue resulting in the children field specified in `fieldName` could not be read correctly in Cascader. [#11311](https://github.com/ant-design/ant-design/pull/11311) [@405go](https://github.com/405go)
|
||||
- TypeScript
|
||||
- 🐞 Fix type definition of Pagination. [#11474](https://github.com/ant-design/ant-design/pull/11474) [@kagd](https://github.com/kagd)
|
||||
- 🐞 Fix type definition of Select. [#11189](https://github.com/ant-design/ant-design/pull/11189<Paste>) [@thisJJ](https://github.com/thisJJ)
|
||||
|
||||
## 3.7.2
|
||||
|
||||
|
||||
@@ -15,6 +15,88 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.8.2
|
||||
|
||||
`2018-8-18`
|
||||
- 🐞 修复 Tag 组件 `visible` 属性初始值为 false 时仍然可见的问题。[#11757](https://github.com/ant-design/ant-design/issues/11757)
|
||||
- 🐞 修复 Modal 文本在双击打开的时候会被选中的问题。[#11777](https://github.com/ant-design/ant-design/issues/11777)
|
||||
- 🐞 修复 Rate 组件点击时的样式问题。[#11736](https://github.com/ant-design/ant-design/issues/11736)
|
||||
- 🐞 修复 Badge 组件在子元素为 `display:block` 时的样式问题。[#84119d8](https://github.com/ant-design/ant-design/commit/84119d8959d55edf535a9cac5ff532e61b6ee698)
|
||||
- Drawer
|
||||
- 🐞 修复 Drawer 组件不兼容 IE10 和 IE9 的问题。[#11583](https://github.com/ant-design/ant-design/issues/11583)
|
||||
- 🐞 修复 Drawer 组件在移动设备上无法垂直滚动的问题。 [#11443](https://github.com/ant-design/ant-design/issues/11443)
|
||||
- TypeScript
|
||||
- 🐞 修复 TreeNode 组件缺少的 `selectable` 属性定义。[#11604](https://github.com/ant-design/ant-design/issues/11604) [@apieceofbart](https://github.com/apieceofbart)
|
||||
- 🐞 修复 Input 组件缺失 `autosize` 属性的类型错误。[#11697](https://github.com/ant-design/ant-design/issues/11697)
|
||||
|
||||
## 3.8.1
|
||||
|
||||
`2018-08-12`
|
||||
|
||||
- 🐞 修复 TimePicker 面板输入框宽度过长的问题。[80f8267](https://github.com/ant-design/ant-design/commit/80f82674fb63b068d047651ccba772999139f1b7)
|
||||
- 🐞 修复 Tabs 中隐藏的输入框可能被聚焦的问题。[#11261](https://github.com/ant-design/ant-design/issues/11261)
|
||||
- 🐞 修复 Badge 组件属性 `offset` 的坐标设置顺序问题。[#11648](https://github.com/ant-design/ant-design/pull/11648) [@tangjinzhou](https://github.com/tangjinzhou)
|
||||
- Upload
|
||||
- 🐞 修复 Upload 组件删除按钮可能不展示的问题。[#10454](https://github.com/ant-design/ant-design/issues/10454)
|
||||
- 🐞 修复 Upload 组件缩略图地址没有文件扩展名时的显示问题。[#11684](https://github.com/ant-design/ant-design/pull/11684) [@elantion](https://github.com/elantion)
|
||||
- 🐞 修复 Anchor 组件当 `affix=true` 时无法在滚动的窗口中固定的问题。[#11688](https://github.com/ant-design/ant-design/pull/11688) [@vitaliymaz](https://github.com/vitaliymaz)
|
||||
- 🐞 修复 List.Grid 组件中的卡片宽度问题。[!11712](https://github.com/ant-design/ant-design/issues/11712)
|
||||
- 🐞 修复 Radio 在 safari 下对齐的问题。[754a22c](https://github.com/ant-design/ant-design/commit/754a22ca24dee685666554778f53a5fe700959ff)
|
||||
- 💄 添加点击动画效果到组件 Switch, Radio.Button 和 Tag。[9cf6ae6](https://github.com/ant-design/ant-design/commit/9cf6ae601010acbf665d575d34c0cc0918e604e7)
|
||||
- TypeScript
|
||||
- 🐞 修复 Collapse 组件缺少的 `destroyInactivePanel` 定义。[#11646](https://github.com/ant-design/ant-design/pull/11646) [@zheeeng](https://github.com/zheeeng)
|
||||
- 💄 修复 AutoComplete 没有 `getPopupContainer` 属性定义的问题。[#11690](https://github.com/ant-design/ant-design/pull/11690) [@Huanghuiying0624](https://github.com/Huanghuiying0624)
|
||||
- 🐞 修复 Upload 组件的 `lastModifiedDate` 定义。[#11709](https://github.com/ant-design/ant-design/pull/11709) [@andycall](https://github.com/andycall)
|
||||
- 💄 使用新的 React 生命周期函数,包括组件 Upload, CheckboxGroup, Layout.Sider, Tooltip, Popconfirm。[#11666](https://github.com/ant-design/ant-design/pull/11666) [@dancerphil](https://github.com/dancerphil) [#11682](https://github.com/ant-design/ant-design/pull/11682) [@dancerphil](https://github.com/dancerphil)
|
||||
|
||||
## 3.8.0
|
||||
|
||||
`2018-08-05`
|
||||
|
||||
非常感谢在 3.8.0 上提交 PR 的 24 位贡献者!
|
||||
|
||||
- 💄 支持 TypeScript 3,并优化了大量组件定义。
|
||||
- 💄 使用 [font-variant-numeric](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant-numeric) 优化了等宽数字的实现方式,解决了数字字体和其他字体不一致的问题。[#11567](https://github.com/ant-design/ant-design/pull/11567) [@tibdex](https://github.com/tibdex)
|
||||
- 🌟 Timeline 现在支持左/右/交替三种布局形式。[#11490](https://github.com/ant-design/ant-design/pull/11490) [@jrvboesch](https://github.com/jrvboesch)
|
||||
- 🌟 Button 增加 `block` 属性用于撑满父容器宽度。[#11500](https://github.com/ant-design/ant-design/pull/11500) [@ilanus](https://github.com/ilanus)
|
||||
- Tree
|
||||
- 💄 优化了组件可访问性。
|
||||
- 🐞 修复一个拖拽后节点失踪的问题。[#11492](https://github.com/ant-design/ant-design/issues/11492)
|
||||
- 🐞 修复一个在拖拽后节点位置没有垂直居中的问题。[#11458](https://github.com/ant-design/ant-design/issues/11458)
|
||||
- Table
|
||||
- 🌟 新增 `rowSelection.columnTitle` 可以定制选择列的列标题。[#11042](https://github.com/ant-design/ant-design/issues/11042) [@littleLane](https://github.com/littleLane)
|
||||
- 💄 新增了一个[可拖拽改变列宽的例子](/components/table/#components-table-demo-resizable-column)。
|
||||
- 💄 支持按住 shift 进行多选。[#11404](https://github.com/ant-design/ant-design/issues/11404) [@RaphaelChauveau](https://github.com/RaphaelChauveau)
|
||||
- Avatar
|
||||
- 🌟 新增 `onError` 属性,作为图片加载失败时的回调。[#11285](https://github.com/ant-design/ant-design/pull/11285/) [@paranoidjk](https://github.com/paranoidjk)
|
||||
- 🌟 新增 `size` 属性,方便自定义头像大小。[#11256](https://github.com/ant-design/ant-design/issues/11256) [@emersonlaurentino](https://github.com/emersonlaurentino)
|
||||
- 🌟 Card 新增 `headStyle` 属性用于定制标题样式。[#11407](https://github.com/ant-design/ant-design/pull/11407) [@emersonlaurentino](https://github.com/emersonlaurentino)
|
||||
- 🐞 修复 DatePicker 上无法使用 Tooltip 的问题。[#11451](https://github.com/ant-design/ant-design/issues/11451) [@yociduo](https://github.com/yociduo)
|
||||
- 🐞 修复 Input.Group 上无法使用 Tooltip 的问题。[#11532](https://github.com/ant-design/ant-design/issues/11532) [@yociduo](https://github.com/yociduo)
|
||||
- 🐞 修复一个 DatePicker 中时间面板 hover 时数字跳动的问题。[#11460](https://github.com/ant-design/ant-design/issues/11460)
|
||||
- 🐞 Tabs 修复了一个切换焦点异常的问题。[#11261](https://github.com/ant-design/ant-design/issues/11261)
|
||||
- Select
|
||||
- 🌟 支持 `data-*` 属性。
|
||||
- 🐞 修复一个选中项在列表中没有聚焦的问题。[#11268](https://github.com/ant-design/ant-design/issues/11268)
|
||||
- 🌟 Calendar 新增了 `onChange` 作为日期改变的回调。[#11476](https://github.com/ant-design/ant-design/pull/11476) [@tangjinzhou](https://github.com/tangjinzhou)
|
||||
- 🌟 Popconfirm 新增 `icon` 支持自定义图标。[#11191](https://github.com/ant-design/ant-design/pull/11191) [@nuintun](https://github.com/nuintun)
|
||||
- Modal
|
||||
- 🌟 新增 `centered` 属性用于设置对话框垂直居中。[#11537](https://github.com/ant-design/ant-design/pull/11537) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 修复了多个对话框会被 ESC 一次性全部关掉的问题。[#11394](https://github.com/ant-design/ant-design/issues/11394) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 再次修复 Model.confirm 的标题区域某些情况下会显示滚动条的问题。[#11568](https://github.com/ant-design/ant-design/pull/11568) [@cheshireoctopus](https://github.com/cheshireoctopus)
|
||||
- 🌟 Progress 新增 `strokeLinecap` 属性用于调整边缘形状。[#11547](https://github.com/ant-design/ant-design/pull/11547) [@blatinier](https://github.com/blatinier)
|
||||
- 🌟 Drawer 新增 `className` 并废弃 `wrapClassName`。[#11609](https://github.com/ant-design/ant-design/pull/11609) [@fergiar](https://github.com/fergiar)
|
||||
|
||||
## 3.7.3
|
||||
|
||||
`2018-07-28`
|
||||
|
||||
- 🐞 修复 Steps 在 `labelPlacement` 为 `vertical` 时标题与图标不对齐的问题。[#11426](https://github.com/ant-design/ant-design/pull/11426) [@yoyo837](https://github.com/yoyo837)
|
||||
- 🐞 修复 Cascader 设置 `fieldNames` 时不能正确读取子节点的问题。[#11311](https://github.com/ant-design/ant-design/pull/11311) [@405go](https://github.com/405go)
|
||||
- TypeScript
|
||||
- 🐞 修复 Pagination 类型定义。[#11474](https://github.com/ant-design/ant-design/pull/11474) [@kagd](https://github.com/kagd)
|
||||
- 🐞 修复 Select 类型定义。[#11189](https://github.com/ant-design/ant-design/pull/11189<Paste>) [@thisJJ](https://github.com/thisJJ)
|
||||
|
||||
## 3.7.2
|
||||
|
||||
`2018-07-25`
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
# Ant Design
|
||||
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://circleci.com/gh/ant-design/ant-design/)
|
||||
[](https://codecov.io/gh/ant-design/ant-design/branch/master)
|
||||
[](https://david-dm.org/ant-design/ant-design)
|
||||
[](https://david-dm.org/ant-design/ant-design?type=dev)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# Ant Design
|
||||
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://circleci.com/gh/ant-design/ant-design/)
|
||||
[](https://codecov.io/gh/ant-design/ant-design/branch/master)
|
||||
[](https://david-dm.org/ant-design/ant-design)
|
||||
[](https://david-dm.org/ant-design/ant-design?type=dev)
|
||||
|
||||
103
components/_util/wave.tsx
Normal file
103
components/_util/wave.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import * as React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import TransitionEvents from 'css-animation/lib/Event';
|
||||
|
||||
export default class Wave extends React.Component<{insertExtraNode?: boolean}> {
|
||||
private instance?: {
|
||||
cancel: () => void;
|
||||
};
|
||||
|
||||
private styleForPesudo: HTMLStyleElement | null;
|
||||
|
||||
isNotGrey(color: string) {
|
||||
const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/);
|
||||
if (match && match[1] && match[2] && match[3]) {
|
||||
return !(match[1] === match[2] && match[2] === match[3]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
onClick = (node: HTMLElement) => {
|
||||
if (node.className.indexOf('-leave') >= 0) {
|
||||
return;
|
||||
}
|
||||
this.removeExtraStyleNode();
|
||||
const { insertExtraNode } = this.props;
|
||||
const extraNode = document.createElement('div');
|
||||
extraNode.className = 'ant-click-animating-node';
|
||||
const attributeName = insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
|
||||
node.removeAttribute(attributeName);
|
||||
node.setAttribute(attributeName, 'true');
|
||||
// Get wave color from target
|
||||
const waveColor =
|
||||
getComputedStyle(node).getPropertyValue('border-top-color') || // Firefox Compatible
|
||||
getComputedStyle(node).getPropertyValue('border-color') ||
|
||||
getComputedStyle(node).getPropertyValue('background-color');
|
||||
// Not white or transparnt or grey
|
||||
if (waveColor &&
|
||||
waveColor !== '#ffffff' &&
|
||||
waveColor !== 'rgb(255, 255, 255)' &&
|
||||
this.isNotGrey(waveColor) &&
|
||||
!/rgba\(\d*, \d*, \d*, 0\)/.test(waveColor) && // any transparent rgba color
|
||||
waveColor !== 'transparent') {
|
||||
extraNode.style.borderColor = waveColor;
|
||||
this.styleForPesudo = document.createElement('style');
|
||||
this.styleForPesudo.innerHTML =
|
||||
`[ant-click-animating-without-extra-node]:after { border-color: ${waveColor}; }`;
|
||||
document.body.appendChild(this.styleForPesudo);
|
||||
}
|
||||
if (insertExtraNode) {
|
||||
node.appendChild(extraNode);
|
||||
}
|
||||
const transitionEnd = () => {
|
||||
node.removeAttribute(attributeName);
|
||||
this.removeExtraStyleNode();
|
||||
if (insertExtraNode) {
|
||||
node.removeChild(extraNode);
|
||||
}
|
||||
TransitionEvents.removeEndEventListener(node, transitionEnd);
|
||||
};
|
||||
TransitionEvents.addEndEventListener(node, transitionEnd);
|
||||
}
|
||||
|
||||
bindAnimationEvent = (node: HTMLElement) => {
|
||||
if (node.getAttribute('disabled') ||
|
||||
node.className.indexOf('disabled') >= 0) {
|
||||
return;
|
||||
}
|
||||
const onClick = (e: MouseEvent) => {
|
||||
// Fix radio button click twice
|
||||
if ((e.target as HTMLElement).tagName === 'INPUT') {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => this.onClick(node), 0);
|
||||
};
|
||||
node.addEventListener('click', onClick, true);
|
||||
return {
|
||||
cancel: () => {
|
||||
node.removeEventListener('click', onClick, true);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
removeExtraStyleNode() {
|
||||
if (this.styleForPesudo && document.body.contains(this.styleForPesudo)) {
|
||||
document.body.removeChild(this.styleForPesudo);
|
||||
this.styleForPesudo = null;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.instance = this.bindAnimationEvent(findDOMNode(this) as HTMLElement);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.instance) {
|
||||
this.instance.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import shallowequal from 'shallowequal';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import Affix from '../affix';
|
||||
@@ -240,6 +240,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
affix,
|
||||
showInkInFixed,
|
||||
children,
|
||||
getContainer,
|
||||
} = this.props;
|
||||
const { activeLink } = this.state;
|
||||
|
||||
@@ -273,7 +274,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
);
|
||||
|
||||
return !affix ? anchorContent : (
|
||||
<Affix offsetTop={offsetTop}>
|
||||
<Affix offsetTop={offsetTop} target={getContainer}>
|
||||
{anchorContent}
|
||||
</Affix>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface AnchorLinkProps {
|
||||
|
||||
@@ -62,11 +62,8 @@ 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));
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
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 () => {
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface AutoCompleteProps extends AbstractSelectProps {
|
||||
value?: SelectValue;
|
||||
defaultValue?: SelectValue;
|
||||
dataSource?: DataSourceItemType[];
|
||||
autoFocus?: boolean;
|
||||
backfill?: boolean;
|
||||
optionLabelProp?: string;
|
||||
onChange?: (value: SelectValue) => void;
|
||||
|
||||
@@ -15,7 +15,8 @@ describe('Avatar Render', () => {
|
||||
|
||||
const wrapper = mount(<Avatar src="http://error.url">Fallback</Avatar>, { attachTo: div });
|
||||
wrapper.instance().setScale = jest.fn(() => wrapper.instance().setState({ scale: 0.5 }));
|
||||
wrapper.setState({ isImgExist: false });
|
||||
|
||||
wrapper.find('img').simulate('error');
|
||||
|
||||
const children = wrapper.find('.ant-avatar-string');
|
||||
expect(children.length).toBe(1);
|
||||
@@ -26,4 +27,41 @@ describe('Avatar Render', () => {
|
||||
wrapper.detach();
|
||||
global.document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('should handle onError correctly', () => {
|
||||
const LOAD_FAILURE_SRC = 'http://error.url';
|
||||
const LOAD_SUCCESS_SRC = 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png';
|
||||
|
||||
const div = global.document.createElement('div');
|
||||
global.document.body.appendChild(div);
|
||||
|
||||
class Foo extends React.Component {
|
||||
state = {
|
||||
src: LOAD_FAILURE_SRC,
|
||||
}
|
||||
|
||||
handleImgError = () => {
|
||||
this.setState({
|
||||
src: LOAD_SUCCESS_SRC,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { src } = this.state;
|
||||
return <Avatar src={src} onError={this.handleImgError} />;
|
||||
}
|
||||
}
|
||||
|
||||
const wrapper = mount(<Foo />, { attachTo: div });
|
||||
// mock img load Error, since jsdom do not load resource by default
|
||||
// https://github.com/jsdom/jsdom/issues/1816
|
||||
wrapper.find('img').simulate('error');
|
||||
|
||||
expect(wrapper.find(Avatar).instance().state.isImgExist).toBe(true);
|
||||
expect(div.querySelector('img').getAttribute('src')).toBe(LOAD_SUCCESS_SRC);
|
||||
|
||||
wrapper.detach();
|
||||
global.document.body.removeChild(div);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -201,6 +201,14 @@ exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
|
||||
exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
style="width:64px;height:64px;line-height:64px;font-size:32px"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
@@ -224,6 +232,14 @@ exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-square ant-avatar-icon"
|
||||
style="width:64px;height:64px;line-height:64px;font-size:32px"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-lg ant-avatar-square ant-avatar-icon"
|
||||
>
|
||||
|
||||
@@ -19,11 +19,13 @@ import { Avatar } from 'antd';
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<div>
|
||||
<Avatar size={64} icon="user" />
|
||||
<Avatar size="large" icon="user" />
|
||||
<Avatar icon="user" />
|
||||
<Avatar size="small" icon="user" />
|
||||
</div>
|
||||
<div>
|
||||
<Avatar shape="square" size={64} icon="user" />
|
||||
<Avatar shape="square" size="large" icon="user" />
|
||||
<Avatar shape="square" icon="user" />
|
||||
<Avatar shape="square" size="small" icon="user" />
|
||||
|
||||
@@ -12,6 +12,7 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| icon | the `Icon` type for an icon avatar, see `Icon` Component | string | - |
|
||||
| shape | the shape of avatar | `circle` \| `square` | `circle` |
|
||||
| size | the size of the avatar | `large` \| `small` \| `default` | `default` |
|
||||
| size | the size of the avatar | number \| string: `large` `small` `default` | `default` |
|
||||
| src | the address of the image for an image avatar | string | - |
|
||||
| alt | This attribute defines the alternative text describing the image | string | - |
|
||||
| alt | This attribute defines the alternative text describing the image | string | - |
|
||||
| onError | handler when img load error,return false to prevent default fallback behavior | () => boolean | - |
|
||||
|
||||
@@ -6,8 +6,11 @@ import classNames from 'classnames';
|
||||
export interface AvatarProps {
|
||||
/** Shape of avatar, options:`circle`, `square` */
|
||||
shape?: 'circle' | 'square';
|
||||
/** Size of avatar, options:`large`, `small`, `default` */
|
||||
size?: 'large' | 'small' | 'default';
|
||||
/*
|
||||
* Size of avatar, options: `large`, `small`, `default`
|
||||
* or a custom number size
|
||||
* */
|
||||
size?: 'large' | 'small' | 'default' | number;
|
||||
/** Src of image avatar */
|
||||
src?: string;
|
||||
/** Type of the Icon to be used in avatar */
|
||||
@@ -17,6 +20,9 @@ export interface AvatarProps {
|
||||
className?: string;
|
||||
children?: any;
|
||||
alt?: string;
|
||||
/* callback when img load error */
|
||||
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self*/
|
||||
onError?: () => boolean;
|
||||
}
|
||||
|
||||
export interface AvatarState {
|
||||
@@ -72,13 +78,21 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
}
|
||||
}
|
||||
|
||||
handleImgLoadError = () => this.setState({ isImgExist: false });
|
||||
handleImgLoadError = () => {
|
||||
const { onError } = this.props;
|
||||
const errorFlag = onError ? onError() : undefined;
|
||||
if (errorFlag !== false) {
|
||||
this.setState({ isImgExist: false });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls, shape, size, src, icon, className, alt, ...others
|
||||
} = this.props;
|
||||
|
||||
const { isImgExist, scale } = this.state;
|
||||
|
||||
const sizeCls = classNames({
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
@@ -86,12 +100,19 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
|
||||
const classString = classNames(prefixCls, className, sizeCls, {
|
||||
[`${prefixCls}-${shape}`]: shape,
|
||||
[`${prefixCls}-image`]: src && this.state.isImgExist,
|
||||
[`${prefixCls}-image`]: src && isImgExist,
|
||||
[`${prefixCls}-icon`]: icon,
|
||||
});
|
||||
|
||||
const sizeStyle: React.CSSProperties = typeof size === 'number' ? {
|
||||
width: size,
|
||||
height: size,
|
||||
lineHeight: `${size}px`,
|
||||
fontSize: icon ? size / 2 : 18,
|
||||
} : {};
|
||||
|
||||
let children = this.props.children;
|
||||
if (src && this.state.isImgExist) {
|
||||
if (src && isImgExist) {
|
||||
children = (
|
||||
<img
|
||||
src={src}
|
||||
@@ -103,20 +124,24 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
children = <Icon type={icon} />;
|
||||
} else {
|
||||
const childrenNode = this.avatarChildren;
|
||||
if (childrenNode || this.state.scale !== 1) {
|
||||
if (childrenNode || scale !== 1) {
|
||||
const childrenStyle: React.CSSProperties = {
|
||||
msTransform: `scale(${this.state.scale})`,
|
||||
WebkitTransform: `scale(${this.state.scale})`,
|
||||
transform: `scale(${this.state.scale})`,
|
||||
msTransform: `scale(${scale})`,
|
||||
WebkitTransform: `scale(${scale})`,
|
||||
transform: `scale(${scale})`,
|
||||
position: 'absolute',
|
||||
display: 'inline-block',
|
||||
left: `calc(50% - ${Math.round(childrenNode.offsetWidth / 2)}px)`,
|
||||
};
|
||||
const sizeChildrenStyle: React.CSSProperties =
|
||||
typeof size === 'number' ? {
|
||||
lineHeight: `${size}px`,
|
||||
} : {};
|
||||
children = (
|
||||
<span
|
||||
className={`${prefixCls}-string`}
|
||||
ref={span => this.avatarChildren = span}
|
||||
style={childrenStyle}
|
||||
style={{ ...sizeChildrenStyle, ...childrenStyle }}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
@@ -133,7 +158,11 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
||||
}
|
||||
}
|
||||
return (
|
||||
<span {...others} className={classString}>
|
||||
<span
|
||||
{...others}
|
||||
style={{ ...sizeStyle, ...others.style }}
|
||||
className={classString}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -16,3 +16,4 @@ title: Avatar
|
||||
| size | 设置头像的大小 | Enum{ 'large', 'small', 'default' } | `default` |
|
||||
| src | 图片类头像的资源地址 | string | - |
|
||||
| alt | 图像无法显示时的替代文本 | string | - |
|
||||
| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - |
|
||||
|
||||
@@ -63,6 +63,8 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
this.setScrollTop(easeInOutCubic(time, scrollTop, 0, 450));
|
||||
if (time < 450) {
|
||||
raf(frameFunc);
|
||||
} else {
|
||||
this.setScrollTop(0);
|
||||
}
|
||||
};
|
||||
raf(frameFunc);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import Animate from 'rc-animate';
|
||||
import ScrollNumber from './ScrollNumber';
|
||||
import classNames from 'classnames';
|
||||
@@ -85,8 +85,8 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
[`${prefixCls}-not-a-wrapper`]: !children,
|
||||
});
|
||||
const styleWithOffset = offset ? {
|
||||
marginTop: offset[0],
|
||||
marginLeft: offset[1],
|
||||
marginLeft: offset[0],
|
||||
marginTop: offset[1],
|
||||
...style,
|
||||
} : style;
|
||||
// <Badge status="success" />
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
color: unset;
|
||||
|
||||
&-count {
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
top: -@badge-height / 2;
|
||||
transform: translate(50%, -50%);
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: @badge-height;
|
||||
border-radius: @badge-height / 2;
|
||||
min-width: @badge-height;
|
||||
@@ -26,7 +28,7 @@
|
||||
font-size: @badge-font-size;
|
||||
font-weight: @badge-font-weight;
|
||||
white-space: nowrap;
|
||||
transform-origin: -10% center;
|
||||
transform-origin: 0 center;
|
||||
box-shadow: 0 0 0 1px #fff;
|
||||
a,
|
||||
a:hover {
|
||||
@@ -40,9 +42,10 @@
|
||||
|
||||
&-dot {
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
transform: translate(50%, -50%);
|
||||
transform-origin: 0 center;
|
||||
top: -@badge-dot-size / 2;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: @badge-dot-size;
|
||||
width: @badge-dot-size;
|
||||
border-radius: 100%;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import { cloneElement } from 'react';
|
||||
import warning from '../_util/warning';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
|
||||
export interface BreadcrumbItemProps {
|
||||
prefixCls?: string;
|
||||
|
||||
@@ -37,6 +37,43 @@ exports[`renders ./components/button/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/button/demo/block.md correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary ant-btn-block"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-block"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Default
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-dashed ant-btn-block"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Dashed
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-danger ant-btn-block"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
danger
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/button/demo/button-group.md correctly 1`] = `
|
||||
<div>
|
||||
<h4>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Wave from '../_util/wave';
|
||||
import Icon from '../icon';
|
||||
import Group from './button-group';
|
||||
|
||||
@@ -47,6 +48,7 @@ export interface BaseButtonProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
ghost?: boolean;
|
||||
block?: boolean;
|
||||
}
|
||||
|
||||
export type AnchorButtonProps = {
|
||||
@@ -70,6 +72,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
prefixCls: 'ant-btn',
|
||||
loading: false,
|
||||
ghost: false,
|
||||
block: false,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
@@ -81,16 +84,15 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
|
||||
className: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
block: PropTypes.bool,
|
||||
};
|
||||
|
||||
timeout: number;
|
||||
delayTimeout: number;
|
||||
private delayTimeout: number;
|
||||
|
||||
constructor(props: ButtonProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: props.loading,
|
||||
clicked: false,
|
||||
hasTwoCNChar: false,
|
||||
};
|
||||
}
|
||||
@@ -119,9 +121,6 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
if (this.delayTimeout) {
|
||||
clearTimeout(this.delayTimeout);
|
||||
}
|
||||
@@ -145,12 +144,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
}
|
||||
|
||||
handleClick: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> = e => {
|
||||
// Add click effect
|
||||
this.setState({ clicked: true });
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = window.setTimeout(() => this.setState({ clicked: false }), 500);
|
||||
|
||||
const onClick = this.props.onClick;
|
||||
const { onClick } = this.props;
|
||||
if (onClick) {
|
||||
(onClick as React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>)(e);
|
||||
}
|
||||
@@ -163,10 +157,10 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
|
||||
render() {
|
||||
const {
|
||||
type, shape, size, className, children, icon, prefixCls, ghost, loading: _loadingProp, ...rest
|
||||
type, shape, size, className, children, icon, prefixCls, ghost, loading: _loadingProp, block, ...rest
|
||||
} = this.props;
|
||||
|
||||
const { loading, clicked, hasTwoCNChar } = this.state;
|
||||
const { loading, hasTwoCNChar } = this.state;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
@@ -187,9 +181,9 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
||||
[`${prefixCls}-icon-only`]: !children && icon,
|
||||
[`${prefixCls}-loading`]: loading,
|
||||
[`${prefixCls}-clicked`]: clicked,
|
||||
[`${prefixCls}-background-ghost`]: ghost,
|
||||
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar,
|
||||
[`${prefixCls}-block`]: block,
|
||||
});
|
||||
|
||||
const iconType = loading ? 'loading' : icon;
|
||||
@@ -212,14 +206,16 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
const { htmlType, ...otherProps } = rest;
|
||||
|
||||
return (
|
||||
<button
|
||||
{...otherProps}
|
||||
type={htmlType || 'button'}
|
||||
className={classes}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
{iconNode}{kids}
|
||||
</button>
|
||||
<Wave>
|
||||
<button
|
||||
{...otherProps}
|
||||
type={htmlType || 'button'}
|
||||
className={classes}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
{iconNode}{kids}
|
||||
</button>
|
||||
</Wave>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
27
components/button/demo/block.md
Normal file
27
components/button/demo/block.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
order: 9
|
||||
title:
|
||||
zh-CN: block 按钮
|
||||
en-US: block Button
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
`block`属性将使按钮适合其父宽度。
|
||||
|
||||
## en-US
|
||||
|
||||
`block` property will make the button fit to its parent width.
|
||||
|
||||
````jsx
|
||||
import { Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Button type="primary" block>Primary</Button>
|
||||
<Button block>Default</Button>
|
||||
<Button type="dashed" block>Dashed</Button>
|
||||
<Button type="danger" block>danger</Button>
|
||||
</div>,
|
||||
mountNode);
|
||||
````
|
||||
@@ -27,6 +27,7 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
|
||||
| target | same as target attribute of a, works when href is specified | string | - |
|
||||
| type | can be set to `primary` `ghost` `dashed` `danger`(added in 2.7) or omitted (meaning `default`) | string | `default` |
|
||||
| onClick | set the handler to handle `click` event | function | - |
|
||||
| block | option to fit button width to its parent width | boolean | `false` |
|
||||
|
||||
`<Button>Hello world!</Button>` will be rendered into `<button><span>Hello world!</span></button>`, and all the properties which are not listed above will be transferred to the `<button>` tag.
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ subtitle: 按钮
|
||||
| target | 相当于 a 链接的 target 属性,href 存在时生效 | string | - |
|
||||
| type | 设置按钮类型,可选值为 `primary` `dashed` `danger`(版本 2.7 中增加) 或者不设 | string | - |
|
||||
| onClick | `click` 事件的 handler | function | - |
|
||||
| block | 将按钮宽度调整为其父宽度的选项 | boolean | `false` |
|
||||
|
||||
`<Button>Hello world!</Button>` 最终会被渲染为 `<button><span>Hello world!</span></button>`,并且除了上表中的属性,其它属性都会直接传到 `<button></button>`。
|
||||
|
||||
|
||||
@@ -131,24 +131,6 @@
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&-clicked:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
bottom: -1px;
|
||||
right: -1px;
|
||||
border-radius: inherit;
|
||||
border: 0 solid @primary-color;
|
||||
opacity: 0.4;
|
||||
animation: buttonEffect .4s;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-danger&-clicked:after {
|
||||
border-color: @btn-danger-color;
|
||||
}
|
||||
|
||||
&-background-ghost {
|
||||
background: transparent !important;
|
||||
border-color: #fff;
|
||||
@@ -171,16 +153,9 @@
|
||||
letter-spacing: .34em;
|
||||
margin-right: -.34em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes buttonEffect {
|
||||
to {
|
||||
opacity: 0;
|
||||
top: -6px;
|
||||
left: -6px;
|
||||
bottom: -6px;
|
||||
right: -6px;
|
||||
border-width: 6px;
|
||||
&-block {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,3 +44,4 @@ When data is in the form of dates, such as schedules, timetables, prices calenda
|
||||
| value | The current selected date | [moment](http://momentjs.com/) | current date |
|
||||
| onPanelChange | Callback for when panel changes | function(date: moment, mode: string) | - |
|
||||
| onSelect | Callback for when a date is selected | function(date: moment) | - |
|
||||
| onChange | Callback for when date changes | function(date: moment) | - |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import * as moment from 'moment';
|
||||
import FullCalendar from 'rc-calendar/lib/FullCalendar';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
@@ -36,6 +36,7 @@ export interface CalendarProps {
|
||||
style?: React.CSSProperties;
|
||||
onPanelChange?: (date?: moment.Moment, mode?: CalendarMode) => void;
|
||||
onSelect?: (date?: moment.Moment) => void;
|
||||
onChange?: (date?: moment.Moment) => void;
|
||||
disabledDate?: (current: moment.Moment) => boolean;
|
||||
validRange ?: [moment.Moment, moment.Moment];
|
||||
}
|
||||
@@ -53,6 +54,7 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
mode: 'month',
|
||||
onSelect: noop,
|
||||
onPanelChange: noop,
|
||||
onChange: noop,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
@@ -68,6 +70,7 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
onPanelChange: PropTypes.func,
|
||||
value: PropTypes.object,
|
||||
onSelect: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
constructor(props: CalendarProps) {
|
||||
@@ -157,10 +160,13 @@ export default class Calendar extends React.Component<CalendarProps, CalendarSta
|
||||
}
|
||||
|
||||
onPanelChange(value: moment.Moment, mode: CalendarMode | undefined) {
|
||||
const { onPanelChange } = this.props;
|
||||
const { onPanelChange, onChange } = this.props;
|
||||
if (onPanelChange) {
|
||||
onPanelChange(value, mode);
|
||||
}
|
||||
if (onChange && value !== this.state.value) {
|
||||
onChange(value);
|
||||
}
|
||||
}
|
||||
|
||||
onSelect = (value: moment.Moment) => {
|
||||
|
||||
@@ -45,3 +45,4 @@ title: Calendar
|
||||
| value | 展示日期 | [moment](http://momentjs.com/) | 当前日期 |
|
||||
| onPanelChange | 日期面板变化回调 | function(date: moment, mode: string) | 无 |
|
||||
| onSelect | 点击选择日期回调 | function(date: moment) | 无 |
|
||||
| onChange | 日期变化回调 | function(date: moment) | 无 |
|
||||
|
||||
@@ -707,25 +707,27 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
tab1
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
tab2
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
/>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
tab1
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
tab2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -733,11 +735,11 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-content ant-tabs-content-animated"
|
||||
style="display:none"
|
||||
style="margin-left:0%"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-inactive"
|
||||
aria-hidden="false"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||
role="tabpanel"
|
||||
/>
|
||||
<div
|
||||
@@ -804,33 +806,35 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
article
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
app
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
project
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
/>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
article
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
app
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
project
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -65,6 +65,7 @@ class TabsCard extends React.Component {
|
||||
title="Card title"
|
||||
extra={<a href="#">More</a>}
|
||||
tabList={tabList}
|
||||
activeTabKey={this.state.key}
|
||||
onTabChange={(key) => { this.onTabChange(key, 'key'); }}
|
||||
>
|
||||
{contentList[this.state.key]}
|
||||
@@ -83,7 +84,5 @@ class TabsCard extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<TabsCard />,
|
||||
mountNode);
|
||||
ReactDOM.render(<TabsCard />, mountNode);
|
||||
````
|
||||
|
||||
@@ -23,6 +23,7 @@ A card can be used to display content related to a single subject. The content c
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| actions | The action list, shows at the bottom of the Card. | Array<ReactNode> | - |
|
||||
| activeTabKey | Current TabPane's key | string | - |
|
||||
| headStyle | Inline style to apply to the card head | object | - |
|
||||
| bodyStyle | Inline style to apply to the card content | object | - |
|
||||
| bordered | Toggles rendering of the border around the card | boolean | `true` |
|
||||
| cover | Card cover | ReactNode | - |
|
||||
|
||||
@@ -27,6 +27,7 @@ export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 't
|
||||
title?: React.ReactNode;
|
||||
extra?: React.ReactNode;
|
||||
bordered?: boolean;
|
||||
headStyle?: React.CSSProperties;
|
||||
bodyStyle?: React.CSSProperties;
|
||||
style?: React.CSSProperties;
|
||||
loading?: boolean;
|
||||
@@ -134,7 +135,7 @@ export default class Card extends React.Component<CardProps, CardState> {
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
prefixCls = 'ant-card', className, extra, bodyStyle = {}, noHovering, hoverable, title, loading,
|
||||
prefixCls = 'ant-card', className, extra, headStyle = {}, bodyStyle = {}, noHovering, hoverable, title, loading,
|
||||
bordered = true, type, cover, actions, tabList, children, activeTabKey, defaultActiveTabKey, ...others
|
||||
} = this.props;
|
||||
|
||||
@@ -231,7 +232,7 @@ export default class Card extends React.Component<CardProps, CardState> {
|
||||
) : null;
|
||||
if (title || extra || tabs) {
|
||||
head = (
|
||||
<div className={`${prefixCls}-head`}>
|
||||
<div className={`${prefixCls}-head`} style={headStyle}>
|
||||
<div className={`${prefixCls}-head-wrapper`}>
|
||||
{title && <div className={`${prefixCls}-head-title`}>{title}</div>}
|
||||
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
|
||||
|
||||
@@ -24,6 +24,7 @@ cols: 1
|
||||
| --- | --- | --- | --- |
|
||||
| actions | 卡片操作组,位置在卡片底部 | Array<ReactNode> | - |
|
||||
| activeTabKey | 当前激活页签的 key | string | - |
|
||||
| headStyle | 自定义标题区域样式 | object | - |
|
||||
| bodyStyle | 内容区域自定义样式 | object | - |
|
||||
| bordered | 是否有边框 | boolean | true |
|
||||
| cover | 卡片封面 | ReactNode | - |
|
||||
|
||||
@@ -143,7 +143,7 @@ exports[`renders ./components/cascader/demo/disabled-option.md correctly 1`] = `
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/fileds-name.md correctly 1`] = `
|
||||
exports[`renders ./components/cascader/demo/fields-name.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-cascader-picker"
|
||||
tabindex="0"
|
||||
|
||||
@@ -190,4 +190,40 @@ describe('Cascader', () => {
|
||||
wrapper.setProps({ options: [options[0]] });
|
||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1);
|
||||
});
|
||||
|
||||
it('can use fieldNames', () => {
|
||||
const customerOptions = [{
|
||||
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',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
const wrapper = mount(<Cascader
|
||||
options={customerOptions}
|
||||
fieldNames={{
|
||||
children: 'items',
|
||||
label: 'name',
|
||||
value: 'code',
|
||||
}}
|
||||
/>);
|
||||
wrapper.instance().handleChange(['zhejiang', 'hangzhou', 'xihu'], customerOptions);
|
||||
expect(wrapper.find('.ant-cascader-picker-label').text().split('/').length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
order: 10
|
||||
title:
|
||||
zh-CN: 自定义字段名
|
||||
en-US: Custom Filed Names
|
||||
en-US: Custom Field Names
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
@@ -11,7 +11,7 @@ title:
|
||||
|
||||
## en-US
|
||||
|
||||
Custom filed names.
|
||||
Custom field names.
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
@@ -28,7 +28,7 @@ Cascade selection box.
|
||||
| disabled | whether disabled select | boolean | false |
|
||||
| displayRender | render function of displaying selected options | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
|
||||
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' |
|
||||
| fieldNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
| fieldNames | custom field name for label and value and children (before 3.7.0 it calls `filedNames` which is typo)) | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative.[example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body |
|
||||
| loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - |
|
||||
| notFoundContent | Specify content to show when no result matches. | string | 'Not Found' |
|
||||
|
||||
@@ -253,6 +253,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta
|
||||
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
||||
const selectedOptions: CascaderOptionType[] = arrayTreeFilter(options,
|
||||
(o: CascaderOptionType, level: number) => o[names.value] === unwrappedValue[level],
|
||||
{ childrenKeyName: names.children },
|
||||
);
|
||||
const label = selectedOptions.map(o => o[names.label]);
|
||||
return displayRender(label, selectedOptions);
|
||||
|
||||
@@ -29,7 +29,7 @@ subtitle: 级联选择
|
||||
| disabled | 禁用 | boolean | false |
|
||||
| displayRender | 选择后展示的渲染函数 | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
|
||||
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' |
|
||||
| fieldNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
| fieldNames | 自定义 options 中 label name children 的字段(注意,3.7.0 之前的版本为 `filedNames`) | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body |
|
||||
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - |
|
||||
| notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import RcCheckbox from 'rc-checkbox';
|
||||
import shallowEqual from 'shallowequal';
|
||||
@@ -35,7 +35,7 @@ export interface CheckboxChangeEvent {
|
||||
target: CheckboxChangeEventTarget;
|
||||
stopPropagation: () => void;
|
||||
preventDefault: () => void;
|
||||
nativeEvent: Event;
|
||||
nativeEvent: MouseEvent;
|
||||
}
|
||||
|
||||
export default class Checkbox extends React.Component<CheckboxProps, {}> {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import classNames from 'classnames';
|
||||
import shallowEqual from 'shallowequal';
|
||||
import Checkbox from './Checkbox';
|
||||
@@ -38,7 +39,7 @@ export interface CheckboxGroupContext {
|
||||
};
|
||||
}
|
||||
|
||||
export default class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupState> {
|
||||
class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupState> {
|
||||
static defaultProps = {
|
||||
options: [],
|
||||
prefixCls: 'ant-checkbox',
|
||||
@@ -55,6 +56,15 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
|
||||
checkboxGroup: PropTypes.any,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: CheckboxGroupProps) {
|
||||
if ('value' in nextProps) {
|
||||
return {
|
||||
value: nextProps.value || [],
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
constructor(props: CheckboxGroupProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -72,13 +82,6 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: CheckboxGroupProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({
|
||||
value: nextProps.value || [],
|
||||
});
|
||||
}
|
||||
}
|
||||
shouldComponentUpdate(nextProps: CheckboxGroupProps, nextState: CheckboxGroupState) {
|
||||
return !shallowEqual(this.props, nextProps) ||
|
||||
!shallowEqual(this.state, nextState);
|
||||
@@ -141,3 +144,7 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
polyfill(CheckboxGroup);
|
||||
|
||||
export default CheckboxGroup;
|
||||
|
||||
@@ -64,4 +64,19 @@ describe('CheckboxGroup', () => {
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should be controlled by value', () => {
|
||||
const options = [
|
||||
{ label: 'Apple', value: 'Apple' },
|
||||
{ label: 'Orange', value: 'Orange' },
|
||||
];
|
||||
|
||||
const wrapper = mount(
|
||||
<Checkbox.Group options={options} />
|
||||
);
|
||||
|
||||
expect(wrapper.instance().state.value).toEqual([]);
|
||||
wrapper.setProps({ value: ['Apple'] });
|
||||
expect(wrapper.instance().state.value).toEqual(['Apple']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
content: ' ';
|
||||
transition: all .1s @ease-in-back;
|
||||
transition: all .1s @ease-in-back, opacity .1s;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,15 +86,17 @@
|
||||
|
||||
// 半选状态
|
||||
.@{checkbox-prefix-cls}-indeterminate .@{checkbox-inner-prefix-cls}:after {
|
||||
@indeterminate-width: (@checkbox-size / 14) * 8px;
|
||||
@indeterminate-height: (@checkbox-size / 14) * 1px;
|
||||
@indeterminate-width: @checkbox-size - 7px;
|
||||
@indeterminate-height: @checkbox-size - 7px;
|
||||
content: ' ';
|
||||
transform: scale(1);
|
||||
position: absolute;
|
||||
left: (@checkbox-size - 2 - @indeterminate-width) / 2;
|
||||
top: (@checkbox-size - 3 - @indeterminate-height) / 2;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
border: 0;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: @indeterminate-width;
|
||||
height: @indeterminate-height;
|
||||
background-color: @checkbox-color;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.@{checkbox-prefix-cls}-indeterminate.@{checkbox-prefix-cls}-disabled .@{checkbox-inner-prefix-cls}:after {
|
||||
@@ -110,10 +113,10 @@
|
||||
border-left: 0;
|
||||
content: ' ';
|
||||
transition: all .2s @ease-out-back .1s;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.@{checkbox-prefix-cls}-checked,
|
||||
.@{checkbox-prefix-cls}-indeterminate {
|
||||
.@{checkbox-prefix-cls}-checked {
|
||||
.@{checkbox-inner-prefix-cls} {
|
||||
background-color: @checkbox-color;
|
||||
border-color: @checkbox-color;
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface CollapseProps {
|
||||
defaultActiveKey?: Array<string>;
|
||||
/** 手风琴效果 */
|
||||
accordion?: boolean;
|
||||
destroyInactivePanel?: boolean;
|
||||
onChange?: (key: string | string[]) => void;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
|
||||
@@ -68,6 +68,7 @@ function fixLocale(value: RangePickerValue | undefined, localeCode: string) {
|
||||
class RangePicker extends React.Component<any, RangePickerState> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-calendar',
|
||||
tagPrefixCls: 'ant-tag',
|
||||
allowClear: true,
|
||||
showToday: false,
|
||||
};
|
||||
@@ -209,7 +210,7 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
}
|
||||
|
||||
renderFooter = (...args: any[]) => {
|
||||
const { prefixCls, ranges, renderExtraFooter } = this.props;
|
||||
const { prefixCls, ranges, renderExtraFooter, tagPrefixCls } = this.props;
|
||||
if (!ranges && !renderExtraFooter) {
|
||||
return null;
|
||||
}
|
||||
@@ -223,6 +224,7 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
return (
|
||||
<Tag
|
||||
key={range}
|
||||
prefixCls={tagPrefixCls}
|
||||
color="blue"
|
||||
onClick={() => this.handleRangeClick(value)}
|
||||
onMouseEnter={() => this.setState({ hoverValue: value })}
|
||||
@@ -358,6 +360,8 @@ class RangePicker extends React.Component<any, RangePickerState> {
|
||||
tabIndex={props.disabled ? -1 : 0}
|
||||
onFocus={props.onFocus}
|
||||
onBlur={props.onBlur}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
>
|
||||
<RcDatePicker
|
||||
{...props}
|
||||
|
||||
@@ -189,6 +189,8 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
|
||||
style={props.style}
|
||||
onFocus={props.onFocus}
|
||||
onBlur={props.onBlur}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
>
|
||||
<RcDatePicker
|
||||
{...props}
|
||||
|
||||
@@ -7,7 +7,7 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
RangePicker 可以设置常用的 预设范围 提高用户体验。
|
||||
可以预设常用的日期范围以提高用户体验。
|
||||
|
||||
## en-US
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ title:
|
||||
|
||||
The input box comes in three sizes. `default` will be used if `size` is omitted.
|
||||
|
||||
|
||||
````jsx
|
||||
import { DatePicker, Radio } from 'antd';
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/th_TH';
|
||||
import TimePickerLocale from '../../time-picker/locale/th_TH';
|
||||
import assign from 'object-assign';
|
||||
|
||||
// Merge into a locale object
|
||||
const locale = {
|
||||
lang: assign({
|
||||
lang: {
|
||||
placeholder: 'เลือกวันที่',
|
||||
rangePlaceholder: ['วันเริ่มต้น', 'วันสิ้นสุด'],
|
||||
}, CalendarLocale),
|
||||
timePickerLocale: assign({}, TimePickerLocale),
|
||||
...CalendarLocale,
|
||||
},
|
||||
timePickerLocale: {
|
||||
...TimePickerLocale,
|
||||
},
|
||||
};
|
||||
|
||||
// All settings at:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
.@{calendar-prefix-cls}-picker-container {
|
||||
.reset-component;
|
||||
font-family: @font-family;
|
||||
position: absolute;
|
||||
z-index: @zindex-picker;
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
}
|
||||
|
||||
li {
|
||||
text-align: center;
|
||||
padding-left: 32px;
|
||||
list-style: none;
|
||||
box-sizing: content-box;
|
||||
margin: 0;
|
||||
|
||||
@@ -67,6 +67,20 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseEnter = (e: React.MouseEventHandler<HTMLInputElement>) => {
|
||||
const { onMouseEnter } = this.props;
|
||||
if (onMouseEnter) {
|
||||
onMouseEnter(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseLeave = (e: React.MouseEventHandler<HTMLInputElement>) => {
|
||||
const { onMouseLeave } = this.props;
|
||||
if (onMouseLeave) {
|
||||
onMouseLeave(e);
|
||||
}
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.picker.focus();
|
||||
}
|
||||
@@ -134,6 +148,8 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
|
||||
onOpenChange={this.handleOpenChange}
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleBlur}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import classNames from 'classnames';
|
||||
export interface DividerProps {
|
||||
prefixCls?: string;
|
||||
type?: 'horizontal' | 'vertical';
|
||||
orientation?: 'left' | 'right';
|
||||
orientation?: 'left' | 'right' | '';
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
dashed?: boolean;
|
||||
|
||||
@@ -55,12 +55,12 @@ describe('Drawer', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('wrapClassName is test_drawer', () => {
|
||||
it('className is test_drawer', () => {
|
||||
const wrapper = render(
|
||||
<Drawer
|
||||
destroyOnClose
|
||||
visible={false}
|
||||
wrapClassName="test_drawer"
|
||||
className="test_drawer"
|
||||
getContainer={false}
|
||||
>
|
||||
Here is content of Drawer
|
||||
|
||||
@@ -40,7 +40,7 @@ class MultiDrawer extends React.Component {
|
||||
</Button>
|
||||
<Drawer
|
||||
title="Multi-level drawer"
|
||||
wrapClassName="test_drawer"
|
||||
className="test_drawer"
|
||||
width={520}
|
||||
closable={false}
|
||||
onClose={this.onClose}
|
||||
|
||||
@@ -1,5 +1,46 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Drawer className is test_drawer 1`] = `
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-drawer ant-drawer-right test_drawer"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%;opacity:0;transition:opacity .3s"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-drawer-close"
|
||||
>
|
||||
<span
|
||||
class="ant-drawer-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-drawer-body"
|
||||
>
|
||||
Here is content of Drawer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Drawer closable is false 1`] = `
|
||||
<div
|
||||
class=""
|
||||
@@ -12,7 +53,7 @@ exports[`Drawer closable is false 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);width:256px"
|
||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
@@ -45,7 +86,7 @@ exports[`Drawer destroyOnClose is true 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);width:256px"
|
||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
@@ -86,7 +127,7 @@ exports[`Drawer have a title 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);width:256px"
|
||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:256px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
@@ -136,7 +177,7 @@ exports[`Drawer render correctly 1`] = `
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);width:400px"
|
||||
style="transform:translateX(100%);-ms-transform:translateX(100%);width:400px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
@@ -164,44 +205,3 @@ exports[`Drawer render correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Drawer wrapClassName is test_drawer 1`] = `
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-drawer ant-drawer-right test_drawer"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-mask"
|
||||
/>
|
||||
<div
|
||||
class="ant-drawer-content-wrapper"
|
||||
style="transform:translateX(100%);width:256px"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-content"
|
||||
>
|
||||
<div
|
||||
class="ant-drawer-wrapper-body"
|
||||
style="overflow:auto;height:100%;opacity:0;transition:opacity .3s"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-drawer-close"
|
||||
>
|
||||
<span
|
||||
class="ant-drawer-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-drawer-body"
|
||||
>
|
||||
Here is content of Drawer
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`Drawer render correctly 1`] = `
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn ant-btn-clicked"
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
|
||||
@@ -55,9 +55,3 @@ class App extends React.Component {
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container{
|
||||
display:none
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -55,10 +55,3 @@ class App extends React.Component {
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
||||
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container{
|
||||
display:none
|
||||
}
|
||||
</style>
|
||||
@@ -28,11 +28,9 @@ class DrawerForm extends React.Component {
|
||||
};
|
||||
|
||||
onClose = () => {
|
||||
this.setState(
|
||||
{
|
||||
visible: false,
|
||||
}
|
||||
);
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
@@ -174,13 +172,8 @@ class DrawerForm extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const App = Form.create()(DrawerForm);
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container{
|
||||
display:none
|
||||
}
|
||||
</style>
|
||||
@@ -52,13 +52,12 @@ class App extends React.Component {
|
||||
<Drawer
|
||||
title="Multi-level drawer"
|
||||
width={520}
|
||||
wrapClassName="test_drawer"
|
||||
closable={false}
|
||||
onClose={this.onClose}
|
||||
visible={this.state.visible}
|
||||
>
|
||||
<Button type="primary" onClick={this.showChildrenDrawer}>
|
||||
Two-level drawer
|
||||
Two-level drawer
|
||||
</Button>
|
||||
<Drawer
|
||||
title="Two-level Drawer"
|
||||
@@ -102,9 +101,3 @@ class App extends React.Component {
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container{
|
||||
display:none
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -24,29 +24,27 @@ const pStyle = {
|
||||
marginBottom: 16,
|
||||
};
|
||||
|
||||
const DescriptionItem = ({ title, content }) => {
|
||||
return (
|
||||
<div
|
||||
const DescriptionItem = ({ title, content }) => (
|
||||
<div
|
||||
style={{
|
||||
fontSize: 14,
|
||||
lineHeight: '22px',
|
||||
marginBottom: 7,
|
||||
color: 'rgba(0,0,0,0.65)',
|
||||
}}
|
||||
>
|
||||
<p
|
||||
style={{
|
||||
fontSize: 14,
|
||||
lineHeight: '22px',
|
||||
marginBottom: 7,
|
||||
color: 'rgba(0,0,0,0.65)',
|
||||
marginRight: 8,
|
||||
display: 'inline-block',
|
||||
color: 'rgba(0,0,0,0.85)',
|
||||
}}
|
||||
>
|
||||
<p
|
||||
style={{
|
||||
marginRight: 8,
|
||||
display: 'inline-block',
|
||||
color: 'rgba(0,0,0,0.85)',
|
||||
}}
|
||||
>
|
||||
{title}:
|
||||
</p>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
{title}:
|
||||
</p>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
|
||||
class App extends React.Component {
|
||||
state = { visible: false };
|
||||
@@ -185,9 +183,3 @@ class App extends React.Component {
|
||||
|
||||
ReactDOM.render(<App />, mountNode);
|
||||
```
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container{
|
||||
display:none
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
type: Feedback
|
||||
category: Components
|
||||
subtitle:
|
||||
subtitle:
|
||||
title: Drawer
|
||||
---
|
||||
|
||||
@@ -27,7 +27,13 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
|
||||
| title | The title for Drawer. | string\|ReactNode | - |
|
||||
| visible | Whether the Drawer dialog is visible or not. | boolean | false |
|
||||
| width | Width of the Drawer dialog. | string\|number | 256 |
|
||||
| wrapClassName | The class name of the container of the Drawer dialog. | string | - |
|
||||
| className | The class name of the container of the Drawer dialog. | string | - |
|
||||
| zIndex | The `z-index` of the Drawer. | Number | 1000 |
|
||||
| placement | The placement of the Drawer. | 'left' \| 'right' | 'right'
|
||||
| onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button. | function(e) | - |
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import RcDrawer from 'rc-drawer';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import createReactContext, { Context } from 'create-react-context';
|
||||
import warning from 'warning';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const DrawerContext: Context<Drawer | null> = createReactContext(null);
|
||||
|
||||
@@ -22,12 +24,14 @@ export interface DrawerProps {
|
||||
title?: React.ReactNode;
|
||||
visible?: boolean;
|
||||
width?: number | string;
|
||||
/* deprecated, use className instead */
|
||||
wrapClassName?: string;
|
||||
zIndex?: number;
|
||||
prefixCls?: string;
|
||||
push?: boolean;
|
||||
placement?: 'left' | 'right';
|
||||
onClose?: (e: EventType) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface IDrawerState {
|
||||
@@ -51,11 +55,11 @@ export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
|
||||
title: PropTypes.node,
|
||||
visible: PropTypes.bool,
|
||||
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
wrapClassName: PropTypes.string,
|
||||
zIndex: PropTypes.number,
|
||||
prefixCls: PropTypes.string,
|
||||
placement: PropTypes.string,
|
||||
onClose: PropTypes.func,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -175,7 +179,8 @@ export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
|
||||
);
|
||||
}
|
||||
renderProvider = (value: Drawer) => {
|
||||
let { zIndex, style, placement, ...rest } = this.props;
|
||||
let { zIndex, style, placement, className, wrapClassName, ...rest } = this.props;
|
||||
warning(wrapClassName === undefined, 'wrapClassName is deprecated, please use className instead.');
|
||||
const RcDrawerStyle = this.state.push
|
||||
? {
|
||||
zIndex,
|
||||
@@ -193,7 +198,7 @@ export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
|
||||
showMask={this.props.mask}
|
||||
placement={placement}
|
||||
style={RcDrawerStyle}
|
||||
className={this.props.wrapClassName}
|
||||
className={classNames(wrapClassName, className)}
|
||||
>
|
||||
{this.renderBody()}
|
||||
</RcDrawer>
|
||||
|
||||
@@ -28,7 +28,13 @@ title: Drawer
|
||||
| title | 标题 | string \| ReactNode | - |
|
||||
| visible | Drawer 是否可见 | boolean | - |
|
||||
| width | 宽度 | string \| number | 256 |
|
||||
| wrapClassName | 对话框外层容器的类名 | string | - |
|
||||
| className | 对话框外层容器的类名 | string | - |
|
||||
| zIndex | 设置 Drawer 的 `z-index` | Number | 1000 |
|
||||
| placement | 抽屉的方向 | 'left' \| 'right' | 'right'
|
||||
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 |
|
||||
|
||||
<style>
|
||||
#_hj_feedback_container {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,25 +5,32 @@
|
||||
.@{dawer-prefix-cls} {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
width: 0%;
|
||||
z-index: @zindex-modal;
|
||||
transition: transform 0.3s @ease-in-out-circ;
|
||||
transition: transform @animation-duration-slow @ease-base-in;
|
||||
> * {
|
||||
transition: transform 0.3s @ease-in-out-circ;
|
||||
transition: transform @animation-duration-slow @ease-base-in;
|
||||
}
|
||||
|
||||
&-content-wrapper {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
}
|
||||
.@{dawer-prefix-cls}-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity @animation-duration-slow linear;
|
||||
}
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
.@{dawer-prefix-cls}-content-wrapper,
|
||||
.@{dawer-prefix-cls}-content {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
.@{dawer-prefix-cls}-content-wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
&.@{dawer-prefix-cls}-open {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-left {
|
||||
&.@{dawer-prefix-cls}-open {
|
||||
@@ -44,13 +51,44 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
&.@{dawer-prefix-cls}-open {
|
||||
> * {
|
||||
pointer-events: auto;
|
||||
|
||||
&-top,
|
||||
&-bottom {
|
||||
.@{dawer-prefix-cls}-content-wrapper,
|
||||
.@{dawer-prefix-cls}-content {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-top {
|
||||
&.@{dawer-prefix-cls}-open {
|
||||
.@{dawer-prefix-cls}-content-wrapper {
|
||||
box-shadow: @shadow-1-down;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-bottom {
|
||||
.@{dawer-prefix-cls} {
|
||||
&-content-wrapper {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
&.@{dawer-prefix-cls}-open {
|
||||
.@{dawer-prefix-cls}-content-wrapper {
|
||||
box-shadow: @shadow-1-up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.@{dawer-prefix-cls}-open {
|
||||
.@{dawer-prefix-cls} {
|
||||
&-content {
|
||||
opacity: 1;
|
||||
}
|
||||
&-mask {
|
||||
opacity: 0.3;
|
||||
height: 100%;
|
||||
animation: antdDrawerFadeIn @animation-duration-slow @ease-base-out;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +120,7 @@
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s;
|
||||
transition: color @animation-duration-slow;
|
||||
color: @text-color-secondary;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
@@ -129,21 +167,29 @@
|
||||
|
||||
&-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
background-color: @modal-mask-bg;
|
||||
height: 100%;
|
||||
transition: opacity 0.3s @ease-in-out-circ;
|
||||
filter: ~"alpha(opacity=50)";
|
||||
transition: opacity @animation-duration-slow linear, height 0s ease @animation-duration-slow;
|
||||
}
|
||||
|
||||
&-open {
|
||||
overflow: hidden;
|
||||
transition: transform @animation-duration-slow @ease-base-out;
|
||||
> * {
|
||||
transition: transform @animation-duration-slow @ease-base-out;
|
||||
}
|
||||
&-content {
|
||||
box-shadow: @shadow-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antdDrawerFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import createDOMForm from 'rc-form/lib/createDOMForm';
|
||||
import createFormField from 'rc-form/lib/createFormField';
|
||||
@@ -40,7 +40,7 @@ export interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
|
||||
|
||||
export type ValidationRule = {
|
||||
/** validation error message */
|
||||
message?: string;
|
||||
message?: React.ReactNode;
|
||||
/** built-in validation type, available options: https://github.com/yiminghe/async-validator#type */
|
||||
type?: string;
|
||||
/** indicates whether field is required */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import intersperse from 'intersperse';
|
||||
import Animate from 'rc-animate';
|
||||
@@ -98,7 +98,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
if (!child.props) {
|
||||
continue;
|
||||
}
|
||||
if (FIELD_META_PROP in child.props) { // And means FIELD_DATA_PROP in chidl.props, too.
|
||||
if (FIELD_META_PROP in child.props) { // And means FIELD_DATA_PROP in child.props, too.
|
||||
controls.push(child);
|
||||
} else if (child.props.children) {
|
||||
controls = controls.concat(this.getControls(child.props.children, recursively));
|
||||
|
||||
@@ -527,6 +527,7 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-enabled"
|
||||
id="gender"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -534,6 +535,8 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
data-__field="[object Object]"
|
||||
data-__meta="[object Object]"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
>
|
||||
@@ -1612,6 +1615,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-enabled"
|
||||
id="prefix"
|
||||
style="width:70px"
|
||||
>
|
||||
<div
|
||||
@@ -1620,6 +1624,8 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
data-__field="[object Object]"
|
||||
data-__meta="[object Object]"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
>
|
||||
@@ -1683,6 +1689,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
id="website"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -1690,6 +1697,8 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
data-__field="[object Object]"
|
||||
data-__meta="[object Object]"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
@@ -2247,6 +2256,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-enabled"
|
||||
id="select"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -2254,6 +2264,8 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
data-__field="[object Object]"
|
||||
data-__meta="[object Object]"
|
||||
role="combobox"
|
||||
tabindex="0"
|
||||
>
|
||||
@@ -2306,6 +2318,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select ant-select-enabled"
|
||||
id="select-multiple"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
@@ -2313,6 +2326,8 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--multiple"
|
||||
data-__field="[object Object]"
|
||||
data-__meta="[object Object]"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
@@ -2793,10 +2808,16 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
>
|
||||
<ul
|
||||
class="ant-rate"
|
||||
role="radiogroup"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-checked="true"
|
||||
aria-posinset="1"
|
||||
aria-setsize="5"
|
||||
class="ant-rate-star ant-rate-star-full"
|
||||
role="radio"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-rate-star-first"
|
||||
@@ -2814,7 +2835,12 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-checked="true"
|
||||
aria-posinset="2"
|
||||
aria-setsize="5"
|
||||
class="ant-rate-star ant-rate-star-full"
|
||||
role="radio"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-rate-star-first"
|
||||
@@ -2832,7 +2858,12 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-checked="true"
|
||||
aria-posinset="3"
|
||||
aria-setsize="5"
|
||||
class="ant-rate-star ant-rate-star-full"
|
||||
role="radio"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-rate-star-first"
|
||||
@@ -2850,7 +2881,12 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-checked="true"
|
||||
aria-posinset="4"
|
||||
aria-setsize="5"
|
||||
class="ant-rate-star ant-rate-star-zero"
|
||||
role="radio"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-rate-star-first"
|
||||
@@ -2868,7 +2904,12 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-checked="false"
|
||||
aria-posinset="5"
|
||||
aria-setsize="5"
|
||||
class="ant-rate-star ant-rate-star-zero"
|
||||
role="radio"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-rate-star-first"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
||||
|
||||
@@ -19,7 +19,7 @@ if (typeof window !== 'undefined') {
|
||||
import * as React from 'react';
|
||||
import { Children, cloneElement } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
|
||||
export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
||||
export type BreakpointMap = Partial<Record<Breakpoint, string>>;
|
||||
|
||||
@@ -18,7 +18,7 @@ When a numeric value needs to be provided.
|
||||
| defaultValue | initial value | number | |
|
||||
| disabled | disable the input | boolean | false |
|
||||
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - |
|
||||
| max | max vale | number | Infinity |
|
||||
| max | max value | number | Infinity |
|
||||
| min | min value | number | -Infinity |
|
||||
| parser | Specifies the value extracted from formatter | function( string): number | - |
|
||||
| precision | precision of input value | number | - |
|
||||
|
||||
@@ -6,6 +6,10 @@ export interface GroupProps {
|
||||
size?: 'large' | 'small' | 'default';
|
||||
children?: any;
|
||||
style?: React.CSSProperties;
|
||||
onMouseEnter?: React.MouseEventHandler<HTMLSpanElement>;
|
||||
onMouseLeave?: React.MouseEventHandler<HTMLSpanElement>;
|
||||
onFocus?: React.FocusEventHandler<HTMLSpanElement>;
|
||||
onBlur?: React.FocusEventHandler<HTMLSpanElement>;
|
||||
prefixCls?: string;
|
||||
compact?: boolean;
|
||||
}
|
||||
@@ -18,7 +22,14 @@ const Group: React.StatelessComponent<GroupProps> = (props) => {
|
||||
[`${prefixCls}-compact`]: props.compact,
|
||||
}, className);
|
||||
return (
|
||||
<span className={cls} style={props.style}>
|
||||
<span
|
||||
className={cls}
|
||||
style={props.style}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
onFocus={props.onFocus}
|
||||
onBlur={props.onBlur}
|
||||
>
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import Group from './Group';
|
||||
@@ -53,7 +53,6 @@ export default class Input extends React.Component<InputProps, any> {
|
||||
addonBefore: PropTypes.node,
|
||||
addonAfter: PropTypes.node,
|
||||
prefixCls: PropTypes.string,
|
||||
autosize: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
|
||||
onPressEnter: PropTypes.func,
|
||||
onKeyDown: PropTypes.func,
|
||||
onKeyUp: PropTypes.func,
|
||||
@@ -128,25 +127,16 @@ export default class Input extends React.Component<InputProps, any> {
|
||||
|
||||
// Need another wrapper for changing display:table to display:inline-block
|
||||
// and put style prop in wrapper
|
||||
if (addonBefore || addonAfter) {
|
||||
return (
|
||||
<span
|
||||
className={groupClassName}
|
||||
style={props.style}
|
||||
>
|
||||
<span className={className}>
|
||||
{addonBefore}
|
||||
{React.cloneElement(children, { style: null })}
|
||||
{addonAfter}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<span className={className}>
|
||||
{addonBefore}
|
||||
{children}
|
||||
{addonAfter}
|
||||
<span
|
||||
className={groupClassName}
|
||||
style={props.style}
|
||||
>
|
||||
<span className={className}>
|
||||
{addonBefore}
|
||||
{React.cloneElement(children, { style: null })}
|
||||
{addonAfter}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ export interface AutoSizeType {
|
||||
maxRows?: number;
|
||||
}
|
||||
|
||||
export interface TextAreaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
export type HTMLTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
||||
|
||||
export interface TextAreaProps extends HTMLTextareaProps {
|
||||
prefixCls?: string;
|
||||
autosize?: boolean | AutoSizeType;
|
||||
onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
||||
@@ -33,9 +35,7 @@ export interface TextAreaState {
|
||||
textareaStyles?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export type HTMLTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
||||
|
||||
export default class TextArea extends React.Component<TextAreaProps & HTMLTextareaProps, TextAreaState> {
|
||||
export default class TextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-input',
|
||||
};
|
||||
|
||||
@@ -14,7 +14,6 @@ title:
|
||||
`autosize` prop for a `textarea` type of `Input` makes the height to automatically adjust based on the content.
|
||||
An options object can be provided to `autosize` to specify the minimum and maximum number of lines the textarea will automatically adjust.
|
||||
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
|
||||
@@ -9,12 +9,10 @@ title:
|
||||
|
||||
我们为 `<Input />` 输入框定义了三种尺寸(大、默认、小),高度分别为 `40px`、`32px` 和 `24px`。
|
||||
|
||||
|
||||
## en-US
|
||||
|
||||
There are three sizes of an Input box: `large` (40px)、`default` (32px) and `small` (24px).
|
||||
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ The rest of the props of `Input.TextArea` are the same as the original [textarea
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| enterButton | to show a enter button after input | boolean\|ReactNode | false |
|
||||
| enterButton | to show an enter button after input | boolean\|ReactNode | false |
|
||||
| onSearch | The callback function that is triggered when you click on the search-icon or press Enter key. | function(value, event) | |
|
||||
|
||||
Supports all props of `Input`.
|
||||
|
||||
@@ -15,9 +15,10 @@ if (typeof window !== 'undefined') {
|
||||
}
|
||||
|
||||
import * as React from 'react';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import Icon from '../icon';
|
||||
import isNumeric from '../_util/isNumeric';
|
||||
|
||||
@@ -67,7 +68,7 @@ const generateId = (() => {
|
||||
};
|
||||
})();
|
||||
|
||||
export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
class Sider extends React.Component<SiderProps, SiderState> {
|
||||
static __ANT_LAYOUT_SIDER: any = true;
|
||||
|
||||
static defaultProps = {
|
||||
@@ -90,6 +91,15 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
siderHook: PropTypes.object,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: SiderProps) {
|
||||
if ('collapsed' in nextProps) {
|
||||
return {
|
||||
collapsed: nextProps.collapsed,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private mql: MediaQueryList;
|
||||
private uniqueId: string;
|
||||
|
||||
@@ -122,14 +132,6 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: SiderProps) {
|
||||
if ('collapsed' in nextProps) {
|
||||
this.setState({
|
||||
collapsed: nextProps.collapsed,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.mql) {
|
||||
this.mql.addListener(this.responsiveHandler);
|
||||
@@ -234,3 +236,7 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
polyfill(Sider);
|
||||
|
||||
export default Sider;
|
||||
|
||||
@@ -292,7 +292,7 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
|
||||
class="ant-layout-footer"
|
||||
style="text-align:center"
|
||||
>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -546,7 +546,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
class="ant-layout-footer"
|
||||
style="text-align:center"
|
||||
>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -650,7 +650,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
class="ant-layout-footer"
|
||||
style="text-align:center"
|
||||
>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -820,7 +820,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
class="ant-layout-footer"
|
||||
style="text-align:center"
|
||||
>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -916,7 +916,7 @@ exports[`renders ./components/layout/demo/top.md correctly 1`] = `
|
||||
class="ant-layout-footer"
|
||||
style="text-align:center"
|
||||
>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1132,7 +1132,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
class="ant-layout-footer"
|
||||
style="text-align:center"
|
||||
>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -76,6 +76,15 @@ describe('Layout', () => {
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should be controlled by collapsed', () => {
|
||||
const wrapper = mount(
|
||||
<Sider>Sider</Sider>
|
||||
);
|
||||
expect(wrapper.instance().state.collapsed).toBe(false);
|
||||
wrapper.setProps({ collapsed: true });
|
||||
expect(wrapper.instance().state.collapsed).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sider onBreakpoint', () => {
|
||||
|
||||
@@ -78,7 +78,7 @@ ReactDOM.render(
|
||||
</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>,
|
||||
|
||||
@@ -43,7 +43,7 @@ ReactDOM.render(
|
||||
<div style={{ background: '#fff', padding: 24, minHeight: 380 }}>Content</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</Footer>
|
||||
</Layout>,
|
||||
mountNode);
|
||||
@@ -53,7 +53,7 @@ ReactDOM.render(
|
||||
#components-layout-demo-fixed .logo {
|
||||
width: 120px;
|
||||
height: 31px;
|
||||
background: rgba(255,255,255,.2);
|
||||
background: rgba(255,255,255,.2);
|
||||
margin: 16px 24px 16px 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ ReactDOM.render(
|
||||
</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>,
|
||||
|
||||
@@ -18,7 +18,7 @@ Two-columns layout. The sider menu can be collapsed when horizontal space is lim
|
||||
|
||||
Generally, the mainnav is placed on the left side of the page, and the secondary menu is placed on the top of the working area. Contents will adapt the layout to the viewing area to improve the horizontal space usage, while the layout of the whole page is not stable.
|
||||
|
||||
The level of the aisde navigation is scalable. The first, second, and third level navigations could be present more fluently and relevantly, and aside navigation can be fixed, allowing the user to quickly switch and spot the current position, improving the user experience. However, this navigation occupies some horizontal space of the contents
|
||||
The level of the aside navigation is scalable. The first, second, and third level navigations could be present more fluently and relevantly, and aside navigation can be fixed, allowing the user to quickly switch and spot the current position, improving the user experience. However, this navigation occupies some horizontal space of the contents
|
||||
|
||||
````jsx
|
||||
import { Layout, Menu, Breadcrumb, Icon } from 'antd';
|
||||
@@ -87,7 +87,7 @@ class SiderDemo extends React.Component {
|
||||
</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>
|
||||
|
||||
@@ -74,7 +74,7 @@ ReactDOM.render(
|
||||
</Layout>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</Footer>
|
||||
</Layout>,
|
||||
mountNode);
|
||||
@@ -84,7 +84,7 @@ ReactDOM.render(
|
||||
#components-layout-demo-top-side .logo {
|
||||
width: 120px;
|
||||
height: 31px;
|
||||
background: rgba(255,255,255,.2);
|
||||
background: rgba(255,255,255,.2);
|
||||
margin: 16px 28px 16px 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ ReactDOM.render(
|
||||
<div style={{ background: '#fff', padding: 24, minHeight: 280 }}>Content</div>
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Ant Design ©2016 Created by Ant UED
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</Footer>
|
||||
</Layout>,
|
||||
mountNode);
|
||||
@@ -59,7 +59,7 @@ ReactDOM.render(
|
||||
#components-layout-demo-top .logo {
|
||||
width: 120px;
|
||||
height: 31px;
|
||||
background: rgba(255,255,255,.2);
|
||||
background: rgba(255,255,255,.2);
|
||||
margin: 16px 24px 16px 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { SiderProps } from './Sider';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { Col } from '../grid';
|
||||
import { ListGridType, ColumnType } from './index';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { SpinProps } from '../spin';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
margin-bottom: 16px;
|
||||
&-content {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as PropTypes from 'prop-types';
|
||||
|
||||
export interface LocaleReceiverProps {
|
||||
componentName: string;
|
||||
|
||||
@@ -386,7 +386,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-left"
|
||||
class="anticon anticon-right"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
@@ -395,7 +395,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-right"
|
||||
class="anticon anticon-left"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user