@bootstrap-styled/ra-ui
Version:
UI components for react-admin
534 lines (468 loc) • 20.9 kB
JavaScript
"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;