UNPKG

@6thquake/react-material

Version:

React components that implement Google's Material Design.

427 lines (352 loc) 12.7 kB
"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;