mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-28 05:05:48 +08:00
Merge pull request #19049 from ant-design/master
chore: Merge master into feature
This commit is contained in:
commit
dc0dfea201
@ -433,6 +433,7 @@ exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
U
|
U
|
||||||
</span>
|
</span>
|
||||||
@ -486,6 +487,7 @@ exports[`renders ./components/avatar/demo/toggle-debug.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
Avatar
|
Avatar
|
||||||
</span>
|
</span>
|
||||||
@ -507,6 +509,7 @@ exports[`renders ./components/avatar/demo/toggle-debug.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
Avatar
|
Avatar
|
||||||
</span>
|
</span>
|
||||||
@ -554,6 +557,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
U
|
U
|
||||||
</span>
|
</span>
|
||||||
@ -563,6 +567,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
USER
|
USER
|
||||||
</span>
|
</span>
|
||||||
@ -580,6 +585,7 @@ exports[`renders ./components/avatar/demo/type.md correctly 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
>
|
>
|
||||||
U
|
U
|
||||||
</span>
|
</span>
|
||||||
|
@ -29,6 +29,7 @@ export interface AvatarProps {
|
|||||||
|
|
||||||
export interface AvatarState {
|
export interface AvatarState {
|
||||||
scale: number;
|
scale: number;
|
||||||
|
mounted: boolean;
|
||||||
isImgExist: boolean;
|
isImgExist: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
|||||||
|
|
||||||
state = {
|
state = {
|
||||||
scale: 1,
|
scale: 1,
|
||||||
|
mounted: false,
|
||||||
isImgExist: true,
|
isImgExist: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,6 +55,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setScale();
|
this.setScale();
|
||||||
|
this.setState({ mounted: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps: AvatarProps) {
|
componentDidUpdate(prevProps: AvatarProps) {
|
||||||
@ -105,7 +108,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
|||||||
...others
|
...others
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { isImgExist, scale } = this.state;
|
const { isImgExist, scale, mounted } = this.state;
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('avatar', customizePrefixCls);
|
const prefixCls = getPrefixCls('avatar', customizePrefixCls);
|
||||||
|
|
||||||
@ -144,6 +147,7 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
|||||||
WebkitTransform: transformString,
|
WebkitTransform: transformString,
|
||||||
transform: transformString,
|
transform: transformString,
|
||||||
};
|
};
|
||||||
|
|
||||||
const sizeChildrenStyle: React.CSSProperties =
|
const sizeChildrenStyle: React.CSSProperties =
|
||||||
typeof size === 'number'
|
typeof size === 'number'
|
||||||
? {
|
? {
|
||||||
@ -160,9 +164,15 @@ export default class Avatar extends React.Component<AvatarProps, AvatarState> {
|
|||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
const childrenStyle: React.CSSProperties = {};
|
||||||
|
if (!mounted) {
|
||||||
|
childrenStyle.opacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
children = (
|
children = (
|
||||||
<span
|
<span
|
||||||
className={`${prefixCls}-string`}
|
className={`${prefixCls}-string`}
|
||||||
|
style={{ opacity: 0 }}
|
||||||
ref={(node: HTMLElement) => (this.avatarChildren = node)}
|
ref={(node: HTMLElement) => (this.avatarChildren = node)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -130,6 +130,11 @@
|
|||||||
.button-size(@btn-height-lg; @btn-padding-lg; @btn-font-size-lg; 0);
|
.button-size(@btn-height-lg; @btn-padding-lg; @btn-font-size-lg; 0);
|
||||||
line-height: @btn-height-lg - 2px;
|
line-height: @btn-height-lg - 2px;
|
||||||
}
|
}
|
||||||
|
&-lg > .@{btnClassName}.@{btnClassName}-icon-only {
|
||||||
|
.square(@btn-height-lg);
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
&-sm > .@{btnClassName},
|
&-sm > .@{btnClassName},
|
||||||
&-sm > span > .@{btnClassName} {
|
&-sm > span > .@{btnClassName} {
|
||||||
.button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; 0);
|
.button-size(@btn-height-sm; @btn-padding-sm; @font-size-base; 0);
|
||||||
@ -138,6 +143,11 @@
|
|||||||
font-size: @font-size-base;
|
font-size: @font-size-base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&-sm > .@{btnClassName}.@{btnClassName}-icon-only {
|
||||||
|
.square(@btn-height-sm);
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Base styles of buttons
|
// Base styles of buttons
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import Collapse from '..';
|
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
|
|
||||||
describe('Collapse', () => {
|
describe('Collapse', () => {
|
||||||
|
// Fix css-animation deps on these
|
||||||
|
// https://github.com/yiminghe/css-animation/blob/a5986d73fd7dfce75665337f39b91483d63a4c8c/src/Event.js#L44
|
||||||
|
window.AnimationEvent = window.AnimationEvent || (() => {});
|
||||||
|
window.TransitionEvent = window.TransitionEvent || (() => {});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
// restore it
|
||||||
|
delete window.AnimationEvent;
|
||||||
|
delete window.TransitionEvent;
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line global-require
|
||||||
|
const Collapse = require('..').default;
|
||||||
mountTest(Collapse);
|
mountTest(Collapse);
|
||||||
|
|
||||||
it('should support remove expandIcon', () => {
|
it('should support remove expandIcon', () => {
|
||||||
@ -24,4 +36,24 @@ describe('Collapse', () => {
|
|||||||
);
|
);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('could be expand and collapse', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
const wrapper = mount(
|
||||||
|
<Collapse>
|
||||||
|
<Collapse.Panel header="This is panel header 1" key="1">
|
||||||
|
content
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>,
|
||||||
|
);
|
||||||
|
expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(false);
|
||||||
|
wrapper
|
||||||
|
.find('.ant-collapse-header')
|
||||||
|
.at(0)
|
||||||
|
.simulate('click');
|
||||||
|
expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(true);
|
||||||
|
jest.runAllTimers();
|
||||||
|
expect(wrapper.find('.ant-collapse-item').hasClass('ant-collapse-item-active')).toBe(true);
|
||||||
|
jest.useRealTimers();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -360,6 +360,7 @@ exports[`ConfigProvider components Avatar configProvider 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="config-avatar-string"
|
class="config-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
@ -370,6 +371,7 @@ exports[`ConfigProvider components Avatar normal 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-avatar-string"
|
class="ant-avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
@ -380,6 +382,7 @@ exports[`ConfigProvider components Avatar prefixCls 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="prefix-Avatar-string"
|
class="prefix-Avatar-string"
|
||||||
|
style="opacity:0"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
|
@ -47,7 +47,7 @@ class WeekPicker extends React.Component<any, WeekPickerState> {
|
|||||||
const value = props.value || props.defaultValue;
|
const value = props.value || props.defaultValue;
|
||||||
if (value && !interopDefault(moment).isMoment(value)) {
|
if (value && !interopDefault(moment).isMoment(value)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'The value/defaultValue of DatePicker or MonthPicker must be ' +
|
'The value/defaultValue of WeekPicker must be ' +
|
||||||
'a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value',
|
'a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount, render } from 'enzyme';
|
import { mount, render } from 'enzyme';
|
||||||
|
import moment from 'moment';
|
||||||
import { setMockDate, resetMockDate } from '../../../tests/utils';
|
import { setMockDate, resetMockDate } from '../../../tests/utils';
|
||||||
import DatePicker from '..';
|
import DatePicker from '..';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
@ -71,4 +72,16 @@ describe('WeekPicker', () => {
|
|||||||
),
|
),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support allowClear', () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
const wrapper = mount(
|
||||||
|
<WeekPicker defaultValue={moment()} onChange={onChange} />,
|
||||||
|
);
|
||||||
|
wrapper
|
||||||
|
.find('.ant-calendar-picker-clear')
|
||||||
|
.hostNodes()
|
||||||
|
.simulate('click');
|
||||||
|
expect(onChange).toHaveBeenCalledWith(null, '');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
52
components/date-picker/__tests__/invalid.test.js
Normal file
52
components/date-picker/__tests__/invalid.test.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
import DatePicker from '..';
|
||||||
|
|
||||||
|
const { MonthPicker, WeekPicker, RangePicker } = DatePicker;
|
||||||
|
|
||||||
|
describe('invalid value or defaultValue', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('DatePicker should throw error when value or defaultValue is not moment object', () => {
|
||||||
|
expect(() => {
|
||||||
|
mount(<DatePicker value={{}} />);
|
||||||
|
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||||
|
expect(() => {
|
||||||
|
mount(<DatePicker defaultValue={{}} />);
|
||||||
|
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('WeekPicker should throw error when value or defaultValue is not moment object', () => {
|
||||||
|
expect(() => {
|
||||||
|
mount(<WeekPicker value={{}} />);
|
||||||
|
}).toThrow('The value/defaultValue of WeekPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||||
|
expect(() => {
|
||||||
|
mount(<WeekPicker defaultValue={{}} />);
|
||||||
|
}).toThrow('The value/defaultValue of WeekPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('RangePicker should throw error when value or defaultValue is not moment object', () => {
|
||||||
|
expect(() => {
|
||||||
|
mount(<RangePicker value={[{}, {}]} />);
|
||||||
|
}).toThrow('The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||||
|
expect(() => {
|
||||||
|
mount(<RangePicker defaultValue={[{}, {}]} />);
|
||||||
|
}).toThrow('The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, see: https://u.ant.design/date-picker-value')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('MonthPicker should throw error when value or defaultValue is not moment object', () => {
|
||||||
|
expect(() => {
|
||||||
|
mount(<MonthPicker value={{}} />);
|
||||||
|
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value');
|
||||||
|
expect(() => {
|
||||||
|
mount(<MonthPicker defaultValue={{}} />);
|
||||||
|
}).toThrow('The value/defaultValue of DatePicker or MonthPicker must be a moment object after `antd@2.0`, see: https://u.ant.design/date-picker-value')
|
||||||
|
});
|
||||||
|
});
|
@ -290,6 +290,7 @@ class Input extends React.Component<InputProps, any> {
|
|||||||
// Input elements must be either controlled or uncontrolled,
|
// Input elements must be either controlled or uncontrolled,
|
||||||
// specify either the value prop, or the defaultValue prop, but not both.
|
// specify either the value prop, or the defaultValue prop, but not both.
|
||||||
'defaultValue',
|
'defaultValue',
|
||||||
|
'size',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return this.renderLabeledIcon(
|
return this.renderLabeledIcon(
|
||||||
|
@ -114,11 +114,14 @@ export default class Search extends React.Component<SearchProps, any> {
|
|||||||
|
|
||||||
let button: React.ReactNode;
|
let button: React.ReactNode;
|
||||||
const enterButtonAsElement = enterButton as React.ReactElement<any>;
|
const enterButtonAsElement = enterButton as React.ReactElement<any>;
|
||||||
if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
|
const isAntdButton =
|
||||||
|
enterButtonAsElement.type &&
|
||||||
|
(enterButtonAsElement.type as typeof Button).__ANT_BUTTON === true;
|
||||||
|
if (isAntdButton || enterButtonAsElement.type === 'button') {
|
||||||
button = React.cloneElement(enterButtonAsElement, {
|
button = React.cloneElement(enterButtonAsElement, {
|
||||||
onClick: this.onSearch,
|
onClick: this.onSearch,
|
||||||
key: 'enterButton',
|
key: 'enterButton',
|
||||||
...(enterButtonAsElement.type === Button
|
...(isAntdButton
|
||||||
? {
|
? {
|
||||||
className: btnClassName,
|
className: btnClassName,
|
||||||
size,
|
size,
|
||||||
|
@ -201,7 +201,7 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/input/demo/algin.md correctly 1`] = `
|
exports[`renders ./components/input/demo/align.md correctly 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="ant-mentions"
|
class="ant-mentions"
|
||||||
|
@ -4,7 +4,6 @@ import Select from '..';
|
|||||||
import Icon from '../../icon';
|
import Icon from '../../icon';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import { resetWarned } from '../../_util/warning';
|
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
@ -133,16 +132,4 @@ describe('Select', () => {
|
|||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('warning if user use `inputValue`', () => {
|
|
||||||
resetWarned();
|
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
||||||
|
|
||||||
mount(<Select inputValue="" />);
|
|
||||||
expect(errorSpy).toHaveBeenLastCalledWith(
|
|
||||||
'Warning: [antd: Select] `inputValue` is deprecated. Please use `searchValue` instead.',
|
|
||||||
);
|
|
||||||
|
|
||||||
errorSpy.mockRestore();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,6 @@ Select component to select value from options.
|
|||||||
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | value | |
|
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | value | |
|
||||||
| optionLabelProp | Which prop value of option will render as content of select. [Example](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | `value` for `combobox`, `children` for other modes | |
|
| optionLabelProp | Which prop value of option will render as content of select. [Example](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | `value` for `combobox`, `children` for other modes | |
|
||||||
| placeholder | Placeholder of select | string\|ReactNode | - | |
|
| placeholder | Placeholder of select | string\|ReactNode | - | |
|
||||||
| searchValue | Search input value | string | - | 3.23.2 |
|
|
||||||
| showArrow | Whether to show the drop-down arrow | boolean | true | 3.2.1 |
|
| showArrow | Whether to show the drop-down arrow | boolean | true | 3.2.1 |
|
||||||
| showSearch | Whether show search input in single mode. | boolean | false | |
|
| showSearch | Whether show search input in single mode. | boolean | false | |
|
||||||
| size | Size of Select input. `default` `large` `small` | string | default | |
|
| size | Size of Select input. `default` `large` `small` | string | default | |
|
||||||
|
@ -53,9 +53,6 @@ export type SelectValue = string | string[] | number | number[] | LabeledValue |
|
|||||||
|
|
||||||
export interface SelectProps<T = SelectValue> extends AbstractSelectProps {
|
export interface SelectProps<T = SelectValue> extends AbstractSelectProps {
|
||||||
value?: T;
|
value?: T;
|
||||||
/** @deprecated Use `searchValue` instead. */
|
|
||||||
inputValue?: string;
|
|
||||||
searchValue?: string;
|
|
||||||
defaultValue?: T;
|
defaultValue?: T;
|
||||||
mode?: 'default' | 'multiple' | 'tags' | 'combobox' | string;
|
mode?: 'default' | 'multiple' | 'tags' | 'combobox' | string;
|
||||||
optionLabelProp?: string;
|
optionLabelProp?: string;
|
||||||
@ -139,12 +136,6 @@ export default class Select<T = SelectValue> extends React.Component<SelectProps
|
|||||||
'it will be removed in next major version, ' +
|
'it will be removed in next major version, ' +
|
||||||
'please use AutoComplete instead',
|
'please use AutoComplete instead',
|
||||||
);
|
);
|
||||||
|
|
||||||
warning(
|
|
||||||
!('inputValue' in props),
|
|
||||||
'Select',
|
|
||||||
'`inputValue` is deprecated. Please use `searchValue` instead.',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotFoundContent(renderEmpty: RenderEmptyHandler) {
|
getNotFoundContent(renderEmpty: RenderEmptyHandler) {
|
||||||
@ -207,8 +198,6 @@ export default class Select<T = SelectValue> extends React.Component<SelectProps
|
|||||||
clearIcon,
|
clearIcon,
|
||||||
menuItemSelectedIcon,
|
menuItemSelectedIcon,
|
||||||
showArrow,
|
showArrow,
|
||||||
inputValue,
|
|
||||||
searchValue,
|
|
||||||
...restProps
|
...restProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const rest = omit(restProps, ['inputIcon']);
|
const rest = omit(restProps, ['inputIcon']);
|
||||||
@ -270,7 +259,6 @@ export default class Select<T = SelectValue> extends React.Component<SelectProps
|
|||||||
showArrow={showArrow}
|
showArrow={showArrow}
|
||||||
{...rest}
|
{...rest}
|
||||||
{...modeConfig}
|
{...modeConfig}
|
||||||
inputValue={searchValue || inputValue}
|
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
className={cls}
|
className={cls}
|
||||||
optionLabelProp={optionLabelProp || 'children'}
|
optionLabelProp={optionLabelProp || 'children'}
|
||||||
|
@ -47,7 +47,6 @@ title: Select
|
|||||||
| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索。[示例](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | value | |
|
| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索。[示例](https://codesandbox.io/s/antd-reproduction-template-tk678) | string | value | |
|
||||||
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` (combobox 模式下为 `value`) | |
|
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` (combobox 模式下为 `value`) | |
|
||||||
| placeholder | 选择框默认文字 | string | - | |
|
| placeholder | 选择框默认文字 | string | - | |
|
||||||
| searchValue | 搜索框文本 | string | - | 3.23.2 |
|
|
||||||
| showArrow | 是否显示下拉小箭头 | boolean | true | 3.2.1 |
|
| showArrow | 是否显示下拉小箭头 | boolean | true | 3.2.1 |
|
||||||
| showSearch | 使单选模式可搜索 | boolean | false | |
|
| showSearch | 使单选模式可搜索 | boolean | false | |
|
||||||
| size | 选择框大小,可选 `large` `small` | string | default | |
|
| size | 选择框大小,可选 `large` `small` | string | default | |
|
||||||
|
@ -428,3 +428,543 @@ exports[`Transfer should show sorted targetkey 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Transfer should support render value and label in item 1`] = `
|
||||||
|
<Transfer
|
||||||
|
dataSource={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"key": "a",
|
||||||
|
"title": "title",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
locale={Object {}}
|
||||||
|
render={[Function]}
|
||||||
|
showSearch={false}
|
||||||
|
>
|
||||||
|
<LocaleReceiver
|
||||||
|
componentName="Transfer"
|
||||||
|
defaultLocale={
|
||||||
|
Object {
|
||||||
|
"itemUnit": "item",
|
||||||
|
"itemsUnit": "items",
|
||||||
|
"searchPlaceholder": "Search here",
|
||||||
|
"titles": Array [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer"
|
||||||
|
>
|
||||||
|
<TransferList
|
||||||
|
checkedKeys={Array []}
|
||||||
|
dataSource={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"key": "a",
|
||||||
|
"title": "title",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
direction="left"
|
||||||
|
handleClear={[Function]}
|
||||||
|
handleFilter={[Function]}
|
||||||
|
handleSelect={[Function]}
|
||||||
|
handleSelectAll={[Function]}
|
||||||
|
itemUnit="item"
|
||||||
|
itemsUnit="items"
|
||||||
|
lazy={Object {}}
|
||||||
|
notFoundContent={
|
||||||
|
<Context.Consumer>
|
||||||
|
[Function]
|
||||||
|
</Context.Consumer>
|
||||||
|
}
|
||||||
|
onItemSelect={[Function]}
|
||||||
|
onItemSelectAll={[Function]}
|
||||||
|
onScroll={[Function]}
|
||||||
|
prefixCls="ant-transfer-list"
|
||||||
|
render={[Function]}
|
||||||
|
searchPlaceholder="Search here"
|
||||||
|
showSearch={false}
|
||||||
|
titleText=""
|
||||||
|
titles={
|
||||||
|
Array [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list-header"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={false}
|
||||||
|
indeterminate={false}
|
||||||
|
onChange={[Function]}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="ant-checkbox-wrapper"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={false}
|
||||||
|
className=""
|
||||||
|
defaultChecked={false}
|
||||||
|
onBlur={[Function]}
|
||||||
|
onChange={[Function]}
|
||||||
|
onFocus={[Function]}
|
||||||
|
prefixCls="ant-checkbox"
|
||||||
|
style={Object {}}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="ant-checkbox"
|
||||||
|
style={Object {}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked={false}
|
||||||
|
className="ant-checkbox-input"
|
||||||
|
onBlur={[Function]}
|
||||||
|
onChange={[Function]}
|
||||||
|
onFocus={[Function]}
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="ant-checkbox-inner"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Checkbox>
|
||||||
|
</label>
|
||||||
|
</Checkbox>
|
||||||
|
<span
|
||||||
|
className="ant-transfer-list-header-selected"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
1
|
||||||
|
|
||||||
|
item
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="ant-transfer-list-header-title"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list-body"
|
||||||
|
>
|
||||||
|
<ListBody
|
||||||
|
dataSource={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"key": "a",
|
||||||
|
"title": "title",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
direction="left"
|
||||||
|
filteredItems={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"key": "a",
|
||||||
|
"title": "title",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
filteredRenderItems={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"key": "a",
|
||||||
|
"title": "title",
|
||||||
|
},
|
||||||
|
"renderedEl": "label",
|
||||||
|
"renderedText": "title value",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
itemUnit="item"
|
||||||
|
itemsUnit="items"
|
||||||
|
lazy={Object {}}
|
||||||
|
notFoundContent={
|
||||||
|
<Context.Consumer>
|
||||||
|
[Function]
|
||||||
|
</Context.Consumer>
|
||||||
|
}
|
||||||
|
onItemSelect={[Function]}
|
||||||
|
onItemSelectAll={[Function]}
|
||||||
|
onScroll={[Function]}
|
||||||
|
prefixCls="ant-transfer-list"
|
||||||
|
render={[Function]}
|
||||||
|
searchPlaceholder="Search here"
|
||||||
|
selectedKeys={Array []}
|
||||||
|
showSearch={false}
|
||||||
|
titleText=""
|
||||||
|
titles={
|
||||||
|
Array [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Animate
|
||||||
|
animation={Object {}}
|
||||||
|
className="ant-transfer-list-content"
|
||||||
|
component="ul"
|
||||||
|
componentProps={
|
||||||
|
Object {
|
||||||
|
"onScroll": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onAppear={[Function]}
|
||||||
|
onEnd={[Function]}
|
||||||
|
onEnter={[Function]}
|
||||||
|
onLeave={[Function]}
|
||||||
|
transitionAppear={false}
|
||||||
|
transitionEnter={true}
|
||||||
|
transitionLeave={false}
|
||||||
|
transitionName=""
|
||||||
|
>
|
||||||
|
<ul
|
||||||
|
className="ant-transfer-list-content"
|
||||||
|
onScroll={[Function]}
|
||||||
|
>
|
||||||
|
<AnimateChild
|
||||||
|
animation={Object {}}
|
||||||
|
key="a"
|
||||||
|
transitionAppear={false}
|
||||||
|
transitionEnter={true}
|
||||||
|
transitionLeave={false}
|
||||||
|
transitionName=""
|
||||||
|
>
|
||||||
|
<ListItem
|
||||||
|
checked={false}
|
||||||
|
item={
|
||||||
|
Object {
|
||||||
|
"key": "a",
|
||||||
|
"title": "title",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key="a"
|
||||||
|
lazy={Object {}}
|
||||||
|
onClick={[Function]}
|
||||||
|
prefixCls="ant-transfer-list"
|
||||||
|
renderedEl="label"
|
||||||
|
renderedText="title value"
|
||||||
|
>
|
||||||
|
<LazyLoad
|
||||||
|
debounce={false}
|
||||||
|
elementType="div"
|
||||||
|
height={32}
|
||||||
|
offset={500}
|
||||||
|
offsetBottom={0}
|
||||||
|
offsetHorizontal={0}
|
||||||
|
offsetLeft={0}
|
||||||
|
offsetRight={0}
|
||||||
|
offsetTop={0}
|
||||||
|
offsetVertical={0}
|
||||||
|
throttle={0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="LazyLoad"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"height": 32,
|
||||||
|
"width": undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</LazyLoad>
|
||||||
|
</ListItem>
|
||||||
|
</AnimateChild>
|
||||||
|
</ul>
|
||||||
|
</Animate>
|
||||||
|
</ListBody>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TransferList>
|
||||||
|
<Operation
|
||||||
|
className="ant-transfer-operation"
|
||||||
|
leftActive={false}
|
||||||
|
moveToLeft={[Function]}
|
||||||
|
moveToRight={[Function]}
|
||||||
|
rightActive={false}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-operation"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
block={false}
|
||||||
|
disabled={true}
|
||||||
|
ghost={false}
|
||||||
|
htmlType="button"
|
||||||
|
icon="right"
|
||||||
|
loading={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
<Wave>
|
||||||
|
<button
|
||||||
|
className="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
|
||||||
|
disabled={true}
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
type="right"
|
||||||
|
>
|
||||||
|
<LocaleReceiver
|
||||||
|
componentName="Icon"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
aria-label="icon: right"
|
||||||
|
className="anticon anticon-right"
|
||||||
|
>
|
||||||
|
<IconReact
|
||||||
|
className=""
|
||||||
|
type="right-o"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
className=""
|
||||||
|
data-icon="right"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
key="svg-right"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.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.1a31.96 31.96 0 0 0 0-50.4z"
|
||||||
|
key="svg-right-svg-0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</IconReact>
|
||||||
|
</i>
|
||||||
|
</LocaleReceiver>
|
||||||
|
</Icon>
|
||||||
|
</button>
|
||||||
|
</Wave>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
block={false}
|
||||||
|
disabled={true}
|
||||||
|
ghost={false}
|
||||||
|
htmlType="button"
|
||||||
|
icon="left"
|
||||||
|
loading={false}
|
||||||
|
onClick={[Function]}
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
<Wave>
|
||||||
|
<button
|
||||||
|
className="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
|
||||||
|
disabled={true}
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
type="left"
|
||||||
|
>
|
||||||
|
<LocaleReceiver
|
||||||
|
componentName="Icon"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
aria-label="icon: left"
|
||||||
|
className="anticon anticon-left"
|
||||||
|
>
|
||||||
|
<IconReact
|
||||||
|
className=""
|
||||||
|
type="left-o"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
className=""
|
||||||
|
data-icon="left"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
key="svg-left"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 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"
|
||||||
|
key="svg-left-svg-0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</IconReact>
|
||||||
|
</i>
|
||||||
|
</LocaleReceiver>
|
||||||
|
</Icon>
|
||||||
|
</button>
|
||||||
|
</Wave>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Operation>
|
||||||
|
<TransferList
|
||||||
|
checkedKeys={Array []}
|
||||||
|
dataSource={Array []}
|
||||||
|
direction="right"
|
||||||
|
handleClear={[Function]}
|
||||||
|
handleFilter={[Function]}
|
||||||
|
handleSelect={[Function]}
|
||||||
|
handleSelectAll={[Function]}
|
||||||
|
itemUnit="item"
|
||||||
|
itemsUnit="items"
|
||||||
|
lazy={Object {}}
|
||||||
|
notFoundContent={
|
||||||
|
<Context.Consumer>
|
||||||
|
[Function]
|
||||||
|
</Context.Consumer>
|
||||||
|
}
|
||||||
|
onItemSelect={[Function]}
|
||||||
|
onItemSelectAll={[Function]}
|
||||||
|
onScroll={[Function]}
|
||||||
|
prefixCls="ant-transfer-list"
|
||||||
|
render={[Function]}
|
||||||
|
searchPlaceholder="Search here"
|
||||||
|
showSearch={false}
|
||||||
|
titleText=""
|
||||||
|
titles={
|
||||||
|
Array [
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list-header"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={false}
|
||||||
|
indeterminate={false}
|
||||||
|
onChange={[Function]}
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="ant-checkbox-wrapper"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={false}
|
||||||
|
className=""
|
||||||
|
defaultChecked={false}
|
||||||
|
onBlur={[Function]}
|
||||||
|
onChange={[Function]}
|
||||||
|
onFocus={[Function]}
|
||||||
|
prefixCls="ant-checkbox"
|
||||||
|
style={Object {}}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="ant-checkbox"
|
||||||
|
style={Object {}}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked={false}
|
||||||
|
className="ant-checkbox-input"
|
||||||
|
onBlur={[Function]}
|
||||||
|
onChange={[Function]}
|
||||||
|
onFocus={[Function]}
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="ant-checkbox-inner"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</Checkbox>
|
||||||
|
</label>
|
||||||
|
</Checkbox>
|
||||||
|
<span
|
||||||
|
className="ant-transfer-list-header-selected"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
0
|
||||||
|
|
||||||
|
item
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="ant-transfer-list-header-title"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list-body"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-transfer-list-body-not-found"
|
||||||
|
>
|
||||||
|
<Empty
|
||||||
|
className="ant-empty-small"
|
||||||
|
image={<Simple />}
|
||||||
|
>
|
||||||
|
<LocaleReceiver
|
||||||
|
componentName="Empty"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-empty ant-empty-normal ant-empty-small"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="ant-empty-image"
|
||||||
|
>
|
||||||
|
<Simple>
|
||||||
|
<svg
|
||||||
|
height="41"
|
||||||
|
viewBox="0 0 64 41"
|
||||||
|
width="64"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
fill="none"
|
||||||
|
fillRule="evenodd"
|
||||||
|
transform="translate(0 1)"
|
||||||
|
>
|
||||||
|
<ellipse
|
||||||
|
cx="32"
|
||||||
|
cy="33"
|
||||||
|
fill="#F5F5F5"
|
||||||
|
rx="32"
|
||||||
|
ry="7"
|
||||||
|
/>
|
||||||
|
<g
|
||||||
|
fillRule="nonzero"
|
||||||
|
stroke="#D9D9D9"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
|
||||||
|
fill="#FAFAFA"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</Simple>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
className="ant-empty-description"
|
||||||
|
>
|
||||||
|
No Data
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</LocaleReceiver>
|
||||||
|
</Empty>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TransferList>
|
||||||
|
</div>
|
||||||
|
</LocaleReceiver>
|
||||||
|
</Transfer>
|
||||||
|
`;
|
||||||
|
@ -113,6 +113,24 @@ describe('Transfer', () => {
|
|||||||
expect(handleChange).toHaveBeenCalledWith(['a', 'b'], 'right', ['a']);
|
expect(handleChange).toHaveBeenCalledWith(['a', 'b'], 'right', ['a']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should move selected keys to left list', () => {
|
||||||
|
const handleChange = jest.fn();
|
||||||
|
const wrapper = mount(
|
||||||
|
<Transfer
|
||||||
|
{...listCommonProps}
|
||||||
|
selectedKeys={['a']}
|
||||||
|
targetKeys={['a']}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
wrapper
|
||||||
|
.find(TransferOperation)
|
||||||
|
.find(Button)
|
||||||
|
.at(1)
|
||||||
|
.simulate('click'); // move selected keys to left list
|
||||||
|
expect(handleChange).toHaveBeenCalledWith([], 'left', ['a']);
|
||||||
|
});
|
||||||
|
|
||||||
it('should move selected keys expect disabled to corresponding list', () => {
|
it('should move selected keys expect disabled to corresponding list', () => {
|
||||||
const handleChange = jest.fn();
|
const handleChange = jest.fn();
|
||||||
const wrapper = mount(<Transfer {...listDisabledProps} onChange={handleChange} />);
|
const wrapper = mount(<Transfer {...listDisabledProps} onChange={handleChange} />);
|
||||||
@ -450,4 +468,44 @@ describe('Transfer', () => {
|
|||||||
expect(listTarget.prop('style')).toHaveProperty('backgroundColor', 'blue');
|
expect(listTarget.prop('style')).toHaveProperty('backgroundColor', 'blue');
|
||||||
expect(operation.prop('style')).toHaveProperty('backgroundColor', 'yellow');
|
expect(operation.prop('style')).toHaveProperty('backgroundColor', 'yellow');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support onScroll', () => {
|
||||||
|
const onScroll = jest.fn();
|
||||||
|
const component = mount(
|
||||||
|
<Transfer
|
||||||
|
{...listCommonProps}
|
||||||
|
onScroll={onScroll}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
component.find('.ant-transfer-list').at(0).find('.ant-transfer-list-content').at(0).simulate('scroll');
|
||||||
|
expect(onScroll).toHaveBeenLastCalledWith('left', expect.anything());
|
||||||
|
component.find('.ant-transfer-list').at(1).find('.ant-transfer-list-content').at(0).simulate('scroll');
|
||||||
|
expect(onScroll).toHaveBeenLastCalledWith('right', expect.anything());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support rowKey is function', () => {
|
||||||
|
expect(() => {
|
||||||
|
mount(
|
||||||
|
<Transfer
|
||||||
|
{...listCommonProps}
|
||||||
|
rowKey={record => record.key}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support render value and label in item', () => {
|
||||||
|
const component = mount(
|
||||||
|
<Transfer
|
||||||
|
dataSource={[
|
||||||
|
{
|
||||||
|
key: 'a',
|
||||||
|
title: 'title',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
render={record => ({ value: `${record.title} value`, label: 'label' })}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -25,6 +25,7 @@ describe('Transfer.Search', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('onSearch', () => {
|
it('onSearch', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
const dataSource = [
|
const dataSource = [
|
||||||
{
|
{
|
||||||
key: 'a',
|
key: 'a',
|
||||||
@ -59,6 +60,7 @@ describe('Transfer.Search', () => {
|
|||||||
.find('.ant-input')
|
.find('.ant-input')
|
||||||
.at(0)
|
.at(0)
|
||||||
.simulate('change', { target: { value: 'a' } });
|
.simulate('change', { target: { value: 'a' } });
|
||||||
|
jest.runAllTimers();
|
||||||
expect(onSearch).toHaveBeenCalledWith('left', 'a');
|
expect(onSearch).toHaveBeenCalledWith('left', 'a');
|
||||||
|
|
||||||
onSearch.mockReset();
|
onSearch.mockReset();
|
||||||
@ -68,9 +70,11 @@ describe('Transfer.Search', () => {
|
|||||||
.at(0)
|
.at(0)
|
||||||
.simulate('click');
|
.simulate('click');
|
||||||
expect(onSearch).toHaveBeenCalledWith('left', '');
|
expect(onSearch).toHaveBeenCalledWith('left', '');
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('legacy onSearchChange', () => {
|
it('legacy onSearchChange', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
const onSearchChange = jest.fn();
|
const onSearchChange = jest.fn();
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
@ -81,11 +85,13 @@ describe('Transfer.Search', () => {
|
|||||||
.find('.ant-input')
|
.find('.ant-input')
|
||||||
.at(0)
|
.at(0)
|
||||||
.simulate('change', { target: { value: 'a' } });
|
.simulate('change', { target: { value: 'a' } });
|
||||||
|
jest.runAllTimers();
|
||||||
|
|
||||||
expect(errorSpy.mock.calls[0][0]).toMatch(
|
expect(errorSpy.mock.calls[0][0]).toMatch(
|
||||||
'Warning: [antd: Transfer] `onSearchChange` is deprecated. Please use `onSearch` instead.',
|
'Warning: [antd: Transfer] `onSearchChange` is deprecated. Please use `onSearch` instead.',
|
||||||
);
|
);
|
||||||
expect(onSearchChange.mock.calls[0][0]).toEqual('left');
|
expect(onSearchChange.mock.calls[0][0]).toEqual('left');
|
||||||
expect(onSearchChange.mock.calls[0][1].target.value).toEqual('a');
|
expect(onSearchChange.mock.calls[0][1].target.value).toEqual('a');
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -190,6 +190,8 @@
|
|||||||
|
|
||||||
> span {
|
> span {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{iconfont-css-prefix}-loading,
|
.@{iconfont-css-prefix}-loading,
|
||||||
@ -423,6 +425,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{upload-item}-name {
|
.@{upload-item}-name {
|
||||||
|
@ -23,10 +23,10 @@ As a part of nature, it will have deep influence on user behavior, and designers
|
|||||||
- The visual system plays the most important role in human perception and cognition. By refining the objective laws in nature and applying it to the interface design, a more layered product experience is created. In addition, hearing systems or tactile systems could be added in future to bring more dimensions and more real product experience. See visual language.
|
- The visual system plays the most important role in human perception and cognition. By refining the objective laws in nature and applying it to the interface design, a more layered product experience is created. In addition, hearing systems or tactile systems could be added in future to bring more dimensions and more real product experience. See visual language.
|
||||||
- In the real product design, a series of methods such as behavior analysis, artificial intelligence and sensors could be applied to assist users to make effective decisions and reduce extra operations of users, so as to save users' mental and physical resources and make human-computer interaction more natural.
|
- In the real product design, a series of methods such as behavior analysis, artificial intelligence and sensors could be applied to assist users to make effective decisions and reduce extra operations of users, so as to save users' mental and physical resources and make human-computer interaction more natural.
|
||||||
|
|
||||||
## Determinacy
|
## Certainty
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/ZxgRAMzXNrxHTcvMLchq.png" alt="Determine" />
|
<img src="https://gw.alipayobjects.com/zos/rmsportal/ZxgRAMzXNrxHTcvMLchq.png" alt="Certainty" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The designers needs to make better design decisions and create a high-definition and low-entropy atmosphere for developer team. Meanwhile, different designers could produce the same design output which fit business needs based on the same understanding of business requirements and design system.
|
The designers needs to make better design decisions and create a high-definition and low-entropy atmosphere for developer team. Meanwhile, different designers could produce the same design output which fit business needs based on the same understanding of business requirements and design system.
|
||||||
|
@ -100,6 +100,7 @@ module.exports = {
|
|||||||
antd: path.join(process.cwd(), 'index'),
|
antd: path.join(process.cwd(), 'index'),
|
||||||
site: path.join(process.cwd(), 'site'),
|
site: path.join(process.cwd(), 'site'),
|
||||||
'react-router': 'react-router/umd/ReactRouter',
|
'react-router': 'react-router/umd/ReactRouter',
|
||||||
|
'react-intl': 'react-intl/dist',
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
Loading…
Reference in New Issue
Block a user