UNPKG

@lonelyplanet/dotcom-core

Version:

This package is meant to house some of our more common UI and shared libs across dotcom applications.

494 lines (409 loc) 13.9 kB
"use strict"; var __extends = this && this.__extends || function () { var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; } || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; }(); var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = this && this.__generator || function (thisArg, body) { var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var moreLink_1 = require("backpack-ui/dist/components/moreLink"); var text_1 = require("backpack-ui/dist/components/text"); var cn = require("classnames"); var React = require("react"); var cleanQuery_1 = require("../../helpers/cleanQuery"); var template_1 = require("../../templates/template"); var container_1 = require("../_backpack/container"); var overlay_1 = require("../_backpack/overlay"); var autocompleteResults_1 = require("../autocompleteResults"); var searchInput_1 = require("../searchInput"); var searchInputCancelButton_1 = require("../searchInputCancelButton"); var styles = { "autocomplete": "lp-global-autocomplete", "autocompleteWithResults": "lp-global-autocompleteWithResults", "autocompleteSearchForm": "lp-global-autocompleteSearchForm", "autocompleteInputLabel": "lp-global-autocompleteInputLabel", "autocompleteResultsContainer": "lp-global-autocompleteResultsContainer", "autocompleteResults": "lp-global-autocompleteResults", "autocompleteHeading": "lp-global-autocompleteHeading", "autocompleteLinkContainer": "lp-global-autocompleteLinkContainer", "autocompleteLink": "lp-global-autocompleteLink" }; var GlobalAutocomplete = /** @class */ function (_super) { __extends(GlobalAutocomplete, _super); function GlobalAutocomplete(props) { var _this = _super.call(this, props) || this; _this.delaySearch = 150; _this.handleSearch = function (e) { clearTimeout(_this.delayTimer); if (e.target.value !== _this.state.keyword) { _this.setState({ keyword: e.target.value }, function () { _this.delayTimer = setTimeout(function () { _this.fetchData(); }, _this.delaySearch); }); } }; _this.handleClickAway = function (e) { e.preventDefault(); _this.resetInput(); _this.clearData(); _this.enableScrolling(); _this.autocomplete.current.blur(); }; _this.handleKeydown = function (e) { if (e.keyCode === 27 && _this.state.isOpen) { e.preventDefault(); _this.resetInput(); _this.clearData(); _this.enableScrolling(); } }; _this.state = { keyword: "", isOpen: false, places: [], pois: [], news: [] }; _this.autocomplete = React.createRef(); return _this; } GlobalAutocomplete.prototype.componentDidMount = function () { var _this = this; var $ = window.$; var $search = $(".js-lp-global-header-search, .js-lp-search"); $search.on("click", function (e) { e.preventDefault(); _this.setState({ isOpen: true }); _this.disableScrolling(); _this.autocomplete.current.focus(); }); if (typeof document !== "undefined") { document.addEventListener("keydown", this.handleKeydown); } }; GlobalAutocomplete.prototype.componentDidUpdate = function (prevProps, prevState) { var _this = this; clearTimeout(this.scrollTimer); if (this.state.keyword !== "" && this.state.keyword === prevState.keyword) { var $ = window.$; var $results_1 = $(".js-templateAreaResultsAutocomplete"); var $keywords_1 = $(".js-templateAreaKeywordsAutocomplete"); $results_1.on("scroll", function (e) { e.preventDefault(); _this.scrollTimer = setTimeout(function () { if ($results_1.scrollTop() > 10) { $keywords_1.addClass("lp-global-templateAreaKeywordsAutocompleteShadow"); } else { $keywords_1.removeClass("lp-global-templateAreaKeywordsAutocompleteShadow"); } }, 50); }); } }; GlobalAutocomplete.prototype.componentWillUnmount = function () { if (typeof document !== "undefined") { document.removeEventListener("keydown", this.handleKeydown); } }; GlobalAutocomplete.prototype.render = function () { var _this = this; var totalResults = this.state.places.length + this.state.pois.length + this.state.news.length; return React.createElement(React.Fragment, null, this.state.isOpen && React.createElement(React.Fragment, null, React.createElement("div", { className: cn(styles.autocomplete, totalResults > 0 && styles.autocompleteWithResults) }, React.createElement(template_1.default.Autocomplete, null, React.createElement(template_1.default.Position, { area: "keywords" }, React.createElement(container_1.default, null, React.createElement("form", { action: "https://www.lonelyplanet.com/search?q=" + encodeURI(this.state.keyword), className: styles.autocompleteSearchForm, onSubmit: function (e) { e.preventDefault(); window.location.href = "https://www.lonelyplanet.com/search?q=" + encodeURI(_this.state.keyword); } }, React.createElement("label", { className: styles.autocompleteInputLabel, htmlFor: "lp-search-input" }, React.createElement("svg", { className: "svg-icon", viewBox: "0 0 32 32", "aria-hidden": "true" }, React.createElement("path", { d: "M32 30.2l-8.4-8.4c2-2.4 3-5.3 3-8.4 0-7.4-6-13.4-13.3-13.4s-13.3 6-13.3 13.3 6 13.3 13.3 13.3c3.1 0 6.1-1.1 8.4-3l8.4 8.4 1.9-1.8zM2.6 13.3c0-5.9 4.8-10.7 10.7-10.7s10.7 4.8 10.7 10.7c0 2.8-1.1 5.5-3 7.5-2 2.1-4.8 3.2-7.7 3.2-5.9 0-10.7-4.8-10.7-10.7z" }))), React.createElement(searchInput_1.default, { onChange: this.handleSearch, placeholder: "Search places, cities, countries and continents", ref: this.autocomplete, value: this.state.keyword, id: "lp-search-input" }), React.createElement(searchInputCancelButton_1.default, { onClick: this.handleClickAway })))), totalResults > 0 && React.createElement(template_1.default.Position, { area: "results" }, React.createElement(container_1.default, { className: styles.autocompleteResultsContainer }, this.state.places && this.state.places.length > 0 && React.createElement("div", { className: styles.autocompleteResults }, React.createElement(text_1.Heading, { className: styles.autocompleteHeading, level: 2, size: 6, weight: "light" }, "Destinations"), React.createElement(autocompleteResults_1.AutocompleteResults.List, { items: this.state.places })), this.state.pois && this.state.pois.length > 0 && React.createElement("div", { className: styles.autocompleteResults }, React.createElement(text_1.Heading, { className: styles.autocompleteHeading, level: 2, size: 6, weight: "light" }, "Points of interest"), React.createElement(autocompleteResults_1.AutocompleteResults.List, { items: this.state.pois })), this.state.news && this.state.news.length > 0 && React.createElement("div", { className: styles.autocompleteResults }, React.createElement(text_1.Heading, { className: styles.autocompleteHeading, level: 2, size: 6, weight: "light" }, "News and articles"), React.createElement(autocompleteResults_1.AutocompleteResults.List, { items: this.state.news }))), React.createElement(container_1.default, { className: styles.autocompleteLinkContainer }, React.createElement("div", { className: styles.autocompleteLink }, React.createElement(moreLink_1.default, { href: "https://www.lonelyplanet.com/search?q=" + encodeURI(this.state.keyword), size: "small", caps: true }, "See all results")))))), React.createElement(overlay_1.default, { onClick: this.handleClickAway }))); }; GlobalAutocomplete.prototype.clearData = function () { this.setState({ places: [], pois: [], news: [] }); }; GlobalAutocomplete.prototype.resetInput = function () { this.setState({ keyword: "", isOpen: false }); }; GlobalAutocomplete.prototype.fetchData = function () { return __awaiter(this, void 0, void 0, function () { var resultsMax, query, _a, places, pois, news; return __generator(this, function (_b) { switch (_b.label) { case 0: resultsMax = 4; query = cleanQuery_1.default(this.state.keyword); if (!query.length) return [3 /*break*/ , 2]; return [4 /*yield*/ , Promise.all([this.callFetch(query, "place"), this.callFetch(query, "poi"), this.callFetch(query, "video,article,news")])]; case 1: _a = _b.sent(), places = _a[0], pois = _a[1], news = _a[2]; this.setState({ places: places.data.slice(0, resultsMax), pois: pois.data.slice(0, resultsMax), news: news.data.slice(0, resultsMax) }); return [3 /*break*/ , 3]; case 2: this.clearData(); _b.label = 3; case 3: return [2 /*return*/ ]; } }); }); }; GlobalAutocomplete.prototype.callFetch = function (query, type) { return __awaiter(this, void 0, void 0, function () { var response; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/ , fetch("https://www.lonelyplanet.com/search/api?q=" + query + "&type=" + type)]; case 1: response = _a.sent(); if (!response.ok) { return [2 /*return*/ , { total: 0, data: [], error: true }]; } return [4 /*yield*/ , response.json()]; case 2: return [2 /*return*/ , _a.sent()]; } }); }); }; GlobalAutocomplete.prototype.disableScrolling = function () { if (typeof document !== "undefined") { document.documentElement.style.height = "100%"; document.documentElement.style.overflow = "hidden"; document.body.style.height = "100%"; document.body.style.overflow = "hidden"; } }; GlobalAutocomplete.prototype.enableScrolling = function () { if (typeof document !== "undefined") { document.documentElement.removeAttribute("style"); document.body.removeAttribute("style"); } }; return GlobalAutocomplete; }(React.PureComponent); exports.GlobalAutocomplete = GlobalAutocomplete; exports.default = GlobalAutocomplete;