@6thquake/react-material
Version:
React components that implement Google's Material Design.
278 lines (244 loc) • 6.86 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
/**
* @ignore - do not document.
*/
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import MenuItem from '../MenuItem';
import Pagination from '../Pagination';
import AsyncSelectFilter from './AsyncSelectFilter';
import Divider from '../Divider';
import withStyles from '../styles/withStyles';
import AsyncSelectRoot from './AsyncSelectRoot';
import { debounce } from '../utils/throttle';
import yellow from '../colors/yellow';
import Input from '../Input';
const styles = theme => ({
selectMenu: {
whiteSpace: 'pre-wrap'
},
root: {
width: '100%'
},
icon: {
color: theme.palette.grey[300]
},
inputText: {
color: theme.palette.common.white,
'&$disabled': {
color: theme.palette.grey[200]
}
},
underline: {
'&:after': {
borderBottomColor: yellow[500]
},
'&:before': {
borderBottomColor: theme.palette.grey[300]
} // '&$disabled:before': {
// borderBottomColor: theme.palette.grey[200],
// },
// '&:hover:not($disabled):not($focused):not($error):before': {
// borderBottomColor: 'red',
// },
}
});
var _ref = React.createElement(Input, null);
var _ref2 = React.createElement(Divider, null);
class AsyncSelect extends Component {
constructor(props) {
super(props);
this.throttlingtem = debounce(props.onChangeFilter, props.debounceProps.wait);
}
onChangePage(currentPage1) {
this.props.onChangePage(currentPage1);
}
onChangeFilter(e) {
if (this.props.debounceAble) {
e.persist();
this.throttlingtem(e.target.value);
} else {
this.props.onChangeFilter(e.target.value);
}
}
menuItems() {
const {
options,
children,
mapper
} = this.props;
if (children) {
return children;
}
if (Array.isArray(options)) {
return options.map((name, index) => {
switch (typeof name) {
case 'string':
return React.createElement(MenuItem, {
key: index,
value: name
}, name);
case 'object':
return React.createElement(MenuItem, {
key: index,
value: typeof mapper.value === 'function' ? mapper.value(name, index) : name
}, typeof mapper.label === 'function' ? mapper.label(name, index) : name[mapper.label]);
default:
throw new Error('React-Material:select[dataSource] only supports type `string[] | Object[]`.');
}
});
}
throw new Error('React-Material: the `options` property must be an array ');
}
render() {
const _this$props = this.props,
{
isDark,
paginationProps,
placeholder,
multiple,
classes,
disabled,
htmlFor,
value,
onChange,
onOpen,
readOnly,
comparison,
renderValue
} = _this$props,
other = _objectWithoutPropertiesLoose(_this$props, ["isDark", "paginationProps", "placeholder", "multiple", "classes", "disabled", "htmlFor", "value", "onChange", "onOpen", "readOnly", "comparison", "renderValue"]);
const input = isDark ? React.createElement(Input, {
classes: {
root: classes.inputText,
underline: classes.underline
}
}) : _ref;
return React.createElement(AsyncSelectRoot, _extends({}, other, {
input: input,
readOnly: readOnly,
disabled: disabled,
onOpen: onOpen,
multiple: multiple,
value: value,
comparison: comparison,
onChange: onChange,
classes: _extends({}, classes, {
root: classes.root,
selectMenu: classes.selectMenu
}),
inputProps: {
placeholder,
id: htmlFor
},
renderValue: renderValue
}), React.createElement(AsyncSelectFilter, {
fullWidth: true,
autoFocus: true,
placeholder: placeholder,
onChange: this.onChangeFilter.bind(this)
}), this.menuItems(), _ref2, React.createElement(Pagination, _extends({}, paginationProps, {
onChangePage: this.onChangePage.bind(this)
})));
}
}
process.env.NODE_ENV !== "production" ? AsyncSelect.propTypes = {
/**
* compare the value of selected with option value,return Boolen,
*/
comparison: PropTypes.func,
/**
* If true, aysncselect will add debounce when filter options by filter value.
*/
debounceAble: PropTypes.bool,
/**
* If debounceAble is true, config debounce wait and max continue time,the unit is milliseconds.
*/
debounceProps: PropTypes.shape({
wait: PropTypes.number
}),
/**
* decided select is disabled
*/
disabled: PropTypes.bool,
/**
* filter function
*/
filter: PropTypes.func,
/**
* option item label and value, when assignment option by options
*/
mapper: PropTypes.shape({
label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
value: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
}),
/**
* decided multiple select
*/
multiple: PropTypes.bool,
/**
* callback to parent component when select option
*/
onChange: PropTypes.func.isRequired,
/**
* callback to parent component when filter change
*/
onChangeFilter: PropTypes.func,
/**
* callback to parent component when current page change
*/
onChangePage: PropTypes.func,
/**
* callback to parent component when select open
*/
onOpen: PropTypes.func.isRequired,
/**
* select options,
*/
options: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object])),
/**
* pagination component config
*/
paginationProps: PropTypes.object,
/**
* placeholder of filter box
*/
placeholder: PropTypes.string,
/**
* decided select is readonly
*/
readonly: PropTypes.bool,
/**
* Render the selected value
*
* Signature:
* `function(value: any) => ReactElement`
* value: The value provided to the component..
*/
renderValue: PropTypes.func,
/**
* The input value. This prop is required when the native prop is false (default).
*/
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object]))])
} : void 0;
AsyncSelect.defaultProps = {
paginationProps: {
page: 0,
rowsPerPage: 5,
count: 0
},
mapper: {
label: 'label',
value: 'value'
},
comparison: (select, option) => {
return select === option;
},
debounceProps: {
wait: 1000
}
};
export default withStyles(styles, {
name: 'RMAsyncSelect'
})(AsyncSelect);