UNPKG

wix-style-react

Version:
353 lines (351 loc) • 12.9 kB
"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