@panneau/field-autosuggest
Version:
Autosuggest fields for Panneau
315 lines (294 loc) • 12.9 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
var _excluded = ["label", "name", "value"];
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import get from 'lodash/get';
import isObject from 'lodash/isObject';
import Autosuggest from 'react-autosuggest';
import { injectIntl } from 'react-intl';
import { FormGroup } from '@panneau/field';
import { getJSON, PropTypes as PanneauPropTypes } from '@panneau/core';
var styles = {
"autosuggest": "panneau-field-autosuggest-autosuggest",
"input": "panneau-field-autosuggest-input",
"suggestionsContainer": "panneau-field-autosuggest-suggestionsContainer",
"open": "panneau-field-autosuggest-open",
"suggestions": "panneau-field-autosuggest-suggestions",
"suggestion": "panneau-field-autosuggest-suggestion",
"thumbnail": "panneau-field-autosuggest-thumbnail",
"cols": "panneau-field-autosuggest-cols",
"col": "panneau-field-autosuggest-col",
"expand": "panneau-field-autosuggest-expand",
"title": "panneau-field-autosuggest-title",
"description": "panneau-field-autosuggest-description",
"highlighted": "panneau-field-autosuggest-highlighted"
};
var propTypes = {
intl: PanneauPropTypes.intl.isRequired,
name: PropTypes.string,
label: PanneauPropTypes.label,
value: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]),
placeholder: PanneauPropTypes.message,
suggestions: PropTypes.array,
// eslint-disable-line react/forbid-prop-types
suggestionsEndpoint: PropTypes.string,
suggestionValuePath: PropTypes.string,
suggestionTitlePath: PropTypes.string,
suggestionDescriptionPath: PropTypes.string,
suggestionThumbnailPath: PropTypes.string,
getSuggestionValue: PropTypes.func,
getSuggestionTitle: PropTypes.func,
getSuggestionDescription: PropTypes.func,
getSuggestionThumbnail: PropTypes.func,
onChange: PropTypes.func,
onSelect: PropTypes.func
};
var defaultProps = {
name: null,
label: null,
value: null,
placeholder: null,
suggestions: [],
suggestionsEndpoint: null,
suggestionValuePath: 'name',
suggestionTitlePath: 'name',
suggestionDescriptionPath: 'description',
suggestionThumbnailPath: 'thumbnail',
getSuggestionValue: null,
getSuggestionTitle: null,
getSuggestionDescription: null,
getSuggestionThumbnail: null,
onChange: null,
onSelect: null
};
/**
* Autosuggest field
* @extends Component
*/
var AutosuggestField = /*#__PURE__*/function (_Component) {
_inherits(AutosuggestField, _Component);
var _super = _createSuper(AutosuggestField);
function AutosuggestField(props) {
var _this;
_classCallCheck(this, AutosuggestField);
_this = _super.call(this, props);
_this.onInputChange = _this.onInputChange.bind(_assertThisInitialized(_this));
_this.onSuggestionSelected = _this.onSuggestionSelected.bind(_assertThisInitialized(_this));
_this.onSuggestionsFetchRequested = _this.onSuggestionsFetchRequested.bind(_assertThisInitialized(_this));
_this.onSuggestionsClearRequested = _this.onSuggestionsClearRequested.bind(_assertThisInitialized(_this));
_this.onSuggestionsFetched = _this.onSuggestionsFetched.bind(_assertThisInitialized(_this));
_this.onSuggestionsFetchError = _this.onSuggestionsFetchError.bind(_assertThisInitialized(_this));
_this.getSuggestionValue = _this.getSuggestionValue.bind(_assertThisInitialized(_this));
_this.renderSuggestion = _this.renderSuggestion.bind(_assertThisInitialized(_this));
_this.renderSuggestions = _this.renderSuggestions.bind(_assertThisInitialized(_this));
_this.state = {
suggestions: props.suggestions || []
};
return _this;
}
_createClass(AutosuggestField, [{
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(_ref) {
var nextSuggestions = _ref.suggestions;
var suggestions = this.props.suggestions;
var suggestionsChanged = nextSuggestions !== suggestions;
if (suggestionsChanged) {
this.setState({
suggestions: nextSuggestions || []
});
}
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(_ref2) {
var prevSuggestionsEndpoint = _ref2.suggestionsEndpoint;
var suggestionsEndpoint = this.props.suggestionsEndpoint;
var suggestionsEndpointChanged = prevSuggestionsEndpoint !== suggestionsEndpoint;
if (suggestionsEndpointChanged && suggestionsEndpoint !== null) {
this.fetchSuggestions();
}
}
}, {
key: "onInputChange",
value: function onInputChange(event, _ref3) {
var newValue = _ref3.newValue;
var onChange = this.props.onChange;
if (onChange) {
onChange(newValue);
}
}
}, {
key: "onSuggestionSelected",
value: function onSuggestionSelected(event, _ref4) {
var suggestion = _ref4.suggestion;
var onSelect = this.props.onSelect;
if (onSelect) {
onSelect(suggestion);
}
}
}, {
key: "onSuggestionsFetchRequested",
value: function onSuggestionsFetchRequested() {
var _this$props = this.props,
suggestionsEndpoint = _this$props.suggestionsEndpoint,
suggestions = _this$props.suggestions;
if (suggestionsEndpoint !== null) {
this.fetchSuggestions();
} else {
this.setState({
suggestions: suggestions
});
}
}
}, {
key: "onSuggestionsClearRequested",
value: function onSuggestionsClearRequested() {
this.setState({
suggestions: []
});
}
}, {
key: "onSuggestionsFetched",
value: function onSuggestionsFetched(data) {
this.setState({
suggestions: data
});
}
}, {
key: "onSuggestionsFetchError",
value: function onSuggestionsFetchError() {
this.setState({
suggestions: []
});
} // eslint-disable-next-line class-methods-use-this
}, {
key: "getSuggestionValue",
value: function getSuggestionValue(suggestion) {
var _this$props2 = this.props,
getSuggestionValue = _this$props2.getSuggestionValue,
suggestionValuePath = _this$props2.suggestionValuePath;
return getSuggestionValue !== null ? getSuggestionValue(suggestion, this.props) : get(suggestion, suggestionValuePath, '');
}
}, {
key: "fetchSuggestions",
value: function fetchSuggestions() {
var suggestionsEndpoint = this.props.suggestionsEndpoint;
getJSON(suggestionsEndpoint, {
credentials: 'include'
}).then(this.onSuggestionsFetched)["catch"](this.onSuggestionsFetchError);
} // eslint-disable-next-line class-methods-use-this
}, {
key: "renderSuggestions",
value: function renderSuggestions(_ref5) {
var containerProps = _ref5.containerProps,
children = _ref5.children;
return /*#__PURE__*/React.createElement("div", containerProps, children);
} // eslint-disable-next-line class-methods-use-this
}, {
key: "renderSuggestion",
value: function renderSuggestion(suggestion) {
var _classNames;
var _this$props3 = this.props,
getSuggestionTitle = _this$props3.getSuggestionTitle,
getSuggestionDescription = _this$props3.getSuggestionDescription,
getSuggestionThumbnail = _this$props3.getSuggestionThumbnail,
suggestionTitlePath = _this$props3.suggestionTitlePath,
suggestionDescriptionPath = _this$props3.suggestionDescriptionPath,
suggestionThumbnailPath = _this$props3.suggestionThumbnailPath;
var thumbnail = getSuggestionThumbnail !== null ? getSuggestionThumbnail(suggestion) : get(suggestion, suggestionThumbnailPath, null);
var title = getSuggestionTitle !== null ? getSuggestionTitle(suggestion) : get(suggestion, suggestionTitlePath, null);
var description = getSuggestionDescription !== null ? getSuggestionDescription(suggestion) : get(suggestion, suggestionDescriptionPath, null);
var labelClassNames = classNames((_classNames = {}, _defineProperty(_classNames, styles.col, true), _defineProperty(_classNames, styles.expand, true), _classNames));
var thumbnailStyle = thumbnail !== null ? {
backgroundImage: "url(".concat(thumbnail, ")")
} : null;
return /*#__PURE__*/React.createElement("div", {
className: styles.inner
}, /*#__PURE__*/React.createElement("div", {
className: styles.cols
}, thumbnail ? /*#__PURE__*/React.createElement("div", {
className: styles.col
}, /*#__PURE__*/React.createElement("div", {
className: styles.thumbnail,
style: thumbnailStyle
})) : null, /*#__PURE__*/React.createElement("div", {
className: labelClassNames
}, title !== null ? /*#__PURE__*/React.createElement("div", {
className: styles.title
}, title) : null, description !== null ? /*#__PURE__*/React.createElement("div", {
className: styles.description
}, description) : null)));
}
}, {
key: "renderInput",
value: function renderInput() {
var _this$props4 = this.props,
value = _this$props4.value,
placeholder = _this$props4.placeholder,
intl = _this$props4.intl;
var suggestions = this.state.suggestions;
var inputPlaceholder = placeholder || '';
var inputProps = {
value: value || '',
onChange: this.onInputChange,
placeholder: isObject(inputPlaceholder) ? intl.formatMessage(inputPlaceholder) : inputPlaceholder
};
var theme = {
container: classNames(_defineProperty({}, styles.autosuggest, true)),
containerOpen: classNames(_defineProperty({}, styles.open, true)),
input: classNames(_defineProperty({
'form-control': true
}, styles.input, true)),
suggestionsContainer: classNames(_defineProperty({}, styles.suggestionsContainer, true)),
suggestionsContainerOpen: classNames(_defineProperty({}, styles.open, true)),
suggestionsList: classNames(_defineProperty({}, styles.suggestions, true)),
suggestion: classNames(_defineProperty({}, styles.suggestion, true)),
suggestionHighlighted: classNames(_defineProperty({}, styles.highlighted, true))
};
return /*#__PURE__*/React.createElement(Autosuggest, {
suggestions: suggestions,
inputProps: inputProps,
theme: theme,
getSuggestionValue: this.getSuggestionValue,
renderSuggestion: this.renderSuggestion,
onSuggestionsFetchRequested: this.onSuggestionsFetchRequested,
onSuggestionsClearRequested: this.onSuggestionsClearRequested,
onSuggestionSelected: this.onSuggestionSelected
});
}
}, {
key: "render",
value: function render() {
var _this$props5 = this.props,
label = _this$props5.label,
name = _this$props5.name,
value = _this$props5.value,
other = _objectWithoutProperties(_this$props5, _excluded);
return /*#__PURE__*/React.createElement(FormGroup, _extends({
className: classNames(_defineProperty({}, styles.container, true)),
name: name,
label: label
}, other), this.renderInput());
}
}], [{
key: "parse",
value: function parse(value) {
return value;
}
}]);
return AutosuggestField;
}(Component);
AutosuggestField.propTypes = propTypes;
AutosuggestField.defaultProps = defaultProps;
export default injectIntl(AutosuggestField);