UNPKG

@6thquake/react-material

Version:

React components that implement Google's Material Design.

440 lines (390 loc) 12.7 kB
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);