wix-style-react
Version:
wix-style-react
353 lines (351 loc) • 12.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = exports.GoogleAddressInputHandler = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _castArray = _interopRequireDefault(require("lodash/castArray"));
var _wixUiIconsCommon = require("@wix/wix-ui-icons-common");
var _Input = _interopRequireDefault(require("../Input"));
var _InputWithOptions = _interopRequireDefault(require("../InputWithOptions"));
var _google2address = require("./google2address");
var _GoogleAddressInputSt = require("./GoogleAddressInput.st.css");
var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/GoogleAddressInput/GoogleAddressInput.js",
_GoogleAddressInput;
/* eslint-disable no-console */
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 _objectSpread(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) { (0, _defineProperty2.default)(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; }
var GoogleAddressInputHandler = exports.GoogleAddressInputHandler = {
geocode: 'geocode',
places: 'places'
};
/**
* Address input box (using Google Maps)
*/
class GoogleAddressInput extends _react.default.Component {
constructor(props) {
super(props);
this.state = {
suggestions: [],
value: props.value || ''
};
this.autoCompleteRequestId = 0;
this.geocodeRequestId = 0;
this.client = new props.Client();
this.onChange = this.onChange.bind(this);
this.onBlur = this.onBlur.bind(this);
this.onFocus = this.onFocus.bind(this);
this.onSet = this.onSet.bind(this);
this.onManuallyInput = this.onManuallyInput.bind(this);
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.value !== this.props.value) {
this._getSuggestions(nextProps.value).then(suggestions => {
this.setState({
suggestions
});
}).catch(() => {
// Nothing really to do...
this.setState({
suggestions: []
});
});
}
}
render() {
var {
suggestions,
value
} = this.state;
var {
magnifyingGlass
} = this.props;
var options = [...suggestions.map((suggestion, index) => {
var {
place_id,
description
} = suggestion;
return {
id: place_id || index,
value: description
};
}), ...(this.props.footer ? [_objectSpread({
id: suggestions.length,
value: this.props.footer
}, this.props.footerOptions)] : [])];
var suffix = magnifyingGlass ? /*#__PURE__*/_react.default.createElement(_Input.default.IconAffix, {
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 79,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.Search, {
"data-hook": "search-icon",
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 80,
columnNumber: 9
}
})) : undefined;
return /*#__PURE__*/_react.default.createElement("div", {
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 85,
columnNumber: 7
}
}, /*#__PURE__*/_react.default.createElement(_InputWithOptions.default, (0, _extends2.default)({
ref: autocomplete => this.autocomplete = autocomplete
}, this.props, {
onInput: this.onChange,
onBlur: this.onBlur,
onFocus: this.onFocus,
onSelect: option => this.onSet(option.value),
onManuallyInput: this.onManuallyInput,
value: value,
options: options,
fixedFooter: suggestions.length && this.props.poweredByGoogle ? GoogleAddressInput.getGoogleFooter() : null,
suffix: suffix,
selectedHighlight: false,
menuArrow: false,
__self: this,
__source: {
fileName: _jsxFileName,
lineNumber: 86,
columnNumber: 9
}
})));
}
focus() {
this.autocomplete.focus();
}
select() {
this.autocomplete.select();
}
onChange(e) {
var value = e.target.value;
this.props.onChange && this.props.onChange(e);
this.props.onSet && this.props.onSet(null);
if (typeof this.props.value !== 'undefined') {
// Controlled mode
return;
}
this._getSuggestions(value).then(suggestions => {
this.setState({
suggestions
});
}).catch(() => {
// Nothing really to do...
this.setState({
suggestions: []
});
});
}
onBlur() {
this.props.onBlur && this.props.onBlur();
if (this.props.clearSuggestionsOnBlur) {
this.timer = setTimeout(() => {
this.setState({
suggestions: []
});
}, 250);
}
}
onFocus() {
this.props.onFocus && this.props.onFocus();
}
onSet(value) {
var {
countryCode,
handler
} = this.props;
var suggestion = this.state.suggestions.find(s => s.description === value);
this.setState({
suggestions: [],
value: this.props.value || value
});
var requestId = ++this.geocodeRequestId;
var handlerCall;
if (handler === GoogleAddressInputHandler.places && suggestion && suggestion.place_id) {
var request = {
request: {
placeId: suggestion.place_id
}
};
if (this.props.placeDetailsFields) {
request.request.fields = this.props.placeDetailsFields;
}
handlerCall = this.client.placeDetails(request);
} else {
handlerCall = this.client.geocode({
request: {
region: countryCode,
[suggestion ? 'placeId' : 'address']: suggestion ? suggestion.place_id : value
}
});
}
handlerCall.then(results => {
results = (0, _castArray.default)(results).filter(Boolean);
if (requestId !== this.geocodeRequestId) {
return;
}
if (results.length === 0) {
console.error("[GoogleAddressInput] handler (".concat(handler, ") returned no results on"), value);
this.props.onSet && this.props.onSet(null);
// This shouldn't happen since we're running geocode on exactly the same
// value returned by suggestions list
return;
}
var firstResult = (0, _google2address.trySetStreetNumberIfNotReceived)(results[0], this.state.value);
var result = {
originValue: value,
googleResult: firstResult,
address: (0, _google2address.google2address)(firstResult)
};
this.props.onSet && this.props.onSet(result);
}).catch(e => {
console.error("[GoogleAddressInput] handler (".concat(handler, ") failed on"), value, e.message);
this.props.onSet && this.props.onSet(null);
});
}
onManuallyInput(inputValue) {
var {
value,
fallbackToManual,
onSet
} = this.props;
if (fallbackToManual) {
this._getSuggestions(inputValue, typeof value !== 'undefined').then(suggestions => {
if (suggestions.length === 0) {
// No suggestion to the text entered
if (inputValue) {
this.onSet(inputValue);
} else {
onSet && onSet(null);
}
}
});
}
}
componentWillUnmount() {
if (this.timer) {
clearTimeout(this.timer);
}
}
_getSuggestions(value, skipSetState) {
var {
valuePrefix = '',
countryCode,
types,
filterTypes
} = this.props;
var requestId = ++this.autoCompleteRequestId;
return new Promise(resolve => {
if (skipSetState) {
// Controlled mode
resolve();
return;
}
this.setState({
value
}, () => resolve());
}).then(() => {
if (value === '') {
return Promise.resolve([]);
}
var request = {
types,
componentRestrictions: {
country: countryCode
},
input: valuePrefix + value
};
return this.client.autocomplete({
request
});
}).then(results => {
if (results.length === 0) {
return Promise.resolve([]);
}
if (requestId !== this.autoCompleteRequestId) {
return Promise.resolve([]);
}
if (filterTypes) {
results = results.filter(result => (0, _google2address.includes)(result.types, filterTypes));
}
return Promise.resolve(results);
});
}
}
_GoogleAddressInput = GoogleAddressInput;
GoogleAddressInput.getGoogleFooter = () => /*#__PURE__*/_react.default.createElement("div", {
className: _GoogleAddressInputSt.classes.googleFooter,
"data-hook": "google-footer",
__self: _GoogleAddressInput,
__source: {
fileName: _jsxFileName,
lineNumber: 110,
columnNumber: 5
}
});
GoogleAddressInput.displayName = 'GoogleAddressInput';
GoogleAddressInput.defaultProps = {
magnifyingGlass: true,
autoSelect: true,
footerOptions: {},
clearSuggestionsOnBlur: true,
fallbackToManual: false,
poweredByGoogle: false,
handler: GoogleAddressInputHandler.geocode
};
GoogleAddressInput.propTypes = {
/** Placeholder for the input box */
placeholder: _propTypes.default.string,
/** Value to place before every search term (normally should not be used) */
valuePrefix: _propTypes.default.string,
/** Country code used to help with suggestions and geocoding */
countryCode: _propTypes.default.string,
/** Controlled mode - value to display */
value: _propTypes.default.string,
/** Limit the autocomplete to specific types (see [here](https://developers.google.com/places/supported_types#table3) for list) */
types: _propTypes.default.array,
/** Lower level filtering of autocomplete result types (see [here](https://developers.google.com/places/supported_types) for list) */
filterTypes: _propTypes.default.array,
/** Fields indicating which types of Places data to return (see [here](https://developers.google.com/maps/documentation/javascript/places#place_details)**/
placeDetailsFields: _propTypes.default.array,
/** Sets UI to indicate a status */
status: _propTypes.default.oneOf(['error', 'warning', 'loading']),
/** The status message to display when hovering the status icon, if not given or empty there will be no tooltip */
statusMessage: _propTypes.default.node,
onChange: _propTypes.default.func,
onBlur: _propTypes.default.func,
onFocus: _propTypes.default.func,
onKeyDown: _propTypes.default.func,
/** Callback for results. Will return an object containing: originValue (value in the search), googleResult (google geocode result for the search), address (which will include: formatted (google formatted address), country, countryCode, street, number, postalCode, latLng (lat, lng)) */
onSet: _propTypes.default.func,
/** Google map client implementation (should implement autocomplete and geocode functions). Normally you would use wix-style-react/clients/GoogleMapsClient */
Client: _propTypes.default.func.isRequired,
/** Show or hide magnifying glass icon */
magnifyingGlass: _propTypes.default.bool,
/** Sets the input to readOnly */
readOnly: _propTypes.default.bool,
autoSelect: _propTypes.default.bool,
/** Display a footer as the last suggestion in the list */
footer: _propTypes.default.any,
/** Set the footer's options (e.g. disabled, overrideStyles, etc. ) */
footerOptions: _propTypes.default.object,
/** Clear the suggestions list upon input blur */
clearSuggestionsOnBlur: _propTypes.default.bool,
/** If set to `true`, we will attempt to get a Google location from the input's text if there are no suggestions. This is useful when looking for locations for which google does not give suggestions - for example: Apartment/Apt */
fallbackToManual: _propTypes.default.bool,
/** Shows the Powered By Google credit in a fixed footer */
poweredByGoogle: _propTypes.default.bool,
/** Sets how to get more details for a place (e.g. geocode, places, etc) */
handler: _propTypes.default.oneOf([GoogleAddressInputHandler.geocode, GoogleAddressInputHandler.places])
};
var _default = exports.default = GoogleAddressInput;
//# sourceMappingURL=GoogleAddressInput.js.map