UNPKG

@coreui/coreui-pro

Version:

The most popular front-end framework for developing responsive, mobile-first projects on the web rewritten by the CoreUI Team

891 lines (863 loc) 32.7 kB
/*! * CoreUI autocomplete.js v5.23.0 (https://coreui.io) * Copyright 2025 The CoreUI Team (https://github.com/orgs/coreui/people) * Licensed under MIT (https://github.com/coreui/coreui/blob/main/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./base-component.js'), require('./dom/data.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/sanitizer.js'), require('./util/index.js')) : typeof define === 'function' && define.amd ? define(['@popperjs/core', './base-component', './dom/data', './dom/event-handler', './dom/selector-engine', './util/sanitizer', './util/index'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Autocomplete = factory(global["@popperjs/core"], global.BaseComponent, global.Data, global.EventHandler, global.SelectorEngine, global.Sanitizer, global.Index)); })(this, (function (Popper, BaseComponent, Data, EventHandler, SelectorEngine, sanitizer_js, index_js) { 'use strict'; function _interopNamespaceDefault(e) { const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } }); if (e) { for (const k in e) { if (k !== 'default') { const d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } n.default = e; return Object.freeze(n); } const Popper__namespace = /*#__PURE__*/_interopNamespaceDefault(Popper); /** * -------------------------------------------------------------------------- * CoreUI PRO autocomplete.js * License (https://coreui.io/pro/license/) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ const NAME = 'autocomplete'; const DATA_KEY = 'coreui.autocomplete'; const EVENT_KEY = `.${DATA_KEY}`; const DATA_API_KEY = '.data-api'; const ARROW_UP_KEY = 'ArrowUp'; const ARROW_DOWN_KEY = 'ArrowDown'; const BACKSPACE_KEY = 'Backspace'; const DELETE_KEY = 'Delete'; const ENTER_KEY = 'Enter'; const ESCAPE_KEY = 'Escape'; const TAB_KEY = 'Tab'; const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button const EVENT_BLUR = `blur${EVENT_KEY}`; const EVENT_CHANGED = `changed${EVENT_KEY}`; const EVENT_CLICK = `click${EVENT_KEY}`; const EVENT_HIDE = `hide${EVENT_KEY}`; const EVENT_HIDDEN = `hidden${EVENT_KEY}`; const EVENT_INPUT = `input${EVENT_KEY}`; const EVENT_KEYDOWN = `keydown${EVENT_KEY}`; const EVENT_KEYUP = `keyup${EVENT_KEY}`; const EVENT_SHOW = `show${EVENT_KEY}`; const EVENT_SHOWN = `shown${EVENT_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`; const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`; const CLASS_NAME_AUTOCOMPLETE = 'autocomplete'; const CLASS_NAME_BUTTONS = 'autocomplete-buttons'; const CLASS_NAME_CLEANER = 'autocomplete-cleaner'; const CLASS_NAME_DISABLED = 'disabled'; const CLASS_NAME_DROPDOWN = 'autocomplete-dropdown'; const CLASS_NAME_INDICATOR = 'autocomplete-indicator'; const CLASS_NAME_INPUT = 'autocomplete-input'; const CLASS_NAME_INPUT_HINT = 'autocomplete-input-hint'; const CLASS_NAME_INPUT_GROUP = 'autocomplete-input-group'; const CLASS_NAME_LABEL = 'label'; const CLASS_NAME_OPTGROUP = 'autocomplete-optgroup'; const CLASS_NAME_OPTGROUP_LABEL = 'autocomplete-optgroup-label'; const CLASS_NAME_OPTION = 'autocomplete-option'; const CLASS_NAME_OPTIONS = 'autocomplete-options'; const CLASS_NAME_OPTIONS_EMPTY = 'autocomplete-options-empty'; const CLASS_NAME_SELECTED = 'selected'; const CLASS_NAME_SHOW = 'show'; const SELECTOR_DATA_TOGGLE = '[data-coreui-toggle="autocomplete"]:not(.disabled)'; const SELECTOR_DATA_TOGGLE_SHOWN = `.autocomplete:not(.disabled).${CLASS_NAME_SHOW}`; const SELECTOR_INDICATOR = '.autocomplete-indicator'; const SELECTOR_OPTGROUP = '.autocomplete-optgroup'; const SELECTOR_OPTION = '.autocomplete-option'; const SELECTOR_OPTIONS = '.autocomplete-options'; const SELECTOR_OPTIONS_EMPTY = '.autocomplete-options-empty'; const SELECTOR_VISIBLE_ITEMS = '.autocomplete-options .autocomplete-option:not(.disabled):not(:disabled)'; const Default = { allowList: sanitizer_js.DefaultAllowlist, allowOnlyDefinedOptions: false, ariaCleanerLabel: 'Clear selection', ariaIndicatorLabel: 'Toggle visibility of options menu', cleaner: false, clearSearchOnSelect: true, container: false, disabled: false, highlightOptionsOnSearch: false, id: null, indicator: false, invalid: false, name: null, options: false, optionsGroupsTemplate: null, optionsMaxHeight: 'auto', optionsTemplate: null, placeholder: null, required: false, sanitize: true, sanitizeFn: null, search: null, searchNoResultsLabel: false, showHints: false, valid: false, value: null }; const DefaultType = { allowList: 'object', allowOnlyDefinedOptions: 'boolean', ariaCleanerLabel: 'string', ariaIndicatorLabel: 'string', cleaner: 'boolean', clearSearchOnSelect: 'boolean', container: '(string|element|boolean)', disabled: 'boolean', highlightOptionsOnSearch: 'boolean', id: '(string|null)', indicator: 'boolean', invalid: 'boolean', name: '(string|null)', options: '(array|null)', optionsGroupsTemplate: '(function|null)', optionsMaxHeight: '(number|string)', optionsTemplate: '(function|null)', placeholder: '(string|null)', required: 'boolean', sanitize: 'boolean', sanitizeFn: '(null|function)', search: '(array|string|null)', searchNoResultsLabel: 'boolean|string', showHints: 'boolean', valid: 'boolean', value: '(number|string|null)' }; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ class Autocomplete extends BaseComponent { constructor(element, config) { var _this$_config$id; super(element, config); this._uniqueId = (_this$_config$id = this._config.id) != null ? _this$_config$id : index_js.getUID(`${this.constructor.NAME}`); this._indicatorElement = null; this._inputElement = null; this._inputHintElement = null; this._togglerElement = null; this._optionsElement = null; this._menu = null; this._selected = []; this._options = this._getOptionsFromConfig(); this._popper = null; this._search = ''; this._createAutocomplete(); this._addEventListeners(); Data.set(this._element, DATA_KEY, this); } // Getters static get Default() { return Default; } static get DefaultType() { return DefaultType; } static get NAME() { return NAME; } // Public toggle() { return this._isShown() ? this.hide() : this.show(); } show() { if (this._config.disabled || this._isShown()) { return; } if (!this._config.searchNoResultsLabel && this._flattenOptions().filter(option => option.label.toLowerCase().includes(this._search.toLowerCase())).length === 0) { return; } EventHandler.trigger(this._element, EVENT_SHOW); this._element.classList.add(CLASS_NAME_SHOW); this._inputElement.setAttribute('aria-expanded', 'true'); if (this._config.container) { this._menu.style.minWidth = `${this._element.offsetWidth}px`; this._menu.classList.add(CLASS_NAME_SHOW); } EventHandler.trigger(this._element, EVENT_SHOWN); this._createPopper(); } hide() { EventHandler.trigger(this._element, EVENT_HIDE); if (this._popper) { this._popper.destroy(); } this._element.classList.remove(CLASS_NAME_SHOW); this._inputElement.setAttribute('aria-expanded', 'false'); if (this._config.container) { this._menu.classList.remove(CLASS_NAME_SHOW); } if (this._inputHintElement) { this._inputHintElement.value = ''; } EventHandler.trigger(this._element, EVENT_HIDDEN); } dispose() { if (this._popper) { this._popper.destroy(); } super.dispose(); } clear() { this.deselectAll(); this.search(''); this._filterOptionsList(); this._inputElement.value = ''; EventHandler.trigger(this._element, EVENT_CHANGED, { value: this._selected }); } search(label) { this._search = label.length > 0 ? label.toLowerCase() : ''; if (!this._isExternalSearch()) { this._filterOptionsList(); } EventHandler.trigger(this._element, EVENT_INPUT, { value: label }); } update(config) { if (config.value) { this.deselectAll(); } this._config = { ...this._config, ...this._configAfterMerge(config) }; this._options = this._getOptionsFromConfig(); this._optionsElement.innerHTML = ''; this._createOptions(this._optionsElement, this._options); } deselectAll(options = this._selected) { if (this._selected.length === 0) { return; } for (const option of options) { if (option.disabled) { continue; } if (Array.isArray(option.options)) { this.deselectAll(option.options); continue; } this._deselectOption(option.value); this._updateCleaner(); } } // Helpers _flattenOptions(options = this._options, flat = []) { for (const opt of options) { if (opt && Array.isArray(opt.options)) { this._flattenOptions(opt.options, flat); continue; } flat.push(opt); } return flat; } _getClassNames() { return this._element.classList.value.split(' '); } _highlightOption(label) { const regex = new RegExp(this._search, 'gi'); return label.replace(regex, string => `<strong>${string}</strong>`); } _isExternalSearch() { return Array.isArray(this._config.search) && this._config.search.includes('external'); } _isGlobalSearch() { return Array.isArray(this._config.search) && this._config.search.includes('global'); } _isVisible(element) { const style = window.getComputedStyle(element); return style.display !== 'none'; } _isShown() { return this._element.classList.contains(CLASS_NAME_SHOW); } // Private _addEventListeners() { EventHandler.on(this._element, EVENT_CLICK, event => { if (!this._config.disabled && !event.target.closest(SELECTOR_INDICATOR)) { this.show(); } }); EventHandler.on(this._element, EVENT_KEYDOWN, event => { if (event.key === ESCAPE_KEY) { this.hide(); if (this._config.allowOnlyDefinedOptions && this._selected.length === 0) { this.search(''); this._inputElement.value = ''; } return; } if (this._isGlobalSearch() && (event.key.length === 1 || event.key === BACKSPACE_KEY || event.key === DELETE_KEY)) { this._inputElement.focus(); } }); EventHandler.on(this._menu, EVENT_KEYDOWN, event => { if (this._isGlobalSearch() && (event.key.length === 1 || event.key === BACKSPACE_KEY || event.key === DELETE_KEY)) { this._inputElement.focus(); } }); EventHandler.on(this._togglerElement, EVENT_KEYDOWN, event => { if (!this._isShown() && (event.key === ENTER_KEY || event.key === ARROW_DOWN_KEY)) { event.preventDefault(); this.show(); return; } if (this._isShown() && event.key === ARROW_DOWN_KEY) { event.preventDefault(); this._selectMenuItem(event); } }); EventHandler.on(this._indicatorElement, EVENT_CLICK, event => { event.preventDefault(); this.toggle(); }); EventHandler.on(this._inputElement, EVENT_BLUR, () => { const options = this._flattenOptions().filter(option => option.label.toLowerCase().startsWith(this._inputElement.value.toLowerCase())); if (this._config.allowOnlyDefinedOptions && this._selected.length === 0 && options.length === 0) { this.clear(); } }); EventHandler.on(this._inputElement, EVENT_KEYDOWN, event => { if (!this._isShown() && event.key !== TAB_KEY) { this.show(); } if (event.key === ARROW_DOWN_KEY && this._inputElement.value.length === this._inputElement.selectionStart) { this._selectMenuItem(event); return; } if (event.key === TAB_KEY && this._config.showHints && this._inputElement.value.length > 0) { if (this._inputHintElement.value) { event.preventDefault(); event.stopPropagation(); } const options = this._flattenOptions().filter(option => option.label.toLowerCase().startsWith(this._inputElement.value.toLowerCase())); if (options.length > 0) { this._selectOption(options[0]); } } if (event.key === ENTER_KEY) { event.preventDefault(); event.stopPropagation(); if (this._inputElement.value.length === 0) { return; } const options = this._flattenOptions().filter(option => option.label.toLowerCase() === this._inputElement.value.toLowerCase()); if (options.length > 0) { this._selectOption(options[0]); } if (options.length === 0 && !this._config.allowOnlyDefinedOptions) { EventHandler.trigger(this._element, EVENT_CHANGED, { value: this._inputElement.value }); this.hide(); if (this._config.clearSearchOnSelect) { this.search(''); } } } }); EventHandler.on(this._inputElement, EVENT_KEYUP, event => { if (event.key.length === 1 || event.key === BACKSPACE_KEY || event.key === DELETE_KEY) { const { value } = event.target; this.search(value); if (this._config.showHints) { const options = value ? this._flattenOptions().filter(option => option.label.toLowerCase().startsWith(value.toLowerCase())) : []; this._inputHintElement.value = options.length > 0 ? `${value}${options[0].label.slice(value.length)}` : ''; } if (this._selected.length > 0) { this.deselectAll(); EventHandler.trigger(this._element, EVENT_CHANGED, { value: this._selected }); } } }); EventHandler.on(this._optionsElement, EVENT_CLICK, event => { event.preventDefault(); event.stopPropagation(); this._onOptionsClick(event.target); }); EventHandler.on(this._cleanerElement, EVENT_CLICK, event => { if (!this._config.disabled) { event.preventDefault(); event.stopPropagation(); this.clear(); } }); EventHandler.on(this._cleanerElement, EVENT_KEYDOWN, event => { if (!this._config.disabled && event.key === ENTER_KEY) { event.preventDefault(); event.stopPropagation(); this.clear(); } }); EventHandler.on(this._optionsElement, EVENT_KEYDOWN, event => { if (event.key === ENTER_KEY) { this._onOptionsClick(event.target); } if ([ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)) { event.preventDefault(); this._selectMenuItem(event); } }); } _getOptionsFromConfig(options = this._config.options) { if (!options || !Array.isArray(options)) { return []; } const _options = []; for (const option of options) { var _option$value; if (option.options && Array.isArray(option.options)) { const customGroupProperties = { ...option }; delete customGroupProperties.label; delete customGroupProperties.options; _options.push({ ...customGroupProperties, label: option.label, options: this._getOptionsFromConfig(option.options) }); continue; } const label = typeof option === 'string' ? option : option.label; const value = (_option$value = option.value) != null ? _option$value : typeof option === 'string' ? option : option.label; const isSelected = option.selected || this._config.value && this._config.value === value; const customProperties = typeof option === 'object' ? { ...option } : {}; delete customProperties.label; delete customProperties.value; delete customProperties.selected; delete customProperties.disabled; _options.push({ ...customProperties, label, value: String(value), ...(isSelected && { selected: true }), ...(option.disabled && { disabled: true }) }); if (isSelected) { this._selected.push({ label: option.label, value: String(value) }); } } return _options; } _createAutocomplete() { this._element.classList.add(CLASS_NAME_AUTOCOMPLETE); this._element.classList.toggle('is-invalid', this._config.invalid); this._element.classList.toggle('is-valid', this._config.valid); if (this._config.disabled) { this._element.classList.add(CLASS_NAME_DISABLED); } for (const className of this._getClassNames()) { this._element.classList.add(className); } this._createInputGroup(); this._createButtons(); this._createOptionsContainer(); this._updateOptionsList(); } _createInputGroup() { var _this$_config$placeho; const togglerEl = document.createElement('div'); togglerEl.classList.add(CLASS_NAME_INPUT_GROUP); this._togglerElement = togglerEl; if (!this._config.search && !this._config.disabled) { togglerEl.tabIndex = -1; } if (!this._config.disabled && this._config.showHints) { const inputHintEl = document.createElement('input'); inputHintEl.classList.add(CLASS_NAME_INPUT, CLASS_NAME_INPUT_HINT); inputHintEl.setAttribute('name', (this._config.name || `${this._uniqueId}-hint`).toString()); inputHintEl.autocomplete = 'off'; inputHintEl.readOnly = true; inputHintEl.tabIndex = -1; inputHintEl.setAttribute('aria-hidden', true); togglerEl.append(inputHintEl); this._inputHintElement = inputHintEl; } const inputEl = document.createElement('input'); inputEl.classList.add(CLASS_NAME_INPUT); inputEl.id = this._uniqueId; inputEl.setAttribute('name', (this._config.name || this._uniqueId).toString()); inputEl.autocomplete = 'off'; inputEl.placeholder = (_this$_config$placeho = this._config.placeholder) != null ? _this$_config$placeho : ''; inputEl.role = 'combobox'; inputEl.setAttribute('aria-autocomplete', 'list'); inputEl.setAttribute('aria-expanded', 'false'); inputEl.setAttribute('aria-haspopup', 'listbox'); if (this._config.disabled) { inputEl.setAttribute('disabled', true); inputEl.tabIndex = -1; } if (this._config.required) { inputEl.setAttribute('required', true); } togglerEl.append(inputEl); this._inputElement = inputEl; this._element.append(togglerEl); } _createButtons() { if (!this._config.cleaner && !this._config.indicator) { return; } const buttons = document.createElement('div'); buttons.classList.add(CLASS_NAME_BUTTONS); if (!this._config.disabled && this._config.cleaner) { const cleaner = document.createElement('button'); cleaner.type = 'button'; cleaner.classList.add(CLASS_NAME_CLEANER); cleaner.style.display = 'none'; cleaner.setAttribute('aria-label', this._config.ariaCleanerLabel); buttons.append(cleaner); this._cleanerElement = cleaner; } if (this._config.indicator) { const indicator = document.createElement('button'); indicator.type = 'button'; indicator.classList.add(CLASS_NAME_INDICATOR); indicator.setAttribute('aria-label', this._config.ariaIndicatorLabel); if (this._config.disabled) { indicator.tabIndex = -1; } buttons.append(indicator); this._indicatorElement = indicator; this._indicatorElement = indicator; } this._togglerElement.append(buttons); this._updateCleaner(); } _createPopper() { if (typeof Popper__namespace === 'undefined') { throw new TypeError('CoreUI\'s Auto Complete component require Popper (https://popper.js.org)'); } const popperConfig = { modifiers: [{ name: 'preventOverflow', options: { boundary: 'clippingParents' } }, { name: 'offset', options: { offset: [0, 2] } }], placement: index_js.isRTL() ? 'bottom-end' : 'bottom-start' }; this._popper = Popper__namespace.createPopper(this._togglerElement, this._menu, popperConfig); } _createOptionsContainer() { const dropdownDiv = document.createElement('div'); dropdownDiv.classList.add(CLASS_NAME_DROPDOWN); dropdownDiv.role = 'listbox'; dropdownDiv.setAttribute('aria-labelledby', this._uniqueId); dropdownDiv.setAttribute('id', `${this._uniqueId}-listbox`); const optionsDiv = document.createElement('div'); optionsDiv.classList.add(CLASS_NAME_OPTIONS); if (this._config.optionsMaxHeight !== 'auto') { optionsDiv.style.maxHeight = `${this._config.optionsMaxHeight}px`; optionsDiv.style.overflow = 'auto'; } dropdownDiv.append(optionsDiv); const { container } = this._config; if (container) { this._inputElement.setAttribute('aria-owns', `${this._uniqueId}-listbox`); dropdownDiv.id = `${this._uniqueId}-listbox`; container.append(dropdownDiv); } else { this._element.append(dropdownDiv); } this._createOptions(optionsDiv, this._options); this._optionsElement = optionsDiv; this._menu = dropdownDiv; } _createOptions(parentElement, options) { for (const option of options) { if (Array.isArray(option.options)) { const optgroup = document.createElement('div'); optgroup.classList.add(CLASS_NAME_OPTGROUP); optgroup.setAttribute('role', 'group'); const optgrouplabel = document.createElement('div'); if (this._config.optionsGroupsTemplate && typeof this._config.optionsGroupsTemplate === 'function') { optgrouplabel.innerHTML = this._config.sanitize ? sanitizer_js.sanitizeHtml(this._config.optionsGroupsTemplate(option), this._config.allowList, this._config.sanitizeFn) : this._config.optionsGroupsTemplate(option); } else { optgrouplabel.textContent = option.label; } optgrouplabel.classList.add(CLASS_NAME_OPTGROUP_LABEL); optgroup.append(optgrouplabel); this._createOptions(optgroup, option.options); parentElement.append(optgroup); continue; } const optionDiv = document.createElement('div'); optionDiv.classList.add(CLASS_NAME_OPTION); if (option.disabled) { optionDiv.classList.add(CLASS_NAME_DISABLED); optionDiv.setAttribute('aria-disabled', 'true'); } optionDiv.dataset.value = option.value; optionDiv.tabIndex = 0; if (this._isExternalSearch() && this._config.highlightOptionsOnSearch && this._search) { optionDiv.innerHTML = this._highlightOption(option.label); } else if (this._config.optionsTemplate && typeof this._config.optionsTemplate === 'function') { optionDiv.innerHTML = this._config.sanitize ? sanitizer_js.sanitizeHtml(this._config.optionsTemplate(option), this._config.allowList, this._config.sanitizeFn) : this._config.optionsTemplate(option); } else { optionDiv.textContent = option.label; } parentElement.append(optionDiv); } } _onOptionsClick(element) { if (element.classList.contains(CLASS_NAME_LABEL)) { return; } if (!element.classList.contains(CLASS_NAME_OPTION)) { element = element.closest(SELECTOR_OPTION); if (!element) { return; } } const { value } = element.dataset; const foundOption = this._findOptionByValue(value); if (foundOption) { this._selectOption(foundOption); this._inputElement.focus(); } } _findOptionByValue(value, options = this._options) { for (const option of options) { if (option.value === value) { return option; } if (option.options && Array.isArray(option.options)) { const found = this._findOptionByValue(value, option.options); if (found) { return found; } } } return null; } _selectOption(option) { this.deselectAll(); if (this._selected.filter(selectedOption => selectedOption.value === option.value).length === 0) { this._selected.push(option); } const foundOption = SelectorEngine.findOne(`[data-value="${option.value}"]`, this._optionsElement); if (foundOption) { foundOption.classList.add(CLASS_NAME_SELECTED); foundOption.setAttribute('aria-selected', true); } EventHandler.trigger(this._element, EVENT_CHANGED, { value: option }); this._inputElement.value = option.label; if (this._config.showHints) { this._inputHintElement.value = ''; } this.hide(); if (this._config.clearSearchOnSelect) { this.search(''); } this._updateCleaner(); } _deselectOption(value) { this._selected = this._selected.filter(option => option.value !== value); const option = SelectorEngine.findOne(`[data-value="${value}"]`, this._optionsElement); if (option) { option.classList.remove(CLASS_NAME_SELECTED); option.setAttribute('aria-selected', false); } // EventHandler.trigger(this._element, EVENT_CHANGED, { // value: this._selected // }) } _updateCleaner() { if (!this._config.cleaner || this._cleanerElement === null) { return; } if (this._selected.length > 0) { this._cleanerElement.style.removeProperty('display'); return; } this._cleanerElement.style.display = 'none'; } _updateOptionsList(options = this._options) { for (const option of options) { if (Array.isArray(option.options)) { this._updateOptionsList(option.options); continue; } if (option.selected) { this._selectOption(option); } } } _filterOptionsList() { const options = SelectorEngine.find(SELECTOR_OPTION, this._menu); let visibleOptions = 0; for (const option of options) { // eslint-disable-next-line unicorn/prefer-includes if (option.textContent.toLowerCase().indexOf(this._search) === -1) { option.style.display = 'none'; } else { if (this._config.highlightOptionsOnSearch && !this._config.optionsTemplate) { option.innerHTML = this._highlightOption(option.textContent); } option.style.removeProperty('display'); visibleOptions++; } const optgroup = option.closest(SELECTOR_OPTGROUP); if (optgroup) { // eslint-disable-next-line unicorn/prefer-array-some if (SelectorEngine.children(optgroup, SELECTOR_OPTION).filter(element => this._isVisible(element)).length > 0) { optgroup.style.removeProperty('display'); } else { optgroup.style.display = 'none'; } } } if (visibleOptions > 0) { if (SelectorEngine.findOne(SELECTOR_OPTIONS_EMPTY, this._menu)) { SelectorEngine.findOne(SELECTOR_OPTIONS_EMPTY, this._menu).remove(); } return; } if (visibleOptions === 0) { if (this._config.searchNoResultsLabel) { const placeholder = document.createElement('div'); placeholder.classList.add(CLASS_NAME_OPTIONS_EMPTY); placeholder.innerHTML = this._config.searchNoResultsLabel; if (!SelectorEngine.findOne(SELECTOR_OPTIONS_EMPTY, this._menu)) { SelectorEngine.findOne(SELECTOR_OPTIONS, this._menu).append(placeholder); } return; } this.hide(); } } _selectMenuItem({ key, target }) { const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => index_js.isVisible(element)); if (!items.length) { return; } // if target isn't included in items (e.g. when expanding the dropdown) // allow cycling to get the last item in case key equals ARROW_UP_KEY index_js.getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus(); } _configAfterMerge(config) { if (config.container === true) { config.container = document.body; } if (typeof config.container === 'object' || typeof config.container === 'string') { config.container = index_js.getElement(config.container); } if (typeof config.options === 'string') { config.options = config.options.split(/,\s*/).map(String); } if (typeof config.search === 'string') { config.search = config.search.split(/,\s*/).map(String); } return config; } // Static static autocompleteInterface(element, config) { const data = Autocomplete.getOrCreateInstance(element, config); if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`); } data[config](); } } static jQueryInterface(config) { return this.each(function () { Autocomplete.autocompleteInterface(this, config); }); } static clearMenus(event) { if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY) { return; } const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); for (const toggle of openToggles) { const context = Autocomplete.getInstance(toggle); if (!context) { continue; } const composedPath = event.composedPath(); if (composedPath.includes(context._element)) { continue; } ({ relatedTarget: context._element }); if (event.type === 'click') ; context.hide(); context.search(''); if (context._config.allowOnlyDefinedOptions && context._selected.length === 0) { context._inputElement.value = ''; } } } } /** * Data API implementation */ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { for (const autocomplete of SelectorEngine.find(SELECTOR_DATA_TOGGLE)) { Autocomplete.autocompleteInterface(autocomplete); } }); EventHandler.on(document, EVENT_CLICK_DATA_API, Autocomplete.clearMenus); EventHandler.on(document, EVENT_KEYUP_DATA_API, Autocomplete.clearMenus); /** * jQuery */ index_js.defineJQueryPlugin(Autocomplete); return Autocomplete; })); //# sourceMappingURL=autocomplete.js.map