Compare commits

...

5 Commits

Author SHA1 Message Date
gx 598e883c9c fix: build 2021-06-01 15:28:29 +08:00
gx 0c824495a1 fix: 分页情况下的搜索功能修改 2021-06-01 15:26:44 +08:00
gx af7f18c7d4 fix: 去掉console 2021-05-28 21:19:34 +08:00
gx 95d92db03f fix: build 2021-05-28 13:52:50 +08:00
gx df35554b5e fix: 增加分页功能 2021-05-28 13:51:27 +08:00
13 changed files with 1659 additions and 829 deletions

View File

@ -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%;

View File

@ -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);

View File

@ -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'];

View File

@ -1,92 +1,127 @@
/**
*
* @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++) {
mockData.push({
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
disabled: i % 3 < 1,
const mockData = [];
for (let i = 0; i < 12000; i++) {
mockData.push({
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
disabled: i % 3 < 1,
});
AllTargetKeys.push(i.toString());
}
const targetKeys = mockData
});
AllTargetKeys.push(i.toString());
}
const targetKeys = mockData
.filter(item => +item.key % 3 > 1)
.map(item => item.key);
class Demo1 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);
}
moveAllToRight = () => {
this.setState({
targetKeys: AllTargetKeys
})
}
moveAllToLeft = () => {
this.setState({
targetKeys: []
})
}
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>
<Transfer
dataSource={mockData}
titles={['Source', 'Target']}
targetKeys={targetKeys}
selectedKeys={state.selectedKeys}
onChange={this.handleChange}
onSelectChange={this.handleSelectChange}
onScroll={this.handleScroll}
render={item => item.title}
/>
</div>
);
}
}
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);
}
export default Demo1
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);
}
moveAllToRight = () => {
this.setState({
targetKeys: AllTargetKeys
})
}
moveAllToLeft = () => {
this.setState({
targetKeys: []
})
}
close() {
this.setState({
showModal: false
});
}
open() {
this.setState({
showModal: true
});
}
render () {
const state = this.state;
const targetKeys = [...this.state.targetKeys];
return (
<div>
<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}
selectedKeys={state.selectedKeys}
onChange={this.handleChange}
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;

File diff suppressed because one or more lines are too long

42
dist/demo.css vendored
View File

@ -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%;

2
dist/demo.css.map vendored

File diff suppressed because one or more lines are too long

1655
dist/demo.js vendored

File diff suppressed because one or more lines are too long

2
dist/demo.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -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",

View File

@ -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>

View File

@ -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%;

View File

@ -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
totalDataSource.push(item);
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>