downshift-pelias
Version:
Downshift + pelias-js geo autocomplete/dropdown/search React component
252 lines (243 loc) • 9.16 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react'), require('prop-types'), require('downshift')) :
typeof define === 'function' && define.amd ? define(['react', 'prop-types', 'downshift'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.DownshiftPelias = factory(global.React, global.PropTypes, global.Downshift));
})(this, (function (React, PropTypes, Downshift) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
var Downshift__default = /*#__PURE__*/_interopDefaultLegacy(Downshift);
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _extends() {
_extends = Object.assign ? Object.assign.bind() : function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _objectWithoutProperties(source, excluded) {
if (source == null) return {};
var target = _objectWithoutPropertiesLoose(source, excluded);
var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
}
const _excluded = ["getInputProps", "highlightedIndex", "inputValue"];
class DownshiftPelias extends React__default["default"].Component {
constructor(props) {
super(props);
_defineProperty(this, "handleInputValueChange", (inputValue, stateAndHelpers) => {
// Runs `handleInputValueChange` if provided by parent
if (typeof this.props.handleInputValueChange === 'function') {
this.props.handleInputValueChange(inputValue, stateAndHelpers);
}
this.doAutocomplete(inputValue);
});
_defineProperty(this, "doAutocomplete", inputValue => {
const timestamp = Date.now();
this.lastInputTimestamp = timestamp;
if (!inputValue) {
this.setState({
pending: false,
results: null
});
return;
}
this.setState({
pending: true
});
this.props.pelias.autocomplete.setSearchTerm(inputValue).execute().then(response => {
// Only display the results if the timestamp associated
// with this request is still current
if (timestamp === this.lastInputTimestamp) {
this.setState({
pending: false,
results: response
});
}
}).catch(error => {
console.log(error);
if (timestamp === this.lastInputTimestamp) {
this.setState({
pending: false,
error: true
});
}
});
});
_defineProperty(this, "doSearch", inputValue => {
const timestamp = Date.now();
this.lastInputTimestamp = timestamp;
if (!inputValue) {
this.setState({
pending: false,
results: null
});
return;
}
this.setState({
pending: true
});
this.props.pelias.search.setSearchTerm(inputValue).execute().then(response => {
// Only display the results if the timestamp associated
// with this request is still current
if (timestamp === this.lastInputTimestamp) {
this.setState({
pending: false,
results: response
});
}
}).catch(error => {
console.log(error);
if (timestamp === this.lastInputTimestamp) {
this.setState({
pending: false,
error: true
});
}
});
});
_defineProperty(this, "defaultItemToString", item => item ? item.properties.label : '');
this.state = {
results: null,
pending: false,
error: false
};
// For internal use only to track when inputs are being made,
// so we know when to throw away async responses that become stale
this.lastInputTimestamp = Date.now();
}
render() {
return /*#__PURE__*/React__default["default"].createElement(Downshift__default["default"], _extends({
onChange: this.handleChange,
onInputValueChange: this.handleInputValueChange,
itemToString: this.props.itemToString || this.defaultItemToString
}, this.props), _ref => {
let {
getInputProps: _getInputProps,
highlightedIndex,
inputValue
} = _ref,
args = _objectWithoutProperties(_ref, _excluded);
return this.props.children(_objectSpread2(_objectSpread2({}, args), {}, {
// Put back the stuff we destructured
highlightedIndex,
inputValue,
// Modify the `onKeyDown` prop of input props so that it handles the "Enter"
// key being pressed, by default.
getInputProps: args => _getInputProps(_objectSpread2(_objectSpread2({}, args), {}, {
onKeyDown: event => {
// Run `onKeyDown` from parent <input> element, if provided
if (args && typeof args.onKeyDown === 'function') {
args.onKeyDown(event);
}
// If `enter` key is pressed and nothing in the menu is highlighted,
// then perform a search by calling `doSearch`. This retrieves
// results Pelias's search query endpoint.
if (event.key === 'Enter' && highlightedIndex === null) {
// Bail if default Downshift behavior is prevented
if (event.nativeEvent.preventDownshiftDefault === true) {
return;
}
this.doSearch(inputValue);
}
}
})),
doSearch: () => {
this.doSearch(inputValue);
},
results: this.state.results,
pending: this.state.pending,
error: this.state.error
}));
});
}
}
_defineProperty(DownshiftPelias, "propTypes", {
children: PropTypes__default["default"].func.isRequired,
pelias: PropTypes__default["default"].shape({
search: PropTypes__default["default"].shape({
setSearchTerm: PropTypes__default["default"].func.isRequired,
execute: PropTypes__default["default"].func.isRequired
}).isRequired,
autocomplete: PropTypes__default["default"].object.isRequired
}).isRequired,
itemToString: PropTypes__default["default"].func
});
return DownshiftPelias;
}));