forked from lekoala/bootstrap5-autocomplete
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautocomplete.min.js.map
7 lines (7 loc) · 29.9 KB
/
autocomplete.min.js.map
1
2
3
4
5
6
7
{
"version": 3,
"sources": ["autocomplete.js"],
"sourcesContent": ["/**\r\n * Bootstrap 5 autocomplete\r\n */\r\n\r\n// #region config\r\n\r\n/**\r\n * @typedef Config\r\n * @property {Boolean} showAllSuggestions Show all suggestions even if they don't match\r\n * @property {Number} suggestionsThreshold Number of chars required to show suggestions\r\n * @property {Number} maximumItems Maximum number of items to display\r\n * @property {Boolean} autoselectFirst Always select the first item\r\n * @property {Boolean} updateOnSelect Update input value on selection (doesn't play nice with autoselectFirst)\r\n * @property {Boolean} highlightTyped Highlight matched part of the label\r\n * @property {Boolean} fullWidth Match the width on the input field\r\n * @property {String} labelField Key for the label\r\n * @property {String} valueField Key for the value\r\n * @property {String} queryField Key for the query parameter for server\r\n * @property {Array|Object} items An array of label/value objects or an object with key/values\r\n * @property {Function} source A function that provides the list of items\r\n * @property {String} datalist The id of the source datalist\r\n * @property {String} server Endpoint for data provider\r\n * @property {String|Object} serverParams Parameters to pass along to the server\r\n * @property {Boolean} liveServer Should the endpoint be called each time on input\r\n * @property {Boolean} noCache Prevent caching by appending a timestamp\r\n * @property {Number} debounceTime Debounce time for live server\r\n * @property {String} notFoundMessage Display a no suggestions found message. Leave empty to disable\r\n * @property {Function} onRenderItem Callback function that returns the label\r\n * @property {Function} onSelectItem Callback function to call on selection\r\n * @property {Function} onServerResponse Callback function to process server response\r\n */\r\n\r\n/**\r\n * @type {Config}\r\n */\r\nconst DEFAULTS = {\r\n showAllSuggestions: false,\r\n suggestionsThreshold: 1,\r\n maximumItems: 0,\r\n autoselectFirst: true,\r\n updateOnSelect: false,\r\n highlightTyped: false,\r\n fullWidth: false,\r\n labelField: \"label\",\r\n valueField: \"value\",\r\n queryField: \"query\",\r\n items: [],\r\n source: null,\r\n datalist: \"\",\r\n server: \"\",\r\n serverParams: {},\r\n liveServer: false,\r\n noCache: true,\r\n debounceTime: 300,\r\n notFoundMessage: \"\",\r\n onRenderItem: (item, label) => {\r\n return label;\r\n },\r\n onSelectItem: (item) => {},\r\n onServerResponse: (response) => {\r\n return response.json();\r\n },\r\n};\r\n\r\n// #endregion\r\n\r\n// #region constants\r\n\r\nconst LOADING_CLASS = \"is-loading\";\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst NEXT = \"next\";\r\nconst PREV = \"prev\";\r\n\r\nconst INSTANCE_MAP = new WeakMap();\r\nlet counter = 0;\r\n\r\n// #endregion\r\n\r\n// #region functions\r\n\r\n/**\r\n * @param {Function} func\r\n * @param {number} timeout\r\n * @returns {Function}\r\n */\r\nfunction debounce(func, timeout = 300) {\r\n let timer;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n //@ts-ignore\r\n func.apply(this, args);\r\n }, timeout);\r\n };\r\n}\r\n\r\n/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nfunction removeDiacritics(str) {\r\n return str.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {HTMLElement} newEl\r\n * @returns {HTMLElement}\r\n */\r\nfunction insertAfter(el, newEl) {\r\n return el.parentNode.insertBefore(newEl, el.nextSibling);\r\n}\r\n\r\n// #endregion\r\n\r\nclass Autocomplete {\r\n /**\r\n * @param {HTMLInputElement} el\r\n * @param {Config|Object} config\r\n */\r\n constructor(el, config = {}) {\r\n INSTANCE_MAP.set(el, this);\r\n counter++;\r\n this._searchInput = el;\r\n\r\n this._configure(config);\r\n\r\n // Private vars\r\n this._preventInput = false;\r\n this._keyboardNavigation = false;\r\n this._searchFunc = debounce(() => {\r\n this._loadFromServer(true);\r\n }, this._config.debounceTime);\r\n\r\n // Create html\r\n this._configureSearchInput();\r\n this._configureDropElement();\r\n\r\n // Add listeners (remove then on dispose()). See handleEvent.\r\n this._searchInput.addEventListener(\"focus\", this);\r\n this._searchInput.addEventListener(\"blur\", this);\r\n this._searchInput.addEventListener(\"input\", this);\r\n this._searchInput.addEventListener(\"keydown\", this);\r\n this._dropElement.addEventListener(\"mousemove\", this);\r\n\r\n this._fetchData();\r\n }\r\n\r\n // #region Core\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Config|Object} config\r\n */\r\n static init(selector = \"input.autocomplete\", config = {}) {\r\n /**\r\n * @type {NodeListOf<HTMLInputElement>}\r\n */\r\n const nodes = document.querySelectorAll(selector);\r\n nodes.forEach((el) => {\r\n this.getOrCreateInstance(el, config);\r\n });\r\n }\r\n\r\n /**\r\n * @param {HTMLInputElement} el\r\n */\r\n static getInstance(el) {\r\n return INSTANCE_MAP.has(el) ? INSTANCE_MAP.get(el) : null;\r\n }\r\n\r\n /**\r\n * @param {HTMLInputElement} el\r\n * @param {Object} config\r\n */\r\n static getOrCreateInstance(el, config = {}) {\r\n return this.getInstance(el) || new this(el, config);\r\n }\r\n\r\n dispose() {\r\n this._searchInput.removeEventListener(\"focus\", this);\r\n this._searchInput.removeEventListener(\"blur\", this);\r\n this._searchInput.removeEventListener(\"input\", this);\r\n this._searchInput.removeEventListener(\"keydown\", this);\r\n this._dropElement.removeEventListener(\"mousemove\", this);\r\n\r\n this._dropElement.parentElement.removeChild(this._dropElement);\r\n\r\n INSTANCE_MAP.delete(this._searchInput);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n this[`on${event.type}`](event);\r\n }\r\n\r\n /**\r\n * @param {Config|Object} config\r\n */\r\n _configure(config = {}) {\r\n this._config = Object.assign({}, DEFAULTS);\r\n\r\n // Handle options, using arguments first and data attr as override\r\n const o = { ...config, ...this._searchInput.dataset };\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Typecast provided options based on defaults types\r\n for (const [key, defaultValue] of Object.entries(DEFAULTS)) {\r\n // Check for undefined keys\r\n if (o[key] === void 0) {\r\n continue;\r\n }\r\n const value = o[key];\r\n switch (typeof defaultValue) {\r\n case \"number\":\r\n this._config[key] = parseInt(value);\r\n break;\r\n case \"boolean\":\r\n this._config[key] = parseBool(value);\r\n break;\r\n case \"string\":\r\n this._config[key] = value.toString();\r\n break;\r\n case \"object\":\r\n // Arrays have a type object in js\r\n if (Array.isArray(defaultValue)) {\r\n if (typeof value === \"string\") {\r\n const separator = value.includes(\"|\") ? \"|\" : \",\";\r\n this._config[key] = value.split(separator);\r\n } else {\r\n this._config[key] = value;\r\n }\r\n } else {\r\n this._config[key] = typeof value === \"string\" ? JSON.parse(value) : value;\r\n }\r\n break;\r\n case \"function\":\r\n this._config[key] = typeof value === \"string\" ? window[value] : value;\r\n break;\r\n default:\r\n this._config[key] = value;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Html\r\n\r\n _configureSearchInput() {\r\n this._searchInput.autocomplete = \"off\";\r\n this._searchInput.spellcheck = false;\r\n // @link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-autocomplete\r\n this._searchInput.ariaAutoComplete = \"list\";\r\n // @link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded\r\n // use the aria-expanded state on the element with role combobox to communicate that the list is displayed.\r\n this._searchInput.ariaExpanded = \"false\";\r\n // include aria-haspopup matching the role of the element that contains the collection of suggested values.\r\n this._searchInput.ariaHasPopup = \"menu\";\r\n this._searchInput.setAttribute(\"role\", \"combobox\");\r\n }\r\n\r\n _configureDropElement() {\r\n this._dropElement = document.createElement(\"ul\");\r\n this._dropElement.setAttribute(\"id\", \"ac-menu-\" + counter);\r\n this._dropElement.setAttribute(\"role\", \"menu\");\r\n this._dropElement.classList.add(...[\"dropdown-menu\", \"autocomplete-menu\", \"p-0\"]);\r\n this._dropElement.style.maxHeight = \"280px\";\r\n if (!this._config.fullWidth) {\r\n this._dropElement.style.maxWidth = \"360px\";\r\n }\r\n this._dropElement.style.overflowY = \"auto\";\r\n\r\n insertAfter(this._searchInput, this._dropElement);\r\n // include aria-controls with the value of the id of the suggested list of values.\r\n this._searchInput.setAttribute(\"aria-controls\", this._dropElement.getAttribute(\"id\"));\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Events\r\n\r\n oninput(e) {\r\n if (this._preventInput) {\r\n return;\r\n }\r\n this._showOrSearch();\r\n }\r\n\r\n onblur(e) {\r\n this._hideSuggestions();\r\n }\r\n\r\n onfocus(e) {\r\n this._showOrSearch();\r\n }\r\n\r\n /**\r\n * keypress doesn't send arrow keys, so we use keydown\r\n * @param {KeyboardEvent} e\r\n */\r\n onkeydown(e) {\r\n const key = e.keyCode || e.key;\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n e.preventDefault();\r\n const selection = this.getSelection();\r\n if (selection) {\r\n selection.click();\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n e.preventDefault();\r\n this._keyboardNavigation = true;\r\n this._moveSelection(PREV);\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n e.preventDefault();\r\n this._keyboardNavigation = true;\r\n this._moveSelection(NEXT);\r\n break;\r\n case 27:\r\n case \"Escape\":\r\n this._searchInput.focus();\r\n this._hideSuggestions();\r\n break;\r\n }\r\n }\r\n\r\n onmousemove(e) {\r\n // Moving the mouse means no longer using keyboard\r\n this._keyboardNavigation = false;\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Api\r\n\r\n /**\r\n * @param {String} k\r\n * @returns {Config}\r\n */\r\n getConfig(k = null) {\r\n if (k !== null) {\r\n return this._config[k];\r\n }\r\n return this._config;\r\n }\r\n\r\n /**\r\n * @param {String} k\r\n * @param {*} v\r\n */\r\n setConfig(k, v) {\r\n this._config[k] = v;\r\n }\r\n\r\n setData(src) {\r\n this._items = {};\r\n this._addItems(src);\r\n }\r\n\r\n enable() {\r\n this._searchInput.setAttribute(\"disabled\", \"\");\r\n }\r\n\r\n disable() {\r\n this._searchInput.removeAttribute(\"disabled\");\r\n }\r\n\r\n /**\r\n * @returns {boolean}\r\n */\r\n isDisabled() {\r\n return this._searchInput.hasAttribute(\"disabled\") || this._searchInput.disabled || this._searchInput.hasAttribute(\"readonly\");\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Selection management\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getSelection() {\r\n return this._dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeSelection() {\r\n const selection = this.getSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n /**\r\n * @param {String} dir\r\n * @returns {HTMLElement}\r\n */\r\n _moveSelection(dir = NEXT) {\r\n const active = this.getSelection();\r\n /**\r\n * @type {*}\r\n */\r\n let sel = null;\r\n\r\n // select first li\r\n if (!active) {\r\n sel = this._dropElement.firstChild;\r\n } else {\r\n const sibling = dir === NEXT ? \"nextSibling\" : \"previousSibling\";\r\n\r\n // Iterate over visible li\r\n sel = active.parentNode;\r\n do {\r\n sel = sel[sibling];\r\n } while (sel && sel.style.display == \"none\");\r\n\r\n // We have a new selection\r\n if (sel) {\r\n // Change classes\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Scroll if necessary\r\n if (dir === PREV) {\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n sel.parentNode.scrollTop = sel.offsetTop - sel.parentNode.offsetTop;\r\n } else {\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (sel.offsetTop > sel.parentNode.offsetHeight - sel.offsetHeight) {\r\n sel.parentNode.scrollTop += sel.offsetHeight;\r\n }\r\n }\r\n } else if (active) {\r\n sel = active.parentElement;\r\n }\r\n }\r\n\r\n if (sel) {\r\n const a = sel.querySelector(\"a\");\r\n a.classList.add(...ACTIVE_CLASSES);\r\n this._searchInput.setAttribute(\"aria-activedescendant\", a.getAttribute(\"id\"));\r\n if (this._config.updateOnSelect) {\r\n this._searchInput.value = a.dataset.label;\r\n }\r\n } else {\r\n this._searchInput.setAttribute(\"aria-activedescendant\", \"\");\r\n }\r\n return sel;\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Implementation\r\n\r\n /**\r\n * Do we have enough input to show suggestions ?\r\n * @returns {Boolean}\r\n */\r\n _shouldShow() {\r\n if (this.isDisabled()) {\r\n return false;\r\n }\r\n return this._searchInput.value.length >= this._config.suggestionsThreshold;\r\n }\r\n\r\n /**\r\n * Show suggestions or load them\r\n */\r\n _showOrSearch() {\r\n if (!this._shouldShow()) {\r\n this._hideSuggestions();\r\n return;\r\n }\r\n if (this._config.liveServer) {\r\n this._searchFunc();\r\n } else if (this._config.source) {\r\n this._config.source(this._searchInput.value, (items) => {\r\n this.setData(items);\r\n this._showSuggestions();\r\n });\r\n } else {\r\n this._showSuggestions();\r\n }\r\n }\r\n\r\n /**\r\n * @param {String} lookup\r\n * @param {Object} item\r\n * @returns {HTMLElement}\r\n */\r\n _createItem(lookup, item) {\r\n let label = item.label;\r\n\r\n if (this._config.highlightTyped) {\r\n const idx = removeDiacritics(label).toLowerCase().indexOf(lookup);\r\n label =\r\n label.substring(0, idx) +\r\n `<mark>${label.substring(idx, idx + lookup.length)}</mark>` +\r\n label.substring(idx + lookup.length, label.length);\r\n }\r\n\r\n label = this._config.onRenderItem(item, label);\r\n\r\n const newChild = document.createElement(\"li\");\r\n newChild.setAttribute(\"role\", \"presentation\");\r\n const newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.setAttribute(\"id\", this._dropElement.getAttribute(\"id\") + \"-\" + this._dropElement.children.length);\r\n newChildLink.classList.add(...[\"dropdown-item\", \"text-truncate\"]);\r\n newChildLink.setAttribute(\"data-value\", item.value);\r\n newChildLink.setAttribute(\"data-label\", item.label);\r\n // Behave like a datalist (tab doesn't allow item selection)\r\n // @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist\r\n newChildLink.setAttribute(\"tabindex\", \"-1\");\r\n newChildLink.setAttribute(\"role\", \"menuitem\");\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerHTML = label;\r\n if (item.data) {\r\n for (const [key, value] of Object.entries(item.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this._keyboardNavigation) {\r\n return;\r\n }\r\n this.removeSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Prevent searchInput losing focus and close the menu\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n event.preventDefault();\r\n });\r\n // Apply value\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n\r\n // Prevent input otherwise it might trigger autocomplete due to value change\r\n this._preventInput = true;\r\n this._searchInput.value = item.label;\r\n this._config.onSelectItem(item);\r\n this._hideSuggestions();\r\n this._preventInput = false;\r\n });\r\n\r\n return newChild;\r\n }\r\n\r\n /**\r\n * Show drop menu with suggestions\r\n */\r\n _showSuggestions() {\r\n const lookup = removeDiacritics(this._searchInput.value).toLowerCase();\r\n this._dropElement.innerHTML = \"\";\r\n\r\n const keys = Object.keys(this._items);\r\n let count = 0;\r\n let firstItem = null;\r\n for (let i = 0; i < keys.length; i++) {\r\n const key = keys[i];\r\n const entry = this._items[key];\r\n\r\n const text = removeDiacritics(entry.label).toLowerCase();\r\n const isMatched = lookup.length > 0 ? text.indexOf(lookup) >= 0 : true;\r\n if (this._config.showAllSuggestions || isMatched) {\r\n count++;\r\n const newItem = this._createItem(lookup, entry);\r\n if (!firstItem) {\r\n firstItem = newItem;\r\n }\r\n this._dropElement.appendChild(newItem);\r\n if (this._config.maximumItems > 0 && count >= this._config.maximumItems) {\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (firstItem && this._config.autoselectFirst) {\r\n this._moveSelection(NEXT);\r\n }\r\n\r\n if (count === 0) {\r\n if (this._config.notFoundMessage) {\r\n const newChild = document.createElement(\"li\");\r\n newChild.setAttribute(\"role\", \"presentation\");\r\n newChild.innerHTML = `<span class=\"dropdown-item\">${this._config.notFoundMessage}</span>`;\r\n this._dropElement.appendChild(newChild);\r\n } else {\r\n // Remove dropdown if not found\r\n this._hideSuggestions();\r\n }\r\n } else {\r\n // Or show it if necessary\r\n this._dropElement.classList.add(\"show\");\r\n this._searchInput.ariaExpanded = \"true\";\r\n this._positionMenu();\r\n }\r\n }\r\n\r\n /**\r\n * Hide the dropdown menu\r\n */\r\n _hideSuggestions() {\r\n this._dropElement.classList.remove(\"show\");\r\n this._searchInput.ariaExpanded = \"false\";\r\n this.removeSelection();\r\n }\r\n\r\n /**\r\n * Position the dropdown menu\r\n */\r\n _positionMenu() {\r\n if (this._config.fullWidth) {\r\n // Use full input width\r\n this._dropElement.style.left = this._searchInput.offsetLeft + \"px\";\r\n this._dropElement.style.width = this._searchInput.offsetWidth + \"px\";\r\n } else {\r\n // Position next to search input\r\n let left = this._searchInput.offsetLeft;\r\n\r\n // Overflow right\r\n const w = document.body.offsetWidth - 1; // avoid rounding issues\r\n const scrollbarOffset = 30; // scrollbars are not taken into account\r\n const wdiff = w - (left + this._dropElement.offsetWidth) - scrollbarOffset;\r\n\r\n // If the dropdowns goes out of the viewport, remove the diff from the left position\r\n if (wdiff < 0) {\r\n left = left + wdiff;\r\n }\r\n this._dropElement.style.left = left + \"px\";\r\n }\r\n\r\n // Overflow bottom\r\n const h = document.body.offsetHeight;\r\n const bottom = this._searchInput.getBoundingClientRect().y + window.pageYOffset + this._dropElement.offsetHeight;\r\n\r\n const hdiff = h - bottom;\r\n if (hdiff < 0) {\r\n // We display above input\r\n this._dropElement.style.transform = \"translateY(calc(-100% - \" + this._searchInput.offsetHeight + \"px))\";\r\n } else {\r\n this._dropElement.style.transform = \"none\";\r\n }\r\n }\r\n\r\n _fetchData() {\r\n this._items = {};\r\n\r\n // From an array of items or an object\r\n this._addItems(this._config.items);\r\n\r\n // From a datalist\r\n if (this._config.datalist) {\r\n const datalist = document.querySelector(`#${this._config.datalist}`);\r\n if (datalist) {\r\n const items = Array.from(datalist.children).map((o) => {\r\n const value = o.getAttribute(\"value\") ?? o.innerHTML.toLowerCase();\r\n const label = o.innerHTML;\r\n\r\n return {\r\n value: value,\r\n label: label,\r\n };\r\n });\r\n this._addItems(items);\r\n }\r\n }\r\n\r\n // From an external source\r\n if (this._config.server && !this._config.liveServer) {\r\n this._loadFromServer();\r\n }\r\n }\r\n\r\n _addItems(src) {\r\n const keys = Object.keys(src);\r\n for (let i = 0; i < keys.length; i++) {\r\n const key = keys[i];\r\n const entry = src[key];\r\n const item = typeof entry === \"string\" ? {} : entry;\r\n\r\n // Normalize entry\r\n item.label = entry[this._config.labelField] ?? entry;\r\n item.value = entry[this._config.valueField] ?? key;\r\n this._items[item.value] = item;\r\n }\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n _loadFromServer(show = false) {\r\n if (this._abortController) {\r\n this._abortController.abort();\r\n }\r\n this._abortController = new AbortController();\r\n\r\n const params = Object.assign({}, this._config.serverParams);\r\n // Pass current value\r\n params[this._config.queryField] = this._searchInput.value;\r\n // Prevent caching\r\n if (this._config.noCache) {\r\n params.t = Date.now();\r\n }\r\n // We have a related field\r\n if (params.related) {\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n //@ts-ignore\r\n const input = document.getElementById(params.related);\r\n if (input) {\r\n params.related = input.value;\r\n }\r\n }\r\n const urlParams = new URLSearchParams(params).toString();\r\n\r\n this._searchInput.classList.add(LOADING_CLASS);\r\n fetch(this._config.server + \"?\" + urlParams, { signal: this._abortController.signal })\r\n .then((r) => this._config.onServerResponse(r))\r\n .then((suggestions) => {\r\n const data = suggestions.data || suggestions;\r\n this.setData(data);\r\n this._abortController = null;\r\n if (show) {\r\n this._showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n })\r\n .finally((e) => {\r\n this._searchInput.classList.remove(LOADING_CLASS);\r\n });\r\n }\r\n\r\n // #endregion\r\n}\r\n\r\nexport default Autocomplete;\r\n"],
"mappings": "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",
"names": []
}