{"version":3,"file":"stimulus-autocomplete-0uJFzWRU.js","sources":["../../../../../shared/node_modules/stimulus-autocomplete/src/autocomplete.js"],"sourcesContent":["import { Controller } from \"@hotwired/stimulus\"\n\nconst optionSelector = \"[role='option']:not([aria-disabled])\"\nconst activeSelector = \"[aria-selected='true']\"\n\nexport default class Autocomplete extends Controller {\n static targets = [\"input\", \"hidden\", \"results\"]\n static classes = [\"selected\"]\n static values = {\n ready: Boolean,\n submitOnEnter: Boolean,\n url: String,\n minLength: Number,\n delay: { type: Number, default: 300 },\n queryParam: { type: String, default: \"q\" },\n }\n static uniqOptionId = 0\n\n connect() {\n this.close()\n\n if(!this.inputTarget.hasAttribute(\"autocomplete\")) this.inputTarget.setAttribute(\"autocomplete\", \"off\")\n this.inputTarget.setAttribute(\"spellcheck\", \"false\")\n\n this.mouseDown = false\n\n this.onInputChange = debounce(this.onInputChange, this.delayValue)\n\n this.inputTarget.addEventListener(\"keydown\", this.onKeydown)\n this.inputTarget.addEventListener(\"blur\", this.onInputBlur)\n this.inputTarget.addEventListener(\"input\", this.onInputChange)\n this.resultsTarget.addEventListener(\"mousedown\", this.onResultsMouseDown)\n this.resultsTarget.addEventListener(\"click\", this.onResultsClick)\n\n if (this.inputTarget.hasAttribute(\"autofocus\")) {\n this.inputTarget.focus()\n }\n\n this.readyValue = true\n }\n\n disconnect() {\n if (this.hasInputTarget) {\n this.inputTarget.removeEventListener(\"keydown\", this.onKeydown)\n this.inputTarget.removeEventListener(\"blur\", this.onInputBlur)\n this.inputTarget.removeEventListener(\"input\", this.onInputChange)\n }\n\n if (this.hasResultsTarget) {\n this.resultsTarget.removeEventListener(\"mousedown\", this.onResultsMouseDown)\n this.resultsTarget.removeEventListener(\"click\", this.onResultsClick)\n }\n }\n\n sibling(next) {\n const options = this.options\n const selected = this.selectedOption\n const index = options.indexOf(selected)\n const sibling = next ? options[index + 1] : options[index - 1]\n const def = next ? options[0] : options[options.length - 1]\n return sibling || def\n }\n\n select(target) {\n const previouslySelected = this.selectedOption\n if (previouslySelected) {\n previouslySelected.removeAttribute(\"aria-selected\")\n previouslySelected.classList.remove(...this.selectedClassesOrDefault)\n }\n\n target.setAttribute(\"aria-selected\", \"true\")\n target.classList.add(...this.selectedClassesOrDefault)\n this.inputTarget.setAttribute(\"aria-activedescendant\", target.id)\n target.scrollIntoView({ behavior: \"auto\", block: \"nearest\" })\n }\n\n onKeydown = (event) => {\n const handler = this[`on${event.key}Keydown`]\n if (handler) handler(event)\n }\n\n onEscapeKeydown = (event) => {\n if (!this.resultsShown) return\n\n this.hideAndRemoveOptions()\n event.stopPropagation()\n event.preventDefault()\n }\n\n onArrowDownKeydown = (event) => {\n const item = this.sibling(true)\n if (item) this.select(item)\n event.preventDefault()\n }\n\n onArrowUpKeydown = (event) => {\n const item = this.sibling(false)\n if (item) this.select(item)\n event.preventDefault()\n }\n\n onTabKeydown = (event) => {\n const selected = this.selectedOption\n if (selected) this.commit(selected)\n }\n\n onEnterKeydown = (event) => {\n const selected = this.selectedOption\n if (selected && this.resultsShown) {\n this.commit(selected)\n if (!this.hasSubmitOnEnterValue) {\n event.preventDefault()\n }\n }\n }\n\n onInputBlur = () => {\n if (this.mouseDown) return\n this.close()\n }\n\n commit(selected) {\n if (selected.getAttribute(\"aria-disabled\") === \"true\") return\n\n if (selected instanceof HTMLAnchorElement) {\n selected.click()\n this.close()\n return\n }\n\n const textValue = selected.getAttribute(\"data-autocomplete-label\") || selected.textContent.trim()\n const value = selected.getAttribute(\"data-autocomplete-value\") || textValue\n this.inputTarget.value = textValue\n\n if (this.hasHiddenTarget) {\n this.hiddenTarget.value = value\n this.hiddenTarget.dispatchEvent(new Event(\"input\"))\n this.hiddenTarget.dispatchEvent(new Event(\"change\"))\n } else {\n this.inputTarget.value = value\n }\n\n this.inputTarget.focus()\n this.hideAndRemoveOptions()\n\n this.element.dispatchEvent(\n new CustomEvent(\"autocomplete.change\", {\n bubbles: true,\n detail: { value: value, textValue: textValue, selected: selected }\n })\n )\n }\n\n clear() {\n this.inputTarget.value = \"\"\n if (this.hasHiddenTarget) this.hiddenTarget.value = \"\"\n }\n\n onResultsClick = (event) => {\n if (!(event.target instanceof Element)) return\n const selected = event.target.closest(optionSelector)\n if (selected) this.commit(selected)\n }\n\n onResultsMouseDown = () => {\n this.mouseDown = true\n this.resultsTarget.addEventListener(\"mouseup\", () => {\n this.mouseDown = false\n }, { once: true })\n }\n\n onInputChange = () => {\n if (this.hasHiddenTarget) this.hiddenTarget.value = \"\"\n\n const query = this.inputTarget.value.trim()\n if (query && query.length >= this.minLengthValue) {\n this.fetchResults(query)\n } else {\n this.hideAndRemoveOptions()\n }\n }\n\n identifyOptions() {\n const prefix = this.resultsTarget.id || \"stimulus-autocomplete\"\n const optionsWithoutId = this.resultsTarget.querySelectorAll(`${optionSelector}:not([id])`)\n optionsWithoutId.forEach(el => el.id = `${prefix}-option-${Autocomplete.uniqOptionId++}`)\n }\n\n hideAndRemoveOptions() {\n this.close()\n this.resultsTarget.innerHTML = null\n }\n\n fetchResults = async (query) => {\n if (!this.hasUrlValue) return\n\n const url = this.buildURL(query)\n try {\n this.element.dispatchEvent(new CustomEvent(\"loadstart\"))\n const html = await this.doFetch(url)\n this.replaceResults(html)\n this.element.dispatchEvent(new CustomEvent(\"load\"))\n this.element.dispatchEvent(new CustomEvent(\"loadend\"))\n } catch(error) {\n this.element.dispatchEvent(new CustomEvent(\"error\"))\n this.element.dispatchEvent(new CustomEvent(\"loadend\"))\n throw error\n }\n }\n\n buildURL(query) {\n const url = new URL(this.urlValue, window.location.href)\n const params = new URLSearchParams(url.search.slice(1))\n params.append(this.queryParamValue, query)\n url.search = params.toString()\n\n return url.toString()\n }\n\n doFetch = async (url) => {\n const response = await fetch(url, this.optionsForFetch())\n\n if (!response.ok) {\n throw new Error(`Server responded with status ${response.status}`)\n }\n\n const html = await response.text()\n return html\n }\n\n replaceResults(html) {\n this.resultsTarget.innerHTML = html\n this.identifyOptions()\n if (!!this.options) {\n this.open()\n } else {\n this.close()\n }\n }\n\n open() {\n if (this.resultsShown) return\n\n this.resultsShown = true\n this.element.setAttribute(\"aria-expanded\", \"true\")\n this.element.dispatchEvent(\n new CustomEvent(\"toggle\", {\n detail: { action: \"open\", inputTarget: this.inputTarget, resultsTarget: this.resultsTarget }\n })\n )\n }\n\n close() {\n if (!this.resultsShown) return\n\n this.resultsShown = false\n this.inputTarget.removeAttribute(\"aria-activedescendant\")\n this.element.setAttribute(\"aria-expanded\", \"false\")\n this.element.dispatchEvent(\n new CustomEvent(\"toggle\", {\n detail: { action: \"close\", inputTarget: this.inputTarget, resultsTarget: this.resultsTarget }\n })\n )\n }\n\n get resultsShown() {\n return !this.resultsTarget.hidden\n }\n\n set resultsShown(value) {\n this.resultsTarget.hidden = !value\n }\n\n get options() {\n return Array.from(this.resultsTarget.querySelectorAll(optionSelector))\n }\n\n get selectedOption() {\n return this.resultsTarget.querySelector(activeSelector)\n }\n\n get selectedClassesOrDefault() {\n return this.hasSelectedClass ? this.selectedClasses : [\"active\"]\n }\n\n optionsForFetch() {\n return { headers: { \"X-Requested-With\": \"XMLHttpRequest\" } } // override if you need\n }\n}\n\nconst debounce = (fn, delay = 10) => {\n let timeoutId = null\n\n return (...args) => {\n clearTimeout(timeoutId)\n timeoutId = setTimeout(fn, delay)\n }\n}\n\nexport { Autocomplete }\n"],"names":["optionSelector","activeSelector","_Autocomplete","Controller","__publicField","event","handler","item","selected","query","url","html","error","response","debounce","next","options","index","sibling","def","target","previouslySelected","textValue","value","prefix","el","params","Autocomplete","fn","delay","timeoutId","args"],"mappings":"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","x_google_ignoreList":[0]}