@6thquake/react-material
Version:
React components that implement Google's Material Design.
427 lines (352 loc) • 12.7 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _withStyles = _interopRequireDefault(require("../styles/withStyles"));
var _TextField = _interopRequireDefault(require("../TextField"));
var _Paper = _interopRequireDefault(require("../Paper"));
var _Pagination = _interopRequireDefault(require("../Pagination"));
var _Divider = _interopRequireDefault(require("../Divider"));
var _MenuItem = _interopRequireDefault(require("../MenuItem"));
var _throttle = require("../utils/throttle");
/**
* @ignore - do not document.
*/
var styles = function styles(theme) {
return {
root: {
flexGrow: 1
},
container: {
flexGrow: 1,
position: 'relative'
},
textarea: {
width: '100%'
},
modal: {
position: 'fixed',
top: 0,
right: 0,
bottom: 0,
left: 0,
overflow: 'hidden',
outline: 0,
backgroundColor: 'rgb(0, 0, 0)',
opacity: 0,
zIndex: 1
},
paper: {
position: 'absolute',
zIndex: 200,
marginTop: theme.spacing(1),
left: 0,
right: 0,
padding: '10px'
},
chip: {
margin: "".concat(theme.spacing(0.5), "px ").concat(theme.spacing(0.25), "px")
},
inputRoot: {
flexGrow: 1,
flexWrap: 'wrap'
},
inputHold: {
padding: '10px 0 7px'
},
notFound: {
padding: '10px',
color: 'rgba(0,0,0,0.5)'
}
};
};
var Mention =
/*#__PURE__*/
function (_Component) {
(0, _inherits2.default)(Mention, _Component);
function Mention(props) {
var _this;
(0, _classCallCheck2.default)(this, Mention);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Mention).call(this));
_this.handleChange = function (e) {
var trigger = null;
if (_this.state.open === false) {
// 可选框未打开时打开可选框
if (e.target.value.indexOf(' ') === -1 && _this.props.prefix.indexOf(e.target.value.charAt(0)) > -1) {
// 标志符在开头
trigger = e.target.value[0];
_this.setState({
open: true,
triggerOption: trigger
});
_this.props.onSearchChange(e.target.value.slice(1, e.target.value.length), trigger); // 让外部传入可选的项目
} else if (e.target.value.indexOf(' ') > -1) {
// 标志符在中间但是前面有空格
var stringForComplete = e.target.value.split(' ').pop();
if (_this.props.prefix.indexOf(stringForComplete[0]) > -1) {
trigger = stringForComplete[0];
}
if (trigger) {
_this.setState({
open: true,
triggerOption: trigger
});
_this.props.onSearchChange(stringForComplete.slice(1, stringForComplete.length), trigger); // 让外部传入可选的项目
}
}
} else if (e.target.value) {
// 可选框打开时是过滤字符串的功能
var targetOptionIndex = e.target.value.lastIndexOf(_this.state.triggerOption);
var searchLength = e.target.value.length;
var filterOption = e.target.value.slice(targetOptionIndex + 1, searchLength);
_this.props.onSearchChange(filterOption, _this.state.triggerOption);
}
_this.setState({
inputValue: e.target.value
});
_this.props.onChange(e.target.value); // 用来回显
};
_this.handleItemClick = function (item) {
return function (e) {
var position = _this.state.inputValue.lastIndexOf(_this.state.triggerOption); // 找到触发符号的位置
var newValue = _this.state.inputValue.slice(0, position + 1) + item; // 把选中的item接到后面
var newSelectedItem = [].concat((0, _toConsumableArray2.default)(_this.state.selectedItem), [item]); // 所有的选中值
_this.setState({
open: false,
inputValue: newValue,
selectedItem: newSelectedItem
});
_this.props.onSelect(newSelectedItem); // 回传选中值
_this.props.onChange(newValue); // 回传输入值
};
};
_this.state = {
open: false,
inputValue: props.defaultValue,
selectedItem: props.selected,
triggerOption: '',
pageConfig: {
page: props.pageConfig.page || 0,
rowsPerPage: props.pageConfig.rowsPerPage || 5,
count: props.pageConfig.count || 5
}
};
return _this;
}
(0, _createClass2.default)(Mention, [{
key: "handleBlur",
value: function handleBlur(e) {
this.setState({
open: false
});
}
}, {
key: "pageCallbackFn",
value: function pageCallbackFn(i) {
// 切换页面的函数
this.setState({
pageConfig: (0, _extends2.default)({}, this.state.pageConfig, {
page: i
})
});
}
}, {
key: "render",
value: function render() {
var _this2 = this;
var _this$props = this.props,
classes = _this$props.classes,
placeholder = _this$props.placeholder,
children = _this$props.children,
dataSource = _this$props.dataSource,
disabled = _this$props.disabled,
showError = _this$props.showError,
pageConfig = _this$props.pageConfig,
debounceProps = _this$props.debounceProps;
var _this$state$pageConfi = this.state.pageConfig,
count = _this$state$pageConfi.count,
page = _this$state$pageConfi.page,
rowsPerPage = _this$state$pageConfi.rowsPerPage;
var _this$state = this.state,
open = _this$state.open,
inputValue = _this$state.inputValue,
selectedItem = _this$state.selectedItem;
var items;
var showPagination = false;
var noItemPatterned = false;
noItemPatterned = dataSource && dataSource.length === 0 || !dataSource && !_react.default.children;
if (pageConfig) {
showPagination = true;
}
if (dataSource) {
// 通过dataSource传参的情况
items = dataSource ? dataSource.map(function (item) {
var selected = false;
if (typeof item === 'string') {
if (!Array.isArray(selectedItem)) {
throw new Error('React-Material: the `value` property must be an array ' + 'when using the `AutoComplete` component with `multiple`.');
}
selected = selectedItem.indexOf(item) !== -1;
return _react.default.createElement(_MenuItem.default, {
key: item,
value: item,
selected: selected,
onClick: _this2.handleItemClick(item)
}, item);
}
throw new Error('AutoComplete[dataSource] only supports type `string[] | Object[]`.');
}) : [];
} else if (_react.default.Children) {
// 通过child传参的情况
items = _react.default.Children ? _react.default.Children.map(children, function (child) {
if (!_react.default.isValidElement(child)) {
return null;
}
var selected = false;
if (!Array.isArray(selectedItem)) {
throw new Error('React-Material: the `value` property must be an array ' + 'when using the `AutoComplete` component with `multiple`.');
}
selected = selectedItem.indexOf(child.props.value) !== -1;
return _react.default.cloneElement(child, {
onClick: _this2.handleItemClick(child.props.value),
role: 'option',
selected: selected,
value: undefined,
// The value is most likely not a valid HTML attribute.
'data-value': child.props.value // Instead, we provide it as a data attribute.
});
}) : [];
}
return _react.default.createElement("div", {
className: classes.root
}, open ? _react.default.createElement("div", {
onClick: this.handleBlur.bind(this),
className: classes.modal
}) : null, _react.default.createElement("div", {
className: classes.container
}, _react.default.createElement(_TextField.default, {
disabled: disabled,
className: classes.textarea,
onChange: (0, _throttle.debounce)(this.handleChange, debounceProps.wait).bind(this),
value: inputValue,
placeholder: placeholder,
error: showError
}), open && !noItemPatterned && _react.default.createElement(_Paper.default, {
className: classes.paper,
square: true
}, items.slice(count === 0 ? count : page * rowsPerPage, (page + 1) * rowsPerPage > count ? count : (page + 1) * rowsPerPage), _react.default.createElement(_Divider.default, null), showPagination && _react.default.createElement(_Pagination.default, (0, _extends2.default)({}, this.state.pageConfig, {
onChangePage: this.pageCallbackFn.bind(this)
}))), open && noItemPatterned && _react.default.createElement(_Paper.default, {
className: classes.notFound
}, 'no patterned result, press space to end')));
}
}], [{
key: "getDerivedStateFromProps",
value: function getDerivedStateFromProps(newProps, prevState) {
// 父组件改変分页参数时state要跟着变
if (newProps !== prevState.preProps) {
return {
pageConfig: (0, _extends2.default)({}, prevState.pageConfig, {
count: newProps.pageConfig.count
}),
prevProps: newProps
};
}
return null;
}
}]);
return Mention;
}(_react.Component);
Mention.propTypes = {
/**
* set the option to be selected
*/
dataSource: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.array]),
/**
* debounce props
*/
debounceProps: _propTypes.default.shape({
wait: _propTypes.default.number
}),
/**
* default value
*/
defaultValue: _propTypes.default.string,
/**
* should component disabled
*/
disabled: _propTypes.default.bool,
// inputChangeCb: PropTypes.func.isRequired,
/**
* Callback when input @ content changes, parameters are (value,trigger)
*/
onChange: _propTypes.default.func.isRequired,
/**
* Callback when input content changes
*/
onSearchChange: _propTypes.default.func.isRequired,
/**
* callback when select value change
*/
onSelect: _propTypes.default.func.isRequired,
/**
* pagination config
*/
pageConfig: _propTypes.default.shape({
count: _propTypes.default.number,
page: _propTypes.default.number,
rowsPerPage: _propTypes.default.number
}),
/**
* text palcehold
*/
placeholder: _propTypes.default.string,
/**
* set char of trigger
*/
prefix: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.array]),
/**
* set if the text can only be read
*/
readOnly: _propTypes.default.bool,
/**
* select value,
*/
selected: _propTypes.default.array,
/**
* show error
*/
showError: _propTypes.default.bool // triggerOptions: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
};
Mention.defaultProps = {
onSearchChange: function onSearchChange() {},
onChange: function onChange() {},
onSelect: function onSelect() {},
disabled: false,
prefix: ['@'],
// 默认的触发符号
placeholder: 'please input something',
readOnly: false,
defaultValue: '',
selected: [],
// 初始化传入的item
debounceProps: {
wait: 1000
}
};
var _default = (0, _withStyles.default)(styles, {
name: 'RMMention'
})(Mention);
exports.default = _default;