Transfer support disabled (#12084)

This commit is contained in:
zombieJ 2018-09-15 15:18:59 +08:00 committed by 偏右
parent 2b22d6b19c
commit f9dd709e2f
10 changed files with 282 additions and 233 deletions

View File

@ -490,6 +490,10 @@
// ---
@skeleton-color: #f2f2f2;
// Transfer
// ---
@transfer-disabled-bg: @disabled-bg;
// Message
// ---
@message-notice-content-padding: 10px 16px;

View File

@ -248,235 +248,247 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
`;
exports[`renders ./components/transfer/demo/basic.md correctly 1`] = `
<div
class="ant-transfer"
>
<div>
<div
class="ant-transfer-list"
class="ant-transfer"
>
<div
class="ant-transfer-list-header"
class="ant-transfer-list"
>
<label
class="ant-checkbox-wrapper"
<div
class="ant-transfer-list-header"
>
<span
class="ant-checkbox"
<label
class="ant-checkbox-wrapper"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-header-selected"
>
<span>
14 items
</span>
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-header-title"
class="ant-transfer-list-header-selected"
>
Source
<span>
14 items
</span>
<span
class="ant-transfer-list-header-title"
>
Source
</span>
</span>
</span>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
</ul>
<div
class="ant-transfer-list-body-not-found"
>
Not Found
</div>
</div>
</div>
<div
class="ant-transfer-list-body"
class="ant-transfer-operation"
>
<ul
class="ant-transfer-list-content"
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
</ul>
<i
class="anticon anticon-right"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
height="1em"
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"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
>
<i
class="anticon anticon-left"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
height="1em"
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"
/>
</svg>
</i>
</button>
</div>
<div
class="ant-transfer-list"
>
<div
class="ant-transfer-list-body-not-found"
class="ant-transfer-list-header"
>
Not Found
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-header-selected"
>
<span>
6 items
</span>
<span
class="ant-transfer-list-header-title"
>
Target
</span>
</span>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
</ul>
<div
class="ant-transfer-list-body-not-found"
>
Not Found
</div>
</div>
</div>
</div>
<div
class="ant-transfer-operation"
<span
class="ant-switch"
tabindex="0"
>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
<span
class="ant-switch-inner"
>
<i
class="anticon anticon-right"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
height="1em"
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"
/>
</svg>
</i>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
>
<i
class="anticon anticon-left"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
height="1em"
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"
/>
</svg>
</i>
</button>
</div>
<div
class="ant-transfer-list"
>
<div
class="ant-transfer-list-header"
>
<label
class="ant-checkbox-wrapper"
>
<span
class="ant-checkbox"
>
<input
class="ant-checkbox-input"
type="checkbox"
/>
<span
class="ant-checkbox-inner"
/>
</span>
</label>
<span
class="ant-transfer-list-header-selected"
>
<span>
6 items
</span>
<span
class="ant-transfer-list-header-title"
>
Target
</span>
</span>
</div>
<div
class="ant-transfer-list-body"
>
<ul
class="ant-transfer-list-content"
>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
<div
class="LazyLoad"
style="height:32px"
/>
</ul>
<div
class="ant-transfer-list-body-not-found"
>
Not Found
</div>
</div>
</div>
disabled
</span>
</span>
</div>
`;

View File

@ -14,7 +14,7 @@ title:
The most basic usage of `Transfer` involves providing the source data and target keys arrays, plus the rendering and some callback functions.
````jsx
import { Transfer } from 'antd';
import { Transfer, Switch } from 'antd';
const mockData = [];
for (let i = 0; i < 20; i++) {
@ -26,20 +26,21 @@ for (let i = 0; i < 20; i++) {
});
}
const targetKeys = mockData
const oriTargetKeys = mockData
.filter(item => +item.key % 3 > 1)
.map(item => item.key);
class App extends React.Component {
state = {
targetKeys,
targetKeys: oriTargetKeys,
selectedKeys: [],
disabled: false,
}
handleChange = (nextTargetKeys, direction, moveKeys) => {
this.setState({ targetKeys: nextTargetKeys });
console.log('targetKeys: ', targetKeys);
console.log('targetKeys: ', nextTargetKeys);
console.log('direction: ', direction);
console.log('moveKeys: ', moveKeys);
}
@ -56,19 +57,28 @@ class App extends React.Component {
console.log('target:', e.target);
}
handleDisable = (disabled) => {
this.setState({ disabled });
};
render() {
const state = this.state;
const { targetKeys, selectedKeys, disabled } = this.state;
return (
<Transfer
dataSource={mockData}
titles={['Source', 'Target']}
targetKeys={state.targetKeys}
selectedKeys={state.selectedKeys}
onChange={this.handleChange}
onSelectChange={this.handleSelectChange}
onScroll={this.handleScroll}
render={item => item.title}
/>
<div>
<Transfer
dataSource={mockData}
titles={['Source', 'Target']}
targetKeys={targetKeys}
selectedKeys={selectedKeys}
onChange={this.handleChange}
onSelectChange={this.handleSelectChange}
onScroll={this.handleScroll}
render={item => item.title}
disabled={disabled}
/>
<Switch unCheckedChildren="disabled" checkedChildren="disabled" checked={disabled} onChange={this.handleDisable} />
</div>
);
}
}

View File

@ -18,7 +18,9 @@ One or more elements can be selected from either column, one click on the proper
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| className | A custom CSS class. | string | ['', ''] |
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop. | [TransferItem](https://git.io/vMM64)\[] | \[] |
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column.
Except the elements whose keys are included in `targetKeys` prop. | [TransferItem](https://git.io/vMM64)\[] | \[] |
| disabled | Whether disabled transfer | boolean | false |
| filterOption | A function to determine whether an item should show in search result list | (inputValue, option): boolean | |
| footer | A function used for rendering the footer. | (props): ReactNode | |
| lazy | property of [react-lazy-load](https://github.com/loktar00/react-lazy-load) for lazy rendering items. Turn off it by set to `false`. | object\|boolean | `{ height: 32, offset: 32 }` |

View File

@ -27,6 +27,7 @@ export interface TransferItem {
export interface TransferProps {
prefixCls?: string;
className?: string;
disabled?: boolean;
dataSource: TransferItem[];
targetKeys?: string[];
selectedKeys?: string[];
@ -74,6 +75,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
static propTypes = {
prefixCls: PropTypes.string,
disabled: PropTypes.bool,
dataSource: PropTypes.array,
render: PropTypes.func,
targetKeys: PropTypes.array,
@ -348,6 +350,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
const {
prefixCls = 'ant-transfer',
className,
disabled,
operations = [],
showSearch,
body,
@ -366,7 +369,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
const leftActive = targetSelectedKeys.length > 0;
const rightActive = sourceSelectedKeys.length > 0;
const cls = classNames(className, prefixCls);
const cls = classNames(className, prefixCls, disabled && `${prefixCls}-disabled`);
const titles = this.getTitles(locale);
return (
@ -389,6 +392,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
footer={footer}
lazy={lazy}
onScroll={this.handleLeftScroll}
disabled={disabled}
{...locale}
/>
<Operation
@ -400,6 +404,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
leftArrowText={operations[1]}
moveToLeft={this.moveToLeft}
style={operationStyle}
disabled={disabled}
/>
<List
prefixCls={`${prefixCls}-list`}
@ -419,6 +424,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
footer={footer}
lazy={lazy}
onScroll={this.handleRightScroll}
disabled={disabled}
{...locale}
/>
</div>

View File

@ -21,6 +21,7 @@ title: Transfer
| --- | --- | --- | --- |
| className | 自定义类 | string | |
| dataSource | 数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外。 | [TransferItem](https://git.io/vMM64)\[] | \[] |
| disabled | 是否禁用 | boolean | false |
| filterOption | 接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | (inputValue, option): boolean | |
| footer | 底部渲染函数 | (props): ReactNode | |
| lazy | Transfer 使用了 [react-lazy-load](https://github.com/loktar00/react-lazy-load) 优化性能,这里可以设置相关参数。设为 `false` 可以关闭懒加载。 | object\|boolean | `{ height: 32, offset: 32 }` |

View File

@ -9,20 +9,23 @@ export default class Item extends React.Component<any, any> {
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
}
render() {
const { renderedText, renderedEl, item, lazy, checked, prefixCls, onClick } = this.props;
const {
renderedText, renderedEl, item, lazy,
checked, disabled, prefixCls, onClick,
} = this.props;
const className = classNames({
[`${prefixCls}-content-item`]: true,
[`${prefixCls}-content-item-disabled`]: item.disabled,
[`${prefixCls}-content-item-disabled`]: disabled || item.disabled,
});
const listItem = (
<li
className={className}
title={renderedText}
onClick={item.disabled ? undefined : () => onClick(item)}
onClick={(disabled || item.disabled) ? undefined : () => onClick(item)}
>
<Checkbox checked={checked} disabled={item.disabled} />
<Checkbox checked={checked} disabled={disabled || item.disabled} />
<span>{renderedEl}</span>
</li>
);

View File

@ -43,6 +43,7 @@ export interface TransferListProps {
footer?: (props: any) => void;
lazy?: boolean | {};
onScroll: Function;
disabled?: boolean;
}
export default class TransferList extends React.Component<TransferListProps, any> {
@ -160,7 +161,7 @@ export default class TransferList extends React.Component<TransferListProps, any
render() {
const {
prefixCls, dataSource, titleText, checkedKeys, lazy,
prefixCls, dataSource, titleText, checkedKeys, lazy, disabled,
body = noop, footer = noop, showSearch, style, filter,
searchPlaceholder, notFoundContent, itemUnit, itemsUnit, onScroll,
} = this.props;
@ -192,6 +193,7 @@ export default class TransferList extends React.Component<TransferListProps, any
const checked = checkedKeys.indexOf(item.key) >= 0;
return (
<Item
disabled={disabled}
key={item.key}
item={item}
lazy={lazy}
@ -219,7 +221,7 @@ export default class TransferList extends React.Component<TransferListProps, any
) : null;
const listBody = bodyDom || (
<div className={showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`}>
<div className={classNames(showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`)}>
{search}
<Animate
component="ul"
@ -247,6 +249,7 @@ export default class TransferList extends React.Component<TransferListProps, any
const checkAllCheckbox = (
<Checkbox
ref="checkbox"
disabled={disabled}
checked={checkedAll}
indeterminate={checkStatus === 'part'}
onChange={() => this.props.handleSelectAll(filteredDataSource, checkedAll)}

View File

@ -10,11 +10,13 @@ export interface TransferOperationProps {
leftActive?: boolean;
rightActive?: boolean;
style?: React.CSSProperties;
disabled?: boolean;
}
export default class Operation extends React.Component<TransferOperationProps, any> {
render() {
const {
disabled,
moveToLeft,
moveToRight,
leftArrowText = '',
@ -29,7 +31,7 @@ export default class Operation extends React.Component<TransferOperationProps, a
<Button
type="primary"
size="small"
disabled={!rightActive}
disabled={disabled || !rightActive}
onClick={moveToRight}
icon="right"
>
@ -38,7 +40,7 @@ export default class Operation extends React.Component<TransferOperationProps, a
<Button
type="primary"
size="small"
disabled={!leftActive}
disabled={disabled || !leftActive}
onClick={moveToLeft}
icon="left"
>

View File

@ -8,6 +8,12 @@
.reset-component;
position: relative;
&-disabled {
.@{transfer-prefix-cls}-list {
background: @transfer-disabled-bg;
}
}
&-list {
border: @border-width-base @border-style-base @border-color-base;
display: inline-block;