Merge branch 'feature-3.8.0' of https://github.com/ant-design/ant-design into feature/svg-icon

# Conflicts:
#	components/locale-provider/__tests__/__snapshots__/demo.test.js.snap
#	components/locale-provider/__tests__/__snapshots__/index.test.js.snap
#	components/transfer/__tests__/__snapshots__/demo.test.js.snap
#	components/transfer/__tests__/__snapshots__/index.test.js.snap
This commit is contained in:
HeskeyBaozi 2018-07-23 09:58:55 +08:00
commit bab50e6bed
50 changed files with 828 additions and 3765 deletions

View File

@ -17,12 +17,10 @@ timeline: true
## 3.7.0
3.7.0 is a heavy update that brings a lot of exciting changes and new features.
3.7.0 is a heavy update that brings a lot of exciting changes and new features.
Here are some highlights ✨:
- 🌟 Add drawer component : [Drawer](https://ant.design/components/drawer-cn/). [#10791](https://github.com/ant-design/ant-design/pull/10791)
- 🌟 Horizontal menu automatically collapses when there is no enough space. [#11234](https://github.com/ant-design/ant-design/pull/11234)
![demo](https://user-images.githubusercontent.com/1731837/42550555-0fef7878-8505-11e8-9d2f-f708fec66b44.gif)
- 🌟 Add `Tree.DirectoryTree` component as the built-in directory tree. [#7749](https://github.com/ant-design/ant-design/issues/7749)
Component Fixes / Enhancements:
@ -33,8 +31,8 @@ Component Fixes / Enhancements:
- 🌟 Add `maxTagCount` prop to set the max count of visible tags. [fb96c9d](https://github.com/ant-design/ant-design/commit/fb96c9db351e44a202f64f780470c6319a8a9626)
- 🌟 Add `maxTagPlaceholder` prop to set the content when the tag is hidden. [fb96c9d](https://github.com/ant-design/ant-design/commit/fb96c9db351e44a202f64f780470c6319a8a9626)
- 🌟 Search input now supports case sensitive search. [#10990](https://github.com/ant-design/ant-design/issues/10990)
- 🗑 Remove `label` prop and use `title` prop instead in the `treeData`.
- Upgrade `rc-upload` to `2.5.0` for Upload.
- 🗑 Remove `label` prop and use `title` prop instead in the `treeData`.
- Upgrade `rc-upload` to `2.5.0` for Upload.
- 🌟 Add `directory` prop to support folder uploading. [#7315](https://github.com/ant-design/ant-design/issues/7315)
- 🌟 `action` prop supports to be the a function which returns a Promise object. [fd96967](https://github.com/ant-design/ant-design/commit/fd96967c872600b79bb608e9ddf9f8c38814a704)
- Dropdown

View File

@ -17,12 +17,10 @@ timeline: true
## 3.7.0
3.7.0是一个重磅更新,带来了很多激动人心的变化和新特性。
3.7.0是一个重磅更新,带来了很多激动人心的变化和新特性。
以下是一些亮点✨:
- 🔥 增加抽屉组件 : [`Drawer`](https://ant.design/components/drawer-cn/) [#10791](https://github.com/ant-design/ant-design/pull/10791)
- 🔥 Menu 增加一个横向菜单在空间不足时溢出部分自动收起的特性。[#11234](https://github.com/ant-design/ant-design/pull/11234)
![demo](https://user-images.githubusercontent.com/1731837/42550555-0fef7878-8505-11e8-9d2f-f708fec66b44.gif)
- 🔥 新增 `Tree.DirectoryTree` 组件,作为内置的目录树。[#7749](https://github.com/ant-design/ant-design/issues/7749)
组件修复/功能增强:
@ -64,7 +62,7 @@ timeline: true
- 🌟 增加 `okButtonDisabled` and `cancelButtonDisabled` 属性用于禁用确定和取消按钮。[#10955](https://github.com/ant-design/ant-design/pull/10955)
- 🌟 Cascader 新增 fieldNames 并废弃拼写错误的 filedNames。 [#10896](https://github.com/ant-design/ant-design/issues/10896)
- 🐞 修复时间轴不能与`Tooltip`一起使用的问题。 [0e3b67e](https://github.com/ant-design/ant-design/commit/0e3b67e9999d867cc304f3be61a8a042a2ab92ee)
- 🐞 修复当 Avata 自定义大小时,圆角不改变的问题。[e1e6523](https://github.com/ant-design/ant-design/commit/e1e6523452286ba56f20b73abad762a58ea7d7bc)
- 🐞 修复当 Avatar 自定义大小时,圆角不改变的问题。[e1e6523](https://github.com/ant-design/ant-design/commit/e1e6523452286ba56f20b73abad762a58ea7d7bc)
## 3.6.6

View File

@ -34,6 +34,10 @@
* 支持服务端渲染。
* [Electron](http://electron.atom.io/)
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
| --------- | --------- | --------- | --------- | --------- | --------- |
| IE9, IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions
## 参与共建 [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
请参考[贡献指南](https://ant.design/docs/react/contributing-cn).
@ -94,7 +98,7 @@ $ npm install
$ npm start
```
打开浏览器访问 http://127.0.0.1:8001 ,更多本地开发文档参见: https://github.com/ant-design/ant-design/wiki/Development
打开浏览器访问 http://127.0.0.1:8001 ,更多[本地开发文档](https://github.com/ant-design/ant-design/wiki/Development)
## 如何贡献

View File

@ -38,6 +38,10 @@ An enterprise-class UI design language and React-based implementation.
* Server-side Rendering
* [Electron](http://electron.atom.io/)
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Electron |
| --------- | --------- | --------- | --------- | --------- | --------- |
| IE9, IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions
## Let's build a better antd together [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
Read our [contributing guide](https://ant.design/docs/react/contributing).
@ -67,7 +71,6 @@ Or [import components on demand](https://ant.design/docs/react/getting-started#I
See [Use in TypeScript](https://ant.design/docs/react/use-in-typescript)
## Internationalization
See [i18n](http://ant.design/docs/react/i18n).
@ -98,7 +101,7 @@ $ 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 .
Open your browser and visit http://127.0.0.1:8001 , see more at [Development](https://github.com/ant-design/ant-design/wiki/Development).
## Contributing

View File

@ -27,6 +27,14 @@ export default class AnchorLink extends React.Component<AnchorLinkProps, any> {
this.context.antAnchor.registerLink(this.props.href);
}
componentWillReceiveProps(nextProps: AnchorLinkProps) {
const { href } = nextProps;
if (this.props.href !== href) {
this.context.antAnchor.unregisterLink(this.props.href);
this.context.antAnchor.registerLink(href);
}
}
componentWillUnmount() {
this.context.antAnchor.unregisterLink(this.props.href);
}

View File

@ -90,4 +90,20 @@ describe('Anchor Render', () => {
wrapper.setProps({ children: null });
expect(wrapper.instance().links).toEqual([]);
});
it('should update links when link href update', async () => {
let anchorInstance = null;
function AnchorUpdate({ href }) {
return (
<Anchor ref={c => anchorInstance = c}>
<Link href={href} title="API" />
</Anchor>
);
}
const wrapper = mount(<AnchorUpdate href="#API" />);
expect(anchorInstance.links).toEqual(['#API']);
wrapper.setProps({ href: '#API_1' });
expect(anchorInstance.links).toEqual(['#API_1']);
});
});

View File

@ -34,9 +34,9 @@ const dataSource = ['12345', '23456', '34567'];
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` |
| placeholder | 输入框提示 | string | - |
| value | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | 无 |
| onBlur | 获取焦点时的回调 | function() | - |
| onBlur | 失去焦点时的回调 | function() | - |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 |
| onFocus | 失去焦点时的回调 | function() | - |
| onFocus | 获得焦点时的回调 | function() | - |
| onSearch | 搜索补全项的时候调用 | function(value) | 无 |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |

View File

@ -19,6 +19,7 @@ export type CardType = 'inner';
export interface CardTabListType {
key: string;
tab: React.ReactNode;
disabled?: boolean;
}
export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
@ -225,7 +226,7 @@ export default class Card extends React.Component<CardProps, CardState> {
size="large"
onChange={this.onTabChange}
>
{tabList.map(item => <Tabs.TabPane tab={item.tab} key={item.key} />)}
{tabList.map(item => <Tabs.TabPane tab={item.tab} disabled={item.disabled} key={item.key} />)}
</Tabs>
) : null;
if (title || extra || tabs) {

View File

@ -1,6 +1,7 @@
/* tslint:disable jsx-no-multiline-js */
import * as React from 'react';
import * as moment from 'moment';
import { polyfill } from 'react-lifecycles-compat';
import RangeCalendar from 'rc-calendar/lib/RangeCalendar';
import RcDatePicker from 'rc-calendar/lib/Picker';
import classNames from 'classnames';
@ -63,13 +64,31 @@ function fixLocale(value: RangePickerValue | undefined, localeCode: string) {
}
}
export default class RangePicker extends React.Component<any, RangePickerState> {
class RangePicker extends React.Component<any, RangePickerState> {
static defaultProps = {
prefixCls: 'ant-calendar',
allowClear: true,
showToday: false,
};
static getDerivedStateFromProps(nextProps: any, prevState: any) {
let state = null;
if ('value' in nextProps) {
const value = nextProps.value || [];
state = {
value,
showDate: getShowDateFromValue(value) || prevState.showDate,
};
}
if (('open' in nextProps) && prevState.open !== nextProps.open) {
state = {
...state,
open: nextProps.open,
};
}
return state;
}
private picker: HTMLSpanElement;
constructor(props: any) {
@ -93,22 +112,6 @@ export default class RangePicker extends React.Component<any, RangePickerState>
};
}
componentWillReceiveProps(nextProps: any) {
if ('value' in nextProps) {
const state = this.state;
const value = nextProps.value || [];
this.setState({
value,
showDate: getShowDateFromValue(value) || state.showDate,
});
}
if ('open' in nextProps) {
this.setState({
open: nextProps.open,
});
}
}
clearSelection = (e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
e.stopPropagation();
@ -366,3 +369,7 @@ export default class RangePicker extends React.Component<any, RangePickerState>
);
}
}
polyfill(RangePicker);
export default RangePicker;

View File

@ -1,5 +1,6 @@
import * as React from 'react';
import * as moment from 'moment';
import { polyfill } from 'react-lifecycles-compat';
import Calendar from 'rc-calendar';
import RcDatePicker from 'rc-calendar/lib/Picker';
import classNames from 'classnames';
@ -10,12 +11,19 @@ function formatValue(value: moment.Moment | null, format: string): string {
return (value && value.format(format)) || '';
}
export default class WeekPicker extends React.Component<any, any> {
class WeekPicker extends React.Component<any, any> {
static defaultProps = {
format: 'gggg-wo',
allowClear: true,
};
static getDerivedStateFromProps(nextProps: any) {
if ('value' in nextProps) {
return { value: nextProps.value };
}
return null;
}
private input: any;
constructor(props: any) {
@ -31,11 +39,6 @@ export default class WeekPicker extends React.Component<any, any> {
value,
};
}
componentWillReceiveProps(nextProps: any) {
if ('value' in nextProps) {
this.setState({ value: nextProps.value });
}
}
weekDateRender = (current: any) => {
const selectedValue = this.state.value;
const { prefixCls } = this.props;
@ -149,3 +152,7 @@ export default class WeekPicker extends React.Component<any, any> {
);
}
}
polyfill(WeekPicker);
export default WeekPicker;

View File

@ -1,5 +1,6 @@
import * as React from 'react';
import * as moment from 'moment';
import { polyfill } from 'react-lifecycles-compat';
import MonthCalendar from 'rc-calendar/lib/MonthCalendar';
import RcDatePicker from 'rc-calendar/lib/Picker';
import classNames from 'classnames';
@ -15,13 +16,22 @@ export interface PickerProps {
}
export default function createPicker(TheCalendar: React.ComponentClass): any {
return class CalenderWrapper extends React.Component<any, any> {
class CalenderWrapper extends React.Component<any, any> {
static defaultProps = {
prefixCls: 'ant-calendar',
allowClear: true,
showToday: true,
};
static getDerivedStateFromProps(nextProps: PickerProps) {
if ('value' in nextProps) {
return {
value: nextProps.value,
showDate: nextProps.value,
};
}
}
private input: any;
constructor(props: any) {
@ -39,15 +49,6 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
};
}
componentWillReceiveProps(nextProps: PickerProps) {
if ('value' in nextProps) {
this.setState({
value: nextProps.value,
showDate: nextProps.value,
});
}
}
renderFooter = (...args: any[]) => {
const { prefixCls, renderExtraFooter } = this.props;
return renderExtraFooter ? (
@ -195,5 +196,7 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
</span>
);
}
};
}
polyfill(CalenderWrapper);
return CalenderWrapper;
}

View File

@ -81,7 +81,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| format | to set the date format, refer to [moment.js](http://momentjs.com/) | string | "YYYY-MM-DD" |
| renderExtraFooter | render extra footer in panel | () => React.ReactNode | - |
| showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() |
| showTime.defaultValue | to set default time of selected date, [demo](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() |
| showToday | whether to show "Today" button | boolean | true |
| value | to set date | [moment](http://momentjs.com/) | - |
| onCalendarChange | a callback function, can be executed when the start time or the end time of the range is changing | function(dates: [moment, moment], dateStrings: [string, string]) | 无 |
@ -118,7 +118,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| ranges | preseted ranges for quick selection | { \[range: string]: [moment](http://momentjs.com/)\[] } \| () => { \[range: string]: [moment](http://momentjs.com/)\[] } | - |
| renderExtraFooter | render extra footer in panel | () => React.ReactNode | - |
| showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] |
| showTime.defaultValue | to set default time of selected date, [demo](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] |
| value | to set date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - |
| onChange | a callback function, can be executed when the selected time is changing | function(dates: [moment, moment], dateStrings: [string, string]) | - |
| onOk | callback when click ok button | function() | - |

View File

@ -81,7 +81,7 @@ import 'moment/locale/zh-cn';
| mode | 日期面板的状态 | `time|date|month|year` | 'date' |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() |
| showToday | 是否展示“今天”按钮 | boolean | true |
| value | 日期 | [moment](http://momentjs.com/) | 无 |
| onChange | 时间发生变化的回调 | function(date: moment, dateString: string) | 无 |
@ -118,7 +118,7 @@ import 'moment/locale/zh-cn';
| ranges       | 预设时间范围快捷选择 | { \[range: string]: [moment](http://momentjs.com/)\[] } \| () => { \[range: string]: [moment](http://momentjs.com/)\[] } | 无 |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] |
| value | 日期 | [moment](http://momentjs.com/)\[] | 无 |
| onCalendarChange | 待选日期发生变化的回调 | function(dates: [moment, moment], dateStrings: [string, string]) | 无 |
| onChange | 日期范围发生变化的回调 | function(dates: [moment, moment], dateStrings: [string, string]) | 无 |

View File

@ -50,7 +50,6 @@
&-horizontal&-with-text-left,
&-horizontal&-with-text-right {
font-size: @font-size-base;
.@{divider-prefix-cls}-inner-text {
display: inline-block;
padding: 0 10px;

View File

@ -1,9 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Drawer closable is false 1`] = `
<div
class=""
>
<div>
<div
class="ant-drawer ant-drawer-right ant-drawer-open"
>
@ -33,9 +31,7 @@ exports[`Drawer closable is false 1`] = `
`;
exports[`Drawer destroyOnClose is true 1`] = `
<div
class=""
>
<div>
<div
class="ant-drawer ant-drawer-right"
>
@ -48,16 +44,18 @@ exports[`Drawer destroyOnClose is true 1`] = `
>
<div
class="ant-drawer-content"
/>
>
<div
style="overflow: auto; height: 100%; width: 256px;"
/>
</div>
</div>
</div>
</div>
`;
exports[`Drawer have a title 1`] = `
<div
class=""
>
<div>
<div
class="ant-drawer ant-drawer-right ant-drawer-open"
>
@ -104,9 +102,7 @@ exports[`Drawer have a title 1`] = `
`;
exports[`Drawer render correctly 1`] = `
<div
class=""
>
<div>
<div
class="ant-drawer ant-drawer-right ant-drawer-open"
>

View File

@ -10,9 +10,7 @@ exports[`Drawer render correctly 1`] = `
open
</span>
</button>
<div
class=""
>
<div>
<div
class="ant-drawer ant-drawer-right ant-drawer-open"
>

View File

@ -108,8 +108,16 @@ export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
}
renderBody = () => {
const { destroyOnClose, visible, width, placement } = this.props;
let containerStyle: React.CSSProperties = { width };
if (placement === 'left' || placement === 'right') {
containerStyle = {
overflow: 'auto',
height: '100%',
width,
};
}
if (destroyOnClose && !visible) {
return null;
return <div style={containerStyle}/>;
}
const { prefixCls, title, closable } = this.props;
let header;
@ -132,14 +140,7 @@ export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
</button>
);
}
let containerStyle: React.CSSProperties = { width };
if (placement === 'left' || placement === 'right') {
containerStyle = {
overflow: 'auto',
height: '100%',
width,
};
}
return (
<div style={containerStyle}>
{header}
@ -172,6 +173,7 @@ export default class Drawer extends React.Component<DrawerProps, IDrawerState> {
showMask={this.props.mask}
placement={placement}
style={RcDrawerStyle}
class={this.props.wrapClassName}
>
{this.renderBody()}
</RcDrawer>

View File

@ -8,7 +8,7 @@
width: 100%;
height: 100%;
pointer-events: none;
z-index: 99999;
z-index: @zindex-modal;
transition: transform .3s @ease-in-out-circ;
>* {
transition: transform .3s @ease-in-out-circ;

View File

@ -100,7 +100,6 @@ title: Layout
| trigger | 自定义 trigger设置为 null 时隐藏 trigger | string\|ReactNode | - |
| width | 宽度 | number\|string | 200 |
| onCollapse | 展开-收起时的回调函数,有点击 trigger 以及响应式反馈两种方式可以触发 | (collapsed, type) => {} | - |
| theme | 主题颜色 | string: `light` `dark` | `dark` |
| onBreakpoint | 触发响应式布局[断点](/components/grid#api)时的回调 | (broken) => {} | - |
#### breakpoint width

View File

@ -362,25 +362,8 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M769.2 254.8C726.2 211.7 668.9 188 608 188s-118.2 23.7-161.2 66.8C403.7 297.8 380 355.1 380 416s23.7 118.2 66.8 161.2c43 43.1 100.3 66.8 161.2 66.8s118.2-23.7 161.2-66.8c43.1-43 66.8-100.3 66.8-161.2s-23.7-118.2-66.8-161.2z"
fill="none"
/>
<path
d="M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L114.3 856.1c-3.1 3.1-3.1 8.2 0 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6C473 696.1 537.7 720 608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2z"
/>
</svg>
</i>
class="anticon anticon-search"
/>
</span>
</div>
</div>
@ -403,21 +386,8 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
@ -425,21 +395,8 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div
@ -491,25 +448,8 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M769.2 254.8C726.2 211.7 668.9 188 608 188s-118.2 23.7-161.2 66.8C403.7 297.8 380 355.1 380 416s23.7 118.2 66.8 161.2c43 43.1 100.3 66.8 161.2 66.8s118.2-23.7 161.2-66.8c43.1-43 66.8-100.3 66.8-161.2s-23.7-118.2-66.8-161.2z"
fill="none"
/>
<path
d="M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L114.3 856.1c-3.1 3.1-3.1 8.2 0 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6C473 696.1 537.7 720 608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2z"
/>
</svg>
</i>
class="anticon anticon-search"
/>
</span>
</div>
</div>
@ -1570,27 +1510,9 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
<span>
Name
<i
class="anticon ant-dropdown-trigger"
>
<svg
aria-hidden="true"
class="ant-dropdown-trigger"
data-icon="filter"
fill="currentColor"
height="1em"
title="Filter menu"
viewBox="0 0 1024 1024"
width="1em"
>
<path
class="st0"
d="M411 561.4l9.5 16.6h183l9.5-16.6L811.3 226H212.7zM420.6 642h182.9v156H420.6z"
/>
<path
d="M880.1 154H143.9c-24.5 0-39.8 26.7-27.5 48L349 597.4V838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V597.4L907.7 202c12.2-21.3-3.1-48-27.6-48zM603.4 798H420.6V642h182.9v156zm9.6-236.6l-9.5 16.6h-183l-9.5-16.6L212.7 226h598.6L613 561.4z"
/>
</svg>
</i>
class="anticon anticon-filter ant-dropdown-trigger"
title="Filter menu"
/>
</span>
</th>
<th

View File

@ -58,9 +58,7 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
aria-haspopup="true"
class="ant-menu-submenu-title"
>
<span
class="submenu-title-wrapper"
>
<span>
<i
class="anticon"
>

View File

@ -85,7 +85,6 @@ describe('Menu', () => {
wrapper.update();
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
wrapper.setProps({ openKeys: ['1'] });
wrapper.update();
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
});
@ -104,7 +103,6 @@ describe('Menu', () => {
wrapper.update();
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
wrapper.setProps({ openKeys: ['1'] });
wrapper.update();
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
});
@ -123,7 +121,6 @@ describe('Menu', () => {
wrapper.update();
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
wrapper.setProps({ openKeys: ['1'] });
wrapper.update();
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
});

View File

@ -44,7 +44,7 @@ class App extends React.Component {
<Menu.Item key="app" disabled>
<Icon type="appstore" />Navigation Two
</Menu.Item>
<SubMenu title={<span className="submenu-title-wrapper"><Icon type="setting" />Navigation Three - Submenu</span>}>
<SubMenu title={<span><Icon type="setting" />Navigation Three - Submenu</span>}>
<MenuItemGroup title="Item 1">
<Menu.Item key="setting:1">Option 1</Menu.Item>
<Menu.Item key="setting:2">Option 2</Menu.Item>

View File

@ -24,13 +24,14 @@
}
&-dark&-horizontal {
border-bottom-color: @menu-dark-bg;
border-bottom: 0;
}
&-dark&-horizontal > &-item,
&-dark&-horizontal > &-submenu {
border-color: @menu-dark-bg;
border-bottom: 0;
top: 0;
}
&-dark&-horizontal > &-item > a:before {

View File

@ -179,10 +179,6 @@
position: absolute;
border-radius: @border-radius-base;
z-index: @zindex-dropdown;
.submenu-title-wrapper {
padding-right: 20px;
}
}
> .@{menu-prefix-cls} {
@ -266,13 +262,12 @@
border-bottom: @border-width-base @border-style-base @border-color-split;
box-shadow: none;
line-height: 46px;
white-space: nowrap;
> .@{menu-prefix-cls}-item,
> .@{menu-prefix-cls}-submenu {
position: relative;
top: 1px;
display: inline-block;
float: left;
border-bottom: 2px solid transparent;
&:hover,

View File

@ -21,7 +21,7 @@
}
&-notice-content {
padding: 10px 16px;
padding: @message-notice-content-padding;
border-radius: @border-radius-base;
box-shadow: @shadow-2;
background: @component-background;

View File

@ -24,6 +24,7 @@ used in the following cases:
- `notification.info(config)`
- `notification.warning(config)`
- `notification.warn(config)`
- `notification.open(config)`
- `notification.close(key: String)`
- `notification.destroy()`

View File

@ -23,6 +23,7 @@ subtitle: 通知提醒框
- `notification.info(config)`
- `notification.warning(config)`
- `notification.warn(config)`
- `notification.open(config)`
- `notification.close(key: String)`
- `notification.destroy()`

View File

@ -407,16 +407,11 @@ exports[`renders ./components/select/demo/search-box.md correctly 1`] = `
>
<div
class="ant-select-selection__placeholder"
style="display:none;user-select:none;-webkit-user-select:none"
style="display:block;user-select:none;-webkit-user-select:none"
unselectable="on"
>
input search text
</div>
<div
class="ant-select-selection-selected-value"
style="display:block;opacity:1"
title=""
/>
<div
class="ant-select-search ant-select-search--inline"
style="display:none"

View File

@ -58,7 +58,7 @@ function fetch(value, callback) {
class SearchInput extends React.Component {
state = {
data: [],
value: '',
value: undefined,
}
handleSearch = (value) => {

View File

@ -49,6 +49,8 @@ export interface SelectProps extends AbstractSelectProps {
onFocus?: () => any;
onPopupScroll?: () => any;
onInputKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
onMouseEnter?: (e: React.MouseEvent<HTMLInputElement>) => any;
onMouseLeave?: (e: React.MouseEvent<HTMLInputElement>) => any;
maxTagCount?: number;
maxTagPlaceholder?: React.ReactNode | ((omittedValues: SelectValue[]) => React.ReactNode);
optionFilterProp?: string;

View File

@ -38,6 +38,7 @@
.reset-component;
display: inline-block;
position: relative;
outline: 0;
ul,
ol {

View File

@ -482,4 +482,8 @@
@collapse-content-padding: @padding-md;
@collapse-content-bg: @component-background;
// Message
// ---
@message-notice-content-padding: 10px 16px;
@import "./default.deperated.less";

View File

@ -104,23 +104,16 @@
}
&-small&-checked {
&:before,
&:after {
&:before {
left: 100%;
margin-left: @switch-sm-checked-margin-left;
}
.@{switch-prefix-cls}-inner {
margin-left: 3px;
margin-right: 18px;
}
}
&-small:active&-checked:before,
&-small:active&-checked:after {
margin-left: -16.5px;
}
&-small&-loading:before {
animation: AntSwitchSmallLoadingCircle 1s infinite linear;
font-weight: bold;
@ -134,15 +127,15 @@
margin-right: 24px;
}
&:before,
&:after {
&:before {
left: 100%;
margin-left: -19px;
}
&:active:before,
&:active:after {
margin-left: -25px;
&:after {
left: 100%;
transform: translateX(-100%);
margin-left: -1px;
}
}

View File

@ -626,7 +626,8 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
const recordKey = (typeof rowKey === 'function') ?
rowKey(record, index) : (record as any)[rowKey as string];
warning(recordKey !== undefined,
'Each record in dataSource of table should have a unique `key` prop, or set `rowKey` to an unique primary key,' +
'Each record in dataSource of table should have a unique `key` prop, ' +
'or set `rowKey` of Table to an unique primary key, ' +
'see https://u.ant.design/table-row-key',
);
return recordKey === undefined ? index : recordKey;

View File

@ -162,7 +162,7 @@ class EditableTable extends React.Component {
});
this.setState({ data: newData, editingKey: '' });
} else {
newData.push(data);
newData.push(row);
this.setState({ data: newData, editingKey: '' });
}
});

View File

@ -106,7 +106,7 @@ export interface TableProps<T> {
onExpandedRowsChange?: (expandedRowKeys: string[] | number[]) => void;
onExpand?: (expanded: boolean, record: T) => void;
onChange?: (
pagination: PaginationConfig | boolean,
pagination: PaginationConfig,
filters: Record<keyof T, string[]>,
sorter: SorterResult<T>,
) => void;

View File

@ -54,25 +54,8 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M769.2 254.8C726.2 211.7 668.9 188 608 188s-118.2 23.7-161.2 66.8C403.7 297.8 380 355.1 380 416s23.7 118.2 66.8 161.2c43 43.1 100.3 66.8 161.2 66.8s118.2-23.7 161.2-66.8c43.1-43 66.8-100.3 66.8-161.2s-23.7-118.2-66.8-161.2z"
fill="none"
/>
<path
d="M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L114.3 856.1c-3.1 3.1-3.1 8.2 0 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6C473 696.1 537.7 720 608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2z"
/>
</svg>
</i>
class="anticon anticon-search"
/>
</span>
</div>
</div>
@ -108,23 +91,10 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
<span>
to left
to right
</span>
</button>
<button
@ -133,23 +103,10 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
<span>
to right
to left
</span>
</button>
</div>
@ -203,25 +160,8 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M769.2 254.8C726.2 211.7 668.9 188 608 188s-118.2 23.7-161.2 66.8C403.7 297.8 380 355.1 380 416s23.7 118.2 66.8 161.2c43 43.1 100.3 66.8 161.2 66.8s118.2-23.7 161.2-66.8c43.1-43 66.8-100.3 66.8-161.2s-23.7-118.2-66.8-161.2z"
fill="none"
/>
<path
d="M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L114.3 856.1c-3.1 3.1-3.1 8.2 0 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6C473 696.1 537.7 720 608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2z"
/>
</svg>
</i>
class="anticon anticon-search"
/>
</span>
</div>
</div>
@ -368,21 +308,8 @@ exports[`renders ./components/transfer/demo/basic.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
@ -390,21 +317,8 @@ exports[`renders ./components/transfer/demo/basic.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div
@ -541,21 +455,8 @@ exports[`renders ./components/transfer/demo/custom-item.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
@ -563,21 +464,8 @@ exports[`renders ./components/transfer/demo/custom-item.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div
@ -687,21 +575,8 @@ exports[`renders ./components/transfer/demo/large-data.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
@ -709,21 +584,8 @@ exports[`renders ./components/transfer/demo/large-data.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div
@ -827,25 +689,8 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M769.2 254.8C726.2 211.7 668.9 188 608 188s-118.2 23.7-161.2 66.8C403.7 297.8 380 355.1 380 416s23.7 118.2 66.8 161.2c43 43.1 100.3 66.8 161.2 66.8s118.2-23.7 161.2-66.8c43.1-43 66.8-100.3 66.8-161.2s-23.7-118.2-66.8-161.2z"
fill="none"
/>
<path
d="M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L114.3 856.1c-3.1 3.1-3.1 8.2 0 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6C473 696.1 537.7 720 608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2z"
/>
</svg>
</i>
class="anticon anticon-search"
/>
</span>
</div>
</div>
@ -868,21 +713,8 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
@ -890,21 +722,8 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div
@ -956,25 +775,8 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
class="ant-transfer-list-search-action"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M769.2 254.8C726.2 211.7 668.9 188 608 188s-118.2 23.7-161.2 66.8C403.7 297.8 380 355.1 380 416s23.7 118.2 66.8 161.2c43 43.1 100.3 66.8 161.2 66.8s118.2-23.7 161.2-66.8c43.1-43 66.8-100.3 66.8-161.2s-23.7-118.2-66.8-161.2z"
fill="none"
/>
<path
d="M608 112c-167.9 0-304 136.1-304 304 0 70.3 23.9 135 63.9 186.5L114.3 856.1c-3.1 3.1-3.1 8.2 0 11.3l42.3 42.3c3.1 3.1 8.2 3.1 11.3 0l253.6-253.6C473 696.1 537.7 720 608 720c167.9 0 304-136.1 304-304S775.9 112 608 112zm161.2 465.2C726.2 620.3 668.9 644 608 644s-118.2-23.7-161.2-66.8C403.7 534.2 380 476.9 380 416s23.7-118.2 66.8-161.2c43-43.1 100.3-66.8 161.2-66.8s118.2 23.7 161.2 66.8c43.1 43 66.8 100.3 66.8 161.2s-23.7 118.2-66.8 161.2z"
/>
</svg>
</i>
class="anticon anticon-search"
/>
</span>
</div>
</div>

View File

@ -96,48 +96,22 @@ exports[`Transfer should render correctly 1`] = `
<div
class="ant-transfer-operation"
>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<i
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div
@ -291,21 +265,8 @@ exports[`Transfer should show sorted targetkey 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="left"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8c-16.4 12.8-16.4 37.5 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</i>
class="anticon anticon-right"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
@ -313,21 +274,8 @@ exports[`Transfer should show sorted targetkey 1`] = `
type="button"
>
<i
class="anticon"
>
<svg
aria-hidden="true"
data-icon="right"
fill="currentColor"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7c-5.3-4.1-12.9-.4-12.9 6.3v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1c16.4-12.8 16.4-37.6 0-50.4z"
/>
</svg>
</i>
class="anticon anticon-left"
/>
</button>
</div>
<div

View File

@ -93,14 +93,14 @@ describe('Transfer', () => {
it('should move selected keys to corresponding list', () => {
const handleChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onChange={handleChange} />);
wrapper.find(TransferOperation).find(Button).at(1).simulate('click'); // move selected keys to right list
wrapper.find(TransferOperation).find(Button).at(0).simulate('click'); // move selected keys to right list
expect(handleChange).toHaveBeenCalledWith(['a', 'b'], 'right', ['a']);
});
it('should move selected keys expect disabled to corresponding list', () => {
const handleChange = jest.fn();
const wrapper = mount(<Transfer {...listDisabledProps} onChange={handleChange} />);
wrapper.find(TransferOperation).find(Button).at(1).simulate('click'); // move selected keys to right list
wrapper.find(TransferOperation).find(Button).at(0).simulate('click'); // move selected keys to right list
expect(handleChange).toHaveBeenCalledWith(['b'], 'right', ['b']);
});
@ -209,7 +209,7 @@ describe('Transfer', () => {
.simulate('change', { target: { value: 'content2' } });
wrapper.find(TransferList).at(0).find('.ant-transfer-list-header input[type="checkbox"]').filterWhere(n => !n.prop('checked'))
.simulate('change');
wrapper.find(TransferOperation).find(Button).at(1).simulate('click');
wrapper.find(TransferOperation).find(Button).at(0).simulate('click');
expect(handleChange).toHaveBeenCalledWith(['1', '3', '4'], 'right', ['1']);
});

View File

@ -26,15 +26,6 @@ export default class Operation extends React.Component<TransferOperationProps, a
} = this.props;
return (
<div className={className} style={style}>
<Button
type="primary"
size="small"
disabled={!leftActive}
onClick={moveToLeft}
icon="left"
>
{leftArrowText}
</Button>
<Button
type="primary"
size="small"
@ -44,6 +35,15 @@ export default class Operation extends React.Component<TransferOperationProps, a
>
{rightArrowText}
</Button>
<Button
type="primary"
size="small"
disabled={!leftActive}
onClick={moveToLeft}
icon="left"
>
{leftArrowText}
</Button>
</div>
);
}

View File

@ -158,6 +158,7 @@ export default class DirectoryTree extends React.Component<DirectoryTreeProps, D
expandFolderNode = (event: React.MouseEvent<HTMLElement>, node: AntTreeNode) => {
const { expandedKeys = [] } = this.state;
const { onExpand } = this.props;
const { eventKey = '', expanded, isLeaf } = node.props;
if (isLeaf || event.shiftKey || event.metaKey || event.ctrlKey) {
@ -176,6 +177,14 @@ export default class DirectoryTree extends React.Component<DirectoryTreeProps, D
this.setUncontrolledState({
expandedKeys: newExpandedKeys,
});
if (onExpand) {
onExpand(newExpandedKeys, {
expanded: !expanded,
node,
nativeEvent: event.nativeEvent,
});
}
}
setUncontrolledState = (state: DirectoryTreeState) => {

View File

@ -1104,6 +1104,132 @@ exports[`Directory Tree expand double click 2`] = `
</ul>
`;
exports[`Directory Tree expand with state control click 1`] = `
<ul
class="ant-tree ant-tree-directory"
role="tree-node"
unselectable="on"
>
<li
class="ant-tree-treenode-switcher-open ant-tree-treenode-selected"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
/>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open ant-tree-node-selected"
title="parent"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
class="anticon anticon-folder-open"
/>
</span>
<span
class="ant-tree-title"
>
parent
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
style=""
>
<li
class="ant-tree-treenode-switcher-close"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
/>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="children"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
class="anticon anticon-folder"
/>
</span>
<span
class="ant-tree-title"
>
children
</span>
</span>
</li>
</ul>
</li>
</ul>
`;
exports[`Directory Tree expand with state control doubleClick 1`] = `
<ul
class="ant-tree ant-tree-directory"
role="tree-node"
unselectable="on"
>
<li
class="ant-tree-treenode-switcher-open"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
/>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="parent"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
class="anticon anticon-folder-open"
/>
</span>
<span
class="ant-tree-title"
>
parent
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
style=""
>
<li
class="ant-tree-treenode-switcher-close"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
/>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="children"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
class="anticon anticon-folder"
/>
</span>
<span
class="ant-tree-title"
>
children
</span>
</span>
</li>
</ul>
</li>
</ul>
`;
exports[`Directory Tree expandedKeys update 1`] = `
<ul
class="ant-tree ant-tree-directory"

View File

@ -49,6 +49,42 @@ describe('Directory Tree', () => {
wrapper.find(TreeNode).find('.ant-tree-node-content-wrapper').at(0).simulate('doubleClick');
expect(wrapper.render()).toMatchSnapshot();
});
describe('with state control', () => {
class StateDirTree extends React.Component {
state = {
expandedKeys: [],
};
onExpand = (expandedKeys) => {
this.setState({ expandedKeys });
};
render() {
const { expandedKeys } = this.state;
return (
<DirectoryTree expandedKeys={expandedKeys} onExpand={this.onExpand} {...this.props}>
<TreeNode key="0-0" title="parent">
<TreeNode key="0-0-0" title="children" />
</TreeNode>
</DirectoryTree>
);
}
}
['click', 'doubleClick'].forEach((action) => {
it(action, () => {
const wrapper = mount(
<StateDirTree expandAction={action} />
);
wrapper.find(TreeNode).find('.ant-tree-node-content-wrapper').at(0).simulate(action);
jest.runAllTimers();
expect(wrapper.render()).toMatchSnapshot();
});
});
});
});
it('defaultExpandAll', () => {

View File

@ -4,7 +4,7 @@ order: 1
title: Design Values
---
Ant Design provides a practical evaluation of better design for both designers of Ant Design and designers who are using it. At the same time, it build a foundation for design principles and design patterns which could provide guideline and general solutions for specified design goal.
Ant Design provides a practical evaluation of better design for both designers of Ant Design and designers who are using it. At the same time, it builds a foundation for design principles and design patterns which could provide guideline and general solutions for specified design goal.
<div>
<img src="https://gw.alipayobjects.com/zos/rmsportal/kEwBspjVFChYqhqafCiW.png" />

View File

@ -7,7 +7,7 @@ title:
可视化语言是基于中台设计语言 Ant Design 衍生的一套具有数据可视化特性的设计指导原则,让数据表达更符合用户心理,帮助『设计者』孵化出更具业务特性的可视化解决方案以满足个性化设计需求,屏蔽不必要的设计差异和实现成本,从而解放『设计者』和前端的研发资源,实现全面提高数据图表的研发效率。
同时,这是一份动态更新的设计文档,你的阅读和反馈正是我们不断前进的动力,[Github 反馈地址](https://github.com/antvis/site/issues)。
同时,这是一份动态更新的设计文档,你的阅读和反馈正是我们不断前进的动力,[GitHub 反馈地址](https://github.com/antvis/site/issues)。
## 设计资源

View File

@ -61,12 +61,12 @@
"rc-checkbox": "~2.1.5",
"rc-collapse": "~1.9.0",
"rc-dialog": "~7.1.0",
"rc-drawer": "~1.5.3",
"rc-drawer": "~1.5.9",
"rc-dropdown": "~2.2.0",
"rc-editor-mention": "^1.0.2",
"rc-form": "^2.1.0",
"rc-input-number": "~4.0.0",
"rc-menu": "~7.2.2",
"rc-menu": "~7.0.2",
"rc-notification": "~3.1.1",
"rc-pagination": "~1.16.1",
"rc-progress": "~2.2.2",
@ -85,7 +85,7 @@
"rc-upload": "~2.5.0",
"rc-util": "^4.0.4",
"react-lazy-load": "^3.0.12",
"react-lifecycles-compat": "^3.0.4",
"react-lifecycles-compat": "^3.0.2",
"react-slick": "~0.23.1",
"shallowequal": "^1.0.1",
"warning": "~4.0.1"
@ -94,6 +94,7 @@
"@babel/types": "7.0.0-beta.44",
"@types/react": "^16.0.0",
"@types/react-dom": "^16.0.0",
"@yesmeck/offline-plugin": "^5.0.5",
"ansi-styles": "^3.2.0",
"ant-design-palettes": "^1.0.0",
"antd-theme-generator": "1.0.7",
@ -142,7 +143,6 @@
"majo": "^0.6.2",
"mockdate": "^2.0.1",
"moment-timezone": "^0.5.5",
"offline-plugin": "yesmeck/offline-plugin#fix-cache-key",
"pre-commit": "^1.2.2",
"preact": "^8.2.5",
"preact-compat": "^3.17.0",

View File

@ -1,6 +1,6 @@
const path = require('path');
const CSSSplitWebpackPlugin = require('css-split-webpack-plugin').default;
const OfflinePlugin = require('offline-plugin');
const OfflinePlugin = require('@yesmeck/offline-plugin');
const replaceLib = require('antd-tools/lib/replaceLib');
const getExternalResources = require('./getExternalResources');

View File

@ -6,7 +6,7 @@ import { addLocaleData, IntlProvider } from 'react-intl';
import 'moment/locale/zh-cn';
import { LocaleProvider } from 'antd';
import zhCN from 'antd/lib/locale-provider/zh_CN';
import OfflineRuntime from 'offline-plugin/runtime';
import OfflineRuntime from '@yesmeck/offline-plugin/runtime';
import Header from './Header';
import Footer from './Footer';
import enLocale from '../../en-US';