UNPKG

@bootstrap-styled/ra-ui

Version:
534 lines (468 loc) 20.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.AutocompleteInput = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); 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 _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _get = _interopRequireDefault(require("lodash/get")); var _isEqual = _interopRequireDefault(require("lodash/isEqual")); var _reactAutosuggest = _interopRequireDefault(require("react-autosuggest")); var _Paper = _interopRequireDefault(require("@material-ui/core/Paper")); var _Popper = _interopRequireDefault(require("@material-ui/core/Popper")); var _TextField = _interopRequireDefault(require("@material-ui/core/TextField")); var _MenuItem = _interopRequireDefault(require("@material-ui/core/MenuItem")); var _styles = require("@material-ui/core/styles"); var _parse = _interopRequireDefault(require("autosuggest-highlight/parse")); var _match = _interopRequireDefault(require("autosuggest-highlight/match")); var _compose = _interopRequireDefault(require("recompose/compose")); var _classnames = _interopRequireDefault(require("classnames")); var _raCore = require("ra-core"); var styles = function styles(theme) { return (0, _styles.createStyles)({ container: { flexGrow: 1, position: 'relative' }, root: {}, suggestionsContainerOpen: { position: 'absolute', marginBottom: theme.spacing.unit * 3, zIndex: 2 }, suggestionsPaper: { maxHeight: '50vh', overflowY: 'auto' }, suggestion: { display: 'block', fontFamily: theme.typography.fontFamily }, suggestionText: { fontWeight: 300 }, highlightedSuggestionText: { fontWeight: 500 }, suggestionsList: { margin: 0, padding: 0, listStyleType: 'none' } }); }; var AutocompleteInput = function (_React$Component) { (0, _inherits2.default)(AutocompleteInput, _React$Component); function AutocompleteInput() { var _getPrototypeOf2; var _this; (0, _classCallCheck2.default)(this, AutocompleteInput); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(AutocompleteInput)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", { dirty: false, inputValue: null, searchText: '', selectedItem: null, suggestions: [] }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "ignoreNextChoicesUpdate", false); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "inputEl", null); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "anchorEl", null); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSelectedItem", function (_ref, inputValue) { var choices = _ref.choices; return choices && inputValue ? choices.find(function (choice) { return _this.getSuggestionValue(choice) === inputValue; }) : null; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSuggestionValue", function (suggestion) { return (0, _get.default)(suggestion, _this.props.optionValue); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSuggestionText", function (suggestion) { if (!suggestion) return ''; var _this$props = _this.props, optionText = _this$props.optionText, translate = _this$props.translate, translateChoice = _this$props.translateChoice; var suggestionLabel = typeof optionText === 'function' ? optionText(suggestion) : (0, _get.default)(suggestion, optionText, ''); return translateChoice ? translate(suggestionLabel, { _: suggestionLabel }).toString() : suggestionLabel.toString(); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSuggestionSelected", function (event, _ref2) { var suggestion = _ref2.suggestion, method = _ref2.method; var input = _this.props.input; var inputValue = _this.getSuggestionValue(suggestion); if (input && input.onChange) { input.onChange(inputValue); } if (method === 'enter') { event.preventDefault(); } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSuggestionsFetchRequested", function () { _this.setState(function (_ref3) { var suggestions = _ref3.suggestions, prevSuggestions = _ref3.prevSuggestions; return { suggestions: prevSuggestions || suggestions }; }); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSuggestionsClearRequested", function () { _this.updateFilter(''); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMatchSuggestionOrFilter", function (inputValue) { _this.setState({ dirty: true, searchText: inputValue }); _this.updateFilter(inputValue); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleChange", function (event, _ref4) { var newValue = _ref4.newValue, method = _ref4.method; switch (method) { case 'type': case 'escape': { _this.handleMatchSuggestionOrFilter(newValue); } break; } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderInput", function (inputProps) { var _this$props2 = _this.props, helperText = _this$props2.helperText, input = _this$props2.input; var autoFocus = inputProps.autoFocus, className = inputProps.className, _inputProps$classes = inputProps.classes, classes = _inputProps$classes === void 0 ? {} : _inputProps$classes, isRequired = inputProps.isRequired, label = inputProps.label, meta = inputProps.meta, onChange = inputProps.onChange, resource = inputProps.resource, source = inputProps.source, value = inputProps.value, ref = inputProps.ref, _inputProps$options = inputProps.options, InputProps = _inputProps$options.InputProps, suggestionsContainerProps = _inputProps$options.suggestionsContainerProps, options = (0, _objectWithoutProperties2.default)(_inputProps$options, ["InputProps", "suggestionsContainerProps"]), other = (0, _objectWithoutProperties2.default)(inputProps, ["autoFocus", "className", "classes", "isRequired", "label", "meta", "onChange", "resource", "source", "value", "ref", "options"]); if (typeof meta === 'undefined') { throw new Error("The TextInput component wasn't called within a redux-form <Field>. Did you decorate it and forget to add the addField prop to your component? See https://marmelab.com/react-admin/Inputs.html#writing-your-own-input-component for details."); } var touched = meta.touched, error = meta.error; var storeInputRef = function storeInputRef(input) { _this.inputEl = input; _this.updateAnchorEl(); ref(input); }; return _react.default.createElement(_TextField.default, (0, _extends2.default)({ label: _react.default.createElement(_raCore.FieldTitle, { label: label, source: source, resource: resource, isRequired: isRequired }), value: value, onChange: onChange, autoFocus: autoFocus, margin: "normal", className: (0, _classnames.default)(classes.root, className), inputRef: storeInputRef, error: !!(touched && error), helperText: touched && error || helperText, name: input.name }, options, { InputProps: (0, _objectSpread2.default)({ classes: { input: classes.input } }, InputProps, other) })); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderSuggestionsContainer", function (autosuggestOptions) { var _autosuggestOptions$c = autosuggestOptions.containerProps, className = _autosuggestOptions$c.className, containerProps = (0, _objectWithoutProperties2.default)(_autosuggestOptions$c, ["className"]), children = autosuggestOptions.children; var _this$props3 = _this.props, _this$props3$classes = _this$props3.classes, classes = _this$props3$classes === void 0 ? {} : _this$props3$classes, options = _this$props3.options; _this.updateAnchorEl(); return _react.default.createElement(_Popper.default, (0, _extends2.default)({ className: className, open: Boolean(children), anchorEl: _this.anchorEl, placement: "bottom-start" }, options.suggestionsContainerProps), _react.default.createElement(_Paper.default, (0, _extends2.default)({ square: true, className: classes.suggestionsPaper }, containerProps), children)); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderSuggestionComponent", function (_ref5) { var suggestion = _ref5.suggestion, query = _ref5.query, isHighlighted = _ref5.isHighlighted, props = (0, _objectWithoutProperties2.default)(_ref5, ["suggestion", "query", "isHighlighted"]); return _react.default.createElement("div", props); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "renderSuggestion", function (suggestion, _ref6) { var query = _ref6.query, isHighlighted = _ref6.isHighlighted; var label = _this.getSuggestionText(suggestion); var matches = (0, _match.default)(label, query); var parts = (0, _parse.default)(label, matches); var _this$props4 = _this.props, _this$props4$classes = _this$props4.classes, classes = _this$props4$classes === void 0 ? {} : _this$props4$classes, suggestionComponent = _this$props4.suggestionComponent; return _react.default.createElement(_MenuItem.default, { selected: isHighlighted, component: suggestionComponent || _this.renderSuggestionComponent, suggestion: suggestion, query: query, isHighlighted: isHighlighted }, _react.default.createElement("div", null, parts.map(function (part, index) { return part.highlight ? _react.default.createElement("span", { key: index, className: classes.highlightedSuggestionText }, part.text) : _react.default.createElement("strong", { key: index, className: classes.suggestionText }, part.text); }))); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleBlur", function () { var _this$state = _this.state, dirty = _this$state.dirty, searchText = _this$state.searchText, selectedItem = _this$state.selectedItem; var _this$props5 = _this.props, allowEmpty = _this$props5.allowEmpty, input = _this$props5.input; if (dirty) { if (searchText === '' && allowEmpty) { input && input.onBlur && input.onBlur(null); } else { input && input.onBlur && input.onBlur(_this.state.inputValue); _this.setState({ dirty: false, searchText: _this.getSuggestionText(selectedItem), suggestions: _this.props.limitChoicesToValue && selectedItem ? [selectedItem] : _this.props.choices }); } } else { input && input.onBlur && input.onBlur(_this.state.inputValue); } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleFocus", function () { var input = _this.props.input; input && input.onFocus && input.onFocus(); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateFilter", function (value) { var _this$props6 = _this.props, setFilter = _this$props6.setFilter, choices = _this$props6.choices; if (_this.previousFilterValue !== value) { if (setFilter) { setFilter(value); } else { _this.setState({ suggestions: choices.filter(function (choice) { return _this.getSuggestionText(choice).toLowerCase().indexOf(value.toLowerCase()) !== -1; }) }); } } _this.previousFilterValue = value; }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "shouldRenderSuggestions", function (val) { var shouldRenderSuggestions = _this.props.shouldRenderSuggestions; if (shouldRenderSuggestions !== undefined && typeof shouldRenderSuggestions === 'function') { return shouldRenderSuggestions(val); } return true; }); return _this; } (0, _createClass2.default)(AutocompleteInput, [{ key: "componentWillMount", value: function componentWillMount() { var selectedItem = this.getSelectedItem(this.props, this.props.input.value); this.setState({ selectedItem: selectedItem, inputValue: this.props.input.value, searchText: this.getSuggestionText(selectedItem), suggestions: this.props.limitChoicesToValue && selectedItem ? [selectedItem] : this.props.choices }); } }, { key: "componentWillReceiveProps", value: function componentWillReceiveProps(nextProps) { var _this2 = this; var choices = nextProps.choices, input = nextProps.input, limitChoicesToValue = nextProps.limitChoicesToValue; if (input.value !== this.state.inputValue) { var selectedItem = this.getSelectedItem(nextProps, input.value); this.setState({ selectedItem: selectedItem, inputValue: input.value, searchText: this.getSuggestionText(selectedItem), dirty: false, suggestions: limitChoicesToValue && selectedItem ? [selectedItem] : this.props.choices, prevSuggestions: false }); this.ignoreNextChoicesUpdate = true; this.updateFilter(''); } else if (!(0, _isEqual.default)(choices, this.props.choices)) { if (this.ignoreNextChoicesUpdate) { this.ignoreNextChoicesUpdate = false; return; } var _selectedItem = this.getSelectedItem(nextProps, this.state.inputValue); this.setState(function (_ref7) { var dirty = _ref7.dirty, searchText = _ref7.searchText; return { selectedItem: _selectedItem, searchText: dirty ? searchText : _this2.getSuggestionText(_selectedItem), suggestions: limitChoicesToValue && !dirty && _selectedItem ? [_selectedItem] : choices, prevSuggestions: false }; }); } } }, { key: "updateAnchorEl", value: function updateAnchorEl() { if (!this.inputEl) { return; } var inputPosition = this.inputEl.getBoundingClientRect(); if (!this.anchorEl) { this.anchorEl = { getBoundingClientRect: function getBoundingClientRect() { return inputPosition; } }; } else { var anchorPosition = this.anchorEl.getBoundingClientRect(); if (anchorPosition.x !== inputPosition.x || anchorPosition.y !== inputPosition.y) { this.anchorEl = { getBoundingClientRect: function getBoundingClientRect() { return inputPosition; } }; } } } }, { key: "render", value: function render() { var _this$props7 = this.props, alwaysRenderSuggestions = _this$props7.alwaysRenderSuggestions, _this$props7$classes = _this$props7.classes, classes = _this$props7$classes === void 0 ? {} : _this$props7$classes, isRequired = _this$props7.isRequired, label = _this$props7.label, meta = _this$props7.meta, resource = _this$props7.resource, source = _this$props7.source, className = _this$props7.className, options = _this$props7.options, rest = (0, _objectWithoutProperties2.default)(_this$props7, ["alwaysRenderSuggestions", "classes", "isRequired", "label", "meta", "resource", "source", "className", "options"]); var _this$state2 = this.state, suggestions = _this$state2.suggestions, searchText = _this$state2.searchText; return _react.default.createElement(_reactAutosuggest.default, (0, _extends2.default)({ theme: { container: classes.container, suggestionsContainerOpen: classes.suggestionsContainerOpen, suggestionsList: classes.suggestionsList, suggestion: classes.suggestion }, renderInputComponent: this.renderInput, suggestions: suggestions, alwaysRenderSuggestions: alwaysRenderSuggestions, onSuggestionSelected: this.handleSuggestionSelected, onSuggestionsFetchRequested: this.handleSuggestionsFetchRequested, onSuggestionsClearRequested: this.handleSuggestionsClearRequested, renderSuggestionsContainer: this.renderSuggestionsContainer, getSuggestionValue: this.getSuggestionText, renderSuggestion: this.renderSuggestion, shouldRenderSuggestions: this.shouldRenderSuggestions, inputProps: { className: className, classes: classes, isRequired: isRequired, label: label, meta: meta, onChange: this.handleChange, resource: resource, source: source, value: searchText, onBlur: this.handleBlur, onFocus: this.handleFocus, options: options } }, rest)); } }]); return AutocompleteInput; }(_react.default.Component); exports.AutocompleteInput = AutocompleteInput; AutocompleteInput.propTypes = { allowEmpty: _propTypes.default.bool, alwaysRenderSuggestions: _propTypes.default.bool, choices: _propTypes.default.arrayOf(_propTypes.default.object), classes: _propTypes.default.object, className: _propTypes.default.string, InputProps: _propTypes.default.object, input: _propTypes.default.object, isRequired: _propTypes.default.bool, label: _propTypes.default.string, limitChoicesToValue: _propTypes.default.bool, meta: _propTypes.default.object, options: _propTypes.default.object, optionText: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]).isRequired, optionValue: _propTypes.default.string.isRequired, resource: _propTypes.default.string, setFilter: _propTypes.default.func, shouldRenderSuggestions: _propTypes.default.func, source: _propTypes.default.string, suggestionComponent: _propTypes.default.func, translate: _propTypes.default.func.isRequired, translateChoice: _propTypes.default.bool.isRequired }; AutocompleteInput.defaultProps = { choices: [], options: {}, optionText: 'name', optionValue: 'id', limitChoicesToValue: false, translateChoice: true }; var _default = (0, _compose.default)(_raCore.addField, _raCore.translate, (0, _styles.withStyles)(styles))(AutocompleteInput); exports.default = _default;