Merge from branch "master"

This commit is contained in:
afc163 2017-03-28 15:58:41 +08:00
commit 4f89e54cb2
30 changed files with 113 additions and 71 deletions

View File

@ -1,6 +1,7 @@
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import KeyCode from 'rc-util/lib/KeyCode';
import Cascader from '..';
const options = [{
@ -51,7 +52,6 @@ describe('Cascader', () => {
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('can be selected', () => {
const wrapper = mount(<Cascader options={options} />);
wrapper.find('input').simulate('click');
@ -68,4 +68,13 @@ describe('Cascader', () => {
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('backspace should work with `Cascader[showSearch]`', () => {
const wrapper = mount(<Cascader options={options} showSearch />);
wrapper.find('input').simulate('change', { target: { value: '123' } });
expect(wrapper.state('inputValue')).toBe('123');
wrapper.find('input').simulate('keydown', { keyCode: KeyCode.BACKSPACE });
// Simulate onKeyDown will not trigger onChange by default, so the value is still '123'
expect(wrapper.state('inputValue')).toBe('123');
});
});

View File

@ -3,6 +3,7 @@ import RcCascader from 'rc-cascader';
import arrayTreeFilter from 'array-tree-filter';
import classNames from 'classnames';
import omit from 'omit.js';
import KeyCode from 'rc-util/lib/KeyCode';
import Input from '../input';
import Icon from '../icon';
@ -172,6 +173,12 @@ export default class Cascader extends React.Component<CascaderProps, any> {
}
}
handleKeyDown = (e) => {
if (e.keyCode === KeyCode.BACKSPACE) {
e.stopPropagation();
}
}
handleInputChange = (e) => {
const inputValue = e.target.value;
this.setState({ inputValue });
@ -334,6 +341,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
autoComplete="off"
onClick={showSearch ? this.handleInputClick : undefined}
onBlur={showSearch ? this.handleInputBlur : undefined}
onKeyDown={this.handleKeyDown}
onChange={showSearch ? this.handleInputChange : undefined}
/>
<span className={`${prefixCls}-picker-label`}>

View File

@ -19,7 +19,7 @@ export interface PickerProps {
popupStyle?: React.CSSProperties;
locale?: any;
size?: 'large' | 'small' | 'default';
getCalendarContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getCalendarContainer?: (triggerNode: Element) => HTMLElement;
open?: boolean;
onOpenChange?: (status: boolean) => void;
disabledDate?: (current: moment.Moment) => boolean;

View File

@ -9,7 +9,7 @@ export interface DropDownProps {
onVisibleChange?: (visible?: boolean) => void;
visible?: boolean;
align?: Object;
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getPopupContainer?: (triggerNode: Element) => HTMLElement;
prefixCls?: string;
placement?: 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight';
}

View File

@ -72,13 +72,13 @@
text-align: left;
outline: 0;
-moz-appearance: textfield;
line-height: @input-height-base - 2px;
height: @input-height-base - 2px;
transition: all 0.3s linear;
color: @input-color;
border: 0;
border-radius: @border-radius-base;
padding: 0 7px;
.placeholder();
&[disabled] {
.disabled();
@ -90,7 +90,6 @@
input {
height: @input-height-lg - 2px;
line-height: @input-height-lg - 2px;
}
}
@ -99,7 +98,6 @@
input {
height: @input-height-sm - 2px;
line-height: @input-height-sm - 2px;
}
}

View File

@ -72,4 +72,29 @@ describe('Locale Provider', () => {
expect(DatePickerPlaceholder).toBe(locale.DatePicker.lang.placeholder);
});
});
it('should change locale of Modal.xxx', () => {
class ModalDemo extends React.Component {
componentDidMount() {
Modal.confirm({
title: 'Hello World!',
});
}
render() {
return null;
}
}
[enUS, ptBR, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR].forEach((locale) => {
mount(
<LocaleProvider locale={locale}>
<ModalDemo />
</LocaleProvider>
);
const currentConfirmNode = document.querySelectorAll('.ant-confirm')[document.querySelectorAll('.ant-confirm').length - 1];
const cancelButtonText = currentConfirmNode.querySelectorAll('.ant-btn:not(.ant-btn-primary) span')[0].innerHTML;
const okButtonText = currentConfirmNode.querySelectorAll('.ant-btn-primary span')[0].innerHTML;
expect(cancelButtonText).toBe(locale.Modal.cancelText);
expect(okButtonText).toBe(locale.Modal.okText);
});
});
});

View File

@ -34,7 +34,7 @@ export default class LocaleProvider extends React.Component<LocaleProviderProps,
};
}
componentDidMount() {
componentWillMount() {
this.componentDidUpdate();
}

View File

@ -47,6 +47,6 @@ export default {
uploading: 'Закачиваю...',
removeFile: 'Удалить файл',
uploadError: 'Ошибка при закачке',
previewFile: 'Предпросмотр файл',
previewFile: 'Предпросмотр файла',
},
};

