Merge remote-tracking branch 'origin/feature-3.8.0' into tmp

This commit is contained in:
zombiej 2018-07-30 12:05:50 +08:00
commit b8b9aeb1ce
37 changed files with 552 additions and 181 deletions

View File

@ -15,7 +15,8 @@ describe('Avatar Render', () => {
const wrapper = mount(<Avatar src="http://error.url">Fallback</Avatar>, { attachTo: div });
wrapper.instance().setScale = jest.fn(() => wrapper.instance().setState({ scale: 0.5 }));
wrapper.setState({ isImgExist: false });
wrapper.find('img').simulate('error');
const children = wrapper.find('.ant-avatar-string');
expect(children.length).toBe(1);
@ -26,4 +27,41 @@ describe('Avatar Render', () => {
wrapper.detach();
global.document.body.removeChild(div);
});
it('should handle onError correctly', () => {
const LOAD_FAILURE_SRC = 'http://error.url';
const LOAD_SUCCESS_SRC = 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png';
const div = global.document.createElement('div');
global.document.body.appendChild(div);
class Foo extends React.Component {
state = {
src: LOAD_FAILURE_SRC,
}
handleImgError = () => {
this.setState({
src: LOAD_SUCCESS_SRC,
});
return false;
}
render() {
const { src } = this.state;
return <Avatar src={src} onError={this.handleImgError} />;
}
}
const wrapper = mount(<Foo />, { attachTo: div });
// mock img load Error, since jsdom do not load resource by default
// https://github.com/jsdom/jsdom/issues/1816
wrapper.find('img').simulate('error');
expect(wrapper.find(Avatar).instance().state.isImgExist).toBe(true);
expect(div.querySelector('img').getAttribute('src')).toBe(LOAD_SUCCESS_SRC);
wrapper.detach();
global.document.body.removeChild(div);
});
});

View File

@ -15,3 +15,4 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
| size | the size of the avatar | `large` \| `small` \| `default` | `default` |
| src | the address of the image for an image avatar | string | - |
| alt | This attribute defines the alternative text describing the image | string | - |
| onError | handler when img load errorreturn false to prevent default fallback behavior | () => boolean | - |

View File

