增加删除已选操作区
This commit is contained in:
parent
8ec2d4633d
commit
1f97ec83d6
|
@ -58,7 +58,6 @@ class Demo1 extends React.Component {
|
|||
const targetKeys = [...this.state.targetKeys];
|
||||
return (
|
||||
<Transfer
|
||||
draggable={true}
|
||||
dataSource={mockData}
|
||||
titles={['Source', 'Target']}
|
||||
targetKeys={targetKeys}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
*
|
||||
* @title 拖拽穿梭
|
||||
* @description 通过`draggable`参数设置是否可以通过拖拽进行穿梭和排序
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import Transfer from '../../src';
|
||||
|
||||
const mockData = [];
|
||||
for (let i = 0; i < 20; i++) {
|
||||
mockData.push({
|
||||
key: i.toString(),
|
||||
title: `content${i + 1}`,
|
||||
description: `description of content${i + 1}`,
|
||||
disabled: i % 3 < 1,
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
const targetKeys = mockData
|
||||
.filter(item => +item.key % 3 > 1)
|
||||
.map(item => item.key);
|
||||
|
||||
class Demo5 extends React.Component {
|
||||
state = {
|
||||
targetKeys,
|
||||
selectedKeys: [],
|
||||
showModal: false,
|
||||
modalSize: ''
|
||||
}
|
||||
|
||||
handleChange = (nextTargetKeys, direction, moveKeys) => {
|
||||
this.setState({ targetKeys: nextTargetKeys });
|
||||
|
||||
console.log('targetKeys: ', nextTargetKeys);
|
||||
console.log('direction: ', direction);
|
||||
console.log('moveKeys: ', moveKeys);
|
||||
}
|
||||
|
||||
handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
|
||||
this.setState({ selectedKeys: [...sourceSelectedKeys, ...targetSelectedKeys] });
|
||||
|
||||
console.log('sourceSelectedKeys: ', sourceSelectedKeys);
|
||||
console.log('targetSelectedKeys: ', targetSelectedKeys);
|
||||
}
|
||||
|
||||
handleScroll = (direction, e) => {
|
||||
console.log('direction:', direction);
|
||||
console.log('target:', e.target);
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const state = this.state;
|
||||
// targetKeys需要通过数组的扩展运算符进行赋值
|
||||
const targetKeys = [...this.state.targetKeys];
|
||||
return (
|
||||
<Transfer
|
||||
draggable={true}
|
||||
showCheckbox={false}
|
||||
dataSource={mockData}
|
||||
titles={['Source', 'Target']}
|
||||
targetKeys={targetKeys}
|
||||
selectedKeys={state.selectedKeys}
|
||||
onChange={this.handleChange}
|
||||
onSelectChange={this.handleSelectChange}
|
||||
onScroll={this.handleScroll}
|
||||
render={item => item.title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Demo5
|
File diff suppressed because one or more lines are too long
|
@ -14,6 +14,8 @@
|
|||
width: 180px;
|
||||
height: 200px;
|
||||
padding-top: 33px; }
|
||||
.u-transfer-list.u-transfer-list-draggable:first-child {
|
||||
margin-right: 16px; }
|
||||
.u-transfer-list-with-footer {
|
||||
padding-bottom: 33px; }
|
||||
.u-transfer-list-search-action {
|
||||
|
@ -85,13 +87,16 @@
|
|||
transition: none; }
|
||||
.u-transfer-list-delete-selected-btn {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: -32px;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
background: #505F79;
|
||||
opacity: 0.65;
|
||||
text-align: center;
|
||||
line-height: 32px; }
|
||||
line-height: 32px;
|
||||
z-index: 10; }
|
||||
.u-transfer-list-delete-selected-btn.hide {
|
||||
display: none; }
|
||||
.u-transfer-list-delete-selected-btn .uf {
|
||||
color: #fff; }
|
||||
.u-transfer-list-body-not-found {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -14,7 +14,7 @@ import { Transfer } from 'tinper-bee';
|
|||
or
|
||||
|
||||
import Transfer from 'bee-transfer';
|
||||
import bee-transfer/build/Transfer.css;
|
||||
import 'bee-transfer/build/Transfer.css';
|
||||
|
||||
```
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ class Transfer extends React.Component{
|
|||
}
|
||||
// clear key nolonger existed
|
||||
// clear checkedKeys according to targetKeys
|
||||
console.log(sourceSelectedKeys.filter(existInDateSourcekey)
|
||||
.filter(data => targetKeys.filter(key => key === data).length === 0))
|
||||
this.setState({
|
||||
sourceSelectedKeys: sourceSelectedKeys.filter(existInDateSourcekey)
|
||||
.filter(data => targetKeys.filter(key => key === data).length === 0),
|
||||
|
@ -291,8 +293,13 @@ class Transfer extends React.Component{
|
|||
|
||||
// dropped outside the list
|
||||
if (!destination) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
if(destination.droppableId === 'droppable_delbtn') {
|
||||
this.moveTo('left');
|
||||
return;
|
||||
}
|
||||
|
||||
let { targetKeys, onChange } = this.props;
|
||||
let sourceIndex = source.index; //初始位置
|
||||
let disIndex = destination.index; //移动后的位置
|
||||
|
@ -392,15 +399,18 @@ class Transfer extends React.Component{
|
|||
draggable={draggable}
|
||||
id={'1'}
|
||||
/>
|
||||
<Operation
|
||||
rightActive={rightActive}
|
||||
rightArrowText={operations[0]}
|
||||
moveToRight={this.moveToRight}
|
||||
leftActive={leftActive}
|
||||
leftArrowText={operations[1]}
|
||||
moveToLeft={this.moveToLeft}
|
||||
className={`${prefixCls}-operation`}
|
||||
/>
|
||||
{!draggable?
|
||||
<Operation
|
||||
rightActive={rightActive}
|
||||
rightArrowText={operations[0]}
|
||||
moveToRight={this.moveToRight}
|
||||
leftActive={leftActive}
|
||||
leftArrowText={operations[1]}
|
||||
moveToLeft={this.moveToLeft}
|
||||
className={`${prefixCls}-operation`}
|
||||
/>
|
||||
: ''
|
||||
}
|
||||
<List
|
||||
titleText={titles[1]} //右侧标题
|
||||
dataSource={rightDataSource} //右侧数据源
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
width: 180px;
|
||||
height: 200px;
|
||||
padding-top: 33px;
|
||||
&.u-transfer-list-draggable:first-child{
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
&-with-footer {
|
||||
padding-bottom: 33px;
|
||||
|
@ -119,16 +122,19 @@
|
|||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-delete-selected-btn{
|
||||
&.hide{
|
||||
display: none;
|
||||
}
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: -32px;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
background: #505F79;
|
||||
opacity: 0.65;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
z-index: 10;
|
||||
.uf{
|
||||
color: #fff;
|
||||
}
|
||||
|
|
156
src/item.js
156
src/item.js
|
@ -1,78 +1,78 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import PureRenderMixin from './PureRenderMixin';
|
||||
import assign from 'object-assign';
|
||||
import Lazyload from 'react-lazy-load';
|
||||
import Checkbox from 'bee-checkbox';
|
||||
|
||||
function isRenderResultPlainObject(result) {
|
||||
return result && !React.isValidElement(result) &&
|
||||
Object.prototype.toString.call(result) === '[object Object]';
|
||||
}
|
||||
|
||||
class Item extends React.Component{
|
||||
shouldComponentUpdate(...args) {
|
||||
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
|
||||
}
|
||||
// matchFilter = (text) => {
|
||||
// const { filter, filterOption, item } = this.props;
|
||||
// if (filterOption) {
|
||||
// return filterOption(filter, item);
|
||||
// }
|
||||
// return text.indexOf(filter) >= 0;
|
||||
// }
|
||||
render() {
|
||||
const { render, filter, item, lazy, checked, prefixCls, onClick,renderedText,renderedEl, showCheckbox } = this.props;
|
||||
const className = classNames({
|
||||
[`${prefixCls}-content-item`]: true,
|
||||
[`${prefixCls}-content-item-disabled`]: item.disabled,
|
||||
[`${prefixCls}-content-item-selected`]: checked
|
||||
});
|
||||
|
||||
const lazyProps = assign({
|
||||
height: 32,
|
||||
offset: 500,
|
||||
throttle: 0,
|
||||
debounce: false,
|
||||
}, lazy);
|
||||
|
||||
let lazyFlag = true;
|
||||
if(lazy && lazy.container == "modal")
|
||||
{
|
||||
lazyFlag = false
|
||||
}
|
||||
|
||||
if(!lazyFlag) {
|
||||
return (
|
||||
<li
|
||||
className={className}
|
||||
title={renderedText}
|
||||
onClick={item.disabled ? undefined : () => onClick(item)}
|
||||
>
|
||||
<Checkbox checked={checked} disabled={item.disabled} onClick={item.disabled ? undefined : () => onClick(item)}/>
|
||||
<span>{renderedEl}</span>
|
||||
</li>
|
||||
)
|
||||
}else {
|
||||
return (
|
||||
<Lazyload {...lazyProps}>
|
||||
<li
|
||||
className={className}
|
||||
title={renderedText}
|
||||
onClick={item.disabled ? undefined : () => onClick(item)}
|
||||
>
|
||||
{
|
||||
showCheckbox?
|
||||
<Checkbox checked={checked} disabled={item.disabled} onClick={item.disabled ? undefined : () => onClick(item)}/>
|
||||
:''
|
||||
}
|
||||
<span>{renderedEl}</span>
|
||||
</li>
|
||||
</Lazyload>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default Item;
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import PureRenderMixin from './PureRenderMixin';
|
||||
import assign from 'object-assign';
|
||||
import Lazyload from 'react-lazy-load';
|
||||
import Checkbox from 'bee-checkbox';
|
||||
|
||||
function isRenderResultPlainObject(result) {
|
||||
return result && !React.isValidElement(result) &&
|
||||
Object.prototype.toString.call(result) === '[object Object]';
|
||||
}
|
||||
|
||||
class Item extends React.Component{
|
||||
shouldComponentUpdate(...args) {
|
||||
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
|
||||
}
|
||||
// matchFilter = (text) => {
|
||||
// const { filter, filterOption, item } = this.props;
|
||||
// if (filterOption) {
|
||||
// return filterOption(filter, item);
|
||||
// }
|
||||
// return text.indexOf(filter) >= 0;
|
||||
// }
|
||||
render() {
|
||||
const { render, filter, item, lazy, checked, prefixCls, onClick,renderedText,renderedEl, showCheckbox } = this.props;
|
||||
const className = classNames({
|
||||
[`${prefixCls}-content-item`]: true,
|
||||
[`${prefixCls}-content-item-disabled`]: item.disabled,
|
||||
[`${prefixCls}-content-item-selected`]: checked
|
||||
});
|
||||
|
||||
const lazyProps = assign({
|
||||
height: 32,
|
||||
offset: 500,
|
||||
throttle: 0,
|
||||
debounce: false,
|
||||
}, lazy);
|
||||
|
||||
let lazyFlag = true;
|
||||
if(lazy && lazy.container == "modal")
|
||||
{
|
||||
lazyFlag = false
|
||||
}
|
||||
|
||||
if(!lazyFlag) {
|
||||
return (
|
||||
<li
|
||||
className={className}
|
||||
title={renderedText}
|
||||
onClick={item.disabled ? undefined : () => onClick(item)}
|
||||
>
|
||||
<Checkbox checked={checked} disabled={item.disabled} onClick={item.disabled ? undefined : () => onClick(item)}/>
|
||||
<span>{renderedEl}</span>
|
||||
</li>
|
||||
)
|
||||
}else {
|
||||
return (
|
||||
<Lazyload {...lazyProps}>
|
||||
<li
|
||||
className={className}
|
||||
title={renderedText}
|
||||
onClick={item.disabled ? undefined : () => onClick(item)}
|
||||
>
|
||||
{
|
||||
showCheckbox?
|
||||
<Checkbox checked={checked} disabled={item.disabled} onClick={item.disabled ? undefined : () => onClick(item)}/>
|
||||
:''
|
||||
}
|
||||
<span>{renderedEl}</span>
|
||||
</li>
|
||||
</Lazyload>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default Item;
|
||||
|
|
30
src/list.js
30
src/list.js
|
@ -213,6 +213,7 @@ class TransferList extends React.Component {
|
|||
|
||||
const listCls = classNames(prefixCls, {
|
||||
[`${prefixCls}-with-footer`]: !!footerDom,
|
||||
[`${prefixCls}-draggable`]: !!draggable
|
||||
});
|
||||
|
||||
const filteredDataSource = [];
|
||||
|
@ -264,21 +265,6 @@ class TransferList extends React.Component {
|
|||
</div>
|
||||
)}
|
||||
</Draggable>)
|
||||
// return (
|
||||
// <Item
|
||||
// key={item.key}
|
||||
// item={item}
|
||||
// lazy={lazy}
|
||||
// render={render}
|
||||
// renderedText={renderedText}
|
||||
// renderedEl={renderedEl}
|
||||
// filter={filter}
|
||||
// filterOption={filterOption}
|
||||
// checked={checked}
|
||||
// prefixCls={prefixCls}
|
||||
// onClick={this.handleSelect}
|
||||
// />
|
||||
// );
|
||||
});
|
||||
|
||||
let unit = '';
|
||||
|
@ -310,7 +296,6 @@ class TransferList extends React.Component {
|
|||
<Droppable droppableId={`droppable_${id}`} direction='vertical' isDropDisabled={!draggable}>
|
||||
{(provided, snapshot) => (
|
||||
<div ref={provided.innerRef} key={id} className={`${prefixCls}-content`}>
|
||||
{/* Animate component is a list container. And it's scrollable. */}
|
||||
<Animate
|
||||
component="ul"
|
||||
transitionName={this.state.mounted ? `${prefixCls}-content-item-highlight` : ''}
|
||||
|
@ -318,7 +303,6 @@ class TransferList extends React.Component {
|
|||
>
|
||||
{showItems}
|
||||
</Animate>
|
||||
{/* div component is the delete button at the bottom of container */}
|
||||
{/* <div
|
||||
className={dragging ? `${prefixCls}-delete-selected-btn` : ''}
|
||||
ondragenter={()=>{debugger}} //ondragenter and ondrop events won't be triggered when the mouse key is released。
|
||||
|
@ -329,6 +313,18 @@ class TransferList extends React.Component {
|
|||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
<Droppable droppableId={`droppable_delbtn`} direction='vertical' isDropDisabled={!draggable}>
|
||||
{(provided, snapshot) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
className={dragging ? `${prefixCls}-delete-selected-btn` : ''}
|
||||
ondragenter={()=>{debugger}} //ondragenter and ondrop events won't be triggered when the mouse key is released。
|
||||
ondrop={this.handleDeleteSelected}
|
||||
>
|
||||
{dragging ? <Icon type="uf-del"></Icon> : ''}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
<div className={`${prefixCls}-body-not-found ${dataSource.length == 0? "show" : ""}`}>
|
||||
{notFoundContent}
|
||||
</div>
|
||||
|
|
118
src/operation.js
118
src/operation.js
|
@ -1,60 +1,60 @@
|
|||
import React from 'react';
|
||||
import Button from 'bee-button';
|
||||
import Icon from 'bee-icon';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function noop() {
|
||||
}
|
||||
|
||||
const propTypes = {
|
||||
className: PropTypes.string,
|
||||
leftArrowText: PropTypes.string,
|
||||
rightArrowText: PropTypes.string,
|
||||
moveToLeft: PropTypes.func,
|
||||
moveToRight: PropTypes.func,
|
||||
leftActive: PropTypes.boolean,
|
||||
rightActive: PropTypes.boolean,
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
leftArrowText: '',
|
||||
rightArrowText: '',
|
||||
moveToLeft: noop,
|
||||
moveToRight: noop,
|
||||
};
|
||||
|
||||
class TransferOperation extends React.Component{
|
||||
|
||||
render() {
|
||||
const {
|
||||
moveToLeft,
|
||||
moveToRight,
|
||||
leftArrowText,
|
||||
rightArrowText,
|
||||
leftActive,
|
||||
rightActive,
|
||||
className,
|
||||
} = this.props;
|
||||
|
||||
const moveToLeftButton = (
|
||||
<Button size="sm" disabled={!leftActive} onClick={moveToLeft}>
|
||||
{<span><Icon type="uf-arrow-left" />{leftArrowText}</span>}
|
||||
</Button>
|
||||
);
|
||||
const moveToRightButton = (
|
||||
<Button size="sm" disabled={!rightActive} onClick={moveToRight}>
|
||||
{<span>{rightArrowText}<Icon type="uf-arrow-right" /></span>}
|
||||
</Button>
|
||||
);
|
||||
return (
|
||||
<div className={className}>
|
||||
{moveToLeftButton}
|
||||
{moveToRightButton}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TransferOperation.propsType = propTypes;
|
||||
TransferOperation.defaultProps = defaultProps;
|
||||
import React from 'react';
|
||||
import Button from 'bee-button';
|
||||
import Icon from 'bee-icon';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function noop() {
|
||||
}
|
||||
|
||||
const propTypes = {
|
||||
className: PropTypes.string,
|
||||
leftArrowText: PropTypes.string,
|
||||
rightArrowText: PropTypes.string,
|
||||
moveToLeft: PropTypes.func,
|
||||
moveToRight: PropTypes.func,
|
||||
leftActive: PropTypes.boolean,
|
||||
rightActive: PropTypes.boolean,
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
leftArrowText: '',
|
||||
rightArrowText: '',
|
||||
moveToLeft: noop,
|
||||
moveToRight: noop,
|
||||
};
|
||||
|
||||
class TransferOperation extends React.Component{
|
||||
|
||||
render() {
|
||||
const {
|
||||
moveToLeft,
|
||||
moveToRight,
|
||||
leftArrowText,
|
||||
rightArrowText,
|
||||
leftActive,
|
||||
rightActive,
|
||||
className,
|
||||
} = this.props;
|
||||
|
||||
const moveToLeftButton = (
|
||||
<Button size="sm" disabled={!leftActive} onClick={moveToLeft}>
|
||||
{<span><Icon type="uf-arrow-left" />{leftArrowText}</span>}
|
||||
</Button>
|
||||
);
|
||||
const moveToRightButton = (
|
||||
<Button size="sm" disabled={!rightActive} onClick={moveToRight}>
|
||||
{<span>{rightArrowText}<Icon type="uf-arrow-right" /></span>}
|
||||
</Button>
|
||||
);
|
||||
return (
|
||||
<div className={className}>
|
||||
{moveToLeftButton}
|
||||
{moveToRightButton}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TransferOperation.propsType = propTypes;
|
||||
TransferOperation.defaultProps = defaultProps;
|
||||
export default TransferOperation;
|
Loading…
Reference in New Issue