Compare commits
5 Commits
master
...
2.0.21-bet
Author | SHA1 | Date |
---|---|---|
gx | 598e883c9c | |
gx | 0c824495a1 | |
gx | af7f18c7d4 | |
gx | 95d92db03f | |
gx | df35554b5e |
|
@ -16,6 +16,13 @@
|
|||
padding-top: 33px; }
|
||||
.u-transfer-list.u-transfer-list-draggable:first-child {
|
||||
margin-right: 16px; }
|
||||
.u-transfer-list.u-transfer-list-with-pagination {
|
||||
height: 240px; }
|
||||
.u-transfer-list.u-transfer-list-with-pagination .u-transfer-list-body {
|
||||
height: calc(100% - 40px); }
|
||||
.u-transfer-list.u-transfer-list-with-pagination .u-transfer-list-body .u-transfer-list-content-item-highlight-enter {
|
||||
animation: none;
|
||||
transition: none; }
|
||||
.u-transfer-list-with-footer {
|
||||
padding-bottom: 33px; }
|
||||
.u-transfer-list-search-action {
|
||||
|
@ -109,6 +116,38 @@
|
|||
.u-transfer-list-content-item-highlight-enter {
|
||||
animation: transferHighlightIn 1s ease;
|
||||
transition: none; }
|
||||
.u-transfer-list-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
padding: 5px 0;
|
||||
justify-content: flex-end;
|
||||
border-top: 1px solid #d9d9d9; }
|
||||
.u-transfer-list-pagination-slash {
|
||||
margin: 0 10px 0 5px; }
|
||||
.u-transfer-list-pagination .u-form-control {
|
||||
width: 42px;
|
||||
height: 80%;
|
||||
background-color: #fff;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 8px;
|
||||
outline: none;
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
transition: border-color .3s; }
|
||||
.u-transfer-list-pagination span.prev-link.disabled,
|
||||
.u-transfer-list-pagination span.prev-link.disabled *,
|
||||
.u-transfer-list-pagination span.next-link.disabled,
|
||||
.u-transfer-list-pagination span.next-link.disabled * {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed; }
|
||||
.u-transfer-list-pagination .uf {
|
||||
cursor: pointer; }
|
||||
.u-transfer-list-pagination-item-highlight-enter {
|
||||
animation: none;
|
||||
transition: none; }
|
||||
.u-transfer-list-delete-selected {
|
||||
display: none;
|
||||
width: 100%;
|
||||
|
|
|
@ -59,7 +59,8 @@ var defaultProps = {
|
|||
appendToBottom: false,
|
||||
renderOperation: function renderOperation() {
|
||||
return '';
|
||||
} //自定义操作
|
||||
}, //自定义操作,
|
||||
pagination: false
|
||||
};
|
||||
|
||||
var propTypes = {
|
||||
|
@ -84,7 +85,8 @@ var propTypes = {
|
|||
showCheckbox: _propTypes2["default"].bool,
|
||||
draggable: _propTypes2["default"].bool,
|
||||
appendToBottom: _propTypes2["default"].bool,
|
||||
renderOperation: _propTypes2["default"].func
|
||||
renderOperation: _propTypes2["default"].func,
|
||||
pagination: _propTypes2["default"].bool
|
||||
};
|
||||
|
||||
var defaultTitles = ['', ''];
|
||||
|
@ -348,6 +350,7 @@ var Transfer = function (_React$Component) {
|
|||
listStyle = _props.listStyle,
|
||||
_props$className = _props.className,
|
||||
className = _props$className === undefined ? '' : _props$className,
|
||||
pagination = _props.pagination,
|
||||
filterOption = _props.filterOption,
|
||||
render = _props.render,
|
||||
lazy = _props.lazy,
|
||||
|
@ -401,7 +404,8 @@ var Transfer = function (_React$Component) {
|
|||
draggable: draggable,
|
||||
id: '1',
|
||||
droppableId: droppableId,
|
||||
draggingItemId: draggingItemId
|
||||
draggingItemId: draggingItemId,
|
||||
pagination: pagination
|
||||
}),
|
||||
!draggable ? _react2["default"].createElement(_operation2["default"], {
|
||||
rightActive: rightActive,
|
||||
|
@ -434,7 +438,8 @@ var Transfer = function (_React$Component) {
|
|||
lazy: lazy,
|
||||
showCheckbox: showCheckbox,
|
||||
draggable: draggable,
|
||||
id: '2'
|
||||
id: '2',
|
||||
pagination: pagination
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -503,8 +508,12 @@ var _initialiseProps = function _initialiseProps() {
|
|||
return _this3.moveTo('left');
|
||||
};
|
||||
|
||||
this.moveToRight = function (insertIndex) {
|
||||
return _this3.moveTo('right', insertIndex);
|
||||
this.moveToRight = function () {
|
||||
return _this3.moveTo('right');
|
||||
};
|
||||
|
||||
this.multiMoveToRight = function (insertIndex) {
|
||||
_this3.moveTo('right', insertIndex);
|
||||
};
|
||||
|
||||
this.handleSelectAll = function (direction, filteredDataSource, checkAll) {
|
||||
|
@ -640,7 +649,7 @@ var _initialiseProps = function _initialiseProps() {
|
|||
} else {
|
||||
// case5:从左往右拖拽(添加已选)
|
||||
if (_this3.state.sourceSelectedKeys.length > 1) {
|
||||
return _this3.moveToRight(destination.index);
|
||||
return _this3.multiMoveToRight(destination.index);
|
||||
}
|
||||
var _result = (0, _utils.move)( // 一次移动的方法
|
||||
_this3.getList(source.droppableId), _this3.getList(destination.droppableId), source, destination, targetKeys);
|
||||
|
|
310
build/list.js
310
build/list.js
|
@ -44,6 +44,10 @@ var _beeIcon = require('bee-icon');
|
|||
|
||||
var _beeIcon2 = _interopRequireDefault(_beeIcon);
|
||||
|
||||
var _beeFormControl = require('bee-form-control');
|
||||
|
||||
var _beeFormControl2 = _interopRequireDefault(_beeFormControl);
|
||||
|
||||
var _reactBeautifulDnd = require('react-beautiful-dnd');
|
||||
|
||||
var _tinperBeeCore = require('tinper-bee-core');
|
||||
|
@ -66,7 +70,8 @@ var defaultProps = {
|
|||
dataSource: [],
|
||||
titleText: '',
|
||||
showSearch: false,
|
||||
render: noop
|
||||
render: noop,
|
||||
pagination: false
|
||||
};
|
||||
function isRenderResultPlainObject(result) {
|
||||
return result && !_react2["default"].isValidElement(result) && Object.prototype.toString.call(result) === '[object Object]';
|
||||
|
@ -80,75 +85,20 @@ var TransferList = function (_React$Component) {
|
|||
|
||||
var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
|
||||
|
||||
_this.matchFilter = function (text, item) {
|
||||
//filter:搜索框中的内容
|
||||
//filterOption:用户自定义的搜索过滤方法
|
||||
var _this$props = _this.props,
|
||||
filter = _this$props.filter,
|
||||
filterOption = _this$props.filterOption;
|
||||
_initialiseProps.call(_this);
|
||||
|
||||
if (filterOption) {
|
||||
return filterOption(filter, item);
|
||||
}
|
||||
return text.indexOf(filter) >= 0;
|
||||
};
|
||||
|
||||
_this.handleSelect = function (selectedItem) {
|
||||
// checkedKeys:已勾选的Keys数组
|
||||
// result:是否已勾选,true:已勾选 false:未勾选
|
||||
var checkedKeys = _this.props.checkedKeys;
|
||||
|
||||
var result = checkedKeys.some(function (key) {
|
||||
return key === selectedItem.key;
|
||||
});
|
||||
_this.props.handleSelect(selectedItem, result);
|
||||
};
|
||||
|
||||
_this.handleFilter = function (e) {
|
||||
_this.props.handleFilter(e);
|
||||
};
|
||||
|
||||
_this.handleClear = function () {
|
||||
_this.props.handleClear();
|
||||
};
|
||||
|
||||
_this.renderItem = function (item) {
|
||||
var _this$props$render = _this.props.render,
|
||||
render = _this$props$render === undefined ? noop : _this$props$render;
|
||||
|
||||
var renderResult = render(item);
|
||||
var isRenderResultPlain = isRenderResultPlainObject(renderResult);
|
||||
return {
|
||||
renderedText: isRenderResultPlain ? renderResult.value : renderResult,
|
||||
renderedEl: isRenderResultPlain ? renderResult.label : renderResult
|
||||
};
|
||||
};
|
||||
|
||||
_this.onKeyDown = function (event, provided, snapshot, item) {
|
||||
if (provided.dragHandleProps) {
|
||||
provided.dragHandleProps.onKeyDown(event);
|
||||
}
|
||||
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (snapshot.isDragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.keyCode !== _tinperBeeCore.KeyCode.ENTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 为了选择,我们使用此事件 we are using the event for selection
|
||||
event.preventDefault();
|
||||
|
||||
_this.performAction(event, item);
|
||||
};
|
||||
var pagination = props.pagination;
|
||||
|
||||
var dataSource = _this.handleFilterDataSource();
|
||||
var totalPages = Math.ceil(dataSource.length / 10);
|
||||
var paginationInfo = pagination ? {
|
||||
currentPage: 1,
|
||||
totalPages: totalPages === 0 ? 1 : totalPages
|
||||
} : {};
|
||||
_this.state = {
|
||||
mounted: false
|
||||
mounted: false,
|
||||
paginationInfo: paginationInfo,
|
||||
dataSource: dataSource
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
|
@ -163,6 +113,29 @@ var TransferList = function (_React$Component) {
|
|||
}, 0);
|
||||
};
|
||||
|
||||
TransferList.prototype.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
var paginationInfo = this.state.paginationInfo;
|
||||
var pagination = nextProps.pagination;
|
||||
|
||||
var dataSource = this.handleFilterDataSource(nextProps);
|
||||
if (pagination) {
|
||||
var totalPages = Math.ceil(dataSource.length / 10);
|
||||
var currentPage = paginationInfo.currentPage;
|
||||
this.setState({
|
||||
dataSource: dataSource,
|
||||
paginationInfo: {
|
||||
totalPages: totalPages === 0 ? 1 : totalPages,
|
||||
currentPage: totalPages === 0 ? 1 : currentPage && totalPages && totalPages < currentPage ? totalPages : currentPage // 在最后一页移除元素之后,当前页设置为最后一页
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
dataSource: dataSource
|
||||
});
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
TransferList.prototype.componentWillUnmount = function componentWillUnmount() {
|
||||
clearTimeout(this.timer);
|
||||
};
|
||||
|
@ -233,12 +206,12 @@ var TransferList = function (_React$Component) {
|
|||
|
||||
var _props = this.props,
|
||||
prefixCls = _props.prefixCls,
|
||||
dataSource = _props.dataSource,
|
||||
titleText = _props.titleText,
|
||||
filter = _props.filter,
|
||||
checkedKeys = _props.checkedKeys,
|
||||
lazy = _props.lazy,
|
||||
filterOption = _props.filterOption,
|
||||
pagination = _props.pagination,
|
||||
_props$body = _props.body,
|
||||
body = _props$body === undefined ? noop : _props$body,
|
||||
_props$footer = _props.footer,
|
||||
|
@ -258,14 +231,23 @@ var TransferList = function (_React$Component) {
|
|||
|
||||
// Custom Layout
|
||||
|
||||
var _state = this.state,
|
||||
paginationInfo = _state.paginationInfo,
|
||||
dataSource = _state.dataSource;
|
||||
|
||||
var footerDom = footer((0, _objectAssign2["default"])({}, this.props));
|
||||
var bodyDom = body((0, _objectAssign2["default"])({}, this.props));
|
||||
|
||||
var listCls = (0, _classnames2["default"])(prefixCls, (_classNames2 = {}, _defineProperty(_classNames2, prefixCls + '-with-footer', !!footerDom), _defineProperty(_classNames2, prefixCls + '-draggable', !!draggable), _classNames2));
|
||||
|
||||
var listCls = (0, _classnames2["default"])(prefixCls, (_classNames2 = {}, _defineProperty(_classNames2, prefixCls + '-with-footer', !!footerDom), _defineProperty(_classNames2, prefixCls + '-draggable', !!draggable), _defineProperty(_classNames2, prefixCls + '-with-pagination', !!pagination), _classNames2));
|
||||
var filteredDataSource = [];
|
||||
var totalDataSource = [];
|
||||
var showItems = dataSource.map(function (item, index) {
|
||||
var totalDataSource = pagination ? dataSource : [];
|
||||
var splitedDataSource = !pagination ? dataSource.concat() : dataSource.slice(10 * (paginationInfo.currentPage - 1), 10 * paginationInfo.currentPage);
|
||||
if (pagination) {
|
||||
filteredDataSource = dataSource.filter(function (item) {
|
||||
return !item.disabled;
|
||||
});
|
||||
}
|
||||
var showItems = splitedDataSource.map(function (item, index) {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
@ -274,14 +256,14 @@ var TransferList = function (_React$Component) {
|
|||
renderedText = _renderItem.renderedText,
|
||||
renderedEl = _renderItem.renderedEl;
|
||||
|
||||
if (filter && filter.trim() && !_this4.matchFilter(renderedText, item)) {
|
||||
return null;
|
||||
// all show items
|
||||
|
||||
|
||||
if (!pagination) {
|
||||
totalDataSource.push(item);
|
||||
}
|
||||
|
||||
// all show items
|
||||
totalDataSource.push(item);
|
||||
|
||||
if (!item.disabled) {
|
||||
if (!item.disabled && !pagination) {
|
||||
filteredDataSource.push(item);
|
||||
}
|
||||
|
||||
|
@ -391,6 +373,7 @@ var TransferList = function (_React$Component) {
|
|||
);
|
||||
}
|
||||
),
|
||||
pagination ? this.createListPagination() : null,
|
||||
_react2["default"].createElement(
|
||||
'div',
|
||||
{ className: prefixCls + '-body-not-found ' + (dataSource.length == 0 ? "show" : "") },
|
||||
|
@ -445,6 +428,177 @@ var TransferList = function (_React$Component) {
|
|||
return TransferList;
|
||||
}(_react2["default"].Component);
|
||||
|
||||
var _initialiseProps = function _initialiseProps() {
|
||||
var _this5 = this;
|
||||
|
||||
this.matchFilter = function (text, item, filter, filterOption) {
|
||||
//filter:搜索框中的内容
|
||||
//filterOption:用户自定义的搜索过滤方法
|
||||
if (filterOption) {
|
||||
return filterOption(filter, item);
|
||||
}
|
||||
return text.indexOf(filter) >= 0;
|
||||
};
|
||||
|
||||
this.handleSelect = function (selectedItem) {
|
||||
// checkedKeys:已勾选的Keys数组
|
||||
// result:是否已勾选,true:已勾选 false:未勾选
|
||||
var checkedKeys = _this5.props.checkedKeys;
|
||||
|
||||
var result = checkedKeys.some(function (key) {
|
||||
return key === selectedItem.key;
|
||||
});
|
||||
_this5.props.handleSelect(selectedItem, result);
|
||||
};
|
||||
|
||||
this.handleFilter = function (e) {
|
||||
_this5.props.handleFilter(e);
|
||||
};
|
||||
|
||||
this.handleClear = function () {
|
||||
_this5.props.handleClear();
|
||||
};
|
||||
|
||||
this.renderItem = function (item) {
|
||||
var _props$render2 = _this5.props.render,
|
||||
render = _props$render2 === undefined ? noop : _props$render2;
|
||||
|
||||
var renderResult = render(item);
|
||||
var isRenderResultPlain = isRenderResultPlainObject(renderResult);
|
||||
return {
|
||||
renderedText: isRenderResultPlain ? renderResult.value : renderResult,
|
||||
renderedEl: isRenderResultPlain ? renderResult.label : renderResult
|
||||
};
|
||||
};
|
||||
|
||||
this.onKeyDown = function (event, provided, snapshot, item) {
|
||||
if (provided.dragHandleProps) {
|
||||
provided.dragHandleProps.onKeyDown(event);
|
||||
}
|
||||
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (snapshot.isDragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.keyCode !== _tinperBeeCore.KeyCode.ENTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 为了选择,我们使用此事件 we are using the event for selection
|
||||
event.preventDefault();
|
||||
|
||||
_this5.performAction(event, item);
|
||||
};
|
||||
|
||||
this.handleChangePage = function (value) {
|
||||
var val = +value;
|
||||
var paginationInfo = _this5.state.paginationInfo;
|
||||
|
||||
if (Number.isNaN(val) || typeof val !== 'number' || val % 1 !== 0) {
|
||||
return;
|
||||
}
|
||||
if (val > paginationInfo.totalPages) {
|
||||
val = paginationInfo.totalPages;
|
||||
}
|
||||
if (val < 1) {
|
||||
val = 1;
|
||||
}
|
||||
_this5.setState({
|
||||
paginationInfo: _extends({}, paginationInfo, {
|
||||
currentPage: val
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
this.handleMove = function (step) {
|
||||
var _state$paginationInfo = _this5.state.paginationInfo,
|
||||
currentPage = _state$paginationInfo.currentPage,
|
||||
totalPages = _state$paginationInfo.totalPages;
|
||||
|
||||
var newCurrentPage = currentPage + step;
|
||||
if (newCurrentPage < 1 || newCurrentPage > totalPages) {
|
||||
return;
|
||||
}
|
||||
_this5.setState({
|
||||
paginationInfo: {
|
||||
totalPages: totalPages,
|
||||
currentPage: newCurrentPage
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.createListPagination = function () {
|
||||
var prefixCls = _this5.props.prefixCls;
|
||||
var paginationInfo = _this5.state.paginationInfo;
|
||||
var currentPage = paginationInfo.currentPage,
|
||||
totalPages = paginationInfo.totalPages;
|
||||
|
||||
return _react2["default"].createElement(
|
||||
'div',
|
||||
{ className: prefixCls + '-pagination' },
|
||||
_react2["default"].createElement(
|
||||
'span',
|
||||
{
|
||||
onClick: function onClick() {
|
||||
return _this5.handleMove(-1);
|
||||
},
|
||||
className: 'prev-link ' + (currentPage === 1 ? 'disabled' : '')
|
||||
},
|
||||
_react2["default"].createElement(_beeIcon2["default"], { type: 'uf-arrow-left' })
|
||||
),
|
||||
_react2["default"].createElement(_beeFormControl2["default"], {
|
||||
size: 'sm',
|
||||
value: currentPage,
|
||||
ref: 'input',
|
||||
onChange: _this5.handleChangePage
|
||||
}),
|
||||
_react2["default"].createElement(
|
||||
'span',
|
||||
{
|
||||
className: prefixCls + '-pagination-slash'
|
||||
},
|
||||
'/'
|
||||
),
|
||||
_react2["default"].createElement(
|
||||
'span',
|
||||
null,
|
||||
totalPages
|
||||
),
|
||||
_react2["default"].createElement(
|
||||
'span',
|
||||
{
|
||||
onClick: function onClick() {
|
||||
return _this5.handleMove(1);
|
||||
},
|
||||
className: 'next-link ' + (currentPage === totalPages ? 'disabled' : '')
|
||||
},
|
||||
_react2["default"].createElement(_beeIcon2["default"], { type: 'uf-arrow-right' })
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
this.handleFilterDataSource = function (nextProps) {
|
||||
var _ref2 = nextProps || _this5.props,
|
||||
dataSource = _ref2.dataSource,
|
||||
filter = _ref2.filter,
|
||||
filterOption = _ref2.filterOption;
|
||||
|
||||
return dataSource.filter(function (data) {
|
||||
var _renderItem2 = _this5.renderItem(data),
|
||||
renderedText = _renderItem2.renderedText;
|
||||
|
||||
if (filter && filter.trim() && !_this5.matchFilter(renderedText, data, filter, filterOption)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
TransferList.defaultProps = defaultProps;
|
||||
exports["default"] = TransferList;
|
||||
module.exports = exports['default'];
|
|
@ -1,18 +1,18 @@
|
|||
/**
|
||||
*
|
||||
* @title 常用可选transfer
|
||||
* @description targetKeys需要通过ES6的扩展运算符进行赋值,实现对象的深拷贝
|
||||
*
|
||||
*/
|
||||
*
|
||||
* @title 默认的模态框
|
||||
* @description
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import Button from 'bee-button';
|
||||
import Transfer from '../../src';
|
||||
import React, { Component } from 'react';
|
||||
import Button from 'bee-button'
|
||||
import Modal from 'bee-modal'
|
||||
import Transfer from '../../src'
|
||||
|
||||
const AllTargetKeys = [];
|
||||
const mockData = [];
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const mockData = [];
|
||||
for (let i = 0; i < 12000; i++) {
|
||||
mockData.push({
|
||||
key: i.toString(),
|
||||
title: `content${i + 1}`,
|
||||
|
@ -21,20 +21,25 @@ for (let i = 0; i < 20; i++) {
|
|||
|
||||
});
|
||||
AllTargetKeys.push(i.toString());
|
||||
}
|
||||
|
||||
const targetKeys = mockData
|
||||
}
|
||||
const targetKeys = mockData
|
||||
.filter(item => +item.key % 3 > 1)
|
||||
.map(item => item.key);
|
||||
|
||||
class Demo1 extends React.Component {
|
||||
state = {
|
||||
class Demo1 extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
targetKeys,
|
||||
selectedKeys: [],
|
||||
showModal: false,
|
||||
modalSize: ''
|
||||
};
|
||||
this.close = this.close.bind(this);
|
||||
this.open = this.open.bind(this);
|
||||
}
|
||||
|
||||
|
||||
handleChange = (nextTargetKeys, direction, moveKeys) => {
|
||||
this.setState({ targetKeys: nextTargetKeys });
|
||||
|
||||
|
@ -66,14 +71,38 @@ class Demo1 extends React.Component {
|
|||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
close() {
|
||||
this.setState({
|
||||
showModal: false
|
||||
});
|
||||
}
|
||||
open() {
|
||||
this.setState({
|
||||
showModal: true
|
||||
});
|
||||
}
|
||||
render () {
|
||||
const state = this.state;
|
||||
const targetKeys = [...this.state.targetKeys];
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={this.moveAllToRight} style={{margin:'8px'}}>全部移到右边</Button>
|
||||
<Button onClick={this.moveAllToLeft} style={{margin:'8px'}}>全部移到左边</Button>
|
||||
<Button
|
||||
bordered
|
||||
className="demo-margin"
|
||||
onClick = { this.open }>
|
||||
打开模态框
|
||||
</Button>
|
||||
<Modal
|
||||
show = { this.state.showModal }
|
||||
onHide = { this.close } >
|
||||
<Modal.Header closeButton closeButtonProps={{fieldId:'closeBtn'}}>
|
||||
<Modal.Title>标题</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<Transfer
|
||||
pagination
|
||||
dataSource={mockData}
|
||||
titles={['Source', 'Target']}
|
||||
targetKeys={targetKeys}
|
||||
|
@ -82,11 +111,17 @@ class Demo1 extends React.Component {
|
|||
onSelectChange={this.handleSelectChange}
|
||||
onScroll={this.handleScroll}
|
||||
render={item => item.title}
|
||||
lazy
|
||||
/>
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button onClick={ this.close } colors="secondary" style={{marginRight: 8}}>取消</Button>
|
||||
<Button onClick={ this.close } bordered>确认</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Demo1
|
||||
export default Demo1;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -16,6 +16,13 @@
|
|||
padding-top: 33px; }
|
||||
.u-transfer-list.u-transfer-list-draggable:first-child {
|
||||
margin-right: 16px; }
|
||||
.u-transfer-list.u-transfer-list-with-pagination {
|
||||
height: 240px; }
|
||||
.u-transfer-list.u-transfer-list-with-pagination .u-transfer-list-body {
|
||||
height: calc(100% - 40px); }
|
||||
.u-transfer-list.u-transfer-list-with-pagination .u-transfer-list-body .u-transfer-list-content-item-highlight-enter {
|
||||
animation: none;
|
||||
transition: none; }
|
||||
.u-transfer-list-with-footer {
|
||||
padding-bottom: 33px; }
|
||||
.u-transfer-list-search-action {
|
||||
|
@ -109,6 +116,41 @@
|
|||
.u-transfer-list-content-item-highlight-enter {
|
||||
animation: transferHighlightIn 1s ease;
|
||||
transition: none; }
|
||||
.u-transfer-list-pagination {
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
padding: 5px 0;
|
||||
-ms-flex-pack: end;
|
||||
justify-content: flex-end;
|
||||
border-top: 1px solid #d9d9d9; }
|
||||
.u-transfer-list-pagination-slash {
|
||||
margin: 0 10px 0 5px; }
|
||||
.u-transfer-list-pagination .u-form-control {
|
||||
width: 42px;
|
||||
height: 80%;
|
||||
background-color: #fff;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 8px;
|
||||
outline: none;
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
transition: border-color .3s; }
|
||||
.u-transfer-list-pagination span.prev-link.disabled,
|
||||
.u-transfer-list-pagination span.prev-link.disabled *,
|
||||
.u-transfer-list-pagination span.next-link.disabled,
|
||||
.u-transfer-list-pagination span.next-link.disabled * {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed; }
|
||||
.u-transfer-list-pagination .uf {
|
||||
cursor: pointer; }
|
||||
.u-transfer-list-pagination-item-highlight-enter {
|
||||
animation: none;
|
||||
transition: none; }
|
||||
.u-transfer-list-delete-selected {
|
||||
display: none;
|
||||
width: 100%;
|
||||
|
|
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
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "bee-transfer",
|
||||
"version": "2.0.20",
|
||||
"version": "2.0.21-beta.2",
|
||||
"description": "Transfer ui component for react",
|
||||
"keywords": [
|
||||
"react",
|
||||
|
|
|
@ -18,7 +18,8 @@ const defaultProps = {
|
|||
showCheckbox: true,
|
||||
draggable: false,
|
||||
appendToBottom: false,
|
||||
renderOperation:()=>'',//自定义操作
|
||||
renderOperation:()=>'',//自定义操作,
|
||||
pagination: false
|
||||
};
|
||||
|
||||
const propTypes = {
|
||||
|
@ -43,7 +44,8 @@ const propTypes = {
|
|||
showCheckbox: PropTypes.bool,
|
||||
draggable: PropTypes.bool,
|
||||
appendToBottom: PropTypes.bool,
|
||||
renderOperation:PropTypes.func
|
||||
renderOperation:PropTypes.func,
|
||||
pagination: PropTypes.bool
|
||||
};
|
||||
|
||||
const defaultTitles = ['', ''];
|
||||
|
@ -222,7 +224,11 @@ class Transfer extends React.Component{
|
|||
}
|
||||
|
||||
moveToLeft = () => this.moveTo('left')
|
||||
moveToRight = insertIndex => this.moveTo('right', insertIndex)
|
||||
moveToRight = () => this.moveTo('right')
|
||||
|
||||
multiMoveToRight = insertIndex => {
|
||||
this.moveTo('right', insertIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* List中的item选中/未选中状态改变时触发
|
||||
|
@ -390,7 +396,7 @@ class Transfer extends React.Component{
|
|||
}
|
||||
} else { // case5:从左往右拖拽(添加已选)
|
||||
if (this.state.sourceSelectedKeys.length > 1) {
|
||||
return this.moveToRight(destination.index)
|
||||
return this.multiMoveToRight(destination.index)
|
||||
}
|
||||
const result = move( // 一次移动的方法
|
||||
this.getList(source.droppableId),
|
||||
|
@ -432,7 +438,7 @@ class Transfer extends React.Component{
|
|||
render() {
|
||||
const {
|
||||
prefixCls = 'u-transfer', operations = [], showSearch, notFoundContent,
|
||||
searchPlaceholder, body, footer, listStyle, className = '',
|
||||
searchPlaceholder, body, footer, listStyle, className = '', pagination,
|
||||
filterOption, render, lazy, showCheckbox, draggable,renderOperation
|
||||
} = this.props;
|
||||
const { leftFilter, rightFilter, sourceSelectedKeys, targetSelectedKeys, leftDataSource, rightDataSource, droppableId, draggingItemId } = this.state;
|
||||
|
@ -471,6 +477,7 @@ class Transfer extends React.Component{
|
|||
id={'1'}
|
||||
droppableId={droppableId}
|
||||
draggingItemId={draggingItemId}
|
||||
pagination={pagination}
|
||||
/>
|
||||
{!draggable?
|
||||
<Operation
|
||||
|
@ -507,6 +514,7 @@ class Transfer extends React.Component{
|
|||
showCheckbox={showCheckbox}
|
||||
draggable={draggable}
|
||||
id={'2'}
|
||||
pagination={pagination}
|
||||
/>
|
||||
</DragDropContext>
|
||||
</div>
|
||||
|
|
|
@ -27,6 +27,19 @@
|
|||
margin-right: 16px;
|
||||
}
|
||||
|
||||
&.u-transfer-list-with-pagination {
|
||||
height: 240px;
|
||||
|
||||
.u-transfer-list-body {
|
||||
height: calc(100% - 40px);
|
||||
|
||||
.u-transfer-list-content-item-highlight-enter {
|
||||
animation: none;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-with-footer {
|
||||
padding-bottom: 33px;
|
||||
}
|
||||
|
@ -152,6 +165,50 @@
|
|||
transition: none;
|
||||
}
|
||||
}
|
||||
&-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
padding: 5px 0;
|
||||
justify-content: flex-end;
|
||||
border-top: 1px solid #d9d9d9;
|
||||
|
||||
&-slash {
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
|
||||
.u-form-control {
|
||||
width: 42px;
|
||||
height: 80%;
|
||||
background-color: #fff;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 8px;
|
||||
outline: none;
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
transition: border-color .3s;
|
||||
}
|
||||
|
||||
span.prev-link,
|
||||
span.next-link {
|
||||
&.disabled,
|
||||
&.disabled * {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.uf {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-item-highlight-enter {
|
||||
animation: none;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
&-delete-selected{
|
||||
display: none;
|
||||
width: 100%;
|
||||
|
|
135
src/list.js
135
src/list.js
|
@ -8,6 +8,7 @@ import { TransferItem } from './index';
|
|||
import Item from './item';
|
||||
import Checkbox from 'bee-checkbox';
|
||||
import Icon from 'bee-icon';
|
||||
import FormControl from 'bee-form-control';
|
||||
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
||||
import { KeyCode} from 'tinper-bee-core';
|
||||
|
||||
|
@ -19,6 +20,7 @@ const defaultProps = {
|
|||
titleText: '',
|
||||
showSearch: false,
|
||||
render: noop,
|
||||
pagination: false
|
||||
};
|
||||
function isRenderResultPlainObject(result) {
|
||||
return result && !React.isValidElement(result) &&
|
||||
|
@ -29,8 +31,17 @@ class TransferList extends React.Component {
|
|||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { pagination } = props
|
||||
const dataSource = this.handleFilterDataSource()
|
||||
const totalPages = Math.ceil(dataSource.length / 10)
|
||||
const paginationInfo = pagination ? {
|
||||
currentPage: 1,
|
||||
totalPages: totalPages === 0 ? 1 : totalPages
|
||||
} : {}
|
||||
this.state = {
|
||||
mounted: false,
|
||||
paginationInfo,
|
||||
dataSource
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -42,6 +53,28 @@ class TransferList extends React.Component {
|
|||
}, 0);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
const { paginationInfo } = this.state
|
||||
const { pagination } = nextProps
|
||||
const dataSource = this.handleFilterDataSource(nextProps)
|
||||
if (pagination) {
|
||||
const totalPages = Math.ceil(dataSource.length / 10)
|
||||
const currentPage = paginationInfo.currentPage
|
||||
this.setState({
|
||||
dataSource,
|
||||
paginationInfo: {
|
||||
totalPages: totalPages === 0 ? 1 : totalPages,
|
||||
currentPage: totalPages === 0 ? 1 : (currentPage && totalPages && totalPages < currentPage) ? totalPages : currentPage // 在最后一页移除元素之后,当前页设置为最后一页
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
dataSource
|
||||
})
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
|
@ -51,10 +84,9 @@ class TransferList extends React.Component {
|
|||
}
|
||||
|
||||
|
||||
matchFilter = (text,item) => {
|
||||
matchFilter = (text,item,filter,filterOption) => {
|
||||
//filter:搜索框中的内容
|
||||
//filterOption:用户自定义的搜索过滤方法
|
||||
const { filter, filterOption} = this.props;
|
||||
if (filterOption) {
|
||||
return filterOption(filter, item);
|
||||
}
|
||||
|
@ -146,34 +178,112 @@ class TransferList extends React.Component {
|
|||
this.performAction(event,item);
|
||||
};
|
||||
|
||||
handleChangePage = value => {
|
||||
let val = +value
|
||||
const { paginationInfo } = this.state
|
||||
if (Number.isNaN(val) || typeof val !== 'number' || val % 1 !== 0) {
|
||||
return
|
||||
}
|
||||
if (val > paginationInfo.totalPages) {
|
||||
val = paginationInfo.totalPages
|
||||
}
|
||||
if (val < 1) {
|
||||
val = 1
|
||||
}
|
||||
this.setState({
|
||||
paginationInfo: {
|
||||
...paginationInfo,
|
||||
currentPage: val
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
handleMove = step => {
|
||||
const { currentPage, totalPages } = this.state.paginationInfo
|
||||
const newCurrentPage = currentPage + step
|
||||
if (newCurrentPage < 1 || newCurrentPage > totalPages) {
|
||||
return
|
||||
}
|
||||
this.setState({
|
||||
paginationInfo: {
|
||||
totalPages,
|
||||
currentPage: newCurrentPage
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
createListPagination = () => {
|
||||
const { prefixCls } = this.props
|
||||
const { paginationInfo } = this.state
|
||||
const { currentPage, totalPages } = paginationInfo
|
||||
return <div className={`${prefixCls}-pagination`}>
|
||||
<span
|
||||
onClick={() => this.handleMove(-1)}
|
||||
className={`prev-link ${currentPage === 1 ? 'disabled' : ''}`}
|
||||
>
|
||||
<Icon type="uf-arrow-left" />
|
||||
</span>
|
||||
<FormControl
|
||||
size="sm"
|
||||
value={currentPage}
|
||||
ref="input"
|
||||
onChange={this.handleChangePage}
|
||||
/>
|
||||
<span
|
||||
className={`${prefixCls}-pagination-slash`}
|
||||
>/</span>
|
||||
<span>{totalPages}</span>
|
||||
<span
|
||||
onClick={() => this.handleMove(1)}
|
||||
className={`next-link ${currentPage === totalPages ? 'disabled' : ''}`}
|
||||
>
|
||||
<Icon type="uf-arrow-right" />
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
handleFilterDataSource = (nextProps) => {
|
||||
const { dataSource, filter, filterOption } = nextProps || this.props
|
||||
return dataSource.filter(data => {
|
||||
const { renderedText } = this.renderItem(data);
|
||||
if (filter && filter.trim() && !this.matchFilter(renderedText, data, filter, filterOption)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, dataSource, titleText, filter, checkedKeys, lazy, filterOption,
|
||||
const { prefixCls, titleText, filter, checkedKeys, lazy, filterOption, pagination,
|
||||
body = noop, footer = noop, showSearch, render = noop, style, id, showCheckbox, draggable, droppableId, draggingItemId } = this.props;
|
||||
let { searchPlaceholder, notFoundContent } = this.props;
|
||||
|
||||
// Custom Layout
|
||||
const { paginationInfo, dataSource } = this.state
|
||||
const footerDom = footer(assign({}, this.props));
|
||||
const bodyDom = body(assign({}, this.props));
|
||||
|
||||
const listCls = classNames(prefixCls, {
|
||||
[`${prefixCls}-with-footer`]: !!footerDom,
|
||||
[`${prefixCls}-draggable`]: !!draggable
|
||||
[`${prefixCls}-draggable`]: !!draggable,
|
||||
[`${prefixCls}-with-pagination`]: !!pagination
|
||||
});
|
||||
|
||||
const filteredDataSource = [];
|
||||
const totalDataSource = [];
|
||||
const showItems = dataSource.map((item,index) => {
|
||||
let filteredDataSource = [];
|
||||
const totalDataSource = pagination ? dataSource : [];
|
||||
const splitedDataSource = !pagination ? dataSource.concat() : dataSource.slice(10 * (paginationInfo.currentPage - 1), 10 * paginationInfo.currentPage)
|
||||
if (pagination) {
|
||||
filteredDataSource = dataSource.filter(item => !item.disabled)
|
||||
}
|
||||
const showItems = splitedDataSource.map((item,index) => {
|
||||
if(!item){return}
|
||||
const { renderedText, renderedEl } = this.renderItem(item);
|
||||
if (filter && filter.trim() && !this.matchFilter(renderedText, item)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// all show items
|
||||
if (!pagination) {
|
||||
totalDataSource.push(item);
|
||||
}
|
||||
|
||||
if (!item.disabled) {
|
||||
if (!item.disabled && !pagination) {
|
||||
filteredDataSource.push(item);
|
||||
}
|
||||
|
||||
|
@ -262,6 +372,7 @@ class TransferList extends React.Component {
|
|||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
{pagination ? this.createListPagination() : null}
|
||||
<div className={`${prefixCls}-body-not-found ${dataSource.length == 0? "show" : ""}`}>
|
||||
{notFoundContent}
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue