slim-select 3.1.4 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"slimselect.js","sources":["../src/slim-select/classes.ts","../src/slim-select/helpers.ts","../src/slim-select/store.ts","../src/slim-select/render.ts","../src/slim-select/select.ts","../src/slim-select/settings.ts","../src/slim-select/index.ts","../src/slim-select/index.umd.ts"],"sourcesContent":["export default class CssClasses {\n public main: string\n // Placeholder\n public placeholder: string\n\n // Values\n public values: string\n public single: string\n public max: string\n public value: string\n public valueText: string\n public valueDelete: string\n public valueOut: string\n\n // Deselect\n public deselect: string\n public deselectPath: string // Not a class but whatever\n\n // Arrow\n public arrow: string\n public arrowClose: string // Not a class but whatever\n public arrowOpen: string // Not a class but whatever\n\n // Content\n public content: string\n public contentOpen: string\n public dirAbove: string\n public dirBelow: string\n\n // Search\n public search: string\n public searchHighlighter: string\n public searching: string\n public addable: string\n public addablePath: string // Not a class but whatever\n\n // List optgroups/options\n public list: string\n\n // Optgroup\n public optgroup: string\n public optgroupLabel: string\n public optgroupLabelText: string\n public optgroupActions: string\n public optgroupSelectAll: string // optgroup select all\n public optgroupSelectAllBox: string // Not a class but whatever\n public optgroupSelectAllCheck: string // Not a class but whatever\n public optgroupClosable: string\n\n // Option\n public option: string\n public optionDelete: string // Not a class but whatever\n public highlighted: string\n\n // Misc\n public mainOpen: string\n public close: string\n public selected: string\n public error: string\n public disabled: string\n public hide: string\n\n constructor(classes?: Partial<CssClasses>) {\n if (!classes) {\n classes = {}\n }\n\n this.main = classes.main || 'ss-main'\n this.placeholder = classes.placeholder || 'ss-placeholder'\n this.values = classes.values || 'ss-values'\n this.single = classes.single || 'ss-single'\n this.max = classes.max || 'ss-max'\n this.value = classes.value || 'ss-value'\n this.valueText = classes.valueText || 'ss-value-text'\n this.valueDelete = classes.valueDelete || 'ss-value-delete'\n this.valueOut = classes.valueOut || 'ss-value-out'\n\n this.deselect = classes.deselect || 'ss-deselect'\n this.deselectPath = classes.deselectPath || 'M10,10 L90,90 M10,90 L90,10'\n this.arrow = classes.arrow || 'ss-arrow'\n this.arrowClose = classes.arrowClose || 'M10,30 L50,70 L90,30'\n this.arrowOpen = classes.arrowOpen || 'M10,70 L50,30 L90,70'\n this.content = classes.content || 'ss-content'\n this.contentOpen = classes.contentOpen || 'ss-open'\n this.dirAbove = classes.dirAbove || 'ss-dir-above'\n this.dirBelow = classes.dirBelow || 'ss-dir-below'\n this.search = classes.search || 'ss-search'\n this.searchHighlighter = classes.searchHighlighter || 'ss-search-highlight'\n this.searching = classes.searching || 'ss-searching'\n this.addable = classes.addable || 'ss-addable'\n this.addablePath = classes.addablePath || 'M50,10 L50,90 M10,50 L90,50'\n this.list = classes.list || 'ss-list'\n this.optgroup = classes.optgroup || 'ss-optgroup'\n this.optgroupLabel = classes.optgroupLabel || 'ss-optgroup-label'\n this.optgroupLabelText = classes.optgroupLabelText || 'ss-optgroup-label-text'\n this.optgroupActions = classes.optgroupActions || 'ss-optgroup-actions'\n this.optgroupSelectAll = classes.optgroupSelectAll || 'ss-selectall'\n this.optgroupSelectAllBox = classes.optgroupSelectAllBox || 'M60,10 L10,10 L10,90 L90,90 L90,50'\n this.optgroupSelectAllCheck = classes.optgroupSelectAllCheck || 'M30,45 L50,70 L90,10'\n this.optgroupClosable = classes.optgroupClosable || 'ss-closable'\n this.option = classes.option || 'ss-option'\n this.optionDelete = classes.optionDelete || 'M10,10 L90,90 M10,90 L90,10'\n this.highlighted = classes.highlighted || 'ss-highlighted'\n this.mainOpen = classes.mainOpen || 'ss-open'\n this.close = classes.close || 'ss-close'\n this.selected = classes.selected || 'ss-selected'\n this.error = classes.error || 'ss-error'\n this.disabled = classes.disabled || 'ss-disabled'\n this.hide = classes.hide || 'ss-hide'\n }\n}\n","// Generate an 8 character random string\nexport function generateID(): string {\n return Math.random().toString(36).substring(2, 10)\n}\n\nexport function hasClassInTree(element: HTMLElement, className: string): HTMLElement | null {\n function hasClass(e: HTMLElement, c: string) {\n // If the element has the class return element\n if (c && e && e.classList && e.classList.contains(c)) {\n return e\n }\n\n // If the element has a dataset id of the class return element\n if (c && e && e.dataset && e.dataset.id && e.dataset.id === className) {\n return e\n }\n\n return null\n }\n\n function parentByClass(e: any, c: string): any {\n if (!e || e === (document as any)) {\n return null\n } else if (hasClass(e, c)) {\n return e\n } else {\n return parentByClass(e.parentNode, c)\n }\n }\n\n return hasClass(element, className) || parentByClass(element, className)\n}\n\n// debounce will call the last requested function after the wait time\nexport function debounce<T extends (...args: any[]) => void>(func: T, wait = 50, immediate = false): () => void {\n let timeout: any\n return function (this: any, ...args: any[]): void {\n const context = self\n const later = () => {\n timeout = null\n if (!immediate) {\n func.apply(context, args)\n }\n }\n const callNow = immediate && !timeout\n clearTimeout(timeout)\n timeout = setTimeout(later, wait)\n if (callNow) {\n func.apply(context, args)\n }\n }\n}\n\nexport function isEqual(a: any, b: any): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport function kebabCase(str: string): string {\n const result = str.replace(/[A-Z\\u00C0-\\u00D6\\u00D8-\\u00DE]/g, (match) => '-' + match.toLowerCase())\n return str[0] === str[0].toUpperCase() ? result.substring(1) : result\n}\n","import { generateID } from './helpers'\n\nexport class Option {\n id: string\n value: string\n text: string\n html: string\n defaultSelected: boolean\n selected: boolean\n display: boolean\n disabled: boolean\n placeholder: boolean\n class: string\n style: string\n data: { [key: string]: string }\n mandatory: boolean\n\n constructor(option: Partial<Option>) {\n this.id = !option.id || option.id === '' ? generateID() : option.id\n this.value = option.value === undefined ? option.text || '' : option.value || ''\n this.text = option.text || ''\n this.html = option.html || ''\n this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false\n this.selected = option.selected !== undefined ? option.selected : false\n this.display = option.display !== undefined ? option.display : true\n this.disabled = option.disabled !== undefined ? option.disabled : false\n this.mandatory = option.mandatory !== undefined ? option.mandatory : false\n this.placeholder = option.placeholder !== undefined ? option.placeholder : false\n this.class = option.class || ''\n this.style = option.style || ''\n this.data = option.data || {}\n }\n}\nexport class Optgroup {\n public id: string\n public label: string\n public selectAll: boolean\n public selectAllText: string\n public closable: 'off' | 'open' | 'close'\n public options: Partial<Option>[]\n\n constructor(optgroup: Partial<Optgroup>) {\n this.id = !optgroup.id || optgroup.id === '' ? generateID() : optgroup.id\n this.label = optgroup.label || ''\n this.selectAll = optgroup.selectAll === undefined ? false : optgroup.selectAll\n this.selectAllText = optgroup.selectAllText || 'Select All'\n this.closable = optgroup.closable || 'off'\n\n // If options exist, loop through options and create new option class\n // and set the options to the optgroup options field\n this.options = []\n if (optgroup.options) {\n for (const o of optgroup.options) {\n this.options.push(new Option(o))\n }\n }\n }\n}\n\nexport default class Store {\n private selectType: 'single' | 'multiple' = 'single'\n\n // Main data set, never null\n private data: (Option | Optgroup)[] = []\n private selectedOrder: string[] = []\n\n constructor(type: 'single' | 'multiple', data: (Partial<Option> | Partial<Optgroup>)[]) {\n this.selectType = type\n this.setData(data)\n }\n\n // Validate DataArrayPartial\n public validateDataArray(data: (Partial<Option> | Partial<Optgroup>)[]): Error | null {\n if (!Array.isArray(data)) {\n return new Error('Data must be an array')\n }\n\n // Loop through each data object\n for (let dataObj of data) {\n if (!dataObj) continue\n\n // Optgroup\n if (dataObj instanceof Optgroup || 'label' in dataObj) {\n if (!('label' in dataObj)) {\n return new Error('Optgroup must have a label')\n }\n\n if ('options' in dataObj && dataObj.options) {\n for (let option of dataObj.options) {\n const validationError = this.validateOption(option)\n if (validationError) {\n return validationError\n }\n }\n }\n } else if (dataObj instanceof Option || 'text' in dataObj) {\n const validationError = this.validateOption(dataObj)\n if (validationError) {\n return validationError\n }\n } else {\n return new Error('Data object must be a valid optgroup or option')\n }\n }\n\n return null\n }\n\n // Validate Option\n public validateOption(option: Partial<Option>): Error | null {\n if (!('text' in option)) {\n return new Error('Option must have a text')\n }\n\n return null\n }\n\n public partialToFullData(data: (Partial<Option> | Partial<Optgroup>)[]): (Option | Optgroup)[] {\n let dataFinal: (Option | Optgroup)[] = []\n data.forEach((dataObj) => {\n if (!dataObj) return\n\n // Optgroup\n if (dataObj instanceof Optgroup || 'label' in dataObj) {\n let optOptions: Option[] = []\n if ('options' in dataObj && dataObj.options) {\n dataObj.options.forEach((option: Partial<Option>) => {\n optOptions.push(new Option(option))\n })\n }\n\n if (optOptions.length > 0) {\n dataFinal.push(new Optgroup(dataObj as Partial<Optgroup>))\n }\n }\n\n // Option\n if (dataObj instanceof Option || 'text' in dataObj) {\n dataFinal.push(new Option(dataObj as Partial<Option>))\n }\n })\n\n return dataFinal\n }\n\n public setData(data: (Partial<Option> | Partial<Optgroup>)[], preserveSelected: boolean = false) {\n // Convert new data to full data array\n const newData = this.partialToFullData(data)\n\n if (preserveSelected) {\n // Get currently selected options before updating data\n const selectedOptions = this.getSelectedOptions()\n\n // Check which selected options are missing from new data\n const missingSelected: (Option | Optgroup)[] = []\n selectedOptions.forEach((selectedOption) => {\n let found = false\n\n // Check if this selected option exists in new data\n for (const newItem of newData) {\n if (newItem instanceof Option && newItem.id === selectedOption.id) {\n found = true\n break\n }\n if (newItem instanceof Optgroup) {\n for (const opt of newItem.options) {\n if (opt.id === selectedOption.id) {\n found = true\n break\n }\n }\n }\n }\n\n if (!found) {\n missingSelected.push(selectedOption)\n }\n })\n\n // Add missing selected options to the beginning of the data\n this.data = [...missingSelected, ...newData]\n } else {\n this.data = newData\n }\n\n // Run this.data through setSelected by value\n // to set the selected property and clean any wrong selected\n if (this.selectType === 'single') {\n this.setSelectedBy('id', this.getSelected())\n }\n }\n\n // Get data will return all the data\n public getData(): Option[] | Optgroup[] {\n return this.filter(null, true) as Option[] | Optgroup[]\n }\n\n // Get data options will return the data as a\n // flat array of just options\n public getDataOptions(): Option[] {\n return this.filter(null, false) as Option[]\n }\n\n public addOption(option: Partial<Option>, addToStart: boolean = false) {\n if (addToStart) {\n let data = [new Option(option)] as (Option | Optgroup)[]\n this.setData(data.concat(this.getData()))\n } else {\n this.setData(this.getData().concat(new Option(option)))\n }\n }\n\n // Pass in an array of id that will loop through\n // each option and set the selected property to true\n // but also clean selected by determining selectType\n public setSelectedBy(selectedType: 'id' | 'value', selectedValues: string[]) {\n let firstOption: Partial<Option> | null = null\n let hasSelected = false\n const selectedObjects: Partial<Option>[] = []\n\n for (let dataObj of this.data) {\n // Optgroup\n if (dataObj instanceof Optgroup) {\n for (let option of dataObj.options as Partial<Option>[]) {\n if (!firstOption) {\n firstOption = option\n }\n\n let optionValue = option[selectedType] || ''\n option.selected = hasSelected ? false : selectedValues.includes(optionValue)\n\n // If the option is selected, set hasSelected to true\n // for single based selects\n if (option.selected) {\n selectedObjects.push(option)\n\n if (this.selectType === 'single') {\n hasSelected = true\n }\n }\n }\n }\n\n // Option\n if (dataObj instanceof Option) {\n if (!firstOption) {\n firstOption = dataObj\n }\n\n dataObj.selected = hasSelected ? false : selectedValues.includes(dataObj[selectedType])\n\n // If the option is selected, set hasSelected to true\n // for single based selects\n if (dataObj.selected) {\n selectedObjects.push(dataObj)\n\n if (this.selectType === 'single') {\n hasSelected = true\n }\n }\n }\n }\n\n // If no options are selected, select the first option\n if (this.selectType === 'single' && firstOption && !hasSelected) {\n firstOption.selected = true\n selectedObjects.push(firstOption)\n }\n\n // Put together a list of selected ids in the order of the selected values\n const selectedIds = selectedValues.map((value) => {\n return selectedObjects.find((option) => option[selectedType] === value)?.id || ''\n })\n\n this.selectedOrder = selectedIds\n }\n\n public getSelected(): string[] {\n return this.getSelectedOptions().map((option) => option.id)\n }\n\n public getSelectedValues(): string[] {\n return this.getSelectedOptions().map((option) => option.value)\n }\n\n public getSelectedOptions(): Option[] {\n return this.filter((opt: Option) => {\n return opt.selected\n }, false) as Option[]\n }\n\n public getOptgroupByID(id: string): Optgroup | null {\n // Loop through each data object\n // and if optgroup is found, return it\n for (let dataObj of this.data) {\n if (dataObj instanceof Optgroup && dataObj.id === id) {\n return dataObj\n }\n }\n\n return null\n }\n\n public getOptionByID(id: string): Option | null {\n let options = this.filter((opt: Option) => {\n return opt.id === id\n }, false) as Option[]\n\n return options.length ? options[0] : null\n }\n\n public getSelectType(): string {\n return this.selectType\n }\n\n public getFirstOption(): Option | null {\n let option: Option | null = null\n for (let dataObj of this.data) {\n if (dataObj instanceof Optgroup) {\n option = dataObj.options[0] as Option\n } else if (dataObj instanceof Option) {\n option = dataObj\n }\n\n if (option) {\n break\n }\n }\n return option\n }\n\n // Take in search string and return filtered list of values\n public search(search: string, searchFilter: (opt: Option, search: string) => boolean): (Option | Optgroup)[] {\n search = search.trim()\n\n // If search is empty, return all data\n if (search === '') {\n return this.getData()\n }\n\n // Run filter with search function\n return this.filter((opt: Option): boolean => {\n return searchFilter(opt, search)\n }, true)\n }\n\n // Filter takes in a function that will be used to filter the data\n // This will also keep optgroups of sub options meet the filter requirements\n public filter(filter: { (opt: Option): boolean } | null, includeOptgroup: boolean): (Option | Optgroup)[] {\n const dataSearch: (Option | Optgroup)[] = []\n this.data.forEach((dataObj: Option | Optgroup) => {\n // Optgroup\n if (dataObj instanceof Optgroup) {\n let optOptions: Option[] = []\n let options = dataObj.options as Option[]\n options.forEach((option: Option) => {\n if (!filter || filter(option as Option)) {\n // If you dont want to include optgroups\n // just push to the dataSearch array\n if (!includeOptgroup) {\n dataSearch.push(new Option(option))\n } else {\n optOptions.push(new Option(option))\n }\n }\n })\n\n // If we pushed any options to the optOptions array\n // push the optgroup to the dataSearch array\n if (optOptions.length > 0) {\n // Create new optgroup with the new options\n let optgroup = new Optgroup(dataObj)\n optgroup.options = optOptions\n\n // Push optgroup to dataSearch\n dataSearch.push(optgroup)\n }\n }\n\n // Option\n if (dataObj instanceof Option) {\n if (!filter || filter(dataObj)) {\n dataSearch.push(new Option(dataObj))\n }\n }\n })\n\n return dataSearch\n }\n\n // Take in an array of options and reoder them based upon the selected order\n public selectedOrderOptions(options: Option[]): Option[] {\n const newOrder: Option[] = []\n this.selectedOrder.forEach((id) => {\n const option = options.find((opt) => opt.id === id)\n if (option) {\n newOrder.push(option)\n }\n })\n\n // add any remaining options that were not in the selected order\n options.forEach((option) => {\n let isIn = false\n newOrder.forEach((selectedOption) => {\n if (option.id === selectedOption.id) {\n isIn = true\n\n return\n }\n })\n\n if (!isIn) {\n newOrder.push(option)\n }\n })\n\n return newOrder\n }\n}\n","import { debounce } from './helpers'\nimport Settings from './settings'\nimport Store, { Optgroup, Option } from './store'\nimport CssClasses from './classes'\n\nexport interface Callbacks {\n open: () => void\n close: () => void\n addable?: (\n value: string\n ) => Promise<Partial<Option> | string> | Partial<Option> | string | false | undefined | null | Error\n setSelected: (value: string | string[], runAfterChange: boolean) => void\n addOption: (option: Option) => void\n search: (search: string) => void\n beforeChange?: (newVal: Option[], oldVal: Option[]) => boolean | void\n afterChange?: (newVal: Option[]) => void\n}\n\nexport interface Main {\n main: HTMLDivElement\n values: HTMLDivElement\n deselect: {\n main: HTMLDivElement\n svg: SVGSVGElement\n path: SVGPathElement\n }\n arrow: {\n main: SVGSVGElement\n path: SVGPathElement\n }\n}\n\nexport interface Content {\n main: HTMLDivElement\n search: Search\n list: HTMLDivElement\n}\n\nexport interface Search {\n main: HTMLDivElement\n input: HTMLInputElement\n addable?: {\n main: HTMLDivElement\n svg: SVGSVGElement\n path: SVGPathElement\n }\n}\n\nexport default class Render {\n public settings: Settings\n public store: Store\n public callbacks: Callbacks\n\n // Used to compute the range selection\n private lastSelectedOption: Option | null\n\n // Elements\n public main: Main\n public content: Content\n\n // Classes\n public classes: CssClasses\n\n constructor(settings: Required<Settings>, classes: Required<CssClasses>, store: Store, callbacks: Callbacks) {\n this.store = store\n this.settings = settings\n this.classes = classes\n this.callbacks = callbacks\n this.lastSelectedOption = null\n\n this.main = this.mainDiv()\n this.content = this.contentDiv()\n\n // Add classes and styles to main/content\n this.updateClassStyles()\n this.updateAriaAttributes()\n\n // Position content off-screen initially to prevent scrollbars\n // This must be after updateClassStyles() since it removes all style attributes\n // The main element isn't in the DOM yet, so getBoundingClientRect() would return zeros\n // Once opened, moveContent() will position it correctly\n if (this.settings.contentPosition !== 'relative') {\n this.content.main.style.top = '-9999px'\n this.content.main.style.left = '-9999px'\n this.content.main.style.margin = '0'\n this.content.main.style.width = 'auto'\n }\n\n // Add content to the content location settings\n if (this.settings.contentLocation) {\n this.settings.contentLocation.appendChild(this.content.main)\n }\n }\n\n // Remove disabled classes\n public enable(): void {\n // Remove disabled class\n this.main.main.classList.remove(this.classes.disabled)\n this.main.main.setAttribute('aria-disabled', 'false')\n\n // Set search input to \"enabled\"\n this.content.search.input.disabled = false\n }\n\n // Set disabled classes\n public disable(): void {\n // Add disabled class\n this.main.main.classList.add(this.classes.disabled)\n this.main.main.setAttribute('aria-disabled', 'true')\n\n // Set search input to disabled\n this.content.search.input.disabled = true\n }\n\n public open(): void {\n this.main.arrow.path.setAttribute('d', this.classes.arrowOpen)\n this.main.main.setAttribute('aria-expanded', 'true')\n\n // Set direction class on both main and content (persists, never removed)\n const isAbove = this.settings.openPosition === 'up'\n const dirClass = isAbove ? this.classes.dirAbove : this.classes.dirBelow\n this.main.main.classList.add(dirClass)\n this.content.main.classList.add(dirClass)\n\n // Add open class to content to trigger open animation\n this.content.main.classList.add(this.classes.contentOpen)\n\n // Make search visible to screen readers when opened\n this.content.search.input.removeAttribute('aria-hidden')\n\n // move the content in to the right location\n this.moveContent()\n\n // Move to last selected option\n const selectedOptions = this.store.getSelectedOptions()\n if (selectedOptions.length) {\n const selectedId = selectedOptions[selectedOptions.length - 1].id\n const selectedOption = this.content.list.querySelector('[data-id=\"' + selectedId + '\"]') as HTMLElement\n if (selectedOption) {\n this.ensureElementInView(this.content.list, selectedOption)\n }\n }\n }\n\n public close(): void {\n this.main.main.setAttribute('aria-expanded', 'false')\n this.main.arrow.path.setAttribute('d', this.classes.arrowClose)\n\n // Remove open class from content to trigger close animation\n // Direction class (dirAbove/dirBelow) persists to maintain correct transform-origin\n this.content.main.classList.remove(this.classes.contentOpen)\n\n // Hide search from screen readers when closed\n this.content.search.input.setAttribute('aria-hidden', 'true')\n\n // Clear active descendant when closed\n this.main.main.removeAttribute('aria-activedescendant')\n\n // Remove direction class from main and content after animation is complete\n setTimeout(() => {\n this.main.main.classList.remove(this.classes.dirAbove, this.classes.dirBelow)\n this.content.main.classList.remove(this.classes.dirAbove, this.classes.dirBelow)\n }, 100)\n }\n\n public updateClassStyles(): void {\n // Clear all classes and styles\n this.main.main.className = ''\n this.main.main.removeAttribute('style')\n this.content.main.className = ''\n this.content.main.removeAttribute('style')\n\n // Make sure main/content has its base class\n this.main.main.classList.add(this.classes.main)\n this.content.main.classList.add(this.classes.content)\n\n // Add styles\n if (this.settings.style !== '') {\n this.main.main.style.cssText = this.settings.style\n this.content.main.style.cssText = this.settings.style\n }\n\n // Add classes\n if (this.settings.class.length) {\n for (const c of this.settings.class) {\n if (c.trim() !== '') {\n this.main.main.classList.add(c.trim())\n this.content.main.classList.add(c.trim())\n }\n }\n }\n\n // Misc classes\n // Add content position class\n if (this.settings.contentPosition === 'relative' || this.settings.contentPosition === 'fixed') {\n this.content.main.classList.add('ss-' + this.settings.contentPosition)\n }\n }\n\n public updateAriaAttributes() {\n const listboxId = this.content.list.id\n\n // Main combobox\n this.main.main.role = 'combobox'\n this.main.main.setAttribute('aria-haspopup', 'listbox')\n this.main.main.setAttribute('aria-controls', listboxId)\n this.main.main.setAttribute('aria-expanded', 'false')\n\n this.content.list.setAttribute('role', 'listbox')\n this.content.list.setAttribute('aria-label', this.settings.ariaLabel + ' listbox')\n\n // Add aria-multiselectable for multiple selects\n if (this.settings.isMultiple) {\n this.content.list.setAttribute('aria-multiselectable', 'true')\n }\n\n // Search input should also control the listbox\n this.content.search.input.setAttribute('aria-controls', listboxId)\n }\n\n public mainDiv(): Main {\n // Create main container\n const main = document.createElement('div')\n\n // Add id to data-id\n main.dataset.id = this.settings.id\n // main.id = this.settings.id+'-main' // Remove for now as it is not needed and add duplicate id errors\n\n // Add label\n main.setAttribute('aria-label', this.settings.ariaLabel)\n\n // Set tabable to allow tabbing to the element\n main.tabIndex = 0\n\n // Deal with keyboard events on the main div\n // This is to allow for normal selecting\n // when you may not have a search bar\n main.onkeydown = (e: KeyboardEvent): boolean => {\n // Convert above if else statemets to switch\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n this.callbacks.open()\n e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up')\n return false\n case 'Tab':\n this.callbacks.close()\n return true // Continue doing normal tabbing\n case 'Enter':\n case ' ':\n this.callbacks.open()\n const highlighted = this.content.list.querySelector('.' + this.classes.highlighted) as HTMLDivElement\n if (highlighted) {\n highlighted.click()\n }\n return false\n case 'Escape':\n this.callbacks.close()\n return false\n }\n\n // Check if they type a-z, A-Z and 0-9\n if (e.key.length === 1) {\n this.callbacks.open()\n }\n\n return true\n }\n\n // Add onclick for main div\n main.onclick = (e: Event): void => {\n // Dont do anything if disabled\n if (this.settings.disabled) {\n return\n }\n\n this.settings.isOpen ? this.callbacks.close() : this.callbacks.open()\n }\n\n // Add values\n const values = document.createElement('div')\n values.classList.add(this.classes.values)\n main.appendChild(values)\n\n // Add deselect\n const deselect = document.createElement('div')\n deselect.classList.add(this.classes.deselect)\n\n // Check if deselect is to be shown or not\n const selectedOptions = this.store?.getSelectedOptions()\n if (!this.settings.allowDeselect || (this.settings.isMultiple && selectedOptions && selectedOptions.length <= 0)) {\n deselect.classList.add(this.classes.hide)\n } else {\n deselect.classList.remove(this.classes.hide)\n }\n\n // Add deselect onclick event\n deselect.onclick = (e: Event) => {\n e.stopPropagation()\n\n // Dont do anything if disabled\n if (this.settings.disabled) {\n return\n }\n\n // By Default we will delete\n let shouldDelete = true\n const before = this.store.getSelectedOptions()\n const after = [] as Option[]\n\n // Add beforeChange callback\n if (this.callbacks.beforeChange) {\n shouldDelete = this.callbacks.beforeChange(after, before) === true\n }\n\n if (shouldDelete) {\n if (this.settings.isMultiple) {\n this.callbacks.setSelected([], false)\n this.updateDeselectAll()\n } else {\n // Get first option and set it as selected\n const firstOption = this.store.getFirstOption()\n const id = firstOption ? firstOption.id : ''\n\n this.callbacks.setSelected(id, false)\n }\n\n // Check if we need to close the dropdown\n if (this.settings.closeOnSelect) {\n this.callbacks.close()\n }\n\n // Run afterChange callback\n if (this.callbacks.afterChange) {\n this.callbacks.afterChange(this.store.getSelectedOptions())\n }\n }\n }\n\n // Add deselect svg\n const deselectSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n deselectSvg.setAttribute('viewBox', '0 0 100 100')\n const deselectPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n deselectPath.setAttribute('d', this.classes.deselectPath)\n deselectSvg.appendChild(deselectPath)\n deselect.appendChild(deselectSvg)\n main.appendChild(deselect)\n\n // Add arrow\n const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n arrow.classList.add(this.classes.arrow)\n arrow.setAttribute('viewBox', '0 0 100 100')\n const arrowPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n arrowPath.setAttribute('d', this.classes.arrowClose)\n if (this.settings.alwaysOpen) {\n arrow.classList.add(this.classes.hide)\n }\n arrow.appendChild(arrowPath)\n main.appendChild(arrow)\n\n return {\n main: main,\n values: values,\n deselect: {\n main: deselect,\n svg: deselectSvg,\n path: deselectPath\n },\n arrow: {\n main: arrow,\n path: arrowPath\n }\n }\n }\n\n public mainFocus(eventType: string | null): void {\n // Trigger focus but dont scroll to it\n // Need for prevent refocus the element if event is not keyboard event.\n // For example if event is mouse click or tachpad click this condition prevent refocus on element\n // because click by mouse change focus position and not need return focus to element.\n if (eventType !== 'click') {\n this.main.main.focus({ preventScroll: true })\n }\n }\n\n public placeholder(): HTMLDivElement {\n // Figure out if there is a placeholder option\n const placeholderOption = this.store.filter((o) => o.placeholder, false) as Option[]\n\n // If there is a placeholder option use that\n // If placeholder has an html value, use that\n // If placeholder has a text, use that\n // If nothing is set, use the placeholder text\n let placeholderText = this.settings.placeholderText\n if (placeholderOption.length) {\n if (placeholderOption[0].html !== '') {\n placeholderText = placeholderOption[0].html\n } else if (placeholderOption[0].text !== '') {\n placeholderText = placeholderOption[0].text\n }\n }\n\n // Create placeholder div\n const placeholder = document.createElement('div')\n placeholder.classList.add(this.classes.placeholder)\n placeholder.innerHTML = placeholderText\n return placeholder\n }\n\n // Get selected values and append to multiSelected values container\n // and remove those who shouldnt exist\n public renderValues(): void {\n // If single select set placeholder or selected value\n if (!this.settings.isMultiple) {\n this.renderSingleValue()\n return\n }\n\n this.renderMultipleValues()\n\n this.updateDeselectAll()\n }\n\n private renderSingleValue(): void {\n const selected = this.store.filter((o: Option): boolean => {\n return o.selected && !o.placeholder\n }, false) as Option[]\n const selectedSingle = selected.length > 0 ? selected[0] : null\n\n // If nothing is seleected use settings placeholder text\n if (!selectedSingle) {\n this.main.values.innerHTML = this.placeholder().outerHTML\n } else {\n // Create single value container\n const singleValue = document.createElement('div')\n singleValue.classList.add(this.classes.single)\n if (selectedSingle.html) {\n singleValue.innerHTML = selectedSingle.html\n } else {\n singleValue.innerText = selectedSingle.text\n }\n\n // If there is a selected value, set a single div\n this.main.values.innerHTML = singleValue.outerHTML\n }\n\n // If allowDeselect is false or selected value is empty just hide deselect\n if (!this.settings.allowDeselect || !selected.length) {\n this.main.deselect.main.classList.add(this.classes.hide)\n } else {\n this.main.deselect.main.classList.remove(this.classes.hide)\n }\n }\n\n private renderMultipleValues(): void {\n // Get various pieces of data\n let currentNodes = this.main.values.childNodes as NodeListOf<HTMLDivElement>\n let selectedOptions = this.store.filter((opt: Option) => {\n // Only grab options that are selected and display is true\n return opt.selected && opt.display\n }, false) as Option[]\n\n // If selectedOptions is empty set placeholder\n if (selectedOptions.length === 0) {\n this.main.values.innerHTML = this.placeholder().outerHTML\n return\n } else {\n // If there is a placeholder, remove it\n const placeholder = this.main.values.querySelector('.' + this.classes.placeholder)\n if (placeholder) {\n placeholder.remove()\n }\n }\n\n // If selectedOptions is greater than maxItems, set maxValuesMessage\n if (selectedOptions.length > this.settings.maxValuesShown) {\n // Creating the element that shows the number of selected items\n const singleValue = document.createElement('div')\n singleValue.classList.add(this.classes.max)\n singleValue.textContent = this.settings.maxValuesMessage.replace('{number}', selectedOptions.length.toString())\n\n // If there is a selected value, set a single div\n this.main.values.innerHTML = singleValue.outerHTML\n return\n } else {\n // If there is a message, remove it\n const maxValuesMessage = this.main.values.querySelector('.' + this.classes.max)\n if (maxValuesMessage) {\n maxValuesMessage.remove()\n }\n }\n\n // Lets check for data selected order\n if (this.settings.keepOrder) {\n selectedOptions = this.store.selectedOrderOptions(selectedOptions)\n }\n\n // Loop through currentNodes and only include ones that are not in selectedIDs\n let removeNodes: HTMLDivElement[] = []\n for (let i = 0; i < currentNodes.length; i++) {\n const node = currentNodes[i]\n const id = node.getAttribute('data-id')\n if (id) {\n // Check if id is in selectedOptions\n const found = selectedOptions.filter((opt: Option) => {\n return opt.id === id\n }, false)\n\n // If not found, add to removeNodes\n if (!found.length) {\n removeNodes.push(node)\n }\n }\n }\n\n // Loop through and remove\n for (const n of removeNodes) {\n n.classList.add(this.classes.valueOut)\n setTimeout(() => {\n if (this.main.values.hasChildNodes() && this.main.values.contains(n)) {\n this.main.values.removeChild(n)\n }\n }, 100)\n }\n\n // Add values that dont currently exist\n currentNodes = this.main.values.childNodes as NodeListOf<HTMLDivElement>\n for (let d = 0; d < selectedOptions.length; d++) {\n let shouldAdd = true\n for (let i = 0; i < currentNodes.length; i++) {\n if (selectedOptions[d].id === String(currentNodes[i].dataset.id)) {\n shouldAdd = false\n }\n }\n\n // If shouldAdd, insertAdjacentElement it to the values container in the order of the selectedOptions\n if (shouldAdd) {\n // If keepOrder is true, we will just append it to the end\n if (this.settings.keepOrder) {\n this.main.values.appendChild(this.multipleValue(selectedOptions[d]))\n } else {\n // else we will insert it in the order of the selectedOptions\n if (currentNodes.length === 0) {\n this.main.values.appendChild(this.multipleValue(selectedOptions[d]))\n } else if (d === 0) {\n this.main.values.insertBefore(this.multipleValue(selectedOptions[d]), currentNodes[d])\n } else {\n currentNodes[d - 1].insertAdjacentElement('afterend', this.multipleValue(selectedOptions[d]))\n }\n }\n }\n }\n }\n\n public multipleValue(option: Option): HTMLDivElement {\n const value = document.createElement('div')\n value.classList.add(this.classes.value)\n value.dataset.id = option.id\n\n const text = document.createElement('div')\n text.classList.add(this.classes.valueText)\n text.textContent = option.text // For multiple values always use text\n value.appendChild(text)\n\n // Only add deletion if the option is not mandatory\n if (!option.mandatory) {\n // Create delete div element\n const deleteDiv = document.createElement('div')\n deleteDiv.classList.add(this.classes.valueDelete)\n deleteDiv.setAttribute('tabindex', '0') // Make the div focusable for tab navigation\n\n // Add delete onclick event\n deleteDiv.onclick = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Dont do anything if disabled\n if (this.settings.disabled) {\n return\n }\n\n // By Default we will delete\n let shouldDelete = true\n const before = this.store.getSelectedOptions()\n const after = before.filter((o) => {\n return o.selected && o.id !== option.id\n }, true)\n\n // Check if minSelected is set and if after length so, return\n if (this.settings.minSelected && after.length < this.settings.minSelected) {\n return\n }\n\n // If there is a beforeDeselect function run it\n if (this.callbacks.beforeChange) {\n shouldDelete = this.callbacks.beforeChange(after, before) === true\n }\n\n if (shouldDelete) {\n // Loop through after and append ids to a variable called selected\n let selectedIds: string[] = []\n for (const o of after) {\n if (o instanceof Optgroup) {\n for (const c of o.options) {\n if (c.id) {\n selectedIds.push(c.id)\n }\n }\n }\n\n if (o instanceof Option) {\n selectedIds.push(o.id)\n }\n }\n this.callbacks.setSelected(selectedIds, false)\n\n // Check if we need to close the dropdown\n if (this.settings.closeOnSelect) {\n this.callbacks.close()\n }\n\n // Run afterChange callback\n if (this.callbacks.afterChange) {\n this.callbacks.afterChange(after)\n }\n\n this.updateDeselectAll()\n }\n }\n\n // Add delete svg\n const deleteSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n deleteSvg.setAttribute('viewBox', '0 0 100 100')\n const deletePath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n deletePath.setAttribute('d', this.classes.optionDelete)\n deleteSvg.appendChild(deletePath)\n deleteDiv.appendChild(deleteSvg)\n\n value.appendChild(deleteDiv)\n\n // Add keydown event listener for keyboard navigation (Enter key)\n deleteDiv.onkeydown = (e) => {\n if (e.key === 'Enter') {\n deleteDiv.click() // Trigger the click event when Enter is pressed\n }\n }\n }\n\n return value\n }\n\n public contentDiv(): Content {\n const main = document.createElement('div')\n\n // Add id to data-id\n main.dataset.id = this.settings.id\n // main.id = this.settings.id + '-content' // Remove for now as it is not needed and add duplicate id errors\n\n // Add search\n const search = this.searchDiv()\n main.appendChild(search.main)\n\n // Add list\n const list = this.listDiv()\n main.appendChild(list)\n\n return {\n main: main,\n search: search,\n list: list\n }\n }\n\n public moveContent(): void {\n // If contentPosition is relative, dont move the content anywhere other than below\n if (this.settings.contentPosition === 'relative') {\n this.moveContentBelow()\n return\n }\n\n // If openContent is not auto set content\n if (this.settings.openPosition === 'down') {\n this.moveContentBelow()\n return\n } else if (this.settings.openPosition === 'up') {\n this.moveContentAbove()\n return\n }\n\n // Auto - Determine where to put the content\n if (this.putContent() === 'up') {\n this.moveContentAbove()\n } else {\n this.moveContentBelow()\n }\n }\n\n public searchDiv(): Search {\n const main = document.createElement('div')\n const input = document.createElement('input')\n const addable = document.createElement('div')\n main.classList.add(this.classes.search)\n\n // Setup search return object\n const searchReturn: Search = {\n main,\n input\n }\n\n // We still want the search to be tabable but not shown\n if (!this.settings.showSearch) {\n main.classList.add(this.classes.hide)\n input.readOnly = true\n }\n\n input.type = 'search'\n input.placeholder = this.settings.searchPlaceholder\n input.tabIndex = -1\n input.setAttribute('aria-label', this.settings.searchPlaceholder)\n input.setAttribute('aria-autocomplete', 'list')\n input.setAttribute('autocapitalize', 'off')\n input.setAttribute('autocomplete', 'off')\n input.setAttribute('autocorrect', 'off')\n // Hide from screen readers by default (shown when opened)\n input.setAttribute('aria-hidden', 'true')\n\n input.oninput = debounce((e: Event) => {\n this.callbacks.search((e.target as HTMLInputElement).value)\n }, 100)\n\n // Deal with keyboard events on search input field\n input.onkeydown = (e: KeyboardEvent): boolean => {\n // Convert above if else statemets to switch\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up')\n return false\n case 'Tab':\n // When tabbing close the dropdown\n // which will also focus on main div\n // and then continuing normal tabbing\n this.callbacks.close()\n return true // Continue doing normal tabbing\n case 'Escape':\n this.callbacks.close()\n return false\n case ' ':\n const highlighted = this.content.list.querySelector('.' + this.classes.highlighted) as HTMLDivElement\n if (highlighted) {\n highlighted.click()\n return false\n }\n return true\n case 'Enter':\n // Check if there's a highlighted option first\n const highlightedEnter = this.content.list.querySelector('.' + this.classes.highlighted) as HTMLDivElement\n if (highlightedEnter) {\n // If an option is highlighted, select it (even if addable is enabled)\n highlightedEnter.click()\n return false\n } else if (this.callbacks.addable) {\n // If no option is highlighted and addable is enabled, add new item\n addable.click()\n return false\n }\n return true\n }\n\n return true // Allow normal typing\n }\n\n main.appendChild(input)\n\n // If addable is enabled, add the addable div\n if (this.callbacks.addable) {\n // Add main class\n addable.classList.add(this.classes.addable)\n\n // Add svg icon\n const plus = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n plus.setAttribute('viewBox', '0 0 100 100')\n const plusPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n plusPath.setAttribute('d', this.classes.addablePath)\n plus.appendChild(plusPath)\n addable.appendChild(plus)\n\n // Add click event to addable div\n addable.onclick = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Do nothing if addable is not set\n if (!this.callbacks.addable) {\n return\n }\n\n // Grab input value\n const inputValue = this.content.search.input.value.trim()\n if (inputValue === '') {\n this.content.search.input.focus()\n return\n }\n\n // Run finish will be ran at the end of the addable function.\n // Reason its in a function is so we can run it after the\n // addable function is done for promise based addables\n const runFinish = (oo: Partial<Option>) => {\n let newOption = new Option(oo)\n\n // Call addOption to add the new option\n this.callbacks.addOption(newOption)\n\n // set selected value for single and multiple\n if (this.settings.isMultiple) {\n let ids = this.store.getSelected()\n ids.push(newOption.id)\n this.callbacks.setSelected(ids, true)\n } else {\n this.callbacks.setSelected([newOption.id], true)\n }\n\n // Clear search\n this.callbacks.search('')\n\n // Close it only if closeOnSelect = true\n if (this.settings.closeOnSelect) {\n setTimeout(() => {\n // Give it a little padding for a better looking animation\n this.callbacks.close()\n }, 100)\n }\n }\n\n // Call addable callback\n const addableValue = this.callbacks.addable(inputValue)\n\n // If addableValue is false, undefined or null, do nothing\n if (addableValue === false || addableValue === undefined || addableValue === null) {\n return\n }\n\n // If addableValue is a promise, wait for it to resolve\n if (addableValue instanceof Promise) {\n addableValue.then((value) => {\n if (typeof value === 'string') {\n runFinish({\n text: value,\n value: value\n })\n } else if (addableValue instanceof Error) {\n this.renderError(addableValue.message)\n } else {\n runFinish(value)\n }\n })\n } else if (typeof addableValue === 'string') {\n runFinish({\n text: addableValue,\n value: addableValue\n })\n } else if (addableValue instanceof Error) {\n this.renderError(addableValue.message)\n } else {\n runFinish(addableValue)\n }\n\n return\n }\n main.appendChild(addable)\n\n // Add the addable to the search return\n searchReturn.addable = {\n main: addable,\n svg: plus,\n path: plusPath\n }\n }\n\n return searchReturn\n }\n\n public searchFocus(): void {\n this.content.search.input.focus()\n }\n\n public getOptions(notPlaceholder = false, notDisabled = false, notHidden = false): HTMLDivElement[] {\n // Put together query string\n let query = '.' + this.classes.option\n if (notPlaceholder) {\n query += ':not(.' + this.classes.placeholder + ')'\n }\n if (notDisabled) {\n query += ':not(.' + this.classes.disabled + ')'\n }\n if (notHidden) {\n query += ':not(.' + this.classes.hide + ')'\n }\n\n return Array.from(this.content.list.querySelectorAll(query))\n }\n\n // highlightUp is used to highlight the previous option in the list\n public highlight(dir: 'up' | 'down'): void {\n // Get full list of options in list\n const options = this.getOptions(true, true, true)\n\n // If there are no options, do nothing\n if (options.length === 0) {\n return\n }\n\n // If length is 1, highlight it\n if (options.length === 1) {\n // Check if option doesnt already have highlighted class\n if (!options[0].classList.contains(this.classes.highlighted)) {\n options[0].classList.add(this.classes.highlighted)\n return\n }\n }\n\n // Loop through options and see if there are no highlighted ones\n let highlighted = false\n for (const o of options) {\n if (o.classList.contains(this.classes.highlighted)) {\n highlighted = true\n }\n }\n\n // If no highlighted, see if any are selected and if so highlight selected first one\n if (!highlighted) {\n for (const o of options) {\n if (o.classList.contains(this.classes.selected)) {\n o.classList.add(this.classes.highlighted)\n break\n }\n }\n }\n\n // Loop through options and find the highlighted one\n for (let i = 0; i < options.length; i++) {\n // Found highlighted option\n if (options[i].classList.contains(this.classes.highlighted)) {\n const prevOption = options[i]\n // Remove highlighted class from current one\n prevOption.classList.remove(this.classes.highlighted)\n\n // If previous option has parent classes ss-optgroup with ss-open then click it\n const prevParent = prevOption.parentElement\n if (prevParent && prevParent.classList.contains(this.classes.mainOpen)) {\n const optgroupLabel = prevParent.querySelector('.' + this.classes.optgroupLabel) as HTMLDivElement\n if (optgroupLabel) {\n optgroupLabel.click()\n }\n }\n\n // Highlight the next one\n let selectOption =\n options[dir === 'down' ? (i + 1 < options.length ? i + 1 : 0) : i - 1 >= 0 ? i - 1 : options.length - 1]\n selectOption.classList.add(this.classes.highlighted)\n this.ensureElementInView(this.content.list, selectOption)\n\n // Update aria-activedescendant for screen readers\n if (selectOption.id) {\n this.main.main.setAttribute('aria-activedescendant', selectOption.id)\n }\n\n // If selected option has parent classes ss-optgroup with ss-close then click it\n const selectParent = selectOption.parentElement\n if (selectParent && selectParent.classList.contains(this.classes.close)) {\n const optgroupLabel = selectParent.querySelector('.' + this.classes.optgroupLabel) as HTMLDivElement\n if (optgroupLabel) {\n optgroupLabel.click()\n }\n }\n\n return\n }\n }\n\n // If we get here, there is no highlighted option\n // So we will highlight the first or last based upon direction\n const firstHighlight = options[dir === 'down' ? 0 : options.length - 1]\n firstHighlight.classList.add(this.classes.highlighted)\n\n // Update aria-activedescendant for screen readers\n if (firstHighlight.id) {\n this.main.main.setAttribute('aria-activedescendant', firstHighlight.id)\n }\n\n // Scroll to highlighted one\n this.ensureElementInView(this.content.list, firstHighlight)\n }\n\n // Create main container that options will reside\n public listDiv(): HTMLDivElement {\n const options = document.createElement('div')\n options.classList.add(this.classes.list)\n\n // Add id for ARIA controls reference\n const listId = this.settings.id + '-list'\n options.id = listId\n options.dataset.id = listId\n\n return options\n }\n\n public renderError(error: string) {\n // Clear out innerHtml\n this.content.list.innerHTML = ''\n\n const errorDiv = document.createElement('div')\n errorDiv.classList.add(this.classes.error)\n errorDiv.textContent = error\n this.content.list.appendChild(errorDiv)\n }\n\n public renderSearching() {\n // Clear out innerHtml\n this.content.list.innerHTML = ''\n\n const searchingDiv = document.createElement('div')\n searchingDiv.classList.add(this.classes.searching)\n searchingDiv.textContent = this.settings.searchingText\n this.content.list.appendChild(searchingDiv)\n }\n\n // Take in data and add options to\n public renderOptions(data: (Option | Optgroup)[]): void {\n // Clear out innerHtml\n this.content.list.innerHTML = ''\n\n // If no results show no results text\n if (data.length === 0) {\n const noResults = document.createElement('div')\n noResults.classList.add(this.classes.search)\n\n //\n if (this.callbacks.addable) {\n noResults.innerHTML = this.settings.addableText.replace('{value}', this.content.search.input.value)\n } else {\n noResults.innerHTML = this.settings.searchText\n }\n this.content.list.appendChild(noResults)\n return\n }\n\n // If settings has allowDeselect and isSingle, add empty placeholder in the event they want to deselect\n if (this.settings.allowDeselect && !this.settings.isMultiple) {\n // Check if store options have a placeholder\n const placeholderOption = this.store.filter((o) => o.placeholder, false) as Option[]\n if (!placeholderOption.length) {\n this.store.addOption(\n new Option({\n text: '',\n value: '',\n selected: false,\n placeholder: true\n }),\n true\n )\n }\n }\n\n // Append individual options to div container\n const fragment = document.createDocumentFragment()\n for (const d of data) {\n // Create optgroup\n if (d instanceof Optgroup) {\n // Create optgroup\n const optgroupEl = document.createElement('div')\n optgroupEl.classList.add(this.classes.optgroup)\n\n // Create label\n const optgroupLabel = document.createElement('div')\n optgroupLabel.classList.add(this.classes.optgroupLabel)\n optgroupEl.appendChild(optgroupLabel)\n\n // Create label text div element\n const optgroupLabelText = document.createElement('div')\n optgroupLabelText.classList.add(this.classes.optgroupLabelText)\n optgroupLabelText.textContent = d.label\n optgroupLabel.appendChild(optgroupLabelText)\n\n // Create options container\n const optgroupActions = document.createElement('div')\n optgroupActions.classList.add(this.classes.optgroupActions)\n optgroupLabel.appendChild(optgroupActions)\n\n // If selectByGroup is true and isMultiple then add click event to label\n if (this.settings.isMultiple && d.selectAll) {\n // Create new div to hold a checkbox svg\n const selectAll = document.createElement('div')\n selectAll.classList.add(this.classes.optgroupSelectAll)\n\n // Check options and if all are selected, if so add class selected\n let allSelected = true\n for (const o of d.options) {\n if (!o.selected) {\n allSelected = false\n break\n }\n }\n\n // Add class if all selected\n if (allSelected) {\n selectAll.classList.add(this.classes.selected)\n }\n\n // Add select all text span\n const selectAllText = document.createElement('span')\n selectAllText.textContent = d.selectAllText\n selectAll.appendChild(selectAllText)\n\n // Create new svg for checkbox\n const selectAllSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n selectAllSvg.setAttribute('viewBox', '0 0 100 100')\n selectAll.appendChild(selectAllSvg)\n\n // Create new path for box\n const selectAllBox = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n selectAllBox.setAttribute('d', this.classes.optgroupSelectAllBox)\n selectAllSvg.appendChild(selectAllBox)\n\n // Create new path for check\n const selectAllCheck = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n selectAllCheck.setAttribute('d', this.classes.optgroupSelectAllCheck)\n selectAllSvg.appendChild(selectAllCheck)\n\n // Add click event listener to select all\n selectAll.addEventListener('click', (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Get the store current selected values\n const currentSelected = this.store.getSelected()\n\n // If all selected, remove all options from selected\n // call setSelected and return\n if (allSelected) {\n // Put together new list minus all options in this optgroup\n const newSelected = currentSelected.filter((s) => {\n for (const o of d.options) {\n if (s === o.id) {\n return false\n }\n }\n\n return true\n })\n\n this.callbacks.setSelected(newSelected, true)\n return\n } else {\n // Put together new list with all options in this optgroup\n let optionIds = d.options.map((o) => o.id).filter((id) => id !== undefined)\n const newSelected = currentSelected.concat(optionIds)\n\n // Loop through options and if they don't exist in the store\n // run addOption callback\n for (const o of d.options) {\n if (o.id && !this.store.getOptionByID(o.id)) {\n this.callbacks.addOption(new Option(o))\n }\n }\n\n this.callbacks.setSelected(newSelected, true)\n return\n }\n })\n\n // Append select all to label\n optgroupActions.appendChild(selectAll)\n }\n\n // If optgroup has collapsable\n if (d.closable !== 'off') {\n // Create new div to hold a checkbox svg\n const optgroupClosable = document.createElement('div')\n optgroupClosable.classList.add(this.classes.optgroupClosable)\n\n // Create svg arrow\n const optgroupClosableSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n optgroupClosableSvg.setAttribute('viewBox', '0 0 100 100')\n optgroupClosableSvg.classList.add(this.classes.arrow)\n optgroupClosable.appendChild(optgroupClosableSvg)\n\n // Create new path for arrow\n const optgroupClosableArrow = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n optgroupClosableSvg.appendChild(optgroupClosableArrow)\n\n // If any options are selected or someone is searching, set optgroup to open\n if (d.options.some((o) => o.selected) || this.content.search.input.value.trim() !== '') {\n optgroupClosable.classList.add(this.classes.mainOpen)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen)\n } else if (d.closable === 'open') {\n optgroupEl.classList.add(this.classes.mainOpen)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen)\n } else if (d.closable === 'close') {\n optgroupEl.classList.add(this.classes.close)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowClose)\n }\n\n // Add click event listener to close\n optgroupLabel.addEventListener('click', (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // If optgroup is closed, open it\n if (optgroupEl.classList.contains(this.classes.close)) {\n optgroupEl.classList.remove(this.classes.close)\n optgroupEl.classList.add(this.classes.mainOpen)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen)\n } else {\n optgroupEl.classList.remove(this.classes.mainOpen)\n optgroupEl.classList.add(this.classes.close)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowClose)\n }\n })\n\n // Append close to label\n optgroupActions.appendChild(optgroupClosable)\n }\n\n // Add optgroup label\n optgroupEl.appendChild(optgroupLabel)\n\n // Loop through options\n for (const option of d.options) {\n optgroupEl.appendChild(this.option(new Option(option)))\n fragment.appendChild(optgroupEl)\n }\n }\n\n // Create option\n if (d instanceof Option) {\n fragment.appendChild(this.option(d as Option))\n }\n }\n\n // Append fragment to list\n this.content.list.appendChild(fragment)\n }\n\n // Create option div element\n public option(option: Option): HTMLDivElement {\n // Add hidden placeholder\n if (option.placeholder) {\n const placeholder = document.createElement('div')\n placeholder.classList.add(this.classes.option)\n placeholder.classList.add(this.classes.hide)\n return placeholder\n }\n\n // Create option\n const optionEl = document.createElement('div')\n optionEl.dataset.id = option.id // Dataset id for identifying an option\n optionEl.id = this.settings.id + '-' + option.id // Unique ID for ARIA references\n optionEl.classList.add(this.classes.option)\n optionEl.setAttribute('role', 'option') // WCAG attribute\n if (option.class) {\n option.class.split(' ').forEach((dataClass: string) => {\n optionEl.classList.add(dataClass)\n })\n }\n if (option.style) {\n optionEl.style.cssText = option.style\n }\n\n // Set option content\n if (this.settings.searchHighlight && this.content.search.input.value.trim() !== '') {\n optionEl.innerHTML = this.highlightText(\n option.html !== '' ? option.html : option.text,\n this.content.search.input.value,\n this.classes.searchHighlighter\n )\n } else if (option.html !== '') {\n optionEl.innerHTML = option.html\n } else {\n optionEl.textContent = option.text\n }\n\n // Set title attribute\n if (this.settings.showOptionTooltips && optionEl.textContent) {\n optionEl.setAttribute('title', optionEl.textContent)\n }\n\n // If option is disabled\n if (!option.display) {\n optionEl.classList.add(this.classes.hide)\n }\n\n // If allowed to deselect, null onclick and add disabled\n if (option.disabled) {\n optionEl.classList.add(this.classes.disabled)\n }\n\n // If option is selected and hideSelectedOption is true, hide it\n if (option.selected && this.settings.hideSelected) {\n optionEl.classList.add(this.classes.hide)\n }\n\n // If option is selected\n if (option.selected) {\n optionEl.classList.add(this.classes.selected)\n optionEl.setAttribute('aria-selected', 'true')\n this.main.main.setAttribute('aria-activedescendant', optionEl.id)\n } else {\n optionEl.classList.remove(this.classes.selected)\n optionEl.setAttribute('aria-selected', 'false')\n }\n\n // Add click event listener\n optionEl.addEventListener('click', (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Setup variables\n const selectedOptions = this.store.getSelected()\n const element = e.currentTarget as HTMLDivElement\n const elementID = String(element.dataset.id)\n const isCmd = e.ctrlKey || e.metaKey // Cmd (Mac) or Ctrl (Windows/Linux)\n\n // If the option is disabled, do nothing\n if (option.disabled) {\n return\n }\n\n // allowDeselect only applies to single-select mode\n // In multi-select, you can always toggle options on/off\n if (!this.settings.isMultiple && option.selected && !this.settings.allowDeselect) {\n return\n }\n\n // Prevent deselection of mandatory options\n if (option.selected && option.mandatory) {\n return\n }\n\n // Check limit and do nothing if limit is reached and the option is not selected\n // Also check reverse for min limit and is selected (allow Cmd to bypass minSelected)\n if (\n (this.settings.isMultiple && this.settings.maxSelected <= selectedOptions.length && !option.selected) ||\n (this.settings.isMultiple && this.settings.minSelected >= selectedOptions.length && option.selected && !isCmd)\n ) {\n return\n }\n\n // Setup variables\n let shouldUpdate = false\n const before = this.store.getSelectedOptions()\n let after = [] as Option[]\n\n // If multiple - mimic native browser multi-select behavior\n if (this.settings.isMultiple) {\n const isCurrentlySelected = before.some((o: Option) => o.id === elementID)\n const isShift = e.shiftKey\n\n // Shift+Click: Select range from last clicked to current\n if (isShift && this.lastSelectedOption) {\n const options = this.store.getDataOptions()\n const lastIndex = options.findIndex((o: Option) => o.id === this.lastSelectedOption!.id)\n const currentIndex = options.findIndex((o: Option) => o.id === option.id)\n\n if (lastIndex >= 0 && currentIndex >= 0) {\n const startIndex = Math.min(lastIndex, currentIndex)\n const endIndex = Math.max(lastIndex, currentIndex)\n const rangeOptions = options.slice(startIndex, endIndex + 1)\n\n // Check if range would exceed maxSelected\n const newSelections = rangeOptions.filter((opt) => !before.find((b) => b.id === opt.id))\n if (before.length + newSelections.length <= this.settings.maxSelected) {\n // Add range to existing selections\n after = before.concat(newSelections)\n } else {\n // Range too large, keep existing selections\n after = before\n }\n } else {\n after = before\n }\n }\n // Cmd/Ctrl+Click: Toggle selection without affecting others (keeps dropdown open)\n else if (isCmd) {\n if (isCurrentlySelected) {\n // Deselect this option\n after = before.filter((o: Option) => o.id !== elementID)\n } else {\n // Add this option to selection\n after = before.concat(option)\n }\n this.lastSelectedOption = option\n }\n // Regular Click: Toggle this option (add/remove), will close dropdown\n else {\n if (isCurrentlySelected) {\n // Deselect this option\n after = before.filter((o: Option) => o.id !== elementID)\n } else {\n // Add this option to selection\n after = before.concat(option)\n }\n this.lastSelectedOption = option\n }\n }\n\n // If single\n if (!this.settings.isMultiple) {\n if (option.selected) {\n // If selected after would remove\n after = []\n } else {\n // If not selected after would add\n after = [option]\n }\n }\n\n // If no beforeOnChange is set automatically update at end\n if (!this.callbacks.beforeChange) {\n shouldUpdate = true\n }\n\n if (this.callbacks.beforeChange) {\n // Check if beforeChange returns false\n if (this.callbacks.beforeChange(after, before) === false) {\n shouldUpdate = false\n } else {\n shouldUpdate = true\n }\n }\n\n if (shouldUpdate) {\n // Check if the option exists in the store\n // if not run addOption callback\n if (!this.store.getOptionByID(elementID)) {\n this.callbacks.addOption(option)\n }\n\n // Get values from after and set as selected\n this.callbacks.setSelected(\n after.map((o: Option) => o.id),\n false\n )\n\n // Close dropdown unless using modifier keys in multi-select\n // (mimics native multi-select behavior where you can keep selecting)\n const isModifierKey = e.ctrlKey || e.metaKey || e.shiftKey // Cmd/Ctrl or Shift\n const shouldClose = this.settings.closeOnSelect && !(this.settings.isMultiple && isModifierKey)\n\n if (shouldClose) {\n this.callbacks.close()\n }\n\n // callback that the value has changed\n if (this.callbacks.afterChange) {\n this.callbacks.afterChange(after)\n }\n }\n })\n\n return optionEl\n }\n\n public destroy(): void {\n // Remove main\n this.main.main.remove()\n\n // Remove content\n this.content.main.remove()\n }\n\n private highlightText(str: string, search: any, className: string) {\n const searchTerm = search.trim()\n if (searchTerm === '') {\n return str\n }\n\n // Escape special regex characters in the search term to prevent regex injection\n const escapedSearch = searchTerm.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\n // Create a temporary div to parse HTML and work with text nodes only\n const tempDiv = document.createElement('div')\n tempDiv.innerHTML = str\n\n // Function to recursively process text nodes\n const highlightTextNodes = (node: Node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || ''\n const regex = new RegExp('(' + escapedSearch + ')', 'i')\n\n if (regex.test(text)) {\n // Create a temporary container for the highlighted content\n const wrapper = document.createElement('span')\n const parts = text.split(regex)\n\n parts.forEach((part, index) => {\n if (part && regex.test(part)) {\n // This is the matched part - wrap it in mark\n const mark = document.createElement('mark')\n mark.className = className\n mark.textContent = part\n wrapper.appendChild(mark)\n } else if (part) {\n // This is not the matched part - keep as text\n wrapper.appendChild(document.createTextNode(part))\n }\n })\n\n // Replace the text node with the wrapper\n node.parentNode?.replaceChild(wrapper, node)\n }\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n // Recursively process child nodes\n Array.from(node.childNodes).forEach((child) => highlightTextNodes(child))\n }\n }\n\n // Process all text nodes in the temporary div\n Array.from(tempDiv.childNodes).forEach((node) => highlightTextNodes(node))\n\n return tempDiv.innerHTML\n }\n\n public moveContentAbove(): void {\n // Get main and content height\n const mainHeight = this.main.main.offsetHeight\n const contentHeight = this.content.main.offsetHeight\n\n // Set direction classes on both main and content\n this.main.main.classList.remove(this.classes.dirBelow)\n this.main.main.classList.add(this.classes.dirAbove)\n this.content.main.classList.remove(this.classes.dirBelow)\n this.content.main.classList.add(this.classes.dirAbove)\n\n // Set the content position\n const containerRect = this.main.main.getBoundingClientRect()\n this.content.main.style.margin = '-' + (mainHeight + contentHeight - 1) + 'px 0px 0px 0px'\n this.content.main.style.top =\n containerRect.top + containerRect.height + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollY) + 'px'\n this.content.main.style.left =\n containerRect.left + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollX) + 'px'\n this.content.main.style.width = containerRect.width + 'px'\n }\n\n public moveContentBelow(): void {\n // Set direction classes on both main and content\n this.main.main.classList.remove(this.classes.dirAbove)\n this.main.main.classList.add(this.classes.dirBelow)\n this.content.main.classList.remove(this.classes.dirAbove)\n this.content.main.classList.add(this.classes.dirBelow)\n\n // Set the content position\n const containerRect = this.main.main.getBoundingClientRect()\n this.content.main.style.margin = '-1px 0px 0px 0px'\n // Dont do anything if the content is relative\n if (this.settings.contentPosition !== 'relative') {\n this.content.main.style.top =\n containerRect.top +\n containerRect.height +\n (this.settings.contentPosition === 'fixed' ? 0 : window.scrollY) +\n 'px'\n this.content.main.style.left =\n containerRect.left + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollX) + 'px'\n this.content.main.style.width = containerRect.width + 'px'\n }\n }\n\n public ensureElementInView(container: HTMLElement, element: HTMLElement): void {\n // Determine container top and bottom\n const cTop = container.scrollTop + container.offsetTop // Make sure to have offsetTop\n const cBottom = cTop + container.clientHeight\n\n // Determine element top and bottom\n const eTop = element.offsetTop\n const eBottom = eTop + element.clientHeight\n\n // Check if out of view\n if (eTop < cTop) {\n container.scrollTop -= cTop - eTop\n } else if (eBottom > cBottom) {\n container.scrollTop += eBottom - cBottom\n }\n }\n\n public putContent(): 'up' | 'down' {\n // Get main and content height\n const mainHeight = this.main.main.offsetHeight\n const mainRect = this.main.main.getBoundingClientRect()\n const contentHeight = this.content.main.offsetHeight\n\n // From bottom of mainHeight figure out if content will fit below without going below the window\n const spaceBelow = window.innerHeight - (mainRect.top + mainHeight)\n\n // If space below is less than content height\n if (spaceBelow <= contentHeight) {\n // If space above is more than content height\n if (mainRect.top > contentHeight) {\n // Move content above\n return 'up'\n } else {\n // Move content below\n return 'down'\n }\n }\n\n // Move content below\n return 'down'\n }\n\n // Updates deselect based on item count and allowDeselect setting\n public updateDeselectAll(): void {\n if (!this.store || !this.settings) {\n return\n }\n const selected = this.store.getSelectedOptions()\n const hasSelectedItems = selected && selected.length > 0\n const isMultiple = this.settings.isMultiple\n const allowDeselect = this.settings.allowDeselect\n\n const deselectButton = this.main.deselect.main\n const hideClass = this.classes.hide\n\n if (allowDeselect && !(isMultiple && !hasSelectedItems)) {\n deselectButton.classList.remove(hideClass)\n } else {\n deselectButton.classList.add(hideClass)\n }\n }\n}\n","import { kebabCase } from './helpers'\nimport { Optgroup, Option } from './store'\n\nexport default class Select {\n public select: HTMLSelectElement\n\n // Mutation observer fields\n public onValueChange?: (value: Option[]) => void\n public onClassChange?: (classes: string[]) => void\n public onDisabledChange?: (disabled: boolean) => void\n public onOptionsChange?: (data: (Option | Optgroup)[]) => void\n public onLabelClick?: () => void\n\n // Change observers\n private listen: boolean = false\n private observer: MutationObserver | null = null\n private isUpdating: boolean = false\n private pendingOptionsChange: (Option | Optgroup)[] | null = null\n\n // Event handlers for preventing native select behavior (especially on iOS Safari)\n private preventNativeSelect: ((e: Event) => void) | null = null\n private preventNativeSelectMousedown: ((e: Event) => void) | null = null\n private preventNativeSelectFocus: ((e: Event) => void) | null = null\n\n constructor(select: HTMLSelectElement) {\n this.select = select\n\n this.valueChange = this.valueChange.bind(this)\n // Add change event listener\n this.select.addEventListener('change', this.valueChange, {\n // allow bubbling of event\n passive: true\n })\n\n // Initiate mutation observer\n this.observer = new MutationObserver(this.observeCall.bind(this))\n\n // Start listening for changes\n this.changeListen(true)\n }\n\n public enable(): void {\n this.select.disabled = false\n }\n\n public disable(): void {\n this.select.disabled = true\n }\n\n public hideUI(): void {\n this.select.tabIndex = -1\n // Visually hide but keep focusable for form validation\n // Use 1px dimensions so browser validation popup can display\n this.select.style.position = 'absolute'\n this.select.style.width = '1px'\n this.select.style.height = '1px'\n this.select.style.opacity = '0'\n this.select.style.overflow = 'hidden'\n this.select.style.pointerEvents = 'none'\n // Remove any spacing or borders that could affect layout\n this.select.style.margin = '0'\n this.select.style.padding = '0'\n this.select.style.borderWidth = '0'\n // Clip to completely hide the 1px\n this.select.style.clip = 'rect(0 0 0 0)'\n this.select.setAttribute('aria-hidden', 'true')\n\n // Prevent native select from opening when label is clicked (especially on iOS Safari)\n // iOS Safari programmatically focuses/clicks the select when label is clicked,\n // bypassing pointer-events: none, so we need to prevent these events\n // Only add listeners if they haven't been added yet\n if (!this.preventNativeSelect) {\n this.preventNativeSelect = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n this.preventNativeSelectMousedown = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n this.preventNativeSelectFocus = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n // Add event listeners with capture phase to catch events before they reach the select\n this.select.addEventListener('click', this.preventNativeSelect, { capture: true, passive: false })\n this.select.addEventListener('mousedown', this.preventNativeSelectMousedown, { capture: true, passive: false })\n this.select.addEventListener('focus', this.preventNativeSelectFocus, { capture: true, passive: false })\n }\n }\n\n public showUI(): void {\n this.select.removeAttribute('tabindex')\n // Reset visual hiding styles\n this.select.style.position = ''\n this.select.style.width = ''\n this.select.style.height = ''\n this.select.style.opacity = ''\n this.select.style.overflow = ''\n this.select.style.pointerEvents = ''\n this.select.style.margin = ''\n this.select.style.padding = ''\n this.select.style.borderWidth = ''\n this.select.style.clip = ''\n this.select.removeAttribute('aria-hidden')\n\n // Remove event listeners that prevent native select behavior\n if (this.preventNativeSelect) {\n this.select.removeEventListener('click', this.preventNativeSelect, { capture: true })\n this.preventNativeSelect = null\n }\n if (this.preventNativeSelectMousedown) {\n this.select.removeEventListener('mousedown', this.preventNativeSelectMousedown, { capture: true })\n this.preventNativeSelectMousedown = null\n }\n if (this.preventNativeSelectFocus) {\n this.select.removeEventListener('focus', this.preventNativeSelectFocus, { capture: true })\n this.preventNativeSelectFocus = null\n }\n }\n\n public changeListen(listen: boolean) {\n this.listen = listen\n\n // Start listening for changes\n if (listen) {\n if (this.observer) {\n this.observer.observe(this.select, {\n subtree: true, // subtree for optgroups options\n childList: true, // children changes\n attributes: true // attributes changes\n })\n }\n }\n\n // Stop listening for changes\n if (!listen) {\n if (this.observer) {\n this.observer.disconnect()\n }\n }\n }\n\n // This function get triggers when the select value changes\n // and will call the onValueChange function if it exists\n public valueChange(ev: Event): boolean {\n if (this.listen && this.onValueChange) {\n this.onValueChange(this.getSelectedOptions())\n }\n\n // Allow bubbling back to other change event listeners\n return true\n }\n\n private observeCall(mutations: MutationRecord[]): void {\n // If we are not listening, do nothing.\n if (!this.listen) {\n return\n }\n\n let classChanged = false\n let disabledChanged = false\n let optgroupOptionChanged = false\n\n // Loop through mutations and check various things\n for (const m of mutations) {\n // Check if its the select\n if (m.target === this.select) {\n // Check if disabled has changed\n if (m.attributeName === 'disabled') {\n disabledChanged = true\n }\n\n // Check if class has changed\n if (m.attributeName === 'class') {\n classChanged = true\n }\n\n if (m.type === 'childList') {\n for (const n of Array.from(m.addedNodes)) {\n if (n.nodeName === 'OPTION' && (<HTMLOptionElement>n).value === this.select.value) {\n // we added a new option that's now the select value\n this.select.dispatchEvent(new Event('change'))\n break\n }\n }\n\n // options changed, so we need the optionsChange event to fire\n optgroupOptionChanged = true\n }\n }\n\n // Check if its an optgroup or option\n if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {\n optgroupOptionChanged = true\n }\n }\n\n // If class has changed then call the class change function\n if (classChanged && this.onClassChange) {\n this.onClassChange(this.select.className.split(' '))\n }\n\n // If disabled has changed then call the disabled change function\n if (disabledChanged && this.onDisabledChange) {\n this.changeListen(false)\n this.onDisabledChange(this.select.disabled)\n this.changeListen(true)\n }\n\n // If optgroup or option has changed then call the select change function\n if (optgroupOptionChanged && this.onOptionsChange) {\n // If we're currently updating, queue this change to process after update completes\n if (this.isUpdating) {\n // Only queue if the select element actually has options (not empty from updateOptions clearing)\n // Check the select element directly, not getData() which might return stale data\n if (this.select.options.length > 0) {\n const currentData = this.getData()\n // Only queue if we have actual data\n if (currentData.length > 0) {\n this.pendingOptionsChange = currentData\n }\n }\n return\n }\n\n this.changeListen(false)\n this.onOptionsChange(this.getData())\n this.changeListen(true)\n }\n }\n\n // From the select element pull optgroup and options into data\n public getData(): (Option | Optgroup)[] {\n let data = []\n\n // Loop through nodes and get data\n const nodes = this.select.childNodes as any as HTMLOptGroupElement[] | HTMLOptionElement[]\n for (const n of nodes) {\n // Optgroup\n if (n.nodeName === 'OPTGROUP') {\n data.push(this.getDataFromOptgroup(n as HTMLOptGroupElement))\n }\n\n // Option\n if (n.nodeName === 'OPTION') {\n data.push(this.getDataFromOption(n as HTMLOptionElement))\n }\n }\n\n return data\n }\n\n public getDataFromOptgroup(optgroup: HTMLOptGroupElement): Optgroup {\n let data = {\n id: optgroup.id,\n label: optgroup.label,\n selectAll: optgroup.dataset ? optgroup.dataset.selectall === 'true' : false,\n selectAllText: optgroup.dataset ? optgroup.dataset.selectalltext : 'Select all',\n closable: optgroup.dataset ? optgroup.dataset.closable : 'off',\n options: []\n } as Optgroup\n\n const options = optgroup.childNodes as any as HTMLOptionElement[]\n for (const o of options) {\n if (o.nodeName === 'OPTION') {\n data.options!.push(this.getDataFromOption(o as HTMLOptionElement))\n }\n }\n\n return data\n }\n\n // From passed in option pull pieces of usable information\n public getDataFromOption(option: HTMLOptionElement): Option {\n return {\n id: option.id,\n value: option.value,\n text: option.text,\n html: option.dataset && option.dataset.html ? option.dataset.html : '',\n defaultSelected: option.defaultSelected,\n selected: option.selected,\n display: option.style.display !== 'none',\n disabled: option.disabled,\n mandatory: option.dataset ? option.dataset.mandatory === 'true' : false,\n placeholder: option.dataset.placeholder === 'true',\n class: option.className,\n style: option.style.cssText,\n data: option.dataset\n } as Option\n }\n\n public getSelectedOptions(): Option[] {\n let options = []\n\n // Loop through options and set selected\n const opts = this.select.childNodes as any as (HTMLOptGroupElement | HTMLOptionElement)[]\n for (const o of opts) {\n if (o.nodeName === 'OPTGROUP') {\n const optgroupOptions = o.childNodes as any as HTMLOptionElement[]\n for (const oo of optgroupOptions) {\n if (oo.nodeName === 'OPTION') {\n const option = oo as HTMLOptionElement\n if (option.selected) {\n options.push(this.getDataFromOption(option))\n }\n }\n }\n }\n\n if (o.nodeName === 'OPTION') {\n const option = o as HTMLOptionElement\n if (option.selected) {\n options.push(this.getDataFromOption(option))\n }\n }\n }\n\n return options\n }\n\n public getSelectedValues(): string[] {\n return this.getSelectedOptions().map((option) => option.value)\n }\n\n public setSelected(ids: string[]): void {\n // Stop listening to changes\n this.changeListen(false)\n\n // Loop through options and set selected\n const options = this.select.childNodes as any as (HTMLOptGroupElement | HTMLOptionElement)[]\n for (const o of options) {\n if (o.nodeName === 'OPTGROUP') {\n const optgroup = o as HTMLOptGroupElement\n const optgroupOptions = optgroup.childNodes as any as HTMLOptionElement[]\n for (const oo of optgroupOptions) {\n if (oo.nodeName === 'OPTION') {\n const option = oo as HTMLOptionElement\n option.selected = ids.includes(option.id)\n }\n }\n }\n\n if (o.nodeName === 'OPTION') {\n const option = o as HTMLOptionElement\n option.selected = ids.includes(option.id)\n }\n }\n\n // Stop listening to changes\n this.changeListen(true)\n }\n\n // Set selected options by value instead of id\n // This is useful when the id is not known\n // and only the value is known\n // but the value is not unique and can be duplicated\n public setSelectedByValue(values: string[]): void {\n // Stop listening to changes\n this.changeListen(false)\n\n // Loop through options and set selected\n const options = this.select.childNodes as any as (HTMLOptGroupElement | HTMLOptionElement)[]\n for (const o of options) {\n if (o.nodeName === 'OPTGROUP') {\n const optgroup = o as HTMLOptGroupElement\n const optgroupOptions = optgroup.childNodes as any as HTMLOptionElement[]\n for (const oo of optgroupOptions) {\n if (oo.nodeName === 'OPTION') {\n const option = oo as HTMLOptionElement\n option.selected = values.includes(option.value)\n }\n }\n }\n\n if (o.nodeName === 'OPTION') {\n const option = o as HTMLOptionElement\n option.selected = values.includes(option.value)\n }\n }\n\n // Stop listening to changes\n this.changeListen(true)\n }\n\n public updateSelect(id?: string, style?: string, classes?: string[]): void {\n // Stop listening to changes\n this.changeListen(false)\n\n // Update id, only if the id isnt already set\n if (id) {\n this.select.dataset.id = id\n }\n\n // Update style\n if (style) {\n this.select.style.cssText = style\n }\n\n // Update classes\n if (classes) {\n this.select.className = ''\n classes.forEach((c) => {\n if (c.trim() !== '') {\n this.select.classList.add(c.trim())\n }\n })\n }\n\n // Start listening to changes\n this.changeListen(true)\n }\n\n public updateOptions(data: (Option | Optgroup)[]): void {\n // Don't update if data is empty (prevents clearing select when no data)\n if (!data || data.length === 0) {\n return\n }\n\n // Set updating flag FIRST to prevent mutation observer from processing during update\n // This must be set before stopping listening so any queued mutations see the flag\n this.isUpdating = true\n this.pendingOptionsChange = null\n\n // Stop listening to changes\n this.changeListen(false)\n\n // Clear out select\n this.select.innerHTML = ''\n\n for (const d of data) {\n if (d instanceof Optgroup) {\n this.select.appendChild(this.createOptgroup(d))\n }\n\n if (d instanceof Option) {\n this.select.appendChild(this.createOption(d))\n }\n }\n\n // Trigger change event on original select\n this.select.dispatchEvent(new Event('change', { bubbles: true }))\n\n // Start listening to changes\n this.changeListen(true)\n\n // Clear updating flag\n this.isUpdating = false\n\n // Process any pending options change that was queued during the update\n // Only process if it has data (don't process empty data from innerHTML clearing)\n if (this.pendingOptionsChange !== null) {\n const pending: (Option | Optgroup)[] = this.pendingOptionsChange\n if (pending.length > 0 && this.onOptionsChange) {\n this.pendingOptionsChange = null\n // Process the queued change\n this.changeListen(false)\n this.onOptionsChange(pending)\n this.changeListen(true)\n } else {\n // Clear pending if it was empty\n this.pendingOptionsChange = null\n }\n }\n }\n\n public createOptgroup(optgroup: Optgroup): HTMLOptGroupElement {\n const optgroupEl = document.createElement('optgroup')\n optgroupEl.id = optgroup.id\n optgroupEl.label = optgroup.label\n if (optgroup.selectAll) {\n optgroupEl.dataset.selectAll = 'true'\n }\n if (optgroup.closable !== 'off') {\n optgroupEl.dataset.closable = optgroup.closable\n }\n if (optgroup.options) {\n for (const option of optgroup.options) {\n optgroupEl.appendChild(this.createOption(option as Option))\n }\n }\n return optgroupEl\n }\n\n public createOption(info: Option): HTMLOptionElement {\n const optionEl = document.createElement('option')\n optionEl.id = info.id\n optionEl.value = info.value\n optionEl.textContent = info.text\n if (info.html !== '') {\n optionEl.setAttribute('data-html', info.html)\n }\n optionEl.defaultSelected = info.defaultSelected\n optionEl.selected = info.selected // Explicitly set selected because defaultSelected: true sets selected to true\n if (info.disabled) {\n optionEl.disabled = true\n }\n if (!info.display) {\n optionEl.style.display = 'none'\n }\n if (info.placeholder) {\n optionEl.setAttribute('data-placeholder', 'true')\n }\n if (info.mandatory) {\n optionEl.setAttribute('data-mandatory', 'true')\n }\n if (info.class) {\n info.class.split(' ').forEach((optionClass: string) => {\n optionEl.classList.add(optionClass)\n })\n }\n if (info.data && typeof info.data === 'object') {\n Object.keys(info.data).forEach((key) => {\n optionEl.setAttribute('data-' + kebabCase(key), info.data[key])\n })\n }\n\n return optionEl\n }\n\n // Find and handle labels associated with this select\n public setupLabelHandlers(): void {\n const labels: HTMLLabelElement[] = []\n\n // Find labels that point to this select via 'for' attribute\n const selectId = this.select.id\n if (selectId) {\n const labelsByFor = document.querySelectorAll<HTMLLabelElement>(`label[for=\"${selectId}\"]`)\n labelsByFor.forEach((label) => labels.push(label))\n }\n\n // Find labels that wrap this select (label contains select)\n let parent = this.select.parentElement\n while (parent && parent !== document.body) {\n if (parent.tagName === 'LABEL') {\n labels.push(parent as HTMLLabelElement)\n break\n }\n parent = parent.parentElement\n }\n\n // Remove duplicates\n const uniqueLabels = Array.from(new Set(labels))\n\n uniqueLabels.forEach((label) => {\n // Skip if already handled\n if ((label as any).__slimSelectLabelHandler) {\n return\n }\n\n // Add click handler to label\n const labelClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement\n\n // Only continue if the target is the label\n if (target !== label) {\n return\n }\n\n // At this point, we know the click is directly on the label element\n // Prevent default label behavior (focusing the select)\n // Don't stop propagation to allow other handlers (like closing other SlimSelect instances)\n e.preventDefault()\n // e.stopPropagation() // dont stop propagation\n\n // Trigger the callback to toggle SlimSelect\n if (this.onLabelClick) {\n this.onLabelClick!()\n }\n }\n\n // Store the handler on the label for cleanup later\n ;(label as any).__slimSelectLabelHandler = labelClickHandler\n label.addEventListener('click', labelClickHandler, { capture: true, passive: false })\n })\n }\n\n // Remove label handlers\n public removeLabelHandlers(): void {\n const labels: HTMLLabelElement[] = []\n\n // Find labels that point to this select via 'for' attribute\n const selectId = this.select.id\n if (selectId) {\n const labelsByFor = document.querySelectorAll<HTMLLabelElement>(`label[for=\"${selectId}\"]`)\n labelsByFor.forEach((label) => labels.push(label))\n }\n\n // Find labels that wrap this select\n let parent = this.select.parentElement\n while (parent && parent !== document.body) {\n if (parent.tagName === 'LABEL') {\n labels.push(parent as HTMLLabelElement)\n break\n }\n parent = parent.parentElement\n }\n\n // Remove duplicates\n const uniqueLabels = Array.from(new Set(labels))\n\n uniqueLabels.forEach((label) => {\n const handler = (label as any).__slimSelectLabelHandler\n if (handler) {\n label.removeEventListener('click', handler, { capture: true })\n delete (label as any).__slimSelectLabelHandler\n }\n })\n }\n\n public destroy() {\n this.changeListen(false)\n\n // Remove event change listener\n this.select.removeEventListener('change', this.valueChange)\n\n // Remove event listeners that prevent native select behavior\n if (this.preventNativeSelect) {\n this.select.removeEventListener('click', this.preventNativeSelect, { capture: true })\n this.preventNativeSelect = null\n }\n if (this.preventNativeSelectMousedown) {\n this.select.removeEventListener('mousedown', this.preventNativeSelectMousedown, { capture: true })\n this.preventNativeSelectMousedown = null\n }\n if (this.preventNativeSelectFocus) {\n this.select.removeEventListener('focus', this.preventNativeSelectFocus, { capture: true })\n this.preventNativeSelectFocus = null\n }\n\n // Disconnect observer and null\n if (this.observer) {\n this.observer.disconnect()\n this.observer = null\n }\n\n // Remove label handlers\n this.removeLabelHandlers()\n\n // Remove dataset id from original select\n delete this.select.dataset.id\n\n // Show the original select\n this.showUI()\n }\n}\n","import { generateID } from './helpers'\n\nexport default class Settings {\n public id: string = '' // Primary ID for the select\n public style: string = '' // Style attribute from the select element\n public class: string[] = [] // Class attribute from the select element\n\n // Dynamic settings\n public isMultiple: boolean = false\n public isOpen: boolean = false\n public isFullOpen: boolean = false\n public intervalMove: ReturnType<typeof setInterval> | null = null\n\n // Fields set from constructor\n public disabled: boolean\n public alwaysOpen: boolean\n public showSearch: boolean\n public focusSearch: boolean\n public ariaLabel: string\n public searchPlaceholder: string\n public searchText: string\n public searchingText: string\n public searchHighlight: boolean\n public closeOnSelect: boolean\n public contentLocation: HTMLElement | null\n public contentPosition: 'relative' | 'absolute' | 'fixed'\n public openPosition: 'auto' | 'up' | 'down'\n public placeholderText: string\n public allowDeselect: boolean\n public hideSelected: boolean\n public keepOrder: boolean\n public showOptionTooltips: boolean\n public minSelected: number\n public maxSelected: number\n public timeoutDelay: number\n public maxValuesShown: number\n public maxValuesMessage: string\n public addableText: string\n\n constructor(settings?: Partial<Settings>) {\n if (!settings) {\n settings = {}\n }\n\n this.id = 'ss-' + generateID()\n this.style = settings.style || ''\n this.class = settings.class || []\n\n this.disabled = settings.disabled !== undefined ? settings.disabled : false\n this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false\n this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true\n this.focusSearch = settings.focusSearch !== undefined ? settings.focusSearch : true\n this.ariaLabel = settings.ariaLabel || 'Combobox'\n this.searchPlaceholder = settings.searchPlaceholder || 'Search...'\n this.searchText = settings.searchText || 'No Results'\n this.searchingText = settings.searchingText || 'Searching...'\n this.searchHighlight = settings.searchHighlight !== undefined ? settings.searchHighlight : false\n this.closeOnSelect = settings.closeOnSelect !== undefined ? settings.closeOnSelect : true\n this.contentLocation = settings.contentLocation || document.body\n this.contentPosition = settings.contentPosition || 'absolute'\n this.openPosition = settings.openPosition || 'auto' // options: auto, up, down\n this.placeholderText = settings.placeholderText !== undefined ? settings.placeholderText : 'Select Value'\n this.allowDeselect = settings.allowDeselect !== undefined ? settings.allowDeselect : false\n this.hideSelected = settings.hideSelected !== undefined ? settings.hideSelected : false\n this.keepOrder = settings.keepOrder !== undefined ? settings.keepOrder : false\n this.showOptionTooltips = settings.showOptionTooltips !== undefined ? settings.showOptionTooltips : false\n this.minSelected = settings.minSelected || 0\n this.maxSelected = settings.maxSelected || 1000\n this.timeoutDelay = settings.timeoutDelay || 200\n this.maxValuesShown = settings.maxValuesShown || 20\n this.maxValuesMessage = settings.maxValuesMessage || '{number} selected'\n this.addableText = settings.addableText || 'Press \"Enter\" to add {value}'\n }\n}\n","import CssClasses from './classes'\nimport { debounce, hasClassInTree, isEqual } from './helpers'\nimport Render from './render'\nimport Select from './select'\nimport Settings from './settings'\nimport Store, { Option, Optgroup } from './store'\n\n// Export classes\nexport { Settings, Option, Optgroup }\n\n// Export interfaces from render\nexport type { Main, Content, Search } from './render'\n\nexport interface Config {\n select: string | Element\n data?: (Partial<Option> | Partial<Optgroup>)[]\n settings?: Partial<Settings>\n cssClasses?: Partial<CssClasses>\n events?: Events\n}\n\nexport interface Events {\n search?: (\n searchValue: string,\n currentData: (Option | Optgroup)[]\n ) => Promise<(Partial<Option> | Partial<Optgroup>)[]> | (Partial<Option> | Partial<Optgroup>)[]\n searchFilter?: (option: Option, search: string) => boolean\n addable?: (\n value: string\n ) => Promise<Partial<Option> | string> | Partial<Option> | string | false | null | undefined | Error\n beforeChange?: (newVal: Option[], oldVal: Option[]) => boolean | void\n afterChange?: (newVal: Option[]) => void\n beforeOpen?: () => void\n afterOpen?: () => void\n beforeClose?: () => void\n afterClose?: () => void\n error?: (err: Error) => void\n}\n\nexport default class SlimSelect {\n public selectEl: HTMLSelectElement\n\n // Classes\n public settings!: Settings\n public cssClasses!: CssClasses\n public select!: Select\n public store!: Store\n public render!: Render\n\n // Timeout tracking for cleanup\n private openTimeout: ReturnType<typeof setTimeout> | null = null\n private closeTimeout: ReturnType<typeof setTimeout> | null = null\n\n // Events\n public events = {\n search: undefined,\n searchFilter: (opt: Option, search: string) => {\n return opt.text.toLowerCase().indexOf(search.toLowerCase()) !== -1\n },\n addable: undefined,\n beforeChange: undefined,\n afterChange: undefined,\n beforeOpen: undefined,\n afterOpen: undefined,\n beforeClose: undefined,\n afterClose: undefined\n } as Events\n\n constructor(config: Config) {\n // Make sure you get the right element\n this.selectEl = (\n typeof config.select === 'string' ? document.querySelector(config.select) : config.select\n ) as HTMLSelectElement\n if (!this.selectEl) {\n if (config.events && config.events.error) {\n config.events.error(new Error('Could not find select element'))\n }\n return\n }\n if (this.selectEl.tagName !== 'SELECT') {\n if (config.events && config.events.error) {\n config.events.error(new Error('Element isnt of type select'))\n }\n return\n }\n\n // If select already has a slim select id on it lets destroy it first\n if (this.selectEl.dataset.ssid) {\n this.destroy()\n }\n\n // Set settings\n this.settings = new Settings(config.settings)\n\n // Set CSS classes\n this.cssClasses = new CssClasses(config.cssClasses)\n\n // Set events\n const debounceEvents = ['beforeOpen', 'afterOpen', 'beforeClose', 'afterClose']\n for (const key in config.events) {\n // Check if key exists in events\n if (!config.events.hasOwnProperty(key)) {\n continue\n }\n\n // Check if key is in debounceEvents\n if (debounceEvents.indexOf(key) !== -1) {\n ;(this.events as { [key: string]: any })[key] = debounce((config.events as { [key: string]: any })[key], 100)\n } else {\n ;(this.events as { [key: string]: any })[key] = (config.events as { [key: string]: any })[key]\n }\n }\n\n // Upate settings with type, style and classname\n this.settings.disabled = config.settings?.disabled ? config.settings.disabled : this.selectEl.disabled\n this.settings.isMultiple = this.selectEl.multiple\n this.settings.style = this.selectEl.style.cssText\n this.settings.class = this.selectEl.className.split(' ')\n\n // Set select class\n this.select = new Select(this.selectEl)\n // Ensure the select has an id for label associations\n if (!this.selectEl.id) {\n this.selectEl.id = this.settings.id\n }\n this.select.updateSelect(this.settings.id, this.settings.style, this.settings.class)\n this.select.hideUI() // Hide the original select element\n\n // Add select listeners\n this.select.onValueChange = (options: Option[]) => {\n // Run set selected from the values given\n this.setSelected(options.map((option) => option.id))\n }\n this.select.onClassChange = (classes: string[]) => {\n // Update settings with new class\n this.settings.class = classes\n\n // Run render updateClassStyles\n this.render.updateClassStyles()\n }\n this.select.onDisabledChange = (disabled: boolean) => {\n if (disabled) {\n this.disable()\n } else {\n this.enable()\n }\n }\n this.select.onOptionsChange = (data: (Option | Optgroup)[]) => {\n // Process the data (including empty data for clearing all options)\n // Empty data is safe to process here because if we were updating, the change would be queued\n // and onOptionsChange wouldn't be called directly\n this.setData(data || [])\n }\n // Set up label click handler to toggle SlimSelect\n // This allows clicking the label to open/close, matching the main div behavior\n this.select.onLabelClick = () => {\n if (!this.settings.disabled) {\n this.settings.isOpen ? this.close() : this.open()\n }\n }\n\n // Set store class\n const data = config.data ? config.data : this.select.getData()\n this.store = new Store(this.settings.isMultiple ? 'multiple' : 'single', data)\n\n // If data is passed update the original select element\n if (config.data) {\n this.select.updateOptions(this.store.getData())\n }\n\n // Set render renderCallbacks\n const renderCallbacks = {\n open: this.open.bind(this),\n close: this.close.bind(this),\n addable: this.events.addable ? this.events.addable : undefined,\n setSelected: this.setSelected.bind(this),\n addOption: this.addOption.bind(this),\n search: this.search.bind(this),\n beforeChange: this.events.beforeChange,\n afterChange: this.events.afterChange\n }\n\n // Setup render class\n this.render = new Render(this.settings, this.cssClasses, this.store, renderCallbacks)\n this.render.renderValues()\n this.render.renderOptions(this.store.getData())\n\n // Add aria-label or aria-labelledby if exists\n const selectAriaLabel = this.selectEl.getAttribute('aria-label')\n const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby')\n\n if (selectAriaLabel) {\n this.render.main.main.setAttribute('aria-label', selectAriaLabel)\n } else if (selectAriaLabelledBy) {\n this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy)\n }\n\n // Add render after original select element\n if (this.selectEl.parentNode) {\n this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling)\n }\n\n // Add window resize listener to moveContent if window size changes\n window.addEventListener('resize', this.windowResize, false)\n\n // If the user wants to show the content forcibly on a specific side,\n // there is no need to listen for scroll events\n if (this.settings.openPosition === 'auto') {\n window.addEventListener('scroll', this.windowScroll, false)\n }\n\n // Add window visibility change listener to closeContent if window is hidden\n document.addEventListener('visibilitychange', this.windowVisibilityChange)\n\n // If disabled lets call it\n if (this.settings.disabled) {\n this.disable()\n }\n\n // If alwaysOpnen then open it\n if (this.settings.alwaysOpen) {\n this.open()\n }\n\n // Set up label handlers to open SlimSelect when label is clicked\n this.select.setupLabelHandlers()\n\n // Add SlimSelect to select element\n ;(this.selectEl as any).slim = this\n }\n\n // Set to enabled and remove disabled classes\n public enable(): void {\n this.settings.disabled = false\n\n this.select.enable()\n this.render.enable()\n }\n\n // Set to disabled and add disabled classes\n public disable(): void {\n this.settings.disabled = true\n\n this.select.disable()\n this.render.disable()\n }\n\n public getData(): Option[] | Optgroup[] {\n return this.store.getData()\n }\n\n public setData(data: (Partial<Option> | Partial<Optgroup>)[]): void {\n // Get original selected values\n const selected = this.store.getSelected()\n\n // Validate data\n const err = this.store.validateDataArray(data)\n if (err) {\n if (this.events.error) {\n this.events.error(err)\n }\n return\n }\n\n // Update the store\n this.store.setData(data)\n const dataClean = this.store.getData()\n\n // Update original select element\n this.select.updateOptions(dataClean)\n\n // Update the render\n this.render.renderValues()\n this.render.renderOptions(dataClean)\n\n // Trigger afterChange event, if it doesnt equal the original selected values\n if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {\n this.events.afterChange(this.store.getSelectedOptions())\n }\n }\n\n public getSelected(): string[] {\n let options = this.store.getSelectedOptions()\n if (this.settings.keepOrder) {\n options = this.store.selectedOrderOptions(options)\n }\n return options.map((option) => option.value)\n }\n\n // Will take in a string or array of strings and set the selected by either the id or value\n public setSelected(values: string | string[], runAfterChange = true): void {\n // Get original selected values\n const selected = this.store.getSelected()\n const options = this.store.getDataOptions()\n values = Array.isArray(values) ? values : [values]\n const ids = []\n\n // for back-compatibility support both, set by id and set by value\n for (const value of values) {\n if (options.find((option) => option.id == value)) {\n ids.push(value)\n continue\n }\n\n // if option with given id is not found try to search by value\n for (const option of options.filter((option) => option.value == value)) {\n ids.push(option.id)\n }\n }\n\n // Update the store\n this.store.setSelectedBy('id', ids)\n const data = this.store.getData()\n\n // Update the select element\n this.select.updateOptions(data)\n\n // Update the render\n this.render.renderValues()\n\n // If there is a search input value lets run through the search again\n // Otherwise we will just render the options from store data\n if (this.render.content.search.input.value !== '') {\n this.search(this.render.content.search.input.value)\n } else {\n this.render.renderOptions(data)\n }\n\n // Trigger afterChange event, if it doesnt equal the original selected values\n if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {\n this.events.afterChange(this.store.getSelectedOptions())\n }\n }\n\n public addOption(option: Partial<Option>): void {\n // Get original selected values\n const selected = this.store.getSelected()\n\n // Add option to store if it does not already include the option\n if (!this.store.getDataOptions().some((o) => o.value === (option.value ?? option.text))) {\n this.store.addOption(option)\n }\n const data = this.store.getData()\n\n // Update the select element\n this.select.updateOptions(data)\n\n // Update the render\n this.render.renderValues()\n this.render.renderOptions(data)\n\n // Trigger afterChange event, if it doesnt equal the original selected values\n if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {\n this.events.afterChange(this.store.getSelectedOptions())\n }\n }\n\n public open(): void {\n // Dont open if disabled\n // Dont do anything if the content is already open\n if (this.settings.disabled || this.settings.isOpen) {\n return\n }\n\n // Run beforeOpen callback\n if (this.events.beforeOpen) {\n this.events.beforeOpen()\n }\n\n // Tell render to open\n this.render.open()\n\n // Focus on input field only if search is enabled\n if (this.settings.showSearch && this.settings.focusSearch) {\n this.render.searchFocus()\n }\n\n this.settings.isOpen = true\n // setTimeout is for animation completion\n this.openTimeout = setTimeout(() => {\n // Run afterOpen callback\n if (this.events.afterOpen) {\n this.events.afterOpen()\n }\n\n // Update settings\n // Prevent overide if user close fast without wait full open\n // For detail see issue https://github.com/brianvoe/slim-select/issues/397\n if (this.settings.isOpen) {\n this.settings.isFullOpen = true\n }\n\n // Add onclick listener to document to closeContent if clicked outside\n document.addEventListener('click', this.documentClick)\n }, this.settings.timeoutDelay)\n\n // Start an interval to check if main has moved\n // in order to keep content close to main\n if (this.settings.contentPosition === 'absolute') {\n if (this.settings.intervalMove) {\n clearInterval(this.settings.intervalMove)\n }\n this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500)\n }\n }\n\n public close(eventType: string | null = null): void {\n // Dont do anything if the content is already closed\n // Dont do anything if alwaysOpen is true\n if (!this.settings.isOpen || this.settings.alwaysOpen) {\n return\n }\n\n // Run beforeClose calback\n if (this.events.beforeClose) {\n this.events.beforeClose()\n }\n\n // Tell render to close\n this.render.close()\n\n // Clear search only if not empty\n if (this.render.content.search.input.value !== '') {\n this.search('') // Clear search\n }\n\n // If we arent tabbing focus back on the main element\n this.render.mainFocus(eventType)\n\n // Update settings\n this.settings.isOpen = false\n this.settings.isFullOpen = false\n\n // Reset the content below\n this.closeTimeout = setTimeout(() => {\n // Run afterClose callback\n if (this.events.afterClose) {\n this.events.afterClose()\n }\n\n // Add onclick listener to document to closeContent if clicked outside\n document.removeEventListener('click', this.documentClick)\n }, this.settings.timeoutDelay)\n\n if (this.settings.intervalMove) {\n clearInterval(this.settings.intervalMove)\n }\n }\n\n // Take in string value and search current options\n public search(value: string): void {\n // If the passed in value is not the same as the search input value\n // then lets update the search input value\n if (this.render.content.search.input.value !== value) {\n this.render.content.search.input.value = value\n }\n\n // If value is empty then render all options\n if (value === '') {\n this.render.renderOptions(this.store.getData())\n return\n }\n\n // If no search event run regular search\n if (!this.events.search) {\n // If value is empty then render all options\n const searchResults = value === '' ? this.store.getData() : this.store.search(value, this.events.searchFilter!)\n this.render.renderOptions(searchResults)\n return\n }\n\n // Search event exists so lets render the searching text\n this.render.renderSearching()\n\n // Based upon the search event deal with the response\n const searchResp = this.events.search(value, this.store.getSelectedOptions())\n\n // If the search event returns a promise\n if (searchResp instanceof Promise) {\n searchResp\n .then((data: (Partial<Option> | Partial<Optgroup>)[]) => {\n // Update store data with search results, preserving selected options\n this.store.setData(data, true)\n\n // Update original select element\n this.select.updateOptions(this.store.getData())\n\n // Render the updated data\n this.render.renderOptions(this.store.getData())\n })\n .catch((err: Error | string) => {\n // Update the render with error\n this.render.renderError(typeof err === 'string' ? err : err.message)\n })\n\n return\n } else if (Array.isArray(searchResp)) {\n // Update store data with search results, preserving selected options\n this.store.setData(searchResp, true)\n\n // Update original select element\n this.select.updateOptions(this.store.getData())\n\n // Render the updated data\n this.render.renderOptions(this.store.getData())\n } else {\n // Update the render with error\n this.render.renderError('Search event must return a promise or an array of data')\n }\n }\n\n public destroy(): void {\n // Clear any pending timeouts\n if (this.openTimeout) {\n clearTimeout(this.openTimeout)\n this.openTimeout = null\n }\n if (this.closeTimeout) {\n clearTimeout(this.closeTimeout)\n this.closeTimeout = null\n }\n if (this.settings.intervalMove) {\n clearInterval(this.settings.intervalMove)\n this.settings.intervalMove = null\n }\n\n // Remove all event listeners\n document.removeEventListener('click', this.documentClick)\n window.removeEventListener('resize', this.windowResize, false)\n if (this.settings.openPosition === 'auto') {\n window.removeEventListener('scroll', this.windowScroll, false)\n }\n document.removeEventListener('visibilitychange', this.windowVisibilityChange)\n\n // Delete the store data\n this.store.setData([])\n\n // Remove the render\n this.render.destroy()\n\n // Show the original select element\n this.select.destroy()\n }\n\n private windowResize: (e: Event) => void = debounce(() => {\n if (!this.settings.isOpen && !this.settings.isFullOpen) {\n return\n }\n\n this.render.moveContent()\n })\n\n // Event listener for window scrolling\n private windowScroll: (e: Event) => void = debounce(() => {\n // If the content is not open, there is no need to move it\n if (!this.settings.isOpen && !this.settings.isFullOpen) {\n return\n }\n\n this.render.moveContent()\n })\n\n // Event listener for document click\n private documentClick: (e: Event) => void = (e: Event) => {\n // If the content is not open, there is no need to close it\n if (!this.settings.isOpen) {\n return\n }\n\n // Check if the click was on the content by looking at the parents\n if (e.target && !hasClassInTree(e.target as HTMLElement, this.settings.id)) {\n this.close(e.type)\n }\n }\n\n // Event Listener for window visibility change\n private windowVisibilityChange: (e: Event) => void = () => {\n if (document.hidden) {\n this.close()\n }\n }\n}\n","// UMD entry point - only exports the default SlimSelect class\n// This avoids the mixed exports issue for UMD/IIFE builds\nimport SlimSelect, * as namedExports from './index'\n\n// Attach all named exports as properties on the default export\nObject.assign(SlimSelect, namedExports)\n\nexport default SlimSelect\n"],"names":["CssClasses","classes","generateID","hasClassInTree","element","className","hasClass","e","c","parentByClass","debounce","func","wait","immediate","timeout","args","context","later","callNow","isEqual","a","b","kebabCase","str","result","match","Option","option","Optgroup","optgroup","o","Store","type","data","dataObj","validationError","dataFinal","optOptions","preserveSelected","newData","selectedOptions","missingSelected","selectedOption","found","newItem","opt","addToStart","selectedType","selectedValues","firstOption","hasSelected","selectedObjects","optionValue","selectedIds","value","id","options","search","searchFilter","filter","includeOptgroup","dataSearch","newOrder","isIn","Render","settings","store","callbacks","dirClass","selectedId","listboxId","main","highlighted","values","deselect","shouldDelete","before","after","deselectSvg","deselectPath","arrow","arrowPath","eventType","placeholderOption","placeholderText","placeholder","selected","selectedSingle","singleValue","currentNodes","maxValuesMessage","removeNodes","node","n","d","shouldAdd","i","text","deleteDiv","deleteSvg","deletePath","list","input","addable","searchReturn","highlightedEnter","plus","plusPath","inputValue","runFinish","oo","newOption","ids","addableValue","notPlaceholder","notDisabled","notHidden","query","dir","prevOption","prevParent","optgroupLabel","selectOption","selectParent","firstHighlight","listId","error","errorDiv","searchingDiv","noResults","fragment","optgroupEl","optgroupLabelText","optgroupActions","selectAll","allSelected","selectAllText","selectAllSvg","selectAllBox","selectAllCheck","currentSelected","newSelected","s","optionIds","optgroupClosable","optgroupClosableSvg","optgroupClosableArrow","optionEl","dataClass","elementID","isCmd","shouldUpdate","isCurrentlySelected","lastIndex","currentIndex","startIndex","endIndex","newSelections","isModifierKey","searchTerm","escapedSearch","tempDiv","highlightTextNodes","regex","wrapper","part","index","mark","child","mainHeight","contentHeight","containerRect","container","cTop","cBottom","eTop","eBottom","mainRect","hasSelectedItems","isMultiple","allowDeselect","deselectButton","hideClass","Select","select","listen","ev","mutations","classChanged","disabledChanged","optgroupOptionChanged","m","currentData","nodes","opts","optgroupOptions","style","pending","info","optionClass","key","labels","selectId","label","parent","labelClickHandler","handler","Settings","SlimSelect","config","debounceEvents","disabled","renderCallbacks","selectAriaLabel","selectAriaLabelledBy","err","dataClean","runAfterChange","searchResults","searchResp"],"mappings":"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"}
1
+ {"version":3,"file":"slimselect.js","sources":["../src/slim-select/classes.ts","../src/slim-select/helpers.ts","../src/slim-select/store.ts","../src/slim-select/render.ts","../src/slim-select/select.ts","../src/slim-select/settings.ts","../src/slim-select/index.ts","../src/slim-select/index.umd.ts"],"sourcesContent":["export default class CssClasses {\n public main: string\n // Placeholder\n public placeholder: string\n\n // Values\n public values: string\n public single: string\n public max: string\n public value: string\n public valueText: string\n public valueDelete: string\n public valueOut: string\n\n // Deselect\n public deselect: string\n public deselectPath: string // Not a class but whatever\n\n // Arrow\n public arrow: string\n public arrowClose: string // Not a class but whatever\n public arrowOpen: string // Not a class but whatever\n\n // Content\n public content: string\n public contentOpen: string\n public dirAbove: string\n public dirBelow: string\n\n // Search\n public search: string\n public searchHighlighter: string\n public searching: string\n public addable: string\n public addablePath: string // Not a class but whatever\n\n // List optgroups/options\n public list: string\n\n // Optgroup\n public optgroup: string\n public optgroupLabel: string\n public optgroupLabelText: string\n public optgroupActions: string\n public optgroupSelectAll: string // optgroup select all\n public optgroupSelectAllBox: string // Not a class but whatever\n public optgroupSelectAllCheck: string // Not a class but whatever\n public optgroupClosable: string\n\n // Option\n public option: string\n public optionDelete: string // Not a class but whatever\n public highlighted: string\n\n // Misc\n public mainOpen: string\n public close: string\n public selected: string\n public error: string\n public disabled: string\n public hide: string\n\n constructor(classes?: Partial<CssClasses>) {\n if (!classes) {\n classes = {}\n }\n\n this.main = classes.main || 'ss-main'\n this.placeholder = classes.placeholder || 'ss-placeholder'\n this.values = classes.values || 'ss-values'\n this.single = classes.single || 'ss-single'\n this.max = classes.max || 'ss-max'\n this.value = classes.value || 'ss-value'\n this.valueText = classes.valueText || 'ss-value-text'\n this.valueDelete = classes.valueDelete || 'ss-value-delete'\n this.valueOut = classes.valueOut || 'ss-value-out'\n\n this.deselect = classes.deselect || 'ss-deselect'\n this.deselectPath = classes.deselectPath || 'M10,10 L90,90 M10,90 L90,10'\n this.arrow = classes.arrow || 'ss-arrow'\n this.arrowClose = classes.arrowClose || 'M10,30 L50,70 L90,30'\n this.arrowOpen = classes.arrowOpen || 'M10,70 L50,30 L90,70'\n this.content = classes.content || 'ss-content'\n this.contentOpen = classes.contentOpen || 'ss-open'\n this.dirAbove = classes.dirAbove || 'ss-dir-above'\n this.dirBelow = classes.dirBelow || 'ss-dir-below'\n this.search = classes.search || 'ss-search'\n this.searchHighlighter = classes.searchHighlighter || 'ss-search-highlight'\n this.searching = classes.searching || 'ss-searching'\n this.addable = classes.addable || 'ss-addable'\n this.addablePath = classes.addablePath || 'M50,10 L50,90 M10,50 L90,50'\n this.list = classes.list || 'ss-list'\n this.optgroup = classes.optgroup || 'ss-optgroup'\n this.optgroupLabel = classes.optgroupLabel || 'ss-optgroup-label'\n this.optgroupLabelText = classes.optgroupLabelText || 'ss-optgroup-label-text'\n this.optgroupActions = classes.optgroupActions || 'ss-optgroup-actions'\n this.optgroupSelectAll = classes.optgroupSelectAll || 'ss-selectall'\n this.optgroupSelectAllBox = classes.optgroupSelectAllBox || 'M60,10 L10,10 L10,90 L90,90 L90,50'\n this.optgroupSelectAllCheck = classes.optgroupSelectAllCheck || 'M30,45 L50,70 L90,10'\n this.optgroupClosable = classes.optgroupClosable || 'ss-closable'\n this.option = classes.option || 'ss-option'\n this.optionDelete = classes.optionDelete || 'M10,10 L90,90 M10,90 L90,10'\n this.highlighted = classes.highlighted || 'ss-highlighted'\n this.mainOpen = classes.mainOpen || 'ss-open'\n this.close = classes.close || 'ss-close'\n this.selected = classes.selected || 'ss-selected'\n this.error = classes.error || 'ss-error'\n this.disabled = classes.disabled || 'ss-disabled'\n this.hide = classes.hide || 'ss-hide'\n }\n}\n","// Generate an 8 character random string\nexport function generateID(): string {\n return Math.random().toString(36).substring(2, 10)\n}\n\nexport function hasClassInTree(element: HTMLElement, className: string): HTMLElement | null {\n function hasClass(e: HTMLElement, c: string) {\n // If the element has the class return element\n if (c && e && e.classList && e.classList.contains(c)) {\n return e\n }\n\n // If the element has a dataset id of the class return element\n if (c && e && e.dataset && e.dataset.id && e.dataset.id === className) {\n return e\n }\n\n return null\n }\n\n function parentByClass(e: any, c: string): any {\n if (!e || e === (document as any)) {\n return null\n } else if (hasClass(e, c)) {\n return e\n } else {\n return parentByClass(e.parentNode, c)\n }\n }\n\n return hasClass(element, className) || parentByClass(element, className)\n}\n\n// debounce will call the last requested function after the wait time\nexport function debounce<T extends (...args: any[]) => void>(func: T, wait = 50, immediate = false): () => void {\n let timeout: any\n return function (this: any, ...args: any[]): void {\n const context = self\n const later = () => {\n timeout = null\n if (!immediate) {\n func.apply(context, args)\n }\n }\n const callNow = immediate && !timeout\n clearTimeout(timeout)\n timeout = setTimeout(later, wait)\n if (callNow) {\n func.apply(context, args)\n }\n }\n}\n\nexport function isEqual(a: any, b: any): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport function kebabCase(str: string): string {\n const result = str.replace(/[A-Z\\u00C0-\\u00D6\\u00D8-\\u00DE]/g, (match) => '-' + match.toLowerCase())\n return str[0] === str[0].toUpperCase() ? result.substring(1) : result\n}\n","import { generateID } from './helpers'\n\nexport class Option {\n id: string\n value: string\n text: string\n html: string\n defaultSelected: boolean\n selected: boolean\n display: boolean\n disabled: boolean\n placeholder: boolean\n class: string\n style: string\n data: { [key: string]: string }\n mandatory: boolean\n\n constructor(option: Partial<Option>) {\n this.id = !option.id || option.id === '' ? generateID() : option.id\n this.value = option.value === undefined ? option.text || '' : option.value || ''\n this.text = option.text || ''\n this.html = option.html || ''\n this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false\n this.selected = option.selected !== undefined ? option.selected : false\n this.display = option.display !== undefined ? option.display : true\n this.disabled = option.disabled !== undefined ? option.disabled : false\n this.mandatory = option.mandatory !== undefined ? option.mandatory : false\n this.placeholder = option.placeholder !== undefined ? option.placeholder : false\n this.class = option.class || ''\n this.style = option.style || ''\n this.data = option.data || {}\n }\n}\nexport class Optgroup {\n public id: string\n public label: string\n public selectAll: boolean\n public selectAllText: string\n public closable: 'off' | 'open' | 'close'\n public options: Partial<Option>[]\n\n constructor(optgroup: Partial<Optgroup>) {\n this.id = !optgroup.id || optgroup.id === '' ? generateID() : optgroup.id\n this.label = optgroup.label || ''\n this.selectAll = optgroup.selectAll === undefined ? false : optgroup.selectAll\n this.selectAllText = optgroup.selectAllText || 'Select All'\n this.closable = optgroup.closable || 'off'\n\n // If options exist, loop through options and create new option class\n // and set the options to the optgroup options field\n this.options = []\n if (optgroup.options) {\n for (const o of optgroup.options) {\n this.options.push(new Option(o))\n }\n }\n }\n}\n\nexport default class Store {\n private selectType: 'single' | 'multiple' = 'single'\n\n // Main data set, never null\n private data: (Option | Optgroup)[] = []\n private selectedOrder: string[] = []\n\n constructor(type: 'single' | 'multiple', data: (Partial<Option> | Partial<Optgroup>)[]) {\n this.selectType = type\n this.setData(data)\n }\n\n // Validate DataArrayPartial\n public validateDataArray(data: (Partial<Option> | Partial<Optgroup>)[]): Error | null {\n if (!Array.isArray(data)) {\n return new Error('Data must be an array')\n }\n\n // Loop through each data object\n for (let dataObj of data) {\n if (!dataObj) continue\n\n // Optgroup\n if (dataObj instanceof Optgroup || 'label' in dataObj) {\n if (!('label' in dataObj)) {\n return new Error('Optgroup must have a label')\n }\n\n if ('options' in dataObj && dataObj.options) {\n for (let option of dataObj.options) {\n const validationError = this.validateOption(option)\n if (validationError) {\n return validationError\n }\n }\n }\n } else if (dataObj instanceof Option || 'text' in dataObj) {\n const validationError = this.validateOption(dataObj)\n if (validationError) {\n return validationError\n }\n } else {\n return new Error('Data object must be a valid optgroup or option')\n }\n }\n\n return null\n }\n\n // Validate Option\n public validateOption(option: Partial<Option>): Error | null {\n if (!('text' in option)) {\n return new Error('Option must have a text')\n }\n\n return null\n }\n\n public partialToFullData(data: (Partial<Option> | Partial<Optgroup>)[]): (Option | Optgroup)[] {\n let dataFinal: (Option | Optgroup)[] = []\n data.forEach((dataObj) => {\n if (!dataObj) return\n\n // Optgroup\n if (dataObj instanceof Optgroup || 'label' in dataObj) {\n let optOptions: Option[] = []\n if ('options' in dataObj && dataObj.options) {\n dataObj.options.forEach((option: Partial<Option>) => {\n optOptions.push(new Option(option))\n })\n }\n\n if (optOptions.length > 0) {\n dataFinal.push(new Optgroup(dataObj as Partial<Optgroup>))\n }\n }\n\n // Option\n if (dataObj instanceof Option || 'text' in dataObj) {\n dataFinal.push(new Option(dataObj as Partial<Option>))\n }\n })\n\n return dataFinal\n }\n\n public setData(data: (Partial<Option> | Partial<Optgroup>)[], preserveSelected: boolean = false) {\n // Convert new data to full data array\n const newData = this.partialToFullData(data)\n\n if (preserveSelected) {\n // Get currently selected options before updating data\n const selectedOptions = this.getSelectedOptions()\n\n // Check which selected options are missing from new data\n const missingSelected: (Option | Optgroup)[] = []\n selectedOptions.forEach((selectedOption) => {\n let found = false\n\n // Check if this selected option exists in new data\n for (const newItem of newData) {\n if (newItem instanceof Option && newItem.id === selectedOption.id) {\n found = true\n break\n }\n if (newItem instanceof Optgroup) {\n for (const opt of newItem.options) {\n if (opt.id === selectedOption.id) {\n found = true\n break\n }\n }\n }\n }\n\n if (!found) {\n missingSelected.push(selectedOption)\n }\n })\n\n // Add missing selected options to the beginning of the data\n this.data = [...missingSelected, ...newData]\n } else {\n this.data = newData\n }\n\n // Run this.data through setSelected by value\n // to set the selected property and clean any wrong selected\n if (this.selectType === 'single') {\n this.setSelectedBy('id', this.getSelected())\n }\n }\n\n // Get data will return all the data\n public getData(): Option[] | Optgroup[] {\n return this.filter(null, true) as Option[] | Optgroup[]\n }\n\n // Get data options will return the data as a\n // flat array of just options\n public getDataOptions(): Option[] {\n return this.filter(null, false) as Option[]\n }\n\n public addOption(option: Partial<Option>, addToStart: boolean = false) {\n if (addToStart) {\n let data = [new Option(option)] as (Option | Optgroup)[]\n this.setData(data.concat(this.getData()))\n } else {\n this.setData(this.getData().concat(new Option(option)))\n }\n }\n\n // Pass in an array of id that will loop through\n // each option and set the selected property to true\n // but also clean selected by determining selectType\n public setSelectedBy(selectedType: 'id' | 'value', selectedValues: string[]) {\n let firstOption: Partial<Option> | null = null\n let hasSelected = false\n const selectedObjects: Partial<Option>[] = []\n\n for (let dataObj of this.data) {\n // Optgroup\n if (dataObj instanceof Optgroup) {\n for (let option of dataObj.options as Partial<Option>[]) {\n if (!firstOption) {\n firstOption = option\n }\n\n let optionValue = option[selectedType] || ''\n option.selected = hasSelected ? false : selectedValues.includes(optionValue)\n\n // If the option is selected, set hasSelected to true\n // for single based selects\n if (option.selected) {\n selectedObjects.push(option)\n\n if (this.selectType === 'single') {\n hasSelected = true\n }\n }\n }\n }\n\n // Option\n if (dataObj instanceof Option) {\n if (!firstOption) {\n firstOption = dataObj\n }\n\n dataObj.selected = hasSelected ? false : selectedValues.includes(dataObj[selectedType])\n\n // If the option is selected, set hasSelected to true\n // for single based selects\n if (dataObj.selected) {\n selectedObjects.push(dataObj)\n\n if (this.selectType === 'single') {\n hasSelected = true\n }\n }\n }\n }\n\n // If no options are selected, select the first option\n if (this.selectType === 'single' && firstOption && !hasSelected) {\n firstOption.selected = true\n selectedObjects.push(firstOption)\n }\n\n // Put together a list of selected ids in the order of the selected values\n const selectedIds = selectedValues.map((value) => {\n return selectedObjects.find((option) => option[selectedType] === value)?.id || ''\n })\n\n this.selectedOrder = selectedIds\n }\n\n public getSelected(): string[] {\n return this.getSelectedOptions().map((option) => option.id)\n }\n\n public getSelectedValues(): string[] {\n return this.getSelectedOptions().map((option) => option.value)\n }\n\n public getSelectedOptions(): Option[] {\n return this.filter((opt: Option) => {\n return opt.selected\n }, false) as Option[]\n }\n\n public getOptgroupByID(id: string): Optgroup | null {\n // Loop through each data object\n // and if optgroup is found, return it\n for (let dataObj of this.data) {\n if (dataObj instanceof Optgroup && dataObj.id === id) {\n return dataObj\n }\n }\n\n return null\n }\n\n public getOptionByID(id: string): Option | null {\n let options = this.filter((opt: Option) => {\n return opt.id === id\n }, false) as Option[]\n\n return options.length ? options[0] : null\n }\n\n public getSelectType(): string {\n return this.selectType\n }\n\n public getFirstOption(): Option | null {\n let option: Option | null = null\n for (let dataObj of this.data) {\n if (dataObj instanceof Optgroup) {\n option = dataObj.options[0] as Option\n } else if (dataObj instanceof Option) {\n option = dataObj\n }\n\n if (option) {\n break\n }\n }\n return option\n }\n\n // Take in search string and return filtered list of values\n public search(search: string, searchFilter: (opt: Option, search: string) => boolean): (Option | Optgroup)[] {\n search = search.trim()\n\n // If search is empty, return all data\n if (search === '') {\n return this.getData()\n }\n\n // Run filter with search function\n return this.filter((opt: Option): boolean => {\n return searchFilter(opt, search)\n }, true)\n }\n\n // Filter takes in a function that will be used to filter the data\n // This will also keep optgroups of sub options meet the filter requirements\n public filter(filter: { (opt: Option): boolean } | null, includeOptgroup: boolean): (Option | Optgroup)[] {\n const dataSearch: (Option | Optgroup)[] = []\n this.data.forEach((dataObj: Option | Optgroup) => {\n // Optgroup\n if (dataObj instanceof Optgroup) {\n let optOptions: Option[] = []\n let options = dataObj.options as Option[]\n options.forEach((option: Option) => {\n if (!filter || filter(option as Option)) {\n // If you dont want to include optgroups\n // just push to the dataSearch array\n if (!includeOptgroup) {\n dataSearch.push(new Option(option))\n } else {\n optOptions.push(new Option(option))\n }\n }\n })\n\n // If we pushed any options to the optOptions array\n // push the optgroup to the dataSearch array\n if (optOptions.length > 0) {\n // Create new optgroup with the new options\n let optgroup = new Optgroup(dataObj)\n optgroup.options = optOptions\n\n // Push optgroup to dataSearch\n dataSearch.push(optgroup)\n }\n }\n\n // Option\n if (dataObj instanceof Option) {\n if (!filter || filter(dataObj)) {\n dataSearch.push(new Option(dataObj))\n }\n }\n })\n\n return dataSearch\n }\n\n // Take in an array of options and reoder them based upon the selected order\n public selectedOrderOptions(options: Option[]): Option[] {\n const newOrder: Option[] = []\n this.selectedOrder.forEach((id) => {\n const option = options.find((opt) => opt.id === id)\n if (option) {\n newOrder.push(option)\n }\n })\n\n // add any remaining options that were not in the selected order\n options.forEach((option) => {\n let isIn = false\n newOrder.forEach((selectedOption) => {\n if (option.id === selectedOption.id) {\n isIn = true\n\n return\n }\n })\n\n if (!isIn) {\n newOrder.push(option)\n }\n })\n\n return newOrder\n }\n}\n","import { debounce } from './helpers'\nimport Settings from './settings'\nimport Store, { Optgroup, Option } from './store'\nimport CssClasses from './classes'\n\nexport interface Callbacks {\n open: () => void\n close: () => void\n addable?: (\n value: string\n ) => Promise<Partial<Option> | string> | Partial<Option> | string | false | undefined | null | Error\n setSelected: (value: string | string[], runAfterChange: boolean) => void\n addOption: (option: Option) => void\n search: (search: string) => void\n beforeChange?: (newVal: Option[], oldVal: Option[]) => boolean | void\n afterChange?: (newVal: Option[]) => void\n}\n\nexport interface Main {\n main: HTMLDivElement\n values: HTMLDivElement\n deselect: {\n main: HTMLDivElement\n svg: SVGSVGElement\n path: SVGPathElement\n }\n arrow: {\n main: SVGSVGElement\n path: SVGPathElement\n }\n}\n\nexport interface Content {\n main: HTMLDivElement\n search: Search\n list: HTMLDivElement\n}\n\nexport interface Search {\n main: HTMLDivElement\n input: HTMLInputElement\n addable?: {\n main: HTMLDivElement\n svg: SVGSVGElement\n path: SVGPathElement\n }\n}\n\nexport default class Render {\n public settings: Settings\n public store: Store\n public callbacks: Callbacks\n\n // Used to compute the range selection\n private lastSelectedOption: Option | null\n\n // Elements\n public main: Main\n public content: Content\n\n // Classes\n public classes: CssClasses\n\n constructor(settings: Required<Settings>, classes: Required<CssClasses>, store: Store, callbacks: Callbacks) {\n this.store = store\n this.settings = settings\n this.classes = classes\n this.callbacks = callbacks\n this.lastSelectedOption = null\n\n this.main = this.mainDiv()\n this.content = this.contentDiv()\n\n // Add classes and styles to main/content\n this.updateClassStyles()\n this.updateAriaAttributes()\n\n // Position content off-screen initially to prevent scrollbars\n // This must be after updateClassStyles() since it removes all style attributes\n // The main element isn't in the DOM yet, so getBoundingClientRect() would return zeros\n // Once opened, moveContent() will position it correctly\n if (this.settings.contentPosition !== 'relative') {\n this.content.main.style.top = '-9999px'\n this.content.main.style.left = '-9999px'\n this.content.main.style.margin = '0'\n this.content.main.style.width = 'auto'\n }\n\n // Add content to the content location settings\n if (this.settings.contentLocation) {\n this.settings.contentLocation.appendChild(this.content.main)\n }\n }\n\n // Remove disabled classes\n public enable(): void {\n // Remove disabled class\n this.main.main.classList.remove(this.classes.disabled)\n this.main.main.setAttribute('aria-disabled', 'false')\n\n // Set search input to \"enabled\"\n this.content.search.input.disabled = false\n }\n\n // Set disabled classes\n public disable(): void {\n // Add disabled class\n this.main.main.classList.add(this.classes.disabled)\n this.main.main.setAttribute('aria-disabled', 'true')\n\n // Set search input to disabled\n this.content.search.input.disabled = true\n }\n\n public open(): void {\n this.main.arrow.path.setAttribute('d', this.classes.arrowOpen)\n this.main.main.setAttribute('aria-expanded', 'true')\n\n // Set direction class on both main and content (persists, never removed)\n const isAbove = this.settings.openPosition === 'up'\n const dirClass = isAbove ? this.classes.dirAbove : this.classes.dirBelow\n this.main.main.classList.add(dirClass)\n this.content.main.classList.add(dirClass)\n\n // Add open class to content to trigger open animation\n this.content.main.classList.add(this.classes.contentOpen)\n\n // Make search visible to screen readers when opened\n this.content.search.input.removeAttribute('aria-hidden')\n\n // move the content in to the right location\n this.moveContent()\n\n // Move to last selected option\n const selectedOptions = this.store.getSelectedOptions()\n if (selectedOptions.length) {\n const selectedId = selectedOptions[selectedOptions.length - 1].id\n const selectedOption = this.content.list.querySelector('[data-id=\"' + selectedId + '\"]') as HTMLElement\n if (selectedOption) {\n this.ensureElementInView(this.content.list, selectedOption)\n }\n }\n }\n\n public close(): void {\n this.main.main.setAttribute('aria-expanded', 'false')\n this.main.arrow.path.setAttribute('d', this.classes.arrowClose)\n\n // Remove open class from content to trigger close animation\n // Direction class (dirAbove/dirBelow) persists to maintain correct transform-origin\n this.content.main.classList.remove(this.classes.contentOpen)\n\n // Hide search from screen readers when closed\n this.content.search.input.setAttribute('aria-hidden', 'true')\n\n // Clear active descendant when closed\n this.main.main.removeAttribute('aria-activedescendant')\n\n // Remove direction class from main and content after animation is complete\n const animationTiming = this.getAnimationTiming()\n setTimeout(() => {\n this.main.main.classList.remove(this.classes.dirAbove, this.classes.dirBelow)\n this.content.main.classList.remove(this.classes.dirAbove, this.classes.dirBelow)\n }, animationTiming)\n }\n\n private getAnimationTiming(): number {\n const computedStyle = getComputedStyle(this.content.main)\n const cssValue = computedStyle.getPropertyValue('--ss-animation-timing').trim()\n\n if (cssValue) {\n // Parse CSS time value (e.g., \"0.2s\" or \"200ms\")\n if (cssValue.endsWith('ms')) {\n return parseFloat(cssValue)\n } else if (cssValue.endsWith('s')) {\n return parseFloat(cssValue) * 1000\n }\n }\n\n // Fall back to default 200ms\n return 200\n }\n\n public updateClassStyles(): void {\n // Clear all classes and styles\n this.main.main.className = ''\n this.main.main.removeAttribute('style')\n this.content.main.className = ''\n this.content.main.removeAttribute('style')\n\n // Make sure main/content has its base class\n this.main.main.classList.add(this.classes.main)\n this.content.main.classList.add(this.classes.content)\n\n // Add styles\n if (this.settings.style !== '') {\n this.main.main.style.cssText = this.settings.style\n this.content.main.style.cssText = this.settings.style\n }\n\n // Add classes\n if (this.settings.class.length) {\n for (const c of this.settings.class) {\n if (c.trim() !== '') {\n this.main.main.classList.add(c.trim())\n this.content.main.classList.add(c.trim())\n }\n }\n }\n\n // Misc classes\n // Add content position class\n if (this.settings.contentPosition === 'relative' || this.settings.contentPosition === 'fixed') {\n this.content.main.classList.add('ss-' + this.settings.contentPosition)\n }\n }\n\n public updateAriaAttributes() {\n const listboxId = this.content.list.id\n\n // Main combobox\n this.main.main.role = 'combobox'\n this.main.main.setAttribute('aria-haspopup', 'listbox')\n this.main.main.setAttribute('aria-controls', listboxId)\n this.main.main.setAttribute('aria-expanded', 'false')\n\n this.content.list.setAttribute('role', 'listbox')\n this.content.list.setAttribute('aria-label', this.settings.ariaLabel + ' listbox')\n\n // Add aria-multiselectable for multiple selects\n if (this.settings.isMultiple) {\n this.content.list.setAttribute('aria-multiselectable', 'true')\n }\n\n // Search input should also control the listbox\n this.content.search.input.setAttribute('aria-controls', listboxId)\n }\n\n public mainDiv(): Main {\n // Create main container\n const main = document.createElement('div')\n\n // Add id to data-id\n main.dataset.id = this.settings.id\n // main.id = this.settings.id+'-main' // Remove for now as it is not needed and add duplicate id errors\n\n // Add label\n main.setAttribute('aria-label', this.settings.ariaLabel)\n\n // Set tabable to allow tabbing to the element\n main.tabIndex = 0\n\n // Deal with keyboard events on the main div\n // This is to allow for normal selecting\n // when you may not have a search bar\n main.onkeydown = (e: KeyboardEvent): boolean => {\n // Convert above if else statemets to switch\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n this.callbacks.open()\n e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up')\n return false\n case 'Tab':\n this.callbacks.close()\n return true // Continue doing normal tabbing\n case 'Enter':\n case ' ':\n this.callbacks.open()\n const highlighted = this.content.list.querySelector('.' + this.classes.highlighted) as HTMLDivElement\n if (highlighted) {\n highlighted.click()\n }\n return false\n case 'Escape':\n this.callbacks.close()\n return false\n }\n\n // Check if they type a-z, A-Z and 0-9\n if (e.key.length === 1) {\n this.callbacks.open()\n }\n\n return true\n }\n\n // Add onclick for main div\n main.onclick = (e: Event): void => {\n // Dont do anything if disabled\n if (this.settings.disabled) {\n return\n }\n\n this.settings.isOpen ? this.callbacks.close() : this.callbacks.open()\n }\n\n // Add values\n const values = document.createElement('div')\n values.classList.add(this.classes.values)\n main.appendChild(values)\n\n // Add deselect\n const deselect = document.createElement('div')\n deselect.classList.add(this.classes.deselect)\n\n // Check if deselect is to be shown or not\n const selectedOptions = this.store?.getSelectedOptions()\n if (!this.settings.allowDeselect || (this.settings.isMultiple && selectedOptions && selectedOptions.length <= 0)) {\n deselect.classList.add(this.classes.hide)\n } else {\n deselect.classList.remove(this.classes.hide)\n }\n\n // Add deselect onclick event\n deselect.onclick = (e: Event) => {\n e.stopPropagation()\n\n // Dont do anything if disabled\n if (this.settings.disabled) {\n return\n }\n\n // By Default we will delete\n let shouldDelete = true\n const before = this.store.getSelectedOptions()\n const after = [] as Option[]\n\n // Add beforeChange callback\n if (this.callbacks.beforeChange) {\n shouldDelete = this.callbacks.beforeChange(after, before) === true\n }\n\n if (shouldDelete) {\n if (this.settings.isMultiple) {\n this.callbacks.setSelected([], false)\n this.updateDeselectAll()\n } else {\n // Get first option and set it as selected\n const firstOption = this.store.getFirstOption()\n const id = firstOption ? firstOption.id : ''\n\n this.callbacks.setSelected(id, false)\n }\n\n // Check if we need to close the dropdown\n if (this.settings.closeOnSelect) {\n this.callbacks.close()\n }\n\n // Run afterChange callback\n if (this.callbacks.afterChange) {\n this.callbacks.afterChange(this.store.getSelectedOptions())\n }\n }\n }\n\n // Add deselect svg\n const deselectSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n deselectSvg.setAttribute('viewBox', '0 0 100 100')\n const deselectPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n deselectPath.setAttribute('d', this.classes.deselectPath)\n deselectSvg.appendChild(deselectPath)\n deselect.appendChild(deselectSvg)\n main.appendChild(deselect)\n\n // Add arrow\n const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n arrow.classList.add(this.classes.arrow)\n arrow.setAttribute('viewBox', '0 0 100 100')\n const arrowPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n arrowPath.setAttribute('d', this.classes.arrowClose)\n if (this.settings.alwaysOpen) {\n arrow.classList.add(this.classes.hide)\n }\n arrow.appendChild(arrowPath)\n main.appendChild(arrow)\n\n return {\n main: main,\n values: values,\n deselect: {\n main: deselect,\n svg: deselectSvg,\n path: deselectPath\n },\n arrow: {\n main: arrow,\n path: arrowPath\n }\n }\n }\n\n public mainFocus(eventType: string | null): void {\n // Trigger focus but dont scroll to it\n // Need for prevent refocus the element if event is not keyboard event.\n // For example if event is mouse click or tachpad click this condition prevent refocus on element\n // because click by mouse change focus position and not need return focus to element.\n if (eventType !== 'click') {\n this.main.main.focus({ preventScroll: true })\n }\n }\n\n public placeholder(): HTMLDivElement {\n // Figure out if there is a placeholder option\n const placeholderOption = this.store.filter((o) => o.placeholder, false) as Option[]\n\n // If there is a placeholder option use that\n // If placeholder has an html value, use that\n // If placeholder has a text, use that\n // If nothing is set, use the placeholder text\n let placeholderText = this.settings.placeholderText\n if (placeholderOption.length) {\n if (placeholderOption[0].html !== '') {\n placeholderText = placeholderOption[0].html\n } else if (placeholderOption[0].text !== '') {\n placeholderText = placeholderOption[0].text\n }\n }\n\n // Create placeholder div\n const placeholder = document.createElement('div')\n placeholder.classList.add(this.classes.placeholder)\n placeholder.innerHTML = placeholderText\n return placeholder\n }\n\n // Get selected values and append to multiSelected values container\n // and remove those who shouldnt exist\n public renderValues(): void {\n // If single select set placeholder or selected value\n if (!this.settings.isMultiple) {\n this.renderSingleValue()\n return\n }\n\n this.renderMultipleValues()\n\n this.updateDeselectAll()\n }\n\n private renderSingleValue(): void {\n const selected = this.store.filter((o: Option): boolean => {\n return o.selected && !o.placeholder\n }, false) as Option[]\n const selectedSingle = selected.length > 0 ? selected[0] : null\n\n // If nothing is seleected use settings placeholder text\n if (!selectedSingle) {\n this.main.values.innerHTML = this.placeholder().outerHTML\n } else {\n // Create single value container\n const singleValue = document.createElement('div')\n singleValue.classList.add(this.classes.single)\n if (selectedSingle.html) {\n singleValue.innerHTML = selectedSingle.html\n } else {\n singleValue.innerText = selectedSingle.text\n }\n\n // If there is a selected value, set a single div\n this.main.values.innerHTML = singleValue.outerHTML\n }\n\n // If allowDeselect is false or selected value is empty just hide deselect\n if (!this.settings.allowDeselect || !selected.length) {\n this.main.deselect.main.classList.add(this.classes.hide)\n } else {\n this.main.deselect.main.classList.remove(this.classes.hide)\n }\n }\n\n private renderMultipleValues(): void {\n // Get various pieces of data\n let currentNodes = this.main.values.childNodes as NodeListOf<HTMLDivElement>\n let selectedOptions = this.store.filter((opt: Option) => {\n // Only grab options that are selected and display is true\n return opt.selected && opt.display\n }, false) as Option[]\n\n // If selectedOptions is empty set placeholder\n if (selectedOptions.length === 0) {\n this.main.values.innerHTML = this.placeholder().outerHTML\n return\n } else {\n // If there is a placeholder, remove it\n const placeholder = this.main.values.querySelector('.' + this.classes.placeholder)\n if (placeholder) {\n placeholder.remove()\n }\n }\n\n // If selectedOptions is greater than maxItems, set maxValuesMessage\n if (selectedOptions.length > this.settings.maxValuesShown) {\n // Creating the element that shows the number of selected items\n const singleValue = document.createElement('div')\n singleValue.classList.add(this.classes.max)\n singleValue.textContent = this.settings.maxValuesMessage.replace('{number}', selectedOptions.length.toString())\n\n // If there is a selected value, set a single div\n this.main.values.innerHTML = singleValue.outerHTML\n return\n } else {\n // If there is a message, remove it\n const maxValuesMessage = this.main.values.querySelector('.' + this.classes.max)\n if (maxValuesMessage) {\n maxValuesMessage.remove()\n }\n }\n\n // Lets check for data selected order\n if (this.settings.keepOrder) {\n selectedOptions = this.store.selectedOrderOptions(selectedOptions)\n }\n\n // Loop through currentNodes and only include ones that are not in selectedIDs\n let removeNodes: HTMLDivElement[] = []\n for (let i = 0; i < currentNodes.length; i++) {\n const node = currentNodes[i]\n const id = node.getAttribute('data-id')\n if (id) {\n // Check if id is in selectedOptions\n const found = selectedOptions.filter((opt: Option) => {\n return opt.id === id\n }, false)\n\n // If not found, add to removeNodes\n if (!found.length) {\n removeNodes.push(node)\n }\n }\n }\n\n // Loop through and remove\n for (const n of removeNodes) {\n n.classList.add(this.classes.valueOut)\n setTimeout(() => {\n if (this.main.values.hasChildNodes() && this.main.values.contains(n)) {\n this.main.values.removeChild(n)\n }\n }, 100)\n }\n\n // Add values that dont currently exist\n currentNodes = this.main.values.childNodes as NodeListOf<HTMLDivElement>\n for (let d = 0; d < selectedOptions.length; d++) {\n let shouldAdd = true\n for (let i = 0; i < currentNodes.length; i++) {\n if (selectedOptions[d].id === String(currentNodes[i].dataset.id)) {\n shouldAdd = false\n }\n }\n\n // If shouldAdd, insertAdjacentElement it to the values container in the order of the selectedOptions\n if (shouldAdd) {\n // If keepOrder is true, we will just append it to the end\n if (this.settings.keepOrder) {\n this.main.values.appendChild(this.multipleValue(selectedOptions[d]))\n } else {\n // else we will insert it in the order of the selectedOptions\n if (currentNodes.length === 0) {\n this.main.values.appendChild(this.multipleValue(selectedOptions[d]))\n } else if (d === 0) {\n this.main.values.insertBefore(this.multipleValue(selectedOptions[d]), currentNodes[d])\n } else {\n currentNodes[d - 1].insertAdjacentElement('afterend', this.multipleValue(selectedOptions[d]))\n }\n }\n }\n }\n }\n\n public multipleValue(option: Option): HTMLDivElement {\n const value = document.createElement('div')\n value.classList.add(this.classes.value)\n value.dataset.id = option.id\n\n const text = document.createElement('div')\n text.classList.add(this.classes.valueText)\n text.textContent = option.text // For multiple values always use text\n value.appendChild(text)\n\n // Only add deletion if the option is not mandatory\n if (!option.mandatory) {\n // Create delete div element\n const deleteDiv = document.createElement('div')\n deleteDiv.classList.add(this.classes.valueDelete)\n deleteDiv.setAttribute('tabindex', '0') // Make the div focusable for tab navigation\n\n // Add delete onclick event\n deleteDiv.onclick = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Dont do anything if disabled\n if (this.settings.disabled) {\n return\n }\n\n // By Default we will delete\n let shouldDelete = true\n const before = this.store.getSelectedOptions()\n const after = before.filter((o) => {\n return o.selected && o.id !== option.id\n }, true)\n\n // Check if minSelected is set and if after length so, return\n if (this.settings.minSelected && after.length < this.settings.minSelected) {\n return\n }\n\n // If there is a beforeDeselect function run it\n if (this.callbacks.beforeChange) {\n shouldDelete = this.callbacks.beforeChange(after, before) === true\n }\n\n if (shouldDelete) {\n // Loop through after and append ids to a variable called selected\n let selectedIds: string[] = []\n for (const o of after) {\n if (o instanceof Optgroup) {\n for (const c of o.options) {\n if (c.id) {\n selectedIds.push(c.id)\n }\n }\n }\n\n if (o instanceof Option) {\n selectedIds.push(o.id)\n }\n }\n this.callbacks.setSelected(selectedIds, false)\n\n // Check if we need to close the dropdown\n if (this.settings.closeOnSelect) {\n this.callbacks.close()\n }\n\n // Run afterChange callback\n if (this.callbacks.afterChange) {\n this.callbacks.afterChange(after)\n }\n\n this.updateDeselectAll()\n }\n }\n\n // Add delete svg\n const deleteSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n deleteSvg.setAttribute('viewBox', '0 0 100 100')\n const deletePath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n deletePath.setAttribute('d', this.classes.optionDelete)\n deleteSvg.appendChild(deletePath)\n deleteDiv.appendChild(deleteSvg)\n\n value.appendChild(deleteDiv)\n\n // Add keydown event listener for keyboard navigation (Enter key)\n deleteDiv.onkeydown = (e) => {\n if (e.key === 'Enter') {\n deleteDiv.click() // Trigger the click event when Enter is pressed\n }\n }\n }\n\n return value\n }\n\n public contentDiv(): Content {\n const main = document.createElement('div')\n\n // Add id to data-id\n main.dataset.id = this.settings.id\n // main.id = this.settings.id + '-content' // Remove for now as it is not needed and add duplicate id errors\n\n // Add search\n const search = this.searchDiv()\n main.appendChild(search.main)\n\n // Add list\n const list = this.listDiv()\n main.appendChild(list)\n\n return {\n main: main,\n search: search,\n list: list\n }\n }\n\n public moveContent(): void {\n // If contentPosition is relative, dont move the content anywhere other than below\n if (this.settings.contentPosition === 'relative') {\n this.moveContentBelow()\n return\n }\n\n // If openContent is not auto set content\n if (this.settings.openPosition === 'down') {\n this.moveContentBelow()\n return\n } else if (this.settings.openPosition === 'up') {\n this.moveContentAbove()\n return\n }\n\n // Auto - Determine where to put the content\n if (this.putContent() === 'up') {\n this.moveContentAbove()\n } else {\n this.moveContentBelow()\n }\n }\n\n public searchDiv(): Search {\n const main = document.createElement('div')\n const input = document.createElement('input')\n const addable = document.createElement('div')\n main.classList.add(this.classes.search)\n\n // Setup search return object\n const searchReturn: Search = {\n main,\n input\n }\n\n // We still want the search to be tabable but not shown\n if (!this.settings.showSearch) {\n main.classList.add(this.classes.hide)\n input.readOnly = true\n }\n\n input.type = 'search'\n input.placeholder = this.settings.searchPlaceholder\n input.tabIndex = -1\n input.setAttribute('aria-label', this.settings.searchPlaceholder)\n input.setAttribute('aria-autocomplete', 'list')\n input.setAttribute('autocapitalize', 'off')\n input.setAttribute('autocomplete', 'off')\n input.setAttribute('autocorrect', 'off')\n // Hide from screen readers by default (shown when opened)\n input.setAttribute('aria-hidden', 'true')\n\n input.oninput = debounce((e: Event) => {\n this.callbacks.search((e.target as HTMLInputElement).value)\n }, 100)\n\n // Deal with keyboard events on search input field\n input.onkeydown = (e: KeyboardEvent): boolean => {\n // Convert above if else statemets to switch\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up')\n return false\n case 'Tab':\n // When tabbing close the dropdown\n // which will also focus on main div\n // and then continuing normal tabbing\n this.callbacks.close()\n return true // Continue doing normal tabbing\n case 'Escape':\n this.callbacks.close()\n return false\n case ' ':\n const highlighted = this.content.list.querySelector('.' + this.classes.highlighted) as HTMLDivElement\n if (highlighted) {\n highlighted.click()\n return false\n }\n return true\n case 'Enter':\n // Check if there's a highlighted option first\n const highlightedEnter = this.content.list.querySelector('.' + this.classes.highlighted) as HTMLDivElement\n if (highlightedEnter) {\n // If an option is highlighted, select it (even if addable is enabled)\n highlightedEnter.click()\n return false\n } else if (this.callbacks.addable) {\n // If no option is highlighted and addable is enabled, add new item\n addable.click()\n return false\n }\n return true\n }\n\n return true // Allow normal typing\n }\n\n main.appendChild(input)\n\n // If addable is enabled, add the addable div\n if (this.callbacks.addable) {\n // Add main class\n addable.classList.add(this.classes.addable)\n\n // Add svg icon\n const plus = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n plus.setAttribute('viewBox', '0 0 100 100')\n const plusPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n plusPath.setAttribute('d', this.classes.addablePath)\n plus.appendChild(plusPath)\n addable.appendChild(plus)\n\n // Add click event to addable div\n addable.onclick = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Do nothing if addable is not set\n if (!this.callbacks.addable) {\n return\n }\n\n // Grab input value\n const inputValue = this.content.search.input.value.trim()\n if (inputValue === '') {\n this.content.search.input.focus()\n return\n }\n\n // Run finish will be ran at the end of the addable function.\n // Reason its in a function is so we can run it after the\n // addable function is done for promise based addables\n const runFinish = (oo: Partial<Option>) => {\n let newOption = new Option(oo)\n\n // Call addOption to add the new option\n this.callbacks.addOption(newOption)\n\n // set selected value for single and multiple\n if (this.settings.isMultiple) {\n let ids = this.store.getSelected()\n ids.push(newOption.id)\n this.callbacks.setSelected(ids, true)\n } else {\n this.callbacks.setSelected([newOption.id], true)\n }\n\n // Clear search\n this.callbacks.search('')\n\n // Close it only if closeOnSelect = true\n if (this.settings.closeOnSelect) {\n setTimeout(() => {\n // Give it a little padding for a better looking animation\n this.callbacks.close()\n }, 100)\n }\n }\n\n // Call addable callback\n const addableValue = this.callbacks.addable(inputValue)\n\n // If addableValue is false, undefined or null, do nothing\n if (addableValue === false || addableValue === undefined || addableValue === null) {\n return\n }\n\n // If addableValue is a promise, wait for it to resolve\n if (addableValue instanceof Promise) {\n addableValue.then((value) => {\n if (typeof value === 'string') {\n runFinish({\n text: value,\n value: value\n })\n } else if (addableValue instanceof Error) {\n this.renderError(addableValue.message)\n } else {\n runFinish(value)\n }\n })\n } else if (typeof addableValue === 'string') {\n runFinish({\n text: addableValue,\n value: addableValue\n })\n } else if (addableValue instanceof Error) {\n this.renderError(addableValue.message)\n } else {\n runFinish(addableValue)\n }\n\n return\n }\n main.appendChild(addable)\n\n // Add the addable to the search return\n searchReturn.addable = {\n main: addable,\n svg: plus,\n path: plusPath\n }\n }\n\n return searchReturn\n }\n\n public searchFocus(): void {\n this.content.search.input.focus({ preventScroll: true })\n }\n\n public getOptions(notPlaceholder = false, notDisabled = false, notHidden = false): HTMLDivElement[] {\n // Put together query string\n let query = '.' + this.classes.option\n if (notPlaceholder) {\n query += ':not(.' + this.classes.placeholder + ')'\n }\n if (notDisabled) {\n query += ':not(.' + this.classes.disabled + ')'\n }\n if (notHidden) {\n query += ':not(.' + this.classes.hide + ')'\n }\n\n return Array.from(this.content.list.querySelectorAll(query))\n }\n\n // highlightUp is used to highlight the previous option in the list\n public highlight(dir: 'up' | 'down'): void {\n // Get full list of options in list\n const options = this.getOptions(true, true, true)\n\n // If there are no options, do nothing\n if (options.length === 0) {\n return\n }\n\n // If length is 1, highlight it\n if (options.length === 1) {\n // Check if option doesnt already have highlighted class\n if (!options[0].classList.contains(this.classes.highlighted)) {\n options[0].classList.add(this.classes.highlighted)\n return\n }\n }\n\n // Loop through options and see if there are no highlighted ones\n let highlighted = false\n for (const o of options) {\n if (o.classList.contains(this.classes.highlighted)) {\n highlighted = true\n }\n }\n\n // If no highlighted, see if any are selected and if so highlight selected first one\n if (!highlighted) {\n for (const o of options) {\n if (o.classList.contains(this.classes.selected)) {\n o.classList.add(this.classes.highlighted)\n break\n }\n }\n }\n\n // Loop through options and find the highlighted one\n for (let i = 0; i < options.length; i++) {\n // Found highlighted option\n if (options[i].classList.contains(this.classes.highlighted)) {\n const prevOption = options[i]\n // Remove highlighted class from current one\n prevOption.classList.remove(this.classes.highlighted)\n\n // If previous option has parent classes ss-optgroup with ss-open then click it\n const prevParent = prevOption.parentElement\n if (prevParent && prevParent.classList.contains(this.classes.mainOpen)) {\n const optgroupLabel = prevParent.querySelector('.' + this.classes.optgroupLabel) as HTMLDivElement\n if (optgroupLabel) {\n optgroupLabel.click()\n }\n }\n\n // Highlight the next one\n let selectOption =\n options[dir === 'down' ? (i + 1 < options.length ? i + 1 : 0) : i - 1 >= 0 ? i - 1 : options.length - 1]\n selectOption.classList.add(this.classes.highlighted)\n this.ensureElementInView(this.content.list, selectOption)\n\n // Update aria-activedescendant for screen readers\n if (selectOption.id) {\n this.main.main.setAttribute('aria-activedescendant', selectOption.id)\n }\n\n // If selected option has parent classes ss-optgroup with ss-close then click it\n const selectParent = selectOption.parentElement\n if (selectParent && selectParent.classList.contains(this.classes.close)) {\n const optgroupLabel = selectParent.querySelector('.' + this.classes.optgroupLabel) as HTMLDivElement\n if (optgroupLabel) {\n optgroupLabel.click()\n }\n }\n\n return\n }\n }\n\n // If we get here, there is no highlighted option\n // So we will highlight the first or last based upon direction\n const firstHighlight = options[dir === 'down' ? 0 : options.length - 1]\n firstHighlight.classList.add(this.classes.highlighted)\n\n // Update aria-activedescendant for screen readers\n if (firstHighlight.id) {\n this.main.main.setAttribute('aria-activedescendant', firstHighlight.id)\n }\n\n // Scroll to highlighted one\n this.ensureElementInView(this.content.list, firstHighlight)\n }\n\n // Create main container that options will reside\n public listDiv(): HTMLDivElement {\n const options = document.createElement('div')\n options.classList.add(this.classes.list)\n\n // Add id for ARIA controls reference\n const listId = this.settings.id + '-list'\n options.id = listId\n options.dataset.id = listId\n\n return options\n }\n\n public renderError(error: string) {\n // Clear out innerHtml\n this.content.list.innerHTML = ''\n\n const errorDiv = document.createElement('div')\n errorDiv.classList.add(this.classes.error)\n errorDiv.textContent = error\n this.content.list.appendChild(errorDiv)\n }\n\n public renderSearching() {\n // Clear out innerHtml\n this.content.list.innerHTML = ''\n\n const searchingDiv = document.createElement('div')\n searchingDiv.classList.add(this.classes.searching)\n searchingDiv.textContent = this.settings.searchingText\n this.content.list.appendChild(searchingDiv)\n }\n\n // Take in data and add options to\n public renderOptions(data: (Option | Optgroup)[]): void {\n // Clear out innerHtml\n this.content.list.innerHTML = ''\n\n // If no results show no results text\n if (data.length === 0) {\n const noResults = document.createElement('div')\n noResults.classList.add(this.classes.search)\n\n //\n if (this.callbacks.addable) {\n noResults.innerHTML = this.settings.addableText.replace('{value}', this.content.search.input.value)\n } else {\n noResults.innerHTML = this.settings.searchText\n }\n this.content.list.appendChild(noResults)\n return\n }\n\n // If settings has allowDeselect and isSingle, add empty placeholder in the event they want to deselect\n if (this.settings.allowDeselect && !this.settings.isMultiple) {\n // Check if store options have a placeholder\n const placeholderOption = this.store.filter((o) => o.placeholder, false) as Option[]\n if (!placeholderOption.length) {\n this.store.addOption(\n new Option({\n text: '',\n value: '',\n selected: false,\n placeholder: true\n }),\n true\n )\n }\n }\n\n // Append individual options to div container\n const fragment = document.createDocumentFragment()\n for (const d of data) {\n // Create optgroup\n if (d instanceof Optgroup) {\n // Create optgroup\n const optgroupEl = document.createElement('div')\n optgroupEl.classList.add(this.classes.optgroup)\n\n // Create label\n const optgroupLabel = document.createElement('div')\n optgroupLabel.classList.add(this.classes.optgroupLabel)\n optgroupEl.appendChild(optgroupLabel)\n\n // Create label text div element\n const optgroupLabelText = document.createElement('div')\n optgroupLabelText.classList.add(this.classes.optgroupLabelText)\n optgroupLabelText.textContent = d.label\n optgroupLabel.appendChild(optgroupLabelText)\n\n // Create options container\n const optgroupActions = document.createElement('div')\n optgroupActions.classList.add(this.classes.optgroupActions)\n optgroupLabel.appendChild(optgroupActions)\n\n // If selectByGroup is true and isMultiple then add click event to label\n if (this.settings.isMultiple && d.selectAll) {\n // Create new div to hold a checkbox svg\n const selectAll = document.createElement('div')\n selectAll.classList.add(this.classes.optgroupSelectAll)\n\n // Check options and if all are selected, if so add class selected\n let allSelected = true\n for (const o of d.options) {\n if (!o.selected) {\n allSelected = false\n break\n }\n }\n\n // Add class if all selected\n if (allSelected) {\n selectAll.classList.add(this.classes.selected)\n }\n\n // Add select all text span\n const selectAllText = document.createElement('span')\n selectAllText.textContent = d.selectAllText\n selectAll.appendChild(selectAllText)\n\n // Create new svg for checkbox\n const selectAllSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n selectAllSvg.setAttribute('viewBox', '0 0 100 100')\n selectAll.appendChild(selectAllSvg)\n\n // Create new path for box\n const selectAllBox = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n selectAllBox.setAttribute('d', this.classes.optgroupSelectAllBox)\n selectAllSvg.appendChild(selectAllBox)\n\n // Create new path for check\n const selectAllCheck = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n selectAllCheck.setAttribute('d', this.classes.optgroupSelectAllCheck)\n selectAllSvg.appendChild(selectAllCheck)\n\n // Add click event listener to select all\n selectAll.addEventListener('click', (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Get the store current selected values\n const currentSelected = this.store.getSelected()\n\n // If all selected, remove all options from selected\n // call setSelected and return\n if (allSelected) {\n // Put together new list minus all options in this optgroup\n const newSelected = currentSelected.filter((s) => {\n for (const o of d.options) {\n if (s === o.id) {\n return false\n }\n }\n\n return true\n })\n\n this.callbacks.setSelected(newSelected, true)\n return\n } else {\n // Put together new list with all options in this optgroup\n let optionIds = d.options.map((o) => o.id).filter((id) => id !== undefined)\n const newSelected = currentSelected.concat(optionIds)\n\n // Loop through options and if they don't exist in the store\n // run addOption callback\n for (const o of d.options) {\n if (o.id && !this.store.getOptionByID(o.id)) {\n this.callbacks.addOption(new Option(o))\n }\n }\n\n this.callbacks.setSelected(newSelected, true)\n return\n }\n })\n\n // Append select all to label\n optgroupActions.appendChild(selectAll)\n }\n\n // If optgroup has collapsable\n if (d.closable !== 'off') {\n // Create new div to hold a checkbox svg\n const optgroupClosable = document.createElement('div')\n optgroupClosable.classList.add(this.classes.optgroupClosable)\n\n // Create svg arrow\n const optgroupClosableSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n optgroupClosableSvg.setAttribute('viewBox', '0 0 100 100')\n optgroupClosableSvg.classList.add(this.classes.arrow)\n optgroupClosable.appendChild(optgroupClosableSvg)\n\n // Create new path for arrow\n const optgroupClosableArrow = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n optgroupClosableSvg.appendChild(optgroupClosableArrow)\n\n // If any options are selected or someone is searching, set optgroup to open\n if (d.options.some((o) => o.selected) || this.content.search.input.value.trim() !== '') {\n optgroupClosable.classList.add(this.classes.mainOpen)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen)\n } else if (d.closable === 'open') {\n optgroupEl.classList.add(this.classes.mainOpen)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen)\n } else if (d.closable === 'close') {\n optgroupEl.classList.add(this.classes.close)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowClose)\n }\n\n // Add click event listener to close\n optgroupLabel.addEventListener('click', (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // If optgroup is closed, open it\n if (optgroupEl.classList.contains(this.classes.close)) {\n optgroupEl.classList.remove(this.classes.close)\n optgroupEl.classList.add(this.classes.mainOpen)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen)\n } else {\n optgroupEl.classList.remove(this.classes.mainOpen)\n optgroupEl.classList.add(this.classes.close)\n optgroupClosableArrow.setAttribute('d', this.classes.arrowClose)\n }\n })\n\n // Append close to label\n optgroupActions.appendChild(optgroupClosable)\n }\n\n // Add optgroup label\n optgroupEl.appendChild(optgroupLabel)\n\n // Loop through options\n for (const option of d.options) {\n optgroupEl.appendChild(this.option(new Option(option)))\n fragment.appendChild(optgroupEl)\n }\n }\n\n // Create option\n if (d instanceof Option) {\n fragment.appendChild(this.option(d as Option))\n }\n }\n\n // Append fragment to list\n this.content.list.appendChild(fragment)\n }\n\n // Create option div element\n public option(option: Option): HTMLDivElement {\n // Add hidden placeholder\n if (option.placeholder) {\n const placeholder = document.createElement('div')\n placeholder.classList.add(this.classes.option)\n placeholder.classList.add(this.classes.hide)\n return placeholder\n }\n\n // Create option\n const optionEl = document.createElement('div')\n optionEl.dataset.id = option.id // Dataset id for identifying an option\n optionEl.id = this.settings.id + '-' + option.id // Unique ID for ARIA references\n optionEl.classList.add(this.classes.option)\n optionEl.setAttribute('role', 'option') // WCAG attribute\n if (option.class) {\n option.class.split(' ').forEach((dataClass: string) => {\n optionEl.classList.add(dataClass)\n })\n }\n if (option.style) {\n optionEl.style.cssText = option.style\n }\n\n // Set option content\n if (this.settings.searchHighlight && this.content.search.input.value.trim() !== '') {\n optionEl.innerHTML = this.highlightText(\n option.html !== '' ? option.html : option.text,\n this.content.search.input.value,\n this.classes.searchHighlighter\n )\n } else if (option.html !== '') {\n optionEl.innerHTML = option.html\n } else {\n optionEl.textContent = option.text\n }\n\n // Set title attribute\n if (this.settings.showOptionTooltips && optionEl.textContent) {\n optionEl.setAttribute('title', optionEl.textContent)\n }\n\n // If option is disabled\n if (!option.display) {\n optionEl.classList.add(this.classes.hide)\n }\n\n // If allowed to deselect, null onclick and add disabled\n if (option.disabled) {\n optionEl.classList.add(this.classes.disabled)\n }\n\n // If option is selected and hideSelectedOption is true, hide it\n if (option.selected && this.settings.hideSelected) {\n optionEl.classList.add(this.classes.hide)\n }\n\n // If option is selected\n if (option.selected) {\n optionEl.classList.add(this.classes.selected)\n optionEl.setAttribute('aria-selected', 'true')\n this.main.main.setAttribute('aria-activedescendant', optionEl.id)\n } else {\n optionEl.classList.remove(this.classes.selected)\n optionEl.setAttribute('aria-selected', 'false')\n }\n\n // Add click event listener\n optionEl.addEventListener('click', (e: MouseEvent) => {\n e.preventDefault()\n e.stopPropagation()\n\n // Setup variables\n const selectedOptions = this.store.getSelected()\n const element = e.currentTarget as HTMLDivElement\n const elementID = String(element.dataset.id)\n const isCmd = e.ctrlKey || e.metaKey // Cmd (Mac) or Ctrl (Windows/Linux)\n\n // If the option is disabled, do nothing\n if (option.disabled) {\n return\n }\n\n // allowDeselect only applies to single-select mode\n // In multi-select, you can always toggle options on/off\n if (!this.settings.isMultiple && option.selected && !this.settings.allowDeselect) {\n return\n }\n\n // Prevent deselection of mandatory options\n if (option.selected && option.mandatory) {\n return\n }\n\n // Check limit and do nothing if limit is reached and the option is not selected\n // Also check reverse for min limit and is selected (allow Cmd to bypass minSelected)\n if (\n (this.settings.isMultiple && this.settings.maxSelected <= selectedOptions.length && !option.selected) ||\n (this.settings.isMultiple && this.settings.minSelected >= selectedOptions.length && option.selected && !isCmd)\n ) {\n return\n }\n\n // Setup variables\n let shouldUpdate = false\n const before = this.store.getSelectedOptions()\n let after = [] as Option[]\n\n // If multiple - mimic native browser multi-select behavior\n if (this.settings.isMultiple) {\n const isCurrentlySelected = before.some((o: Option) => o.id === elementID)\n const isShift = e.shiftKey\n\n // Shift+Click: Select range from last clicked to current\n if (isShift && this.lastSelectedOption) {\n const options = this.store.getDataOptions()\n const lastIndex = options.findIndex((o: Option) => o.id === this.lastSelectedOption!.id)\n const currentIndex = options.findIndex((o: Option) => o.id === option.id)\n\n if (lastIndex >= 0 && currentIndex >= 0) {\n const startIndex = Math.min(lastIndex, currentIndex)\n const endIndex = Math.max(lastIndex, currentIndex)\n const rangeOptions = options.slice(startIndex, endIndex + 1)\n\n // Check if range would exceed maxSelected\n const newSelections = rangeOptions.filter((opt) => !before.find((b) => b.id === opt.id))\n if (before.length + newSelections.length <= this.settings.maxSelected) {\n // Add range to existing selections\n after = before.concat(newSelections)\n } else {\n // Range too large, keep existing selections\n after = before\n }\n } else {\n after = before\n }\n }\n // Cmd/Ctrl+Click: Toggle selection without affecting others (keeps dropdown open)\n else if (isCmd) {\n if (isCurrentlySelected) {\n // Deselect this option\n after = before.filter((o: Option) => o.id !== elementID)\n } else {\n // Add this option to selection\n after = before.concat(option)\n }\n this.lastSelectedOption = option\n }\n // Regular Click: Toggle this option (add/remove), will close dropdown\n else {\n if (isCurrentlySelected) {\n // Deselect this option\n after = before.filter((o: Option) => o.id !== elementID)\n } else {\n // Add this option to selection\n after = before.concat(option)\n }\n this.lastSelectedOption = option\n }\n }\n\n // If single\n if (!this.settings.isMultiple) {\n if (option.selected) {\n // If selected after would remove\n after = []\n } else {\n // If not selected after would add\n after = [option]\n }\n }\n\n // If no beforeOnChange is set automatically update at end\n if (!this.callbacks.beforeChange) {\n shouldUpdate = true\n }\n\n if (this.callbacks.beforeChange) {\n // Check if beforeChange returns false\n if (this.callbacks.beforeChange(after, before) === false) {\n shouldUpdate = false\n } else {\n shouldUpdate = true\n }\n }\n\n if (shouldUpdate) {\n // Check if the option exists in the store\n // if not run addOption callback\n if (!this.store.getOptionByID(elementID)) {\n this.callbacks.addOption(option)\n }\n\n // Get values from after and set as selected\n this.callbacks.setSelected(\n after.map((o: Option) => o.id),\n false\n )\n\n // Close dropdown unless using modifier keys in multi-select\n // (mimics native multi-select behavior where you can keep selecting)\n const isModifierKey = e.ctrlKey || e.metaKey || e.shiftKey // Cmd/Ctrl or Shift\n const shouldClose = this.settings.closeOnSelect && !(this.settings.isMultiple && isModifierKey)\n\n if (shouldClose) {\n this.callbacks.close()\n }\n\n // callback that the value has changed\n if (this.callbacks.afterChange) {\n this.callbacks.afterChange(after)\n }\n }\n })\n\n return optionEl\n }\n\n public destroy(): void {\n // Remove main\n this.main.main.remove()\n\n // Remove content\n this.content.main.remove()\n }\n\n private highlightText(str: string, search: any, className: string) {\n const searchTerm = search.trim()\n if (searchTerm === '') {\n return str\n }\n\n // Escape special regex characters in the search term to prevent regex injection\n const escapedSearch = searchTerm.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\n // Create a temporary div to parse HTML and work with text nodes only\n const tempDiv = document.createElement('div')\n tempDiv.innerHTML = str\n\n // Function to recursively process text nodes\n const highlightTextNodes = (node: Node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || ''\n const regex = new RegExp('(' + escapedSearch + ')', 'i')\n\n if (regex.test(text)) {\n // Create a temporary container for the highlighted content\n const wrapper = document.createElement('span')\n const parts = text.split(regex)\n\n parts.forEach((part, index) => {\n if (part && regex.test(part)) {\n // This is the matched part - wrap it in mark\n const mark = document.createElement('mark')\n mark.className = className\n mark.textContent = part\n wrapper.appendChild(mark)\n } else if (part) {\n // This is not the matched part - keep as text\n wrapper.appendChild(document.createTextNode(part))\n }\n })\n\n // Replace the text node with the wrapper\n node.parentNode?.replaceChild(wrapper, node)\n }\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n // Recursively process child nodes\n Array.from(node.childNodes).forEach((child) => highlightTextNodes(child))\n }\n }\n\n // Process all text nodes in the temporary div\n Array.from(tempDiv.childNodes).forEach((node) => highlightTextNodes(node))\n\n return tempDiv.innerHTML\n }\n\n public moveContentAbove(): void {\n // Get main and content height\n const mainHeight = this.main.main.offsetHeight\n const contentHeight = this.content.main.offsetHeight\n\n // Set direction classes on both main and content\n this.main.main.classList.remove(this.classes.dirBelow)\n this.main.main.classList.add(this.classes.dirAbove)\n this.content.main.classList.remove(this.classes.dirBelow)\n this.content.main.classList.add(this.classes.dirAbove)\n\n // Set the content position\n const containerRect = this.main.main.getBoundingClientRect()\n this.content.main.style.margin = '-' + (mainHeight + contentHeight - 1) + 'px 0px 0px 0px'\n this.content.main.style.top =\n containerRect.top + containerRect.height + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollY) + 'px'\n this.content.main.style.left =\n containerRect.left + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollX) + 'px'\n this.content.main.style.width = containerRect.width + 'px'\n }\n\n public moveContentBelow(): void {\n // Set direction classes on both main and content\n this.main.main.classList.remove(this.classes.dirAbove)\n this.main.main.classList.add(this.classes.dirBelow)\n this.content.main.classList.remove(this.classes.dirAbove)\n this.content.main.classList.add(this.classes.dirBelow)\n\n // Set the content position\n const containerRect = this.main.main.getBoundingClientRect()\n this.content.main.style.margin = '-1px 0px 0px 0px'\n // Dont do anything if the content is relative\n if (this.settings.contentPosition !== 'relative') {\n this.content.main.style.top =\n containerRect.top +\n containerRect.height +\n (this.settings.contentPosition === 'fixed' ? 0 : window.scrollY) +\n 'px'\n this.content.main.style.left =\n containerRect.left + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollX) + 'px'\n this.content.main.style.width = containerRect.width + 'px'\n }\n }\n\n public ensureElementInView(container: HTMLElement, element: HTMLElement): void {\n // Determine container top and bottom\n const cTop = container.scrollTop + container.offsetTop // Make sure to have offsetTop\n const cBottom = cTop + container.clientHeight\n\n // Determine element top and bottom\n const eTop = element.offsetTop\n const eBottom = eTop + element.clientHeight\n\n // Check if out of view\n if (eTop < cTop) {\n container.scrollTop -= cTop - eTop\n } else if (eBottom > cBottom) {\n container.scrollTop += eBottom - cBottom\n }\n }\n\n public putContent(): 'up' | 'down' {\n // Get main and content height\n const mainHeight = this.main.main.offsetHeight\n const mainRect = this.main.main.getBoundingClientRect()\n const contentHeight = this.content.main.offsetHeight\n\n // From bottom of mainHeight figure out if content will fit below without going below the window\n const spaceBelow = window.innerHeight - (mainRect.top + mainHeight)\n\n // If space below is less than content height\n if (spaceBelow <= contentHeight) {\n // If space above is more than content height\n if (mainRect.top > contentHeight) {\n // Move content above\n return 'up'\n } else {\n // Move content below\n return 'down'\n }\n }\n\n // Move content below\n return 'down'\n }\n\n // Updates deselect based on item count and allowDeselect setting\n public updateDeselectAll(): void {\n if (!this.store || !this.settings) {\n return\n }\n const selected = this.store.getSelectedOptions()\n const hasSelectedItems = selected && selected.length > 0\n const isMultiple = this.settings.isMultiple\n const allowDeselect = this.settings.allowDeselect\n\n const deselectButton = this.main.deselect.main\n const hideClass = this.classes.hide\n\n if (allowDeselect && !(isMultiple && !hasSelectedItems)) {\n deselectButton.classList.remove(hideClass)\n } else {\n deselectButton.classList.add(hideClass)\n }\n }\n}\n","import { kebabCase } from './helpers'\nimport { Optgroup, Option } from './store'\n\nexport default class Select {\n public select: HTMLSelectElement\n\n // Mutation observer fields\n public onValueChange?: (value: Option[]) => void\n public onClassChange?: (classes: string[]) => void\n public onDisabledChange?: (disabled: boolean) => void\n public onOptionsChange?: (data: (Option | Optgroup)[]) => void\n public onLabelClick?: () => void\n\n // Change observers\n private listen: boolean = false\n private observer: MutationObserver | null = null\n private isUpdating: boolean = false\n private pendingOptionsChange: (Option | Optgroup)[] | null = null\n\n // Event handlers for preventing native select behavior (especially on iOS Safari)\n private preventNativeSelect: ((e: Event) => void) | null = null\n private preventNativeSelectMousedown: ((e: Event) => void) | null = null\n private preventNativeSelectFocus: ((e: Event) => void) | null = null\n\n constructor(select: HTMLSelectElement) {\n this.select = select\n\n this.valueChange = this.valueChange.bind(this)\n // Add change event listener\n this.select.addEventListener('change', this.valueChange, {\n // allow bubbling of event\n passive: true\n })\n\n // Initiate mutation observer\n this.observer = new MutationObserver(this.observeCall.bind(this))\n\n // Start listening for changes\n this.changeListen(true)\n }\n\n public enable(): void {\n this.select.disabled = false\n }\n\n public disable(): void {\n this.select.disabled = true\n }\n\n public hideUI(): void {\n this.select.tabIndex = -1\n // Visually hide but keep focusable for form validation\n // Use 1px dimensions so browser validation popup can display\n this.select.style.position = 'absolute'\n this.select.style.width = '1px'\n this.select.style.height = '1px'\n this.select.style.opacity = '0'\n this.select.style.overflow = 'hidden'\n this.select.style.pointerEvents = 'none'\n // Remove any spacing or borders that could affect layout\n this.select.style.margin = '0'\n this.select.style.padding = '0'\n this.select.style.borderWidth = '0'\n // Clip to completely hide the 1px\n this.select.style.clip = 'rect(0 0 0 0)'\n this.select.setAttribute('aria-hidden', 'true')\n\n // Prevent native select from opening when label is clicked (especially on iOS Safari)\n // iOS Safari programmatically focuses/clicks the select when label is clicked,\n // bypassing pointer-events: none, so we need to prevent these events\n // Only add listeners if they haven't been added yet\n if (!this.preventNativeSelect) {\n this.preventNativeSelect = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n this.preventNativeSelectMousedown = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n this.preventNativeSelectFocus = (e: Event) => {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n }\n\n // Add event listeners with capture phase to catch events before they reach the select\n this.select.addEventListener('click', this.preventNativeSelect, { capture: true, passive: false })\n this.select.addEventListener('mousedown', this.preventNativeSelectMousedown, { capture: true, passive: false })\n this.select.addEventListener('focus', this.preventNativeSelectFocus, { capture: true, passive: false })\n }\n }\n\n public showUI(): void {\n this.select.removeAttribute('tabindex')\n // Reset visual hiding styles\n this.select.style.position = ''\n this.select.style.width = ''\n this.select.style.height = ''\n this.select.style.opacity = ''\n this.select.style.overflow = ''\n this.select.style.pointerEvents = ''\n this.select.style.margin = ''\n this.select.style.padding = ''\n this.select.style.borderWidth = ''\n this.select.style.clip = ''\n this.select.removeAttribute('aria-hidden')\n\n // Remove event listeners that prevent native select behavior\n if (this.preventNativeSelect) {\n this.select.removeEventListener('click', this.preventNativeSelect, { capture: true })\n this.preventNativeSelect = null\n }\n if (this.preventNativeSelectMousedown) {\n this.select.removeEventListener('mousedown', this.preventNativeSelectMousedown, { capture: true })\n this.preventNativeSelectMousedown = null\n }\n if (this.preventNativeSelectFocus) {\n this.select.removeEventListener('focus', this.preventNativeSelectFocus, { capture: true })\n this.preventNativeSelectFocus = null\n }\n }\n\n public changeListen(listen: boolean) {\n this.listen = listen\n\n // Start listening for changes\n if (listen) {\n if (this.observer) {\n this.observer.observe(this.select, {\n subtree: true, // subtree for optgroups options\n childList: true, // children changes\n attributes: true // attributes changes\n })\n }\n }\n\n // Stop listening for changes\n if (!listen) {\n if (this.observer) {\n this.observer.disconnect()\n }\n }\n }\n\n // This function get triggers when the select value changes\n // and will call the onValueChange function if it exists\n public valueChange(ev: Event): boolean {\n if (this.listen && this.onValueChange) {\n this.onValueChange(this.getSelectedOptions())\n }\n\n // Allow bubbling back to other change event listeners\n return true\n }\n\n private observeCall(mutations: MutationRecord[]): void {\n // If we are not listening, do nothing.\n if (!this.listen) {\n return\n }\n\n let classChanged = false\n let disabledChanged = false\n let optgroupOptionChanged = false\n let selectionChanged = false;\n\n // Loop through mutations and check various things\n for (const m of mutations) {\n // Check if its the select\n if (m.target === this.select) {\n // Check if disabled has changed\n if (m.attributeName === 'disabled') {\n disabledChanged = true\n }\n\n // Check if class has changed\n if (m.attributeName === 'class') {\n classChanged = true\n }\n\n if (m.type === 'childList') {\n for (const n of Array.from(m.addedNodes)) {\n if (n.nodeName === 'OPTION' && (<HTMLOptionElement>n).value === this.select.value) {\n // we added a new option that's now the select value\n selectionChanged = true;\n break\n }\n }\n\n // options changed, so we need the optionsChange event to fire\n optgroupOptionChanged = true\n }\n }\n\n // Check if its an optgroup or option\n if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {\n optgroupOptionChanged = true\n }\n }\n\n // If class has changed then call the class change function\n if (classChanged && this.onClassChange) {\n this.onClassChange(this.select.className.split(' '))\n }\n\n // If disabled has changed then call the disabled change function\n if (disabledChanged && this.onDisabledChange) {\n this.changeListen(false)\n this.onDisabledChange(this.select.disabled)\n this.changeListen(true)\n }\n\n // If optgroup or option has changed then call the select change function\n if (optgroupOptionChanged && this.onOptionsChange) {\n // If we're currently updating, queue this change to process after update completes\n if (this.isUpdating) {\n // Only queue if the select element actually has options (not empty from updateOptions clearing)\n // Check the select element directly, not getData() which might return stale data\n if (this.select.options.length > 0) {\n const currentData = this.getData()\n // Only queue if we have actual data\n if (currentData.length > 0) {\n this.pendingOptionsChange = currentData\n }\n }\n if(selectionChanged) {\n this.select.dispatchEvent(new Event('change'))\n }\n return\n }\n\n this.changeListen(false)\n this.onOptionsChange(this.getData())\n this.changeListen(true)\n }\n\n if(selectionChanged) {\n this.select.dispatchEvent(new Event('change'))\n }\n }\n\n // From the select element pull optgroup and options into data\n public getData(): (Option | Optgroup)[] {\n let data = []\n\n // Loop through nodes and get data\n const nodes = this.select.childNodes as any as HTMLOptGroupElement[] | HTMLOptionElement[]\n for (const n of nodes) {\n // Optgroup\n if (n.nodeName === 'OPTGROUP') {\n data.push(this.getDataFromOptgroup(n as HTMLOptGroupElement))\n }\n\n // Option\n if (n.nodeName === 'OPTION') {\n data.push(this.getDataFromOption(n as HTMLOptionElement))\n }\n }\n\n return data\n }\n\n public getDataFromOptgroup(optgroup: HTMLOptGroupElement): Optgroup {\n let data = {\n id: optgroup.id,\n label: optgroup.label,\n selectAll: optgroup.dataset ? optgroup.dataset.selectall === 'true' : false,\n selectAllText: optgroup.dataset ? optgroup.dataset.selectalltext : 'Select all',\n closable: optgroup.dataset ? optgroup.dataset.closable : 'off',\n options: []\n } as Optgroup\n\n const options = optgroup.childNodes as any as HTMLOptionElement[]\n for (const o of options) {\n if (o.nodeName === 'OPTION') {\n data.options!.push(this.getDataFromOption(o as HTMLOptionElement))\n }\n }\n\n return data\n }\n\n // From passed in option pull pieces of usable information\n public getDataFromOption(option: HTMLOptionElement): Option {\n return {\n id: option.id,\n value: option.value,\n text: option.text,\n html: option.dataset && option.dataset.html ? option.dataset.html : '',\n defaultSelected: option.defaultSelected,\n selected: option.selected,\n display: option.style.display !== 'none',\n disabled: option.disabled,\n mandatory: option.dataset ? option.dataset.mandatory === 'true' : false,\n placeholder: option.dataset.placeholder === 'true',\n class: option.className,\n style: option.style.cssText,\n data: option.dataset\n } as Option\n }\n\n public getSelectedOptions(): Option[] {\n let options = []\n\n // Loop through options and set selected\n const opts = this.select.childNodes as any as (HTMLOptGroupElement | HTMLOptionElement)[]\n for (const o of opts) {\n if (o.nodeName === 'OPTGROUP') {\n const optgroupOptions = o.childNodes as any as HTMLOptionElement[]\n for (const oo of optgroupOptions) {\n if (oo.nodeName === 'OPTION') {\n const option = oo as HTMLOptionElement\n if (option.selected) {\n options.push(this.getDataFromOption(option))\n }\n }\n }\n }\n\n if (o.nodeName === 'OPTION') {\n const option = o as HTMLOptionElement\n if (option.selected) {\n options.push(this.getDataFromOption(option))\n }\n }\n }\n\n return options\n }\n\n public getSelectedValues(): string[] {\n return this.getSelectedOptions().map((option) => option.value)\n }\n\n public setSelected(ids: string[]): void {\n // Stop listening to changes\n this.changeListen(false)\n\n // Loop through options and set selected\n const options = this.select.childNodes as any as (HTMLOptGroupElement | HTMLOptionElement)[]\n for (const o of options) {\n if (o.nodeName === 'OPTGROUP') {\n const optgroup = o as HTMLOptGroupElement\n const optgroupOptions = optgroup.childNodes as any as HTMLOptionElement[]\n for (const oo of optgroupOptions) {\n if (oo.nodeName === 'OPTION') {\n const option = oo as HTMLOptionElement\n option.selected = ids.includes(option.id)\n }\n }\n }\n\n if (o.nodeName === 'OPTION') {\n const option = o as HTMLOptionElement\n option.selected = ids.includes(option.id)\n }\n }\n\n // Stop listening to changes\n this.changeListen(true)\n }\n\n // Set selected options by value instead of id\n // This is useful when the id is not known\n // and only the value is known\n // but the value is not unique and can be duplicated\n public setSelectedByValue(values: string[]): void {\n // Stop listening to changes\n this.changeListen(false)\n\n // Loop through options and set selected\n const options = this.select.childNodes as any as (HTMLOptGroupElement | HTMLOptionElement)[]\n for (const o of options) {\n if (o.nodeName === 'OPTGROUP') {\n const optgroup = o as HTMLOptGroupElement\n const optgroupOptions = optgroup.childNodes as any as HTMLOptionElement[]\n for (const oo of optgroupOptions) {\n if (oo.nodeName === 'OPTION') {\n const option = oo as HTMLOptionElement\n option.selected = values.includes(option.value)\n }\n }\n }\n\n if (o.nodeName === 'OPTION') {\n const option = o as HTMLOptionElement\n option.selected = values.includes(option.value)\n }\n }\n\n // Stop listening to changes\n this.changeListen(true)\n }\n\n public updateSelect(id?: string, style?: string, classes?: string[]): void {\n // Stop listening to changes\n this.changeListen(false)\n\n // Update id, only if the id isnt already set\n if (id) {\n this.select.dataset.id = id\n }\n\n // Update style\n if (style) {\n this.select.style.cssText = style\n }\n\n // Update classes\n if (classes) {\n this.select.className = ''\n classes.forEach((c) => {\n if (c.trim() !== '') {\n this.select.classList.add(c.trim())\n }\n })\n }\n\n // Start listening to changes\n this.changeListen(true)\n }\n\n public updateOptions(data: (Option | Optgroup)[]): void {\n // Don't update if data is empty (prevents clearing select when no data)\n if (!data || data.length === 0) {\n return\n }\n\n // Set updating flag FIRST to prevent mutation observer from processing during update\n // This must be set before stopping listening so any queued mutations see the flag\n this.isUpdating = true\n this.pendingOptionsChange = null\n\n // Stop listening to changes\n this.changeListen(false)\n\n // Clear out select\n this.select.innerHTML = ''\n\n for (const d of data) {\n if (d instanceof Optgroup) {\n this.select.appendChild(this.createOptgroup(d))\n }\n\n if (d instanceof Option) {\n this.select.appendChild(this.createOption(d))\n }\n }\n\n // Trigger change event on original select\n this.select.dispatchEvent(new Event('change', { bubbles: true }))\n\n // Start listening to changes\n this.changeListen(true)\n\n // Clear updating flag\n this.isUpdating = false\n\n // Process any pending options change that was queued during the update\n // Only process if it has data (don't process empty data from innerHTML clearing)\n if (this.pendingOptionsChange !== null) {\n const pending: (Option | Optgroup)[] = this.pendingOptionsChange\n if (pending.length > 0 && this.onOptionsChange) {\n this.pendingOptionsChange = null\n // Process the queued change\n this.changeListen(false)\n this.onOptionsChange(pending)\n this.changeListen(true)\n } else {\n // Clear pending if it was empty\n this.pendingOptionsChange = null\n }\n }\n }\n\n public createOptgroup(optgroup: Optgroup): HTMLOptGroupElement {\n const optgroupEl = document.createElement('optgroup')\n optgroupEl.id = optgroup.id\n optgroupEl.label = optgroup.label\n if (optgroup.selectAll) {\n optgroupEl.dataset.selectAll = 'true'\n }\n if (optgroup.closable !== 'off') {\n optgroupEl.dataset.closable = optgroup.closable\n }\n if (optgroup.options) {\n for (const option of optgroup.options) {\n optgroupEl.appendChild(this.createOption(option as Option))\n }\n }\n return optgroupEl\n }\n\n public createOption(info: Option): HTMLOptionElement {\n const optionEl = document.createElement('option')\n optionEl.id = info.id\n optionEl.value = info.value\n optionEl.textContent = info.text\n if (info.html !== '') {\n optionEl.setAttribute('data-html', info.html)\n }\n optionEl.defaultSelected = info.defaultSelected\n optionEl.selected = info.selected // Explicitly set selected because defaultSelected: true sets selected to true\n if (info.disabled) {\n optionEl.disabled = true\n }\n if (!info.display) {\n optionEl.style.display = 'none'\n }\n if (info.placeholder) {\n optionEl.setAttribute('data-placeholder', 'true')\n }\n if (info.mandatory) {\n optionEl.setAttribute('data-mandatory', 'true')\n }\n if (info.class) {\n info.class.split(' ').forEach((optionClass: string) => {\n optionEl.classList.add(optionClass)\n })\n }\n if (info.data && typeof info.data === 'object') {\n Object.keys(info.data).forEach((key) => {\n optionEl.setAttribute('data-' + kebabCase(key), info.data[key])\n })\n }\n\n return optionEl\n }\n\n // Find and handle labels associated with this select\n public setupLabelHandlers(): void {\n const labels: HTMLLabelElement[] = []\n\n // Find labels that point to this select via 'for' attribute\n const selectId = this.select.id\n if (selectId) {\n const labelsByFor = document.querySelectorAll<HTMLLabelElement>(`label[for=\"${selectId}\"]`)\n labelsByFor.forEach((label) => labels.push(label))\n }\n\n // Find labels that wrap this select (label contains select)\n let parent = this.select.parentElement\n while (parent && parent !== document.body) {\n if (parent.tagName === 'LABEL') {\n labels.push(parent as HTMLLabelElement)\n break\n }\n parent = parent.parentElement\n }\n\n // Remove duplicates\n const uniqueLabels = Array.from(new Set(labels))\n\n uniqueLabels.forEach((label) => {\n // Skip if already handled\n if ((label as any).__slimSelectLabelHandler) {\n return\n }\n\n // Add click handler to label\n const labelClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement\n\n // Prevent default label behavior (focusing the select)\n // This needs to happen for all clicks on the label or its children\n // to prevent the browser from focusing the hidden select\n e.preventDefault()\n // e.stopPropagation() // dont stop propagation\n\n // Only handle the click if it's directly on the label\n if (target === label && this.onLabelClick) {\n this.onLabelClick()\n }\n }\n\n // Store the handler on the label for cleanup later\n ;(label as any).__slimSelectLabelHandler = labelClickHandler\n label.addEventListener('click', labelClickHandler, { capture: true, passive: false })\n })\n }\n\n // Remove label handlers\n public removeLabelHandlers(): void {\n const labels: HTMLLabelElement[] = []\n\n // Find labels that point to this select via 'for' attribute\n const selectId = this.select.id\n if (selectId) {\n const labelsByFor = document.querySelectorAll<HTMLLabelElement>(`label[for=\"${selectId}\"]`)\n labelsByFor.forEach((label) => labels.push(label))\n }\n\n // Find labels that wrap this select\n let parent = this.select.parentElement\n while (parent && parent !== document.body) {\n if (parent.tagName === 'LABEL') {\n labels.push(parent as HTMLLabelElement)\n break\n }\n parent = parent.parentElement\n }\n\n // Remove duplicates\n const uniqueLabels = Array.from(new Set(labels))\n\n uniqueLabels.forEach((label) => {\n const handler = (label as any).__slimSelectLabelHandler\n if (handler) {\n label.removeEventListener('click', handler, { capture: true })\n delete (label as any).__slimSelectLabelHandler\n }\n })\n }\n\n public destroy() {\n this.changeListen(false)\n\n // Remove event change listener\n this.select.removeEventListener('change', this.valueChange)\n\n // Remove event listeners that prevent native select behavior\n if (this.preventNativeSelect) {\n this.select.removeEventListener('click', this.preventNativeSelect, { capture: true })\n this.preventNativeSelect = null\n }\n if (this.preventNativeSelectMousedown) {\n this.select.removeEventListener('mousedown', this.preventNativeSelectMousedown, { capture: true })\n this.preventNativeSelectMousedown = null\n }\n if (this.preventNativeSelectFocus) {\n this.select.removeEventListener('focus', this.preventNativeSelectFocus, { capture: true })\n this.preventNativeSelectFocus = null\n }\n\n // Disconnect observer and null\n if (this.observer) {\n this.observer.disconnect()\n this.observer = null\n }\n\n // Remove label handlers\n this.removeLabelHandlers()\n\n // Remove dataset id from original select\n delete this.select.dataset.id\n\n // Show the original select\n this.showUI()\n }\n}\n","import { generateID } from './helpers'\n\nexport default class Settings {\n public id: string = '' // Primary ID for the select\n public style: string = '' // Style attribute from the select element\n public class: string[] = [] // Class attribute from the select element\n\n // Dynamic settings\n public isMultiple: boolean = false\n public isOpen: boolean = false\n public isFullOpen: boolean = false\n public intervalMove: ReturnType<typeof setInterval> | null = null\n\n // Fields set from constructor\n public disabled: boolean\n public alwaysOpen: boolean\n public showSearch: boolean\n public focusSearch: boolean\n public keepSearch: boolean\n public ariaLabel: string\n public searchPlaceholder: string\n public searchText: string\n public searchingText: string\n public searchHighlight: boolean\n public closeOnSelect: boolean\n public contentLocation: HTMLElement | null\n public contentPosition: 'relative' | 'absolute' | 'fixed'\n public openPosition: 'auto' | 'up' | 'down'\n public placeholderText: string\n public allowDeselect: boolean\n public hideSelected: boolean\n public keepOrder: boolean\n public showOptionTooltips: boolean\n public minSelected: number\n public maxSelected: number\n public timeoutDelay: number\n public maxValuesShown: number\n public maxValuesMessage: string\n public addableText: string\n\n constructor(settings?: Partial<Settings>) {\n if (!settings) {\n settings = {}\n }\n\n this.id = 'ss-' + generateID()\n this.style = settings.style || ''\n this.class = settings.class || []\n\n this.disabled = settings.disabled !== undefined ? settings.disabled : false\n this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false\n this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true\n this.focusSearch = settings.focusSearch !== undefined ? settings.focusSearch : true\n this.keepSearch = settings.keepSearch !== undefined ? settings.keepSearch : false\n this.ariaLabel = settings.ariaLabel || 'Combobox'\n this.searchPlaceholder = settings.searchPlaceholder || 'Search...'\n this.searchText = settings.searchText || 'No Results'\n this.searchingText = settings.searchingText || 'Searching...'\n this.searchHighlight = settings.searchHighlight !== undefined ? settings.searchHighlight : false\n this.closeOnSelect = settings.closeOnSelect !== undefined ? settings.closeOnSelect : true\n this.contentLocation = settings.contentLocation || document.body\n this.contentPosition = settings.contentPosition || 'absolute'\n this.openPosition = settings.openPosition || 'auto' // options: auto, up, down\n this.placeholderText = settings.placeholderText !== undefined ? settings.placeholderText : 'Select Value'\n this.allowDeselect = settings.allowDeselect !== undefined ? settings.allowDeselect : false\n this.hideSelected = settings.hideSelected !== undefined ? settings.hideSelected : false\n this.keepOrder = settings.keepOrder !== undefined ? settings.keepOrder : false\n this.showOptionTooltips = settings.showOptionTooltips !== undefined ? settings.showOptionTooltips : false\n this.minSelected = settings.minSelected || 0\n this.maxSelected = settings.maxSelected || 1000\n this.timeoutDelay = settings.timeoutDelay || 200\n this.maxValuesShown = settings.maxValuesShown || 20\n this.maxValuesMessage = settings.maxValuesMessage || '{number} selected'\n this.addableText = settings.addableText || 'Press \"Enter\" to add {value}'\n }\n}\n","import CssClasses from './classes'\nimport { debounce, hasClassInTree, isEqual } from './helpers'\nimport Render from './render'\nimport Select from './select'\nimport Settings from './settings'\nimport Store, { Option, Optgroup } from './store'\n\n// Export classes\nexport { Settings, Option, Optgroup }\n\n// Export interfaces from render\nexport type { Main, Content, Search } from './render'\n\nexport interface Config {\n select: string | Element\n data?: (Partial<Option> | Partial<Optgroup>)[]\n settings?: Partial<Settings>\n cssClasses?: Partial<CssClasses>\n events?: Events\n}\n\nexport interface Events {\n search?: (\n searchValue: string,\n currentData: (Option | Optgroup)[]\n ) => Promise<(Partial<Option> | Partial<Optgroup>)[]> | (Partial<Option> | Partial<Optgroup>)[]\n searchFilter?: (option: Option, search: string) => boolean\n addable?: (\n value: string\n ) => Promise<Partial<Option> | string> | Partial<Option> | string | false | null | undefined | Error\n beforeChange?: (newVal: Option[], oldVal: Option[]) => boolean | void\n afterChange?: (newVal: Option[]) => void\n beforeOpen?: () => void\n afterOpen?: () => void\n beforeClose?: () => void\n afterClose?: () => void\n error?: (err: Error) => void\n}\n\nexport default class SlimSelect {\n public selectEl: HTMLSelectElement\n\n // Classes\n public settings!: Settings\n public cssClasses!: CssClasses\n public select!: Select\n public store!: Store\n public render!: Render\n\n // Timeout tracking for cleanup\n private openTimeout: ReturnType<typeof setTimeout> | null = null\n private closeTimeout: ReturnType<typeof setTimeout> | null = null\n\n // Events\n public events = {\n search: undefined,\n searchFilter: (opt: Option, search: string) => {\n return opt.text.toLowerCase().indexOf(search.toLowerCase()) !== -1\n },\n addable: undefined,\n beforeChange: undefined,\n afterChange: undefined,\n beforeOpen: undefined,\n afterOpen: undefined,\n beforeClose: undefined,\n afterClose: undefined\n } as Events\n\n constructor(config: Config) {\n // Make sure you get the right element\n this.selectEl = (\n typeof config.select === 'string' ? document.querySelector(config.select) : config.select\n ) as HTMLSelectElement\n if (!this.selectEl) {\n if (config.events && config.events.error) {\n config.events.error(new Error('Could not find select element'))\n }\n return\n }\n if (this.selectEl.tagName !== 'SELECT') {\n if (config.events && config.events.error) {\n config.events.error(new Error('Element isnt of type select'))\n }\n return\n }\n\n // If select already has a slim select id on it lets destroy it first\n if (this.selectEl.dataset.ssid) {\n this.destroy()\n }\n\n // Set settings\n this.settings = new Settings(config.settings)\n\n // Set CSS classes\n this.cssClasses = new CssClasses(config.cssClasses)\n\n // Set events\n const debounceEvents = ['beforeOpen', 'afterOpen', 'beforeClose', 'afterClose']\n for (const key in config.events) {\n // Check if key exists in events\n if (!config.events.hasOwnProperty(key)) {\n continue\n }\n\n // Check if key is in debounceEvents\n if (debounceEvents.indexOf(key) !== -1) {\n ;(this.events as { [key: string]: any })[key] = debounce((config.events as { [key: string]: any })[key], 100)\n } else {\n ;(this.events as { [key: string]: any })[key] = (config.events as { [key: string]: any })[key]\n }\n }\n\n // Upate settings with type, style and classname\n this.settings.disabled = config.settings?.disabled ? config.settings.disabled : this.selectEl.disabled\n this.settings.isMultiple = this.selectEl.multiple\n this.settings.style = this.selectEl.style.cssText\n this.settings.class = this.selectEl.className.split(' ')\n\n // Set select class\n this.select = new Select(this.selectEl)\n // Ensure the select has an id for label associations\n if (!this.selectEl.id) {\n this.selectEl.id = this.settings.id\n }\n this.select.updateSelect(this.settings.id, this.settings.style, this.settings.class)\n this.select.hideUI() // Hide the original select element\n\n // Add select listeners\n this.select.onValueChange = (options: Option[]) => {\n // Run set selected from the values given\n this.setSelected(options.map((option) => option.id))\n }\n this.select.onClassChange = (classes: string[]) => {\n // Update settings with new class\n this.settings.class = classes\n\n // Run render updateClassStyles\n this.render.updateClassStyles()\n }\n this.select.onDisabledChange = (disabled: boolean) => {\n if (disabled) {\n this.disable()\n } else {\n this.enable()\n }\n }\n this.select.onOptionsChange = (data: (Option | Optgroup)[]) => {\n // Process the data (including empty data for clearing all options)\n // Empty data is safe to process here because if we were updating, the change would be queued\n // and onOptionsChange wouldn't be called directly\n this.setData(data || [])\n }\n // Set up label click handler to toggle SlimSelect\n // This allows clicking the label to open/close, matching the main div behavior\n this.select.onLabelClick = () => {\n if (!this.settings.disabled) {\n this.settings.isOpen ? this.close() : this.open()\n }\n }\n\n // Set store class\n const data = config.data ? config.data : this.select.getData()\n this.store = new Store(this.settings.isMultiple ? 'multiple' : 'single', data)\n\n // If data is passed update the original select element\n if (config.data) {\n this.select.updateOptions(this.store.getData())\n }\n\n // Set render renderCallbacks\n const renderCallbacks = {\n open: this.open.bind(this),\n close: this.close.bind(this),\n addable: this.events.addable ? this.events.addable : undefined,\n setSelected: this.setSelected.bind(this),\n addOption: this.addOption.bind(this),\n search: this.search.bind(this),\n beforeChange: this.events.beforeChange,\n afterChange: this.events.afterChange\n }\n\n // Setup render class\n this.render = new Render(this.settings, this.cssClasses, this.store, renderCallbacks)\n this.render.renderValues()\n this.render.renderOptions(this.store.getData())\n\n // Add aria-label or aria-labelledby if exists\n const selectAriaLabel = this.selectEl.getAttribute('aria-label')\n const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby')\n\n if (selectAriaLabel) {\n this.render.main.main.setAttribute('aria-label', selectAriaLabel)\n } else if (selectAriaLabelledBy) {\n this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy)\n }\n\n // Add render after original select element\n if (this.selectEl.parentNode) {\n this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling)\n }\n\n // Add window resize listener to moveContent if window size changes\n window.addEventListener('resize', this.windowResize, false)\n\n // If the user wants to show the content forcibly on a specific side,\n // there is no need to listen for scroll events\n if (this.settings.openPosition === 'auto') {\n window.addEventListener('scroll', this.windowScroll, false)\n }\n\n // Add window visibility change listener to closeContent if window is hidden\n document.addEventListener('visibilitychange', this.windowVisibilityChange)\n\n // If disabled lets call it\n if (this.settings.disabled) {\n this.disable()\n }\n\n // If alwaysOpnen then open it\n if (this.settings.alwaysOpen) {\n this.open()\n }\n\n // Set up label handlers to open SlimSelect when label is clicked\n this.select.setupLabelHandlers()\n\n // Add SlimSelect to select element\n ;(this.selectEl as any).slim = this\n }\n\n // Set to enabled and remove disabled classes\n public enable(): void {\n this.settings.disabled = false\n\n this.select.enable()\n this.render.enable()\n }\n\n // Set to disabled and add disabled classes\n public disable(): void {\n this.settings.disabled = true\n\n this.select.disable()\n this.render.disable()\n }\n\n public getData(): Option[] | Optgroup[] {\n return this.store.getData()\n }\n\n public setData(data: (Partial<Option> | Partial<Optgroup>)[]): void {\n // Get original selected values\n const selected = this.store.getSelected()\n\n // Validate data\n const err = this.store.validateDataArray(data)\n if (err) {\n if (this.events.error) {\n this.events.error(err)\n }\n return\n }\n\n // Update the store\n this.store.setData(data)\n const dataClean = this.store.getData()\n\n // Update original select element\n this.select.updateOptions(dataClean)\n\n // Update the render\n this.render.renderValues()\n this.render.renderOptions(dataClean)\n\n // Trigger afterChange event, if it doesnt equal the original selected values\n if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {\n this.events.afterChange(this.store.getSelectedOptions())\n }\n }\n\n public getSelected(): string[] {\n let options = this.store.getSelectedOptions()\n if (this.settings.keepOrder) {\n options = this.store.selectedOrderOptions(options)\n }\n return options.map((option) => option.value)\n }\n\n // Will take in a string or array of strings and set the selected by either the id or value\n public setSelected(values: string | string[], runAfterChange = true): void {\n // Get original selected values\n const selected = this.store.getSelected()\n const options = this.store.getDataOptions()\n values = Array.isArray(values) ? values : [values]\n const ids = []\n\n // for back-compatibility support both, set by id and set by value\n for (const value of values) {\n if (options.find((option) => option.id == value)) {\n ids.push(value)\n continue\n }\n\n // if option with given id is not found try to search by value\n for (const option of options.filter((option) => option.value == value)) {\n ids.push(option.id)\n }\n }\n\n // Update the store\n this.store.setSelectedBy('id', ids)\n const data = this.store.getData()\n\n // Update the select element\n this.select.updateOptions(data)\n\n // Update the render\n this.render.renderValues()\n\n // If there is a search input value lets run through the search again\n // Otherwise we will just render the options from store data\n if (this.render.content.search.input.value !== '') {\n this.search(this.render.content.search.input.value)\n } else {\n this.render.renderOptions(data)\n }\n\n // Trigger afterChange event, if it doesnt equal the original selected values\n if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {\n this.events.afterChange(this.store.getSelectedOptions())\n }\n }\n\n public addOption(option: Partial<Option>): void {\n // Get original selected values\n const selected = this.store.getSelected()\n\n // Add option to store if it does not already include the option\n if (!this.store.getDataOptions().some((o) => o.value === (option.value ?? option.text))) {\n this.store.addOption(option)\n }\n const data = this.store.getData()\n\n // Update the select element\n this.select.updateOptions(data)\n\n // Update the render\n this.render.renderValues()\n this.render.renderOptions(data)\n\n // Trigger afterChange event, if it doesnt equal the original selected values\n if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {\n this.events.afterChange(this.store.getSelectedOptions())\n }\n }\n\n public open(): void {\n // Dont open if disabled\n // Dont do anything if the content is already open\n if (this.settings.disabled || this.settings.isOpen) {\n return\n }\n\n // Run beforeOpen callback\n if (this.events.beforeOpen) {\n this.events.beforeOpen()\n }\n\n // Tell render to open\n this.render.open()\n\n // Focus on input field only if search is enabled\n if (this.settings.showSearch && this.settings.focusSearch) {\n this.render.searchFocus()\n }\n\n this.settings.isOpen = true\n // setTimeout is for animation completion\n this.openTimeout = setTimeout(() => {\n // Run afterOpen callback\n if (this.events.afterOpen) {\n this.events.afterOpen()\n }\n\n // Update settings\n // Prevent overide if user close fast without wait full open\n // For detail see issue https://github.com/brianvoe/slim-select/issues/397\n if (this.settings.isOpen) {\n this.settings.isFullOpen = true\n }\n\n // Add onclick listener to document to closeContent if clicked outside\n document.addEventListener('click', this.documentClick)\n }, this.settings.timeoutDelay)\n\n // Start an interval to check if main has moved\n // in order to keep content close to main\n if (this.settings.contentPosition === 'absolute') {\n if (this.settings.intervalMove) {\n clearInterval(this.settings.intervalMove)\n }\n this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500)\n }\n }\n\n public close(eventType: string | null = null): void {\n // Dont do anything if the content is already closed\n // Dont do anything if alwaysOpen is true\n if (!this.settings.isOpen || this.settings.alwaysOpen) {\n return\n }\n\n // Run beforeClose calback\n if (this.events.beforeClose) {\n this.events.beforeClose()\n }\n\n // Tell render to close\n this.render.close()\n\n // Clear search only if not empty and keepSearch is false\n if (!this.settings.keepSearch && this.render.content.search.input.value !== '') {\n this.search('') // Clear search\n }\n\n // If we arent tabbing focus back on the main element\n this.render.mainFocus(eventType)\n\n // Update settings\n this.settings.isOpen = false\n this.settings.isFullOpen = false\n\n // Reset the content below\n this.closeTimeout = setTimeout(() => {\n // Run afterClose callback\n if (this.events.afterClose) {\n this.events.afterClose()\n }\n\n // Add onclick listener to document to closeContent if clicked outside\n document.removeEventListener('click', this.documentClick)\n }, this.settings.timeoutDelay)\n\n if (this.settings.intervalMove) {\n clearInterval(this.settings.intervalMove)\n }\n }\n\n // Take in string value and search current options\n public search(value: string): void {\n // If the passed in value is not the same as the search input value\n // then lets update the search input value\n if (this.render.content.search.input.value !== value) {\n this.render.content.search.input.value = value\n }\n\n // If value is empty then render all options\n if (value === '') {\n this.render.renderOptions(this.store.getData())\n return\n }\n\n // If no search event run regular search\n if (!this.events.search) {\n // If value is empty then render all options\n const searchResults = value === '' ? this.store.getData() : this.store.search(value, this.events.searchFilter!)\n this.render.renderOptions(searchResults)\n return\n }\n\n // Search event exists so lets render the searching text\n this.render.renderSearching()\n\n // Based upon the search event deal with the response\n const searchResp = this.events.search(value, this.store.getSelectedOptions())\n\n // If the search event returns a promise\n if (searchResp instanceof Promise) {\n searchResp\n .then((data: (Partial<Option> | Partial<Optgroup>)[]) => {\n // Update store data with search results, preserving selected options\n this.store.setData(data, true)\n\n // Update original select element\n this.select.updateOptions(this.store.getData())\n\n // Render the updated data\n this.render.renderOptions(this.store.getData())\n })\n .catch((err: Error | string) => {\n // Update the render with error\n this.render.renderError(typeof err === 'string' ? err : err.message)\n })\n\n return\n } else if (Array.isArray(searchResp)) {\n // Update store data with search results, preserving selected options\n this.store.setData(searchResp, true)\n\n // Update original select element\n this.select.updateOptions(this.store.getData())\n\n // Render the updated data\n this.render.renderOptions(this.store.getData())\n } else {\n // Update the render with error\n this.render.renderError('Search event must return a promise or an array of data')\n }\n }\n\n public destroy(): void {\n // Clear any pending timeouts\n if (this.openTimeout) {\n clearTimeout(this.openTimeout)\n this.openTimeout = null\n }\n if (this.closeTimeout) {\n clearTimeout(this.closeTimeout)\n this.closeTimeout = null\n }\n if (this.settings.intervalMove) {\n clearInterval(this.settings.intervalMove)\n this.settings.intervalMove = null\n }\n\n // Remove all event listeners\n document.removeEventListener('click', this.documentClick)\n window.removeEventListener('resize', this.windowResize, false)\n if (this.settings.openPosition === 'auto') {\n window.removeEventListener('scroll', this.windowScroll, false)\n }\n document.removeEventListener('visibilitychange', this.windowVisibilityChange)\n\n // Delete the store data\n this.store.setData([])\n\n // Remove the render\n this.render.destroy()\n\n // Show the original select element\n this.select.destroy()\n }\n\n private windowResize: (e: Event) => void = debounce(() => {\n if (!this.settings.isOpen && !this.settings.isFullOpen) {\n return\n }\n\n this.render.moveContent()\n })\n\n // Event listener for window scrolling\n private windowScroll: (e: Event) => void = debounce(() => {\n // If the content is not open, there is no need to move it\n if (!this.settings.isOpen && !this.settings.isFullOpen) {\n return\n }\n\n this.render.moveContent()\n })\n\n // Event listener for document click\n private documentClick: (e: Event) => void = (e: Event) => {\n // If the content is not open, there is no need to close it\n if (!this.settings.isOpen) {\n return\n }\n\n // Check if the click was on the content by looking at the parents\n if (e.target && !hasClassInTree(e.target as HTMLElement, this.settings.id)) {\n this.close(e.type)\n }\n }\n\n // Event Listener for window visibility change\n private windowVisibilityChange: (e: Event) => void = () => {\n if (document.hidden) {\n this.close()\n }\n }\n}\n","// UMD entry point - only exports the default SlimSelect class\n// This avoids the mixed exports issue for UMD/IIFE builds\nimport SlimSelect, * as namedExports from './index'\n\n// Attach all named exports as properties on the default export\nObject.assign(SlimSelect, namedExports)\n\nexport default SlimSelect\n"],"names":["CssClasses","classes","generateID","hasClassInTree","element","className","hasClass","e","c","parentByClass","debounce","func","wait","immediate","timeout","args","context","later","callNow","isEqual","a","b","kebabCase","str","result","match","Option","option","Optgroup","optgroup","o","Store","type","data","dataObj","validationError","dataFinal","optOptions","preserveSelected","newData","selectedOptions","missingSelected","selectedOption","found","newItem","opt","addToStart","selectedType","selectedValues","firstOption","hasSelected","selectedObjects","optionValue","selectedIds","value","id","options","search","searchFilter","filter","includeOptgroup","dataSearch","newOrder","isIn","Render","settings","store","callbacks","dirClass","selectedId","animationTiming","cssValue","listboxId","main","highlighted","values","deselect","shouldDelete","before","after","deselectSvg","deselectPath","arrow","arrowPath","eventType","placeholderOption","placeholderText","placeholder","selected","selectedSingle","singleValue","currentNodes","maxValuesMessage","removeNodes","node","n","d","shouldAdd","i","text","deleteDiv","deleteSvg","deletePath","list","input","addable","searchReturn","highlightedEnter","plus","plusPath","inputValue","runFinish","oo","newOption","ids","addableValue","notPlaceholder","notDisabled","notHidden","query","dir","prevOption","prevParent","optgroupLabel","selectOption","selectParent","firstHighlight","listId","error","errorDiv","searchingDiv","noResults","fragment","optgroupEl","optgroupLabelText","optgroupActions","selectAll","allSelected","selectAllText","selectAllSvg","selectAllBox","selectAllCheck","currentSelected","newSelected","s","optionIds","optgroupClosable","optgroupClosableSvg","optgroupClosableArrow","optionEl","dataClass","elementID","isCmd","shouldUpdate","isCurrentlySelected","lastIndex","currentIndex","startIndex","endIndex","newSelections","isModifierKey","searchTerm","escapedSearch","tempDiv","highlightTextNodes","regex","wrapper","part","index","mark","child","mainHeight","contentHeight","containerRect","container","cTop","cBottom","eTop","eBottom","mainRect","hasSelectedItems","isMultiple","allowDeselect","deselectButton","hideClass","Select","select","listen","ev","mutations","classChanged","disabledChanged","optgroupOptionChanged","selectionChanged","m","currentData","nodes","opts","optgroupOptions","style","pending","info","optionClass","key","labels","selectId","label","parent","labelClickHandler","target","handler","Settings","SlimSelect","config","debounceEvents","disabled","renderCallbacks","selectAriaLabel","selectAriaLabelledBy","err","dataClean","runAfterChange","searchResults","searchResp"],"mappings":"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"}