@6thquake/react-material
Version:
React components that implement Google's Material Design.
440 lines (390 loc) • 12.7 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
/**
* @ignore - do not document.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { ChevronRight, ChevronLeft, LastPage, FirstPage } from '@material-ui/icons';
import withStyles from '../styles/withStyles';
import List from '../List';
import ListItem from '../ListItem';
import ListItemText from '../ListItemText';
import Checkbox from '../Checkbox';
import Button from '../Button';
import SelectFilter from './SelectFilter';
import Pagination from '../Pagination';
import Divider from '../Divider';
import { debounce } from '../utils/throttle';
const styles = {
root: {
minWidth: '700px',
height: '100%',
minHeight: '300px',
width: '100%',
position: 'relative'
},
lists: {
height: '100%',
maxHeight: '400px',
overflow: 'scroll',
display: 'inline-block',
border: '1px solid rgba(0,0,0,0.1)',
width: '45%',
minWidth: '300px',
maxWidth: '300px',
position: 'absolute'
},
dataSourceLists: {},
targetKeysLists: {
right: '0',
top: '0'
},
btngrp: {
position: 'absolute',
width: '100%',
textAlign: 'center',
top: '50%',
transform: 'translateY(-50%)'
},
devideDataSource: {
position: 'absolute',
top: '250px',
left: '0',
width: '100%'
},
devidetargetKeys: {
position: 'absolute',
top: '250px',
right: '0',
width: '100%'
},
paginationDataSource: {
position: 'absolute',
top: '240px ',
left: '0',
width: '100%'
},
paginationtargetKeys: {
position: 'absolute',
top: '240px',
right: '0',
width: '100%'
}
};
var _ref = React.createElement(LastPage, null);
var _ref2 = React.createElement("br", null);
var _ref3 = React.createElement(ChevronRight, null);
var _ref4 = React.createElement("br", null);
var _ref5 = React.createElement(ChevronLeft, null);
var _ref6 = React.createElement("br", null);
var _ref7 = React.createElement(FirstPage, null);
class Transfer extends React.Component {
constructor(props) {
super(props);
this.subSet = (arr1, arr2) => {
const set1 = new Set(arr1);
const set2 = new Set(arr2);
const subset = [];
for (const item of set1) {
if (!set2.has(item)) {
subset.push(item);
}
}
return subset;
};
this.transferToggle = position => () => {
// 左右移动选中部分
const {
dataSourceChecked,
targetKeysChecked
} = this.state;
const _checked = position === 'left' ? dataSourceChecked : position === 'right' ? targetKeysChecked : '';
const _otherPos = position === 'left' ? 'right' : 'left';
const chooseBox = position === 'left' ? 'dataSource' : 'targetKeys';
const otherBox = position === 'left' ? 'targetKeys' : 'dataSource';
const sub = this.subSet(this.props[chooseBox], _checked);
const newData = {};
newData[chooseBox] = sub;
newData[otherBox] = [].concat(this.props[otherBox], _checked);
this.props.onChange(newData.dataSource, newData.targetKeys);
this.setState({
dataSourceChecked: [],
targetKeysChecked: [],
temp: {
dataSource: [...newData.dataSource],
targetKeys: [...newData.targetKeys]
},
pageConfigDataSource: _extends({}, this.props.pageConfig, {
count: newData.dataSource.length
}),
pageConfigtargetKeys: _extends({}, this.props.pageConfig, {
count: newData.targetKeys.length
})
});
};
this.transferAllToggle = position => () => {
// 左右移动所有
const {
dataSource,
targetKeys
} = this.props;
const _checked = position === 'left' ? dataSource : position === 'right' ? targetKeys : '';
const _otherPos = position === 'left' ? 'right' : 'left';
const chooseBox = position === 'left' ? 'dataSource' : 'targetKeys';
const otherBox = position === 'left' ? 'targetKeys' : 'dataSource';
const sub = this.subSet(this.props[chooseBox], _checked);
const newData = {};
newData[chooseBox] = sub;
newData[otherBox] = [].concat(this.props[otherBox], _checked);
this.props.onChange(newData.dataSource, newData.targetKeys);
this.setState({
dataSourceChecked: [],
targetKeysChecked: [],
temp: {
dataSource: [...newData.dataSource],
targetKeys: [...newData.targetKeys]
},
pageConfigDataSource: _extends({}, this.props.pageConfig, {
count: newData.dataSource.length
}),
pageConfigtargetKeys: _extends({}, this.props.pageConfig, {
count: newData.targetKeys.length
})
});
};
this.handleToggle = (value, position) => () => {
const {
dataSourceChecked,
targetKeysChecked
} = this.state;
const _checked = position === 'left' ? dataSourceChecked : position === 'right' ? targetKeysChecked : '';
const currentIndex = _checked.indexOf(value);
const newChecked = [..._checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
if (position === 'left') {
this.setState({
dataSourceChecked: newChecked
});
}
if (position === 'right') {
this.setState({
targetKeysChecked: newChecked
});
}
};
this.textchange = position => e => {
const chooseBox = position === 'left' ? 'dataSource' : 'targetKeys';
const otherBox = position === 'left' ? 'targetKeys' : 'dataSource';
const filterString = e.target.value;
const filterData = this.props[chooseBox].filter(item => {
return !filterString || item.name.toLowerCase().indexOf(filterString.toLowerCase()) !== -1;
});
const newData = {};
newData[chooseBox] = filterData;
newData[otherBox] = this.state.temp[otherBox];
if (chooseBox === 'dataSource') {
this.setState({
temp: newData,
pageConfigDataSource: _extends({}, this.props.pageConfig, {
page: 0,
count: newData.dataSource.length
})
});
} else if (chooseBox === 'targetKeys') {
this.setState({
temp: newData,
pageConfigtargetKeys: _extends({}, this.props.pageConfig, {
page: 0,
count: newData.targetKeys.length
})
});
}
};
this.state = {
dataSourceChecked: [],
// 左边选中的item
targetKeysChecked: [],
temp: {
dataSource: props.dataSource,
// 左边渲染的数据
targetKeys: props.targetKeys
},
pageConfigDataSource: {
page: props.pageConfig.page || 0,
rowsPerPage: props.pageConfig.rowsPerPage || 5,
count: props.pageConfig.count || 5
},
// 左边的分页参数
pageConfigtargetKeys: {
page: props.pageConfig.page || 0,
rowsPerPage: props.pageConfig.rowsPerPage || 5,
count: props.pageConfig.count || 5
}
};
} // 数组去重
pageCallbackFndataSource(currentPage1) {
// 左边的分页参数改变回调
this.setState({
pageConfigDataSource: _extends({}, this.state.pageConfigDataSource, {
page: currentPage1
})
});
}
pageCallbackFntargetKeys(currentPage1) {
this.setState({
pageConfigtargetKeys: _extends({}, this.state.pageConfigtargetKeys, {
page: currentPage1
})
});
}
listItem(options, pageConfig) {
// 只渲染属于该页面的item
if (Array.isArray(options)) {
const start = pageConfig.page * pageConfig.rowsPerPage;
const end = (pageConfig.page + 1) * pageConfig.rowsPerPage > options.length ? options.length : (pageConfig.page + 1) * pageConfig.rowsPerPage;
return options.slice(start, end);
}
throw new Error('React-Material: the `options` property must be an array ');
}
render() {
const {
classes,
showSearch,
searchPlaceholder,
pageConfig,
debounceProps
} = this.props;
let showPagination = false;
if (pageConfig) {
showPagination = true;
}
return React.createElement("div", {
className: classes.root
}, React.createElement("div", {
className: classes.btngrp
}, React.createElement(Button, {
color: "primary",
onClick: this.transferAllToggle('left')
}, _ref), _ref2, React.createElement(Button, {
color: "primary",
onClick: this.transferToggle('left')
}, _ref3), _ref4, React.createElement(Button, {
color: "primary",
onClick: this.transferToggle('right')
}, _ref5), _ref6, React.createElement(Button, {
color: "primary",
onClick: this.transferAllToggle('right')
}, _ref7)), React.createElement("div", {
className: `${classes.lists} ${classes.dataSourceLists}`
}, React.createElement(List, null, showSearch && React.createElement(SelectFilter, {
fullWidth: true,
autoFocus: true,
placeholder: searchPlaceholder,
onChange: debounce(this.textchange('left'), debounceProps.wait).bind(this)
}), this.listItem(this.state.temp.dataSource, this.state.pageConfigDataSource).map(value => React.createElement(ListItem, {
key: value.id,
role: undefined,
dense: true,
button: true,
onClick: this.handleToggle(value, 'left')
}, React.createElement(Checkbox, {
checked: this.state.dataSourceChecked.indexOf(value) !== -1,
tabIndex: -1,
disableRipple: true
}), React.createElement(ListItemText, {
primary: `${value.name}`
}))), React.createElement(Divider, {
className: classes.devideDataSource
}), showPagination && React.createElement("div", {
className: classes.paginationDataSource
}, React.createElement(Pagination, _extends({}, this.state.pageConfigDataSource, {
onChangePage: this.pageCallbackFndataSource.bind(this)
}))))), React.createElement("div", {
className: `${classes.lists} ${classes.targetKeysLists}`
}, React.createElement(List, null, showSearch && React.createElement(SelectFilter, {
fullWidth: true,
autoFocus: true,
placeholder: searchPlaceholder,
onChange: debounce(this.textchange('right'), debounceProps.wait).bind(this)
}), this.listItem(this.state.temp.targetKeys, this.state.pageConfigtargetKeys).map(value => React.createElement(ListItem, {
key: value.id,
role: undefined,
dense: true,
button: true,
onClick: this.handleToggle(value, 'right')
}, React.createElement(Checkbox, {
checked: this.state.targetKeysChecked.indexOf(value) !== -1,
tabIndex: -1,
disableRipple: true
}), React.createElement(ListItemText, {
primary: `${value.name}`
}))), React.createElement(Divider, {
className: classes.devidetargetKeys
}), showPagination && React.createElement("div", {
className: classes.paginationDataSource
}, React.createElement(Pagination, _extends({}, this.state.pageConfigtargetKeys, {
onChangePage: this.pageCallbackFntargetKeys.bind(this)
}))))));
}
}
Transfer.defaultProps = {
searchPlaceholder: 'please input something',
onChange() {},
showSearch: false,
paginationOption: false,
debounceProps: {
wait: 1000
}
};
process.env.NODE_ENV !== "production" ? Transfer.propTypes = {
/**
* 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.
*/
dataSource: PropTypes.array.isRequired,
/**
* debounce props
*/
debounceProps: PropTypes.shape({
wait: PropTypes.number
}),
/**
* A callback function that is executed when the transfer between columns is complete.
*/
onChange: PropTypes.func,
/**
* pageConfig should contain count, rowsPerPage, page
*/
pageConfig: PropTypes.shape({
count: PropTypes.number,
page: PropTypes.number,
rowsPerPage: PropTypes.number
}),
/**
* the data in the target box
*/
paginationOption: PropTypes.bool,
/**
*
* placeholder of search box
*/
searchPlaceholder: PropTypes.string,
/**
* A set of keys of selected items.
*/
selectedKeys: PropTypes.array.isRequired,
/**
* Whether show search box
*/
showSearch: PropTypes.bool,
/**
* A set of keys of elements that are listed on the right column.
*/
targetKeys: PropTypes.array.isRequired
} : void 0;
export default withStyles(styles, {
name: 'RMTransfer'
})(Transfer);