@ -17,6 +17,9 @@ export interface AvatarProps {
className?: string;
children?: any;
alt?: string;
/* callback when img load error */
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self*/
onError?: () => boolean;
}
export interface AvatarState {
@ -72,7 +75,13 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
}
}
handleImgLoadError = () => this.setState({ isImgExist: false });
handleImgLoadError = () => {
const { onError } = this.props;
const errorFlag = onError ? onError() : undefined;
if (errorFlag !== false) {
this.setState({ isImgExist: false });
}
}
render() {
const {

View File

@ -16,3 +16,4 @@ title: Avatar
| size | 设置头像的大小 | Enum{ 'large', 'small', 'default' } | `default` |
| src | 图片类头像的资源地址 | string | - |
| alt | 图像无法显示时的替代文本 | string | - |
| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - |

View File

@ -707,9 +707,6 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -726,6 +723,9 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
>
tab2
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -804,9 +804,6 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="false"
@ -831,6 +828,9 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
>
project
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>

View File

@ -23,6 +23,7 @@ A card can be used to display content related to a single subject. The content c
| -------- | ----------- | ---- | ------- |
| actions | The action list, shows at the bottom of the Card. | Array<ReactNode> | - |
| activeTabKey | Current TabPane's key | string | - |
| headStyle | Inline style to apply to the card head | object | - |
| bodyStyle | Inline style to apply to the card content | object | - |
| bordered | Toggles rendering of the border around the card | boolean | `true` |
| cover | Card cover | ReactNode | - |

View File

@ -27,6 +27,7 @@ export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 't
title?: React.ReactNode;
extra?: React.ReactNode;
bordered?: boolean;
headStyle?: React.CSSProperties;
bodyStyle?: React.CSSProperties;
style?: React.CSSProperties;
loading?: boolean;
@ -134,7 +135,7 @@ export default class Card extends React.Component<CardProps, CardState> {
}
render() {
const {
prefixCls = 'ant-card', className, extra, bodyStyle = {}, noHovering, hoverable, title, loading,
prefixCls = 'ant-card', className, extra, headStyle = {}, bodyStyle = {}, noHovering, hoverable, title, loading,
bordered = true, type, cover, actions, tabList, children, activeTabKey, defaultActiveTabKey, ...others
} = this.props;
@ -231,7 +232,7 @@ export default class Card extends React.Component<CardProps, CardState> {
) : null;
if (title || extra || tabs) {
head = (
<div className={`${prefixCls}-head`}>
<div className={`${prefixCls}-head`} style={headStyle}>
<div className={`${prefixCls}-head-wrapper`}>
{title && <div className={`${prefixCls}-head-title`}>{title}</div>}
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}

View File

@ -24,6 +24,7 @@ cols: 1
| --- | --- | --- | --- |
| actions | 卡片操作组,位置在卡片底部 | Array<ReactNode> | - |
| activeTabKey | 当前激活页签的 key | string | - |
| headStyle | 自定义标题区域样式 | object | - |
| bodyStyle | 内容区域自定义样式 | object | - |
| bordered | 是否有边框 | boolean | true |
| cover | 卡片封面 | ReactNode | - |

View File

@ -35,7 +35,7 @@ export interface CheckboxChangeEvent {
target: CheckboxChangeEventTarget;
stopPropagation: () => void;
preventDefault: () => void;
nativeEvent: Event;
nativeEvent: MouseEvent;
}
export default class Checkbox extends React.Component<CheckboxProps, {}> {

View File

@ -358,6 +358,8 @@ class RangePicker extends React.Component<any, RangePickerState> {
tabIndex={props.disabled ? -1 : 0}
onFocus={props.onFocus}
onBlur={props.onBlur}
onMouseEnter={props.onMouseEnter}
onMouseLeave={props.onMouseLeave}
>
<RcDatePicker
{...props}

View File

@ -189,6 +189,8 @@ export default function createPicker(TheCalendar: React.ComponentClass): any {
style={props.style}
onFocus={props.onFocus}
onBlur={props.onBlur}
onMouseEnter={props.onMouseEnter}
onMouseLeave={props.onMouseLeave}
>
<RcDatePicker
{...props}

View File

@ -67,6 +67,20 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
}
}
handleMouseEnter = (e: React.MouseEventHandler<HTMLInputElement>) => {
const { onMouseEnter } = this.props;
if (onMouseEnter) {
onMouseEnter(e);
}
}
handleMouseLeave = (e: React.MouseEventHandler<HTMLInputElement>) => {
const { onMouseLeave } = this.props;
if (onMouseLeave) {
onMouseLeave(e);
}
}
focus() {
this.picker.focus();
}
@ -134,6 +148,8 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, defaultFor
onOpenChange={this.handleOpenChange}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
/>
);
}

View File

@ -527,6 +527,7 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
>
<div
class="ant-select ant-select-enabled"
id="gender"
>
<div
aria-autocomplete="list"
@ -534,6 +535,8 @@ exports[`renders ./components/form/demo/coordinated.md correctly 1`] = `
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
data-__field="[object Object]"
data-__meta="[object Object]"
role="combobox"
tabindex="0"
>
@ -1612,6 +1615,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
>
<div
class="ant-select ant-select-enabled"
id="prefix"
style="width:70px"
>
<div
@ -1620,6 +1624,8 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
data-__field="[object Object]"
data-__meta="[object Object]"
role="combobox"
tabindex="0"
>
@ -1683,6 +1689,7 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
>
<div
class="ant-select-show-search ant-select-auto-complete ant-select ant-select-combobox ant-select-enabled"
id="website"
>
<div
aria-autocomplete="list"
@ -1690,6 +1697,8 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
data-__field="[object Object]"
data-__meta="[object Object]"
role="combobox"
>
<div
@ -2247,6 +2256,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
>
<div
class="ant-select ant-select-enabled"
id="select"
>
<div
aria-autocomplete="list"
@ -2254,6 +2264,8 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
data-__field="[object Object]"
data-__meta="[object Object]"
role="combobox"
tabindex="0"
>
@ -2306,6 +2318,7 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
>
<div
class="ant-select ant-select-enabled"
id="select-multiple"
>
<div
aria-autocomplete="list"
@ -2313,6 +2326,8 @@ exports[`renders ./components/form/demo/validate-other.md correctly 1`] = `
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--multiple"
data-__field="[object Object]"
data-__meta="[object Object]"
role="combobox"
>
<div

View File

@ -386,7 +386,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -395,7 +395,7 @@ exports[`renders ./components/locale-provider/demo/all.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>

View File

@ -5761,7 +5761,7 @@ exports[`Locale Provider should display the text as ar 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -5770,7 +5770,7 @@ exports[`Locale Provider should display the text as ar 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -10358,7 +10358,7 @@ exports[`Locale Provider should display the text as bg 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -10367,7 +10367,7 @@ exports[`Locale Provider should display the text as bg 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -14955,7 +14955,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -14964,7 +14964,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -19552,7 +19552,7 @@ exports[`Locale Provider should display the text as cs 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -19561,7 +19561,7 @@ exports[`Locale Provider should display the text as cs 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -24149,7 +24149,7 @@ exports[`Locale Provider should display the text as de 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -24158,7 +24158,7 @@ exports[`Locale Provider should display the text as de 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -28746,7 +28746,7 @@ exports[`Locale Provider should display the text as el 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -28755,7 +28755,7 @@ exports[`Locale Provider should display the text as el 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -33343,7 +33343,7 @@ exports[`Locale Provider should display the text as en 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -33352,7 +33352,7 @@ exports[`Locale Provider should display the text as en 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -37940,7 +37940,7 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -37949,7 +37949,7 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -42537,7 +42537,7 @@ exports[`Locale Provider should display the text as es 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -42546,7 +42546,7 @@ exports[`Locale Provider should display the text as es 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -47134,7 +47134,7 @@ exports[`Locale Provider should display the text as et 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -47143,7 +47143,7 @@ exports[`Locale Provider should display the text as et 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -51731,7 +51731,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -51740,7 +51740,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -56328,7 +56328,7 @@ exports[`Locale Provider should display the text as fi 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -56337,7 +56337,7 @@ exports[`Locale Provider should display the text as fi 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -60925,7 +60925,7 @@ exports[`Locale Provider should display the text as fr 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -60934,7 +60934,7 @@ exports[`Locale Provider should display the text as fr 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -65522,7 +65522,7 @@ exports[`Locale Provider should display the text as fr 2`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -65531,7 +65531,7 @@ exports[`Locale Provider should display the text as fr 2`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -70119,7 +70119,7 @@ exports[`Locale Provider should display the text as is 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -70128,7 +70128,7 @@ exports[`Locale Provider should display the text as is 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -74716,7 +74716,7 @@ exports[`Locale Provider should display the text as it 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -74725,7 +74725,7 @@ exports[`Locale Provider should display the text as it 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -79313,7 +79313,7 @@ exports[`Locale Provider should display the text as ja 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -79322,7 +79322,7 @@ exports[`Locale Provider should display the text as ja 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -83910,7 +83910,7 @@ exports[`Locale Provider should display the text as ko 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -83919,7 +83919,7 @@ exports[`Locale Provider should display the text as ko 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -88507,7 +88507,7 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -88516,7 +88516,7 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -93104,7 +93104,7 @@ exports[`Locale Provider should display the text as nb 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -93113,7 +93113,7 @@ exports[`Locale Provider should display the text as nb 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -97701,7 +97701,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -97710,7 +97710,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -102298,7 +102298,7 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -102307,7 +102307,7 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -106895,7 +106895,7 @@ exports[`Locale Provider should display the text as pl 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -106904,7 +106904,7 @@ exports[`Locale Provider should display the text as pl 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -111492,7 +111492,7 @@ exports[`Locale Provider should display the text as pt 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -111501,7 +111501,7 @@ exports[`Locale Provider should display the text as pt 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -116089,7 +116089,7 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -116098,7 +116098,7 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -120686,7 +120686,7 @@ exports[`Locale Provider should display the text as ru 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -120695,7 +120695,7 @@ exports[`Locale Provider should display the text as ru 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -125283,7 +125283,7 @@ exports[`Locale Provider should display the text as sk 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -125292,7 +125292,7 @@ exports[`Locale Provider should display the text as sk 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -129880,7 +129880,7 @@ exports[`Locale Provider should display the text as sl 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -129889,7 +129889,7 @@ exports[`Locale Provider should display the text as sl 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -134477,7 +134477,7 @@ exports[`Locale Provider should display the text as sr 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -134486,7 +134486,7 @@ exports[`Locale Provider should display the text as sr 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -139074,7 +139074,7 @@ exports[`Locale Provider should display the text as sv 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -139083,7 +139083,7 @@ exports[`Locale Provider should display the text as sv 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -143671,7 +143671,7 @@ exports[`Locale Provider should display the text as th 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -143680,7 +143680,7 @@ exports[`Locale Provider should display the text as th 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -148268,7 +148268,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -148277,7 +148277,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -152865,7 +152865,7 @@ exports[`Locale Provider should display the text as uk 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -152874,7 +152874,7 @@ exports[`Locale Provider should display the text as uk 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -157462,7 +157462,7 @@ exports[`Locale Provider should display the text as vi 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -157471,7 +157471,7 @@ exports[`Locale Provider should display the text as vi 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -162059,7 +162059,7 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -162068,7 +162068,7 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -166656,7 +166656,7 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -166665,7 +166665,7 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>

View File

@ -29,6 +29,14 @@ exports[`renders ./components/popconfirm/demo/dynamic-trigger.md correctly 1`] =
</div>
`;
exports[`renders ./components/popconfirm/demo/icon.md correctly 1`] = `
<a
href="#"
>
Delete
</a>
`;
exports[`renders ./components/popconfirm/demo/locale.md correctly 1`] = `
<a
href="#"

View File

@ -82,4 +82,16 @@ describe('Popconfirm', () => {
expect(cancel).toHaveBeenCalled();
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
});
it('should support customize icon', () => {
const wrapper = mount(
<Popconfirm title="code" icon={<span className="customize-icon">custom-icon</span>}>
<span>show me your code</span>
</Popconfirm>
);
const triggerNode = wrapper.find('span').at(0);
triggerNode.simulate('click');
expect(wrapper.find('.customize-icon').length).toBe(1);
});
});

View File

@ -0,0 +1,24 @@
---
order: 4
title:
zh-CN: 自定义 Icon 图标
en-US: Customize icon
---
## zh-CN
使用 `icon` 自定义提示 `icon`
## en-US
Set `icon` props to customize the icon.
````jsx
import { Popconfirm, Icon } from 'antd';
ReactDOM.render(
<Popconfirm title="Are you sure" icon={<Icon type="question-circle-o" style={{ color: 'red' }} />}>
<a href="#">Delete</a>
</Popconfirm>,
mountNode);
````

View File

@ -22,6 +22,7 @@ The difference with the `confirm` modal dialog is that it's more lightweight tha
| title | title of the confirmation box | string\|ReactNode | - |
| onCancel | callback of cancel | function(e) | - |
| onConfirm | callback of confirmation | function(e) | - |
| icon | customize icon of confirmation | ReactNode | &lt;Icon type="exclamation-circle" /&gt; |
Consult [Tooltip's documentation](https://ant.design/components/tooltip/#API) to find more APIs.

View File

@ -13,6 +13,7 @@ export interface PopconfirmProps extends AbstractTooltipProps {
okText?: React.ReactNode;
okType?: ButtonType;
cancelText?: React.ReactNode;
icon?: React.ReactNode;
}
export interface PopconfirmState {
@ -31,6 +32,7 @@ export default class Popconfirm extends React.Component<PopconfirmProps, Popconf
placement: 'top',
trigger: 'click',
okType: 'primary',
icon: <Icon type="exclamation-circle" />,
};
private tooltip: any;
@ -92,12 +94,12 @@ export default class Popconfirm extends React.Component<PopconfirmProps, Popconf
}
renderOverlay = (popconfirmLocale: PopconfirmLocale) => {
const { prefixCls, title, cancelText, okText, okType } = this.props;
const { prefixCls, title, cancelText, okText, okType, icon } = this.props;
return (
<div>
<div className={`${prefixCls}-inner-content`}>
<div className={`${prefixCls}-message`}>
<Icon type="exclamation-circle" />
{icon}
<div className={`${prefixCls}-message-title`}>{title}</div>
</div>
<div className={`${prefixCls}-buttons`}>

View File

@ -23,6 +23,7 @@ title: Popconfirm
| title | 确认框的描述 | string\|ReactNode | 无 |
| onCancel | 点击取消的回调 | function(e) | 无 |
| onConfirm | 点击确认的回调 | function(e) | 无 |
| icon | 自定义弹出气泡 Icon 图标 | ReactNode | &lt;Icon type="exclamation-circle" /&gt; |
更多属性请参考 [Tooltip](/components/tooltip/#API)。

View File

@ -43,6 +43,17 @@ exports[`renders ./components/popover/demo/control.md correctly 1`] = `
</button>
`;
exports[`renders ./components/popover/demo/hover-with-click.md correctly 1`] = `
<button
class="ant-btn"
type="button"
>
<span>
Hover and click / 悬停并单击
</span>
</button>
`;
exports[`renders ./components/popover/demo/placement.md correctly 1`] = `
<div
class="demo"

View File

@ -0,0 +1,86 @@
---
order: 5
title:
zh-CN: 悬停点击弹出窗口
en-US: Hover with click popover
---
## zh-CN
以下示例显示如何创建可悬停和单击的弹出窗口。
## en-US
The following example shows how to create a popover which can be hovered and clicked.
````jsx
import { Popover, Button } from 'antd';
class App extends React.Component {
state = {
clicked: false,
hovered: false,
};
hide = () => {
this.setState({
clicked: false,
hovered: false,
});
}
handleHoverChange = (visible) => {
this.setState({
hovered: visible,
clicked: false,
});
}
handleClickChange = (visible) => {
this.setState({
clicked: visible,
hovered: false,
});
}
render() {
const hoverContent = (
<div>
This is hover content.
</div>
);
const clickContent = (
<div>
This is click content.
</div>
);
return (
<Popover
style={{ width: 500 }}
content={hoverContent}
title="Hover title"
trigger="hover"
visible={this.state.hovered}
onVisibleChange={this.handleHoverChange}
>
<Popover
content={(
<div>
{clickContent}
<a onClick={this.hide}>Close</a>
</div>
)}
title="Click title"
trigger="click"
visible={this.state.clicked}
onVisibleChange={this.handleClickChange}
>
<Button>Hover and click / 悬停并单击</Button>
</Popover>
</Popover>
);
}
}
ReactDOM.render(<App />, mountNode);
````

View File

@ -40,5 +40,5 @@ export interface RadioChangeEvent {
target: RadioChangeEventTarget;
stopPropagation: () => void;
preventDefault: () => void;
nativeEvent: Event;
nativeEvent: MouseEvent;
}

View File

@ -124,6 +124,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
// 减少状态
filters: this.getFiltersFromColumns(),
pagination: this.getDefaultPagination(props),
pivot: undefined,
};
this.CheckboxPropsCache = {};
@ -250,6 +251,11 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
}
if (selectWay === 'onSelect' && rowSelection.onSelect) {
rowSelection.onSelect(record!, checked!, selectedRows, nativeEvent!);
} else if (selectWay === 'onSelectMulti' && rowSelection.onSelectMulti) {
const changeRows = data.filter(
(row, i) => changeRowKeys!.indexOf(this.getRecordKey(row, i)) >= 0,
);
rowSelection.onSelectMulti(checked!, selectedRows, changeRows);
} else if (selectWay === 'onSelectAll' && rowSelection.onSelectAll) {
const changeRows = data.filter(
(row, i) => changeRowKeys!.indexOf(this.getRecordKey(row, i)) >= 0,
@ -456,11 +462,56 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
const defaultSelection = this.store.getState().selectionDirty ? [] : this.getDefaultSelection();
let selectedRowKeys = this.store.getState().selectedRowKeys.concat(defaultSelection);
let key = this.getRecordKey(record, rowIndex);
const pivot = this.state.pivot;
const rows = this.getFlatCurrentPageData();
let realIndex = rowIndex;
if (this.props.expandedRowRender) {
realIndex = rows.findIndex(row => this.getRecordKey(row, rowIndex) === key);
}
if (nativeEvent.shiftKey && pivot !== undefined && realIndex !== pivot) {
const changeRowKeys = [];
const direction = Math.sign(pivot - realIndex);
const dist = Math.abs(pivot - realIndex);
let step = 0;
while (step <= dist) {
const i = realIndex + (step * direction);
step += 1;
const row = rows[i];
const rowKey = this.getRecordKey(row, i);
const checkboxProps = this.getCheckboxPropsByItem(row, i);
if (!checkboxProps.disabled) {
if (selectedRowKeys.includes(rowKey)) {
if (!checked) {
selectedRowKeys = selectedRowKeys.filter((j: string) => rowKey !== j);
changeRowKeys.push(rowKey);
}
} else if (checked) {
selectedRowKeys.push(rowKey);
changeRowKeys.push(rowKey);
}
}
}
this.setState({ pivot: realIndex });
this.store.setState({
selectionDirty: true,
});
this.setSelectedRowKeys(selectedRowKeys, {
selectWay: 'onSelectMulti',
record,
checked,
changeRowKeys,
nativeEvent,
});
} else {
if (checked) {
selectedRowKeys.push(this.getRecordKey(record, rowIndex));
selectedRowKeys.push(this.getRecordKey(record, realIndex));
} else {
selectedRowKeys = selectedRowKeys.filter((i: string) => key !== i);
}
this.setState({ pivot: realIndex });
this.store.setState({
selectionDirty: true,
});
@ -472,6 +523,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
nativeEvent,
});
}
}
handleRadioSelect = (record: T, rowIndex: number, e: RadioChangeEvent) => {
const checked = e.target.checked;
@ -599,11 +651,11 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
renderSelectionBox = (type: RowSelectionType | undefined) => {
return (_: any, record: T, index: number) => {
let rowIndex = this.getRecordKey(record, index); // 从 1 开始
const rowKey = this.getRecordKey(record, index);
const props = this.getCheckboxPropsByItem(record, index);
const handleChange = (e: RadioChangeEvent | CheckboxChangeEvent) => {
type === 'radio' ? this.handleRadioSelect(record, rowIndex, e) :
this.handleSelect(record, rowIndex, e);
type === 'radio' ? this.handleRadioSelect(record, index, e) :
this.handleSelect(record, index, e);
};
return (
@ -611,7 +663,7 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
<SelectionBox
type={type}
store={this.store}
rowIndex={rowIndex}
rowIndex={rowKey}
onChange={handleChange}
defaultSelection={this.getDefaultSelection()}
{...props}
@ -656,10 +708,11 @@ export default class Table<T> extends React.Component<TableProps<T>, TableState<
className: selectionColumnClass,
fixed: rowSelection.fixed,
width: rowSelection.columnWidth,
title: rowSelection.columnTitle,
};
if (rowSelection.type !== 'radio') {
const checkboxAllDisabled = data.every((item, index) => this.getCheckboxPropsByItem(item, index).disabled);
selectionColumn.title = (
selectionColumn.title = selectionColumn.title || (
<SelectionCheckboxAll
store={this.store}
locale={locale}

View File

@ -162,6 +162,36 @@ describe('Table.rowSelection', () => {
expect(handleSelect.mock.calls[0][3].type).toBe('change');
});
it('fires selectMulti event', () => {
const handleSelectMulti = jest.fn();
const handleSelect = jest.fn();
const rowSelection = {
onSelect: handleSelect,
onSelectMulti: handleSelectMulti,
};
const wrapper = mount(createTable({ rowSelection }));
wrapper.find('input').at(1).simulate('change', {
target: { checked: true },
nativeEvent: { shiftKey: true },
});
expect(handleSelect).toBeCalled();
wrapper.find('input').at(3).simulate('change', {
target: { checked: true },
nativeEvent: { shiftKey: true },
});
expect(handleSelectMulti).toBeCalledWith(true,
[data[0], data[1], data[2]], [data[1], data[2]]);
wrapper.find('input').at(1).simulate('change', {
target: { checked: false },
nativeEvent: { shiftKey: true },
});
expect(handleSelectMulti).toBeCalledWith(false,
[], [data[0], data[1], data[2]]);
});
it('fires selectAll event', () => {
const handleSelectAll = jest.fn();
const rowSelection = {
@ -391,4 +421,25 @@ describe('Table.rowSelection', () => {
expect(checkbox.props().indeterminate).toBe(false);
});
});
// https://github.com/ant-design/ant-design/issues/11042
it('add columnTitle for rowSelection', () => {
const wrapper = mount(
<Table
columns={columns}
dataSource={data}
rowSelection={{
columnTitle: '多选',
}}
/>
);
expect(wrapper.find('thead tr span').at(0).text()).toBe('多选');
wrapper.setProps({
rowSelection: {
type: 'radio',
columnTitle: '单选',
},
});
expect(wrapper.find('thead tr span').at(0).text()).toBe('单选');
});
});

View File

@ -154,6 +154,7 @@ Properties for row selection.
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| columnWidth | Set the width of the selection column | string\|number | - |
| columnTitle | Set the title of the selection column | string\|React.ReactNode | - |
| fixed | Fixed selection column on the left | boolean | - |
| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - |
| hideDefaultSelections | Remove the default `Select All` and `Select Invert` selections | boolean | `false` |
@ -162,6 +163,7 @@ Properties for row selection.
| type | `checkbox` or `radio` | `checkbox` \| `radio` | `checkbox` |
| onChange | Callback executed when selected rows change | Function(selectedRowKeys, selectedRows) | - |
| onSelect | Callback executed when select/deselect one row | Function(record, selected, selectedRows, nativeEvent) | - |
| onSelectMulti | Callback executed when multiple rows are selected/unselected | Function(selected, selectedRows, changeRows) | - |
| onSelectAll | Callback executed when select/deselect all rows | Function(selected, selectedRows, changeRows) | - |
| onSelectInvert | Callback executed when row selection is inverted | Function(selectedRows) | - |

View File

@ -154,6 +154,7 @@ const columns = [{
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| columnWidth | 自定义列表选择框宽度 | string\|number | - |
| columnTitle | 自定义列表选择框标题 | string\|React.ReactNode | - |
| fixed | 把选择框列固定在左边 | boolean | - |
| getCheckboxProps | 选择框的默认属性配置 | Function(record) | - |
| hideDefaultSelections | 去掉『全选』『反选』两个默认选项 | boolean | false |

View File

@ -62,7 +62,7 @@ export interface TableLocale {
export type RowSelectionType = 'checkbox' | 'radio';
export type SelectionSelectFn<T> = (record: T, selected: boolean, selectedRows: Object[], nativeEvent: Event) => any;
export type TableSelectWay = 'onSelect' | 'onSelectAll' | 'onSelectInvert';
export type TableSelectWay = 'onSelect' | 'onSelectMulti' | 'onSelectAll' | 'onSelectInvert';
export interface TableRowSelection<T> {
type?: RowSelectionType;
@ -70,12 +70,15 @@ export interface TableRowSelection<T> {
onChange?: (selectedRowKeys: string[] | number[], selectedRows: Object[]) => void;
getCheckboxProps?: (record: T) => Object;
onSelect?: SelectionSelectFn<T>;
onSelectMulti?: (selected: boolean, selectedRows: Object[], changeRows: Object[]) => void;
onSelectAll?: (selected: boolean, selectedRows: Object[], changeRows: Object[]) => void;
onSelectInvert?: (selectedRows: Object[]) => void;
selections?: SelectionItem[] | boolean;
hideDefaultSelections?: boolean;
fixed?: boolean;
columnWidth?: string | number;
selectWay?: TableSelectWay;
columnTitle?: string | React.ReactNode;
}
export type SortOrder = 'descend' | 'ascend';
export interface SorterResult<T> {
@ -138,6 +141,7 @@ export interface TableState<T> {
filters: TableStateFilters;
sortColumn: ColumnProps<T> | null;
sortOrder?: SortOrder;
pivot?: number;
}
export type SelectionItemSelectFn = (key: string[]) => any;

View File

@ -37,9 +37,6 @@ exports[`renders ./components/tabs/demo/basic.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -64,6 +61,9 @@ exports[`renders ./components/tabs/demo/basic.md correctly 1`] = `
>
Tab 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -131,9 +131,6 @@ exports[`renders ./components/tabs/demo/card.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -158,6 +155,9 @@ exports[`renders ./components/tabs/demo/card.md correctly 1`] = `
>
Tab 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -227,9 +227,6 @@ exports[`renders ./components/tabs/demo/card-top.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -254,6 +251,9 @@ exports[`renders ./components/tabs/demo/card-top.md correctly 1`] = `
>
Tab Title 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -342,9 +342,6 @@ exports[`renders ./components/tabs/demo/custom-add-trigger.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -371,6 +368,9 @@ exports[`renders ./components/tabs/demo/custom-add-trigger.md correctly 1`] = `
/>
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -433,9 +433,6 @@ exports[`renders ./components/tabs/demo/disabled.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -460,6 +457,9 @@ exports[`renders ./components/tabs/demo/disabled.md correctly 1`] = `
>
Tab 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -537,9 +537,6 @@ exports[`renders ./components/tabs/demo/editable-card.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -578,6 +575,9 @@ exports[`renders ./components/tabs/demo/editable-card.md correctly 1`] = `
Tab 3
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -657,9 +657,6 @@ exports[`renders ./components/tabs/demo/extra.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -684,6 +681,9 @@ exports[`renders ./components/tabs/demo/extra.md correctly 1`] = `
>
Tab 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -751,9 +751,6 @@ exports[`renders ./components/tabs/demo/icon.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="false"
@ -780,6 +777,9 @@ exports[`renders ./components/tabs/demo/icon.md correctly 1`] = `
Tab 2
</span>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -880,9 +880,6 @@ exports[`renders ./components/tabs/demo/position.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -907,6 +904,9 @@ exports[`renders ./components/tabs/demo/position.md correctly 1`] = `
>
Tab 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -1039,9 +1039,6 @@ exports[`renders ./components/tabs/demo/size.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -1066,6 +1063,9 @@ exports[`renders ./components/tabs/demo/size.md correctly 1`] = `
>
Tab 3
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>
@ -1180,9 +1180,6 @@ exports[`renders ./components/tabs/demo/slide.md correctly 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -1271,6 +1268,9 @@ exports[`renders ./components/tabs/demo/slide.md correctly 1`] = `
>
Tab 11
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>

View File

@ -37,9 +37,6 @@ exports[`Tabs tabPosition remove card 1`] = `
<div
class="ant-tabs-nav ant-tabs-nav-animated"
>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
<div
aria-disabled="false"
aria-selected="true"
@ -48,6 +45,9 @@ exports[`Tabs tabPosition remove card 1`] = `
>
foo
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
</div>

View File

@ -2,6 +2,9 @@ import React from 'react';
import { mount } from 'enzyme';
import Tooltip from '..';
import Button from '../../button';
import DatePicker from '../../date-picker';
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
describe('Tooltip', () => {
it('check `onVisibleChange` arguments', () => {
@ -174,4 +177,29 @@ describe('Tooltip', () => {
jest.dontMock('rc-trigger', suit);
});
it('should works for date picker', async () => {
const onVisibleChange = jest.fn();
const wrapper = mount(
<Tooltip
title="date picker"
onVisibleChange={onVisibleChange}
>
<DatePicker />
</Tooltip>
);
expect(wrapper.find('span.ant-calendar-picker')).toHaveLength(1);
const picker = wrapper.find('span.ant-calendar-picker').at(0);
picker.simulate('mouseenter');
await delay(100);
expect(onVisibleChange).toBeCalledWith(true);
expect(wrapper.instance().tooltip.props.visible).toBe(true);
picker.simulate('mouseleave');
await delay(100);
expect(onVisibleChange).toBeCalledWith(false);
expect(wrapper.instance().tooltip.props.visible).toBe(false);
});
});

View File

@ -91,10 +91,10 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
<span>
to left
to right
</span>
</button>
<button
@ -103,10 +103,10 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
<span>
to right
to left
</span>
</button>
</div>
@ -308,7 +308,7 @@ exports[`renders ./components/transfer/demo/basic.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -317,7 +317,7 @@ exports[`renders ./components/transfer/demo/basic.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -455,7 +455,7 @@ exports[`renders ./components/transfer/demo/custom-item.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -464,7 +464,7 @@ exports[`renders ./components/transfer/demo/custom-item.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -575,7 +575,7 @@ exports[`renders ./components/transfer/demo/large-data.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -584,7 +584,7 @@ exports[`renders ./components/transfer/demo/large-data.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>
@ -713,7 +713,7 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -722,7 +722,7 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</div>

View File

@ -96,6 +96,14 @@ 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=""
@ -105,14 +113,6 @@ exports[`Transfer should render correctly 1`] = `
class="anticon anticon-left"
/>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<i
class="anticon anticon-right"
/>
</button>
</div>
<div
class="ant-transfer-list"
@ -265,7 +265,7 @@ exports[`Transfer should show sorted targetkey 1`] = `
type="button"
>
<i
class="anticon anticon-left"
class="anticon anticon-right"
/>
</button>
<button
@ -274,7 +274,7 @@ exports[`Transfer should show sorted targetkey 1`] = `
type="button"
>
<i
class="anticon anticon-right"
class="anticon anticon-left"
/>
</button>
</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

@ -69,12 +69,12 @@
"rc-pagination": "~1.16.1",
"rc-progress": "~2.2.2",
"rc-rate": "~2.4.0",
"rc-select": "~8.0.7",
"rc-select": "~8.1.1",
"rc-slider": "~8.6.0",
"rc-steps": "~3.1.0",
"rc-switch": "~1.6.0",
"rc-table": "~6.2.2",
"rc-tabs": "~9.2.0",
"rc-tabs": "~9.3.2",
"rc-time-picker": "~3.3.0",
"rc-tooltip": "~3.7.0",
"rc-tree": "~1.13.0",