UNPKG

wix-style-react

Version:
439 lines (366 loc) • 16.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.GoogleAddressInputHandler = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); 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 _Search = _interopRequireDefault(require("wix-ui-icons-common/Search")); var _Input = _interopRequireDefault(require("../Input")); var _InputWithOptions = _interopRequireDefault(require("../InputWithOptions")); var _google2address = require("./google2address"); var _GoogleAddressInputSt = require("./GoogleAddressInput.st.css"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(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; } } var GoogleAddressInputHandler = { geocode: 'geocode', places: 'places' }; /** * Address input box (using Google Maps) */ exports.GoogleAddressInputHandler = GoogleAddressInputHandler; var GoogleAddressInput = /*#__PURE__*/function (_React$Component) { (0, _inherits2["default"])(GoogleAddressInput, _React$Component); var _super = _createSuper(GoogleAddressInput); function GoogleAddressInput(props) { var _this; (0, _classCallCheck2["default"])(this, GoogleAddressInput); _this = _super.call(this, props); _this.state = { suggestions: [], value: props.value || '' }; _this.autoCompleteRequestId = 0; _this.geocodeRequestId = 0; _this.client = new props.Client(); _this.onChange = _this.onChange.bind((0, _assertThisInitialized2["default"])(_this)); _this.onBlur = _this.onBlur.bind((0, _assertThisInitialized2["default"])(_this)); _this.onFocus = _this.onFocus.bind((0, _assertThisInitialized2["default"])(_this)); _this.onSet = _this.onSet.bind((0, _assertThisInitialized2["default"])(_this)); _this.onManuallyInput = _this.onManuallyInput.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(GoogleAddressInput, [{ key: "UNSAFE_componentWillReceiveProps", value: function UNSAFE_componentWillReceiveProps(nextProps) { var _this2 = this; if (nextProps.value !== this.props.value) { this._getSuggestions(nextProps.value).then(function (suggestions) { _this2.setState({ suggestions: suggestions }); })["catch"](function () { // Nothing really to do... _this2.setState({ suggestions: [] }); }); } } }, { key: "render", value: function render() { var _this3 = this; var _this$state = this.state, suggestions = _this$state.suggestions, value = _this$state.value; var magnifyingGlass = this.props.magnifyingGlass; var options = [].concat((0, _toConsumableArray2["default"])(suggestions.map(function (suggestion, index) { var place_id = suggestion.place_id, description = suggestion.description; return { id: place_id || index, value: description }; })), (0, _toConsumableArray2["default"])(this.props.footer ? [_objectSpread({ id: suggestions.length, value: this.props.footer }, this.props.footerOptions)] : [])); var suffix = magnifyingGlass ? /*#__PURE__*/_react["default"].createElement(_Input["default"].IconAffix, null, /*#__PURE__*/_react["default"].createElement(_Search["default"], { "data-hook": "search-icon" })) : undefined; return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement(_InputWithOptions["default"], (0, _extends2["default"])({ ref: function ref(autocomplete) { return _this3.autocomplete = autocomplete; } }, this.props, { onInput: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onSelect: function onSelect(option) { return _this3.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 }))); } }, { key: "focus", value: function focus() { this.autocomplete.focus(); } }, { key: "select", value: function select() { this.autocomplete.select(); } }, { key: "onChange", value: function onChange(e) { var _this4 = this; 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(function (suggestions) { _this4.setState({ suggestions: suggestions }); })["catch"](function () { // Nothing really to do... _this4.setState({ suggestions: [] }); }); } }, { key: "onBlur", value: function onBlur() { var _this5 = this; this.props.onBlur && this.props.onBlur(); if (this.props.clearSuggestionsOnBlur) { this.timer = setTimeout(function () { _this5.setState({ suggestions: [] }); }, 250); } } }, { key: "onFocus", value: function onFocus() { this.props.onFocus && this.props.onFocus(); } }, { key: "onSet", value: function onSet(value) { var _this6 = this; var _this$props = this.props, countryCode = _this$props.countryCode, handler = _this$props.handler; var suggestion = this.state.suggestions.find(function (s) { return 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: (0, _defineProperty2["default"])({ region: countryCode }, suggestion ? 'placeId' : 'address', suggestion ? suggestion.place_id : value) }); } handlerCall.then(function (results) { results = (0, _castArray["default"])(results).filter(Boolean); if (requestId !== _this6.geocodeRequestId) { return; } if (results.length === 0) { console.error("[GoogleAddressInput] handler (".concat(handler, ") returned no results on"), value); _this6.props.onSet && _this6.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], _this6.state.value); var result = { originValue: value, googleResult: firstResult, address: (0, _google2address.google2address)(firstResult) }; _this6.props.onSet && _this6.props.onSet(result); })["catch"](function (e) { console.error("[GoogleAddressInput] handler (".concat(handler, ") failed on"), value, e.message); _this6.props.onSet && _this6.props.onSet(null); }); } }, { key: "onManuallyInput", value: function onManuallyInput(inputValue) { var _this7 = this; var _this$props2 = this.props, value = _this$props2.value, fallbackToManual = _this$props2.fallbackToManual, onSet = _this$props2.onSet; if (fallbackToManual) { this._getSuggestions(inputValue, typeof value !== 'undefined').then(function (suggestions) { if (suggestions.length === 0) { // No suggestion to the text entered if (inputValue) { _this7.onSet(inputValue); } else { onSet && onSet(null); } } }); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this.timer) { clearTimeout(this.timer); } } }, { key: "_getSuggestions", value: function _getSuggestions(value, skipSetState) { var _this8 = this; var _this$props3 = this.props, _this$props3$valuePre = _this$props3.valuePrefix, valuePrefix = _this$props3$valuePre === void 0 ? '' : _this$props3$valuePre, countryCode = _this$props3.countryCode, types = _this$props3.types, filterTypes = _this$props3.filterTypes; var requestId = ++this.autoCompleteRequestId; return new Promise(function (resolve) { if (skipSetState) { // Controlled mode resolve(); return; } _this8.setState({ value: value }, function () { return resolve(); }); }).then(function () { if (value === '') { return Promise.resolve([]); } var request = { types: types, componentRestrictions: { country: countryCode }, input: valuePrefix + value }; return _this8.client.autocomplete({ request: request }); }).then(function (results) { if (results.length === 0) { return Promise.resolve([]); } if (requestId !== _this8.autoCompleteRequestId) { return Promise.resolve([]); } if (filterTypes) { results = results.filter(function (result) { return (0, _google2address.includes)(result.types, filterTypes); }); } return Promise.resolve(results); }); } }]); return GoogleAddressInput; }(_react["default"].Component); (0, _defineProperty2["default"])(GoogleAddressInput, "getGoogleFooter", function () { return /*#__PURE__*/_react["default"].createElement("div", { className: _GoogleAddressInputSt.classes.googleFooter, "data-hook": "google-footer" }); }); 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 = GoogleAddressInput; exports["default"] = _default;