mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-18 07:12:28 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44fd5990f6 | ||
|
|
d009cf0b76 | ||
|
|
51b74b7daa | ||
|
|
635bc8cedc | ||
|
|
ff59663898 |
9
.babelrc
9
.babelrc
@@ -1,10 +1,3 @@
|
||||
{
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": ["es2015", "react", "stage-0"],
|
||||
"plugins": [
|
||||
"add-module-exports"
|
||||
]
|
||||
}
|
||||
}
|
||||
"presets": ["es2015", "react", "stage-0"]
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
codecov:
|
||||
branch: master
|
||||
@@ -1,5 +0,0 @@
|
||||
components/**/*.js
|
||||
components/**/*.jsx
|
||||
!.eslintrc.js
|
||||
!components/*/__tests__/*
|
||||
!components/*/demo/*
|
||||
19
.eslintrc.js
19
.eslintrc.js
@@ -1,9 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const eslintrc = {
|
||||
extends: ['eslint-config-airbnb'],
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
jasmine: true,
|
||||
mocha: true,
|
||||
jest: true,
|
||||
es6: true,
|
||||
},
|
||||
@@ -22,25 +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/extensions': 0,
|
||||
'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,
|
||||
'jsx-a11y/no-static-element-interactions': 0,
|
||||
'jsx-a11y/anchor-has-content': 0,
|
||||
'react/no-danger': 0,
|
||||
'comma-dangle': ['error', 'always-multiline'],
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env.RUN_ENV === 'DEMO') {
|
||||
@@ -52,12 +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,
|
||||
'jsx-a11y/href-no-hash': 0,
|
||||
'import/newline-after-import': 0,
|
||||
'react/prefer-es6-class': 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
6
.github/CONTRIBUTING.md
vendored
6
.github/CONTRIBUTING.md
vendored
@@ -19,7 +19,7 @@ Tips: choose the corresponding documentation with versions selector which in the
|
||||
|
||||
### 2. Make sure that your question is about Ant Design, not React
|
||||
|
||||
Someone may think all of the questions that he/she meets in developing are about Ant Design, but it's not true. So, please read [React's documentation](http://facebook.github.io/react/docs/getting-started.html) or just Google (not Baidu, seriously) your questions with keyword *React* first. If you are sure that your question is about Ant Design, go ahead.
|
||||
Someone may think all of the questions that he/she meets in developing are about Ant Design, but it's not true. So, please read [React's documentaion](http://facebook.github.io/react/docs/getting-started.html) or just Google(not Baidu, seriously) your questions with keywork *React* first. If you are sure that your question is about Ant Design, go ahead.
|
||||
|
||||
### 3. Read the FAQ and search the issues list of Ant Design
|
||||
|
||||
@@ -48,11 +48,9 @@ If you believe that Ant Design should provide some features, but it does not. Yo
|
||||
|
||||
## Tips about Pull Request
|
||||
|
||||
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
|
||||
|
||||
It's welcomed to pull request. And there are some tips about that:
|
||||
|
||||
1. It is a good habit to create a feature request issue to discuss whether the feature is necessary before you implement it. However, it's unnecessary to create an issue to claim that you found a typo or improved the readability of documentation, just create a pull request.
|
||||
1. It is a good habit to create a feature request issue to disscuss whether the feature is necessary before you implement it. However, it's unnecessary to create an issue to claim that you found a typo or improved the readability of documentaion, just create a pull request.
|
||||
1. Run `npm run lint` and fix those errors before committing in order to keep consistent code style.
|
||||
1. Rebase before creating a PR to keep commit history clear.
|
||||
1. Add some descriptions and refer relative issues for you PR.
|
||||
|
||||
32
.github/ISSUE_TEMPLATE.md
vendored
32
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,15 +1,27 @@
|
||||
<!--
|
||||
IMPORTANT: Please use the following link to create a new issue:
|
||||
<!-- Issue Template For Chinese Users -->
|
||||
|
||||
http://new-issue.ant.design
|
||||
<!-- 请按照下列格式报告问题,务必提供复现步骤,否则恕难解决,感谢您的支持。-->
|
||||
|
||||
If your issue was not created using the app above, it will be closed immediately.
|
||||
-->
|
||||
#### 本地环境
|
||||
|
||||
<!--
|
||||
注意:请使用下面的链接来新建 issue:
|
||||
<!-- 务必提供 -->
|
||||
|
||||
http://new-issue.ant.design
|
||||
- antd 版本:
|
||||
- 操作系统及其版本:
|
||||
- 浏览器及其版本:
|
||||
|
||||
不是用上面的链接创建的 issue 会被立即关闭。
|
||||
-->
|
||||
#### 你做了什么?
|
||||
|
||||
<!-- 引入 antd 了 Button -->
|
||||
|
||||
#### 你期待的结果是:
|
||||
|
||||
<!-- 像官网一样正常显示 -->
|
||||
|
||||
#### 实际上的结果:
|
||||
|
||||
<!-- 缺少样式 -->
|
||||
|
||||
#### 可重现的在线演示
|
||||
|
||||
<!-- 请修改并 Fork http://codepen.io/benjycui/pen/KgPZrE?editors=001 -->
|
||||
|
||||
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,22 +1,8 @@
|
||||
First of all, thank you for your contribution! :-)
|
||||
First of all, thanks for your contribution! :-)
|
||||
|
||||
Please makes sure that these checkboxes are checked before submitting your PR, thank you!
|
||||
Please makes sure these boxes are checked before submitting your PR, thank you!
|
||||
|
||||
* [ ] Make sure that you propose PR to right branch: bugfix for `master`, feature for latest active branch `feature-x.x`.
|
||||
* [ ] Make sure that you follow antd's [code convention](https://github.com/ant-design/ant-design/wiki/Code-convention-for-antd).
|
||||
* [ ] Make sure you follow antd's [code convention](https://github.com/ant-design/ant-design/wiki/Code-convention-for-antd).
|
||||
* [ ] Run `npm run lint` and fix those errors before submitting in order to keep consistent code style.
|
||||
* [ ] Rebase before creating a PR to keep commit history clear.
|
||||
* [ ] Add some descriptions and refer relative issues for you PR.
|
||||
|
||||
Extra checklist:
|
||||
|
||||
**if** *isBugFix* **:**
|
||||
|
||||
* [ ] Make sure that you add at least one unit test for the bug which you had fixed.
|
||||
|
||||
**elif** *isNewFeature* **:**
|
||||
|
||||
* [ ] Update API docs for the component.
|
||||
* [ ] Update/Add demo to demonstrate new feature.
|
||||
* [ ] Update TypeScript definition for the component.
|
||||
* [ ] Add unit tests for the feature.
|
||||
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -15,8 +15,6 @@ Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
*.log
|
||||
*.log.*
|
||||
*.json.gzip
|
||||
node_modules/
|
||||
.buildpath
|
||||
.settings
|
||||
@@ -26,13 +24,6 @@ _site
|
||||
_data
|
||||
dist
|
||||
/lib
|
||||
/es
|
||||
elasticsearch-*
|
||||
config/base.yaml
|
||||
/.vscode/
|
||||
/coverage
|
||||
yarn.lock
|
||||
components/**/*.js
|
||||
components/**/*.jsx
|
||||
!components/**/__tests__/*.js
|
||||
!components/**/__tests__/*.js.snap
|
||||
typings
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"setupFiles": [
|
||||
"./tests/setup.js"
|
||||
],
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
"js",
|
||||
"md"
|
||||
],
|
||||
"transform": {
|
||||
"\\.tsx?$": "./node_modules/typescript-babel-jest",
|
||||
"\\.js$": "./node_modules/babel-jest",
|
||||
"\\.md$": "./node_modules/antd-demo-jest"
|
||||
},
|
||||
"testRegex": "demo\\.test\\.js$",
|
||||
"testEnvironment": "node",
|
||||
"snapshotSerializers": ["enzyme-to-json/serializer"]
|
||||
}
|
||||
21
.lesshintrc
Normal file
21
.lesshintrc
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"propertyOrdering": false,
|
||||
"hexLength": "short",
|
||||
"stringQuotes": false,
|
||||
"decimalZero": false,
|
||||
"importantRule": false,
|
||||
"zeroUnit": "no_unit",
|
||||
"qualifyingElement": false,
|
||||
"duplicateProperty": false,
|
||||
"importPath": false,
|
||||
"finalNewline": false,
|
||||
"newlineAfterBlock": false,
|
||||
"maxCharPerLine": false,
|
||||
"excludedFiles": [
|
||||
"components/layout/style/mixin.less",
|
||||
"components/style/core/base.less",
|
||||
"components/style/core/iconfont.less",
|
||||
"components/style/core/normalize.less",
|
||||
"components/style/mixins/compatibility.less"
|
||||
]
|
||||
}
|
||||
24
.stylelintrc
24
.stylelintrc
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"extends": "stylelint-config-standard",
|
||||
"rules": {
|
||||
"at-rule-empty-line-before": null,
|
||||
"at-rule-name-space-after": null,
|
||||
"comment-empty-line-before": null,
|
||||
"declaration-bang-space-before": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"function-comma-newline-after": null,
|
||||
"function-name-case": null,
|
||||
"function-parentheses-newline-inside": null,
|
||||
"function-max-empty-lines": null,
|
||||
"function-whitespace-after": null,
|
||||
"indentation": null,
|
||||
"number-leading-zero": null,
|
||||
"number-no-trailing-zeros": null,
|
||||
"rule-empty-line-before": null,
|
||||
"selector-combinator-space-after": null,
|
||||
"selector-list-comma-newline-after": null,
|
||||
"selector-pseudo-element-colon-notation": null,
|
||||
"unit-no-unknown": null,
|
||||
"value-list-max-empty-lines": null
|
||||
}
|
||||
}
|
||||
28
.travis.yml
28
.travis.yml
@@ -3,30 +3,4 @@ sudo: false
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "6"
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TEST_TYPE=lint
|
||||
- TEST_TYPE=dist
|
||||
- TEST_TYPE=compile
|
||||
- TEST_TYPE=test:dom
|
||||
- TEST_TYPE=test:node
|
||||
|
||||
script:
|
||||
- |
|
||||
if [ "$TEST_TYPE" = lint ]; then
|
||||
npm run lint
|
||||
elif [ "$TEST_TYPE" = dist ]; then
|
||||
npm run dist && \
|
||||
node ./tests/dekko/dist.test.js
|
||||
elif [ "$TEST_TYPE" = compile ]; then
|
||||
npm run compile && \
|
||||
node ./tests/dekko/lib.test.js
|
||||
elif [ "$TEST_TYPE" = test:dom ]; then
|
||||
npm run dist && \
|
||||
npm test -- --coverage -w 2 && \
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
elif [ "$TEST_TYPE" = test:node ]; then
|
||||
npm test -- --config .jest.node.json -w 2
|
||||
fi
|
||||
- "5"
|
||||
|
||||
61
AUTHORS.txt
61
AUTHORS.txt
@@ -1,58 +1,30 @@
|
||||
Albert Zheng <lisong.zheng@gmail.com>
|
||||
Andrew Murray <radarhere@gmail.com>
|
||||
Andrey G <plandem@gmail.com>
|
||||
Benjy Cui <benjytrys@gmail.com>
|
||||
Bernie <bernie.wangbj@gmail.com>
|
||||
Bozhao <yubz86@gmail.com>
|
||||
Bruce Mitchener <bruce.mitchener@gmail.com>
|
||||
Bruno Maia <bruno.mm.maia@gmail.com>
|
||||
C <4019980@qq.com>
|
||||
Cam Song <neosoyn@gmail.com>
|
||||
Catalin Miron <mironcatalin@gmail.com>
|
||||
Cee Cirno <i@cee.moe>
|
||||
Cody Chan <int64ago@gmail.com>
|
||||
Danny Hoower Antonio Viasus Avila <danjavia@gmail.com>
|
||||
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>
|
||||
ImJoeHs <865439601@qq.com>
|
||||
Infinity <305870677@qq.com>
|
||||
James <james@schoolshape.com>
|
||||
Jerry Bendy <jerry@icewingcc.com>
|
||||
Junyu Zhan <irrigator@yeah.net>
|
||||
KgTong <kgtong1992@gmail.com>
|
||||
Leon Shi <superRaytin@163.com>
|
||||
Leon Shi <superRaytin@gmail.com>
|
||||
Liu Yang <zation1@gmail.com>
|
||||
LongYinan <lynweklm@gmail.com>
|
||||
MG12 <wuzhao.mail@gmail.com>
|
||||
Ma Tianxiao <matx2215@outlook.com>
|
||||
Marius Ileana <visvadw@gmail.com>
|
||||
Marshall Chen <Juniors.fei@gmail.com>
|
||||
Meck <yesmeck@gmail.com>
|
||||
Mr.Tone <vector@malubei.com>
|
||||
Nathan Wells <nwwells@gmail.com>
|
||||
Neverland <chenjiahan@buaa.edu.cn>
|
||||
Nimo <nimo.jser@gmail.com>
|
||||
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>
|
||||
@@ -61,71 +33,44 @@ bang <sqibang@gmail.com>
|
||||
bang88 <sqibang@gmail.com>
|
||||
chencheng (云谦) <sorrycc@gmail.com>
|
||||
ddcat1115 <ddcat1115@gmail.com>
|
||||
denzw <denzw@21cn.com>
|
||||
detailyang <detailyang@gmail.com>
|
||||
devqin <devqin@gmail.com>
|
||||
djorkaeff <djorkae55@gmail.com>
|
||||
ecofe <150641329@qq.com>
|
||||
edgji <j.edgji@gmail.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>
|
||||
jinouwuque <ee2win@gmail.com>
|
||||
kagawagao <kingsongao1221@gmail.com>
|
||||
kaifei <150641329@qq.com>
|
||||
kasinooya <kasinooya@gmail.com>
|
||||
kayw <kayw@outlook.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>
|
||||
parlop <parlop@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>
|
||||
xiaofan2406 <xiaofan2406@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>
|
||||
zuiidea <zuiiidea@gmail.com>
|
||||
偏右 <afc163@gmail.com>
|
||||
逸达 <dqaria@gmail.com>
|
||||
蔡伦 <sliuqin@gmail.com>
|
||||
陆离 <surgesoft@gmail.com>
|
||||
低位 <zhujun87654321@gmail.com>
|
||||
广彬-梁 <326741518@qq.com>
|
||||
闲耘™ <hotoo.cn@gmail.com>
|
||||
吕立青 <jimmy.jinglv@gmail.com>
|
||||
马斯特 <sd4399340@126.com>
|
||||
马金花儿 <o.o@mug.dog>
|
||||
偏右 <afc163@gmail.com>
|
||||
白羊座小葛 <abeyuhang@gmail.com>
|
||||
逸达 <dqaria@gmail.com>
|
||||
闲耘™ <hotoo.cn@gmail.com>
|
||||
|
||||
1040
CHANGELOG.en-US.md
1040
CHANGELOG.en-US.md
File diff suppressed because it is too large
Load Diff
454
CHANGELOG.md
Normal file
454
CHANGELOG.md
Normal file
@@ -0,0 +1,454 @@
|
||||
---
|
||||
order: 3
|
||||
title: 更新日志
|
||||
toc: false
|
||||
timeline: true
|
||||
---
|
||||
|
||||
如果需要查看 `0.12.x` 及之前的更新日志,请移步 [GitHub](https://github.com/ant-design/ant-design/releases?after=1.0.0)。
|
||||
|
||||
---
|
||||
|
||||
## 1.11.2
|
||||
|
||||
`2016-09-26`
|
||||
|
||||
- 修复 Popover 内嵌 Badge 后失效的问题。[#3109](https://github.com/ant-design/ant-design/issues/3109)
|
||||
- 修复 Modal 内嵌的 Button 在某些情况下与 Modal 的滚动不同步的问题。[#3031](https://github.com/ant-design/ant-design/issues/3031)
|
||||
|
||||
## 1.11.1
|
||||
|
||||
`2016-09-14`
|
||||
|
||||
- 修复 Menu 设置成 `theme=dark` 后,链接点击无效的问题。[#2929](https://github.com/ant-design/ant-design/issues/2929)
|
||||
- 修复迷你型 Table 表头与内容不对齐的问题。[#2933](https://github.com/ant-design/ant-design/issues/2933)
|
||||
- 修复 Cascader hover 样式。[#3015](https://github.com/ant-design/ant-design/issues/3015)
|
||||
- 修复 Upload 上传多个文件时,`onChange` 调用不正确的问题。[#3001](https://github.com/ant-design/ant-design/issues/3001)
|
||||
- 修复 TimePicker 报错样式的问题。[#2973](https://github.com/ant-design/ant-design/issues/2973)
|
||||
- 修复 Calendar 控件的年度选择下拉内容截断的问题。[#2927](https://github.com/ant-design/ant-design/issues/2927)
|
||||
|
||||
## 1.11.0
|
||||
|
||||
`2016-09-01`
|
||||
|
||||
- `Tooltip` `Popover` `Popconfirm` 修正默认对齐方式为边缘对齐,增加 arrowPointAtCenter 属性用于箭头指向中心的行为。[commit 977e2e3](https://github.com/ant-design/ant-design/commit/977e2e32fc40968846c8201ed72bdc3818375d2f)
|
||||
- `Table`
|
||||
- 移除数据中添加的 `indexForSort`。[#2501](https://github.com/ant-design/ant-design/issues/2501)
|
||||
- 修复 `pagination` 属性中 `defaultPageSize` 不生效的问题。[#2874](https://github.com/ant-design/ant-design/issues/2874)
|
||||
- 修复数据为空时固定列出现重复提示的问题。[#2812](https://github.com/ant-design/ant-design/issues/2812)
|
||||
- 给树形子数据增加排序功能。[#2839](https://github.com/ant-design/ant-design/issues/2839)
|
||||
- `InputNumber` 样式问题修复。[#2876](https://github.com/ant-design/ant-design/issues/2876)
|
||||
- 修复手动导入 less 文件时 input error 样式被 focus 样式覆盖的问题。[#2916](https://github.com/ant-design/ant-design/issues/2916)
|
||||
- index.d.ts 中补充了一些缺失的声明,修复 `Form` 中 typescript 语法检查报错的问题。[#2885](https://github.com/ant-design/ant-design/issues/2885)
|
||||
- 升级 react-slick 依赖到 `0.13`。
|
||||
|
||||
## 1.10.0
|
||||
|
||||
`2016-08-20`
|
||||
|
||||
- Affix 和 BackTop 新增 `target` 属性,支持指定滚动容器。[#2718](https://github.com/ant-design/ant-design/issues/2718)
|
||||
- 文档页面加上编辑按钮,方便社区贡献。[#2325](https://github.com/ant-design/ant-design/issues/2325)
|
||||
- 升级 rc-cascader 依赖,修复一个 `loadData` 属性和表单结合使用的问题。[#2767](https://github.com/ant-design/ant-design/issues/2767)
|
||||
- 修复 `editable-card` 类型的 Tabs 没有关闭图标的问题。[#2747](https://github.com/ant-design/ant-design/issues/2747)
|
||||
- Menu 修正默认 `z-index`。[#2762](https://github.com/ant-design/ant-design/issues/2762)
|
||||
- 修正 Select 组件在 IE 下的一些样式问题。[#2741](https://github.com/ant-design/ant-design/issues/2741)
|
||||
|
||||
## 1.9.1
|
||||
|
||||
`2016-08-16`
|
||||
|
||||
- 修复 `editable-card` 类型的 Tabs 设置 `activeKey` 无效的问题。[#2725](https://github.com/ant-design/ant-design/issues/2725)
|
||||
- 修复一个 Table 的样式兼容性问题。[#2723](https://github.com/ant-design/ant-design/issues/2723)
|
||||
- 更新 axure 部件库。[#2714](https://github.com/ant-design/ant-design/issues/2714)
|
||||
|
||||
## 1.9.0
|
||||
|
||||
`2016-08-15`
|
||||
|
||||
- Transfer 修复在火狐下 item 文案过长时只显示省略号的问题。[#2674](https://github.com/ant-design/ant-design/issues/2674)
|
||||
- Input 修复 `autosize` 模式下特定场景中不能输入中文及光标定位不准的问题。[#2666](https://github.com/ant-design/ant-design/issues/2666) [#2239](https://github.com/ant-design/ant-design/issues/2239)
|
||||
- Tabs 修复 `type="editable-card"` 模式下的 `children` 解析问题。[#2658](https://github.com/ant-design/ant-design/issues/2658)
|
||||
- Radio 修复若干 less 硬编码问题。[#2424](https://github.com/ant-design/ant-design/issues/2424)
|
||||
- Upload 的 rc-upload 依赖升级至 2.x,引入的变化有:
|
||||
- 增加 `disabled` 属性。[#2645](https://github.com/ant-design/ant-design/issues/2645)
|
||||
- 取消上传时会自动 abort 上传请求。[#2571](https://github.com/ant-design/ant-design/issues/2571) [#2518](https://github.com/ant-design/ant-design/issues/2518)
|
||||
- Table
|
||||
- 修复 spin 在可滚动区域的定位问题。[#2652](https://github.com/ant-design/ant-design/issues/2652)
|
||||
- 修复无数据时 提示样式错位的问题。[#2663](https://github.com/ant-design/ant-design/issues/2663)
|
||||
- Popover 修复设定 `getTooltipContainer` 后会导致内嵌 DatePicker 样式失效的问题。[#2675](https://github.com/ant-design/ant-design/issues/2675)
|
||||
- Modal 修复重复卸载组件导致的报错。[#2688](https://github.com/ant-design/ant-design/issues/2688)
|
||||
- 升级 rc-slider 组件依赖。
|
||||
|
||||
## 1.8.0
|
||||
|
||||
`2016-08-08`
|
||||
|
||||
- 修复可关闭 Tabs 组件只有一个 Tab 的时候报错的问题。[#2559](https://github.com/ant-design/ant-design/issues/2559)
|
||||
- 修复 Datepicker 在 IE8 下关闭图标。[#2584](https://github.com/ant-design/ant-design/issues/2584)
|
||||
- Tags 支持自定义标签颜色。[#2585](https://github.com/ant-design/ant-design/issues/2585)
|
||||
- TreeSelect 修复未找到内容时的样式。[9cee9f](https://github.com/ant-design/ant-design/commit/9cee9f103a4729572358206c81cba84e2fdc20f5)
|
||||
- Modal 适配小屏幕。[#2597](https://github.com/ant-design/ant-design/issues/2597)
|
||||
- 修复了 Row 组件在同一行闭合会报错的问题。[#2603](https://github.com/ant-design/ant-design/issues/2603)
|
||||
- Table 的 `rowSelection.onChange` 的参数 `selectedRows` 现在和 `selectedRowKeys` 保持一致。[#2566](https://github.com/ant-design/ant-design/issues/2603)
|
||||
- Checkbox 和 Radio 现在支持 `onClick` 属性。
|
||||
|
||||
## 1.7.0
|
||||
|
||||
`2016-07-30`
|
||||
|
||||
友情提示 [Ant Design Mobile](http://mobile.ant.design) 已经发布。
|
||||
|
||||
- Table
|
||||
- 现可以定义页头。[demo](http://ant.design/components/table#components-table-demo-bordered)
|
||||
- 修复当 `rowKey` 为 `String` 时的报错问题。[#2500](https://github.com/ant-design/ant-design/issues/2500)
|
||||
- 修复 `Table` 会修改 `dataSource` 里面的值的问题。[#2501](https://github.com/ant-design/ant-design/issues/2501)
|
||||
- Form 现在不再需要显式传递 `form={this.props.form}`。
|
||||
- 优化 Breadcrumb.Item 的 hover 效果。
|
||||
- 优化 Progress 的动画效果。
|
||||
- DatePicker
|
||||
- 优化清除按钮样式。
|
||||
- 修复点击 `此刻` 时不触发 `onChange` 的问题。[#1902](https://github.com/ant-design/ant-design/issues/1902)
|
||||
- Menu
|
||||
- 修复子菜单中的 Item 被选中后,父级元素无样式变化的问题。[#2414](https://github.com/ant-design/ant-design/issues/2414)
|
||||
- 修复 Menu.Item disabled 后的样式问题。
|
||||
- TreeSelect
|
||||
- treeNodes 可以设置是否可选。[#2401](https://github.com/ant-design/ant-design/issues/2401)
|
||||
- 修复多选模式下进行搜索会把已选项清掉的问题。[#2393](https://github.com/ant-design/ant-design/issues/2393)
|
||||
- 修复 TreeSelect 会修改原数据的问题。[#2459](https://github.com/ant-design/ant-design/issues/2459)
|
||||
- 修复了 Select 组件 placeholder 溢出的问题。[#2480](https://github.com/ant-design/ant-design/pull/2480)
|
||||
- 修复 Timeline.Item 无法自定义边框颜色的问题。[#2479](https://github.com/ant-design/ant-design/issues/2479)
|
||||
- 修复 Spin 显示突兀的问题。[#2398](https://github.com/ant-design/ant-design/issues/2398)
|
||||
- 修复 Cascader 选项文字过长导致的样式问题。[#2515](https://github.com/ant-design/ant-design/issues/2515)
|
||||
|
||||
## 1.6.5
|
||||
|
||||
`2016-07-16`
|
||||
|
||||
- 修复 Input 的 `value prop on input should not be null` 警告并且导致在表单中无法重置的问题。[#2335](https://github.com/ant-design/ant-design/issues/2335)
|
||||
- 优化 FormItem 的布局实现,修复表单布局不支持响应式布局的问题。[#2305](https://github.com/ant-design/ant-design/issues/2305)
|
||||
- 修复带时间的 DatePicker 的 onChange 触发逻辑。[#2399](https://github.com/ant-design/ant-design/issues/2399#issuecomment-232893146)
|
||||
- 修复 Transfer 搜索后全选的问题。[#2396](https://github.com/ant-design/ant-design/issues/2396)
|
||||
- 修复 Cascader 样式会被 ant-input 样式覆盖的问题。[#2400](https://github.com/ant-design/ant-design/issues/2400)
|
||||
- 修复 Table 删除数据时导致当前页数溢出的问题。[#2301](https://github.com/ant-design/ant-design/pull/2301)
|
||||
- 修复 resize 浏览器时 Affix 元素没有和原来的位置同步的问题。[#1987](https://github.com/ant-design/ant-design/issues/1987)
|
||||
- 给 Affix 元素添加占位,修复固定时页面跳动的问题。
|
||||
- 修复 Select combobox 模式会导致页面出现横向滚动条的问题。[#2353](https://github.com/ant-design/ant-design/issues/2353)
|
||||
- 修复 Upload 组件已上传文件链接点击无效的问题。[#2331](https://github.com/ant-design/ant-design/issues/2331)
|
||||
- 修复 Upload 上传过程中删除图片后的报错问题。[#2342](https://github.com/ant-design/ant-design/issues/2342)
|
||||
|
||||
## 1.6.4
|
||||
|
||||
`2016-07-08`
|
||||
|
||||
- 修复组件在 react@15.2.0 下报 Unknown props 警告的问题。[#2258](https://github.com/ant-design/ant-design/issues/2258)
|
||||
- `Table`
|
||||
- 修复 filterDropDown 中内容未改变也会调用 onChange 的问题。[#2228](https://github.com/ant-design/ant-design/issues/2228)
|
||||
- 修复设置 scroll.y 高度后导致内容无法对齐的问题。[#2227](https://github.com/ant-design/ant-design/issues/2227)
|
||||
- `Form`
|
||||
- 修复 `FormItem` 中带空格后缀的冒号替换问题,关联issue:[#1877](https://github.com/ant-design/ant-design/issues/1877)
|
||||
- demo 优化。
|
||||
- `Transfer`
|
||||
- 修复重复 render 的问题,性能优化。[#2112](https://github.com/ant-design/ant-design/issues/2112)
|
||||
- 优化搜索逻辑,修复搜索时未对特殊字符进行处理的问题。[#2260](https://github.com/ant-design/ant-design/issues/2260)
|
||||
- 清除按钮样式优化。
|
||||
- 修复 `Steps` 最后一步多余横线隐藏的问题。
|
||||
- 修复 `Cascader` small size 样式下沉 1px,以及 hover/click 样式残缺的问题。[#2234](https://github.com/ant-design/ant-design/issues/2234)
|
||||
- 修复 `RangePicker` 无清除按钮的问题。[#2252](https://github.com/ant-design/ant-design/issues/2252)
|
||||
|
||||
## 1.6.3
|
||||
|
||||
`2016-07-04`
|
||||
|
||||
- 修复 Transfer 的一个 unmount 的错误。[#2206](https://github.com/ant-design/ant-design/pull/2206)
|
||||
- 修复了 Badge、Alert、Menu、Tag、Checkbox、Radio 组件的一些样式细节问题。
|
||||
|
||||
## 1.6.2
|
||||
|
||||
`2016-06-27`
|
||||
|
||||
- 修复 Table、Transfer 的样式错位问题。
|
||||
- 修复 DatePicker 的一个样式问题。[#2182](https://github.com/ant-design/ant-design/issues/2182)
|
||||
- 优化 Menu 的 hover 样式响应性能。
|
||||
|
||||
## 1.6.1
|
||||
|
||||
`2016-06-24`
|
||||
|
||||
- 回滚一个未完成的 DatePicker 时间选项改造效果。
|
||||
|
||||
## 1.6.0
|
||||
|
||||
`2016-06-24`
|
||||
|
||||
- 新增置顶组件 [BackTop](/components/back-top)。
|
||||
- 全新的 [Spin](/components/spin) 样式。
|
||||
- 给 `Modal.xxx` 系列方法添加了 `{ destory }` 的访问值,方便事后销毁。[#2110](https://github.com/ant-design/ant-design/issues/2110)
|
||||
- Table 的 `rowKey` 属性支持直接使用字符串。[#2058](https://github.com/ant-design/ant-design/issues/2058)
|
||||
- Table 增加 `column.filterDropdown` 属性用于自定义渲染筛选菜单的浮层。[#1736](https://github.com/ant-design/ant-design/issues/1736)
|
||||
- 修复 Tooltip、Popover、Popconfirm 设置 `onVisibleChange` 后失效的问题。[#2134](https://github.com/ant-design/ant-design/issues/2134)
|
||||
- 修复在 IE8 下 Checkbox 的勾样式变形的问题。[#2148](https://github.com/ant-design/ant-design/issues/2148)
|
||||
- 优化 Checkbox、Radio 失效状态的文字颜色。[#2114](https://github.com/ant-design/ant-design/issues/2114)
|
||||
- 优化 Checkbox、Radio 的默认边距过于拥挤的问题。[#2137](https://github.com/ant-design/ant-design/issues/2137)
|
||||
- 优化 Pagination 在暗色背景下的样式。[#2126](https://github.com/ant-design/ant-design/issues/2126)
|
||||
- 修复 Table 固定列时内容无法换行和高度对齐的问题,同时修复了一个 Chrome 下的表格内容错位问题。[#2130](https://github.com/ant-design/ant-design/issues/2130)
|
||||
- 修复一个 Table 的 `rowSelection` 设为 null 时可能导致报错的问题。[#2127](https://github.com/ant-design/ant-design/issues/2127)
|
||||
- 修复在 IE8 下点击 Table 选择框报错的问题。[#2154](https://github.com/ant-design/ant-design/issues/2154)
|
||||
- 小幅优化了 Transfer 的渲染性能。[#2112](https://github.com/ant-design/ant-design/issues/2112)
|
||||
- 将 DatePicker 的清除按钮从面板上移到外部输入框,解决用户容易误解为关闭的问题。[#1708](https://github.com/ant-design/ant-design/issues/1708)
|
||||
- Upload 的 `onPreview` 现在没有 `file.url` 时也能生效。[#2163](https://github.com/ant-design/ant-design/issues/2163)
|
||||
|
||||
## 1.5.1
|
||||
|
||||
`2016-06-21`
|
||||
|
||||
- 修复一个 TypeScript 定义文件的语法错误。
|
||||
- 修复 Table 固定表头高度和滚动条样式问题。
|
||||
|
||||
## 1.5.0
|
||||
|
||||
`2016-06-17`
|
||||
|
||||
- 升级 `rc-form` 到 0.17,支持 `getFieldProps('xx.yy')` 的写法,并支持单多选控件进行关联。[#](https://github.com/react-component/form/pull/21)
|
||||
- Input 的 `addonBefore` 和 `addonAfter` 支持内嵌选择框。[#1927](https://github.com/ant-design/ant-design/issues/1927)
|
||||
- 优化了两个 DatePicker 组成的时间范围选择演示的体验。
|
||||
- 优化一个多个对话框的遮罩层高度的问题。[#2009](https://github.com/ant-design/ant-design/issues/2009)
|
||||
- 优化 Table 的 `getCheckboxProps` 的调用次数。[#2086](https://github.com/ant-design/ant-design/issues/2086)
|
||||
- 修复 Table 固定列时,表头无法左右滚动的问题。[#2068](https://github.com/ant-design/ant-design/issues/2068)
|
||||
- 修复小型表格固定表头的样式。[#2023](https://github.com/ant-design/ant-design/issues/2023)
|
||||
- 修复 Tabs 的 `tabPosition` 为左右时样式错位的问题。[#2046](https://github.com/ant-design/ant-design/issues/2046)
|
||||
- 修复 RangePicker 的日期范围背景丢失的问题。
|
||||
- 修复 Switch 失效状态下文字颜色太浅的问题。[#2051](https://github.com/ant-design/ant-design/issues/2051)
|
||||
- 修复一个 Select 的 `disabled` 选项依然可以被移除的问题。[#2034](https://github.com/ant-design/ant-design/issues/2034)
|
||||
- 修复官方站点在 IE 下的报错问题。
|
||||
|
||||
## 1.4.1
|
||||
|
||||
`2016-06-12`
|
||||
|
||||
- 修复一个展开 Tabs 会导致表格宽度溢出的问题。[#2013](https://github.com/ant-design/ant-design/issues/2013)
|
||||
- 修复一个某些情况下表格布局被破坏的问题。
|
||||
|
||||
## 1.4.0
|
||||
|
||||
`2016-06-12`
|
||||
|
||||
此版本之后你可能会遇到 [#2030](https://github.com/ant-design/ant-design/issues/2030),请使用 `react@15+` 或 `npm@3+`。
|
||||
|
||||
- `Input[type="textarea"]` 支持自动调整高度。 [#](http://ant.design/components/input#components-input-demo-autosize-textarea)
|
||||
- `Breadcrumb`
|
||||
- `nameRender` 新增 `route` 和 `params` 参数。 [#1999](https://github.com/ant-design/ant-design/issues/1999)
|
||||
- `linkRender` 新增 `paths` 参数。
|
||||
- 再次修复 `Table` 组件 `rowSelection.onChange` 与 `onRowClick` 冲突问题。 [#1470](https://github.com/ant-design/ant-design/issues/1470)
|
||||
- 修复 `Form.Item` 中 `Input` 高度抖动问题。 [#1955](https://github.com/ant-design/ant-design/issues/1955)
|
||||
- 修复高级搜索的 `ant-advanced-search-form` 样式丢失的问题。
|
||||
|
||||
## 1.3.2
|
||||
|
||||
`2016-06-06`
|
||||
|
||||
- 修复全局模式下引用 antd,IE8 环境报错的问题。 [#1970](https://github.com/ant-design/ant-design/issues/1970)
|
||||
|
||||
## 1.3.1
|
||||
|
||||
`2016-06-06`
|
||||
|
||||
- 修复 `Message` `Notification` 找不到的问题。 [#1968](https://github.com/ant-design/ant-design/issues/1968)
|
||||
|
||||
## 1.3.0
|
||||
|
||||
`2016-06-02`
|
||||
|
||||
- Transfer 组件增加 `rowKey` 属性,可自定义数据源主键。 [#1900](https://github.com/ant-design/ant-design/issues/1900)
|
||||
- Tag 组件 `default` 类型的样式增加边框,防止淹没在背景中。 [#1910](https://github.com/ant-design/ant-design/issues/1910)
|
||||
- Table
|
||||
- 修复筛选为单选时仍旧展示多选框的问题。 [#1880](https://github.com/ant-design/ant-design/issues/1880)
|
||||
- 修复 fixed left 的固定列会覆盖 rowSelection 的 Checkbox 的问题。 [#1829](https://github.com/ant-design/ant-design/issues/1829)
|
||||
- 升级 rc-table 依赖
|
||||
- 修复了 fixed 列中数据重复展示以及一些错位问题。 [#1898](https://github.com/ant-design/ant-design/issues/1898)
|
||||
- `dataIndex` 支持内嵌属性的写法。 [react-component/table#46](https://github.com/react-component/table/issues/46)
|
||||
- 修复了 v1.2.0 新增加的组件属性的 TypeScript 定义。 [#1933](https://github.com/ant-design/ant-design/issues/1933)
|
||||
- Form 修复 label中冒号的国际化问题,采用样式实现冒号,不再需要手动输入冒号。 [#1877](https://github.com/ant-design/ant-design/issues/1877)
|
||||
- 修复 DatePicker 组件点击『此刻』失效的问题,并进行了一些代码优化。 [#1902](https://github.com/ant-design/ant-design/issues/1902)
|
||||
- 升级 rc-upload 依赖,修复了 IE10 中第二次上传同一文件不触发 `onChange` 的问题。 [058af3c](https://github.com/ant-design/ant-design/commit/b15a4e3165be5e4db995d3fe75d4d557c7f21c61)
|
||||
- 文档使用 [bisheng](https://github.com/benjycui/bisheng) 重构。
|
||||
|
||||
## 1.2.1
|
||||
|
||||
`2016-05-27`
|
||||
|
||||
- 修复一个 Select 组件的文字重复问题。
|
||||
|
||||
## 1.2.0
|
||||
|
||||
`2016-05-26`
|
||||
|
||||
- Input 组件的文档现在和 Form 分离。 [3c98d3](https://github.com/ant-design/ant-design/commit/3c98d3f80f4ec80066756adc3b4108141d4383ca)
|
||||
- Affix
|
||||
- 新增了 `onChange` 属性。当固定状态改变时回调 [#1777](https://github.com/ant-design/ant-design/issues/1777)
|
||||
- 找回了从 affixStyle 中走失的 `width` 属性,修复固定后错位的问题。[#1820](https://github.com/ant-design/ant-design/issues/1820)
|
||||
- Table
|
||||
- 修复了 Table 组件的分页相关的一系列问题 [#1669](https://github.com/ant-design/ant-design/issues/1669) [#1842](https://github.com/ant-design/ant-design/issues/1842)
|
||||
- 修复了当有列固定在左边时,选择框不显示的问题 [#1829](https://github.com/ant-design/ant-design/issues/1829)
|
||||
- 修复了当 Checkbox 的 label 为数字 0 时, label 不显示的问题 [#1811](https://github.com/ant-design/ant-design/issues/1811)
|
||||
- 修复 Select combobox 模式下无法重置 `optionLabelProp` 的问题。[#1773](https://github.com/ant-design/ant-design/issues/1773)
|
||||
- 修复了 Tag 组件为 closeable 时,内部链接无法点击的问题 [#1862](https://github.com/ant-design/ant-design/issues/1862)
|
||||
- Tab 组件新增 `hideAdd` 属性,用于关闭右边的添加按钮 [#1750](https://github.com/ant-design/ant-design/issues/1750)
|
||||
- 修复了一个在某些情况下找不到 `normalize.css/normalize.css` 文件的问题。[ant-design/antd-init#52](https://github.com/ant-design/antd-init/issues/52)
|
||||
- 修复构建文件在 IE8 下报错的问题。[#1804](https://github.com/ant-design/ant-design/issues/1804)
|
||||
- 更新了第三方依赖。
|
||||
|
||||
## 1.1.0
|
||||
|
||||
`2016-05-18`
|
||||
|
||||
- Cascader 的选择框支持自定义渲染节点,并给 `displayRender` 方法增加了 `selectedOptions` 参数。[#1726](https://github.com/ant-design/ant-design/issues/1726)
|
||||
- Input.Group 新增 `size` 属性,可设置控件尺寸。[#1732](https://github.com/ant-design/ant-design/issues/1732)
|
||||
- Layout 新增常用布局:侧边导航展开收起模式。[#1643](https://github.com/ant-design/ant-design/issues/1643)
|
||||
- Transfer 支持自定义渲染行数据。[#1664](https://github.com/ant-design/ant-design/issues/1664)
|
||||
- Upload 的 children 为空时,不再显示上传按钮。[#1610](https://github.com/ant-design/ant-design/issues/1610)
|
||||
- Table
|
||||
- 修复 `filter` 过滤数据后显示错误分页的问题。[#1669](https://github.com/ant-design/ant-design/issues/1669)
|
||||
- 修复 `pagination` 不指定时显示错误分页的问题。[#1683](https://github.com/ant-design/ant-design/issues/1683)
|
||||
- Modal
|
||||
- 修复弹出时背景依然跟随滚动的问题。[#1751](https://github.com/ant-design/ant-design/issues/1751)
|
||||
- 修复关闭按钮获得焦点时的样式问题。[#1668](https://github.com/ant-design/ant-design/issues/1668)
|
||||
- 将搜索输入框相关样式移到 Input 组件下。[7b7f846](https://github.com/ant-design/ant-design/commit/7b7f8461611e53f4f96ae8d64d37fe28ee8d2553)
|
||||
- 修复 Select 获得焦点时的样式问题。[#1684](https://github.com/ant-design/ant-design/issues/1684)
|
||||
- 修复 TreeSelect 占位符样式问题。[#1657](https://github.com/ant-design/ant-design/issues/1657)
|
||||
- 修复了类型定义以更好地支持 `TypeScript`。[#1696](https://github.com/ant-design/ant-design/pull/1696) [@xujihui1985](https://github.com/xujihui1985)
|
||||
- 优化了 LocaleProvider。[a3850a4](https://github.com/ant-design/ant-design/commit/a3850a4df84d7055a1a40600919f2f9ba1bbf2b2)
|
||||
- 其他组件的样式优化。
|
||||
|
||||
## 1.0.1
|
||||
|
||||
`2016-05-11`
|
||||
|
||||
- 修复当 Table 的 `rowSelection.type` 为 'radio' 时的报错。[#1627](https://github.com/ant-design/ant-design/issues/1627)
|
||||
- 修复 CheckboxGroup 与 `getFieldProps`共用时的问题。[#1631](https://github.com/ant-design/ant-design/issues/1631)
|
||||
- 修复 RangePicker 中 TimePicker 不会受 locale 控制的问题。[#1635](https://github.com/ant-design/ant-design/issues/1635)
|
||||
- 修复 Tag 组件缺失的问题。
|
||||
- 修复 Table 的 className 不在最外层容器上的问题。
|
||||
- 修复一个样式文件重复打包的问题。
|
||||
|
||||
## 1.0.0
|
||||
|
||||
`2016-05-09`
|
||||
|
||||
很高兴的通知各位,经过四个月时间的紧密开发,`antd@1.0.0` 终于发布了。从去年 5 月 7 日提交第一行代码以来,经过整整一年的开发迭代,antd 受到社区的大量关注,使用的公司和产品持续增加,已经日趋成熟。这个版本我们重构了底层代码和站点,持续完善现有组件功能和优化细节,其中很多都来自社区的贡献,无法一一感谢,欢迎各位持续关注和鞭策。在升级过程中遇到任何问题,请及时反馈给我们。
|
||||
|
||||
### 主要变化
|
||||
|
||||
- **兼容 React@15.x**。
|
||||
- **全新单页站点**,使用 React 和 antd 进行了彻底重构,加载更快,访问更流畅。
|
||||
- **样式支持按需加载**。可参考 [antd-init](https://github.com/ant-design/antd-init) 的模版代码, 需要配合 [babel-plugin-antd](https://github.com/ant-design/babel-plugin-antd#usage) 插件和 `style` 配置进行使用。[#900](https://github.com/ant-design/ant-design/issues/900)
|
||||
- **提供独立的构建文件**。[文档](/docs/react/install#浏览器引入)
|
||||
- 新增卡片组件 [Card](/components/card)。
|
||||
- 新增评分组件 [Rate](/components/rate)。
|
||||
- 新增 [LocaleProvider](/components/locale-provider) 组件,提供组件文案的国际化支持,并新增了英语和俄语的语言配置。[#1411](https://github.com/ant-design/ant-design/issues/1411)
|
||||
- 更好的服务端渲染支持,修复了 Badge、Spin、Calendar、Upload 等组件服务端渲染的问题。
|
||||
- 新增 antd.d.ts 以更好的支持 TypeScript。[@bang88](https://github.com/bang88)
|
||||
- 布局组件支持响应式布局和栅格间隔设置。[#1082](https://github.com/ant-design/ant-design/issues/1082)
|
||||
- Table 支持固定列和横向滚动。[#1265](https://github.com/ant-design/ant-design/issues/1265)
|
||||
|
||||
### 不兼容改动
|
||||
|
||||
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。
|
||||
|
||||
- 推荐使用样式按需加载。如果依然需要整体载入样式,**样式入口文件已变为** `antd/dist/antd.css` 和 `antd/dist/antd.less`。如果你在项目中覆盖了 less 变量,less 文件的引用方式也有 [相应变更](https://github.com/ant-design/ant-design/issues/1558#issuecomment-218120000)。
|
||||
|
||||
```diff
|
||||
- import 'antd/lib/index.css'; // import 'antd/style/index.less';
|
||||
+ import 'antd/dist/antd.css'; // import 'antd/dist/antd.less';
|
||||
```
|
||||
|
||||
- 完全移除了 `0.12` 中废弃的 Validation 组件,可以直接 import [rc-form-validation](https://github.com/react-component/form-validation) 用以代替。[#1096](https://github.com/ant-design/ant-design/issues/1096)
|
||||
- Breadcrumb.Item 的 `href` 属性被移除,请直接用 `a` 标签包裹可点击的内容。
|
||||
- Modal 移除了 `align` 属性,现在可以使用 `style` 属性调整位置。
|
||||
- `Modal.confirm` 等方法的配置项 `iconClassName` 重命名为 `iconType`。
|
||||
- Select 移除了 `onChange` 中的 `label` 参数,新增了 `labelInValue` 属性。[#1695](https://github.com/ant-design/ant-design/issues/1695)
|
||||
- 移除了 `import { Form } from 'antd/lib/form';` 的用法,应统一为 `import { Form } from 'antd';` 或 `import Form from 'antd/lib/form';`。
|
||||
|
||||
#### 有兼容提示的改动
|
||||
|
||||
这里的改动在升级后控制台会出现警告提示,请按提示进行修改。
|
||||
|
||||
- 废弃 QueueAnim,可以直接 import [rc-queue-anim](https://github.com/react-component/queue-anim) 用以代替。Ant Design 的动效方案已移至 [Ant Motion](http://motion.ant.design/components/queue-anim),欢迎前往探索。
|
||||
- Affix 的 `offset` 属性重命名为 `offsetTop`。
|
||||
- Popover 的 `overlay` 属性重命名为 `content`。
|
||||
- Progress.Line 使用方式改为 `<Progress />` 或 `<Progress type="line" />`。
|
||||
- Progress.Circle 使用方式改为 `<Progress type="circle" />`。
|
||||
- Spin 的 `spining` 属性更正为 `spinning`。
|
||||
- Alert 的 type `warn` 重命名为 `warning`。[#1225](https://github.com/ant-design/ant-design/issues/1225)
|
||||
- Tree 的 `onExpand` 参数从 `function(node, expanded, expandedKeys)` 调整为 `function(expandedKeys, {expanded, node})`。
|
||||
|
||||
### Bug 修复
|
||||
|
||||
- 修复 Table 的 `size` 为 `middle` 时,分页器大小无法控制的问题。[#1396](https://github.com/ant-design/ant-design/issues/1396)
|
||||
- 修复 Table 的 `pagination.defaultCurrent` 失效的问题。
|
||||
- 修复 Cascader 的 `defaultValue` 没有被 `value` 覆盖的问题。
|
||||
- 修复 Select 同时设置 `allowClear` `disabled` 时还是会出现清除按钮的问题。[#1480](https://github.com/ant-design/ant-design/issues/1480)
|
||||
- 修复 Transfer 的 `DataSource` 变化时已选中项没有同步的问题。[#1587](https://github.com/ant-design/ant-design/issues/1587)
|
||||
- 修复 DatePicker 日期格式与国际化配置不同步的问题。[#1509](https://github.com/ant-design/ant-design/issues/1509)
|
||||
- 修复 Button 禁用时事件仍然会冒泡的问题。[#1541](https://github.com/ant-design/ant-design/issues/1541)
|
||||
- 修复 Carousel 自动播放时的卡顿和报错问题。[#1397](https://github.com/ant-design/ant-design/issues/1397)
|
||||
- 修复 Tabs 的 card 类型内嵌标准 Tabs 时的样式问题。[#1617](https://github.com/ant-design/ant-design/issues/1617)
|
||||
- 修复 Menu `horizontal` 和 `vertical` 模式不支持受控 `openKeys` 的问题。
|
||||
|
||||
### 其他改进
|
||||
|
||||
- 样式变量梳理,去除了部分无用的变量,另外还有大量样式细节问题修复。
|
||||
- 依赖的 normalize.css 升级到 [4.x](https://github.com/necolas/normalize.css/blob/4.1.1/CHANGELOG.md)。
|
||||
- 使用 ES2016 classes 重构了代码。[@waywardmonkeys](https://github.com/waywardmonkeys)
|
||||
- Popover、Popconfirm 和 Tooltip 组件根据不同的弹出位置有了更精准方向的弹出动画。
|
||||
- 补充 Select TreeSelect Switch Radio Checkbox 等组件的 `focus` 表现,增强表单组件的可用性。[#1358](https://github.com/ant-design/ant-design/issues/1358)
|
||||
- message 和 notification 现在可以全局配置 `duration`。[#1143](https://github.com/ant-design/ant-design/issues/1143)
|
||||
- DatePicker 和 TimePicker 的 `onChange(date, dateString)` 方法增加第二个参数用于获得格式化后的日期字符串。[#1104](https://github.com/ant-design/ant-design/issues/1104)
|
||||
- DatePicker 和 DatePicker.RangePicker 现在可以设置内部 TimePikcer 的属性。[#1415](https://github.com/ant-design/ant-design/issues/1415)
|
||||
- Checkbox
|
||||
- 支持类似 Radio 的使用方式 `<Checkbox>option</Checkbox>`。[#1029](https://github.com/ant-design/ant-design/issues/1029)
|
||||
- Checkbox.Group 现在允许 `label` 和 `value` 不同。[#1025](https://github.com/ant-design/ant-design/issues/1025)
|
||||
- Checkbox.Group 允许单独设置某个 Checkbox 为 `disabled`。[#1218](https://github.com/ant-design/ant-design/issues/1218)
|
||||
- Breadcrumb
|
||||
- 支持路由模式下自定义链接 `linkRender`。[#1026](https://github.com/ant-design/ant-design/issues/1026)
|
||||
- 支持路由模式下自定义最后一项内容 `nameRender`。[#1304](https://github.com/ant-design/ant-design/issues/1304)
|
||||
- Modal
|
||||
- 新增 `Modal.warning` 方法。
|
||||
- 弹出时背景不再跟随滚动。[#1195](https://github.com/ant-design/ant-design/issues/1195)
|
||||
- Select
|
||||
- 搜索框和单选选择框合并,以优化视觉和交互效果。
|
||||
- 优化多选框的选中效果。
|
||||
- Spin
|
||||
- 增加延时展示以优化体验。[#1273](https://github.com/ant-design/ant-design/issues/1273)
|
||||
- 增加 `tip` 属性用于定义加载文案。[#1046](https://github.com/ant-design/ant-design/issues/1046)
|
||||
- Steps
|
||||
- 重构布局方式,以支持更灵活的自适应布局和优化了性能,并移除了 `maxDescriptionWidth` 属性。[#1099](https://github.com/ant-design/ant-design/issues/1099)
|
||||
- 新增 `status` 属性以指定当前步骤状态,同时支持错误步骤的展示。[#1098](https://github.com/ant-design/ant-design/issues/1098)
|
||||
- Timeline
|
||||
- 新增 `dot` 属性,可自定义时间轴点。
|
||||
- 现在可以设置 `className` 和 `style` 的问题。
|
||||
- `color` 属性现在支持自定义色值。
|
||||
- Tree
|
||||
- 当子节点被选中时,自动展开父节点。
|
||||
- 新增 `checkStrictly` 属性,支持父子节点选中关系脱离。
|
||||
- Upload
|
||||
- 在上传文件列表中的文件被删除时,将触发 `onRemove` 事件。[#1240](https://github.com/ant-design/ant-design/issues/1240)
|
||||
- 增加 `onPreview` 支持文件的自定义预览方式。[#1240](https://github.com/ant-design/ant-design/issues/1240)
|
||||
- `data` 属性支持设为一个函数,用于动态修改上传参数。[react-component/upload#32](https://github.com/react-component/upload/pull/32)
|
||||
- Slider `marks` 现在支持 JSX 并可以单独设置某个标记的样式。
|
||||
- Tag 的 `onClose` 可以使用 `e.preventDefault()` 阻止默认事件。[#1267](https://github.com/ant-design/ant-design/issues/1267)
|
||||
- Form.Item 在有多个 child 时也可以自动生成错误信息与校验状态,但一个 Form.Item 内仍然只能有一个表单控件。[#1287](https://github.com/ant-design/ant-design/issues/1287)
|
||||
- Input 新增 `onPressEnter` 属性监听回车事件。
|
||||
- Table 现在可以通过 `filteredValue` `sortOrder` 控制筛选和排序的状态。[#971](https://github.com/ant-design/ant-design/issues/971)
|
||||
- Button 增加了 `icon` 属性。[#1199](https://github.com/ant-design/ant-design/issues/1199)
|
||||
- SubMenu 增加 `onTitleClick` 属性。
|
||||
- Affix 增加 `offsetBottm` 属性,支持固定在底部。[#1000](https://github.com/ant-design/ant-design/issues/1000)
|
||||
|
||||
### 相关工具发布
|
||||
|
||||
- [antd-init](http://github.com/ant-design/antd-init) 同步发布 `1.0.0` 版本,享受最新 [ant-tool](https://github.com/ant-tool/) 工具带来的流畅开发体验。
|
||||
- [Ant Motion](http://motion.ant.design) 全新的动效设计解决方案。
|
||||
- [Ant UX](http://ux.ant.design/) 发布 1.0 版本,提供多种平台的流程素材支持。
|
||||
|
||||
## 0.12.17
|
||||
|
||||
去 [GitHub](https://github.com/ant-design/ant-design/releases?after=1.0.0) 查看 `0.12.x` 及之前的更新日志。
|
||||
1052
CHANGELOG.zh-CN.md
1052
CHANGELOG.zh-CN.md
File diff suppressed because it is too large
Load Diff
@@ -1,46 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at xingmin.zhu@alipay.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
104
README-zh_CN.md
104
README-zh_CN.md
@@ -4,38 +4,15 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Ant Design
|
||||
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://codecov.io/gh/ant-design/ant-design/branch/master)
|
||||
[](https://gemnasium.com/ant-design/ant-design)
|
||||
|
||||
[](https://www.npmjs.org/package/antd)
|
||||
[](https://npmjs.org/package/antd)
|
||||
[](http://isitmaintained.com/project/ant-design/ant-design "Percentage of issues still open")
|
||||
[](https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) (English)
|
||||
[](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 实现。
|
||||
|
||||
[README in English](README.md)
|
||||
|
||||
## 特性
|
||||
|
||||
- 提炼自企业级中后台产品的交互语言和视觉风格。
|
||||
- 开箱即用的高质量 React 组件。
|
||||
- 使用 TypeScript 构建,提供完整的类型定义文件。
|
||||
- 基于 npm + webpack + [dva](https://github.com/dvajs/dva) 的企业级开发框架。
|
||||
|
||||
## 支持环境
|
||||
|
||||
* 现代浏览器和 IE9 及以上。
|
||||
* 支持服务端渲染。
|
||||
* [Electron](http://electron.atom.io/)
|
||||
|
||||
## 参与共建 [](http://makeapullrequest.com)
|
||||
|
||||
`antd` 是一个开源项目,我们欢迎社区参与共建。如果你对此项目感兴趣,有 [很多方式](https://opensource.guide/how-to-contribute/) 进行参与。你可以 watch 这个仓库,加入 [issue 中的讨论](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion),以及尝试实现一些 [已接受的特性](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22)。我们会给予有活跃贡献的社区成员 [collaborator 权限](https://github.com/ant-design/ant-design/issues/3222)。
|
||||
- 提炼和服务企业级中后台产品的交互语言和视觉风格。
|
||||
- [React Component](http://react-component.github.io/badgeboard/) 基础上精心封装的高质量 UI 组件。
|
||||
- 基于 npm + webpack + babel 的工作流,支持 ES2015 和 TypeScript。
|
||||
|
||||
## 安装
|
||||
|
||||
@@ -56,70 +33,41 @@ 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)。
|
||||
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
现代浏览器和 IE8 及以上。
|
||||
|
||||
> [IE8 issues](https://github.com/xcatliu/react-ie8)
|
||||
|
||||
## TypeScript
|
||||
|
||||
```js
|
||||
// tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
///<reference path='./node_modules/antd/type-definitions/antd.d.ts'/>
|
||||
...
|
||||
```
|
||||
|
||||
> 注意:
|
||||
> - 设置 `allowSyntheticDefaultImports` 避免 `error TS1192: Module 'react' has no default export` 的错误。
|
||||
> - 不要使用 @types/antd, antd 已经自带了 TypeScript 定义。
|
||||
|
||||
## 国际化
|
||||
|
||||
参考 [国际化文档](http://ant.design/docs/react/i18n)。
|
||||
|
||||
## 链接
|
||||
|
||||
- [首页](http://ant.design/index-cn)
|
||||
- [UI 组件库](http://ant.design/docs/react/introduce-cn)
|
||||
- [更新日志](CHANGELOG.en-US.md)
|
||||
- [官方脚手架](https://github.com/dvajs/dva-cli)
|
||||
- [首页](http://ant.design/)
|
||||
- [React 实现](http://ant.design/#/docs/react/introduce)
|
||||
- [修改记录](CHANGELOG.md)
|
||||
- [开发脚手架](https://github.com/ant-design/antd-init/)
|
||||
- [开发工具文档](http://ant-tool.github.io/)
|
||||
- [脚手架市场](http://scaffold.ant.design)
|
||||
- [React 底层基础组件](http://react-component.github.io/)
|
||||
- [React 基础组件](http://react-component.github.io/)
|
||||
- [移动端组件](http://mobile.ant.design)
|
||||
- [动效](https://motion.ant.design)
|
||||
- [设计规范速查手册](https://github.com/ant-design/ant-design/wiki/Ant-Design-%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E7%AE%80%E7%89%88)
|
||||
- [开发者说明](https://github.com/ant-design/ant-design/wiki/Development)
|
||||
- [版本发布规则](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B)
|
||||
- [React 代码规范](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-code-style.md)
|
||||
- [组件设计原则](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-design.md)
|
||||
- [网站和组件开发说明](https://github.com/ant-design/ant-design/wiki/%E7%BD%91%E7%AB%99%E5%92%8C%E7%BB%84%E4%BB%B6%E5%BC%80%E5%8F%91%E8%AF%B4%E6%98%8E)
|
||||
- [版本发布手册](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B)
|
||||
- [社区贡献脚手架和范例](https://github.com/ant-design/ant-design/issues/129)
|
||||
- [常见问题](https://github.com/ant-design/ant-design/wiki/FAQ)
|
||||
- [CodePen 模板](http://codepen.io/benjycui/pen/KgPZrE?editors=001) for bug reports
|
||||
- [CodePen 模板](http://codepen.io/benjycui/pen/KgPZrE?editors=001)
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [定制主题](http://ant.design/docs/react/customize-theme-cn)
|
||||
|
||||
## 本地开发
|
||||
|
||||
```bash
|
||||
$ git clone git@github.com:ant-design/ant-design.git
|
||||
$ npm install
|
||||
$ npm start
|
||||
```
|
||||
|
||||
打开浏览器访问 http://127.0.0.1:8001 ,更多本地开发文档参见: https://github.com/ant-design/ant-design/wiki/Development 。
|
||||
|
||||
## 如何贡献
|
||||
|
||||
在任何形式的参与前,请先阅读 [贡献者文档](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md)。如果你希望参与贡献,欢迎 [Pull Request](https://github.com/ant-design/ant-design/pulls),或给我们 [报告 Bug](http://new-issue.ant.design/)。
|
||||
|
||||
> 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。
|
||||
|
||||
## 社区互助
|
||||
|
||||
如果您在使用的过程中碰到问题,可以通过下面几个途径寻求帮助,同时我们也鼓励资深用户通过下面的途径给新人提供帮助。
|
||||
|
||||
通过 Stack Overflow 或者 Segment Fault 提问时,建议加上 `antd` 标签。
|
||||
|
||||
1. [Stack Overflow](http://stackoverflow.com/questions/tagged/antd)(英文)
|
||||
2. [Segment Fault](https://segmentfault.com/t/antd)(中文)
|
||||
3. [](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
我们欢迎任何形式的贡献,有任何建议或意见您可以进行 [Pull Request](https://github.com/ant-design/ant-design/pulls),或者给我们 [提问](https://github.com/ant-design/ant-design/issues)。
|
||||
|
||||
104
README.md
104
README.md
@@ -4,38 +4,19 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Ant Design
|
||||
|
||||
[](https://travis-ci.org/ant-design/ant-design)
|
||||
[](https://codecov.io/gh/ant-design/ant-design/branch/master)
|
||||
[](https://gemnasium.com/ant-design/ant-design)
|
||||
|
||||
[](https://www.npmjs.org/package/antd)
|
||||
[](https://npmjs.org/package/antd)
|
||||
[](http://isitmaintained.com/project/ant-design/ant-design "Percentage of issues still open")
|
||||
[](https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) (English)
|
||||
[](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.
|
||||
|
||||
[中文 README](README-zh_CN.md)
|
||||
## :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 UI design language for web applications.
|
||||
- A set of high-quality React components out of the box.
|
||||
- Written in TypeScript with complete define types.
|
||||
- A npm + webpack + [dva](https://github.com/dvajs/dva) front-end development workflow.
|
||||
|
||||
## Environment Support
|
||||
|
||||
* Modern browsers and Internet Explorer 9+ (with [polyfills](https://ant.design/docs/react/getting-started#Compatibility))
|
||||
* Server-side Rendering
|
||||
* [Electron](http://electron.atom.io/)
|
||||
|
||||
## Let's build a better antd together [](http://makeapullrequest.com)
|
||||
|
||||
`antd` is an open source project, improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22). Actually, there are [many ways](https://opensource.guide/how-to-contribute/) to contribute. And we are always happy to [offer collaborator permission](https://github.com/ant-design/ant-design/issues/3222) for some active contributors.
|
||||
- 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/).
|
||||
- A npm + webpack + babel + dora [workflow](http://ant-tool.github.io/index.html).
|
||||
|
||||
## Install
|
||||
|
||||
@@ -45,6 +26,8 @@ npm install antd
|
||||
|
||||
## Usage
|
||||
|
||||
### Use prebuilt bundle
|
||||
|
||||
```jsx
|
||||
import { DatePicker } from 'antd';
|
||||
ReactDOM.render(<DatePicker />, mountNode);
|
||||
@@ -58,81 +41,66 @@ 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 or babel-loader option
|
||||
// .babelrc
|
||||
{
|
||||
"plugins": [
|
||||
["import", { libraryName: "antd", style: "css" }] // `style: true` for less
|
||||
]
|
||||
"plugins": [["antd", { style: "css" }]]
|
||||
}
|
||||
```
|
||||
|
||||
Then you can import components from antd, equivalent to import manually below.
|
||||
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';
|
||||
```
|
||||
|
||||
- Manually import
|
||||
|
||||
```jsx
|
||||
import DatePicker from 'antd/lib/date-picker'; // for js
|
||||
import 'antd/lib/date-picker/style/css'; // for css
|
||||
// import 'antd/lib/date-picker/style'; // that will import less
|
||||
import DatePicker from 'antd/lib/date-picker'; // just for js
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
```js
|
||||
// tsconfig.json
|
||||
## Browser Support
|
||||
|
||||
Normal browsers and Internet Explorer 8+.
|
||||
|
||||
> [IE8 issues](https://github.com/xcatliu/react-ie8)
|
||||
|
||||
## TypeScript
|
||||
|
||||
tsconfig.json
|
||||
|
||||
```
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true
|
||||
"jsx": "preserve"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Note:
|
||||
> - set `allowSyntheticDefaultImports` to prevent `error TS1192: Module 'react' has no default export`.
|
||||
> - Don't use @types/antd, antd provide a built-in ts definition already.
|
||||
|
||||
## Internationalization
|
||||
|
||||
See [i18n](http://ant.design/docs/react/i18n).
|
||||
|
||||
## Links
|
||||
|
||||
- [Home page](http://ant.design/)
|
||||
- [UI library](http://ant.design/docs/react/introduce)
|
||||
- [Change Log](CHANGELOG.en-US.md)
|
||||
- [Offcial Scaffold Tool](https://github.com/dvajs/dva-cli/)
|
||||
- [Development Tool](http://ant-tool.github.io/)
|
||||
- [Scaffold Market](http://scaffold.ant.design)
|
||||
- [rc-components](http://react-component.github.io/)
|
||||
- [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/)
|
||||
- [Mobile UI](http://mobile.ant.design)
|
||||
- [Motion](https://motion.ant.design)
|
||||
- [React style guide](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-code-style.md)
|
||||
- [React component design guide](https://github.com/react-component/react-component.github.io/blob/master/docs/zh-cn/component-design.md)
|
||||
- [Developer Instruction](https://github.com/ant-design/ant-design/wiki/Development)
|
||||
- [Versioning Release Note](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B)
|
||||
- [Boilerplates](https://github.com/ant-design/ant-design/issues/129)
|
||||
- [FAQ](https://github.com/ant-design/ant-design/wiki/FAQ)
|
||||
- [CodePen boilerplate](http://codepen.io/benjycui/pen/KgPZrE?editors=001) for bug reports
|
||||
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
|
||||
- [Customize Theme](http://ant.design/docs/react/customize-theme)
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
$ git clone git@github.com:ant-design/ant-design.git
|
||||
$ npm install
|
||||
$ npm start
|
||||
```
|
||||
|
||||
Open your browser and visit http://127.0.0.1:8001 , see more at https://github.com/ant-design/ant-design/wiki/Development .
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome all contributions, please read our [CONTRIBUTING.md](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md) first. You can submit any ideas as [pull requests](https://github.com/ant-design/ant-design/pulls) or as [GitHub issues](https://github.com/ant-design/ant-design/issues). If you'd like to improve code, check out the [Development Instructions](https://github.com/ant-design/ant-design/wiki/Development) and have a good time! :)
|
||||
We welcome all contributions, please read our [CONTRIBUTING.md](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md) first. You can submit any ideas as [pull requests](https://github.com/ant-design/ant-design/pulls) or as a [GitHub issue](https://github.com/ant-design/ant-design/issues). If you'd like to improve code, check out the [Development Instruction](https://github.com/ant-design/ant-design/wiki/Development) and have a good time! :)
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`antd exports modules correctly 1`] = `
|
||||
Array [
|
||||
"Affix",
|
||||
"Anchor",
|
||||
"AutoComplete",
|
||||
"Alert",
|
||||
"Avatar",
|
||||
"BackTop",
|
||||
"Badge",
|
||||
"Breadcrumb",
|
||||
"Button",
|
||||
"Calendar",
|
||||
"Card",
|
||||
"Collapse",
|
||||
"Carousel",
|
||||
"Cascader",
|
||||
"Checkbox",
|
||||
"Col",
|
||||
"DatePicker",
|
||||
"Dropdown",
|
||||
"Form",
|
||||
"Icon",
|
||||
"Input",
|
||||
"InputNumber",
|
||||
"Layout",
|
||||
"LocaleProvider",
|
||||
"message",
|
||||
"Menu",
|
||||
"Modal",
|
||||
"notification",
|
||||
"Pagination",
|
||||
"Popconfirm",
|
||||
"Popover",
|
||||
"Progress",
|
||||
"Radio",
|
||||
"Rate",
|
||||
"Row",
|
||||
"Select",
|
||||
"Slider",
|
||||
"Spin",
|
||||
"Steps",
|
||||
"Switch",
|
||||
"Table",
|
||||
"Transfer",
|
||||
"Tree",
|
||||
"TreeSelect",
|
||||
"Tabs",
|
||||
"Tag",
|
||||
"TimePicker",
|
||||
"Timeline",
|
||||
"Tooltip",
|
||||
"Mention",
|
||||
"Upload",
|
||||
"version",
|
||||
]
|
||||
`;
|
||||
@@ -1,7 +0,0 @@
|
||||
import * as antd from '..';
|
||||
|
||||
describe('antd', () => {
|
||||
it('exports modules correctly', () => {
|
||||
expect(Object.keys(antd)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import throttleByAnimationFrame from '../throttleByAnimationFrame';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
describe('Test utils function', () => {
|
||||
it('throttle function should work', () => {
|
||||
const callback = jest.fn();
|
||||
const throttled = throttleByAnimationFrame(callback);
|
||||
expect(callback).not.toBeCalled();
|
||||
|
||||
throttled();
|
||||
throttled();
|
||||
|
||||
jest.runAllTimers();
|
||||
expect(callback).toBeCalled();
|
||||
expect(callback.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('throttle function should be canceled', () => {
|
||||
const callback = jest.fn();
|
||||
const throttled = throttleByAnimationFrame(callback);
|
||||
|
||||
throttled();
|
||||
throttled.cancel();
|
||||
|
||||
jest.runAllTimers();
|
||||
expect(callback).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
import assign from 'object-assign';
|
||||
|
||||
export function getComponentLocale(props, context, componentName, getDefaultLocale) {
|
||||
let locale: any = {};
|
||||
if (context && context.antLocale && context.antLocale[componentName]) {
|
||||
locale = context.antLocale[componentName];
|
||||
} else {
|
||||
const defaultLocale = getDefaultLocale();
|
||||
// TODO: make default lang of antd be English
|
||||
// https://github.com/ant-design/ant-design/issues/6334
|
||||
locale = defaultLocale.default || defaultLocale;
|
||||
}
|
||||
|
||||
const result = assign({}, locale, props.locale);
|
||||
result.lang = assign({}, locale.lang, props.locale.lang);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getLocaleCode(context) {
|
||||
const localeCode = context.antLocale && context.antLocale.locale;
|
||||
// Had use LocaleProvide but didn't set locale
|
||||
if (context.antLocale && context.antLocale.exist && !localeCode) {
|
||||
return 'zh-cn';
|
||||
}
|
||||
return localeCode;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
const availablePrefixs = ['moz', 'ms', 'webkit'];
|
||||
|
||||
function requestAnimationFramePolyfill() {
|
||||
let lastTime = 0;
|
||||
return function(callback) {
|
||||
const currTime = new Date().getTime();
|
||||
const timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
const id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
}
|
||||
|
||||
export default function getRequestAnimationFrame() {
|
||||
if (typeof window === 'undefined') {
|
||||
return () => {};
|
||||
}
|
||||
if (window.requestAnimationFrame) {
|
||||
return window.requestAnimationFrame;
|
||||
}
|
||||
|
||||
const prefix = availablePrefixs.filter(key => `${key}RequestAnimationFrame` in window)[0];
|
||||
|
||||
return prefix
|
||||
? window[`${prefix}RequestAnimationFrame`]
|
||||
: requestAnimationFramePolyfill();
|
||||
}
|
||||
|
||||
export function cancelRequestAnimationFrame(id) {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
if (window.cancelAnimationFrame) {
|
||||
return window.cancelAnimationFrame(id);
|
||||
}
|
||||
const prefix = availablePrefixs.filter(key =>
|
||||
`${key}CancelAnimationFrame` in window || `${key}CancelRequestAnimationFrame` in window,
|
||||
)[0];
|
||||
|
||||
return prefix ?
|
||||
(window[`${prefix}CancelAnimationFrame`] || window[`${prefix}CancelRequestAnimationFrame`]).call(this, id)
|
||||
: clearTimeout(id);
|
||||
}
|
||||
@@ -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,10 +0,0 @@
|
||||
export default function isFlexSupported() {
|
||||
if (typeof window !== 'undefined' && window.document && window.document.documentElement) {
|
||||
const { documentElement } = window.document;
|
||||
return 'flex' in documentElement.style ||
|
||||
'webkitFlex' in documentElement.style ||
|
||||
'Flex' in documentElement.style ||
|
||||
'msFlex' in documentElement.style;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1,37 +1,21 @@
|
||||
import cssAnimation from 'css-animation';
|
||||
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from './getRequestAnimationFrame';
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
function animate(node, show, done) {
|
||||
let height;
|
||||
let requestAnimationFrameId;
|
||||
return cssAnimation(node, 'ant-motion-collapse', {
|
||||
start() {
|
||||
if (!show) {
|
||||
node.style.height = `${node.offsetHeight}px`;
|
||||
node.style.opacity = 1;
|
||||
} else {
|
||||
height = node.offsetHeight;
|
||||
node.style.height = 0;
|
||||
node.style.opacity = 0;
|
||||
}
|
||||
},
|
||||
active() {
|
||||
if (requestAnimationFrameId) {
|
||||
cancelRequestAnimationFrame(requestAnimationFrameId);
|
||||
}
|
||||
requestAnimationFrameId = reqAnimFrame(() => {
|
||||
node.style.height = `${show ? height : 0}px`;
|
||||
node.style.opacity = show ? 1 : 0;
|
||||
});
|
||||
node.style.height = `${show ? height : 0}px`;
|
||||
},
|
||||
end() {
|
||||
if (requestAnimationFrameId) {
|
||||
cancelRequestAnimationFrame(requestAnimationFrameId);
|
||||
}
|
||||
node.style.height = '';
|
||||
node.style.opacity = '';
|
||||
done();
|
||||
},
|
||||
});
|
||||
@@ -1,47 +0,0 @@
|
||||
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from '../_util/getRequestAnimationFrame';
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
export default function throttleByAnimationFrame(fn) {
|
||||
let requestId;
|
||||
|
||||
const later = args => () => {
|
||||
requestId = null;
|
||||
fn(...args);
|
||||
};
|
||||
|
||||
const throttled = (...args) => {
|
||||
if (requestId == null) {
|
||||
requestId = reqAnimFrame(later(args));
|
||||
}
|
||||
};
|
||||
|
||||
(throttled as any).cancel = () => cancelRequestAnimationFrame(requestId);
|
||||
|
||||
return throttled;
|
||||
}
|
||||
|
||||
export function throttleByAnimationFrameDecorator() {
|
||||
return function(target, key, descriptor) {
|
||||
let fn = descriptor.value;
|
||||
let definingProperty = false;
|
||||
return {
|
||||
configurable: true,
|
||||
get() {
|
||||
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
|
||||
return fn;
|
||||
}
|
||||
|
||||
let boundFn = throttleByAnimationFrame(fn.bind(this));
|
||||
definingProperty = true;
|
||||
Object.defineProperty(this, key, {
|
||||
value: boundFn,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
});
|
||||
definingProperty = false;
|
||||
return boundFn;
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
export default function triggerEvent(el, type) {
|
||||
if ('createEvent' in document) {
|
||||
// modern browsers, IE9+
|
||||
const e = document.createEvent('HTMLEvents');
|
||||
e.initEvent(type, false, true);
|
||||
el.dispatchEvent(e);
|
||||
}
|
||||
}
|
||||
@@ -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,68 +0,0 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Affix from '..';
|
||||
import Button from '../../button';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
const events = {};
|
||||
|
||||
class AffixMounter extends React.Component {
|
||||
componentDidMount() {
|
||||
this.container.scrollTop = 100;
|
||||
this.container.addEventListener = jest.fn().mockImplementation((event, cb) => {
|
||||
events[event] = cb;
|
||||
});
|
||||
}
|
||||
getTarget = () => {
|
||||
return this.container;
|
||||
}
|
||||
render() {
|
||||
return (<div
|
||||
style={{
|
||||
height: 100,
|
||||
overflowY: 'scroll',
|
||||
}}
|
||||
ref={(node) => { this.container = node; }}
|
||||
>
|
||||
<div
|
||||
className="background"
|
||||
style={{
|
||||
paddingTop: 60,
|
||||
height: 300,
|
||||
}}
|
||||
>
|
||||
<Affix
|
||||
target={() => this.container}
|
||||
ref={ele => this.affix = ele}
|
||||
>
|
||||
<Button type="primary" >
|
||||
Fixed at the top of container
|
||||
</Button>
|
||||
</Affix>
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Affix Render', () => {
|
||||
it('Anchor render perfectly', () => {
|
||||
document.body.innerHTML = '<div id="mounter" />';
|
||||
|
||||
const wrapper = mount(<AffixMounter />, { attachTo: document.getElementById('mounter') });
|
||||
jest.runAllTimers();
|
||||
|
||||
wrapper.node.affix.refs.fixedNode.parentNode.getBoundingClientRect = jest.fn(() => {
|
||||
return {
|
||||
bottom: 100, height: 28, left: 0, right: 0, top: -50, width: 195,
|
||||
};
|
||||
});
|
||||
|
||||
events.scroll({
|
||||
type: 'scroll',
|
||||
});
|
||||
|
||||
jest.runAllTimers();
|
||||
expect(wrapper.node.affix.state.affixStyle).not.toBe(null);
|
||||
});
|
||||
});
|
||||
@@ -1,77 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/affix/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Affix top
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Affix bottom
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/affix/demo/on-change.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
120px to affix top
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/affix/demo/target.md correctly 1`] = `
|
||||
<div
|
||||
class="scrollable-container"
|
||||
>
|
||||
<div
|
||||
class="background"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Fixed at the top of container
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('affix');
|
||||
@@ -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,48 +1,29 @@
|
||||
---
|
||||
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';
|
||||
|
||||
class Demo extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="scrollable-container" ref={(node) => { this.container = node; }}>
|
||||
<div className="background">
|
||||
<Affix target={() => this.container}>
|
||||
<Button type="primary">
|
||||
Fixed at the top of container
|
||||
</Button>
|
||||
const Demo = () => {
|
||||
return (
|
||||
<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('affix-target')} offsetTop={20}>
|
||||
<Button type="primary">固定在容器顶部</Button>
|
||||
</Affix>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-affix-demo-target .scrollable-container {
|
||||
height: 100px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
#components-affix-demo-target .background {
|
||||
padding-top: 60px;
|
||||
height: 300px;
|
||||
background-image: url('https://zos.alipayobjects.com/rmsportal/RmjwQiJorKyobvI.jpg');
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Navigation
|
||||
title: Affix
|
||||
---
|
||||
|
||||
Make an element sticky to viewport.
|
||||
|
||||
## When To Use
|
||||
|
||||
When user browses a long web page, some content need to stick to the viewport. This is common for menus and actions.
|
||||
|
||||
Please note that Affix should not cover other content on the page, especially when the size of the 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 | - |
|
||||
| target | specifies the scrollable area dom node | () => HTMLElement | () => window |
|
||||
| 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>
|
||||
```
|
||||
@@ -1,20 +1,31 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
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';
|
||||
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
||||
|
||||
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);
|
||||
|
||||
@@ -30,48 +41,22 @@ function getOffset(element: HTMLElement, target) {
|
||||
scrollTop - clientTop,
|
||||
left: elemRect.left - targetRect.left +
|
||||
scrollLeft - clientLeft,
|
||||
width: elemRect.width,
|
||||
height: elemRect.height,
|
||||
};
|
||||
}
|
||||
|
||||
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: PropTypes.number,
|
||||
offsetBottom: PropTypes.number,
|
||||
target: PropTypes.func,
|
||||
};
|
||||
offsetTop: React.PropTypes.number,
|
||||
offsetBottom: React.PropTypes.number,
|
||||
target: React.PropTypes.func,
|
||||
}
|
||||
|
||||
scrollEvent: any;
|
||||
resizeEvent: any;
|
||||
timeout: any;
|
||||
refs: {
|
||||
fixedNode: HTMLElement;
|
||||
};
|
||||
static defaultProps = {
|
||||
target() {
|
||||
return window;
|
||||
},
|
||||
onChange() {},
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -82,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) {
|
||||
@@ -100,33 +85,31 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
});
|
||||
}
|
||||
|
||||
setPlaceholderStyle(placeholderStyle) {
|
||||
setPlaceholderStyle(e, placeholderStyle) {
|
||||
const originalPlaceholderStyle = this.state.placeholderStyle;
|
||||
if (e.type === 'resize') {
|
||||
return;
|
||||
}
|
||||
if (shallowequal(placeholderStyle, originalPlaceholderStyle)) {
|
||||
return;
|
||||
}
|
||||
this.setState({ placeholderStyle });
|
||||
}
|
||||
|
||||
@throttleByAnimationFrameDecorator()
|
||||
updatePosition(e) {
|
||||
let { offsetTop, offsetBottom, offset, target = getDefaultTarget } = this.props;
|
||||
updatePosition = (e) => {
|
||||
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;
|
||||
@@ -137,55 +120,46 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
}
|
||||
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const targetInnerHeight =
|
||||
(targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight;
|
||||
if (scrollTop > elemOffset.top - (offsetTop as number) && offsetMode.top) {
|
||||
const targetInnerHeight = targetNode.innerHeight || targetNode.clientHeight;
|
||||
if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) {
|
||||
// Fixed Top
|
||||
const width = elemOffset.width;
|
||||
this.setAffixStyle(e, {
|
||||
position: 'fixed',
|
||||
top: targetRect.top + (offsetTop as number),
|
||||
top: targetRect.top + offsetTop,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width,
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle({
|
||||
width,
|
||||
height: affixNode.offsetHeight,
|
||||
this.setPlaceholderStyle(e, {
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
height: ReactDOM.findDOMNode(this).offsetHeight,
|
||||
});
|
||||
} else if (
|
||||
scrollTop < elemOffset.top + elemSize.height + (offsetBottom as number) - targetInnerHeight &&
|
||||
scrollTop < elemOffset.top + elemSize.height + offsetBottom - targetInnerHeight &&
|
||||
offsetMode.bottom
|
||||
) {
|
||||
// Fixed Bottom
|
||||
const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom);
|
||||
const width = elemOffset.width;
|
||||
this.setAffixStyle(e, {
|
||||
position: 'fixed',
|
||||
bottom: targetBottomOffet + (offsetBottom as number),
|
||||
bottom: targetBottomOffet + offsetBottom,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width,
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle({
|
||||
width,
|
||||
height: affixNode.offsetHeight,
|
||||
this.setPlaceholderStyle(e, {
|
||||
width: ReactDOM.findDOMNode(this).offsetWidth,
|
||||
height: ReactDOM.findDOMNode(this).offsetHeight,
|
||||
});
|
||||
} else {
|
||||
const { affixStyle } = this.state;
|
||||
if (e.type === 'resize' && affixStyle && affixStyle.position === 'fixed' && affixNode.offsetWidth) {
|
||||
this.setAffixStyle(e, { ...affixStyle, width: affixNode.offsetWidth });
|
||||
} else {
|
||||
this.setAffixStyle(e, null);
|
||||
}
|
||||
this.setPlaceholderStyle(null);
|
||||
this.setAffixStyle(e, null);
|
||||
this.setPlaceholderStyle(e, null);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const target = this.props.target || getDefaultTarget;
|
||||
// Wait for parent component ref has its value
|
||||
this.timeout = setTimeout(() => {
|
||||
this.setTargetEventListeners(target);
|
||||
});
|
||||
warning(!('offset' in this.props), '`offset` prop of Affix is deprecated, use `offsetTop` instead.');
|
||||
|
||||
const target = this.props.target;
|
||||
this.setTargetEventListeners(target);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
@@ -200,16 +174,10 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clearScrollEventListeners();
|
||||
clearTimeout(this.timeout);
|
||||
(this.updatePosition as any).cancel();
|
||||
}
|
||||
|
||||
setTargetEventListeners(getTarget) {
|
||||
const target = getTarget();
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
this.clearScrollEventListeners();
|
||||
this.scrollEvent = addEventListener(target, 'scroll', this.updatePosition);
|
||||
this.resizeEvent = addEventListener(target, 'resize', this.updatePosition);
|
||||
}
|
||||
@@ -224,13 +192,16 @@ 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', 'onChange']);
|
||||
const placeholderStyle = { ...this.state.placeholderStyle, ...this.props.style };
|
||||
const props = { ...this.props };
|
||||
delete props.offsetTop;
|
||||
delete props.offsetBottom;
|
||||
delete props.target;
|
||||
|
||||
return (
|
||||
<div {...props} style={placeholderStyle}>
|
||||
<div {...props} style={this.state.placeholderStyle}>
|
||||
<div className={className} ref="fixedNode" style={this.state.affixStyle}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 固钉
|
||||
type: Navigation
|
||||
title: Affix
|
||||
chinese: 固钉
|
||||
type: Other
|
||||
english: Affix
|
||||
---
|
||||
|
||||
将页面元素钉在可视范围。
|
||||
@@ -15,17 +15,10 @@ title: Affix
|
||||
|
||||
## API
|
||||
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 |
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window |
|
||||
| onChange | 固定状态改变时触发的回调函数 | Function(affixed) | 无 |
|
||||
|
||||
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
|
||||
|
||||
```jsx
|
||||
<Affix style={{ position: 'absolute', top: y, left: x}}>
|
||||
...
|
||||
</Affix>
|
||||
```
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | Number | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | Number | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |
|
||||
| onChange | 固定状态改变时触发的回调函数 | Function | 无 |
|
||||
@@ -1,6 +1,6 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
.@{ant-prefix}-affix {
|
||||
.ant-affix {
|
||||
position: fixed;
|
||||
z-index: @zindex-affix;
|
||||
}
|
||||
|
||||
@@ -1,424 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-banner"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-exclamation-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-banner"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-exclamation-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Very long warning text warning text text text text text text text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<a
|
||||
class="ant-alert-close-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-cross"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-no-icon ant-alert-banner"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning text without icon
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
<div
|
||||
class="ant-alert ant-alert-error ant-alert-banner"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-cross-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Error text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/alert/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-alert ant-alert-success ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Success Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/alert/demo/closable.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<a
|
||||
class="ant-alert-close-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-cross"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-error ant-alert-with-description ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Error Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Error Description Error Description Error Description Error Description Error Description Error Description
|
||||
</span>
|
||||
<a
|
||||
class="ant-alert-close-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-cross"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/alert/demo/close-text.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-alert ant-alert-info ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Info Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
<a
|
||||
class="ant-alert-close-icon"
|
||||
>
|
||||
Close Now
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/alert/demo/description.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-alert ant-alert-success ant-alert-with-description ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Success Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Success Description Success Description Success Description
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-info ant-alert-with-description ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Info Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Info Description Info Description Info Description Info Description
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-with-description ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Warning Description Warning Description Warning Description Warning Description
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-error ant-alert-with-description ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Error Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Error Description Error Description Error Description Error Description
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/alert/demo/icon.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-alert ant-alert-success"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-check-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Success Tips
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-info"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-info-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Informational Notes
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-warning"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-exclamation-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-error"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-cross-circle ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Error
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-success ant-alert-with-description"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-check-circle-o ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
success tips
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Detailed description and advices about successful copywriting.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-info ant-alert-with-description"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-info-circle-o ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Informational Notes
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
Additional description and informations about copywriting.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-with-description"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-exclamation-circle-o ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
This is a warning notice about copywriting.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-error ant-alert-with-description"
|
||||
data-show="true"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-cross-circle-o ant-alert-icon"
|
||||
/>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Error
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
>
|
||||
This is an error message about copywriting.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/alert/demo/style.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-alert ant-alert-success ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Success Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-info ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Info Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-warning ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Warning Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-alert ant-alert-error ant-alert-no-icon"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-alert-message"
|
||||
>
|
||||
Error Text
|
||||
</span>
|
||||
<span
|
||||
class="ant-alert-description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('alert');
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
order: 6
|
||||
iframe: 250
|
||||
title:
|
||||
zh-CN: 顶部公告
|
||||
en-US: Banner
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
页面顶部通告形式,默认有图标且`type` 为 'warning'。
|
||||
|
||||
## en-US
|
||||
|
||||
Display Alert as a banner at top of page.
|
||||
|
||||
````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 />
|
||||
<br />
|
||||
<Alert showIcon={false} message="Warning text without icon" banner />
|
||||
<br />
|
||||
<Alert type="error" message="Error text" banner />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,28 +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);
|
||||
````
|
||||
|
||||
<style>
|
||||
.ant-alert {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -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: Feedback
|
||||
title: Alert
|
||||
---
|
||||
|
||||
Alert component for feedback.
|
||||
|
||||
## When To Use
|
||||
|
||||
- When you need to show alert messages for users.
|
||||
- When you need a persistent static container which is closable by user actions.
|
||||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | Type of Alert styles, options:`success`, `info`, `warning`, `error` | string | `info`, in `banner` mode it's `warning` |
|
||||
| closable | Whether Alert can be closed | boolean | - |
|
||||
| closeText | Close text to show | string\|ReactNode | - |
|
||||
| message | Content of Alert | string\|ReactNode | - |
|
||||
| description | Additional content of Alert | string\|ReactNode | - |
|
||||
| onClose | Callback when close Alert | Function | - |
|
||||
| showIcon | Whether to show icon | boolean | false, in `banner` mode it's true |
|
||||
| banner | Whether to show as banner | boolean | false |
|
||||
72
components/alert/index.tsx → components/alert/index.jsx
Executable file → Normal file
72
components/alert/index.tsx → components/alert/index.jsx
Executable file → Normal file
@@ -4,42 +4,23 @@ 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<HTMLAnchorElement>;
|
||||
/** Whether to show icon */
|
||||
showIcon?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
banner?: boolean;
|
||||
}
|
||||
|
||||
export default class Alert extends React.Component<AlertProps, any> {
|
||||
constructor(props: AlertProps) {
|
||||
export default class Alert extends React.Component {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-alert',
|
||||
showIcon: false,
|
||||
onClose() {},
|
||||
type: 'info',
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
closing: true,
|
||||
closed: false,
|
||||
};
|
||||
}
|
||||
handleClose = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
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
|
||||
@@ -48,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({
|
||||
@@ -58,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 = banner && showIcon === undefined ? true : showIcon;
|
||||
// banner模式默认为警告
|
||||
type = banner && type === undefined ? 'warning' : type || 'info';
|
||||
|
||||
let iconType = '';
|
||||
switch (type) {
|
||||
case 'success':
|
||||
@@ -90,37 +65,32 @@ export default class Alert extends React.Component<AlertProps, any> {
|
||||
iconType += '-o';
|
||||
}
|
||||
|
||||
let alertCls = classNames(prefixCls, {
|
||||
let alertCls = classNames({
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-${type}`]: true,
|
||||
[`${prefixCls}-close`]: !this.state.closing,
|
||||
[`${prefixCls}-with-description`]: !!description,
|
||||
[`${prefixCls}-no-icon`]: !showIcon,
|
||||
[`${prefixCls}-banner`]: !!banner,
|
||||
}, className);
|
||||
});
|
||||
|
||||
// closeable when closeText is assigned
|
||||
if (closeText) {
|
||||
closable = true;
|
||||
}
|
||||
|
||||
const closeIcon = closable ? (
|
||||
<a onClick={this.handleClose} className={`${prefixCls}-close-icon`}>
|
||||
{closeText || <Icon type="cross" />}
|
||||
</a>
|
||||
) : null;
|
||||
|
||||
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>
|
||||
{closeIcon}
|
||||
{closable ? <a onClick={this.handleClose} className={`${prefixCls}-close-icon`}>
|
||||
{closeText || <Icon type="cross" />}
|
||||
</a> : null}
|
||||
</div>
|
||||
</Animate>
|
||||
);
|
||||
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,26 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 警告提示
|
||||
type: Feedback
|
||||
title: Alert
|
||||
---
|
||||
|
||||
警告提示,展现需要关注的信息。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 当某个页面需要向用户显示警告的信息时。
|
||||
- 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info`,`banner` 模式下默认值为 `warning` |
|
||||
| closable | 默认不显示关闭按钮 | boolean | 无 |
|
||||
| closeText | 自定义关闭按钮 | string\|ReactNode | 无 |
|
||||
| message | 警告提示内容 | string\|ReactNode | 无 |
|
||||
| description | 警告提示的辅助性文字介绍 | string\|ReactNode | 无 |
|
||||
| onClose | 关闭时触发的回调函数 | Function | 无 |
|
||||
| showIcon | 是否显示辅助图标 | boolean | false,`banner` 模式下默认值为 true |
|
||||
| banner | 是否用作顶部公告 | boolean | false |
|
||||
@@ -1,82 +1,78 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
@alert-prefix-cls: ~"@{ant-prefix}-alert";
|
||||
|
||||
@alert-message-color: @heading-color;
|
||||
@alert-text-color: @text-color;
|
||||
@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: @alert-text-color;
|
||||
font-size: @font-size-base;
|
||||
color: @text-color;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
|
||||
&&-no-icon {
|
||||
padding: 8px 48px 8px 16px;
|
||||
}
|
||||
margin-bottom: 10px;
|
||||
|
||||
&-icon {
|
||||
font-size: @font-size-lg;
|
||||
top: 9.5px;
|
||||
left: 16px;
|
||||
position: absolute;
|
||||
margin-right: 8px;
|
||||
font-size: 14px;
|
||||
top: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: @font-size-base;
|
||||
font-size: 12px;
|
||||
color: @legend-color;
|
||||
line-height: 21px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-success {
|
||||
border: @border-width-base @border-style-base @green-2;
|
||||
background-color: @green-1;
|
||||
border: 1px solid tint(@success-color, 80%);
|
||||
background-color: tint(@success-color, 90%);
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-info {
|
||||
border: @border-width-base @border-style-base @primary-2;
|
||||
background-color: @primary-1;
|
||||
border: 1px solid tint(@primary-color, 80%);
|
||||
background-color: tint(@primary-color, 90%);
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @info-color;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-warning {
|
||||
border: @border-width-base @border-style-base @yellow-2;
|
||||
background-color: @yellow-1;
|
||||
border: 1px solid tint(@warning-color, 80%);
|
||||
background-color: tint(@warning-color, 90%);
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-error {
|
||||
border: @border-width-base @border-style-base @red-2;
|
||||
background-color: @red-1;
|
||||
border: 1px solid tint(@error-color, 80%);
|
||||
background-color: tint(@error-color, 90%);
|
||||
.@{alert-prefix-cls}-icon {
|
||||
color: @error-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-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 {
|
||||
color: @text-color-secondary;
|
||||
.anticon-cross {
|
||||
color: @legend-color;
|
||||
transition: color .3s ease;
|
||||
&:hover {
|
||||
color: #404040;
|
||||
color: #444;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,9 +83,10 @@
|
||||
}
|
||||
|
||||
&-with-description {
|
||||
padding: 16px 16px 16px 60px;
|
||||
padding: 16px 16px 16px 69px;
|
||||
position: relative;
|
||||
border-radius: @border-radius-base;
|
||||
margin-bottom: 10px;
|
||||
color: @text-color;
|
||||
line-height: 1.5;
|
||||
}
|
||||
@@ -100,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: @font-size-lg;
|
||||
color: @alert-message-color;
|
||||
font-size: 14px;
|
||||
color: @text-color;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&-with-description &-description {
|
||||
@@ -137,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,109 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import AnchorHelper, { scrollTo } from './anchorHelper';
|
||||
|
||||
export interface AnchorLinkProps {
|
||||
href: string;
|
||||
onClick?: (href: string, component: Element) => void;
|
||||
active?: boolean;
|
||||
prefixCls?: string;
|
||||
children?: any;
|
||||
title: React.ReactNode;
|
||||
offsetTop?: number;
|
||||
bounds?: number;
|
||||
target?: () => HTMLElement | Window;
|
||||
affix?: boolean;
|
||||
}
|
||||
|
||||
export default class AnchorLink extends React.Component<AnchorLinkProps, any> {
|
||||
static __ANT_ANCHOR_LINK = true;
|
||||
static contextTypes = {
|
||||
anchorHelper: PropTypes.any,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
href: '#',
|
||||
prefixCls: 'ant-anchor',
|
||||
};
|
||||
|
||||
context: {
|
||||
anchorHelper: AnchorHelper;
|
||||
};
|
||||
|
||||
private _component: HTMLAnchorElement;
|
||||
|
||||
setActiveAnchor() {
|
||||
const { bounds, offsetTop, href, affix } = this.props;
|
||||
const { anchorHelper } = this.context;
|
||||
const active = affix && anchorHelper && anchorHelper.getCurrentAnchor(offsetTop, bounds) === href;
|
||||
if (active && anchorHelper) {
|
||||
anchorHelper.setActiveAnchor(this._component);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setActiveAnchor();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.setActiveAnchor();
|
||||
}
|
||||
|
||||
renderAnchorLink = (child: React.ReactChild) => {
|
||||
// Here child is a ReactChild type
|
||||
if (typeof child !== 'string' && typeof child !== 'number') {
|
||||
const { href } = child.props;
|
||||
if (href) {
|
||||
this.context.anchorHelper.addLink(href);
|
||||
return React.cloneElement(child, {
|
||||
onClick: this.props.onClick,
|
||||
prefixCls: this.props.prefixCls,
|
||||
affix: this.props.affix,
|
||||
offsetTop: this.props.offsetTop,
|
||||
});
|
||||
}
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
refsTo = (component: HTMLAnchorElement) => {
|
||||
this._component = component;
|
||||
}
|
||||
|
||||
scrollTo = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
e.preventDefault();
|
||||
const { onClick, href } = this.props;
|
||||
const { anchorHelper } = this.context;
|
||||
if (onClick) {
|
||||
onClick(href, this._component);
|
||||
} else {
|
||||
const scrollToFn = anchorHelper ? anchorHelper.scrollTo : scrollTo;
|
||||
scrollToFn(href, this.props.offsetTop);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, href, children, title, bounds, offsetTop, affix } = this.props;
|
||||
const { anchorHelper } = this.context;
|
||||
const active = affix && anchorHelper && anchorHelper.getCurrentAnchor(offsetTop, bounds) === href;
|
||||
const cls = classNames({
|
||||
[`${prefixCls}-link`]: true,
|
||||
[`${prefixCls}-link-active`]: active,
|
||||
});
|
||||
return (
|
||||
<div className={cls}>
|
||||
<a
|
||||
ref={this.refsTo}
|
||||
className={`${prefixCls}-link-title`}
|
||||
onClick={this.scrollTo}
|
||||
href={href}
|
||||
title={typeof title === 'string' ? title : ''}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
{React.Children.map(children, this.renderAnchorLink)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Anchor from '..';
|
||||
|
||||
const { Link } = Anchor;
|
||||
|
||||
describe('Anchor Render', () => {
|
||||
it('Anchor render perfectly', () => {
|
||||
const wrapper = mount(
|
||||
<Anchor>
|
||||
<Link href="#API" title="API" />
|
||||
</Anchor>
|
||||
);
|
||||
|
||||
wrapper.find('a[href="#API"]').simulate('click');
|
||||
|
||||
wrapper.node.handleScroll();
|
||||
expect(wrapper.node.state).not.toBe(null);
|
||||
});
|
||||
});
|
||||
@@ -1,153 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/anchor/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-ink"
|
||||
>
|
||||
<span
|
||||
class="ant-anchor-ink-ball animated"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-basic"
|
||||
title="Basic demo"
|
||||
>
|
||||
Basic demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-fixed"
|
||||
title="Fixed demo"
|
||||
>
|
||||
Fixed demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#API"
|
||||
title="API"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Anchor-Props"
|
||||
title="Anchor Props"
|
||||
>
|
||||
Anchor Props
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Link-Props"
|
||||
title="Link Props"
|
||||
>
|
||||
Link Props
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/anchor/demo/fixed.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-anchor-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor fixed"
|
||||
>
|
||||
<div
|
||||
class="ant-anchor-ink"
|
||||
>
|
||||
<span
|
||||
class="ant-anchor-ink-ball animated"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-basic"
|
||||
title="Basic demo"
|
||||
>
|
||||
Basic demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#components-anchor-demo-fixed"
|
||||
title="Fixed demo"
|
||||
>
|
||||
Fixed demo
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#API"
|
||||
title="API"
|
||||
>
|
||||
API
|
||||
</a>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Anchor-Props"
|
||||
title="Anchor Props"
|
||||
>
|
||||
Anchor Props
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ant-anchor-link"
|
||||
>
|
||||
<a
|
||||
class="ant-anchor-link-title"
|
||||
href="#Link-Props"
|
||||
title="Link Props"
|
||||
>
|
||||
Link Props
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('anchor');
|
||||
@@ -1,129 +0,0 @@
|
||||
import getScroll from '../_util/getScroll';
|
||||
import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
|
||||
|
||||
export const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
export const easeInOutCubic = (t: number, b: number, c: number, d: number) => {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return cc / 2 * t * t * t + b;
|
||||
}
|
||||
return cc / 2 * ((t -= 2) * t * t + 2) + b;
|
||||
};
|
||||
|
||||
export function getDefaultTarget() {
|
||||
return typeof window !== 'undefined' ?
|
||||
window : null;
|
||||
}
|
||||
|
||||
export function getOffsetTop(element: HTMLElement): number {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!element.getClientRects().length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
|
||||
if (rect.width || rect.height) {
|
||||
const doc = element.ownerDocument;
|
||||
const docElem = doc.documentElement;
|
||||
return rect.top - docElem.clientTop;
|
||||
}
|
||||
|
||||
return rect.top;
|
||||
}
|
||||
|
||||
export type Section = {
|
||||
top: number;
|
||||
bottom: number;
|
||||
section: any;
|
||||
};
|
||||
|
||||
export function scrollTo(href: string, offsetTop = 0, target = getDefaultTarget, callback = () => { }) {
|
||||
const scrollTop = getScroll(target(), true);
|
||||
const targetElement = document.getElementById(href.substring(1));
|
||||
if (!targetElement) {
|
||||
return;
|
||||
}
|
||||
const eleOffsetTop = getOffsetTop(targetElement);
|
||||
const targetScrollTop = scrollTop + eleOffsetTop - offsetTop;
|
||||
const startTime = Date.now();
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
const time = timestamp - startTime;
|
||||
window.scrollTo(window.pageXOffset, easeInOutCubic(time, scrollTop, targetScrollTop, 450));
|
||||
if (time < 450) {
|
||||
reqAnimFrame(frameFunc);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
reqAnimFrame(frameFunc);
|
||||
history.pushState(null, '', href);
|
||||
}
|
||||
|
||||
class AnchorHelper {
|
||||
private links: Array<string>;
|
||||
private currentAnchor: HTMLAnchorElement | null;
|
||||
private _activeAnchor: string;
|
||||
|
||||
constructor() {
|
||||
this.links = [];
|
||||
this.currentAnchor = null;
|
||||
this._activeAnchor = '';
|
||||
}
|
||||
|
||||
addLink(link: string) {
|
||||
if (this.links.indexOf(link) === -1) {
|
||||
this.links.push(link);
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentActiveAnchor(): HTMLAnchorElement | null {
|
||||
return this.currentAnchor;
|
||||
}
|
||||
|
||||
setActiveAnchor(component: HTMLAnchorElement) {
|
||||
this.currentAnchor = component;
|
||||
}
|
||||
|
||||
getCurrentAnchor(offsetTop: number = 0, bounds = 5) {
|
||||
let activeAnchor = '';
|
||||
if (typeof document === 'undefined') {
|
||||
return activeAnchor;
|
||||
}
|
||||
|
||||
const linksPositions = (this.links
|
||||
.map(section => {
|
||||
const target = document.getElementById(section.substring(1));
|
||||
if (target && getOffsetTop(target) < offsetTop + bounds) {
|
||||
const top = getOffsetTop(target);
|
||||
if (top <= offsetTop + bounds) {
|
||||
return {
|
||||
section,
|
||||
top,
|
||||
bottom: top + target.clientHeight,
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(section => section !== null) as Array<Section>);
|
||||
|
||||
if (linksPositions.length) {
|
||||
const maxSection = linksPositions.reduce((prev, curr) => curr.top > prev.top ? curr : prev);
|
||||
return maxSection.section;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
scrollTo(href: string, offsetTop: number | undefined, target = getDefaultTarget, callback = () => { }) {
|
||||
scrollTo(href, offsetTop, target, callback);
|
||||
}
|
||||
}
|
||||
|
||||
export default AnchorHelper;
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
最简单的用法。
|
||||
|
||||
## en-US
|
||||
|
||||
The simplest usage.
|
||||
|
||||
```jsx
|
||||
import { Anchor } from 'antd';
|
||||
const { Link } = Anchor;
|
||||
|
||||
ReactDOM.render(
|
||||
<Anchor>
|
||||
<Link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<Link href="#components-anchor-demo-fixed" title="Fixed demo" />
|
||||
<Link href="#API" title="API">
|
||||
<Link href="#Anchor-Props" title="Anchor Props" />
|
||||
<Link href="#Link-Props" title="Link Props" />
|
||||
</Link>
|
||||
</Anchor>
|
||||
, mountNode);
|
||||
```
|
||||
|
||||
<style>
|
||||
.code-box-demo .ant-affix {
|
||||
z-index: 11;
|
||||
}
|
||||
</style>
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 固定
|
||||
en-US: Fixed Anchor
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
不浮动,状态不随页面滚动变化。
|
||||
|
||||
## en-US
|
||||
|
||||
Do not change state when page is scrolling.
|
||||
|
||||
```jsx
|
||||
import { Anchor } from 'antd';
|
||||
const { Link } = Anchor;
|
||||
|
||||
ReactDOM.render(
|
||||
<Anchor affix={false}>
|
||||
<Link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<Link href="#components-anchor-demo-fixed" title="Fixed demo" />
|
||||
<Link href="#API" title="API">
|
||||
<Link href="#Anchor-Props" title="Anchor Props" />
|
||||
<Link href="#Link-Props" title="Link Props" />
|
||||
</Link>
|
||||
</Anchor>
|
||||
, mountNode);
|
||||
```
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Other
|
||||
cols: 2
|
||||
title: Anchor
|
||||
---
|
||||
|
||||
Hyperlinks to scroll on one page.
|
||||
|
||||
## When To Use
|
||||
|
||||
For displaying anchor hyperlinks on page and jumping between them.
|
||||
|
||||
## API
|
||||
|
||||
### Anchor Props
|
||||
|
||||
| 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 | - |
|
||||
| bounds | Bounding distance of anchor area | number | 5(px) |
|
||||
| affix | Fixed mode of Anchor | boolean | false |
|
||||
| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false |
|
||||
|
||||
### Link Props
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| href | target of hyperlink | string | |
|
||||
| title | content of hyperlink | string\|ReactNode | |
|
||||
@@ -1,146 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import AnchorLink from './AnchorLink';
|
||||
import Affix from '../affix';
|
||||
import AnchorHelper, { getDefaultTarget } from './anchorHelper';
|
||||
|
||||
export interface AnchorProps {
|
||||
target?: () => HTMLElement | Window;
|
||||
children?: React.ReactNode;
|
||||
prefixCls?: string;
|
||||
offsetTop?: number;
|
||||
bounds?: number;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
affix?: boolean;
|
||||
showInkInFixed?: boolean;
|
||||
}
|
||||
|
||||
export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
static Link = AnchorLink;
|
||||
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-anchor',
|
||||
affix: true,
|
||||
showInkInFixed: false,
|
||||
};
|
||||
|
||||
static childContextTypes = {
|
||||
anchorHelper: PropTypes.any,
|
||||
};
|
||||
|
||||
refs: {
|
||||
ink?: any;
|
||||
};
|
||||
|
||||
private scrollEvent: any;
|
||||
private anchorHelper: AnchorHelper;
|
||||
private _avoidInk: boolean;
|
||||
|
||||
constructor(props: AnchorProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
activeAnchor: null,
|
||||
animated: true,
|
||||
};
|
||||
this.anchorHelper = new AnchorHelper();
|
||||
}
|
||||
|
||||
handleScroll = () => {
|
||||
this.setState({
|
||||
activeAnchor: this.anchorHelper.getCurrentAnchor(this.props.offsetTop, this.props.bounds),
|
||||
});
|
||||
}
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
anchorHelper: this.anchorHelper,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleScroll();
|
||||
this.updateInk();
|
||||
this.scrollEvent = addEventListener((this.props.target || getDefaultTarget)(), 'scroll', this.handleScroll);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.scrollEvent) {
|
||||
this.scrollEvent.remove();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (!this._avoidInk) {
|
||||
this.updateInk();
|
||||
}
|
||||
}
|
||||
|
||||
updateInk = () => {
|
||||
const activeAnchor = this.anchorHelper.getCurrentActiveAnchor();
|
||||
if (activeAnchor) {
|
||||
this.refs.ink.style.top = `${activeAnchor.offsetTop + activeAnchor.clientHeight / 2 - 4.5}px`;
|
||||
}
|
||||
}
|
||||
|
||||
clickAnchorLink = (href: string, component: HTMLElement) => {
|
||||
this._avoidInk = true;
|
||||
this.refs.ink.style.top = `${component.offsetTop + component.clientHeight / 2 - 4.5}px`;
|
||||
this.anchorHelper.scrollTo(href, this.props.offsetTop, getDefaultTarget, () => {
|
||||
this._avoidInk = false;
|
||||
});
|
||||
}
|
||||
|
||||
renderAnchorLink = (child: React.ReactElement<any>) => {
|
||||
const { href } = child.props;
|
||||
const { type } = child as any;
|
||||
if (type.__ANT_ANCHOR_LINK && href) {
|
||||
this.anchorHelper.addLink(href);
|
||||
return React.cloneElement(child, {
|
||||
onClick: this.clickAnchorLink,
|
||||
prefixCls: this.props.prefixCls,
|
||||
bounds: this.props.bounds,
|
||||
affix: this.props.affix || this.props.showInkInFixed,
|
||||
offsetTop: this.props.offsetTop,
|
||||
});
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, offsetTop, style, className = '', affix, showInkInFixed } = this.props;
|
||||
const { activeAnchor, animated } = this.state;
|
||||
const inkClass = classNames({
|
||||
[`${prefixCls}-ink-ball`]: true,
|
||||
animated,
|
||||
visible: !!activeAnchor,
|
||||
});
|
||||
|
||||
const wrapperClass = classNames({
|
||||
[`${prefixCls}-wrapper`]: true,
|
||||
}, className);
|
||||
|
||||
const anchorClass = classNames(prefixCls, {
|
||||
'fixed': !affix && !showInkInFixed,
|
||||
});
|
||||
|
||||
const anchorContent = (
|
||||
<div className={wrapperClass} style={style}>
|
||||
<div className={anchorClass}>
|
||||
<div className={`${prefixCls}-ink`} >
|
||||
<span className={inkClass} ref="ink" />
|
||||
</div>
|
||||
{React.Children.toArray(this.props.children).map(this.renderAnchorLink)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return !affix ? anchorContent : (
|
||||
<Affix offsetTop={offsetTop}>
|
||||
{anchorContent}
|
||||
</Affix>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 锚点
|
||||
cols: 2
|
||||
type: Other
|
||||
title: Anchor
|
||||
---
|
||||
|
||||
用于跳转到页面指定位置。
|
||||
|
||||
## 何时使用
|
||||
|
||||
需要展现当前页面上可供跳转的锚点链接,以及快速在锚点之间跳转。
|
||||
|
||||
## API
|
||||
|
||||
### Anchor Props
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 |
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | |
|
||||
| bounds | 锚点区域边界 | number | 5(px) |
|
||||
| affix | 固定模式 | boolean | false |
|
||||
| showInkInFixed | 固定模式是否显示小圆点 | boolean | false |
|
||||
|
||||
### Link Props
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 |
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| href | 锚点链接 | string | |
|
||||
| title | 文字内容 | string\|ReactNode | |
|
||||
@@ -1,78 +0,0 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
.@{ant-prefix} {
|
||||
&-anchor {
|
||||
position: relative;
|
||||
&-wrapper {
|
||||
background-color: @component-background;
|
||||
}
|
||||
|
||||
&-ink {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
&:before {
|
||||
content: ' ';
|
||||
position: relative;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-color: @border-color-split;
|
||||
margin: 0 auto;
|
||||
}
|
||||
&-ball {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 9px;
|
||||
border: 3px solid @primary-color;
|
||||
background-color: @component-background;
|
||||
left: 50%;
|
||||
transition: top .3s ease-in-out;
|
||||
transform: translateX(-50%);
|
||||
&.visible {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.fixed &-ink &-ink-ball {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-anchor-link {
|
||||
padding: 8px 0 8px 18px;
|
||||
line-height: 1;
|
||||
|
||||
& & {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
display: block;
|
||||
position: relative;
|
||||
transition: all .3s;
|
||||
color: @text-color;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&-title:only-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&-active > &-title {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
& > & {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from 'react';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
|
||||
export default class InputElement extends React.Component<any, any> {
|
||||
private ele: HTMLInputElement;
|
||||
|
||||
focus = () => {
|
||||
this.ele.focus ? this.ele.focus() : (findDOMNode(this.ele) as HTMLInputElement).focus();
|
||||
}
|
||||
blur = () => {
|
||||
this.ele.blur ? this.ele.blur() : (findDOMNode(this.ele) as HTMLInputElement).blur();
|
||||
}
|
||||
render() {
|
||||
return React.cloneElement(this.props.children, {
|
||||
...this.props,
|
||||
ref: ele => this.ele = (ele as HTMLInputElement),
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/antd.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;height:50px;"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__rendered"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
class="ant-select-search ant-select-search--inline"
|
||||
>
|
||||
<div
|
||||
class="ant-select-search__field__wrap"
|
||||
>
|
||||
<textarea
|
||||
class="ant-input ant-select-search__field"
|
||||
style="height:50px;"
|
||||
/>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__rendered"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
class="ant-select-search ant-select-search--inline"
|
||||
>
|
||||
<div
|
||||
class="ant-select-search__field__wrap"
|
||||
>
|
||||
<input
|
||||
class="ant-input ant-input ant-select-search__field"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1`] = `
|
||||
<div
|
||||
class="certain-category-search-wrapper"
|
||||
style="width:250px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-lg ant-select-lg certain-category-search ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:100%;"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__rendered"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
class="ant-select-search ant-select-search--inline"
|
||||
>
|
||||
<div
|
||||
class="ant-select-search__field__wrap"
|
||||
>
|
||||
<span
|
||||
class="ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
class="ant-input ant-input ant-select-search__field"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-input-suffix"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-search certain-category-icon"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__rendered"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
try to type \`b\`
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
class="ant-select-search ant-select-search--inline"
|
||||
>
|
||||
<div
|
||||
class="ant-select-search__field__wrap"
|
||||
>
|
||||
<input
|
||||
class="ant-input ant-input ant-select-search__field"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:200px;"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__rendered"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
class="ant-select-search ant-select-search--inline"
|
||||
>
|
||||
<div
|
||||
class="ant-select-search__field__wrap"
|
||||
>
|
||||
<input
|
||||
class="ant-input ant-input ant-select-search__field"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly 1`] = `
|
||||
<div
|
||||
class="global-search-wrapper"
|
||||
style="width:300px;"
|
||||
>
|
||||
<div
|
||||
class="ant-select-lg ant-select-lg global-search ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
|
||||
style="width:100%;"
|
||||
>
|
||||
<div
|
||||
aria-autocomplete="list"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-select-selection
|
||||
ant-select-selection--single"
|
||||
role="combobox"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__rendered"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selection__placeholder"
|
||||
style="display:block;user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
input here
|
||||
</div>
|
||||
<ul>
|
||||
<li
|
||||
class="ant-select-search ant-select-search--inline"
|
||||
>
|
||||
<div
|
||||
class="ant-select-search__field__wrap"
|
||||
>
|
||||
<span
|
||||
class="ant-input-affix-wrapper"
|
||||
>
|
||||
<input
|
||||
class="ant-input ant-input ant-select-search__field"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<span
|
||||
class="ant-input-suffix"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary ant-btn-lg search-btn"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-search"
|
||||
/>
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-select-search__field__mirror"
|
||||
>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-arrow"
|
||||
style="user-select:none;-webkit-user-select:none;"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<b />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,20 +0,0 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import AutoComplete from '..';
|
||||
|
||||
describe('AutoComplete with Custom Input Element Render', () => {
|
||||
it('AutoComplete with custom Input render perfectly', () => {
|
||||
const wrapper = mount(
|
||||
<AutoComplete dataSource={['12345', '23456', '34567']}>
|
||||
<textarea />
|
||||
</AutoComplete>
|
||||
);
|
||||
|
||||
expect(wrapper.find('textarea').length).toBe(1);
|
||||
wrapper.find('textarea').simulate('change', { target: { value: '123' } });
|
||||
const dropdownWrapper = mount(wrapper.find('Trigger').node.getComponent());
|
||||
|
||||
// should not filter data source defaultly
|
||||
expect(dropdownWrapper.find('MenuItem').length).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('auto-complete');
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 自定义输入组件
|
||||
en-US: Customize Input Component
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
自定义输入组件。
|
||||
|
||||
## en-US
|
||||
|
||||
Customize Input Component
|
||||
|
||||
````jsx
|
||||
import { AutoComplete } from 'antd';
|
||||
|
||||
function onSelect(value) {
|
||||
console.log('onSelect', value);
|
||||
}
|
||||
|
||||
class Complete extends React.Component {
|
||||
state = {
|
||||
dataSource: [],
|
||||
}
|
||||
|
||||
handleSearch = (value) => {
|
||||
this.setState({
|
||||
dataSource: !value ? [] : [
|
||||
value,
|
||||
value + value,
|
||||
value + value + value,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
handleKeyPress = (ev) => {
|
||||
console.log('handleKeyPress', ev);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dataSource } = this.state;
|
||||
return (
|
||||
<AutoComplete
|
||||
dataSource={dataSource}
|
||||
style={{ width: 200, height: 50 }}
|
||||
onSelect={onSelect}
|
||||
onSearch={this.handleSearch}
|
||||
placeholder="input here"
|
||||
>
|
||||
<textarea onKeyPress={this.handleKeyPress} style={{ height: 50 }} />
|
||||
</AutoComplete>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
@@ -1,53 +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);
|
||||
}
|
||||
|
||||
class Complete extends React.Component {
|
||||
state = {
|
||||
dataSource: [],
|
||||
}
|
||||
|
||||
handleSearch = (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}
|
||||
onSearch={this.handleSearch}
|
||||
placeholder="input here"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
@@ -1,152 +0,0 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 查询模式 - 确定类目
|
||||
en-US: Lookup-Patterns - Certain Category
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
[查询模式: 确定类目](https://ant.design/docs/spec/reaction#Lookup-Patterns) 示例。
|
||||
|
||||
## en-US
|
||||
|
||||
Demonstration of [Lookup Patterns: Certain Category](https://ant.design/docs/spec/reaction#Lookup-Patterns).
|
||||
Basic Usage, set datasource of autocomplete with `dataSource` property.
|
||||
|
||||
````jsx
|
||||
import { Icon, Input, AutoComplete } from 'antd';
|
||||
const Option = AutoComplete.Option;
|
||||
const OptGroup = AutoComplete.OptGroup;
|
||||
|
||||
const dataSource = [{
|
||||
title: '话题',
|
||||
children: [{
|
||||
title: 'AntDesign',
|
||||
count: 10000,
|
||||
}, {
|
||||
title: 'AntDesign UI',
|
||||
count: 10600,
|
||||
}],
|
||||
}, {
|
||||
title: '问题',
|
||||
children: [{
|
||||
title: 'AntDesign UI 有多好',
|
||||
count: 60100,
|
||||
}, {
|
||||
title: 'AntDesign 是啥',
|
||||
count: 30010,
|
||||
}],
|
||||
}, {
|
||||
title: '文章',
|
||||
children: [{
|
||||
title: 'AntDesign 是一个设计语言',
|
||||
count: 100000,
|
||||
}],
|
||||
}];
|
||||
|
||||
function renderTitle(title) {
|
||||
return (
|
||||
<span>
|
||||
{title}
|
||||
<a
|
||||
style={{ float: 'right' }}
|
||||
href="https://www.google.com/search?q=antd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>更多
|
||||
</a>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const options = dataSource.map(group => (
|
||||
<OptGroup
|
||||
key={group.title}
|
||||
label={renderTitle(group.title)}
|
||||
>
|
||||
{group.children.map(opt => (
|
||||
<Option key={opt.title} value={opt.title}>
|
||||
{opt.title}
|
||||
<span className="certain-search-item-count">{opt.count} 人 关注</span>
|
||||
</Option>
|
||||
))}
|
||||
</OptGroup>
|
||||
)).concat([
|
||||
<Option disabled key="all" className="show-all">
|
||||
<a
|
||||
href="https://www.google.com/search?q=antd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
查看所有结果
|
||||
</a>
|
||||
</Option>,
|
||||
]);
|
||||
|
||||
function Complete() {
|
||||
return (
|
||||
<div className="certain-category-search-wrapper" style={{ width: 250 }}>
|
||||
<AutoComplete
|
||||
className="certain-category-search"
|
||||
dropdownClassName="certain-category-search-dropdown"
|
||||
dropdownMatchSelectWidth={false}
|
||||
dropdownStyle={{ width: 300 }}
|
||||
size="large"
|
||||
style={{ width: '100%' }}
|
||||
dataSource={options}
|
||||
placeholder="input here"
|
||||
optionLabelProp="value"
|
||||
>
|
||||
<Input suffix={<Icon type="search" className="certain-category-icon" />} />
|
||||
</AutoComplete>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
.certain-category-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input-suffix {
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group-title {
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group {
|
||||
border-bottom: 1px solid #F6F6F6;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item.show-all {
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.certain-search-item-count {
|
||||
position: absolute;
|
||||
color: #999;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
.certain-category-search.ant-select-focused .certain-category-icon {
|
||||
color: #108ee9;
|
||||
}
|
||||
|
||||
.certain-category-icon {
|
||||
color: #6E6E6E;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
font-size: 16px;
|
||||
}
|
||||
````
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 不区分大小写
|
||||
en-US: Non-case-sensitive AutoComplete
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
不区分大小写的 AutoComplete
|
||||
|
||||
## en-US
|
||||
|
||||
A non-case-sensitive AutoComplete
|
||||
|
||||
````jsx
|
||||
import { AutoComplete } from 'antd';
|
||||
|
||||
const dataSource = ['Burns Bay Road', 'Downing Street', 'Wall Street'];
|
||||
|
||||
function Complete() {
|
||||
return (
|
||||
<AutoComplete
|
||||
style={{ width: 200 }}
|
||||
dataSource={dataSource}
|
||||
placeholder="try to type `b`"
|
||||
filterOption={(inputValue, option) => option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
@@ -1,54 +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;
|
||||
|
||||
class Complete extends React.Component {
|
||||
state = {
|
||||
result: [],
|
||||
}
|
||||
|
||||
handleSearch = (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 }}
|
||||
onSearch={this.handleSearch}
|
||||
placeholder="input here"
|
||||
>
|
||||
{children}
|
||||
</AutoComplete>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
@@ -1,126 +0,0 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 查询模式 - 不确定类目
|
||||
en-US: Lookup-Patterns - Uncertain Category
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
[查询模式: 不确定类目](https://ant.design/docs/spec/reaction#Lookup-Patterns) 示例。
|
||||
|
||||
## en-US
|
||||
|
||||
Demonstration of [Lookup Patterns: Uncertain Category](https://ant.design/docs/spec/reaction#Lookup-Patterns).
|
||||
Basic Usage, set datasource of autocomplete with `dataSource` property.
|
||||
|
||||
````jsx
|
||||
import { Icon, Button, Input, AutoComplete } from 'antd';
|
||||
const Option = AutoComplete.Option;
|
||||
|
||||
function onSelect(value) {
|
||||
console.log('onSelect', value);
|
||||
}
|
||||
|
||||
function getRandomInt(max, min = 0) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
|
||||
}
|
||||
|
||||
function searchResult(query) {
|
||||
return (new Array(getRandomInt(5))).join('.').split('.')
|
||||
.map((item, idx) => ({
|
||||
query,
|
||||
category: `${query}${idx}`,
|
||||
count: getRandomInt(200, 100),
|
||||
}));
|
||||
}
|
||||
|
||||
function renderOption(item) {
|
||||
return (
|
||||
<Option key={item.category} text={item.category}>
|
||||
{item.query} 在
|
||||
<a
|
||||
href={`https://s.taobao.com/search?q=${item.query}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{item.category}
|
||||
</a>
|
||||
区块中
|
||||
<span className="global-search-item-count">约 {item.count} 个结果</span>
|
||||
</Option>
|
||||
);
|
||||
}
|
||||
|
||||
class Complete extends React.Component {
|
||||
state = {
|
||||
dataSource: [],
|
||||
}
|
||||
|
||||
handleSearch = (value) => {
|
||||
this.setState({
|
||||
dataSource: value ? searchResult(value) : [],
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dataSource } = this.state;
|
||||
return (
|
||||
<div className="global-search-wrapper" style={{ width: 300 }}>
|
||||
<AutoComplete
|
||||
className="global-search"
|
||||
size="large"
|
||||
style={{ width: '100%' }}
|
||||
dataSource={dataSource.map(renderOption)}
|
||||
onSelect={onSelect}
|
||||
onSearch={this.handleSearch}
|
||||
placeholder="input here"
|
||||
optionLabelProp="text"
|
||||
>
|
||||
<Input
|
||||
suffix={(
|
||||
<Button className="search-btn" size="large" type="primary">
|
||||
<Icon type="search" />
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</AutoComplete>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Complete />, mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
.global-search-wrapper {
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
.global-search {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-select-selection--single {
|
||||
margin-right: -46px;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input:not(:last-child) {
|
||||
padding-right: 62px;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input-suffix {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input-suffix button {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.global-search-item-count {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
}
|
||||
````
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Data Entry
|
||||
cols: 2
|
||||
title: AutoComplete
|
||||
---
|
||||
|
||||
Autocomplete function of input field.
|
||||
|
||||
## When To Use
|
||||
|
||||
When there is a need for autocomplete functionality.
|
||||
|
||||
## API
|
||||
|
||||
```jsx
|
||||
const dataSource = ['12345', '23456', '34567'];
|
||||
<AutoComplete dataSource={dataSource} />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------------|----------------------------------|------------|--------|
|
||||
| dataSource | Data source for autocomplete | [DataSourceItemType](https://git.io/vMMKF)[] | |
|
||||
| value | selected option | string\|string[]\|{ key: string, label: string\|ReactNode }\|Array<{ key: string, label: string\|ReactNode }> | - |
|
||||
| defaultValue | Initial selected option. | string\|string[]\|{ key: string, label: string\|ReactNode }\|Array<{ key: string, label: string\|ReactNode }> | - |
|
||||
| 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) | - |
|
||||
| onSearch | Called when searching items. | function(value) | - |
|
||||
| disabled | Whether disabled select | boolean | false |
|
||||
| defaultActiveFirstOption | Whether active first option by default | boolean | true |
|
||||
| placeholder | placeholder of input | string | - |
|
||||
| children (for dataSource) | Data source for autocomplet | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
|
||||
| children (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |
|
||||
| optionLabelProp | Which prop value of option will render as content of select. | string | `children` |
|
||||
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true |
|
||||
@@ -1,117 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Option, OptGroup } from 'rc-select';
|
||||
import classNames from 'classnames';
|
||||
import Select, { AbstractSelectProps, SelectValue, OptionProps, OptGroupProps } from '../select';
|
||||
import Input from '../input';
|
||||
import InputElement from './InputElement';
|
||||
|
||||
export interface DataSourceItemObject { value: string; text: string; }
|
||||
export type DataSourceItemType = string | DataSourceItemObject;
|
||||
|
||||
export interface InputProps {
|
||||
onChange?: React.FormEventHandler<any>;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export type ValidInputElement =
|
||||
HTMLInputElement |
|
||||
HTMLTextAreaElement |
|
||||
React.ReactElement<InputProps>;
|
||||
|
||||
export interface AutoCompleteProps extends AbstractSelectProps {
|
||||
value?: SelectValue;
|
||||
defaultValue?: SelectValue;
|
||||
dataSource: DataSourceItemType[];
|
||||
optionLabelProp?: string;
|
||||
onChange?: (value: SelectValue) => void;
|
||||
onSelect?: (value: SelectValue, option: Object) => any;
|
||||
children?: ValidInputElement |
|
||||
React.ReactElement<OptionProps> |
|
||||
Array<React.ReactElement<OptionProps>>;
|
||||
}
|
||||
|
||||
function isSelectOptionOrSelectOptGroup(child: any): Boolean {
|
||||
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
|
||||
}
|
||||
|
||||
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,
|
||||
filterOption: false,
|
||||
};
|
||||
|
||||
getInputElement = () => {
|
||||
const { children } = this.props;
|
||||
const element = children && React.isValidElement(children) && children.type !== Option ?
|
||||
React.Children.only(this.props.children) :
|
||||
<Input/>;
|
||||
return (
|
||||
<InputElement
|
||||
{...element.props}
|
||||
className={classNames('ant-input', element.props.className)}
|
||||
>
|
||||
{element}
|
||||
</InputElement>
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
[`${prefixCls}-auto-complete`]: true,
|
||||
});
|
||||
|
||||
let options;
|
||||
const childArray = React.Children.toArray(children);
|
||||
if (childArray.length &&
|
||||
isSelectOptionOrSelectOptGroup(childArray[0])
|
||||
) {
|
||||
options = children;
|
||||
} else {
|
||||
options = dataSource ? dataSource.map((item) => {
|
||||
if (React.isValidElement(item)) {
|
||||
return 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}
|
||||
mode="combobox"
|
||||
optionLabelProp={optionLabelProp}
|
||||
getInputElement={this.getInputElement}
|
||||
notFoundContent={notFoundContent}
|
||||
>
|
||||
{options}
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 自动完成
|
||||
type: Data Entry
|
||||
cols: 2
|
||||
title: AutoComplete
|
||||
---
|
||||
|
||||
输入框自动完成功能。
|
||||
|
||||
## 何时使用
|
||||
|
||||
需要自动完成时。
|
||||
|
||||
## API
|
||||
|
||||
```jsx
|
||||
const dataSource = ['12345', '23456', '34567'];
|
||||
<AutoComplete dataSource={dataSource} />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------------|----------------------------------|------------|---------|
|
||||
| dataSource | 自动完成的数据源 | [DataSourceItemType](https://git.io/vMMKF)[] | |
|
||||
| value | 指定当前选中的条目 | string\|string[]\|{ key: string, label: string\|ReactNode }\|Array<{ key: string, label: string\|ReactNode }> | 无 |
|
||||
| defaultValue | 指定默认选中的条目 | string\|string[]\|{ key: string, label: string\|ReactNode }\|Array<{ key: string, label: string\|ReactNode}> | 无 |
|
||||
| allowClear | 支持清除, 单选模式有效 | boolean | false |
|
||||
| onChange | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) | 无 |
|
||||
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |
|
||||
| onSearch | 搜索补全项的时候调用 | function(value) | 无 |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true
|
||||
| placeholder | 输入框提示 | string | - |
|
||||
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
|
||||
| children (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |
|
||||
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` |
|
||||
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true |
|
||||
@@ -1,64 +0,0 @@
|
||||
@import "../../style/themes/default";
|
||||
@import "../../style/mixins/index";
|
||||
@import "../../input/style/mixin";
|
||||
|
||||
@input-prefix-cls: ~"@{ant-prefix}-input";
|
||||
@select-prefix-cls: ~"@{ant-prefix}-select";
|
||||
@autocomplete-prefix-cls: ~"@{select-prefix-cls}-auto-complete";
|
||||
|
||||
.@{autocomplete-prefix-cls} {
|
||||
&.@{select-prefix-cls} {
|
||||
.@{select-prefix-cls} {
|
||||
&-selection {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
&__rendered {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
height: 100%;
|
||||
line-height: @input-height-base;
|
||||
}
|
||||
&__placeholder {
|
||||
margin-left: (@input-padding-horizontal + 1);
|
||||
margin-right: (@input-padding-horizontal + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-allow-clear {
|
||||
.@{select-prefix-cls}-selection:hover .@{select-prefix-cls}-selection__rendered {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.@{input-prefix-cls} {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&-lg {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: @input-height-lg;
|
||||
}
|
||||
.@{input-prefix-cls} {
|
||||
.input-lg();
|
||||
}
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: @input-height-sm;
|
||||
}
|
||||
.@{input-prefix-cls} {
|
||||
.input-sm();
|
||||
}
|
||||
}
|
||||
|
||||
.@{input-prefix-cls} {
|
||||
border-width: @border-width-base;
|
||||
&:focus,
|
||||
&:hover {
|
||||
.hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
|
||||
import '../../select/style';
|
||||
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Avatar from '..';
|
||||
|
||||
describe('Avatar Render', () => {
|
||||
it('Render long string correctly', () => {
|
||||
const wrapper = mount(<Avatar>TestString</Avatar>);
|
||||
const children = wrapper.find('.ant-avatar-string');
|
||||
expect(children.length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -1,329 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
style="margin-right:24px;"
|
||||
>
|
||||
<span
|
||||
class="ant-badge"
|
||||
title="1"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-square ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-count"
|
||||
data-show="true"
|
||||
>
|
||||
<span
|
||||
class="ant-scroll-number-only"
|
||||
style="transition:none;-ms-transform:translateY(-1100%);-webkit-transform:translateY(-1100%);transform:translateY(-1100%);"
|
||||
>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
0
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
1
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
2
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
3
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
4
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
5
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
6
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
7
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
8
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
9
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
0
|
||||
</p>
|
||||
<p
|
||||
class="current"
|
||||
>
|
||||
1
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
2
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
3
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
4
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
5
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
6
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
7
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
8
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
9
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
0
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
1
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
2
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
3
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
4
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
5
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
6
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
7
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
8
|
||||
</p>
|
||||
<p
|
||||
class=""
|
||||
>
|
||||
9
|
||||
</p>
|
||||
</span>
|
||||
</sup>
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span
|
||||
class="ant-badge"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-square ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<sup
|
||||
class="ant-scroll-number ant-badge-dot"
|
||||
data-show="true"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-sm ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-lg ant-avatar-square ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-square ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-sm ant-avatar-square ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-lg ant-avatar-circle"
|
||||
style="background-color:#f56a00;"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
class="ant-btn ant-btn-sm"
|
||||
style="margin-left:16px;"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Change
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
||||
<div>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
>
|
||||
USER
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-image"
|
||||
>
|
||||
<img
|
||||
src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle"
|
||||
style="color:#f56a00;background-color:#fde3cf;"
|
||||
>
|
||||
<span
|
||||
class="ant-avatar-string"
|
||||
>
|
||||
U
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-avatar ant-avatar-circle ant-avatar-icon"
|
||||
style="background-color:#87d068;"
|
||||
>
|
||||
<i
|
||||
class="anticon anticon-user"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('avatar');
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
order: 3
|
||||
title:
|
||||
zh-CN: 带徽标的头像
|
||||
en-US: With Badge
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通常用于消息提示。
|
||||
|
||||
## en-US
|
||||
|
||||
Usually used for messages remind.
|
||||
|
||||
````jsx
|
||||
import { Avatar, Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<span style={{ marginRight: 24 }}>
|
||||
<Badge count={1}><Avatar shape="square" icon="user" /></Badge>
|
||||
</span>
|
||||
<span>
|
||||
<Badge dot><Avatar shape="square" icon="user" /></Badge>
|
||||
</span>
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
头像有三种尺寸,两种形状可选。
|
||||
|
||||
## en-US
|
||||
|
||||
Three sizes and two shapes are available.
|
||||
|
||||
````jsx
|
||||
import { Avatar } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<div>
|
||||
<Avatar size="large" icon="user" />
|
||||
<Avatar icon="user" />
|
||||
<Avatar size="small" icon="user" />
|
||||
</div>
|
||||
<div>
|
||||
<Avatar shape="square" size="large" icon="user" />
|
||||
<Avatar shape="square" icon="user" />
|
||||
<Avatar shape="square" size="small" icon="user" />
|
||||
</div>
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-avatar-demo-basic .ant-avatar {
|
||||
margin-top: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 自动调整字符大小
|
||||
en-US: Autoset Font Size
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
对于字符型的头像,当字符串较长时,字体大小可以根据头像宽度自动调整。
|
||||
|
||||
## en-US
|
||||
|
||||
For letter type Avatar, when the letters are too long to display, the font size can be automatically adjusted according to the width of the Avatar.
|
||||
|
||||
````jsx
|
||||
import { Avatar, Button } from 'antd';
|
||||
|
||||
const UserList = ['U', 'Lucy', 'Tom', 'Edward'];
|
||||
const colorList = ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];
|
||||
|
||||
class Autoset extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
user: UserList[0],
|
||||
color: colorList[0],
|
||||
};
|
||||
}
|
||||
changeUser = () => {
|
||||
const index = UserList.indexOf(this.state.user);
|
||||
this.setState({
|
||||
user: index < UserList.length - 1 ? UserList[index + 1] : UserList[0],
|
||||
color: index < colorList.length - 1 ? colorList[index + 1] : colorList[0],
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Avatar style={{ backgroundColor: this.state.color }} size="large">{this.state.user}</Avatar>
|
||||
<Button size="small" style={{ marginLeft: 16 }} onClick={this.changeUser}>Change</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Autoset />
|
||||
, mountNode);
|
||||
````
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
order: 1
|
||||
title:
|
||||
zh-CN: 类型
|
||||
en-US: Type
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
支持三种类型:图片、Icon 以及字符,其中 Icon 和字符型可以自定义图标颜色及背景色。
|
||||
|
||||
## en-US
|
||||
|
||||
Image, Icon and letter are supported, and the latter two kinds avatar can have custom colors and background colors.
|
||||
|
||||
````jsx
|
||||
import { Avatar } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Avatar icon="user" />
|
||||
<Avatar>U</Avatar>
|
||||
<Avatar>USER</Avatar>
|
||||
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
|
||||
<Avatar style={{ color: '#f56a00', backgroundColor: '#fde3cf' }}>U</Avatar>
|
||||
<Avatar style={{ backgroundColor: '#87d068' }} icon="user" />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-avatar-demo-type .ant-avatar {
|
||||
margin-top: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
type: Data Display
|
||||
title: Avatar
|
||||
---
|
||||
|
||||
Avatars can be used to represent people or object, which supports image, antd-Icon, or letter.
|
||||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | to set the shape of avatar | Enum{ 'circle', 'square' } | `circle` |
|
||||
| size | to set the size of avatar | Enum{ 'large', 'small', 'default' } | `default` |
|
||||
| src | the address of a image avatar | string | - |
|
||||
| icon | the icon type of a icon avatar, see `Icon` Component | string | - |
|
||||
@@ -1,124 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Icon from '../icon';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface AvatarProps {
|
||||
/** Shape of avatar, options:`circle`, `square` */
|
||||
shape?: 'circle' | 'square';
|
||||
/** Size of avatar, options:`large`, `small`, `default` */
|
||||
size?: 'large' | 'small' | 'default';
|
||||
/** Src of image avatar */
|
||||
src?: string;
|
||||
/** Type of the Icon to be used in avatar */
|
||||
icon?: string;
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
children?: any;
|
||||
}
|
||||
|
||||
export default class Avatar extends React.Component<AvatarProps, any> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-avatar',
|
||||
shape: 'circle',
|
||||
size: 'default',
|
||||
};
|
||||
|
||||
private avatarChildren: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
scale: 1,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setScale();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (prevProps.children !== this.props.children
|
||||
|| (prevState.scale !== this.state.scale && this.state.scale === 1)) {
|
||||
this.setScale();
|
||||
}
|
||||
}
|
||||
|
||||
setScale = () => {
|
||||
const childrenNode = this.avatarChildren;
|
||||
if (childrenNode) {
|
||||
const childrenWidth = childrenNode.offsetWidth;
|
||||
const avatarWidth = ReactDOM.findDOMNode(this).getBoundingClientRect().width;
|
||||
// add 4px gap for each side to get better performance
|
||||
if (avatarWidth - 8 < childrenWidth) {
|
||||
this.setState({
|
||||
scale: (avatarWidth - 8) / childrenWidth,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
scale: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls, shape, size, src, icon, className, ...others,
|
||||
} = this.props;
|
||||
|
||||
const sizeCls = classNames({
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
});
|
||||
|
||||
const classString = classNames(prefixCls, className, sizeCls, {
|
||||
[`${prefixCls}-${shape}`]: shape,
|
||||
[`${prefixCls}-image`]: src,
|
||||
[`${prefixCls}-icon`]: icon,
|
||||
});
|
||||
|
||||
let children = this.props.children;
|
||||
if (src) {
|
||||
children = <img src={src} />;
|
||||
} else if (icon) {
|
||||
children = <Icon type={icon} />;
|
||||
} else {
|
||||
const childrenNode = this.avatarChildren;
|
||||
if (childrenNode || this.state.scale !== 1) {
|
||||
const childrenStyle: React.CSSProperties = {
|
||||
msTransform: `scale(${this.state.scale})`,
|
||||
WebkitTransform: `scale(${this.state.scale})`,
|
||||
transform: `scale(${this.state.scale})`,
|
||||
position: 'absolute',
|
||||
display: 'inline-block',
|
||||
left: `calc(50% - ${Math.round(childrenNode.offsetWidth / 2)}px)`,
|
||||
};
|
||||
children = (
|
||||
<span
|
||||
className={`${prefixCls}-string`}
|
||||
ref={span => this.avatarChildren = span}
|
||||
style={childrenStyle}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
children = (
|
||||
<span
|
||||
className={`${prefixCls}-string`}
|
||||
ref={span => this.avatarChildren = span}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<span {...others} className={classString}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 头像
|
||||
type: Data Display
|
||||
title: Avatar
|
||||
---
|
||||
|
||||
用来代表用户或事物,支持图片、图标或字符展示。
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------- |--------------------------------------------------------- | ---------- | ------- |
|
||||
| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` |
|
||||
| size | 设置头像的大小 | Enum{ 'large', 'small', 'default' } | `default` |
|
||||
| src | 图片类头像的资源地址 | string | - |
|
||||
| icon | 设置头像的图标类型,参考 `Icon` 组件 | string | - |
|
||||
@@ -1,47 +0,0 @@
|
||||
@import "../../style/themes/default";
|
||||
|
||||
@avatar-prefix-cls: ~"@{ant-prefix}-avatar";
|
||||
|
||||
.@{avatar-prefix-cls} {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
background: @avatar-bg;
|
||||
color: @avatar-color;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.avatar-size(@avatar-size-base, @avatar-font-size-base);
|
||||
|
||||
&-lg {
|
||||
.avatar-size(@avatar-size-lg, @avatar-font-size-lg);
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.avatar-size(@avatar-size-sm, @avatar-font-size-sm);
|
||||
}
|
||||
|
||||
&-square {
|
||||
border-radius: @avatar-border-radius;
|
||||
}
|
||||
|
||||
& > img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-size(@size, @font-size) {
|
||||
width: @size;
|
||||
height: @size;
|
||||
line-height: @size;
|
||||
border-radius: @size / 2;
|
||||
|
||||
& > * {
|
||||
line-height: @size;
|
||||
}
|
||||
|
||||
&.@{avatar-prefix-cls}-icon {
|
||||
font-size: @font-size;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/back-top/demo/basic.md correctly 1`] = `
|
||||
<div>
|
||||
Scroll down to see the bottom-right
|
||||
<strong
|
||||
style="color:rgba(64, 64, 64, 0.6);"
|
||||
>
|
||||
gray
|
||||
</strong>
|
||||
button.
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/back-top/demo/custom.md correctly 1`] = `
|
||||
<div>
|
||||
Scroll down to see the bottom-right
|
||||
<strong
|
||||
style="color:#1088e9;"
|
||||
>
|
||||
blue
|
||||
</strong>
|
||||
button.
|
||||
</div>
|
||||
`;
|
||||
@@ -1,3 +0,0 @@
|
||||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('back-top');
|
||||
@@ -1,28 +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 style={{ color: 'rgba(64, 64, 64, 0.6)' }}> gray </strong>
|
||||
button.
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
向下滚动后,见右下角灰色按钮
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user