mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-15 13:59:19 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51b74b7daa | ||
|
|
635bc8cedc | ||
|
|
ff59663898 |
15
.eslintrc.js
15
.eslintrc.js
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const eslintrc = {
|
||||
extends: ['eslint-config-airbnb'],
|
||||
env: {
|
||||
@@ -22,24 +24,18 @@ const eslintrc = {
|
||||
],
|
||||
rules: {
|
||||
'func-names': 0,
|
||||
'prefer-const': 0,
|
||||
'arrow-body-style': 0,
|
||||
'react/sort-comp': 0,
|
||||
'react/prop-types': 0,
|
||||
'react/jsx-first-prop-new-line': 0,
|
||||
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.md'] }],
|
||||
'import/no-unresolved': 0,
|
||||
'import/no-extraneous-dependencies': 0,
|
||||
'no-param-reassign': 0,
|
||||
'no-return-assign': 0,
|
||||
'max-len': 0,
|
||||
'consistent-return': 0,
|
||||
'no-redeclare': 0,
|
||||
'react/require-extension': 0,
|
||||
'react/jsx-indent': 0,
|
||||
'jsx-a11y/no-static-element-interactions': 0,
|
||||
'jsx-a11y/anchor-has-content': 0,
|
||||
'react/no-danger': 0,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env.RUN_ENV === 'DEMO') {
|
||||
@@ -51,13 +47,10 @@ if (process.env.RUN_ENV === 'DEMO') {
|
||||
|
||||
Object.assign(eslintrc.rules, {
|
||||
'no-console': 0,
|
||||
'no-plusplus': 0,
|
||||
'eol-last': 0,
|
||||
'prefer-rest-params': 0,
|
||||
'react/no-multi-comp': 0,
|
||||
'react/prefer-es6-class': 0,
|
||||
'jsx-a11y/href-no-hash': 0,
|
||||
'import/newline-after-import': 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
28
.github/ISSUE_TEMPLATE.md
vendored
28
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,34 +1,26 @@
|
||||
<!-- Issue Template -->
|
||||
<!-- Issue Template For Chinese Users -->
|
||||
|
||||
<!--
|
||||
antd 的用法咨询,建议通过以下渠道,官方 issues 目前没有足够精力提供此类咨询服务:
|
||||
<!-- 请按照下列格式报告问题,务必提供复现步骤,否则恕难解决,感谢您的支持。-->
|
||||
|
||||
1. [Stack Overflow](http://stackoverflow.com/questions/tagged/antd)
|
||||
2. [Segment Fault](https://segmentfault.com/t/antd)(中文)
|
||||
3. [Gitter](https://gitter.im/ant-design/ant-design)
|
||||
|
||||
如果是报告 bug,请按照下列格式书写,并务必提供复现步骤,否则恕难解决,感谢您的支持。
|
||||
-->
|
||||
|
||||
#### 发生问题的环境是:
|
||||
#### 本地环境
|
||||
|
||||
<!-- 务必提供 -->
|
||||
|
||||
- antd 版本:
|
||||
- 操作系统及其版本:
|
||||
- 操作系统及其版本:
|
||||
- 浏览器及其版本:
|
||||
|
||||
#### 您做了什么?请提供尽可能详细的重现步骤。
|
||||
#### 你做了什么?
|
||||
|
||||
<!-- 如:引入 antd 了 Button -->
|
||||
<!-- 引入 antd 了 Button -->
|
||||
|
||||
#### 您期待的结果是:
|
||||
#### 你期待的结果是:
|
||||
|
||||
<!-- 如:像官网一样正常显示 -->
|
||||
<!-- 像官网一样正常显示 -->
|
||||
|
||||
#### 实际上的结果是:
|
||||
#### 实际上的结果:
|
||||
|
||||
<!-- 如:样式错位了,最好提供截图 -->
|
||||
<!-- 缺少样式 -->
|
||||
|
||||
#### 可重现的在线演示
|
||||
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -15,7 +15,6 @@ Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
*.log
|
||||
*.json.gzip
|
||||
node_modules/
|
||||
.buildpath
|
||||
.settings
|
||||
@@ -27,6 +26,4 @@ dist
|
||||
/lib
|
||||
elasticsearch-*
|
||||
config/base.yaml
|
||||
components/**/*.js
|
||||
components/**/*.jsx
|
||||
/.vscode/
|
||||
typings
|
||||
|
||||
@@ -3,4 +3,4 @@ sudo: false
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "6"
|
||||
- "5"
|
||||
|
||||
37
AUTHORS.txt
37
AUTHORS.txt
@@ -1,4 +1,3 @@
|
||||
Andrew Murray <radarhere@gmail.com>
|
||||
Benjy Cui <benjytrys@gmail.com>
|
||||
Bernie <bernie.wangbj@gmail.com>
|
||||
Bozhao <yubz86@gmail.com>
|
||||
@@ -7,40 +6,25 @@ Bruno Maia <bruno.mm.maia@gmail.com>
|
||||
Cam Song <neosoyn@gmail.com>
|
||||
Cee Cirno <i@cee.moe>
|
||||
Daqi Song <dqaria@gmail.com>
|
||||
DengYun <tdzl2003@gmail.com>
|
||||
Eddie Xie <oeddyo@gmail.com>
|
||||
Emma <sima.zhang1990@gmail.com>
|
||||
Eric <84263800@qq.com>
|
||||
Eward Song <eward.song@gmail.com>
|
||||
Gray Choi <gray.choi.1988@gmail.com>
|
||||
Guan Hao <raptium@gmail.com>
|
||||
Haibin Yu <haibin.yu@oceanwing.com>
|
||||
Hanai <ihanai1991@gmail.com>
|
||||
Infinity <305870677@qq.com>
|
||||
James <james@schoolshape.com>
|
||||
Jerry Bendy <jerry@icewingcc.com>
|
||||
KgTong <kgtong1992@gmail.com>
|
||||
Leon Shi <superRaytin@163.com>
|
||||
Leon Shi <superRaytin@gmail.com>
|
||||
Liu Yang <zation1@gmail.com>
|
||||
MG12 <wuzhao.mail@gmail.com>
|
||||
Ma Tianxiao <matx2215@outlook.com>
|
||||
Marius Ileana <visvadw@gmail.com>
|
||||
Marshall Chen <Juniors.fei@gmail.com>
|
||||
Mr.Tone <vector@malubei.com>
|
||||
Neverland <chenjiahan@buaa.edu.cn>
|
||||
Pyiner <lijiuyang1992@gmail.com>
|
||||
Qiaosen Huang <joesonw@gmail.com>
|
||||
RaoHai <surgesoft@gmail.com>
|
||||
Rrrandom <emanonhere@gmail.com>
|
||||
Sean Lin <sean@ejoy.com>
|
||||
Sebastian Blade <blade254353074@hotmail.com>
|
||||
Shawn Sit <xueqingxiao@gmail.com>
|
||||
ShiTengFei <shitengfei@goyoo.com>
|
||||
SimaQ <sima.zhang1990@gmail.com>
|
||||
The Rock <zhoguoxin@126.com>
|
||||
Vadim Macagon <vadim.macagon@gmail.com>
|
||||
Vincent Zhang <vxzhong@qq.com>
|
||||
Wei Zhu <yesmeck@gmail.com>
|
||||
Yuwei Ba <i@xiaoba.me>
|
||||
Zap <a124116186@qq.com>
|
||||
@@ -49,59 +33,44 @@ bang <sqibang@gmail.com>
|
||||
bang88 <sqibang@gmail.com>
|
||||
chencheng (云谦) <sorrycc@gmail.com>
|
||||
ddcat1115 <ddcat1115@gmail.com>
|
||||
detailyang <detailyang@gmail.com>
|
||||
devqin <devqin@gmail.com>
|
||||
djorkaeff <djorkae55@gmail.com>
|
||||
ecofe <150641329@qq.com>
|
||||
elrrrrrrr <elrrrrrrr@gmail.com>
|
||||
ezpub <ez.foro@gmail.com>
|
||||
feng zhi hao <fzhihao@outlook.com>
|
||||
fengmk2 <m@fengmk2.com>
|
||||
genie <genie88@163.com>
|
||||
haoxin <coderhaoxin@outlook.com>
|
||||
hi-caicai <hi@cai-cai.me>
|
||||
ioldfish <fish.wangl@gmail.com>
|
||||
jasonslyvia <jasonslyvia@gmail.com>
|
||||
jiang <155259966@qq.com>
|
||||
kagawagao <kingsongao1221@gmail.com>
|
||||
kaifei <150641329@qq.com>
|
||||
kasinooya <kasinooya@gmail.com>
|
||||
leon.shi <superRaytin@163.com>
|
||||
lgmcolin <gengmin.lgm@gmail.com>
|
||||
lgmcolin <lgmcolin@gmail.com>
|
||||
lixiaochou077 <qi.liqi07@gmail.com>
|
||||
lizhaocai <lzc09008@gmail.com>
|
||||
muzuiget <muzuiget@gmail.com>
|
||||
pizn <pizner@gmail.com>
|
||||
plandem <plandem@gmail.com>
|
||||
popomore <sakura9515@gmail.com>
|
||||
qubaoming <qubaoming@didichuxing.com>
|
||||
ryangun <ryangun@foxmail.com>
|
||||
shelwin <wxfans@gmail.com>
|
||||
shouyong <enlangs@163.com>
|
||||
simaQ <sima.zhang1990@gmail.com>
|
||||
snadn <snadn@snadn.cn>
|
||||
sorrycc <sorrycc@gmail.com>
|
||||
swindme <swindme@163.com>
|
||||
tianli.zhao <275287902@qq.com>
|
||||
tom <caolvchong@gmail.com>
|
||||
ustccjw <317713370@qq.com>
|
||||
warmhug <hualei5280@gmail.com>
|
||||
wizawu <wizawu@gmail.com>
|
||||
yeliex <yeliex@yeliex.com>
|
||||
yiminghe <yiminghe@gmail.com>
|
||||
yubozhao <yubz86@gmail.com>
|
||||
yuche <i@yuche.me>
|
||||
z <haig8@msn.com>
|
||||
zack <zxyah@126.com>
|
||||
zhangpc <zhangpc@tenxcloud.com>
|
||||
zhaocai <lzc09008@gmail.com>
|
||||
zhujun24 <zhujun87654321@gmail.com>
|
||||
zilong <jzlxiaohei@163.com>
|
||||
zinkey <yaya@uloveit.com.cn>
|
||||
偏右 <afc163@gmail.com>
|
||||
逸达 <dqaria@gmail.com>
|
||||
陆离 <surgesoft@gmail.com>
|
||||
低位 <zhujun87654321@gmail.com>
|
||||
闲耘™ <hotoo.cn@gmail.com>
|
||||
偏右 <afc163@gmail.com>
|
||||
白羊座小葛 <abeyuhang@gmail.com>
|
||||
逸达 <dqaria@gmail.com>
|
||||
闲耘™ <hotoo.cn@gmail.com>
|
||||
|
||||
@@ -1,292 +0,0 @@
|
||||
---
|
||||
order: 3
|
||||
title: Change Log
|
||||
toc: false
|
||||
timeline: true
|
||||
---
|
||||
|
||||
If you want to read change logs before `2.0.0`, please visit [GitHub](https://github.com/ant-design/ant-design/releases?after=2.0.0).
|
||||
|
||||
---
|
||||
|
||||
## 2.3.1
|
||||
|
||||
`2016-11-07`
|
||||
|
||||
* Add missing `dist/antd.css` back.
|
||||
|
||||
## 2.3.0
|
||||
|
||||
`2016-11-04`
|
||||
|
||||
* Upgrade normalize.css to 5.0.
|
||||
* Point main file to `lib/index.js` in package.json. [#3397](https://github.com/ant-design/ant-design/pull/3397)
|
||||
* A brand new `Spin` design.
|
||||
* Add `addon` for `TimePicker` to allow render some addon to its bottom.
|
||||
* Add `onDragEnd` for `Tree`.
|
||||
* Add `bordered` for `Collapse`.
|
||||
* Improve `Tabs` switch animation.
|
||||
* Improve `Radio` and `Checkbox` style when it's disabled and mouse hovered. [#3590](https://github.com/ant-design/ant-design/issues/3590)
|
||||
* Opitimize `Transfer` performance.[#2860](https://github.com/ant-design/ant-design/issues/2860)
|
||||
* Fix nested `Popover` style issue. [#3448](https://github.com/ant-design/ant-design/issues/3448)
|
||||
* Fix issue resulting in server side render `Transfer` failed. [#3686](https://github.com/ant-design/ant-design/issues/3686)
|
||||
* Fix issue resulting in preview image not display when `Upload` in `picture-card` mode. [#3706](https://github.com/ant-design/ant-design/pull/3706) [@denzw](https://github.com/denzw)
|
||||
* DatePicker
|
||||
* `onChange` will be triggered when `DatePicker` in `showTime` mode on blur now.
|
||||
* Add `monthCellContentRender` and `cellContentRender` for `MonthPicker`.
|
||||
* `Rangepicker` can input time manually now.[#3718](https://github.com/ant-design/ant-design/issues/3718)
|
||||
* Add czech locale/translations.
|
||||
* Badge
|
||||
* Improve number over 99 displaying when mouse hovering. [#3645](https://github.com/ant-design/ant-design/issues/3645)
|
||||
* Fix moving animation when using `Badge` alone. [#3709](https://github.com/ant-design/ant-design/issues/3709)
|
||||
* Mention
|
||||
* Fix issue resulting in `Mention` will be covered by `Table`. [#3588](https://github.com/ant-design/ant-design/issues/3588)
|
||||
* Add `getSuggestionContainer` to allow specify container. [#3658](https://github.com/ant-design/ant-design/pull/3658)
|
||||
* Tag
|
||||
* Deprecate `color`. [#3560](https://github.com/ant-design/ant-design/issues/3560)
|
||||
* Add `type`. [#3560](https://github.com/ant-design/ant-design/issues/3560)
|
||||
* Add `checkable`. [#3560](https://github.com/ant-design/ant-design/issues/3560)
|
||||
* Radio.Group
|
||||
* Add `className`。
|
||||
* `null` or `undefined` `children` will be ignored.
|
||||
* Select
|
||||
* Add `tokenSeparators` to supoort automatic tokenization。[#2071](https://github.com/ant-design/ant-design/issues/2071)
|
||||
* Add `onFocus` callback. [#3587](https://github.com/ant-design/ant-design/issues/3587)
|
||||
* Fix issue resulting in Select can't display correct selected item text in `combobox` mode. [#3401](https://github.com/ant-design/ant-design/issues/3401)
|
||||
|
||||
## 2.2.1
|
||||
|
||||
`2016-11-02`
|
||||
|
||||
* Fix controlled DatePicker[showTime] not working bug. [#3665](https://github.com/ant-design/ant-design/issues/3665)
|
||||
|
||||
## 2.2.0
|
||||
|
||||
`2016-10-28`
|
||||
|
||||
* Supports TypeScript@2.0. [@AlbertZheng](https://github.com/AlbertZheng) [#3358](https://github.com/ant-design/ant-design/issues/3358)
|
||||
* Not rely on specific version of React now. [#3627](https://github.com/ant-design/ant-design/pull/3627)
|
||||
* Alert supports `className` `style`.
|
||||
* DatePicker & MonthPicker & RangePicker allow developers to set whether to show the clear button. [#3618](https://github.com/ant-design/ant-design/issues/3618)
|
||||
* Form.Item can generate `validateStatus` & `help` for nested form control automatically. [#3212](https://github.com/ant-design/ant-design/issues/3212)
|
||||
* RangePicker can set some hours or minutes or seconds to be not selectable. [#](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date)
|
||||
* Switch
|
||||
* The width of Switch will resize automatically, according to `checkedChildren/unCheckedChildren`. [#3380](https://github.com/ant-design/ant-design/issues/3380)
|
||||
* Improve the switch animation.
|
||||
* Upload can [customized request](https://github.com/react-component/upload#customrequest) now. [@edgji](https://github.com/edgji)
|
||||
* Icon
|
||||
* New icons `bulb` `select` `like-o` `dislike-o`.
|
||||
* Adjust existing icons `loading` `like` `dislike`.
|
||||
* Improve the TypeScript definition of Card & DatePicker & Icon & Table. [@infeng](https://github.com/infeng) [3468](https://github.com/ant-design/ant-design/pull/3468) [#3603](https://github.com/ant-design/ant-design/pull/3603) [#3531](https://github.com/ant-design/ant-design/pull/3531)
|
||||
* Fix Cascader `defaultValue` should work. [#3470](https://github.com/ant-design/ant-design/issues/3470)
|
||||
* Fix the alignment of Button & Input & DatePicker & Select. [#3481](https://github.com/ant-design/ant-design/issues/3481)
|
||||
* DatePicker
|
||||
* Fix wrong timing of triggering `onChange` while `DatePicker[showTime]` is set. [#3523](https://github.com/ant-design/ant-design/issues/3523)
|
||||
* Fix `Dropdown.Button[disabled]` doesn't works for behaviour. [#3535](https://github.com/ant-design/ant-design/issues/3535)
|
||||
* Menu
|
||||
* Fix errors in SSR, thanks to [@xpcode](https://github.com/xpcode) to find the solution. [#2061](https://github.com/ant-design/ant-design/issues/2061) [#2406](https://github.com/ant-design/ant-design/issues/2406) [#3293](https://github.com/ant-design/ant-design/issues/3293)
|
||||
* Fix children don't support `null`. [#3599](https://github.com/ant-design/ant-design/issues/3599)
|
||||
* Fix loading status animation for message.[#3536](https://github.com/ant-design/ant-design/issues/3536)
|
||||
* Form
|
||||
* Fix style issue while using `Form[inline]` and `Input[addonBefore|addonAfter]` together. [#3524](https://github.com/ant-design/ant-design/issues/3524)
|
||||
* Fix style issue for Radio.Button in Form.Item.
|
||||
* Fix style issue for search button in Form.Item. [#3630](https://github.com/ant-design/ant-design/issues/3630)
|
||||
* Fix Form.Item should not treat no user input as validate success. [#3613](https://github.com/ant-design/ant-design/issues/3613)
|
||||
* Should not limit the min width of Popover while `Popover[title]` is not set.
|
||||
* Table
|
||||
* Fix style of fixed header of Table while `dataSource` is empty.[#3567](https://github.com/ant-design/ant-design/issues/3567)
|
||||
* Fix Table will overlap SubMenu while `dataSource` is empty. [#3521](https://github.com/ant-design/ant-design/issues/3521)
|
||||
* Tabs
|
||||
* Height of header of `Tabs[type="card|editable-card"]` should follow design.
|
||||
* Fix height of TabPane should follow height of its content. [#3304](https://github.com/ant-design/ant-design/issues/3304)
|
||||
* Fix style of `TreeSelect[showSearch]`. [#3520](https://github.com/ant-design/ant-design/issues/3520)
|
||||
|
||||
## 2.1.0
|
||||
|
||||
`2016-10-16`
|
||||
|
||||
- Supports spinning Icon.
|
||||
- Tabs's switch animation could be disabled now. [#3324](https://github.com/ant-design/ant-design/issues/3324)
|
||||
- Add Spanish localization for LocaleProvider. @Danjavia
|
||||
- Update Russian localization for LocaleProvider. @plandem
|
||||
- Add `onSelect` event for AutoComplete.
|
||||
- Improve style of Modal.
|
||||
- Improve animation of Tooltip.
|
||||
- Improve style of Transfer's buttons.
|
||||
- Improve style of Tree.
|
||||
- Fix some less variables.
|
||||
- Fix errors while import the whole antd in SSR.
|
||||
- Fix errors while render Affix and BackTop on server. [#3283](https://github.com/ant-design/ant-design/issues/3283) [#3343](https://github.com/ant-design/ant-design/issues/3343)
|
||||
- Fix conflicts between Cascader search mode and browser's autocomplete behaviour. [#3350](https://github.com/ant-design/ant-design/issues/3350)
|
||||
- Fix bug that `h3` cannot be the value of Card[title]. [#3388](https://github.com/ant-design/ant-design/issues/3388)
|
||||
- DatePicker
|
||||
- Fix bug that `onChange` will be trigger twice when `showTime` is set. [#3376](https://github.com/ant-design/ant-design/issues/3376)
|
||||
- Fix differences between overlay's and trigger's date format. [#3405](https://github.com/ant-design/ant-design/issues/3405) [#3298](https://github.com/ant-design/ant-design/issues/3298)
|
||||
- Fix style conflicts with TimePicker. [#3312](https://github.com/ant-design/ant-design/issues/3312) [#3307](https://github.com/ant-design/ant-design/issues/3307)
|
||||
- Fix overflow issue for Form.Item label.
|
||||
- Fix that Icon should not show border in Safari.
|
||||
- Fix infinite loop while inc/dec InputNubmer with keyboard. [#3239](https://github.com/ant-design/ant-design/issues/3239)
|
||||
- Fix the style of the arrow of Popover.
|
||||
- Fix bug Popover and Popconfirm `arrowPointAtCenter` doesn't work.
|
||||
- Select
|
||||
- Fix bug that styles of Select are imported twice. [#3332](https://github.com/ant-design/ant-design/issues/3332)
|
||||
- Fix bug `notFoundContent` cannot be set as `''`. [#3345](https://github.com/ant-design/ant-design/issues/3345)
|
||||
- Fix the unstable width of table cell with Select[showSearch]. [#3413](https://github.com/ant-design/ant-design/issues/3413)
|
||||
- Fix style conflicts while use `border` & `title` & `footer` of Table at the same time. [#3301](https://github.com/ant-design/ant-design/issues/3301)
|
||||
- Fix that the height of TabPane doesn't follow height of content. [#3377](https://github.com/ant-design/ant-design/issues/3377)
|
||||
- Fix bug Transfer[titles] is not under the control of LocaleProvider. [#3264](https://github.com/ant-design/ant-design/pull/3264)
|
||||
- Upload
|
||||
- Fix bug users' `onRemove` will override default behaviour. [#3317](https://github.com/ant-design/ant-design/issues/3317)
|
||||
- Fix style for `listType='picture-card'`.[#3316](https://github.com/ant-design/ant-design/issues/3316)
|
||||
- Fix bug that moment locales is not found while built. [#3204](https://github.com/ant-design/ant-design/issues/3204) [#3411](https://github.com/ant-design/ant-design/issues/3411)
|
||||
|
||||
## 2.0.1
|
||||
|
||||
`2016-10-01`
|
||||
|
||||
- Fix developers cannot call methods of react-slick. [#3164](https://github.com/ant-design/ant-design/issues/3164)
|
||||
- Fix Steps.Step[icon] should support React.ReactNode. [#3159](https://github.com/ant-design/ant-design/issues/3159)
|
||||
- Fix server-side render for Affix. [#3216](https://github.com/ant-design/ant-design/issues/3216)
|
||||
- Fix Mention should supoort `onSelect` `placeholder`. [#3236](https://github.com/ant-design/ant-design/issues/3236) [#3226](https://github.com/ant-design/ant-design/issues/3226)
|
||||
- Fix Transfer cannot work with `getFieldDecorator`.
|
||||
- Fix LocaleProvider doesn't work for time-related components.
|
||||
- Fix Cascader doesn't show search text in search mode.
|
||||
- Fix the animation & text Spin should be placed in vertical middle.
|
||||
- Fix styles of RangePicker Modal Tag Progress.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
`2016-09-28`
|
||||
|
||||
After four months, `antd@2.0.0` is published. We had refactored code and improve functionalities and details of existing components. What's more, we provide English version of the documentation. The antd community help us a lot in developing `antd@2.0.0`.
|
||||
|
||||
If you meet any problem while you try to upgrade from `antd@1.0.0`, feel free to [create issues on GitHub](https://github.com/ant-design/ant-design/issues).
|
||||
|
||||
### 2.x Major changes
|
||||
|
||||
* Refactor components with TypeScript, and provide **`.d.ts` files which are officially supported**. Thanks to all the developers that contributed to [#1846](https://github.com/ant-design/ant-design/issues/1846) and @infeng.
|
||||
* **Translate the documentation into English**, and we are going to provide both of Chinese and English versions of the documentation in the future. Thanks to all the translators and reviewers that contributed to [#1471](https://github.com/ant-design/ant-design/issues/1471).
|
||||
* DatePicker, TimePicker, Calendar and other components that are designed to select time **are refactored to replace [gregorian-calendar](github.com/yiminghe/gregorian-calendar) with [moment](http://momentjs.com/)**.
|
||||
* All the [icons](http://ant.design/components/icon/) are re-designed.
|
||||
* New component [Mention](http://ant.design/components/mention/).
|
||||
* New component [AutoComplete](http://ant.design/components/auto-complete/).
|
||||
* The `getFieldProps` of Form is replaced with `getFieldDecorator` which will warn developers if they make mistakes. Related discussion [#1533](https://github.com/ant-design/ant-design/issues/1533).
|
||||
* Table supports [grouping columns](http://ant.design/components/table/#components-table-demo-grouping-columns). @yesmeck
|
||||
* Removed components and features which are deprecated in `antd@1.x`, such as QueueAnim, Validation, Form.ValueMixin, Progress.Line, Progress.Circle, Popover[overlay] and Slider[marks] will not support array any more.
|
||||
|
||||
### 2.x Breaking changes
|
||||
|
||||
There are some breaking changes in `antd@2.0.0`, and you need to modify your code to work with it.
|
||||
|
||||
* `value` and `defaultValue` of all the time-related components will not support type `String/Date`, please use [moment](http://momentjs.com/):
|
||||
```diff
|
||||
- <TimePicker defaultValue="12:08:23" />
|
||||
+ <TimePicker defaultValue={moment('12:08:23', 'HH:mm:ss')} />
|
||||
|
||||
- <DatePicker defaultValue="2015/01/01" />
|
||||
+ <DatePicker defaultValue={moment('2015/01/01', 'YYYY/MM/DD')} />
|
||||
|
||||
- <Calendar defaultValue={new Date('2010-10-10')} />
|
||||
+ <Calendar defaultValue={moment('2010-10-10', 'YYYY-MM-DD')} />
|
||||
```
|
||||
* Parameters of type `Date/GregorianCalendar` of functions such as `onChange` and `onPanelChange`, plus other callback functions had been changed to type moment. Please consult [APIs of gregorian-calendar](https://github.com/yiminghe/gregorian-calendar) and [APIs of moment](http://momentjs.com/docs/), and update your code accordingly. And you can consult this [commit](https://github.com/ant-design/ant-design/commit/5a4ebe535f0353089b30ac331bc4fb7877963371) to see how to upate.
|
||||
|
||||
Because the return value of `JSON.stringy(date: moment)` will lost time zone, we should use `.format` to convert date to string first, see related issue [#3082](https://github.com/ant-design/ant-design/issues/3082) for details:
|
||||
```js
|
||||
handleSubmit() {
|
||||
const values = this.props.form.getFieldsValue();
|
||||
values.date = values.date.format('YYYY-MM-DD HH:mm:ss'); // or other format
|
||||
const data = JSON.stringify(values);
|
||||
// send data to server
|
||||
}
|
||||
```
|
||||
* For the value of time-related components becomes an instance of `moment`, you should replace `type: 'date'` with `type: 'object'` in form validation.
|
||||
* The `format` of time-related components is changed from [gregorian-calendar-format](https://github.com/yiminghe/gregorian-calendar-format#api) to [moment format](http://momentjs.com/docs/#/parsing/string-format/) now, for instance the format `yyyy-MM-dd` should change to `YYYY-MM-DD`.
|
||||
* `linkRender` and `nameRender` of Breadcrumb are removed, please use `itemRender`.
|
||||
* `onClose` and `onOpen` of Menu are removed, please use `onOpenChange`. As being totally different, please check [this demo](http://beta.ant.design/components/menu/#components-menu-demo-sider-current) first.
|
||||
* Paging columns of Table were removed, please use [fixed columns](http://ant.design/components/table/#components-table-demo-fixed-columns).
|
||||
* `Popover[overlay]` is removed, please use `Popover[content]` instead.
|
||||
|
||||
The following change will throw some warnings in the console and it will still work, but we recommend to update your code.
|
||||
|
||||
* `getFieldProps` of Form is deprecated, please use `getFieldDecorator`:
|
||||
|
||||
```diff
|
||||
- <Input placeholder="text" {...getFieldProps('userName', { ... })} />
|
||||
+ {getFieldDecorator('userName', { ... })(
|
||||
+ <Input placeholder="text" />
|
||||
+ )}
|
||||
```
|
||||
|
||||
Look up to [#1533](https://github.com/ant-design/ant-design/issues/1533) for related discussion.
|
||||
|
||||
* `toggleOpen` of DatePicker is deprecated, please use `onOpenChange`:
|
||||
|
||||
```diff
|
||||
- handleToggleOpen({ open }) {
|
||||
+ handleOpenChange(open) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 2.x Bug fixes
|
||||
|
||||
* Dropdown.Button[disabled] should work. [#3070](https://github.com/ant-design/ant-design/issues/3070)
|
||||
* `option.withRef` of Form.create should work. [#2843](https://github.com/ant-design/ant-design/issues/2843)
|
||||
* Fix slow response of expanding sub menu in Menu[inline] mode. [#2701](https://github.com/ant-design/ant-design/issues/2701)
|
||||
* The button of Modal.confirm(and so on) should not be clickable while it is closed asynchronously. [#2684](https://github.com/ant-design/ant-design/issues/2684)
|
||||
* `format` of DatePicker[showTime] should work. [#3123](https://github.com/ant-design/ant-design/issues/3123)
|
||||
* Fix Table[dataSource] treat key whose value is `0` as inexisting. [#3166](https://github.com/ant-design/ant-design/pull/3166) @noonnightstorm
|
||||
* Tree.Node should not show arrow if it has no child nodes. [#2616](https://github.com/ant-design/ant-design/issues/2616)
|
||||
* Fix cursor style of arrows that are hidden of Tree.Node. [#2748](https://github.com/ant-design/ant-design/issues/2748)
|
||||
|
||||
### 2.x Other improvements
|
||||
|
||||
* Alert supports [`banner` mode](http://ant.design/components/alert/#components-alert-demo-banner).
|
||||
* BackTop will scroll to top with animation.
|
||||
* Badge supports [status dot mode](http://ant.design/components/badge/#components-badge-demo-status).
|
||||
* Cascader supports [searching options directly](http://ant.design/components/cascader/#components-cascader-demo-search).
|
||||
* Checkbox supports [indeterminate mode](http://ant.design/components/checkbox/#components-checkbox-demo-check-all).
|
||||
* Form supports [vertical layout](http://ant.design/components/form/#components-form-demo-validate-customized).
|
||||
* InputNumber supports long press to increase/decrease number. [#](http://ant.design/components/input-number/#components-input-number-demo-basic)
|
||||
* notification supports [customized icon](http://ant.design/components/notification/#components-notification-demo-custom-icon).
|
||||
* Spin allows [customized tips and animation work together](http://ant.design/components/spin/#components-spin-demo-tip). @jerrybendy
|
||||
* Transfer can handle event while options are checked/unchecked. [#](http://ant.design/components/transfer/#components-transfer-demo-basic)
|
||||
* Transfer can determine [whether an option is checkable](http://ant.design/components/transfer/#components-transfer-demo-basic).
|
||||
* Improve style of Alert and notification.
|
||||
* Modal.confirm(and so on) can be closed by keyboard. @Dafrok
|
||||
* Improve the user experience of [selecting time in DatePicker](http://ant.design/components/date-picker/#components-date-picker-demo-time).
|
||||
* Improve the status changed animation of [Spin](http://ant.design/components/spin/#components-spin-demo-nested ).
|
||||
* Update [font-family](https://github.com/ant-design/ant-design/commit/2f308b0f995cfcb2a3c8feb1e35ffd3f0bf93cfc).
|
||||
|
||||
### 2.x Workflow
|
||||
|
||||
* [AntD Library](http://library.ant.design/) a collection of Axure files which includes components and patterns that follow Ant Design Specification.
|
||||
* Rename `babel-plugin-antd` to [`babel-plugin-import`](https://github.com/ant-design/babel-plugin-import), and this means that `babel-plugin-import` becomes an common load-on-demand solution and not just for `antd`.
|
||||
|
||||
Please update `package.json`:
|
||||
|
||||
```diff
|
||||
{
|
||||
"devDependencies": {
|
||||
- "babel-plugin-antd": "^0.x.x",
|
||||
+ "babel-plugin-import": "^1.0.0",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And update your babel config in `.babelrc` or other place:
|
||||
|
||||
```diff
|
||||
{
|
||||
- "plugins": [["antd", { style: "css" }]]
|
||||
+ "plugins": [["import", { libraryName: "antd", style: "css" }]]
|
||||
}
|
||||
```
|
||||
|
||||
* [dva@1.0.0](https://github.com/dvajs/dva) is published and it is officially recommended framework [in real world](http://ant.design/docs/react/practical-projects).
|
||||
* The officially recommended scaffold is [dva-cli](https://github.com/dvajs/dva-cli) now, the old `antd-init` is just for studying and demo.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
Visit [GitHub](https://github.com/ant-design/ant-design/releases?after=2.0.0) to read change logs from `0.x` to `1.x`。
|
||||
@@ -9,283 +9,6 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 2.3.1
|
||||
|
||||
`2016-11-07`
|
||||
|
||||
* 修正上个版本缺少 `dist/antd.css` 的问题。
|
||||
|
||||
## 2.3.0
|
||||
|
||||
`2016-11-04`
|
||||
|
||||
* 升级 normalize.css 到 5.0。
|
||||
* package.json 的 main 换成了 `lib/index.js`。[#3397](https://github.com/ant-design/ant-design/pull/3397)
|
||||
* 全新的 `Spin` 设计。
|
||||
* `TimePicker` 新增了 `addon` 以支持自定义的附加内容。
|
||||
* `Tree` 新增了 `onDragEnd`。
|
||||
* `Collapse` 新增了 `bordered`。
|
||||
* 优化 `Tabs` 切换时的动画效果。
|
||||
* 优化 `Radio` 和 `Checkbox` 在禁用和鼠标停留时的样式。[#3590](https://github.com/ant-design/ant-design/issues/3590)
|
||||
* 优化 `Transfer` 的性能。[#2860](https://github.com/ant-design/ant-design/issues/2860)
|
||||
* 修复 `Popover` 嵌套时的样式问题。[#3448](https://github.com/ant-design/ant-design/issues/3448)
|
||||
* 修复 `Transfer` 服务端渲染报错的问题。[#3686](https://github.com/ant-design/ant-design/issues/3686)
|
||||
* 修复 `Upload` `picture-card` 模式下新上传的图片不显示预览的问题。[#3706](https://github.com/ant-design/ant-design/pull/3706) [@denzw](https://github.com/denzw)
|
||||
* DatePicker
|
||||
* 在 `showTime` 模式下现在失去焦点也会触发 `onChange`。
|
||||
* `MonthPicker` 增加了 `monthCellContentRender` 和 `cellContentRender`。
|
||||
* `RangePicker` 现在可以手动输入时间了。[#3718](https://github.com/ant-design/ant-design/issues/3718)
|
||||
* 新增了捷克语的翻译。
|
||||
* Badge
|
||||
* 优化鼠标停留时超过 99 的数字显示。[#3645](https://github.com/ant-design/ant-design/issues/3645)
|
||||
* 修复单独使用时会有移动动画的问题。[#3709](https://github.com/ant-design/ant-design/issues/3709)
|
||||
* Mention
|
||||
* 修复会被 `Table` 遮住的问题。[#3588](https://github.com/ant-design/ant-design/issues/3588)
|
||||
* 新增 `getSuggestionContainer` 来指定容器。[#3658](https://github.com/ant-design/ant-design/pull/3658)
|
||||
* Tag
|
||||
* 废弃 `color` 属性。[#3560](https://github.com/ant-design/ant-design/issues/3560)
|
||||
* 新增 `type`。[#3560](https://github.com/ant-design/ant-design/issues/3560)
|
||||
* 新增 `checkable`。[#3560](https://github.com/ant-design/ant-design/issues/3560)
|
||||
* Radio.Group
|
||||
* 新增 `className`。
|
||||
* `children` 为 `null` 或 `undefined` 时现在会被忽略。
|
||||
* Select
|
||||
* 新增 `tokenSeparators` 支持粘贴时自动分词。[#2071](https://github.com/ant-design/ant-design/issues/2071)
|
||||
* 新增 `onFocus` 回调。[#3587](https://github.com/ant-design/ant-design/issues/3587)
|
||||
* 修复 `combobox` 模式下选中项不能正确显示的问题。[#3401](https://github.com/ant-design/ant-design/issues/3401)
|
||||
|
||||
## 2.2.1
|
||||
|
||||
`2016-11-02`
|
||||
|
||||
* 修复 Form 中 DatePicker[showTime](受控)无法使用的问题。[#3665](https://github.com/ant-design/ant-design/issues/3665)
|
||||
|
||||
## 2.2.0
|
||||
|
||||
`2016-10-28`
|
||||
|
||||
* 支持 TypeScript@2.0。[@AlbertZheng](https://github.com/AlbertZheng) [#3358](https://github.com/ant-design/ant-design/issues/3358)
|
||||
* 不再强依赖于 React 特定版本。[#3627](https://github.com/ant-design/ant-design/pull/3627)
|
||||
* Alert 支持 `className` `style` 属性。
|
||||
* DatePicker MonthPicker RangePicker 现在允许设置是否显示清除按钮。[#3618](https://github.com/ant-design/ant-design/issues/3618)
|
||||
* Form.Item 现在可以感知深层嵌套的表单域,以自动为其生成错误信息和状态。[#3212](https://github.com/ant-design/ant-design/issues/3212)
|
||||
* RangePicker 现在可以设置不可选的时间。[#](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date)
|
||||
* Switch
|
||||
* 宽度现在会随着 `checkedChildren/unCheckedChildren` 自动调整。[#3380](https://github.com/ant-design/ant-design/issues/3380)
|
||||
* 优化切换动画。
|
||||
* Upload 现在可以 [自定义上传方式](https://github.com/react-component/upload#customrequest)。[@edgji](https://github.com/edgji)
|
||||
* Icon
|
||||
* 新增 `bulb` `select` `like-o` `dislike-o`。
|
||||
* 调整 `loading` `like` `dislike`。
|
||||
* 优化 Card DatePicker Icon Table 的 TypeScript 定义。[@infeng](https://github.com/infeng) [3468](https://github.com/ant-design/ant-design/pull/3468) [#3603](https://github.com/ant-design/ant-design/pull/3603) [#3531](https://github.com/ant-design/ant-design/pull/3531)
|
||||
* 修复 Cascader `defaultValue` 失效的问题。[#3470](https://github.com/ant-design/ant-design/issues/3470)
|
||||
* 修复在一行内同时使用 Button Input DatePicker Select 时对齐的问题。[#3481](https://github.com/ant-design/ant-design/issues/3481)
|
||||
* DatePicker
|
||||
* 修复设置 `DatePicker[showTime]` 后 `onChange` 事件触发时机问题。[#3523](https://github.com/ant-design/ant-design/issues/3523)
|
||||
* 修复 Dropdown.Button disabled 后仍然响应操作的问题。[#3535](https://github.com/ant-design/ant-design/issues/3535)
|
||||
* Menu
|
||||
* 修复服务端渲染问题,感谢 [@xpcode](https://github.com/xpcode) 定位问题。[#2061](https://github.com/ant-design/ant-design/issues/2061) [#2406](https://github.com/ant-design/ant-design/issues/2406) [#3293](https://github.com/ant-design/ant-design/issues/3293)
|
||||
* 修复 children 不能为 `null` 的问题。[#3599](https://github.com/ant-design/ant-design/issues/3599)
|
||||
* 修复 message 加载状态无动画的问题。[#3536](https://github.com/ant-design/ant-design/issues/3536)
|
||||
* Form
|
||||
* 修复 `Form[inline]` 与 `Input[addonBefore|addonAfter]` 一起使用时的样式问题。[#3524](https://github.com/ant-design/ant-design/issues/3524)
|
||||
* 修复 Form.Item 内 Radio.Button 样式问题。
|
||||
* 修复 Form.Item 内搜索按钮的样式问题。[#3630](https://github.com/ant-design/ant-design/issues/3630)
|
||||
* 修复用户无输入时 Form.Item 识别为校验成功的问题。[#3613](https://github.com/ant-design/ant-design/issues/3613)
|
||||
* 当 `Popover[title]` 没有设置时,不再限制 Popover 的最小宽度。
|
||||
* Table
|
||||
* 修复固定表头在没有数据情况下的样式问题。[#3567](https://github.com/ant-design/ant-design/issues/3567)
|
||||
* 修复无数据时会覆盖 SubMenu 的问题。[#3521](https://github.com/ant-design/ant-design/issues/3521)
|
||||
* Tabs
|
||||
* 修复卡片叶签头部高度与设计稿不一致的问题。
|
||||
* 修复 TabPane 的高度会被同级 TabPane 撑高的问题。[#3304](https://github.com/ant-design/ant-design/issues/3304)
|
||||
* 修复 `TreeSelect[showSearch]` 样式问题。[#3520](https://github.com/ant-design/ant-design/issues/3520)
|
||||
|
||||
## 2.1.0
|
||||
|
||||
`2016-10-16`
|
||||
|
||||
- Icon 现在支持旋转动画。
|
||||
- Tabs 现在可以禁用切换动画。[#3324](https://github.com/ant-design/ant-design/issues/3324)
|
||||
- 新增西班牙语的 localization 支持。@Danjavia
|
||||
- 更新俄语的 localization 文案。@plandem
|
||||
- 新增 AutoComplete[onSelect] 回调。
|
||||
- 优化 Modal 样式细节。
|
||||
- 优化 Tooltip 动画。
|
||||
- 优化 Transfer 按钮的样式。
|
||||
- 优化 Tree 的样式细节。
|
||||
- 整理和修复了部分 less 变量。
|
||||
- 修复服务端渲染时全量引入 antd 报错的问题。
|
||||
- 修复 Affix 与 BackTop 的服务端渲染问题。[#3283](https://github.com/ant-design/ant-design/issues/3283) [#3343](https://github.com/ant-design/ant-design/issues/3343)
|
||||
- 修复 Card[title] 内无法使用 `h3` 之类的标签的问题。[#3388](https://github.com/ant-design/ant-design/issues/3388)
|
||||
- 修复 Cascader 搜索模式与浏览器自动完成有冲突的问题。[#3350](https://github.com/ant-design/ant-design/issues/3350)
|
||||
- DatePicker
|
||||
- 修复设置 `showTime` 后,`onChange` 重复触发的问题。[#3376](https://github.com/ant-design/ant-design/issues/3376)
|
||||
- 修复浮层与 Trigger 日期格式不一致的问题。[#3405](https://github.com/ant-design/ant-design/issues/3405) [#3298](https://github.com/ant-design/ant-design/issues/3298)
|
||||
- 修复与 TimePicker 样式冲突问题。[#3312](https://github.com/ant-design/ant-design/issues/3312) [#3307](https://github.com/ant-design/ant-design/issues/3307)
|
||||
- 修复 Form.Item 标签文案过长溢出的问题。
|
||||
- 修复 Icon 在 Safari 下会出现边框的问题。
|
||||
- 修复 InputNubmer 键盘事件死循环问题。[#3239](https://github.com/ant-design/ant-design/issues/3239)
|
||||
- 修复 Popover 箭头样式问题。
|
||||
- 修复 Popover 和 Popconfirm 的 `arrowPointAtCenter` 无效的问题。
|
||||
- Select
|
||||
- 修复样式重复引入的问题。[#3376](https://github.com/ant-design/ant-design/issues/3376)
|
||||
- 修复 `notFoundContent` 无法置空的问题。[#3345](https://github.com/ant-design/ant-design/issues/3345)
|
||||
- 修复 Table 内使用 Select[showSearch] 后宽度会跳动的问题。[#3413](https://github.com/ant-design/ant-design/issues/3413)
|
||||
- 修复 Table 边框线与页头页脚冲突的问题。[#3301](https://github.com/ant-design/ant-design/issues/3301)
|
||||
- 修复 TabPane 高度不随内容变化的问题。[#3377](https://github.com/ant-design/ant-design/issues/3377)
|
||||
- 修复 Transfer[titles] 不受 LocaleProvider 控制的问题。[#3264](https://github.com/ant-design/ant-design/pull/3264)
|
||||
- Upload
|
||||
- 修复用户自定义 `onRemove` 事件会覆盖默认行为的问题。[#3317](https://github.com/ant-design/ant-design/issues/3317)
|
||||
- 修复图片卡片样式问题。[#3316](https://github.com/ant-design/ant-design/issues/3316)
|
||||
- 修复项目构建时 moment locales 找不到的问题。[#3204](https://github.com/ant-design/ant-design/issues/3204) [#3411](https://github.com/ant-design/ant-design/issues/3411)
|
||||
|
||||
## 2.0.1
|
||||
|
||||
`2016-10-01`
|
||||
|
||||
- 修复无法调用 react-slick 方法的问题。[#3164](https://github.com/ant-design/ant-design/issues/3164)
|
||||
- 修复 Steps.Step[icon] 不支持 React.ReactNode 的问题。[#3159](https://github.com/ant-design/ant-design/issues/3159)
|
||||
- 修复 Affix 不支持服务端渲染的问题。[#3216](https://github.com/ant-design/ant-design/issues/3216)
|
||||
- 修复 Mention 不支持 `onSelect` `placeholder` 的问题。[#3236](https://github.com/ant-design/ant-design/issues/3236) [#3226](https://github.com/ant-design/ant-design/issues/3226)
|
||||
- 修复 Transfer 与 `getFieldDecorator` 一起使用时的报错问题。
|
||||
- 修复 LocaleProvider 对时间组件无效的问题。
|
||||
- 修复 Cascader 搜索模式搜索文字显示不了的问题。
|
||||
- 修复 Spin 动画与文案整体不垂直居中的问题。
|
||||
- 修复 RangePicker Modal Tag Progress 等组件样式问题。
|
||||
|
||||
## 2.0.0
|
||||
|
||||
`2016-09-28`
|
||||
|
||||
很高兴的通知各位,经过四个月时间的紧密开发,`antd@2.0.0` 终于发布了。这个版本我们重构了底层代码,持续完善现有组件功能和优化细节,并提供了英文版的文档,其中很多都来自社区的贡献,无法一一感谢,欢迎各位持续关注和鞭策。在升级过程中遇到任何问题,请及时 [反馈给我们](https://github.com/ant-design/ant-design/issues)。
|
||||
|
||||
### 2.x 主要变化
|
||||
|
||||
* 开发语言改为 TypeScript,提供 **官方支持的 `.d.ts` 文件**,感谢 [#1846](https://github.com/ant-design/ant-design/issues/1846) 中所有参与到这次重构的人以及后期 @infeng 对其的完善。
|
||||
* **新增英文文档**, 以后将同时提供中英双语文档,感谢 [#1471](https://github.com/ant-design/ant-design/issues/1471) 里所有参与到翻译和审阅工作中的人。
|
||||
* 时间类组件 DatePicker、TimePicker、Calendar 等的底层 **使用 [moment](http://momentjs.com/) 替换 [gregorian-calendar](github.com/yiminghe/gregorian-calendar)**。
|
||||
* 全新设计的 [图标](http://ant.design/components/icon/)。
|
||||
* 新增提及组件 [Mention](http://ant.design/components/mention/)。
|
||||
* 新增自动完成组件 [AutoComplete](http://ant.design/components/auto-complete/)。
|
||||
* Form 新增 `getFieldDecorator` 作为 `getFieldProps` 的替代,对于不正确的使用方式 `getFieldDecorator` 会给出提示,可以降低踩坑的概率。相关讨论见 [#1533](https://github.com/ant-design/ant-design/issues/1533)。
|
||||
* Table 支持 [表头分组](http://ant.design/components/table/#components-table-demo-grouping-columns)。@yesmeck
|
||||
* 完全移除 `antd@1.x` 中已经废弃的 QueueAnim、Validation、Form.ValueMixin、Progress.Line、Progress.Circle、Popover[overlay] 及 Slider[marks] 对数组的支持。
|
||||
|
||||
### 2.x 不兼容改动
|
||||
|
||||
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。
|
||||
|
||||
* 时间类组件的 `value` 和 `defaultValue` 不再支持 `String/Date` 类型,请使用 [moment](http://momentjs.com/)。
|
||||
```diff
|
||||
- <TimePicker defaultValue="12:08:23" />
|
||||
+ <TimePicker defaultValue={moment('12:08:23', 'HH:mm:ss')} />
|
||||
|
||||
- <DatePicker defaultValue="2015/01/01" />
|
||||
+ <DatePicker defaultValue={moment('2015/01/01', 'YYYY/MM/DD')} />
|
||||
|
||||
- <Calendar defaultValue={new Date('2010-10-10')} />
|
||||
+ <Calendar defaultValue={moment('2010-10-10', 'YYYY-MM-DD')} />
|
||||
```
|
||||
* 时间类组件的 `onChange` 和 `onPanelChange` 及其他回调函数中为 `Date/GregorianCalendar` 类型的参数,均修改为 moment 类型,两者 API 有所不同,但功能基本一致,请对照 [moment 的 API 文档](http://momentjs.com/docs/) 和 [gregorian-calendar 的文档](https://github.com/yiminghe/gregorian-calendar) 进行修改。你也可以参考这个 [commit](https://github.com/ant-design/ant-design/commit/5a4ebe535f0353089b30ac331bc4fb7877963371) 来进行修改。
|
||||
|
||||
由于 `JSON.stringy(date: moment)` 返回的值会丢失时区设置,所以要先使用 `.format` 把日期转成字符串,相关 issue 见 [#3082](https://github.com/ant-design/ant-design/issues/3082):
|
||||
```js
|
||||
handleSubmit() {
|
||||
const values = this.props.form.getFieldsValue();
|
||||
values.date = values.date.format('YYYY-MM-DD HH:mm:ss'); // 或其它格式
|
||||
const data = JSON.stringify(values);
|
||||
// 发送 data 到服务器
|
||||
}
|
||||
```
|
||||
|
||||
* 时间类组件与表单校验一起使用时,`type: 'date'` 改为 `type: 'object'`。
|
||||
* 时间类组件的 `format` 属性也发生了变化,从 [gregorian-calendar-format 的格式](https://github.com/yiminghe/gregorian-calendar-format#api) 变化为与 [moment 的格式](http://momentjs.com/docs/#/parsing/string-format/),例如原来的 `yyyy-MM-dd` 将变为 `YYYY-MM-DD`。
|
||||
* Breadcrumb 移除 `linkRender` 和 `nameRender`,请使用 `itemRender`。
|
||||
* Menu 移除 `onClose` `onOpen`,请使用 `onOpenChange`。API 差异较大,请先研究 [demo](http://beta.ant.design/components/menu/#components-menu-demo-sider-current)。
|
||||
* Table 移除列分页功能,请使用 [固定列](http://ant.design/components/table/#components-table-demo-fixed-columns)。
|
||||
* Popover 移除 `overlay` ,请使用 `content`。
|
||||
|
||||
以下变化升级后旧代码仍然能正常运行,但是控制台会出现警告提示,建议按提示进行修改。
|
||||
|
||||
* Form 废弃 `getFieldProps`,请使用 `getFieldDecorator`:
|
||||
|
||||
```diff
|
||||
- <Input placeholder="text" {...getFieldProps('userName', { ... })} />
|
||||
+ {getFieldDecorator('userName', { ... })(
|
||||
+ <Input placeholder="text" />
|
||||
+ )}
|
||||
```
|
||||
|
||||
相关讨论可以看 [#1533](https://github.com/ant-design/ant-design/issues/1533)。
|
||||
|
||||
* DatePicker 废弃 `toggleOpen`,请使用 `onOpenChange`:
|
||||
|
||||
```diff
|
||||
- handleToggleOpen({ open }) {
|
||||
+ handleOpenChange(open) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 2.x Bug 修复
|
||||
|
||||
* 修复 Dropdown.Button `disabled` 属性无效的问题。[#3070](https://github.com/ant-design/ant-design/issues/3070)
|
||||
* 修复 Form.create `withRef` 选项失效的问题。[#2843](https://github.com/ant-design/ant-design/issues/2843)
|
||||
* 修复 Menu inline 模式下子菜单展开的问题。[#2701](https://github.com/ant-design/ant-design/issues/2701)
|
||||
* 修复 Modal.confirm 之类的弹窗在异步调用时按钮仍可点击的问题。[#2684](https://github.com/ant-design/ant-design/issues/2684)
|
||||
* 修复 DatePicker[showTime] 参数中的 `format` 失效的问题。[#3123](https://github.com/ant-design/ant-design/issues/3123)
|
||||
* 修复 Table[dataSource] 中的项的 key 为 `0` 时识别错误的问题。[#3166](https://github.com/ant-design/ant-design/pull/3166) @noonnightstorm
|
||||
* 修复 Tree.Node 无子节点时仍然显示箭头的问题。[#2616](https://github.com/ant-design/ant-design/issues/2616)
|
||||
* 修复 Tree.Node 箭头隐藏后鼠标 hover 上去光标仍会发生变化的问题。[#2748](https://github.com/ant-design/ant-design/issues/2748)
|
||||
|
||||
### 2.x 其他改进
|
||||
|
||||
* Alert 新增 [`banner` 模式](http://ant.design/components/alert/#components-alert-demo-banner)。
|
||||
* BackTop 增加回到顶部的动画效果。
|
||||
* Badge 新增 [状态点模式](http://ant.design/components/badge/#components-badge-demo-status)。
|
||||
* Cascader 新增 [搜索功能](http://ant.design/components/cascader/#components-cascader-demo-search)。
|
||||
* Checkbox 新增 [indeterminate 状态](http://ant.design/components/checkbox/#components-checkbox-demo-check-all)。
|
||||
* Form 新增 [垂直布局](http://ant.design/components/form/#components-form-demo-validate-customized)。
|
||||
* InputNumber 现在支持长按。[#](http://ant.design/components/input-number/#components-input-number-demo-basic)
|
||||
* notification 支持 [自定义 icon](http://ant.design/components/notification/#components-notification-demo-custom-icon)。
|
||||
* Spin 现在允许 [自定义文案与动画共存](http://ant.design/components/spin/#components-spin-demo-tip)。@jerrybendy
|
||||
* Transfer 现在可以监听用户选择了哪些选项。[#](http://ant.design/components/transfer/#components-transfer-demo-basic)
|
||||
* Transfer 现在可以定义哪些选项是 [不可选择的](http://ant.design/components/transfer/#components-transfer-demo-basic)。
|
||||
* 优化 Alert 和 notification 的样式。
|
||||
* 优化 Modal.confirm 之类的弹窗的键盘交互。@Dafrok
|
||||
* 优化 [DatePicker 的时间选择](http://ant.design/components/date-picker/#components-date-picker-demo-time) 交互。
|
||||
* 优化 [Spin 状态切换](http://ant.design/components/spin/#components-spin-demo-nested ) 时的效果。
|
||||
* 更新 [font-family](https://github.com/ant-design/ant-design/commit/2f308b0f995cfcb2a3c8feb1e35ffd3f0bf93cfc)。
|
||||
|
||||
### 2.x 相关工具发布
|
||||
|
||||
* 新增配套网站 [AntD Library](http://library.ant.design/),提供遵循 Ant Design 设计规范的组件、模式等的 Axure 资源。
|
||||
* `babel-plugin-antd` 更名为 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import),标志着该插件将作为一个通用的按需加载方案存在,而不再是 `antd` 专有。
|
||||
|
||||
请更新 `package.json`:
|
||||
|
||||
```diff
|
||||
{
|
||||
"devDependencies": {
|
||||
- "babel-plugin-antd": "^0.x.x",
|
||||
+ "babel-plugin-import": "^1.0.0",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
同时更新 `.babelrc` 或你在其它地方对其的配置:
|
||||
|
||||
```diff
|
||||
{
|
||||
- "plugins": [["antd", { style: "css" }]]
|
||||
+ "plugins": [["import", { libraryName: "antd", style: "css" }]]
|
||||
}
|
||||
```
|
||||
|
||||
* [dva@1.0.0](https://github.com/dvajs/dva) 也已经发布,并推荐 [在实战项目中使用](http://ant.design/docs/react/practical-projects)。
|
||||
* 脚手架工具推荐使用 [dva-cli](https://github.com/dvajs/dva-cli),原来的 `antd-init` 以后仅会用于学习以及 demo。
|
||||
|
||||
## 1.11.2
|
||||
|
||||
`2016-09-26`
|
||||
@@ -4,13 +4,7 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Ant Design
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://www.npmjs.org/package/antd)
|
||||
[](https://npmjs.org/package/antd)
|
||||
[](https://cdnjs.com/libraries/antd)
|
||||
[](https://david-dm.org/ant-design/ant-design)
|
||||
[](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# Ant Design [](https://travis-ci.org/ant-design/ant-design) [](https://www.npmjs.org/package/antd) [](https://npmjs.org/package/antd) [](https://david-dm.org/ant-design/ant-design) [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
一套企业级的 UI 设计语言和 React 实现。
|
||||
|
||||
@@ -18,8 +12,7 @@
|
||||
|
||||
- 提炼和服务企业级中后台产品的交互语言和视觉风格。
|
||||
- [React Component](http://react-component.github.io/badgeboard/) 基础上精心封装的高质量 UI 组件。
|
||||
- 使用 TypeScript 构建,提供完整的类型定义文件。
|
||||
- 基于 npm + webpack + babel + [dora](https://github.com/dora-js/dora) + [dva](https://github.com/dvajs/dva) 的企业级业务开发框架。
|
||||
- 基于 npm + webpack + babel 的工作流,支持 ES2015 和 TypeScript。
|
||||
|
||||
## 安装
|
||||
|
||||
@@ -40,34 +33,27 @@ ReactDOM.render(<DatePicker />, mountNode);
|
||||
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
```
|
||||
|
||||
按需加载可通过此写法 `import DatePicker from 'antd/lib/date-picker'` 或使用插件 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import)。
|
||||
按需加载可通过此写法 `import DatePicker from 'antd/lib/date-picker'` 或使用插件 [babel-plugin-antd](https://github.com/ant-design/babel-plugin-antd)。
|
||||
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
现代浏览器和 IE9 及以上。
|
||||
现代浏览器和 IE8 及以上。
|
||||
|
||||
> [IE8 issues](https://github.com/xcatliu/react-ie8)
|
||||
|
||||
## TypeScript
|
||||
|
||||
tsconfig.json
|
||||
|
||||
```
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
```js
|
||||
///<reference path='./node_modules/antd/type-definitions/antd.d.ts'/>
|
||||
...
|
||||
```
|
||||
|
||||
## 链接
|
||||
|
||||
- [首页](http://ant.design/)
|
||||
- [React 实现](http://ant.design/docs/react/introduce)
|
||||
- [修改记录](CHANGELOG.zh-CN.md)
|
||||
- [React 实现](http://ant.design/#/docs/react/introduce)
|
||||
- [修改记录](CHANGELOG.md)
|
||||
- [开发脚手架](https://github.com/ant-design/antd-init/)
|
||||
- [开发工具文档](http://ant-tool.github.io/)
|
||||
- [React 基础组件](http://react-component.github.io/)
|
||||
@@ -81,6 +67,7 @@ tsconfig.json
|
||||
- [CodePen 模板](http://codepen.io/benjycui/pen/KgPZrE?editors=001)
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
|
||||
|
||||
## 如何贡献
|
||||
|
||||
我们欢迎任何形式的贡献,有任何建议或意见您可以进行 [Pull Request](https://github.com/ant-design/ant-design/pulls),或者给我们 [提问](https://github.com/ant-design/ant-design/issues)。
|
||||
|
||||
31
README.md
31
README.md
@@ -4,22 +4,19 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Ant Design
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://www.npmjs.org/package/antd)
|
||||
[](https://npmjs.org/package/antd)
|
||||
[](https://david-dm.org/ant-design/ant-design)
|
||||
[](http://isitmaintained.com/project/ant-design/ant-design "Average time to resolve an issue")
|
||||
[](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
# Ant Design [](https://travis-ci.org/ant-design/ant-design) [](https://www.npmjs.org/package/antd) [](https://npmjs.org/package/antd) [](https://david-dm.org/ant-design/ant-design) [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
An enterprise-class UI design language and React-based implementation.
|
||||
|
||||
## :loudspeaker: Document Translation Recruitment
|
||||
|
||||
We are now working on translate components document to English, and we need some translator and reviewer. https://github.com/ant-design/ant-design/issues/1471
|
||||
|
||||
## Features
|
||||
|
||||
- An enterprise-class design language and high quality UI.
|
||||
- Graceful UI components out of the box, base on [React Component](http://react-component.github.io/badgeboard/).
|
||||
- Writen in TypeScript with complete define types.
|
||||
- A npm + webpack + babel + [dora](https://github.com/dora-js/dora) + [dva](https://github.com/dvajs/dva) development framework.
|
||||
- A npm + webpack + babel + dora [workflow](http://ant-tool.github.io/index.html).
|
||||
|
||||
## Install
|
||||
|
||||
@@ -44,19 +41,19 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
|
||||
### Use modularized antd
|
||||
|
||||
- Use [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) (Recommended)
|
||||
- Use [babel-plugin-antd](https://github.com/ant-design/babel-plugin-antd) (Recommended)
|
||||
|
||||
```js
|
||||
// .babelrc
|
||||
{
|
||||
"plugins": [["import", { libraryName: "antd", style: "css" }]]
|
||||
"plugins": [["antd", { style: "css" }]]
|
||||
}
|
||||
```
|
||||
|
||||
Then you can import components from antd directly.
|
||||
|
||||
```jsx
|
||||
// import js and css modularly, parsed by babel-plugin-import
|
||||
// import js and css modularly, parsed by babel-plugin-antd
|
||||
import { DatePicker } from 'antd';
|
||||
```
|
||||
|
||||
@@ -64,13 +61,12 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
|
||||
|
||||
```jsx
|
||||
import DatePicker from 'antd/lib/date-picker'; // just for js
|
||||
import 'antd/lib/date-picker/style/css'; // with style
|
||||
```
|
||||
|
||||
|
||||
## Browser Support
|
||||
|
||||
Normal browsers and Internet Explorer 9+.
|
||||
Normal browsers and Internet Explorer 8+.
|
||||
|
||||
> [IE8 issues](https://github.com/xcatliu/react-ie8)
|
||||
|
||||
@@ -82,8 +78,7 @@ tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true
|
||||
"jsx": "preserve"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -91,8 +86,8 @@ tsconfig.json
|
||||
## Links
|
||||
|
||||
- [Home page](http://ant.design/)
|
||||
- [UI library](http://ant.design/docs/react/introduce)
|
||||
- [ChangeLog](CHANGELOG.en-US.md)
|
||||
- [React UI page](http://ant.design/#/docs/react/introduce)
|
||||
- [ChangeLog](CHANGELOG.md)
|
||||
- [Scaffold tool](https://github.com/ant-design/antd-init/)
|
||||
- [Development tool](http://ant-tool.github.io/)
|
||||
- [React components](http://react-component.github.io/)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import assign from 'object-assign';
|
||||
|
||||
export default function getLocale(props, context, componentName, getDefaultLocale) {
|
||||
const locale = context && context.antLocale && context.antLocale[componentName] ?
|
||||
context.antLocale[componentName] : getDefaultLocale();
|
||||
|
||||
const result = assign({}, locale, props.locale);
|
||||
result.lang = assign({}, locale.lang, props.locale.lang);
|
||||
return result;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
export default function getRequestAnimationFrame() {
|
||||
if (typeof window === 'undefined') {
|
||||
return () => {};
|
||||
}
|
||||
if (window.requestAnimationFrame) {
|
||||
return window.requestAnimationFrame;
|
||||
}
|
||||
const prefix = ['moz', 'ms', 'webkit'].filter(key => `${key}RequestAnimationFrame` in window)[0];
|
||||
return prefix
|
||||
? window[`${prefix}RequestAnimationFrame`]
|
||||
: callback => setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
export default function getScroll(target, top): number {
|
||||
if (typeof window === 'undefined') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const prop = top ? 'pageYOffset' : 'pageXOffset';
|
||||
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||
const isWindow = target === window;
|
||||
|
||||
let ret = isWindow ? target[prop] : target[method];
|
||||
// ie6,7,8 standard mode
|
||||
if (isWindow && typeof ret !== 'number') {
|
||||
ret = window.document.documentElement[method];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
export default function splitObject(obj, parts): Array<any> {
|
||||
const left = {};
|
||||
const right = {};
|
||||
Object.keys(obj).forEach((k) => {
|
||||
if (parts.indexOf(k) !== -1) {
|
||||
left[k] = obj[k];
|
||||
} else {
|
||||
right[k] = obj[k];
|
||||
}
|
||||
});
|
||||
return [left, right];
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import warning from 'warning';
|
||||
|
||||
const warned: { [msg: string]: boolean} = {};
|
||||
export default (valid: boolean, message: string): void => {
|
||||
if (!valid && !warned[message]) {
|
||||
warning(false, message);
|
||||
warned[message] = true;
|
||||
}
|
||||
};
|
||||
@@ -1,31 +1,16 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
title: 基本
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
最简单的用法。
|
||||
|
||||
## en-US
|
||||
|
||||
The simplest usage.
|
||||
|
||||
````jsx
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Affix>
|
||||
<Button type="primary">Affix top</Button>
|
||||
</Affix>
|
||||
<br />
|
||||
<Affix offsetBottom={0}>
|
||||
<Button type="primary">Affix bottom</Button>
|
||||
</Affix>
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
<Affix>
|
||||
<Button type="primary">固定在顶部</Button>
|
||||
</Affix>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
16
components/affix/demo/bottom.md
Normal file
16
components/affix/demo/bottom.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
order: 2
|
||||
title: 下方固定
|
||||
---
|
||||
|
||||
固定在屏幕下方
|
||||
|
||||
````jsx
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Affix offsetBottom={20}>
|
||||
<Button type="primary">固定在距离底部 20px 的位置</Button>
|
||||
</Affix>
|
||||
, mountNode);
|
||||
````
|
||||
16
components/affix/demo/offset.md
Normal file
16
components/affix/demo/offset.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
order: 1
|
||||
title: 偏移
|
||||
---
|
||||
|
||||
达到一定的偏移量才触发。
|
||||
|
||||
````jsx
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Affix offsetTop={75}>
|
||||
<Button type="primary">固定在距离顶部 75px 的位置</Button>
|
||||
</Affix>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,25 +1,16 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 固定状态改变的回调
|
||||
en-US: Callback
|
||||
order: 3
|
||||
title: 固定状态改变的回调
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以获得是否固定的状态。
|
||||
|
||||
## en-US
|
||||
|
||||
Callback with affixed state.
|
||||
|
||||
````jsx
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Affix offsetTop={120} onChange={affixed => console.log(affixed)}>
|
||||
<Button>120px to affix top</Button>
|
||||
</Affix>,
|
||||
mountNode
|
||||
);
|
||||
<Button>固定在距离顶部 120px 的位置</Button>
|
||||
</Affix>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 滚动容器
|
||||
en-US: Container to scroll.
|
||||
order: 4
|
||||
title: 参考对象
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用 `target` 设置 `Affix` 需要监听其滚动事件的元素,默认为 `window`。
|
||||
|
||||
## en-US
|
||||
|
||||
Set a `target` for 'Affix', which is listen to scroll event of target element (default is `window`).
|
||||
|
||||
````jsx
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
const Demo = () => {
|
||||
return (
|
||||
<div className="view-port">
|
||||
<div id="scrollable-container">
|
||||
<div className="background">
|
||||
<div style={{ height: 100, overflow: 'hidden' }}>
|
||||
<div style={{ height: '100%', overflowY: 'scroll' }} id="affix-target">
|
||||
<div style={{ height: 300, backgroundImage: 'url(https://zos.alipayobjects.com/rmsportal/RmjwQiJorKyobvI.jpg)' }}>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<Affix target={() => document.getElementById('scrollable-container')} offsetTop={20}>
|
||||
<Button type="primary">Fixed at the top of container</Button>
|
||||
<Affix target={() => document.getElementById('affix-target')} offsetTop={20}>
|
||||
<Button type="primary">固定在容器顶部</Button>
|
||||
</Affix>
|
||||
</div>
|
||||
</div>
|
||||
@@ -35,18 +27,3 @@ const Demo = () => {
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-affix-demo-target .view-port {
|
||||
height: 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#components-affix-demo-target #scrollable-container {
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
#components-affix-demo-target .background {
|
||||
height: 300px;
|
||||
background-image: url('https://zos.alipayobjects.com/rmsportal/RmjwQiJorKyobvI.jpg');
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Other
|
||||
title: Affix
|
||||
---
|
||||
|
||||
Make an element sticky to viewport.
|
||||
|
||||
## When To Use
|
||||
|
||||
When user browses a long web page, some content need to sticky to viewport. It is common for menus and actions.
|
||||
|
||||
Please note that Affix should not cover other content in page, especially when the size of viewport is small.
|
||||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|--------------|-----------------------|----------|--------------|
|
||||
| offsetTop | Pixels to offset from top when calculating position of scroll | Number | 0 |
|
||||
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | Number | - |
|
||||
| onChange | Callback when affix state is changed | Function(affixed) | - |
|
||||
|
||||
**Note:** Children of `Affix` can not be `position: absolute`, but you can set `Affix` as `position: absolute`:
|
||||
|
||||
```jsx
|
||||
<Affix style={{ position: 'absolute', top: y, left: x}}>
|
||||
...
|
||||
</Affix>
|
||||
```
|
||||
@@ -2,17 +2,30 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import warning from 'warning';
|
||||
import shallowequal from 'shallowequal';
|
||||
import omit from 'omit.js';
|
||||
import getScroll from '../_util/getScroll';
|
||||
|
||||
function getTargetRect(target): ClientRect {
|
||||
function getScroll(target, top) {
|
||||
const prop = top ? 'pageYOffset' : 'pageXOffset';
|
||||
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||
const isWindow = target === window;
|
||||
|
||||
let ret = isWindow ? target[prop] : target[method];
|
||||
// ie6,7,8 standard mode
|
||||
if (isWindow && typeof ret !== 'number') {
|
||||
ret = window.document.documentElement[method];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getTargetRect(target) {
|
||||
return target !== window ?
|
||||
target.getBoundingClientRect() :
|
||||
{ top: 0, left: 0, bottom: 0 };
|
||||
}
|
||||
|
||||
function getOffset(element: HTMLElement, target) {
|
||||
function getOffset(element, target) {
|
||||
const elemRect = element.getBoundingClientRect();
|
||||
const targetRect = getTargetRect(target);
|
||||
|
||||
@@ -31,42 +44,19 @@ function getOffset(element: HTMLElement, target) {
|
||||
};
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
|
||||
function getDefaultTarget() {
|
||||
return typeof window !== 'undefined' ?
|
||||
window : null;
|
||||
};
|
||||
|
||||
// Affix
|
||||
export interface AffixProps {
|
||||
/**
|
||||
* 距离窗口顶部达到指定偏移量后触发
|
||||
*/
|
||||
offsetTop?: number;
|
||||
offset?: number;
|
||||
/** 距离窗口底部达到指定偏移量后触发 */
|
||||
offsetBottom?: number;
|
||||
style?: React.CSSProperties;
|
||||
/** 固定状态改变时触发的回调函数 */
|
||||
onChange?: (affixed?: boolean) => void;
|
||||
/** 设置 Affix 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 */
|
||||
target?: () => Window | HTMLElement;
|
||||
prefixCls?: string;
|
||||
}
|
||||
|
||||
export default class Affix extends React.Component<AffixProps, any> {
|
||||
export default class Affix extends React.Component {
|
||||
static propTypes = {
|
||||
offsetTop: React.PropTypes.number,
|
||||
offsetBottom: React.PropTypes.number,
|
||||
target: React.PropTypes.func,
|
||||
};
|
||||
}
|
||||
|
||||
scrollEvent: any;
|
||||
resizeEvent: any;
|
||||
refs: {
|
||||
fixedNode: HTMLElement;
|
||||
};
|
||||
static defaultProps = {
|
||||
target() {
|
||||
return window;
|
||||
},
|
||||
onChange() {},
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -77,7 +67,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
}
|
||||
|
||||
setAffixStyle(e, affixStyle) {
|
||||
const { onChange = noop, target = getDefaultTarget } = this.props;
|
||||
const { onChange, target } = this.props;
|
||||
const originalAffixStyle = this.state.affixStyle;
|
||||
const isWindow = target() === window;
|
||||
if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) {
|
||||
@@ -107,23 +97,19 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
}
|
||||
|
||||
updatePosition = (e) => {
|
||||
let { offsetTop, offsetBottom, offset, target = getDefaultTarget } = this.props;
|
||||
let { offsetTop, offsetBottom, offset, target } = this.props;
|
||||
const targetNode = target();
|
||||
|
||||
// Backwards support
|
||||
offsetTop = offsetTop || offset;
|
||||
const scrollTop = getScroll(targetNode, true);
|
||||
const affixNode = ReactDOM.findDOMNode(this) as HTMLElement;
|
||||
const elemOffset = getOffset(affixNode, targetNode);
|
||||
const elemOffset = getOffset(ReactDOM.findDOMNode(this), targetNode);
|
||||
const elemSize = {
|
||||
width: this.refs.fixedNode.offsetWidth,
|
||||
height: this.refs.fixedNode.offsetHeight,
|
||||
};
|
||||
|
||||
const offsetMode = {
|
||||
top: false,
|
||||
bottom: false,
|
||||
};
|
||||
const offsetMode = {};
|
||||
// Default to `offsetTop=0`.
|
||||
if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') {
|
||||
offsetMode.top = true;
|
||||
@@ -134,19 +120,18 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
}
|
||||
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const targetInnerHeight =
|
||||
(targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight;
|
||||
const targetInnerHeight = targetNode.innerHeight || targetNode.clientHeight;
|
||||
if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) {
|
||||
// Fixed Top
|
||||
this.setAffixStyle(e, {
|
||||
position: 'fixed',
|
||||
top: targetRect.top + offsetTop,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width: affixNode.offsetWidth,
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle(e, {
|
||||
width: affixNode.offsetWidth,
|
||||
height: affixNode.offsetHeight,
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
height: ReactDOM.findDOMNode(this).offsetHeight,
|
||||
});
|
||||
} else if (
|
||||
scrollTop < elemOffset.top + elemSize.height + offsetBottom - targetInnerHeight &&
|
||||
@@ -158,11 +143,11 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
position: 'fixed',
|
||||
bottom: targetBottomOffet + offsetBottom,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width: affixNode.offsetWidth,
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle(e, {
|
||||
width: affixNode.offsetWidth,
|
||||
height: affixNode.offsetHeight,
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
height: ReactDOM.findDOMNode(this).offsetHeight,
|
||||
});
|
||||
} else {
|
||||
this.setAffixStyle(e, null);
|
||||
@@ -171,7 +156,9 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const target = this.props.target || getDefaultTarget;
|
||||
warning(!('offset' in this.props), '`offset` prop of Affix is deprecated, use `offsetTop` instead.');
|
||||
|
||||
const target = this.props.target;
|
||||
this.setTargetEventListeners(target);
|
||||
}
|
||||
|
||||
@@ -205,10 +192,13 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
|
||||
render() {
|
||||
const className = classNames({
|
||||
[this.props.prefixCls || 'ant-affix']: this.state.affixStyle,
|
||||
'ant-affix': this.state.affixStyle,
|
||||
});
|
||||
|
||||
const props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target']);
|
||||
const props = { ...this.props };
|
||||
delete props.offsetTop;
|
||||
delete props.offsetBottom;
|
||||
delete props.target;
|
||||
|
||||
return (
|
||||
<div {...props} style={this.state.placeholderStyle}>
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 固钉
|
||||
chinese: 固钉
|
||||
type: Other
|
||||
title: Affix
|
||||
english: Affix
|
||||
---
|
||||
|
||||
将页面元素钉在可视范围。
|
||||
@@ -15,17 +15,10 @@ title: Affix
|
||||
|
||||
## API
|
||||
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 |
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | Number | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | Number | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |
|
||||
| onChange | 固定状态改变时触发的回调函数 | Function(affixed) | 无 |
|
||||
|
||||
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
|
||||
|
||||
```jsx
|
||||
<Affix style={{ position: 'absolute', top: y, left: x}}>
|
||||
...
|
||||
</Affix>
|
||||
```
|
||||
| onChange | 固定状态改变时触发的回调函数 | Function | 无 |
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
.@{ant-prefix}-affix {
|
||||
.ant-affix {
|
||||
position: fixed;
|
||||
z-index: @zindex-affix;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 顶部公告
|
||||
en-US: Banner
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用作顶部公告时,默认有图标,`type` 为 'warning',并有特殊样式。
|
||||
|
||||
## en-US
|
||||
|
||||
When `Alert` is used as banner, it has particular style, Icon and `type`(warning) are specified by default.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Alert message="Warning text" banner />
|
||||
<br />
|
||||
<Alert message="Very long warning text warning text text text text text text text" banner closable />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,22 +1,13 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
title: 基本
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
最简单的用法,适用于简短的警告提示。
|
||||
|
||||
## en-US
|
||||
|
||||
The simplest usage for short messages.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Alert message="Success Text" type="success" />
|
||||
ReactDOM.render(<Alert message="成功提示的文案" type="success" />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,33 +1,25 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 可关闭的警告提示
|
||||
en-US: Closable
|
||||
title: 可关闭的警告提示
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
显示关闭按钮,点击可关闭警告提示。
|
||||
|
||||
## en-US
|
||||
|
||||
To show close button.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
const onClose = function (e) {
|
||||
console.log(e, 'I was closed.');
|
||||
console.log(e, '我要被关闭啦!');
|
||||
};
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Alert message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
|
||||
<Alert message="警告提示的文案"
|
||||
type="warning"
|
||||
closable
|
||||
onClose={onClose}
|
||||
/>
|
||||
<Alert message="Error Text"
|
||||
description="Error Description Error Description Error Description Error Description Error Description Error Description"
|
||||
<Alert message="错误提示的文案"
|
||||
description="错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍"
|
||||
type="error"
|
||||
closable
|
||||
onClose={onClose}
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 自定义关闭
|
||||
en-US: Customized Close Text
|
||||
title: 自定义关闭
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`。
|
||||
|
||||
## en-US
|
||||
|
||||
Replace the default icon with customized text.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Alert message="Info Text" type="info" closeText="Close Now" />
|
||||
<Alert message="消息提示的文案" type="info" closeText="不再提醒" />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,40 +1,30 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 含有辅助性文字介绍
|
||||
en-US: Description
|
||||
title: 含有辅助性文字介绍
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
含有辅助性文字介绍的警告提示。
|
||||
|
||||
## en-US
|
||||
|
||||
Additional description for alert message.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Alert
|
||||
message="Success Text"
|
||||
description="Success Description Success Description Success Description"
|
||||
<Alert message="成功提示的文案"
|
||||
description="成功提示的辅助性文字介绍成功提示的辅助性文字介绍成功提示的辅助性文字介绍成功提示的辅助性文字介绍"
|
||||
type="success"
|
||||
/>
|
||||
<Alert
|
||||
message="Info Text"
|
||||
description="Info Description Info Description Info Description Info Description"
|
||||
<Alert message="消息提示的文案"
|
||||
description="消息提示的辅助性文字介绍消息提示的辅助性文字介绍消息提示的辅助性文字介绍"
|
||||
type="info"
|
||||
/>
|
||||
<Alert
|
||||
message="Warning Text"
|
||||
description="Warning Description Warning Description Warning Description Warning Description"
|
||||
message="警告提示的文案"
|
||||
description="警告提示的辅助性文字介绍警告提示的辅助性文字介绍"
|
||||
type="warning"
|
||||
/>
|
||||
<Alert
|
||||
message="Error Text"
|
||||
description="Error Description Error Description Error Description Error Description"
|
||||
message="错误提示的文案"
|
||||
description="错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍"
|
||||
type="error"
|
||||
/>
|
||||
</div>, mountNode);
|
||||
|
||||
@@ -1,47 +1,37 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 图标
|
||||
en-US: Icon
|
||||
title: 图标
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可口的图标让信息类型更加醒目。
|
||||
|
||||
## en-US
|
||||
|
||||
Decent icon make information more clear and more friendly.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Alert message="Success Tips" type="success" showIcon />
|
||||
<Alert message="Informational Notes" type="info" showIcon />
|
||||
<Alert message="Warning" type="warning" showIcon />
|
||||
<Alert message="Error" type="error" showIcon />
|
||||
<Alert
|
||||
message="success tips"
|
||||
description="Detailed description and advices about successful copywriting."
|
||||
<Alert message="成功提示的文案" type="success" showIcon />
|
||||
<Alert message="消息提示的文案" type="info" showIcon />
|
||||
<Alert message="警告提示的文案" type="warning" showIcon />
|
||||
<Alert message="错误提示的文案" type="error" showIcon />
|
||||
<Alert message="成功提示的文案"
|
||||
description="成功提示的辅助性文字介绍成功提示的辅助性文字介绍成功提示的辅助性文字介绍成功提示的辅助性文字介绍"
|
||||
type="success"
|
||||
showIcon
|
||||
/>
|
||||
<Alert
|
||||
message="Informational Notes"
|
||||
description="Additional description and informations about copywriting."
|
||||
<Alert message="消息提示的文案"
|
||||
description="消息提示的辅助性文字介绍消息提示的辅助性文字介绍消息提示的辅助性文字介绍"
|
||||
type="info"
|
||||
showIcon
|
||||
/>
|
||||
<Alert
|
||||
message="Warning"
|
||||
description="This is a warning notice about copywriting."
|
||||
message="警告提示的文案"
|
||||
description="警告提示的辅助性文字介绍警告提示的辅助性文字介绍"
|
||||
type="warning"
|
||||
showIcon
|
||||
/>
|
||||
<Alert
|
||||
message="Error"
|
||||
description="This is an error message about copywriting."
|
||||
message="错误提示的文案"
|
||||
description="错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍错误提示的辅助性文字介绍"
|
||||
type="error"
|
||||
showIcon
|
||||
/>
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 四种样式
|
||||
en-US: More types
|
||||
title: 四种样式
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
共有四种样式 `success`、`info`、`warning`、`error`。
|
||||
|
||||
## en-US
|
||||
|
||||
There are 4 types of Alert: `success`, `info`, `warning`, `error`.
|
||||
|
||||
````jsx
|
||||
import { Alert } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Alert message="Success Text" type="success" />
|
||||
<Alert message="Info Text" type="info" />
|
||||
<Alert message="Warning Text" type="warning" />
|
||||
<Alert message="Error Text" type="error" />
|
||||
<Alert message="成功提示的文案" type="success" />
|
||||
<Alert message="消息提示的文案" type="info" />
|
||||
<Alert message="警告提示的文案" type="warning" />
|
||||
<Alert message="错误提示的文案" type="error" />
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Views
|
||||
title: Alert
|
||||
---
|
||||
|
||||
Alert component for feedback.
|
||||
|
||||
## When To Use
|
||||
|
||||
- When you need to show alert messages for users.
|
||||
- When you need a persist static container, and closable by user actions.
|
||||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | Type of Alert styles, options:`success`, `info`, `warning`, `error` | String | `info` |
|
||||
| closable | Whether Alert can be closed | Boolean | - |
|
||||
| closeText | Close text to show | React.Node | - |
|
||||
| message | Content of Alert | React.Node | - |
|
||||
| description | Additional content of Alert | React.Node | - |
|
||||
| onClose | Callback when close Alert | Function | - |
|
||||
| showIcon | Whether to show icon | Boolean | false |
|
||||
| banner | Whether to show as banner | Boolean | false |
|
||||
53
components/alert/index.tsx → components/alert/index.jsx
Executable file → Normal file
53
components/alert/index.tsx → components/alert/index.jsx
Executable file → Normal file
@@ -4,35 +4,13 @@ import Animate from 'rc-animate';
|
||||
import Icon from '../icon';
|
||||
import classNames from 'classnames';
|
||||
|
||||
function noop() {}
|
||||
|
||||
export interface AlertProps {
|
||||
/**
|
||||
* Type of Alert styles, options:`success`, `info`, `warning`, `error`
|
||||
*/
|
||||
type?: 'success' | 'info' | 'warning' | 'error';
|
||||
/** Whether Alert can be closed */
|
||||
closable?: boolean;
|
||||
/** Close text to show */
|
||||
closeText?: React.ReactNode;
|
||||
/** Content of Alert */
|
||||
message: React.ReactNode;
|
||||
/** Additional content of Alert */
|
||||
description?: React.ReactNode;
|
||||
/** Callback when close Alert */
|
||||
onClose?: React.MouseEventHandler<any>;
|
||||
/** Whether to show icon */
|
||||
showIcon?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
banner?: boolean;
|
||||
}
|
||||
|
||||
export default class Alert extends React.Component<AlertProps, any> {
|
||||
export default class Alert extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-alert',
|
||||
showIcon: false,
|
||||
onClose() {},
|
||||
type: 'info',
|
||||
};
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -42,7 +20,7 @@ export default class Alert extends React.Component<AlertProps, any> {
|
||||
}
|
||||
handleClose = (e) => {
|
||||
e.preventDefault();
|
||||
let dom = ReactDOM.findDOMNode(this) as HTMLElement;
|
||||
let dom = ReactDOM.findDOMNode(this);
|
||||
dom.style.height = `${dom.offsetHeight}px`;
|
||||
// Magic code
|
||||
// 重复一次后才能正确设置 height
|
||||
@@ -51,7 +29,7 @@ export default class Alert extends React.Component<AlertProps, any> {
|
||||
this.setState({
|
||||
closing: false,
|
||||
});
|
||||
(this.props.onClose || noop)(e);
|
||||
this.props.onClose(e);
|
||||
}
|
||||
animationEnd = () => {
|
||||
this.setState({
|
||||
@@ -61,15 +39,9 @@ export default class Alert extends React.Component<AlertProps, any> {
|
||||
}
|
||||
render() {
|
||||
let {
|
||||
closable, description, type, prefixCls = 'ant-alert', message, closeText, showIcon, banner,
|
||||
className = '', style,
|
||||
closable, description, type, prefixCls, message, closeText, showIcon,
|
||||
} = this.props;
|
||||
|
||||
// banner模式默认有 Icon
|
||||
showIcon = showIcon || banner;
|
||||
// banner模式默认为警告
|
||||
type = banner ? 'warning' : type;
|
||||
|
||||
let iconType = '';
|
||||
switch (type) {
|
||||
case 'success':
|
||||
@@ -99,8 +71,6 @@ export default class Alert extends React.Component<AlertProps, any> {
|
||||
[`${prefixCls}-close`]: !this.state.closing,
|
||||
[`${prefixCls}-with-description`]: !!description,
|
||||
[`${prefixCls}-no-icon`]: !showIcon,
|
||||
[`${prefixCls}-banner`]: !!banner,
|
||||
[className]: !!className,
|
||||
});
|
||||
|
||||
// closeable when closeText is assigned
|
||||
@@ -109,14 +79,13 @@ export default class Alert extends React.Component<AlertProps, any> {
|
||||
}
|
||||
|
||||
return this.state.closed ? null : (
|
||||
<Animate
|
||||
component=""
|
||||
<Animate component=""
|
||||
showProp="data-show"
|
||||
transitionName={`${prefixCls}-slide-up`}
|
||||
onEnd={this.animationEnd}
|
||||
>
|
||||
<div data-show={this.state.closing} className={alertCls} style={style}>
|
||||
{showIcon ? <Icon className={`${prefixCls}-icon`} type={iconType} /> : null}
|
||||
<div data-show={this.state.closing} className={alertCls}>
|
||||
{showIcon ? <Icon className="ant-alert-icon" type={iconType} /> : null}
|
||||
<span className={`${prefixCls}-message`}>{message}</span>
|
||||
<span className={`${prefixCls}-description`}>{description}</span>
|
||||
{closable ? <a onClick={this.handleClose} className={`${prefixCls}-close-icon`}>
|
||||
25
components/alert/index.md
Normal file
25
components/alert/index.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 警告提示
|
||||
type: Views
|
||||
english: Alert
|
||||
---
|
||||
|
||||
警告提示,展现需要关注的信息。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 当某个页面需要向用户显示警告的信息时。
|
||||
- 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | 必选参数,指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | String | `info` |
|
||||
| closable | 可选参数,默认不显示关闭按钮 | Boolean | 无 |
|
||||
| closeText | 可选参数,自定义关闭按钮 | React.Node | 无 |
|
||||
| message | 必选参数,警告提示内容 | React.Node | 无 |
|
||||
| description | 可选参数,警告提示的辅助性文字介绍 | React.Node | 无 |
|
||||
| onClose | 可选参数,关闭时触发的回调函数 | Function | 无 |
|
||||
| showIcon | 可选参数,是否显示辅助图标 | Boolean | false |
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 警告提示
|
||||
type: Views
|
||||
title: Alert
|
||||
---
|
||||
|
||||
警告提示,展现需要关注的信息。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 当某个页面需要向用户显示警告的信息时。
|
||||
- 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | String | `info` |
|
||||
| closable | 默认不显示关闭按钮 | Boolean | 无 |
|
||||
| closeText | 自定义关闭按钮 | React.Node | 无 |
|
||||
| message | 警告提示内容 | React.Node | 无 |
|
||||
| description | 警告提示的辅助性文字介绍 | React.Node | 无 |
|
||||
| onClose | 关闭时触发的回调函数 | Function | 无 |
|
||||
| showIcon | 是否显示辅助图标 | Boolean | false |
|
||||
| banner | 是否用作顶部公告 | Boolean | false |
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
@alert-prefix-cls: ~"@{ant-prefix}-alert";
|
||||
@alert-prefix-cls: ant-alert;
|
||||
|
||||
.@{alert-prefix-cls} {
|
||||
position: relative;
|
||||
padding: 8px 48px 8px 38px;
|
||||
padding: 8px 8px 8px 16px;
|
||||
border-radius: @border-radius-base;
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&&-no-icon {
|
||||
padding: 8px 48px 8px 16px;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 14px;
|
||||
top: 9px;
|
||||
left: 16px;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: @font-size-base;
|
||||
font-size: 12px;
|
||||
color: @legend-color;
|
||||
line-height: 21px;
|
||||
display: none;
|
||||
}
|
||||
@@ -61,20 +58,21 @@
|
||||
}
|
||||
|
||||
&-close-icon {
|
||||
font-size: @font-size-base;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 10px;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
height: 12px;
|
||||
line-height: 12px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
.@{iconfont-css-prefix}-cross {
|
||||
.anticon-cross {
|
||||
color: @legend-color;
|
||||
transition: color .3s ease;
|
||||
&:hover {
|
||||
color: #404040;
|
||||
color: #444;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +83,7 @@
|
||||
}
|
||||
|
||||
&-with-description {
|
||||
padding: 16px 16px 16px 60px;
|
||||
padding: 16px 16px 16px 69px;
|
||||
position: relative;
|
||||
border-radius: @border-radius-base;
|
||||
margin-bottom: 10px;
|
||||
@@ -99,24 +97,24 @@
|
||||
|
||||
&-with-description &-icon {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 20px;
|
||||
font-size: 24px;
|
||||
top: 50%;
|
||||
left: 24px;
|
||||
margin-top: -15px;
|
||||
font-size: 29px;
|
||||
}
|
||||
|
||||
&-with-description &-close-icon {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
top: 17px;
|
||||
right: 16px;
|
||||
cursor: pointer;
|
||||
font-size: @font-size-base;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-with-description &-message {
|
||||
font-size: 14px;
|
||||
color: @heading-color;
|
||||
color: @text-color;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&-with-description &-description {
|
||||
@@ -136,12 +134,6 @@
|
||||
animation: antAlertSlideUpOut .3s @ease-in-out-circ;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
&-banner {
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antAlertSlideUpIn {
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本使用
|
||||
en-US: Basic Usage
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
基本使用。通过 dataSource 设置自动完成的数据源
|
||||
|
||||
## en-US
|
||||
|
||||
Basic Usage, set datasource of autocomplete with `dataSource` property.
|
||||
|
||||
````jsx
|
||||
import { AutoComplete } from 'antd';
|
||||
|
||||
function onSelect(value) {
|
||||
console.log('onSelect', value);
|
||||
}
|
||||
|
||||
const Complete = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
dataSource: [],
|
||||
};
|
||||
},
|
||||
handleChange(value) {
|
||||
this.setState({
|
||||
dataSource: !value ? [] : [
|
||||
value,
|
||||
value + value,
|
||||
value + value + value,
|
||||
],
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const { dataSource } = this.state;
|
||||
return (
|
||||
<AutoComplete
|
||||
dataSource={dataSource}
|
||||
style={{ width: 200 }}
|
||||
onSelect={onSelect}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 自定义选项
|
||||
en-US: Customized
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
也可以直接传 `AutoComplete.Option` 作为 `AutoComplete` 的 `children`,而非使用 `dataSource`。
|
||||
|
||||
## en-US
|
||||
|
||||
You could pass `AutoComplete.Option` as children of `AutoComplete`, instead of using `dataSource`。
|
||||
|
||||
````jsx
|
||||
import { AutoComplete } from 'antd';
|
||||
|
||||
const Option = AutoComplete.Option;
|
||||
|
||||
const Complete = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
result: [],
|
||||
};
|
||||
},
|
||||
handleChange(value) {
|
||||
let result;
|
||||
if (!value || value.indexOf('@') >= 0) {
|
||||
result = [];
|
||||
} else {
|
||||
result = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
|
||||
}
|
||||
this.setState({ result });
|
||||
},
|
||||
render() {
|
||||
const { result } = this.state;
|
||||
const children = result.map((email) => {
|
||||
return <Option key={email}>{email}</Option>;
|
||||
});
|
||||
return (
|
||||
<AutoComplete
|
||||
style={{ width: 200 }}
|
||||
onChange={this.handleChange}
|
||||
>
|
||||
{children}
|
||||
</AutoComplete>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Form Controls
|
||||
cols: 1
|
||||
title: AutoComplete
|
||||
---
|
||||
|
||||
Autocomplete function of input field.
|
||||
|
||||
## When To Use
|
||||
|
||||
When need to use autocomplete function.
|
||||
|
||||
## API
|
||||
|
||||
```jsx
|
||||
const dataSource = ['12345', '23456', '34567'];
|
||||
<AutoComplete dataSource={dataSource} />
|
||||
```
|
||||
Since `AutoComplete` is based on `Select`, so besides following API, `AutoComplete` has same API as `Select`.
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------------|----------------------------------|------------|--------|
|
||||
| dataSource | Data source for autocomplete | Array | |
|
||||
| value | selected option | String/Array<String>/{key: String, label: React.Node}/Array<{key, label}> | - |
|
||||
| defaultValue | Initial selected option. | string/Array<String> | - |
|
||||
| allowClear | Show clear button, effective in multiple mode only. | boolean | false |
|
||||
| onChange | Called when select an option or input value change, or value of input is changed | function(value, label) | - |
|
||||
| onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - |
|
||||
| disabled | Whether disabled select | boolean | false |
|
||||
@@ -1,84 +0,0 @@
|
||||
import React from 'react';
|
||||
import Select, { OptionProps, OptGroupProps } from '../select';
|
||||
import { Option, OptGroup } from 'rc-select';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface SelectedValue {
|
||||
key: string;
|
||||
label: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface DataSourceItemObject { value: string; text: string; };
|
||||
export type DataSourceItemType = string | DataSourceItemObject;
|
||||
|
||||
export interface AutoCompleteProps {
|
||||
size?: 'large' | 'small' | 'default';
|
||||
className?: string;
|
||||
notFoundContent?: Element;
|
||||
dataSource: DataSourceItemType[];
|
||||
prefixCls?: string;
|
||||
transitionName?: string;
|
||||
optionLabelProp?: string;
|
||||
choiceTransitionName?: string;
|
||||
showSearch?: boolean;
|
||||
defaultValue?: string | Array<any> | SelectedValue | Array<SelectedValue>;
|
||||
value?: string | Array<any> | SelectedValue | Array<SelectedValue>;
|
||||
allowClear?: boolean;
|
||||
onChange?: (value: string | Array<any> | SelectedValue | Array<SelectedValue>) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export default class AutoComplete extends React.Component<AutoCompleteProps, any> {
|
||||
static Option = Option as React.ClassicComponentClass<OptionProps>;
|
||||
static OptGroup = OptGroup as React.ClassicComponentClass<OptGroupProps>;
|
||||
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-select',
|
||||
transitionName: 'slide-up',
|
||||
optionLabelProp: 'children',
|
||||
choiceTransitionName: 'zoom',
|
||||
showSearch: false,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
antLocale: React.PropTypes.object,
|
||||
};
|
||||
|
||||
render() {
|
||||
let {
|
||||
size, className = '', notFoundContent, prefixCls, optionLabelProp, dataSource, children,
|
||||
} = this.props;
|
||||
|
||||
const cls = classNames({
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
[className]: !!className,
|
||||
[`${prefixCls}-show-search`]: true,
|
||||
});
|
||||
|
||||
const options = children || (dataSource ? dataSource.map((item) => {
|
||||
switch (typeof item) {
|
||||
case 'string':
|
||||
return <Option key={item}>{item}</Option>;
|
||||
case 'object':
|
||||
return (
|
||||
<Option key={(item as DataSourceItemObject).value}>
|
||||
{(item as DataSourceItemObject).text}
|
||||
</Option>
|
||||
);
|
||||
default:
|
||||
throw new Error('AutoComplete[dataSource] only supports type `string[] | Object[]`.');
|
||||
}
|
||||
}) : []);
|
||||
|
||||
return (
|
||||
<Select {...this.props}
|
||||
className={cls}
|
||||
optionLabelProp={optionLabelProp}
|
||||
combobox
|
||||
notFoundContent={notFoundContent} >
|
||||
{options}
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 自动完成
|
||||
type: Form Controls
|
||||
cols: 1
|
||||
title: AutoComplete
|
||||
---
|
||||
|
||||
输入框自动完成功能。
|
||||
|
||||
## 何时使用
|
||||
|
||||
需要自动完成时。
|
||||
|
||||
## API
|
||||
|
||||
```jsx
|
||||
const dataSource = ['12345', '23456', '34567'];
|
||||
<AutoComplete dataSource={dataSource} />
|
||||
```
|
||||
因为 `AutoComplete` 是基于 `Select` 封装的,所以除了以下 API 外,`AutoComplete` 跟 `Select` 拥有一样的 API。
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------------|----------------------------------|------------|---------|
|
||||
| dataSource | 自动完成的数据源 | Array | |
|
||||
| value | 指定当前选中的条目 | String/Array<String>/{key: String, label: React.Node}/Array<{key, label}> | 无 |
|
||||
| defaultValue | 指定默认选中的条目 | String/Array<String>/{key: String, label: React.Node}/Array<{key, label}> | 无 |
|
||||
| allowClear | 支持清除, 单选模式有效 | boolean | false |
|
||||
| onChange | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) | 无 |
|
||||
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
@@ -1,4 +0,0 @@
|
||||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
|
||||
import '../../select/style';
|
||||
@@ -1,26 +1,17 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
title: 基本
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
最简单的用法。
|
||||
|
||||
## en-US
|
||||
|
||||
The most basic usage.
|
||||
|
||||
````jsx
|
||||
import { BackTop } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<BackTop />
|
||||
Scroll down to see the bottom right <strong>gray</strong> button.
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
向下滚动后,见右下角灰色按钮
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,45 +1,30 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 自定义样式
|
||||
en-US: Custom style
|
||||
title: 自定义样式
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以自定义回到顶部按钮的样式,限制宽高:`40px * 40px`。
|
||||
|
||||
## en-US
|
||||
|
||||
You can customize the style of the button, just note the size limit: no more than `40px * 40px`.
|
||||
|
||||
|
||||
````jsx
|
||||
import { BackTop } from 'antd';
|
||||
|
||||
const style = {
|
||||
height: 40,
|
||||
width: 40,
|
||||
lineHeight: '40px',
|
||||
borderRadius: 4,
|
||||
backgroundColor: '#57c5f7',
|
||||
color: '#fff',
|
||||
textAlign: 'center',
|
||||
fontSize: 20,
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<BackTop>
|
||||
<div className="ant-back-top-inner">UP</div>
|
||||
<BackTop style={{ bottom: 100 }}>
|
||||
<div style={style}>UP</div>
|
||||
</BackTop>
|
||||
Scroll down to see the bottom right <strong>blue</strong> button.
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
````
|
||||
|
||||
````css
|
||||
#components-back-top-demo-custom .ant-back-top {
|
||||
bottom: 100px;
|
||||
}
|
||||
#components-back-top-demo-custom .ant-back-top-inner {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
line-height: 40px;
|
||||
border-radius: 4px;
|
||||
background-color: #57c5f7;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
向下滚动后,见右下角蓝色按钮
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Other
|
||||
title: BackTop
|
||||
---
|
||||
|
||||
`BackTop` makes it easy to go back to the top of the page.
|
||||
|
||||
## When To Use
|
||||
|
||||
- When the page content is very long.
|
||||
- When you need to go back to the top very frequently in order to view the contents.
|
||||
|
||||
## API
|
||||
|
||||
> The distance to the bottom is set to `50px` by default, which is overridable.
|
||||
|
||||
> If you decide to use custom styles, please note the size limit: no more than `40px * 40px`.
|
||||
|
||||
|
||||
Property | Description | Type | Default
|
||||
-----|-----|-----|------
|
||||
visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | Number | 400
|
||||
onClick | a callback function, which can be executed when you click the button | Function | -
|
||||
|
||||
114
components/back-top/index.jsx
Normal file
114
components/back-top/index.jsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
import Animate from 'rc-animate';
|
||||
import Icon from '../icon';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'object.omit';
|
||||
|
||||
function getScroll(target, top) {
|
||||
if (typeof window === 'undefined') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const prop = top ? 'pageYOffset' : 'pageXOffset';
|
||||
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||
const isWindow = target === window;
|
||||
|
||||
let ret = isWindow ? target[prop] : target[method];
|
||||
// ie6,7,8 standard mode
|
||||
if (isWindow && typeof ret !== 'number') {
|
||||
ret = window.document.documentElement[method];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export default class BackTop extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
visibilityHeight: React.PropTypes.number,
|
||||
target: React.PropTypes.func,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
onClick() {},
|
||||
visibilityHeight: 400,
|
||||
target() {
|
||||
return window;
|
||||
},
|
||||
prefixCls: 'ant-back-top',
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const scrollTop = getScroll(props.target(), true);
|
||||
this.state = {
|
||||
visible: scrollTop > props.visibilityHeight,
|
||||
};
|
||||
}
|
||||
|
||||
scrollToTop = (e) => {
|
||||
if (e) e.preventDefault();
|
||||
this.setScrollTop(0);
|
||||
this.props.onClick(e);
|
||||
}
|
||||
|
||||
setScrollTop(value) {
|
||||
const targetNode = this.props.target();
|
||||
if (targetNode === window) {
|
||||
document.body.scrollTop = value;
|
||||
document.documentElement.scrollTop = value;
|
||||
} else {
|
||||
targetNode.scrollTop = value;
|
||||
}
|
||||
}
|
||||
|
||||
handleScroll = () => {
|
||||
const { visibilityHeight, target } = this.props;
|
||||
const scrollTop = getScroll(target(), true);
|
||||
this.setState({
|
||||
visible: scrollTop > visibilityHeight,
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.scrollEvent = addEventListener(this.props.target(), 'scroll', this.handleScroll);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.scrollEvent) {
|
||||
this.scrollEvent.remove();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, className, children, ...otherProps } = this.props;
|
||||
const classString = classNames({
|
||||
[prefixCls]: true,
|
||||
[className]: !!className,
|
||||
});
|
||||
|
||||
const defaultElement = (
|
||||
<div className={`${prefixCls}-content`}>
|
||||
<Icon className={`${prefixCls}-icon`} type="to-top" />
|
||||
</div>
|
||||
);
|
||||
|
||||
// fix https://fb.me/react-unknown-prop
|
||||
const divProps = omit(otherProps, [
|
||||
'visibilityHeight',
|
||||
]);
|
||||
|
||||
return (
|
||||
<Animate component="" transitionName="fade">
|
||||
{
|
||||
this.state.visible ?
|
||||
<div {...divProps} className={classString} onClick={this.scrollToTop}>
|
||||
{children || defaultElement}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</Animate>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 回到顶部
|
||||
type: Other
|
||||
subtitle: 回到顶部
|
||||
title: BackTop
|
||||
english: BackTop
|
||||
---
|
||||
|
||||
返回页面顶部的操作按钮。
|
||||
@@ -15,7 +15,6 @@ title: BackTop
|
||||
## API
|
||||
|
||||
> 有默认样式,距离底部 `50px`,可覆盖。
|
||||
|
||||
> 自定义样式宽高不大于 40px * 40px。
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
@@ -1,133 +0,0 @@
|
||||
import React from 'react';
|
||||
import Animate from 'rc-animate';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import Icon from '../icon';
|
||||
import getScroll from '../_util/getScroll';
|
||||
import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
const currentScrollTop = () => {
|
||||
return window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
|
||||
};
|
||||
|
||||
const easeInOutCubic = (t, b, c, d) => {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return cc / 2 * t * t * t + b;
|
||||
} else {
|
||||
return cc / 2 * ((t -= 2) * t * t + 2) + b;
|
||||
}
|
||||
};
|
||||
|
||||
function noop() {}
|
||||
|
||||
function getDefaultTarget() {
|
||||
return typeof window !== 'undefined' ?
|
||||
window : null;
|
||||
}
|
||||
|
||||
export interface BackTopProps {
|
||||
visibilityHeight?: number;
|
||||
onClick?: React.MouseEventHandler<any>;
|
||||
target?: () => HTMLElement | Window;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
static defaultProps = {
|
||||
visibilityHeight: 400,
|
||||
};
|
||||
|
||||
scrollEvent: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
visible: false,
|
||||
};
|
||||
}
|
||||
|
||||
scrollToTop = (e) => {
|
||||
const scrollTop = currentScrollTop();
|
||||
const startTime = Date.now();
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
const time = timestamp - startTime;
|
||||
this.setScrollTop(easeInOutCubic(time, scrollTop, 0, 450));
|
||||
if (time < 450) {
|
||||
reqAnimFrame(frameFunc);
|
||||
}
|
||||
};
|
||||
reqAnimFrame(frameFunc);
|
||||
(this.props.onClick || noop)(e);
|
||||
}
|
||||
|
||||
setScrollTop(value) {
|
||||
const targetNode = (this.props.target || getDefaultTarget)();
|
||||
if (targetNode === window) {
|
||||
document.body.scrollTop = value;
|
||||
document.documentElement.scrollTop = value;
|
||||
} else {
|
||||
(targetNode as HTMLElement).scrollTop = value;
|
||||
}
|
||||
}
|
||||
|
||||
handleScroll = () => {
|
||||
const { visibilityHeight, target = getDefaultTarget } = this.props;
|
||||
const scrollTop = getScroll(target(), true);
|
||||
this.setState({
|
||||
visible: scrollTop > visibilityHeight,
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleScroll();
|
||||
this.scrollEvent = addEventListener((this.props.target || getDefaultTarget)(), 'scroll', this.handleScroll);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.scrollEvent) {
|
||||
this.scrollEvent.remove();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls = 'ant-back-top', className = '', children } = this.props;
|
||||
const classString = classNames({
|
||||
[prefixCls]: true,
|
||||
[className]: !!className,
|
||||
});
|
||||
|
||||
const defaultElement = (
|
||||
<div className={`${prefixCls}-content`}>
|
||||
<Icon className={`${prefixCls}-icon`} type="to-top" />
|
||||
</div>
|
||||
);
|
||||
|
||||
// fix https://fb.me/react-unknown-prop
|
||||
const divProps = omit(this.props, [
|
||||
'prefixCls',
|
||||
'className',
|
||||
'children',
|
||||
'visibilityHeight',
|
||||
]);
|
||||
|
||||
return (
|
||||
<Animate component="" transitionName="fade">
|
||||
{
|
||||
this.state.visible ?
|
||||
<div {...divProps} className={classString} onClick={this.scrollToTop}>
|
||||
{children || defaultElement}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
</Animate>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
@backtop-prefix-cls: ~"@{ant-prefix}-back-top";
|
||||
@backtop-prefix-cls: ant-back-top;
|
||||
|
||||
.@{backtop-prefix-cls} {
|
||||
z-index: @zindex-back-top;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
import { createElement, Component } from 'react';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import React, { createElement } from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import isCssAnimationSupported from '../_util/isCssAnimationSupported';
|
||||
import assign from 'object-assign';
|
||||
import omit from 'omit.js';
|
||||
import omit from 'object.omit';
|
||||
|
||||
function getNumberArray(num) {
|
||||
return num ?
|
||||
@@ -13,26 +11,24 @@ function getNumberArray(num) {
|
||||
.map(i => Number(i)) : [];
|
||||
}
|
||||
|
||||
export interface ScrollNumberProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
count?: string | number;
|
||||
component?: string;
|
||||
onAnimated?: Function;
|
||||
height?: number;
|
||||
style: React.CSSProperties;
|
||||
}
|
||||
|
||||
export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
export default class ScrollNumber extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-scroll-number',
|
||||
count: null,
|
||||
onAnimated() {
|
||||
},
|
||||
component: 'sup',
|
||||
onAnimated() {},
|
||||
height: 18,
|
||||
};
|
||||
}
|
||||
|
||||
lastCount: any;
|
||||
static propTypes = {
|
||||
count: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.number,
|
||||
]),
|
||||
component: React.PropTypes.string,
|
||||
onAnimated: React.PropTypes.func,
|
||||
height: React.PropTypes.number,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -84,10 +80,7 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
animateStarted: false,
|
||||
count: nextProps.count,
|
||||
}, () => {
|
||||
const onAnimated = this.props.onAnimated;
|
||||
if (onAnimated) {
|
||||
onAnimated();
|
||||
}
|
||||
this.props.onAnimated();
|
||||
});
|
||||
}, 5);
|
||||
});
|
||||
@@ -95,10 +88,10 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
}
|
||||
|
||||
renderNumberList(position) {
|
||||
const childrenToReturn: React.ReactElement<any>[] = [];
|
||||
const childrenToReturn = [];
|
||||
for (let i = 0; i < 30; i++) {
|
||||
const currentClassName = (position === i) ? 'current' : '';
|
||||
childrenToReturn.push(<p key={i.toString()} className={currentClassName}>{i % 10}</p>);
|
||||
const currentClassName = (position === i) ? 'current' : null;
|
||||
childrenToReturn.push(<p key={i} className={currentClassName}>{i % 10}</p>);
|
||||
}
|
||||
return childrenToReturn;
|
||||
}
|
||||
@@ -130,17 +123,18 @@ export default class ScrollNumber extends Component<ScrollNumberProps, any> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { component, prefixCls, className, ...otherProps } = this.props;
|
||||
// fix https://fb.me/react-unknown-prop
|
||||
const props = assign({}, omit(this.props, [
|
||||
const restProps = omit(otherProps, [
|
||||
'count',
|
||||
'onAnimated',
|
||||
'component',
|
||||
'prefixCls',
|
||||
]), {
|
||||
className: `${this.props.prefixCls} ${this.props.className}`,
|
||||
});
|
||||
]);
|
||||
const props = {
|
||||
...restProps,
|
||||
className: `${prefixCls} ${className}`,
|
||||
};
|
||||
return createElement(
|
||||
this.props.component || 'sup',
|
||||
component,
|
||||
props,
|
||||
this.renderNumberElement()
|
||||
);
|
||||
@@ -1,27 +1,19 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 大数字
|
||||
en-US: Overflowed count
|
||||
title: 大数字
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
超过 99 的会显示为 `99+`。
|
||||
|
||||
## en-US
|
||||
|
||||
`99+` is displayed when count is larger than `99`.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Badge count={99}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<Badge count={200}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,30 +1,22 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
title: 基本
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
简单的徽章展示。
|
||||
|
||||
## en-US
|
||||
|
||||
Simplest Usage.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Badge count={5}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
.ant-badge:not(.ant-badge-status) {
|
||||
.ant-badge {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.head-example {
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 动态
|
||||
en-US: Dynamic
|
||||
title: 动态
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
展示动态变化的效果。
|
||||
|
||||
## en-US
|
||||
|
||||
The count will be animated as it changes.
|
||||
|
||||
````jsx
|
||||
import { Badge, Button, Icon } from 'antd';
|
||||
const ButtonGroup = Button.Group;
|
||||
@@ -44,10 +36,10 @@ const Test = React.createClass({
|
||||
return (
|
||||
<div>
|
||||
<Badge count={this.state.count}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<Badge dot={this.state.show}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<ButtonGroup>
|
||||
@@ -59,7 +51,7 @@ const Test = React.createClass({
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<Button type="ghost" onClick={this.onClick} style={{ marginLeft: 8 }}>
|
||||
Switch state
|
||||
切换红点显隐
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,5 +59,7 @@ const Test = React.createClass({
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
ReactDOM.render(
|
||||
<Test />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 讨嫌的小红点
|
||||
en-US: Red badge
|
||||
title: 讨嫌的小红点
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
没有具体的数字。
|
||||
|
||||
## en-US
|
||||
|
||||
This will simply display a red badge, without a specific count.
|
||||
|
||||
````jsx
|
||||
import { Badge, Icon } from 'antd';
|
||||
|
||||
@@ -21,7 +13,7 @@ ReactDOM.render(<div>
|
||||
<Icon type="notification" />
|
||||
</Badge>
|
||||
<Badge dot>
|
||||
<a href="#">Link something</a>
|
||||
<a href="#">一个链接</a>
|
||||
</Badge>
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 可点击
|
||||
en-US: Clickable
|
||||
title: 可点击
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用 a 标签进行包裹即可。
|
||||
|
||||
## en-US
|
||||
|
||||
The badge can be wrapped with `a` tag to make it linkable.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<a href="#">
|
||||
<Badge count={5}>
|
||||
<span className="head-example" />
|
||||
<span className="head-example"></span>
|
||||
</Badge>
|
||||
</a>
|
||||
, mountNode);
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 独立使用
|
||||
en-US: Standalone
|
||||
title: 独立使用
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
不包裹任何元素即是独立使用,可自定样式展现。
|
||||
|
||||
> 在右上角的 badge 则限定为红色。
|
||||
|
||||
## en-US
|
||||
|
||||
Used in standalone when children is empty.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 封顶数字
|
||||
en-US: Customized overflow count
|
||||
title: 封顶数字
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
超过 `overflowCount` 的会显示为 `${overflowCount}+`。
|
||||
|
||||
## en-US
|
||||
|
||||
`${overflowCount}+` is displayed when count is larger than `overflowCount`.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Badge count={99} overflowCount={10}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
<Badge count={1000} overflowCount={999}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
order: 7
|
||||
title:
|
||||
zh-CN: 状态点
|
||||
en-US: Status
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用于表示状态的小圆点。
|
||||
|
||||
## en-US
|
||||
|
||||
Standalone badge with status.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Badge status="success" />
|
||||
<Badge status="error" />
|
||||
<Badge status="default" />
|
||||
<Badge status="processing" />
|
||||
<Badge status="warning" />
|
||||
<br />
|
||||
<Badge status="success" text="Success" />
|
||||
<br />
|
||||
<Badge status="error" text="Error" />
|
||||
<br />
|
||||
<Badge status="default" text="Default" />
|
||||
<br />
|
||||
<Badge status="processing" text="Processing" />
|
||||
<br />
|
||||
<Badge status="warning" text="Warning" />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Views
|
||||
title: Badge
|
||||
---
|
||||
|
||||
Small numerical value or status descriptors for UI elements.
|
||||
|
||||
## When To Use
|
||||
|
||||
Badge normally appears in proximity to notification or head picture with eye-catching appeal, typically displaying unread messages count.
|
||||
|
||||
## API
|
||||
|
||||
```jsx
|
||||
<Badge count={5}>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
```
|
||||
|
||||
|
||||
```jsx
|
||||
<Badge count={5} />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------------|-------------------------|------------|---------|
|
||||
| count | Number to show in badge | Number | |
|
||||
| overflowCount | Max count to show | Number | 99 |
|
||||
| dot | whether to show red dot without number | Boolean | false |
|
||||
| status | Set Badge as a status dot | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' |
|
||||
| text | If `status` is set, `text` is to set the text of status dot | String | '' |
|
||||
64
components/badge/index.jsx
Normal file
64
components/badge/index.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import Animate from 'rc-animate';
|
||||
import ScrollNumber from './ScrollNumber';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default class Badge extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-badge',
|
||||
count: null,
|
||||
dot: false,
|
||||
overflowCount: 99,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
count: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.number,
|
||||
]),
|
||||
dot: React.PropTypes.bool,
|
||||
overflowCount: React.PropTypes.number,
|
||||
}
|
||||
|
||||
render() {
|
||||
let { count, prefixCls, overflowCount, className, style, children, dot, ...restProps } = this.props;
|
||||
|
||||
count = count > overflowCount ? `${overflowCount}+` : count;
|
||||
|
||||
// dot mode don't need count
|
||||
if (dot) {
|
||||
count = '';
|
||||
}
|
||||
|
||||
// null undefined "" "0" 0
|
||||
const hidden = (!count || count === '0') && !dot;
|
||||
const scrollNumberCls = prefixCls + (dot ? '-dot' : '-count');
|
||||
const badgeCls = classNames({
|
||||
[className]: !!className,
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-not-a-wrapper`]: !children,
|
||||
});
|
||||
|
||||
return (
|
||||
<span className={badgeCls} title={count} style={null} {...restProps}>
|
||||
{children}
|
||||
<Animate
|
||||
component=""
|
||||
showProp="data-show"
|
||||
transitionName={`${prefixCls}-zoom`}
|
||||
transitionAppear
|
||||
>
|
||||
{
|
||||
hidden ? null :
|
||||
<ScrollNumber
|
||||
data-show={!hidden}
|
||||
className={scrollNumberCls}
|
||||
count={count}
|
||||
style={style}
|
||||
/>
|
||||
}
|
||||
</Animate>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 徽标数
|
||||
chinese: 徽标数
|
||||
type: Views
|
||||
title: Badge
|
||||
english: Badge
|
||||
---
|
||||
|
||||
图标右上角的圆形徽标数字。
|
||||
@@ -15,7 +15,7 @@ title: Badge
|
||||
|
||||
```jsx
|
||||
<Badge count={5}>
|
||||
<a href="#" className="head-example" />
|
||||
<a href="#" className="head-example"></a>
|
||||
</Badge>
|
||||
```
|
||||
|
||||
@@ -28,6 +28,4 @@ title: Badge
|
||||
|----------------|----------------------------------|------------|---------|--------|
|
||||
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | Number | | |
|
||||
| overflowCount | 展示封顶的数字值 | Number | | 99 |
|
||||
| dot | 不展示数字,只有一个小红点 | Boolean | | false |
|
||||
| status | 设置 Badge 为状态点 | Enum | 'success'、'processing'、'default'、'error'、'warning' | '' |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | String | | '' |
|
||||
| dot | 不展示数字,只有一个小红点 | boolean | | false |
|
||||
@@ -1,112 +0,0 @@
|
||||
import React from 'react';
|
||||
import Animate from 'rc-animate';
|
||||
import ScrollNumber from './ScrollNumber';
|
||||
import classNames from 'classnames';
|
||||
import warning from '../_util/warning';
|
||||
import splitObject from '../_util/splitObject';
|
||||
|
||||
export interface BadgeProps {
|
||||
/** Number to show in badge */
|
||||
count: number | string;
|
||||
/** Max count to show */
|
||||
overflowCount?: number;
|
||||
/** whether to show red dot without number */
|
||||
dot?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
status?: 'success' | 'processing' | 'default' | 'error' | 'warning';
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export default class Badge extends React.Component<BadgeProps, any> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-badge',
|
||||
count: null,
|
||||
dot: false,
|
||||
overflowCount: 99,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
count: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.number,
|
||||
]),
|
||||
dot: React.PropTypes.bool,
|
||||
overflowCount: React.PropTypes.number,
|
||||
};
|
||||
|
||||
render() {
|
||||
let [{
|
||||
count, prefixCls, overflowCount, className, style, children, dot, status, text,
|
||||
}, restProps] = splitObject(
|
||||
this.props,
|
||||
['count', 'prefixCls', 'overflowCount', 'className', 'style', 'children', 'dot', 'status', 'text']
|
||||
);
|
||||
const isDot = dot || status;
|
||||
const realCount = count;
|
||||
count = count > overflowCount ? `${overflowCount}+` : count;
|
||||
|
||||
// dot mode don't need count
|
||||
if (isDot) {
|
||||
count = '';
|
||||
}
|
||||
|
||||
// null undefined "" "0" 0
|
||||
const hidden = (!count || count === '0') && !isDot;
|
||||
const scrollNumberCls = classNames({
|
||||
[`${prefixCls}-dot`]: isDot,
|
||||
[`${prefixCls}-count`]: !isDot,
|
||||
});
|
||||
const badgeCls = classNames({
|
||||
[className]: !!className,
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-status`]: !!status,
|
||||
[`${prefixCls}-not-a-wrapper`]: !children,
|
||||
});
|
||||
|
||||
warning(
|
||||
!(children && status),
|
||||
'`Badge[children]` and `Badge[status]` cannot be used at the same time.'
|
||||
);
|
||||
// <Badge status="success" />
|
||||
if (!children && status) {
|
||||
const statusCls = classNames({
|
||||
[`${prefixCls}-status-dot`]: !!status,
|
||||
[`${prefixCls}-status-${status}`]: true,
|
||||
});
|
||||
return (
|
||||
<span className={badgeCls}>
|
||||
<span className={statusCls} />
|
||||
<span className={`${prefixCls}-status-text`}>{text}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span {...restProps} className={badgeCls} title={realCount}>
|
||||
{children}
|
||||
<Animate
|
||||
component=""
|
||||
showProp="data-show"
|
||||
transitionName={children ? `${prefixCls}-zoom` : ''}
|
||||
transitionAppear
|
||||
>
|
||||
{
|
||||
hidden ? null :
|
||||
<ScrollNumber
|
||||
data-show={!hidden}
|
||||
className={scrollNumberCls}
|
||||
count={count}
|
||||
style={style}
|
||||
/>
|
||||
}
|
||||
</Animate>
|
||||
{
|
||||
hidden || !text ? null :
|
||||
<span className={`${prefixCls}-status-text`}>{text}</span>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
@badge-prefix-cls: ~"@{ant-prefix}-badge";
|
||||
@number-prefix-cls: ~"@{ant-prefix}-scroll-number";
|
||||
@badge-prefix-cls: ant-badge;
|
||||
@number-prefix-cls: ant-scroll-number;
|
||||
|
||||
.@{badge-prefix-cls} {
|
||||
position: relative;
|
||||
@@ -47,39 +47,6 @@
|
||||
box-shadow: 0 0 0 1px #fff;
|
||||
}
|
||||
|
||||
&-status {
|
||||
line-height: inherit;
|
||||
vertical-align: baseline;
|
||||
|
||||
&-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&-success {
|
||||
background-color: @success-color;
|
||||
}
|
||||
&-processing {
|
||||
background-color: @primary-color;
|
||||
animation: antStatusProcessing 1.2s infinite ease-in-out;
|
||||
}
|
||||
&-default {
|
||||
background-color: @normal-color;
|
||||
}
|
||||
&-error {
|
||||
background-color: @error-color;
|
||||
}
|
||||
&-warning {
|
||||
background-color: @warning-color;
|
||||
}
|
||||
&-text {
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&-zoom-appear,
|
||||
&-zoom-enter {
|
||||
animation: antZoomBadgeIn .3s @ease-out-back;
|
||||
@@ -95,17 +62,7 @@
|
||||
top: auto;
|
||||
display: block;
|
||||
position: relative;
|
||||
transform: none!important;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antStatusProcessing {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
72
components/breadcrumb/Breadcrumb.jsx
Normal file
72
components/breadcrumb/Breadcrumb.jsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import React, { cloneElement } from 'react';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
|
||||
const defaultNameRender = (breadcrumbName, route, params) => {
|
||||
if (!breadcrumbName) {
|
||||
return null;
|
||||
}
|
||||
const paramsKeys = Object.keys(params).join('|');
|
||||
const name = breadcrumbName.replace(
|
||||
new RegExp(`:(${paramsKeys})`, 'g'),
|
||||
(replacement, key) => params[key] || replacement
|
||||
);
|
||||
return <span>{name}</span>;
|
||||
};
|
||||
|
||||
export default class Breadcrumb extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-breadcrumb',
|
||||
separator: '/',
|
||||
linkRender: (href, name) => <a href={`#${href}`}>{name}</a>,
|
||||
nameRender: defaultNameRender,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
prefixCls: React.PropTypes.string,
|
||||
separator: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element,
|
||||
]),
|
||||
routes: React.PropTypes.array,
|
||||
params: React.PropTypes.object,
|
||||
linkRender: React.PropTypes.func,
|
||||
nameRender: React.PropTypes.func,
|
||||
}
|
||||
|
||||
render() {
|
||||
let crumbs;
|
||||
const { separator, prefixCls, routes, params, children, linkRender, nameRender } = this.props;
|
||||
if (routes && routes.length > 0) {
|
||||
const paths = [];
|
||||
const lastPath = routes.length - 1;
|
||||
crumbs = routes.map((route, i) => {
|
||||
route.path = route.path || '';
|
||||
let path = route.path.replace(/^\//, '');
|
||||
Object.keys(params).forEach(key => {
|
||||
path = path.replace(`:${key}`, params[key]);
|
||||
});
|
||||
if (path) {
|
||||
paths.push(path);
|
||||
}
|
||||
const name = nameRender(route.breadcrumbName, route, params);
|
||||
if (name) {
|
||||
const link = (i === lastPath) ? name : linkRender(`/${paths.join('/')}`, name, paths);
|
||||
return <BreadcrumbItem separator={separator} key={route.breadcrumbName || i}>{link}</BreadcrumbItem>;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
crumbs = React.Children.map(children, (element, index) => {
|
||||
return cloneElement(element, {
|
||||
separator,
|
||||
key: index,
|
||||
});
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div className={prefixCls}>
|
||||
{crumbs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
import React from 'react';
|
||||
import { cloneElement } from 'react';
|
||||
import warning from '../_util/warning';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
|
||||
export interface BreadcrumbProps {
|
||||
prefixCls?: string;
|
||||
routes?: Array<any>;
|
||||
params?: Object;
|
||||
separator?: string | React.ReactNode;
|
||||
itemRender?: (route: any, params: any, routes: Array<any>, paths: Array<string>) => React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
function getBreadcrumbName(route, params) {
|
||||
if (!route.breadcrumbName) {
|
||||
return null;
|
||||
}
|
||||
const paramsKeys = Object.keys(params).join('|');
|
||||
const name = route.breadcrumbName.replace(
|
||||
new RegExp(`:(${paramsKeys})`, 'g'),
|
||||
(replacement, key) => params[key] || replacement
|
||||
);
|
||||
return name;
|
||||
}
|
||||
|
||||
function defaultItemRender(route, params, routes, paths) {
|
||||
const isLastItem = routes.indexOf(route) === routes.length - 1;
|
||||
const name = getBreadcrumbName(route, params);
|
||||
return isLastItem
|
||||
? <span>{name}</span>
|
||||
: <a href={`#/${paths.join('/')}`}>{name}</a>;
|
||||
}
|
||||
|
||||
export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
|
||||
static Item: any;
|
||||
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-breadcrumb',
|
||||
separator: '/',
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
prefixCls: React.PropTypes.string,
|
||||
separator: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element,
|
||||
]),
|
||||
routes: React.PropTypes.array,
|
||||
params: React.PropTypes.object,
|
||||
linkRender: React.PropTypes.func,
|
||||
nameRender: React.PropTypes.func,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const props = this.props;
|
||||
warning(
|
||||
!('linkRender' in props || 'nameRender' in props),
|
||||
'`linkRender` and `nameRender` are removed, please use `itemRender` instead.'
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
let crumbs;
|
||||
const { separator, prefixCls, routes, params = {}, children, itemRender = defaultItemRender } = this.props;
|
||||
if (routes && routes.length > 0) {
|
||||
const paths: string[] = [];
|
||||
crumbs = routes.map((route) => {
|
||||
route.path = route.path || '';
|
||||
let path: string = route.path.replace(/^\//, '');
|
||||
Object.keys(params).forEach(key => {
|
||||
path = path.replace(`:${key}`, params[key]);
|
||||
});
|
||||
if (path) {
|
||||
paths.push(path);
|
||||
}
|
||||
if (route.breadcrumbName) {
|
||||
return (
|
||||
<BreadcrumbItem separator={separator} key={route.breadcrumbName}>
|
||||
{itemRender(route, params, routes, paths)}
|
||||
</BreadcrumbItem>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} else if (children) {
|
||||
crumbs = React.Children.map(children, (element: any, index) => {
|
||||
return cloneElement(element, {
|
||||
separator,
|
||||
key: index,
|
||||
});
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div className={prefixCls}>
|
||||
{crumbs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,10 @@
|
||||
import React from 'react';
|
||||
import splitObject from '../_util/splitObject';
|
||||
|
||||
export interface BreadcrumbItemProps {
|
||||
separator?: React.ReactNode;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps, any> {
|
||||
export default class BreadcrumbItem extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-breadcrumb',
|
||||
separator: '/',
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
prefixCls: React.PropTypes.string,
|
||||
@@ -19,12 +13,10 @@ export default class BreadcrumbItem extends React.Component<BreadcrumbItemProps,
|
||||
React.PropTypes.element,
|
||||
]),
|
||||
href: React.PropTypes.string,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const [{ prefixCls, separator, children }, restProps] = splitObject(
|
||||
this.props, ['prefixCls', 'separator', 'children']
|
||||
);
|
||||
const { prefixCls, separator, children, ...restProps } = this.props;
|
||||
let link;
|
||||
if ('href' in this.props) {
|
||||
link = <a className={`${prefixCls}-link`} {...restProps}>{children}</a>;
|
||||
@@ -29,7 +29,7 @@ const Apps = () => (
|
||||
</ul>
|
||||
);
|
||||
|
||||
const Home = props => (
|
||||
const Home = (props) => (
|
||||
<div>
|
||||
<div className="demo-nav">
|
||||
<Link to="/">Home</Link>
|
||||
|
||||
@@ -6,7 +6,7 @@ title: Breadcrumb
|
||||
|
||||
A breadcrumb displays the current location within a hierarchy. It allows going back to states higher up within the hierarchy.
|
||||
|
||||
## When To Use
|
||||
## When to use
|
||||
|
||||
- When the system has more than two layers in a hierarchy.
|
||||
- When you need to inform the user of where they are.
|
||||
@@ -28,6 +28,5 @@ A breadcrumb displays the current location within a hierarchy. It allows going b
|
||||
| routes | The routing stack information of router | Array | | - |
|
||||
| params | Routing parameter | Object | | - |
|
||||
| separator | Custom separator | String or Element | | '/' |
|
||||
| itemRender | Custom item renderer | (route, params, routes, paths) => React.ReactNode | | - |
|
||||
|
||||
> `linkRender` and `nameRender` were removed after `antd@2.0`, please use `itemRender` instead.
|
||||
| linkRender | Custom link function,and react-router configuration | Function(href, name) | | - |
|
||||
| nameRender | Custom link function,and react-router configuration | Function(name) | | - |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 面包屑
|
||||
chinese: 面包屑
|
||||
type: Navigation
|
||||
title: Breadcrumb
|
||||
english: Breadcrumb
|
||||
---
|
||||
|
||||
显示当前页面在系统层级结构中的位置,并能向上返回。
|
||||
@@ -29,6 +29,5 @@ title: Breadcrumb
|
||||
| routes | router 的路由栈信息 | Array | | - |
|
||||
| params | 路由的参数 | Object | | - |
|
||||
| separator | 分隔符自定义 | String or Element | | '/' |
|
||||
| itemRender | 自定义链接函数,和 react-router 配置使用 | (route, params, routes, paths) => React.ReactNode | | - |
|
||||
|
||||
> 2.0 之后,`linkRender` 和 `nameRender` 被移除,请使用 `itemRender` 来代替。
|
||||
| linkRender | 自定义链接函数,和 react-router 配置使用 | Function(href, name, paths) | | - |
|
||||
| nameRender | 自定义文字函数,和 react-router 配置使用 | Function(breadcrumbName, route, params) | | - |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
@breadcrumb-prefix-cls: ~"@{ant-prefix}-breadcrumb";
|
||||
@breadcrumb-prefix-cls: ant-breadcrumb;
|
||||
|
||||
.@{breadcrumb-prefix-cls} {
|
||||
color: #999;
|
||||
@@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
&-link {
|
||||
> .@{iconfont-css-prefix} + span {
|
||||
> .anticon + span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
27
components/button/button-group.jsx
Normal file
27
components/button/button-group.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const prefix = 'ant-btn-group-';
|
||||
|
||||
export default function ButtonGroup(props) {
|
||||
const { size, className, ...others } = props;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
const sizeCls = ({
|
||||
large: 'lg',
|
||||
small: 'sm',
|
||||
})[size] || '';
|
||||
|
||||
const classes = classNames({
|
||||
'ant-btn-group': true,
|
||||
[prefix + sizeCls]: sizeCls,
|
||||
[className]: className,
|
||||
});
|
||||
|
||||
return <div {...others} className={classes} />;
|
||||
}
|
||||
|
||||
ButtonGroup.propTypes = {
|
||||
size: React.PropTypes.oneOf(['large', 'default', 'small']),
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import splitObject from '../_util/splitObject';
|
||||
|
||||
export type ButtonSize = 'small' | 'large'
|
||||
|
||||
export interface ButtonGroupProps {
|
||||
size?: ButtonSize;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
prefixCls?: string;
|
||||
}
|
||||
|
||||
export default function ButtonGroup(props: ButtonGroupProps) {
|
||||
const [{ prefixCls = 'ant-btn-group', size, className }, others] =
|
||||
splitObject(props, ['prefixCls', 'size', 'className']);
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
const sizeCls = ({
|
||||
large: 'lg',
|
||||
small: 'sm',
|
||||
})[size] || '';
|
||||
|
||||
const classes = classNames({
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-${sizeCls}`]: sizeCls,
|
||||
[className]: className,
|
||||
});
|
||||
|
||||
return <div {...others} className={classes} />;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import Icon from '../icon';
|
||||
import splitObject from '../_util/splitObject';
|
||||
|
||||
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
|
||||
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
|
||||
function isString(str) {
|
||||
@@ -24,32 +24,12 @@ function insertSpace(child) {
|
||||
return child;
|
||||
}
|
||||
|
||||
export type ButtonType = 'primary' | 'ghost' | 'dashed'
|
||||
export type ButtonShape = 'circle' | 'circle-outline'
|
||||
export type ButtonSize = 'small' | 'large'
|
||||
|
||||
export interface ButtonProps {
|
||||
type?: ButtonType;
|
||||
htmlType?: string;
|
||||
icon?: string;
|
||||
shape?: ButtonShape;
|
||||
size?: ButtonSize;
|
||||
onClick?: React.FormEventHandler<any>;
|
||||
onMouseUp?: React.FormEventHandler<any>;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default class Button extends React.Component<ButtonProps, any> {
|
||||
static Group: any;
|
||||
|
||||
export default class Button extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-btn',
|
||||
onClick() {},
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
type: React.PropTypes.string,
|
||||
@@ -60,10 +40,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
loading: React.PropTypes.bool,
|
||||
className: React.PropTypes.string,
|
||||
icon: React.PropTypes.string,
|
||||
};
|
||||
|
||||
timeout: any;
|
||||
clickedTimeout: any;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.clickedTimeout) {
|
||||
@@ -78,7 +55,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
button.className = button.className.replace(` ${this.props.prefixCls}-clicked`, '');
|
||||
}
|
||||
|
||||
handleClick = (e) => {
|
||||
handleClick = (...args) => {
|
||||
// Add click effect
|
||||
const buttonNode = findDOMNode(this);
|
||||
this.clearButton(buttonNode);
|
||||
@@ -86,15 +63,12 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => this.clearButton(buttonNode), 500);
|
||||
|
||||
const onClick = this.props.onClick;
|
||||
if (onClick) {
|
||||
onClick(e);
|
||||
}
|
||||
this.props.onClick(...args);
|
||||
}
|
||||
|
||||
// Handle auto focus when click button in Chrome
|
||||
handleMouseUp = (e) => {
|
||||
(findDOMNode(this) as HTMLElement).blur();
|
||||
findDOMNode(this).blur();
|
||||
if (this.props.onMouseUp) {
|
||||
this.props.onMouseUp(e);
|
||||
}
|
||||
@@ -102,8 +76,7 @@ export default class Button extends React.Component<ButtonProps, any> {
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const [{ type, shape, size, className, htmlType, children, icon, loading, prefixCls }, others] = splitObject(props,
|
||||
['type', 'shape', 'size', 'className', 'htmlType', 'children', 'icon', 'loading', 'prefixCls']);
|
||||
const { type, shape, size, className, htmlType, children, icon, loading, prefixCls, ...others } = props;
|
||||
|
||||
// large => lg
|
||||
// small => sm
|
||||
@@ -23,7 +23,7 @@ import { Button } from 'antd';
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Button type="primary" shape="circle" icon="search" />
|
||||
<Button type="primary" icon="search">Search</Button>
|
||||
<Button type="primary" icon="search">搜索</Button>
|
||||
<br />
|
||||
<Button type="ghost" shape="circle-outline" icon="search" />
|
||||
<Button type="ghost" icon="search">Search</Button>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 多个按钮组合
|
||||
en-US: Multiple Buttons
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
按钮组合使用时,推荐使用1个主操作 + n 个次操作,3个以上操作时把更多操作放到 `Dropdown.Button` 中组合使用。
|
||||
|
||||
## en-US
|
||||
|
||||
If you need several buttons, we recommend that you use 1 primary button + n secondary buttons, and if there are more than three operations, you can group some of them into `Dropdown.Button`.
|
||||
|
||||
|
||||
````jsx
|
||||
import { Button, Menu, Dropdown, Icon } from 'antd';
|
||||
|
||||
function handleMenuClick(e) {
|
||||
console.log('click', e);
|
||||
}
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={handleMenuClick}>
|
||||
<Menu.Item key="1">1st item</Menu.Item>
|
||||
<Menu.Item key="2">2nd item</Menu.Item>
|
||||
<Menu.Item key="3">3rd item</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Button type="primary">primary</Button>
|
||||
<Button type="ghost">secondary</Button>
|
||||
<Dropdown overlay={menu}>
|
||||
<Button type="ghost">
|
||||
more <Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
````
|
||||
@@ -20,12 +20,9 @@ If a large or small button is desired, set the `size` property to either `large`
|
||||
````jsx
|
||||
import { Button } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Button type="primary" size="large">Large</Button>
|
||||
<Button type="primary">Default</Button>
|
||||
<Button type="primary" size="small">Small</Button>
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
ReactDOM.render(<div>
|
||||
<Button type="primary" size="large">Large</Button>
|
||||
<Button type="primary">Default</Button>
|
||||
<Button type="primary" size="small">Small</Button>
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@import "../../style/mixins/index";
|
||||
@import "./mixin";
|
||||
|
||||
@btn-prefix-cls: ~"@{ant-prefix}-btn";
|
||||
@btn-prefix-cls: ant-btn;
|
||||
|
||||
// Button styles
|
||||
// -----------------------------
|
||||
@@ -69,7 +69,7 @@
|
||||
padding-left: 29px;
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
.@{iconfont-css-prefix} {
|
||||
.anticon {
|
||||
margin-left: -14px;
|
||||
transition: all .3s @ease-in-out;
|
||||
}
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
&-sm&-loading {
|
||||
padding-left: 24px;
|
||||
.@{iconfont-css-prefix} {
|
||||
.anticon {
|
||||
margin-left: -17px;
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@
|
||||
border-radius: inherit;
|
||||
border: 0 solid @primary-color;
|
||||
opacity: 0.4;
|
||||
animation: buttonEffect 0.36s ease-out forwards;
|
||||
animation: buttonEffect 0.32s ease forwards;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@@ -118,10 +118,10 @@
|
||||
@keyframes buttonEffect {
|
||||
to {
|
||||
opacity: 0;
|
||||
top: -6px;
|
||||
left: -6px;
|
||||
bottom: -6px;
|
||||
right: -6px;
|
||||
border-width: 6px;
|
||||
top: -5px;
|
||||
left: -5px;
|
||||
bottom: -5px;
|
||||
right: -5px;
|
||||
border-width: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,21 @@
|
||||
border-radius: @border-radius;
|
||||
}
|
||||
|
||||
.button-disabled() {
|
||||
.button-variant(@color; @background; @border) {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(tint(@color, 20%); tint(@background, 20%); tint(@border, 20%));
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(shade(@color, 5%); shade(@background, 5%); shade(@background, 5%));
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
&[disabled],
|
||||
fieldset[disabled] & {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
@@ -19,38 +31,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button-variant-primary(@color; @background) {
|
||||
.button-color(@color; @background; @background);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(@color; tint(@background, 20%); tint(@background, 20%));
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(@color; shade(@background, 5%); shade(@background, 5%));
|
||||
}
|
||||
|
||||
.button-disabled();
|
||||
}
|
||||
|
||||
.button-variant-other(@color; @background; @border) {
|
||||
.button-color(@color; @background; @border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(tint(@primary-color, 20%); @background; tint(@primary-color, 20%));
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(shade(@primary-color, 5%); @background; shade(@primary-color, 5%));
|
||||
}
|
||||
|
||||
.button-disabled();
|
||||
}
|
||||
|
||||
.button-color(@color; @background; @border) {
|
||||
color: @color;
|
||||
background-color: @background;
|
||||
@@ -77,6 +57,7 @@
|
||||
vertical-align: middle;
|
||||
> .@{btnClassName} {
|
||||
position: relative;
|
||||
float: left;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active,
|
||||
@@ -87,11 +68,11 @@
|
||||
|
||||
// size
|
||||
&-lg > .@{btnClassName} {
|
||||
.button-size(@btn-padding-lg; @btn-font-size-lg; @btn-border-radius-base);
|
||||
.button-size(@btn-padding-lg; @btn-font-size-lg; @border-radius-base);
|
||||
}
|
||||
|
||||
&-sm > .@{btnClassName} {
|
||||
.button-size(@btn-padding-sm; @font-size-base; @btn-border-radius-sm);
|
||||
.button-size(@btn-padding-sm; @font-size-base; @border-radius-sm);
|
||||
> .@{iconfont-css-prefix} {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
@@ -105,13 +86,15 @@
|
||||
margin-bottom: 0;
|
||||
font-weight: @btn-font-weight;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
// outline: none;
|
||||
white-space: nowrap;
|
||||
line-height: @line-height-base;
|
||||
.button-size(@btn-padding-base; @font-size-base; @btn-border-radius-base);
|
||||
.button-size(@btn-padding-base; @font-size-base; @border-radius-base);
|
||||
user-select: none;
|
||||
transition: all .3s @ease-in-out;
|
||||
position: relative;
|
||||
@@ -144,39 +127,67 @@
|
||||
}
|
||||
|
||||
&-lg {
|
||||
.button-size(@btn-padding-lg; @btn-font-size-lg; @btn-border-radius-base);
|
||||
.button-size(@btn-padding-lg; @btn-font-size-lg; @border-radius-base);
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.button-size(@btn-padding-sm; @font-size-base; @btn-border-radius-sm);
|
||||
.button-size(@btn-padding-sm; @font-size-base; @border-radius-sm);
|
||||
}
|
||||
}
|
||||
|
||||
// primary button style
|
||||
.btn-primary() {
|
||||
.button-variant-primary(@btn-primary-color; @btn-primary-bg);
|
||||
}
|
||||
.button-variant(@btn-primary-color; @btn-primary-bg; @primary-color);
|
||||
|
||||
// default button style
|
||||
.btn-default() {
|
||||
.button-variant-other(@btn-default-color; @btn-default-bg; @btn-default-border);
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active,
|
||||
&.active {
|
||||
background: #fff;
|
||||
color: @btn-primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
// default button style
|
||||
.btn-default() {
|
||||
.button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(tint(@primary-color, 20%); white; tint(@primary-color, 20%));
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(shade(@primary-color, 5%); white; shade(@primary-color, 5%));
|
||||
}
|
||||
}
|
||||
|
||||
// ghost button style
|
||||
.btn-ghost() {
|
||||
.button-variant-other(@btn-ghost-color, @btn-ghost-bg, @btn-ghost-border);
|
||||
.button-variant(@btn-ghost-color, @btn-ghost-bg, @btn-ghost-border);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(tint(@primary-color, 20%); @btn-ghost-bg; tint(@primary-color, 20%));
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(shade(@primary-color, 5%); @btn-ghost-bg; shade(@primary-color, 5%));
|
||||
}
|
||||
}
|
||||
|
||||
// ghost button style
|
||||
.btn-dashed() {
|
||||
.button-variant-other(@btn-ghost-color, @btn-ghost-bg, @btn-ghost-border);
|
||||
.button-variant(@btn-ghost-color, @btn-ghost-bg, @btn-ghost-border);
|
||||
border-style: dashed;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.button-color(tint(@primary-color, 20%); @btn-ghost-bg; tint(@primary-color, 20%));
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
.button-color(shade(@primary-color, 5%); @btn-ghost-bg; shade(@primary-color, 5%));
|
||||
}
|
||||
}
|
||||
|
||||
// circle button: the content only contains icon
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import React, { PropTypes } from 'react';
|
||||
import { PREFIX_CLS } from './Constants';
|
||||
import Select from '../select';
|
||||
import { Group, Button } from '../radio';
|
||||
const Option = Select.Option;
|
||||
|
||||
export interface HeaderProps {
|
||||
prefixCls?: string;
|
||||
locale?: any;
|
||||
fullscreen?: boolean;
|
||||
yearSelectOffset?: number;
|
||||
yearSelectTotal?: number;
|
||||
type?: string;
|
||||
onValueChange?: (value) => void;
|
||||
onTypeChange?: (type: string) => void;
|
||||
value: any;
|
||||
}
|
||||
function noop() {}
|
||||
|
||||
export default class Header extends React.Component<HeaderProps, any> {
|
||||
export default class Header extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: `${PREFIX_CLS}-header`,
|
||||
yearSelectOffset: 10,
|
||||
yearSelectTotal: 20,
|
||||
};
|
||||
onValueChange: noop,
|
||||
onTypeChange: noop,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
value: PropTypes.object,
|
||||
locale: PropTypes.object,
|
||||
yearSelectOffset: PropTypes.number,
|
||||
yearSelectTotal: PropTypes.number,
|
||||
onValueChange: PropTypes.func,
|
||||
onTypeChange: PropTypes.func,
|
||||
prefixCls: PropTypes.string,
|
||||
selectPrefixCls: PropTypes.string,
|
||||
type: PropTypes.string,
|
||||
fullscreen: PropTypes.bool,
|
||||
}
|
||||
|
||||
getYearSelectElement(year) {
|
||||
const { yearSelectOffset, yearSelectTotal, locale, prefixCls, fullscreen } = this.props;
|
||||
@@ -30,13 +34,13 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
const end = start + yearSelectTotal;
|
||||
const suffix = locale.year === '年' ? '年' : '';
|
||||
|
||||
const options: React.ReactElement<any>[] = [];
|
||||
const options = [];
|
||||
for (let index = start; index < end; index++) {
|
||||
options.push(<Option key={`${index}`}>{index + suffix}</Option>);
|
||||
}
|
||||
return (
|
||||
<Select
|
||||
size={fullscreen ? 'default' : 'small'}
|
||||
size={fullscreen ? null : 'small'}
|
||||
dropdownMatchSelectWidth={false}
|
||||
className={`${prefixCls}-year-select`}
|
||||
onChange={this.onYearChange}
|
||||
@@ -47,21 +51,11 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
);
|
||||
}
|
||||
|
||||
getMonthsLocale(value: moment.Moment) {
|
||||
const current = value.clone();
|
||||
const localeData = value.localeData();
|
||||
const months: any[] = [];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
current.month(i);
|
||||
months.push(localeData.monthsShort(current));
|
||||
}
|
||||
return months;
|
||||
}
|
||||
|
||||
getMonthSelectElement(month, months) {
|
||||
getMonthSelectElement(month) {
|
||||
const props = this.props;
|
||||
const months = props.locale.format.months;
|
||||
const { prefixCls, fullscreen } = props;
|
||||
const options: React.ReactElement<any>[] = [];
|
||||
const options = [];
|
||||
|
||||
for (let index = 0; index < 12; index++) {
|
||||
options.push(<Option key={`${index}`}>{months[index]}</Option>);
|
||||
@@ -69,7 +63,7 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
|
||||
return (
|
||||
<Select
|
||||
size={fullscreen ? 'default' : 'small'}
|
||||
size={fullscreen ? null : 'small'}
|
||||
dropdownMatchSelectWidth={false}
|
||||
className={`${prefixCls}-month-select`}
|
||||
value={String(month)}
|
||||
@@ -82,36 +76,25 @@ export default class Header extends React.Component<HeaderProps, any> {
|
||||
|
||||
onYearChange = (year) => {
|
||||
const newValue = this.props.value.clone();
|
||||
newValue.year(parseInt(year, 10));
|
||||
|
||||
const onValueChange = this.props.onValueChange;
|
||||
if (onValueChange) {
|
||||
onValueChange(newValue);
|
||||
}
|
||||
newValue.setYear(parseInt(year, 10));
|
||||
this.props.onValueChange(newValue);
|
||||
}
|
||||
|
||||
onMonthChange = (month) => {
|
||||
const newValue = this.props.value.clone();
|
||||
newValue.month(parseInt(month, 10));
|
||||
const onValueChange = this.props.onValueChange;
|
||||
if (onValueChange) {
|
||||
onValueChange(newValue);
|
||||
}
|
||||
newValue.setMonth(parseInt(month, 10));
|
||||
this.props.onValueChange(newValue);
|
||||
}
|
||||
|
||||
onTypeChange = (e) => {
|
||||
const onTypeChange = this.props.onTypeChange;
|
||||
if (onTypeChange) {
|
||||
onTypeChange(e.target.value);
|
||||
}
|
||||
this.props.onTypeChange(e.target.value);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { type, value, prefixCls, locale, fullscreen } = this.props;
|
||||
const yearSelect = this.getYearSelectElement(value.year());
|
||||
const monthSelect = type === 'date' ?
|
||||
this.getMonthSelectElement(value.month(), this.getMonthsLocale(value)) : null;
|
||||
const size = (fullscreen ? 'default' : 'small') as any;
|
||||
const yearSelect = this.getYearSelectElement(value.getYear());
|
||||
const monthSelect = type === 'date' ? this.getMonthSelectElement(value.getMonth()) : null;
|
||||
const size = fullscreen ? 'default' : 'small';
|
||||
const typeSwitch = (
|
||||
<Group onChange={this.onTypeChange} value={type} size={size}>
|
||||
<Button value="date">{locale.month}</Button>
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
title:
|
||||
zh-CN: 自定义渲染
|
||||
en-US: Custom Render
|
||||
---
|
||||
@@ -15,18 +15,17 @@ This component can be rendered by using `dateCellRender` and `monthCellRender` w
|
||||
|
||||
````jsx
|
||||
import { Calendar } from 'antd';
|
||||
import moment from 'moment';
|
||||
|
||||
function dateCellRender(value) {
|
||||
return <div>Custom date {value.date()}</div>;
|
||||
return <div>自定义日数据 {value.getDayOfMonth()}</div>;
|
||||
}
|
||||
|
||||
function monthCellRender(value) {
|
||||
return <div>Custom monthly {value.month()}</div>;
|
||||
return <div>自定义月数据 {value.getMonth()}</div>;
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Calendar defaultValue={moment('2010-10-10', 'YYYY-MM-DD')}
|
||||
<Calendar defaultValue={new Date('2010-10-10')}
|
||||
dateCellRender={dateCellRender} monthCellRender={monthCellRender}
|
||||
/>
|
||||
, mountNode);
|
||||
|
||||
@@ -7,24 +7,21 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过 `locale` 配置语言, 默认支持 en_US, zh_CN
|
||||
通过 `locale` 配置时区、语言等, 默认支持 en_US, zh_CN
|
||||
|
||||
## en-US
|
||||
|
||||
To set the language. en_US, zh_CN are supported by default.
|
||||
To set the properties like time zone, language and etc. en_US, zh_CN are supported by default.
|
||||
|
||||
````jsx
|
||||
import { Calendar } from 'antd';
|
||||
import enUS from 'antd/lib/calendar/locale/en_US';
|
||||
import moment from 'moment';
|
||||
// It's recommended to set moment locale globally, otherwise, you need to set it by `value` or `defaultValue`
|
||||
// moment.locale('en');
|
||||
|
||||
function onPanelChange(value, mode) {
|
||||
console.log(value, mode);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Calendar defaultValue={moment().locale('en')} onPanelChange={onPanelChange} locale={enUS} />
|
||||
<Calendar onPanelChange={onPanelChange} locale={enUS} />
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
@@ -18,26 +18,26 @@ import { Calendar } from 'antd';
|
||||
|
||||
function getListData(value) {
|
||||
let listData;
|
||||
switch (value.date()) {
|
||||
switch (value.getDayOfMonth()) {
|
||||
case 8:
|
||||
listData = [
|
||||
{ type: 'warning', content: 'This is warning event.' },
|
||||
{ type: 'normal', content: 'This is usual event.' },
|
||||
{ type: 'warning', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项.' },
|
||||
]; break;
|
||||
case 10:
|
||||
listData = [
|
||||
{ type: 'warning', content: 'This is warning event.' },
|
||||
{ type: 'normal', content: 'This is usual event.' },
|
||||
{ type: 'error', content: 'This is error event.' },
|
||||
{ type: 'warning', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
]; break;
|
||||
case 15:
|
||||
listData = [
|
||||
{ type: 'warning', content: 'This is warning event' },
|
||||
{ type: 'normal', content: 'This is very long usual event。。....' },
|
||||
{ type: 'error', content: 'This is error event.' },
|
||||
{ type: 'error', content: 'This is error event.' },
|
||||
{ type: 'error', content: 'This is error event.' },
|
||||
{ type: 'error', content: 'This is error event.' },
|
||||
{ type: 'warning', content: '这里是警告事项.' },
|
||||
{ type: 'normal', content: '这里是普通事项好长啊。。....' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
{ type: 'error', content: '这里是错误事项.' },
|
||||
]; break;
|
||||
default:
|
||||
}
|
||||
@@ -61,16 +61,16 @@ function dateCellRender(value) {
|
||||
}
|
||||
|
||||
function getMonthData(value) {
|
||||
if (value.month() === 8) {
|
||||
if (value.getMonth() === 8) {
|
||||
return 1394;
|
||||
}
|
||||
}
|
||||
|
||||
function monthCellRender(value) {
|
||||
const num = getMonthData(value);
|
||||
let num = getMonthData(value);
|
||||
return num ? <div className="notes-month">
|
||||
<section>{num}</section>
|
||||
<span>Backlog number</span>
|
||||
<span>待办事项数</span>
|
||||
</div> : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ cols: 1
|
||||
title: Calendar
|
||||
---
|
||||
|
||||
When To Use container for displaying data in calendar form.
|
||||
When to use container for displaying data in calendar form.
|
||||
|
||||
## When To Use
|
||||
## When to use
|
||||
|
||||
When data is in the form of date, such as schedule, timetable, prices calendar, Lunar calendar. This component also supports Year/Month switch.
|
||||
|
||||
@@ -23,11 +23,11 @@ When data is in the form of date, such as schedule, timetable, prices calendar,
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|--------------|----------------|----------|--------------|
|
||||
| value | set date | [moment](http://momentjs.com/) | current date |
|
||||
| defaultValue | set default date | [moment](http://momentjs.com/) | default date |
|
||||
| value | set date | Date | current date |
|
||||
| defaultValue | set default date | Date | current date |
|
||||
| mode | can be set to month or year | string | month |
|
||||
| fullscreen | to set whether full-screen display | boolean | true |
|
||||
| dateCellRender | to set the way of renderer the date cell | function(date: moment): ReactNode | - |
|
||||
| monthCellRender | to set the way of renderer the month cell | function(date: moment): ReactNode | - |
|
||||
| locale | set locale | Object | [defualt](https://github.com/ant-design/ant-design/issues/424) |
|
||||
| onPanelChange| the callback when panel change | function(date: moment, mode: string) | - |
|
||||
| fullscreen | to set whether full-screen display | bool | true |
|
||||
| dateCellRender | to set the way of renderer the date cell| function([GregorianCalendar](https://github.com/yiminghe/gregorian-calendar/))| - |
|
||||
| monthCellRender | to set the way of renderer the month cell | function([GregorianCalendar](https://github.com/yiminghe/gregorian-calendar/)) | - |
|
||||
| locale | set locale | object | [defualt](https://github.com/ant-design/ant-design/issues/424) |
|
||||
| onPanelChange| the callback when panel change | function(date, mode) | - |
|
||||
|
||||
@@ -1,48 +1,27 @@
|
||||
import React from 'react';
|
||||
import { PropTypes } from 'react';
|
||||
import moment from 'moment';
|
||||
import React, { PropTypes } from 'react';
|
||||
import GregorianCalendar from 'gregorian-calendar';
|
||||
import defaultLocale from './locale/zh_CN';
|
||||
import FullCalendar from 'rc-calendar/lib/FullCalendar';
|
||||
import { PREFIX_CLS } from './Constants';
|
||||
import Header from './Header';
|
||||
import getLocale from '../_util/getLocale';
|
||||
declare const require: Function;
|
||||
|
||||
function noop() { return null; }
|
||||
|
||||
function zerofixed(v) {
|
||||
if (v < 10) {
|
||||
return `0${v}`;
|
||||
}
|
||||
if (v < 10) return `0${v}`;
|
||||
return `${v}`;
|
||||
}
|
||||
|
||||
export interface CalendarContext {
|
||||
antLocale?: {
|
||||
Calendar?: any
|
||||
};
|
||||
}
|
||||
|
||||
export interface CalendarProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
value?: moment.Moment;
|
||||
defaultValue?: moment.Moment;
|
||||
mode?: 'month' | 'year';
|
||||
fullscreen?: boolean;
|
||||
dateCellRender?: (date: moment.Moment) => React.ReactNode;
|
||||
monthCellRender?: (date: moment.Moment) => React.ReactNode;
|
||||
locale?: any;
|
||||
style?: React.CSSProperties;
|
||||
onPanelChange?: (date: moment.Moment, mode: string) => void;
|
||||
}
|
||||
|
||||
export default class Calendar extends React.Component<CalendarProps, any> {
|
||||
export default class Calendar extends React.Component {
|
||||
static defaultProps = {
|
||||
monthCellRender: noop,
|
||||
dateCellRender: noop,
|
||||
locale: {},
|
||||
fullscreen: true,
|
||||
prefixCls: PREFIX_CLS,
|
||||
onPanelChange: noop,
|
||||
mode: 'month',
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
monthCellRender: PropTypes.func,
|
||||
@@ -53,54 +32,72 @@ export default class Calendar extends React.Component<CalendarProps, any> {
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
onPanelChange: PropTypes.func,
|
||||
value: PropTypes.object,
|
||||
};
|
||||
value: PropTypes.instanceOf(Date),
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
antLocale: PropTypes.object,
|
||||
};
|
||||
|
||||
context: CalendarContext;
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: props.value || props.defaultValue || moment(),
|
||||
value: this.parseDateFromValue(props.value || new Date()),
|
||||
mode: props.mode,
|
||||
};
|
||||
}
|
||||
|
||||
parseDateFromValue(value) {
|
||||
const date = new GregorianCalendar(this.getLocale());
|
||||
date.setTime(+value);
|
||||
return date;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({
|
||||
value: nextProps.value,
|
||||
value: this.parseDateFromValue(nextProps.value),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
monthCellRender = (value) => {
|
||||
const { prefixCls, monthCellRender = noop as Function } = this.props;
|
||||
getLocale = () => {
|
||||
const props = this.props;
|
||||
let locale = defaultLocale;
|
||||
const context = this.context;
|
||||
if (context && context.antLocale && context.antLocale.Calendar) {
|
||||
locale = context.antLocale.Calendar;
|
||||
}
|
||||
// 统一合并为完整的 Locale
|
||||
const result = { ...locale, ...props.locale };
|
||||
result.lang = { ...locale.lang, ...props.locale.lang };
|
||||
return result;
|
||||
}
|
||||
|
||||
monthCellRender = (value, locale) => {
|
||||
const prefixCls = this.props.prefixCls;
|
||||
const month = value.getMonth();
|
||||
return (
|
||||
<div className={`${prefixCls}-month`}>
|
||||
<div className={`${prefixCls}-value`}>
|
||||
{value.localeData().monthsShort(value)}
|
||||
{locale.format.shortMonths[month]}
|
||||
</div>
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{monthCellRender(value)}
|
||||
{this.props.monthCellRender(value)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
dateCellRender = (value) => {
|
||||
const { prefixCls, dateCellRender = noop as Function } = this.props;
|
||||
const prefixCls = this.props.prefixCls;
|
||||
return (
|
||||
<div className={`${prefixCls}-date`}>
|
||||
<div className={`${prefixCls}-value`}>
|
||||
{zerofixed(value.date())}
|
||||
{zerofixed(value.getDayOfMonth())}
|
||||
</div>
|
||||
<div className={`${prefixCls}-content`}>
|
||||
{dateCellRender(value)}
|
||||
{this.props.dateCellRender(value)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -110,20 +107,14 @@ export default class Calendar extends React.Component<CalendarProps, any> {
|
||||
if (!('value' in this.props) && this.state.value !== value) {
|
||||
this.setState({ value });
|
||||
}
|
||||
const onPanelChange = this.props.onPanelChange;
|
||||
if (onPanelChange) {
|
||||
onPanelChange(value, this.state.mode);
|
||||
}
|
||||
this.props.onPanelChange(value, this.state.mode);
|
||||
}
|
||||
|
||||
setType = (type) => {
|
||||
const mode = (type === 'date') ? 'month' : 'year';
|
||||
if (this.state.mode !== mode) {
|
||||
this.setState({ mode });
|
||||
const onPanelChange = this.props.onPanelChange;
|
||||
if (onPanelChange) {
|
||||
onPanelChange(this.state.value, mode);
|
||||
}
|
||||
this.props.onPanelChange(this.state.value, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,10 +123,7 @@ export default class Calendar extends React.Component<CalendarProps, any> {
|
||||
const { value, mode } = this.state;
|
||||
const { prefixCls, style, className, fullscreen } = props;
|
||||
const type = (mode === 'year') ? 'month' : 'date';
|
||||
const locale = getLocale(
|
||||
props, this.context, 'Calendar',
|
||||
() => require('./locale/zh_CN')
|
||||
);
|
||||
const locale = this.getLocale();
|
||||
|
||||
let cls = className || '';
|
||||
if (fullscreen) {
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
category: Components
|
||||
type: Views
|
||||
subtitle: 日历
|
||||
chinese: 日历
|
||||
cols: 1
|
||||
title: Calendar
|
||||
english: Calendar
|
||||
---
|
||||
|
||||
按照日历形式展示数据的容器。
|
||||
@@ -25,11 +25,11 @@ title: Calendar
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|--------------|----------------|----------|--------------|
|
||||
| value | 展示日期 | [moment](http://momentjs.com/) | 当前日期 |
|
||||
| defaultValue | 默认展示的日期 | [moment](http://momentjs.com/) | 默认日期 |
|
||||
| value | 展示日期 | Date | 当前日期 |
|
||||
| defaultValue | 默认展示日期 | Date | 当前日期 |
|
||||
| mode | 初始模式,`month/year` | string | month |
|
||||
| fullscreen | 是否全屏显示 | boolean | true |
|
||||
| dateCellRender | 自定义渲染日期单元格| function(date: moment): ReactNode | 无 |
|
||||
| monthCellRender | 自定义渲染月单元格 | function(date: moment): ReactNode | 无 |
|
||||
| locale | 国际化配置 | Object | [默认配置](https://github.com/ant-design/ant-design/issues/424) |
|
||||
| onPanelChange| 日期面板变化回调 | function(date: moment, mode: string) | 无 |
|
||||
| fullscreen | 是否全屏显示 | bool | true |
|
||||
| dateCellRender | 自定义渲染日期单元格| function([GregorianCalendar](https://github.com/yiminghe/gregorian-calendar/))| 无 |
|
||||
| monthCellRender | 自定义渲染月单元格 | function([GregorianCalendar](https://github.com/yiminghe/gregorian-calendar/)) | 无 |
|
||||
| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/issues/424) |
|
||||
| onPanelChange| 日期面板变化回调 | function(date, mode) | 无 |
|
||||
|
||||
1
components/calendar/locale/en_US.js
Normal file
1
components/calendar/locale/en_US.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('../../date-picker/locale/en_US');
|
||||
@@ -1,2 +0,0 @@
|
||||
import en_US from '../../date-picker/locale/en_US';
|
||||
export default en_US;
|
||||
1
components/calendar/locale/ru_RU.js
Normal file
1
components/calendar/locale/ru_RU.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('../../date-picker/locale/ru_RU');
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user