{"version":3,"file":"custom-select.module-wt6Lx2aq.js","sources":["../../../../../Flow.Showcase.Static.Bundler/Root/modules/custom-select.module.ts"],"sourcesContent":["// @ts-nocheck\n\n// Save a list of named combobox actions, for future readability\nconst SelectActions = {\n Close: 0,\n CloseSelect: 1,\n First: 2,\n Last: 3,\n Next: 4,\n Open: 5,\n PageDown: 6,\n PageUp: 7,\n Previous: 8,\n Select: 9,\n Type: 10,\n};\n\n/*\n * Helper functions\n */\n\n/**\n * filter an array of options against an input string\n * @param {Option[]} options\n * @param {string} filter\n * @param {string[]} exclude\n * @returns {Option[]} an array of options that begin with the filter string, case-independent\n */\nfunction filterOptions(options = [], filter, exclude = []) {\n return options.filter((option) => {\n const matches =\n !option.disabled &&\n option.text.trim().toLowerCase().indexOf(filter.toLowerCase()) === 0;\n return matches && exclude.indexOf(option.text) < 0;\n });\n}\n\n/**\n * @param {KeyboardEvent} event\n * @param {boolean} menuOpen\n * @returns\n */\nfunction getActionFromKey(event, menuOpen) {\n const { key, altKey, ctrlKey, metaKey } = event;\n const openKeys = [\"ArrowDown\", \"ArrowUp\", \"Enter\", \" \"]; // all keys that will do the default open action\n // handle opening when closed\n if (!menuOpen && openKeys.includes(key)) {\n return SelectActions.Open;\n }\n\n // home and end move the selected option when open or closed\n if (key === \"Home\") {\n return SelectActions.First;\n }\n if (key === \"End\") {\n return SelectActions.Last;\n }\n\n // handle typing characters when open or closed\n if (\n key === \"Backspace\" ||\n key === \"Clear\" ||\n (key.length === 1 && key !== \" \" && !altKey && !ctrlKey && !metaKey)\n ) {\n return SelectActions.Type;\n }\n\n // handle keys when open\n if (menuOpen) {\n if (key === \"ArrowUp\" && altKey) {\n return SelectActions.CloseSelect;\n } else if (key === \"ArrowDown\" && !altKey) {\n return SelectActions.Next;\n } else if (key === \"ArrowUp\") {\n return SelectActions.Previous;\n } else if (key === \"PageUp\") {\n return SelectActions.PageUp;\n } else if (key === \"PageDown\") {\n return SelectActions.PageDown;\n } else if (key === \"Escape\") {\n return SelectActions.Close;\n } else if (key === \"Enter\" || key === \" \") {\n return SelectActions.CloseSelect;\n }\n }\n}\n\n/**\n * return the index of an option from an array of options, based on a search string\n * if the filter is multiple iterations of the same letter (e.g \"aaa\"), then cycle through first-letter matches\n * @param {Option[]} options\n * @param {string} filter\n * @param {number} startIndex\n * @returns\n */\nfunction getIndexByLetter(options, filter, startIndex = 0) {\n const orderedOptions = [\n ...options.slice(startIndex),\n ...options.slice(0, startIndex),\n ];\n /** @type {Option | undefined} */\n const firstMatch = filterOptions(orderedOptions, filter)[0];\n /**\n * @param {string[]} array\n * @returns {boolean}\n */\n const allSameLetter = (array) =>\n array.every((letter) => letter === array[0]);\n\n // first check if there is an exact match for the typed string\n if (firstMatch) {\n return options.indexOf(firstMatch);\n }\n\n // if the same letter is being repeated, cycle through first-letter matches\n else if (allSameLetter(filter.split(\"\"))) {\n const matches = filterOptions(orderedOptions, filter[0]);\n return options.indexOf(matches[0]);\n }\n\n // if no matches, return -1\n else {\n return -1;\n }\n}\n\n/**\n * check if element is visible in browser view port\n * @param {Element} element\n * @returns\n */\nfunction isElementInView(element) {\n var bounding = element.getBoundingClientRect();\n\n return (\n bounding.top >= 0 &&\n bounding.left >= 0 &&\n bounding.bottom <=\n (window.innerHeight || document.documentElement.clientHeight) &&\n bounding.right <=\n (window.innerWidth || document.documentElement.clientWidth)\n );\n}\n\n/**\n * check if an element is currently scrollable\n * @param {Element} element\n * @returns\n */\nfunction isScrollable(element) {\n return element && element.clientHeight < element.scrollHeight;\n}\n\n/**\n * Данные опции селектора\n * @typedef {Object} Option\n * @property {string | undefined} value - html атрибут value\n * @property {string} text - текстовое содержимое\n * @property {boolean} disabled - html аттрибут disabled\n */\n\n/*\n * Select Component\n * Accepts a combobox element and an array of string options\n */\nexport class CustomSelect {\n /**\n * @param {HTMLDivElement} el\n */\n constructor(el) {\n // element refs\n /** @type {HTMLDivElement} */\n this._el = el;\n\n this._labelEl = /** @type {HTMLDivElement?} */ (\n el.querySelector(\".custom-select__label\")\n );\n\n this._comboEl = /** @type {HTMLDivElement} */ (\n el.querySelector(\"[role=combobox]\")\n );\n this._comboTextEl = /** @type {HTMLElement} */ (\n this._comboEl.querySelector(\".custom-select__input-text\")\n );\n\n this._listboxEl = /** @type {HTMLDivElement} */ (\n el.querySelector(\"[role=listbox]\")\n );\n\n this._optionElems = /** @type {HTMLElement[]} */ ([\n ...this._listboxEl.querySelectorAll(\"[role=option]\"),\n ]);\n\n this._inputEl = /** @type {HTMLInputElement} */ (\n el.querySelector(\"input\")\n );\n customSelectMap.set(this._inputEl, this);\n\n // data\n /** @type {string} */\n this._idBase = this._inputEl.id || \"combo\";\n /** @type {Option[]} */\n this._options = [];\n\n // state\n /** @type {number} */\n this._activeIndex = -1;\n /** @type {number} */\n this._selectedIndex = -1;\n /** @type {boolean} */\n this._open = false;\n /** @type {string} */\n this._searchString = \"\";\n /** @type {number | undefined} */\n this._searchTimeout = undefined;\n\n // init\n this._init();\n\n this._onResizeOrScroll = this._onResizeOrScroll.bind(this);\n }\n\n _init() {\n // add event listeners\n if (this._labelEl) {\n this._labelEl.addEventListener(\n \"click\",\n this._onLabelClick.bind(this)\n );\n }\n this._comboEl.addEventListener(\"blur\", this._onComboBlur.bind(this));\n this._listboxEl.addEventListener(\n \"focusout\",\n this._onComboBlur.bind(this)\n );\n this._comboEl.addEventListener(\"click\", this._onComboClick.bind(this));\n this._comboEl.addEventListener(\n \"keydown\",\n this._onComboKeyDown.bind(this)\n );\n\n /** @type {number | undefined} */\n let selectedIndex = undefined;\n\n // init options\n for (let index = 0; index < this._listboxEl.children.length; ++index) {\n const optionEl = /** @type {HTMLElement} */ (\n this._listboxEl.children[index]\n );\n this._options.push({\n value: optionEl.dataset.value,\n text: optionEl.innerText,\n disabled: optionEl.dataset.disabled === \"true\"\n });\n\n // Сохраняем индекс последнего элемента, помеченного selected\n if (optionEl.dataset.selected === \"true\") {\n selectedIndex = index;\n }\n\n optionEl.id = `${this._idBase}-${index}`;\n\n optionEl.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n this._onOptionClick(index);\n });\n optionEl.addEventListener(\n \"mousedown\",\n this._onOptionMouseDown.bind(this)\n );\n }\n\n // Если было передано выбранное значение, то оно имеет приоритет\n // над опциями, помеченными selected\n const selectedValue = this._comboEl.dataset.value;\n if (selectedValue !== undefined) {\n const index = this._options.findIndex(opt => opt.value === selectedValue)\n if (index >= 0) {\n selectedIndex = index;\n }\n }\n\n /**\n * Выбор опции при инициализации\n * @param {number} index\n */\n const initOption = (index) => {\n this._onOptionChange(index);\n this._selectOption(index, false);\n }\n\n const placeholder = this._comboEl.dataset.placeholder;\n // select option\n if (selectedIndex !== undefined) {\n initOption(selectedIndex);\n } else if (placeholder) {\n this._comboTextEl.innerHTML = placeholder;\n } else {\n const firstNotDisabled = this._getFirstNotDisabledIndex();\n if (firstNotDisabled >= 0) {\n initOption(firstNotDisabled);\n }\n }\n }\n\n /**\n * @param {string} char\n */\n _getSearchString(char) {\n // reset typing timeout and start new timeout\n // this allows us to make multiple-letter matches, like a native select\n if (typeof this._searchTimeout === \"number\") {\n window.clearTimeout(this._searchTimeout);\n }\n\n this._searchTimeout = window.setTimeout(() => {\n this._searchString = \"\";\n }, 500);\n\n // add most recent letter to saved search string\n this._searchString += char;\n return this._searchString;\n }\n\n _onLabelClick() {\n this._comboEl.focus();\n }\n\n /**\n *\n * @param {FocusEvent} event\n * @returns\n */\n _onComboBlur(event) {\n // do nothing if relatedTarget is contained within listboxEl\n if (\n this._listboxEl.contains(/** @type {Node} */ (event.relatedTarget))\n ) {\n return;\n }\n\n // select current option and close\n if (this._open) {\n this._selectOption(this._activeIndex);\n this._updateMenuState(false, false);\n }\n }\n\n _onComboClick() {\n this._updateMenuState(!this._open, false);\n }\n\n /**\n * @param {KeyboardEvent} event\n */\n _onComboKeyDown(event) {\n const { key } = event;\n\n const action = getActionFromKey(event, this._open);\n\n switch (action) {\n case SelectActions.Last:\n case SelectActions.First:\n this._updateMenuState(true);\n // intentional fallthrough\n case SelectActions.Next:\n case SelectActions.Previous:\n case SelectActions.PageUp:\n case SelectActions.PageDown:\n event.preventDefault();\n return this._onOptionChange(\n this._getUpdatedIndex(this._activeIndex, action)\n );\n case SelectActions.CloseSelect:\n event.preventDefault();\n this._selectOption(this._activeIndex);\n // intentional fallthrough\n case SelectActions.Close:\n event.preventDefault();\n return this._updateMenuState(false);\n case SelectActions.Type:\n return this._onComboType(key);\n case SelectActions.Open:\n event.preventDefault();\n return this._updateMenuState(true);\n }\n }\n\n /**\n * @param {string} letter\n */\n _onComboType(letter) {\n // open the listbox if it is closed\n this._updateMenuState(true);\n\n // find the index of the first matching option\n const searchString = this._getSearchString(letter);\n const searchIndex = getIndexByLetter(\n this._options,\n searchString,\n this._activeIndex + 1\n );\n\n // if a match was found, go to it\n if (searchIndex >= 0) {\n this._onOptionChange(searchIndex);\n }\n // if no matches, clear the timeout and search string\n else {\n window.clearTimeout(this._searchTimeout);\n this._searchString = \"\";\n }\n }\n\n /**\n * @param {number} index\n */\n _onOptionChange(index) {\n if (index < 0 || index >= this._options.length) {\n return;\n }\n\n // update state\n this._activeIndex = index;\n\n // update aria-activedescendant\n this._comboEl.setAttribute(\n \"aria-activedescendant\",\n `${this._idBase}-${index}`\n );\n\n // update active option styles\n this._optionElems.forEach((optionEl) => {\n optionEl.classList.remove(\"js-option-current\");\n });\n this._optionElems[index].classList.add(\"js-option-current\");\n\n // ensure the new option is in view\n this._maintainScrollVisibility();\n }\n\n /**\n * @param {number} index\n */\n _onOptionClick(index) {\n if (!this._options[index].disabled) {\n this._onOptionChange(index);\n this._selectOption(index);\n this._updateMenuState(false);\n }\n }\n\n _onOptionMouseDown() {\n // Clicking an option will cause a blur event,\n // but we don't want to perform the default keyboard blur action\n this.ignoreBlur = true;\n }\n\n /**\n * @param {number} index\n * @param {boolean} publishEvent\n */\n _selectOption(index, publishEvent = true) {\n if (index < 0 || index >= this._options.length) {\n return;\n }\n\n // update state\n this._activeIndex = index;\n this._selectedIndex = index;\n\n // update displayed value\n const selected = this._options[index].text;\n this._comboTextEl.innerHTML = selected;\n\n // update aria-selected\n this._optionElems.forEach((optionEl) => {\n optionEl.setAttribute(\"aria-selected\", \"false\");\n });\n this._optionElems[index].setAttribute(\"aria-selected\", \"true\");\n\n const value = this._options[index].value;\n if (value && this._inputEl.value !== value) {\n this._inputEl.value = value;\n if (publishEvent) {\n let inputEvent = new Event(\"input\", {bubbles: true});\n this._inputEl.dispatchEvent(inputEvent);\n let changeEvent = new Event(\"change\", { bubbles: true });\n this._inputEl.dispatchEvent(changeEvent);\n }\n }\n }\n\n /**\n * @param {boolean} open\n * @param {boolean} callFocus\n */\n _updateMenuState(open, callFocus = true) {\n if (this._open === open) {\n return;\n }\n\n // update state\n this._open = open;\n\n // update aria-expanded and styles\n this._comboEl.setAttribute(\"aria-expanded\", `${open}`);\n if (open) {\n this._el.classList.add(\"js-open\");\n } else {\n this._el.classList.remove(\"js-open\");\n }\n\n // update activedescendant\n const activeID = open ? `${this._idBase}-${this._activeIndex}` : \"\";\n this._comboEl.setAttribute(\"aria-activedescendant\", activeID);\n\n if (activeID === \"\" && !isElementInView(this._comboEl)) {\n this._comboEl.scrollIntoView({\n behavior: \"smooth\",\n block: \"nearest\",\n });\n }\n\n // move focus back to the combobox, if needed\n callFocus && this._comboEl.focus();\n\n if (this._open) {\n this._updateListBoxPosition();\n window.addEventListener(\"resize\", this._onResizeOrScroll);\n window.addEventListener(\"scroll\", this._onResizeOrScroll, true);\n\n // ensure the new option is in view\n this._maintainScrollVisibility();\n } else {\n window.removeEventListener(\"resize\", this._onResizeOrScroll);\n window.removeEventListener(\"scroll\", this._onResizeOrScroll, true);\n }\n }\n\n /**\n * Рассчитать положение выпадающего списка на основе положения\n * элемента combobox\n */\n _updateListBoxPosition() {\n const comboRect = this._comboEl.getBoundingClientRect();\n this._listboxEl.style.top = comboRect.top + comboRect.height + \"px\";\n this._listboxEl.style.left = comboRect.left + \"px\";\n this._listboxEl.style.width = comboRect.width + \"px\";\n }\n\n /**\n * Скорректировать положение выпадающего списка,\n * когда окно или контейнер селектора скролится или изменяет размеры\n * @param {Event} event\n */\n _onResizeOrScroll(event) {\n if (event.target !== this._listboxEl) {\n // this.selectOption(this.activeIndex);\n // this.updateMenuState(false);\n this._updateListBoxPosition();\n }\n }\n\n /**\n * ensure a given child element is within the parent's visible scroll area\n * if the child is not visible, scroll the parent\n */\n _maintainScrollVisibility() {\n const scrollParent = this._listboxEl;\n const activeElement = /** @type {HTMLElement} */ (\n this._optionElems[this._activeIndex]\n );\n if (!activeElement || !isScrollable(scrollParent)) {\n return;\n }\n\n const { offsetHeight, offsetTop } = activeElement;\n const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;\n\n const isAbove = offsetTop < scrollTop;\n const isBelow =\n offsetTop + offsetHeight > scrollTop + parentOffsetHeight;\n\n if (isAbove) {\n scrollParent.scrollTo(0, offsetTop);\n } else if (isBelow) {\n scrollParent.scrollTo(\n 0,\n offsetTop - parentOffsetHeight + offsetHeight\n );\n }\n }\n\n /**\n * @param {string} value\n * @returns {number}\n */\n _getOptionIndex(value) {\n return this._options.findIndex((option) => option.value === value);\n }\n\n /**\n *\n * @param {string} value\n * @param {string} text\n */\n setOptionText(value, text) {\n let index = this._getOptionIndex(value);\n if (index >= 0) {\n this._options[index].text = text;\n this._optionElems[index].innerText = text;\n if (this._selectedIndex === index) {\n this._comboTextEl.innerText = text;\n }\n }\n }\n\n /**\n *\n * @param {string} value\n */\n selectOption(value) {\n let index = this._getOptionIndex(value);\n this._selectOption(index, false);\n }\n\n /**\n * get an updated option index after performing an action\n * @param {number} currentIndex\n * @param {number} action\n */\n _getUpdatedIndex(currentIndex, action) {\n const pageSize = 10; // used for pageup/pagedown\n\n switch (action) {\n case SelectActions.First: {\n const index = this._getFirstNotDisabledIndex();\n return index >= 0 ? index : currentIndex;\n }\n case SelectActions.Last: {\n const index = this._getLastNotDisabledIndex();\n return index >= 0 ? index : currentIndex;\n }\n case SelectActions.Previous:\n return this._getMovedIndex(currentIndex, -1)\n case SelectActions.Next:\n return this._getMovedIndex(currentIndex, 1);\n case SelectActions.PageUp:\n return this._getMovedIndex(currentIndex, -pageSize);\n case SelectActions.PageDown:\n return this._getMovedIndex(currentIndex, pageSize);\n default:\n return currentIndex;\n }\n }\n\n /**\n * Получить индекс опции, смещенный относительно текущего на заданное количество позиций,\n * пропуская disabled опции\n * @param {number} currentIndex - текущий индекс\n * @param {number} offset - смещение\n * @returns {number}\n */\n _getMovedIndex(currentIndex, offset) {\n let index = currentIndex;\n const dir = Math.sign(offset);\n const stepCount = Math.abs(offset);\n let step = 0;\n while (step < stepCount) {\n index += dir;\n if (index < 0 || index >= this._options.length) {\n return currentIndex;\n }\n if (!this._options[index].disabled) {\n currentIndex = index;\n ++step;\n }\n }\n return currentIndex;\n }\n\n /**\n * Индекс первой опции, у которой нет аттрибута disabled\n * @returns {number}\n */\n _getFirstNotDisabledIndex() {\n return this._options.findIndex(opt => !opt.disabled);\n }\n\n /**\n * Индекс последней опции, у которой нет аттрибута disabled\n * @returns {number}\n */\n _getLastNotDisabledIndex() {\n for (let i = this._options.length - 1; i >= 0; --i) {\n if (!this._options[i].disabled)\n return i;\n }\n return -1;\n }\n}\n\nconst customSelectMap = new WeakMap();\n\n/**\n *\n * @param {HTMLInputElement} el\n * @returns {CustomSelect | undefined}\n */\nexport function getCustomSelectFromElement(el) {\n return customSelectMap.get(el);\n}\n"],"names":["SelectActions","filterOptions","options","filter","exclude","option","getActionFromKey","event","menuOpen","key","altKey","ctrlKey","metaKey","getIndexByLetter","startIndex","orderedOptions","firstMatch","allSameLetter","array","letter","matches","isElementInView","element","bounding","isScrollable","CustomSelect","el","customSelectMap","selectedIndex","index","optionEl","selectedValue","opt","initOption","placeholder","firstNotDisabled","char","action","searchString","searchIndex","publishEvent","selected","value","inputEvent","changeEvent","open","callFocus","activeID","comboRect","scrollParent","activeElement","offsetHeight","offsetTop","parentOffsetHeight","scrollTop","isAbove","isBelow","text","currentIndex","offset","dir","stepCount","step","i","getCustomSelectFromElement"],"mappings":"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"}