View File

@ -19,7 +19,7 @@ export interface MentionProps {
multiLines?: Boolean;
prefix?: string;
placeholder?: string;
getSuggestionContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getSuggestionContainer?: (triggerNode: Element) => HTMLElement;
onFocus?: Function;
onBlur?: Function;
}

View File

@ -26,7 +26,7 @@ A Selector similar to Select2.
| value | Current selected option. | string\|string[] | - |
| defaultValue | Initial selected option. | string\|string[] | - |
| multiple | Allow multiple select. | boolean | false |
| allowClear | Show clear button, working in single mode only. | boolean | false |
| allowClear | Show clear button. | boolean | false |
| 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 |
| tags | When tagging is enabled the user can select from pre-existing options or create a new tag by picking the first choice, which is what the user has typed into the search box so far. | boolean |false |
| onSelect | Called when a option is selected, the params are option's value (or key) and option instance. | function(value, option) | - |

View File

@ -35,7 +35,7 @@ export interface SelectProps extends AbstractSelectProps {
optionFilterProp?: string;
defaultActiveFirstOption?: boolean;
labelInValue?: boolean;
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getPopupContainer?: (triggerNode: Element) => HTMLElement;
dropdownStyle?: React.CSSProperties;
dropdownMenuStyle?: React.CSSProperties;
onChange?: (value: SelectValue) => void;

View File

@ -27,7 +27,7 @@ title: Select
| value | 指定当前选中的条目 | string\|string[] | - |
| defaultValue | 指定默认选中的条目 | string\|string[] | - |
| multiple | 支持多选 | boolean | false |
| allowClear | 支持清除, 单选模式有效 | boolean | false |
| allowClear | 支持清除 | boolean | false |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true |
| tags | 可以把随意输入的条目作为 tag输入项不需要与下拉选项匹配 | boolean |false |
| onSelect | 被选中时调用,参数为选中项的 value (或 key) 值 | function(value, option) | - |

View File

@ -173,6 +173,9 @@
line-height: @input-height-lg - 8px;
}
}
.@{select-prefix-cls}-selection__clear {
top: @input-height-lg / 2;
}
}
}
@ -191,6 +194,9 @@
line-height: @input-height-sm - 8px;
}
}
.@{select-prefix-cls}-selection__clear {
top: @input-height-sm / 2;
}
}
}
@ -335,6 +341,14 @@
content: "\e633";
}
}
.@{select-prefix-cls}-selection__clear {
top: @input-height-base / 2;
}
}
&-allow-clear &-selection--multiple &-selection__rendered {
margin-right: 20px; // In case that clear button will overlap content
}
&-open {
@ -372,6 +386,9 @@
box-shadow: none;
}
}
&-combobox&-allow-clear &-selection:hover &-selection__rendered {
margin-right: 20px; // In case that clear button will overlap content
}
}
.@{select-prefix-cls}-dropdown {

View File

@ -75,7 +75,7 @@ export interface TableProps<T> {
onExpandedRowsChange?: (expandedRowKeys: string[]) => void;
onExpand?: (expanded: boolean, record: T) => void;
onChange?: (pagination: PaginationProps | boolean, filters: string[], sorter: Object) => any;
loading?: boolean | SpinProps ;
loading?: boolean | SpinProps;
locale?: Object;
indentSize?: number;
onRowClick?: (record: T, index: number) => any;

View File

@ -20,7 +20,7 @@ export interface TimePickerProps {
disabledMinutes?: (selectedHour: number) => number[];
disabledSeconds?: (selectedHour: number, selectedMinute: number) => number[];
style?: React.CSSProperties;
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
getPopupContainer?: (triggerNode: Element) => HTMLElement;
addon?: Function;
use12Hours?: boolean;
}

View File

@ -25,8 +25,8 @@ export interface AbstractTooltipProps {
openClassName?: string;
arrowPointAtCenter?: boolean;
// getTooltipContainer had been rename to getPopupContainer
getTooltipContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getTooltipContainer?: (triggerNode: Element) => HTMLElement;
getPopupContainer?: (triggerNode: Element) => HTMLElement;
children?: React.ReactElement<any>;
}

View File

@ -34,7 +34,7 @@ One or more elements can be selected from either column, one click on the proper
| notFoundContent | Text to display when a column is empty. | string\|ReactNode | 'The list is empty' |
| footer | A function used for rendering the footer. | (props): ReactNode | |
| lazy | property of [react-lazy-load](https://github.com/loktar00/react-lazy-load) for lazy rendering items | object | `{ height: 32, offset: 32 }` |
| onSearchChange | A callback function which is executed when search field are changed | (direction: 'left' | 'right', event: Event): void | - |
| onSearchChange | A callback function which is executed when search field are changed | (direction: 'left'\|'right', event: Event): void | - |
## Warning

View File

@ -36,7 +36,7 @@ title: Transfer
| notFoundContent | 当列表为空时显示的内容 | string\|ReactNode | '列表为空' |
| footer | 底部渲染函数 | (props): ReactNode | |
| lazy | Transfer 使用了 [react-lazy-load](https://github.com/loktar00/react-lazy-load) 优化性能,这里可以设置相关参数 | object | `{ height: 32, offset: 32 }` |
| onSearchChange | 搜索框内容时改变时的回调函数 | (direction: 'left' | 'right', event: Event): void | - |
| onSearchChange | 搜索框内容时改变时的回调函数 | (direction: 'left'\|'right', event: Event): void | - |
## 注意

View File

@ -27,6 +27,7 @@ export interface TreeSelectProps {
disabled?: boolean;
treeDefaultExpandAll?: boolean;
treeCheckable?: boolean | React.ReactNode;
treeDefaultExpandedKeys?: Array<string>;
filterTreeNode?: (inputValue: string, treeNode: any) => boolean | boolean;
treeNodeFilterProp?: string;
treeNodeLabelProp?: string;
@ -39,5 +40,5 @@ export interface TreeSelectProps {
notFoundContent?: React.ReactNode;
labelInValue?: boolean;
treeCheckStrictly?: boolean;
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
getPopupContainer?: (triggerNode: Element) => HTMLElement;
}

View File

@ -106,7 +106,7 @@ export default class Tree extends React.Component<TreeProps, any> {
<RcTree
{...props}
className={classString}
checkable={checkable ? (<span className={`${prefixCls}-checkbox-inner`} />) : checkable}
checkable={checkable ? <span className={`${prefixCls}-checkbox-inner`} /> : checkable}
>
{this.props.children}
</RcTree>

View File

@ -3,7 +3,7 @@ order: 0
title: Ant Design of React
---
Following Ant Design specification, We develop a React UI library `antd` that contains a set of high quality components and demos for building rich interactive desktop applications.
Following the Ant Design specification, we developed a React UI library `antd` that contains a set of high quality components and demos for building rich, interactive user interfaces.
<div class="pic-plus">
<img width="150" src="https://t.alipayobjects.com/images/rmsweb/T11aVgXc4eXXXXXXXX.svg">
@ -29,12 +29,12 @@ Following Ant Design specification, We develop a React UI library `antd` that co
- 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.
- Written in TypeScript with complete defined types.
- A npm + webpack + [dva](https://github.com/dvajs/dva) front-end development workflow.
## Environment Support
* Browser: Modern browsers and Internet Explorer 9+
* Modern browsers and Internet Explorer 9+
* Server-side Rendering
* [Electron](http://electron.atom.io/)
@ -43,13 +43,13 @@ Following Ant Design specification, We develop a React UI library `antd` that co
- Stable: [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd)
- Beta: [![](https://cnpmjs.org/badge/v/antd.svg?&tag=beta&subject=npm)](https://www.npmjs.org/package/antd)
You can subscribe to this feed for new version notification: https://github.com/ant-design/ant-design/releases.atom
You can subscribe to this feed for new version notifications: https://github.com/ant-design/ant-design/releases.atom
## Installation
### Using npm or yarn
**We recommend using npm or yarn to install**it not only makes development easierbut you can also take advantage of the whole ecosystem.
**We recommend using npm or yarn to install**it not only makes development easierbut also allow you to take advantage of the rich ecosystem of javascript packages and tooling.
```bash
$ npm install antd --save
@ -63,11 +63,11 @@ If you are in a bad network enviornmentyou can try other registers and tools
### Import in Browser
Add `script` and `link` tag in your browser and use global variable `antd`.
Add `script` and `link` tags in your browser and use the global variable `antd`.
We provide `antd.js` `antd.css` and `antd.min.js` `antd.min.css` under `antd/dist` in antd's npm package. Also you can download from [![CDNJS](https://img.shields.io/cdnjs/v/antd.svg?style=flat-square)](https://cdnjs.com/libraries/antd) or [unpkg](https://unpkg.com/).
We provide `antd.js` `antd.css` and `antd.min.js` `antd.min.css` under `antd/dist` in antd's npm package. You can also download these files directly from [![CDNJS](https://img.shields.io/cdnjs/v/antd.svg?style=flat-square)](https://cdnjs.com/libraries/antd) or [unpkg](https://unpkg.com/).
> **We are strongly not recommended to use these built files**, that make you import all components with large size, and you cannot get bugfixes from the dependencies of antd.
> **We strongly discourage loading these entire files** this will add bloat to your application and make it more difficult to receive bugfixes and updates. Ant is intended to be used in conjunction with a built a tool, such as [webpack](https://webpack.github.io/), which will make it easy to import only the parts of antd that you are using.
## Usage
@ -76,7 +76,7 @@ import { DatePicker } from 'antd';
ReactDOM.render(<DatePicker />, mountNode);
```
And import style manually:
And import stylesheets manually:
```jsx
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
@ -95,7 +95,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
}
```
Then you can import components from antd, equivalent to import manually below.
This allows you to import components from antd without having to manually import the corresponding stylesheet. The antd babel plugin will automatically import stylesheets.
```jsx
// import js and css modularly, parsed by babel-plugin-import
@ -125,7 +125,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
> 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.
> - Don't use @types/antd, antd provides a built-in ts definition already.
## Links
@ -144,7 +144,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
- [Customize Theme](/docs/react/customize-theme)
## Who are using antd
## Companies using antd
- [Ant Financial](http://www.antgroup.com/index.htm?locale=en_US)
- [Alibaba](http://www.alibaba.com/)
@ -152,22 +152,18 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
- [Meituan](http://www.meituan.com)
- [Didi](http://www.xiaojukeji.com/)
> If your company or product uses Ant Design, you are welcome to comment in [this issue](https://github.com/ant-design/ant-design/issues/477). Thank you!
> If your company or product uses Ant Design, let us know [here](https://github.com/ant-design/ant-design/issues/477)!
## Contributing
Please read our [CONTRIBUTING.md](https://github.com/ant-design/ant-design/blob/master/.github/CONTRIBUTING.md) first.
If you have any idea to improve antd, just create a [Pull Request](https://github.com/ant-design/ant-design/pulls). Also, you can also [issue](https://github.com/ant-design/ant-design/issues/new) bugs.
If you'd like to help us improve antd, just create a [Pull Request](https://github.com/ant-design/ant-design/pulls). Feel free to report bugs and issues [here](https://github.com/ant-design/ant-design/issues/new).
> Recommend to read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) and [How to Ask a Question in Open Source Community](https://github.com/seajs/seajs/issues/545) and [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html), a smart question will get right answer quickly.
> If you're new to posting issues, we ask that you read [*How To Ask Questions The Smart Way*](http://www.catb.org/~esr/faqs/smart-questions.html) and [How to Ask a Question in Open Source Community](https://github.com/seajs/seajs/issues/545) and [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html) prior to posting. Well written bug reports help us help you!
## Need Help?
You can ask questions while you meet problem through the following ways.
And we encourage experienced users to help those who are not familiar with `antd`.
For questions on how to use antd, please post questions to [stackoverflow](http://stackoverflow.com/questions/tagged/antd) using the `antd` tag. If you're not finding what you need on stackoverflow, you can find us on [gitter](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) as well.
We recommend to tag your questions with `antd` on Stack Overflow.
1. [Stack Overflow](http://stackoverflow.com/questions/tagged/antd)(Recommended)
2. [![Join the chat at https://gitter.im/ant-design/ant-design](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
As always, we encourage experienced users to help those who are not familiar with `antd`!

View File

@ -58,7 +58,7 @@
"rc-progress": "~2.1.0",
"rc-radio": "~2.0.0",
"rc-rate": "~2.1.0",
"rc-select": "~6.7.1",
"rc-select": "~6.8.0",
"rc-slider": "~6.1.0",
"rc-steps": "~2.4.0",
"rc-switch": "~1.4.2",

View File

@ -51,7 +51,7 @@ module.exports = {
'app.footer.discuss': 'Chat Room',
'app.footer.bug-report': 'Bug Report',
'app.footer.version': 'Version: ',
'app.footer.author': 'Created by Ant UED',
'app.footer.author': 'Created by AIUX',
'app.publish.title': 'antd@2.0.0 is released!',
'app.publish.greeting': 'Hello, ',
'app.publish.intro': ' is released, and please upgrade. ',

View File

@ -81,6 +81,7 @@
color: rgba(255, 255, 255, .75);
left: 50%;
margin-left: -7px;
animation: upDownMove 1.2s ease-in-out infinite alternate;
}
.page {
@ -164,3 +165,9 @@
line-height: 28px;
color: #999;
}
@keyframes upDownMove {
to {
transform: translateY(10px);
}
}

View File

@ -20,7 +20,11 @@ export default function Banner({ location, onEnterChange }) {
const isZhCN = utils.isZhCN(location.pathname);
return (
<section className="page banner-wrapper">
<ScrollElement id="banner" onChange={({ mode }) => onEnterChange(mode)}>
<ScrollElement
className="page" id="banner"
onChange={({ mode }) => onEnterChange(mode)}
playScale={0.9}
>
<QueueAnim className="banner-text-wrapper" type={typeFunc} delay={300} key="banner">
<h2 key="h2">ANT <p>DESIGN</p></h2>
<p key="content"><FormattedMessage id="app.home.slogan" /></p>

View File

@ -7,24 +7,9 @@ import { Icon, Button } from 'antd';
import QueueAnim from 'rc-queue-anim';
import * as utils from '../utils';
function onScrollEvent(e) {
const clientHeight = document.documentElement.clientHeight;
const header = document.getElementById('header');
if (e.pageY >= clientHeight) {
if (header.className.indexOf('home-nav-bottom') < 0) {
header.className += ' home-nav-bottom';
}
} else if (header.className.indexOf('home-nav-bottom') >= 0) {
header.className = header.className.replace(/home-nav-bottom/ig, '');
}
}
export default function Page1({ location }) {
return (
<ScrollOverPack id="page1" className="content-wrapper page"
replay scrollEvent={onScrollEvent}
hideProps={{ image: { reverse: true } }}
>
<ScrollOverPack id="page1" className="content-wrapper page">
<TweenOne key="image" className="image1 image-wrapper"
animation={{ x: 0, opacity: 1, ease: 'easeOutQuad' }}
style={{ transform: 'translateX(-100px)', opacity: 0 }}

View File

@ -10,8 +10,7 @@ import * as utils from '../utils';
export default function Page2({ location }) {
return (
<ScrollOverPack id="page2"
className="content-wrapper page" replay
hideProps={{ image: { reverse: true } }}
className="content-wrapper page"
>
<QueueAnim className="text-wrapper left-text" key="text"
duration={450} type="bottom" leaveReverse

View File

@ -9,9 +9,7 @@ import * as utils from '../utils';
export default function Page3({ location }) {
return (
<ScrollOverPack id="page3" className="content-wrapper page" replay
hideProps={{ image: { reverse: true } }}
>
<ScrollOverPack id="page3" className="content-wrapper page">
<TweenOne key="image" className="image3 image-wrapper"
animation={{ x: 0, opacity: 1, ease: 'easeOutQuad' }}
style={{ transform: 'translateX(-100px)', opacity: 0 }}

View File

@ -6,9 +6,7 @@ import QueueAnim from 'rc-queue-anim';
export default function Page4() {
return (
<ScrollOverPack id="page4" className="content-wrapper page"
hideProps={{ image: { reverse: true } }}
>
<ScrollOverPack id="page4" className="content-wrapper page">
<QueueAnim className="text-wrapper-bottom" key="text"
leaveReverse type="bottom"
>

View File

@ -94,9 +94,6 @@ function getStyle() {
#footer a {
color: #eee;
}
.down {
animation: upDownMove 1.2s ease-in-out infinite;
}
`;
}