PageSourceSearch

https://wdn-cdn.unl.edu/wdn/templates_6.1/js/components/component.search-select.js?v=6.1.6

js unl.edu collected 2026-09-24 06:52:05 UTC 51,776 bytes, 891 lines download raw bytes

1var __defProp = Object.defineProperty;
2var __name = (target, value) => __defProp(target, "name", { value, configurable: !0 });
3import { u as uuidv4 } from "../chunks/chunk.dcf-utility.js?v=6.1.6";
4class DCFSearchSelect {
5  static {
6    __name(this, "DCFSearchSelect");
7  }
8  uuid = uuidv4();
9  multiple = !1;
10  selectID = null;
11  selectElement = null;
12  parsedSelect = [];
13  searchAndSelectID = null;
14  searchAndSelectElement = null;
15  inputID = null;
16  inputElement = null;
17  openButtonElement = null;
18  searchAreaElement = null;
19  availableItemsListID = null;
20  availableItemsListElement = null;
21  listOfAvailableItems = [];
22  selectedItemsListID = null;
23  selectedItemsListElement = null;
24  selectedItemsHelpID = null;
25  currentFocus = null;
26  searchAndSelectClassList = [
27    "dcf-relative"
28  ];
29  searchAreaClassList = [
30    "dcf-relative",
31    "dcf-d-grid",
32    "dcf-overflow-x-hidden",
33    "dcf-overflow-y-auto"
34  ];
35  selectedItemsListClassList = [
36    "dcf-d-flex",
37    "dcf-flex-wrap",
38    "dcf-m-0"
39  ];
40  selectedItemClassList = [
41    "dcf-d-flex",
42    "dcf-flex-nowrap",
43    "dcf-ai-center",
44    "dcf-jc-center",
45    "dcf-mb-0",
46    "dcf-relative"
47  ];
48  selectedItemButtonClassList = [
49    "dcf-btn",
50    "dcf-btn-secondary",
51    "dcf-h-100%",
52    "dcf-z-1"
53  ];
54  selectedItemButtonSVG = `<svg
55    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26" class="dcf-fill-current dcf-w-4 dcf-h-4">
56    <path d="M25.4,22.6L15.8,13l9.6-9.6C25.8,3,26,2.5,26,2s-0.2-1-0.6-1.4c-0.8-0.8-2.1-0.8-2.8,0L13,10.2L3.4,0.6
57        c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2,0,2.8l9.6,9.6l-9.6,9.6C0.2,23,0,23.5,0,24c0,0.5,0.2,1,0.6,1.4C1,25.8,1.5,26,2,26
58        c0.5,0,1-0.2,1.4-0.6l9.6-9.6l9.6,9.6C23,25.8,23.5,26,24,26c0,0,0,0,0,0c0.5,0,1-0.2,1.4-0.6C25.8,25,26,24.5,26,24
59        C26,23.5,25.8,23,25.4,22.6z"/>
60</svg>`;
61  selectedItemLabelClassList = [
62    "dcf-h-100%"
63  ];
64  toggleButtonContainerClassList = [
65    "dcf-sticky",
66    "dcf-top-50%",
67    "dcf-h-0",
68    "dcf-pl-1",
69    "dcf-pr-1"
70  ];
71  toggleButtonClassList = [
72    "dcf-btn",
73    "dcf-btn-tertiary",
74    "dcf-p-3"
75  ];
76  toggleButtonSVG = `<svg
77xmlns="http://www.w3.org/2000/svg"
78viewBox="0 0 24 24"
79class="dcf-fill-current dcf-w-3 dcf-h-3"
80aria-hidden="true"
81>
82<path d="M23.936,2.255C23.848,2.098,23.681,2,23.5,2h-23
83    C0.32,2,0.153,2.098,0.065,2.255c-0.089,0.157-0.085,0.35,0.008,0.504
84    l11.5,19C11.663,21.908,11.826,22,12,22s0.337-0.092,0.428-0.241
85    l11.5-19C24.021,2.605,24.025,2.412,23.936,2.255z"></path>
86</svg>`;
87  inputSingleClassList = [
88    "dcf-b-0"
89  ];
90  inputGroupMultiple = [
91    "dcf-d-flex",
92    "dcf-flex-wrap"
93  ];
94  inputMultipleClassList = [
95    "dcf-b-0",
96    "dcf-flex-grow-1",
97    "dcf-flex-shrink-0"
98  ];
99  availableItemsListClassList = [
100    "dcf-absolute",
101    "dcf-d-none",
102    "dcf-mb-0",
103    "dcf-pl-0",
104    "dcf-w-100%",
105    "dcf-z-2"
106  ];
107  availableItemsGroupClassList = [
108    "dcf-m-0",
109    "dcf-pl-0"
110  ];
111  availableItemsGroupLabelClassList = [
112    "dcf-mb-0",
113    "dcf-bold"
114  ];
115  availableItemClassList = [
116    "dcf-relative",
117    "dcf-d-flex",
118    "dcf-flex-row",
119    "dcf-flex-nowrap",
120    "dcf-jc-between",
121    "dcf-ai-center",
122    "dcf-mb-0"
123  ];
124  availableItemIndicatorSVG = `<svg
125    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" class="dcf-fill-current dcf-h-4 dcf-w-4">
126    <path d="M31,0.4C30.6,0.1,30-0.1,29.4,0c-0.6,0.1-1.1,0.4-1.5,0.9
127    L10.1,26.3L3.8,20c-0.4-0.4-1-0.6-1.6-0.6c0,0,0,0,0,0
128    c-0.6,0-1.2,0.2-1.6,0.6C0.2,20.5,0,21,0,21.6
129    c0,0.6,0.2,1.2,0.7,1.6l8.1,8.1c0.4,0.4,1,0.7,1.6,0.7
130    c0.7,0,1.4-0.4,1.8-1L31.6,3.5
131    C32.3,2.5,32.1,1.1,31,0.4z"/>
132</svg>`;
133  availableItemsNoResultsClassList = [
134    "dcf-mb-0",
135    "dcf-bold"
136  ];
137  /**
138   * Constructor for the multi-select combobox
139   * @param { HTMLSelectElement } selectElement The select that will be used to build the component
140   */
141  constructor(selectElement, options = {}) {
142    "searchAndSelectClassList" in options && Array.isArray(options.searchAndSelectClassList) && (this.searchAndSelectClassList = options.searchAndSelectClassList), "searchAreaClassList" in options && Array.isArray(options.searchAreaClassList) && (this.searchAreaClassList = options.searchAreaClassList), "selectedItemsListClassList" in options && Array.isArray(options.selectedItemsListClassList) && (this.selectedItemsListClassList = options.selectedItemsListClassList), "selectedItemClassList" in options && Array.isArray(options.selectedItemClassList) && (this.selectedItemClassList = options.selectedItemClassList), "selectedItemButtonClassList" in options && Array.isArray(options.selectedItemButtonClassList) && (this.selectedItemButtonClassList = options.selectedItemButtonClassList), "selectedItemButtonSVG" in options && typeof options.selectedItemButtonSVG == "string" && (this.selectedItemButtonSVG = options.selectedItemButtonSVG), "selectedItemLabelClassList" in options && Array.isArray(options.selectedItemLabelClassList) && (this.selectedItemLabelClassList = options.selectedItemLabelClassList), "toggleButtonContainerClassList" in options && Array.isArray(options.toggleButtonContainerClassList) && (this.toggleButtonContainerClassList = options.toggleButtonContainerClassList), "toggleButtonClassList" in options && Array.isArray(options.toggleButtonClassList) && (this.toggleButtonClassList = options.toggleButtonClassList), "toggleButtonSVG" in options && typeof options.toggleButtonSVG == "string" && (this.toggleButtonSVG = options.toggleButtonSVG), "inputSingleClassList" in options && Array.isArray(options.inputSingleClassList) && (this.inputSingleClassList = options.inputSingleClassList), "inputGroupMultiple" in options && Array.isArray(options.inputGroupMultiple) && (this.inputGroupMultiple = options.inputGroupMultiple), "inputMultipleClassList" in options && Array.isArray(options.inputMultipleClassList) && (this.inputMultipleClassList = options.inputMultipleClassList), "availableItemsListClassList" in options && Array.isArray(options.availableItemsListClassList) && (this.availableItemsListClassList = options.availableItemsListClassList), "availableItemsGroupClassList" in options && Array.isArray(options.availableItemsGroupClassList) && (this.availableItemsListClassList = options.availableItemsGroupClassList), "availableItemsGroupLabelClassList" in options && Array.isArray(options.availableItemsGroupLabelClassList) && (this.availableItemsGroupLabelClassList = options.availableItemsGroupLabelClassList), "availableItemClassList" in options && Array.isArray(options.availableItemClassList) && (this.availableItemClassList = options.availableItemClassList), "availableItemIndicatorSVG" in options && typeof options.availableItemIndicatorSVG == "string" && (this.availableItemIndicatorSVG = options.availableItemIndicatorSVG), "availableItemsNoResultsClassList" in options && Array.isArray(options.availableItemsNoResultsClassList) && (this.availableItemsNoResultsClassList = options.availableItemsNoResultsClassList), this.selectElement = selectElement, (this.selectElement.getAttribute("id") === "" || this.selectElement.getAttribute("id") === null) && this.selectElement.setAttribute("id", this.uuid.concat("-search-and-select-select")), this.selectElement.getAttribute("multiple") !== null && (this.multiple = !0), this.selectID = this.selectElement.getAttribute("id"), this.searchAndSelectID = this.uuid.concat("-search-and-select"), this.inputID = this.uuid.concat("-search-and-select-input"), this.availableItemsListID = this.uuid.concat("-search-and-select-available-items-list"), this.searchAndSelectElement = document.createElement("div"), this.searchAndSelectElement.innerHTML = `<div
143class="dcf-search-and-select-search-area-single ${this.searchAreaClassList.join(" ")}" >
144    <input
145    class="${this.inputSingleClassList.join(" ")}"
146    type="text"
147    role="combobox"
148    id=${this.inputID}
149    aria-haspopup="listbox"
150    aria-autocomplete="list"
151    aria-expanded="false"
152    aria-controls="${this.availableItemsListID}"
153    >
154    <div class="dcf-search-and-select-open-btn ${this.toggleButtonContainerClassList.join(" ")}">
155    <button
156        class="${this.toggleButtonClassList.join(" ")}"
157        type="button"
158        tabindex="-1"
159        aria-label="Toggle Selectable List"
160        aria-expanded="false"
161        aria-controls="${this.availableItemsListID}"
162    >
163        ${this.toggleButtonSVG}
164    </button>
165    </div>
166</div>`, this.searchAndSelectElement.classList.add("dcf-search-and-select", ...this.searchAndSelectClassList), this.searchAndSelectElement.setAttribute("id", this.searchAndSelectID), this.searchAndSelectElement.setAttribute("hidden", "hidden"), this.searchAndSelectElement.dataset.for = this.selectID, this.inputElement = this.searchAndSelectElement.querySelector("input"), this.openButtonElement = this.searchAndSelectElement.querySelector(".dcf-search-and-select-open-btn button"), this.searchAreaElement = this.searchAndSelectElement.querySelector(".dcf-search-and-select-search-area-single"), this.multiple && (this.selectedItemsListID = this.uuid.concat("-search-and-select-selected-items-list"), this.selectedItemsHelpID = this.uuid.concat("-search-and-select-selected-items-list-help"), this.searchAndSelectElement.innerHTML = `<div
167class="dcf-search-and-select-search-area-multiple ${this.searchAreaClassList.join(" ")}" >
168    <div class="dcf-search-and-select-multiple-input-group ${this.inputGroupMultiple.join(" ")}">
169    <span id="${this.selectedItemsHelpID}" class="dcf-sr-only">Press Delete or Backspace to Remove.</span>
170    <ul
171        class="dcf-search-and-select-selected-items ${this.selectedItemsListClassList.join(" ")}"
172        role="list"
173        aria-describedby="${this.selectedItemsHelpID}"
174        id=${this.selectedItemsListID}
175        aria-label="Selected Items"
176    ></ul>
177    <input
178        class="${this.inputMultipleClassList.join(" ")}"
179        type="text"
180        role="combobox"
181        id=${this.inputID}
182        aria-haspopup="listbox"
183        aria-autocomplete="list"
184        aria-expanded="false"
185        aria-controls="${this.availableItemsListID}"
186    >
187    </div>
188    <div class="dcf-search-and-select-open-btn ${this.toggleButtonContainerClassList.join(" ")}">
189    <button
190        class="${this.toggleButtonClassList.join(" ")}"
191        type="button"
192        tabindex="-1"
193        aria-label="Toggle Selectable List"
194        aria-expanded="false"
195        aria-controls="${this.availableItemsListID}"
196    >
197        ${this.toggleButtonSVG}
198    </button>
199    </div>
200</div>`, this.inputElement = this.searchAndSelectElement.querySelector("input"), this.openButtonElement = this.searchAndSelectElement.querySelector(".dcf-search-and-select-open-btn button"), this.selectedItemsListElement = this.searchAndSelectElement.querySelector(".dcf-search-and-select-selected-items"), this.searchAreaElement = this.searchAndSelectElement.querySelector(".dcf-search-and-select-search-area-multiple")), this.parsedSelect = this.#parseSelect(), this.selectElement.after(this.searchAndSelectElement), this.availableItemsListElement = this.#buildAvailableItems(), this.availableItemsListElement.setAttribute("id", this.availableItemsListID), this.availableItemsListElement.classList.add(
201      "dcf-search-and-select-available-items",
202      ...this.availableItemsListClassList
203    ), this.searchAndSelectElement.append(this.availableItemsListElement), this.#fixSelectReferences(), this.#transferSelectAttributes(), this.#setDisabled(this.selectElement.getAttribute("disabled") !== null), this.#setReadOnly(this.selectElement.getAttribute("readonly") !== null), this.#addEventListeners(), this.searchAndSelectElement.removeAttribute("hidden"), this.multiple && this.availableItemsListElement.setAttribute("aria-multiselectable", !0), this.selectElement.classList.add("dcf-search-select-initialized"), this.selectElement.dispatchEvent(new CustomEvent(DCFSearchSelect.events("searchSelectReady"), {
204      detail: {
205        classInstance: this
206      }
207    }));
208  }
209  /**
210   * Validates and returns standardized name of events for tabs
211   * @static
212   * @param { string } name - Name of the event to be returned
213   * @returns { string } Standard name of the event
214   */
215  static events(name) {
216    const events = {
217      searchSelectReady: "searchSelectReady"
218    };
219    return Object.freeze(events), name in events ? events[name] : void 0;
220  }
221  /**
222   * Fix any references to the hidden select
223   */
224  #fixSelectReferences() {
225    [
226      "for",
227      "aria-controls",
228      "aria-describedby"
229    ].forEach((singleAttr) => {
230      document.querySelectorAll(`[${singleAttr}="${this.selectID}"]`).forEach((elementToFix) => {
231        elementToFix.setAttribute(singleAttr, this.inputID);
232      });
233    });
234  }
235  /**
236   * If the select element has attributes set it will transfer them to the input
237   */
238  #transferSelectAttributes() {
239    [
240      "aria-describedby",
241      "aria-label",
242      "aria-labelledby",
243      "aria-owns"
244    ].forEach((singleAttr) => {
245      this.selectElement.getAttribute(singleAttr) !== null && this.inputElement.setAttribute(singleAttr, this.selectElement.getAttribute(singleAttr));
246    });
247  }
248  /**
249   * Recursively parses the select/optgroups
250   * @returns { Array<ParsedOptgroup> }
251   */
252  #parseSelect() {
253    const returnedData = this.#parseSelectInner(this.selectElement), optgroups = returnedData.optgroups;
254    return returnedData.options.length > 0 && optgroups.push({
255      tag: "optgroup",
256      label: "Other",
257      element: this.selectElement,
258      items: returnedData.options
259    }), optgroups;
260  }
261  /**
262   * Recursively parses the select/optgroups
263   * @param { HTMLSelectElement|HTMLOptGroupElement } selectOrOptgroup The select or optgroup to parse
264   * @returns { parseSelectInner }
265   */
266  #parseSelectInner(selectOrOptgroup) {
267    const optgroups = [], options = [];
268    for (const optgroupOrOption of selectOrOptgroup.children)
269      if (optgroupOrOption.tagName === "OPTGROUP") {
270        const returnedData = this.#parseSelectInner(optgroupOrOption), returnedOptgroups = returnedData.optgroups;
271        optgroups.push(...returnedOptgroups), optgroups.push({
272          tag: "optgroup",
273          label: optgroupOrOption.getAttribute("label"),
274          element: optgroupOrOption,
275          items: returnedData.options
276        });
277      } else optgroupOrOption.tagName === "OPTION" && options.push({
278        tag: "option",
279        label: optgroupOrOption.innerHTML,
280        value: optgroupOrOption.getAttribute("value"),
281        selected: optgroupOrOption.getAttribute("selected") !== null,
282        disabled: optgroupOrOption.getAttribute("disabled") !== null,
283        elemId: uuidv4().concat("-search-and-select-option"),
284        element: optgroupOrOption
285      });
286    return { optgroups, options };
287  }
288  /**
289   * Builds the available items UL from output of parse select
290   * @returns { HTMLUListElement }
291   */
292  #buildAvailableItems() {
293    return this.multiple ? this.#buildAvailableItemsMultiple() : this.#buildAvailableItemsSingle();
294  }
295  /**
296   * Builds the available items UL from output of parse select
297   * SINGLE
298   * @returns { HTMLUListElement }
299   */
300  #buildAvailableItemsSingle() {
301    const availableItems = document.createElement("ul");
302    availableItems.setAttribute("role", "listbox");
303    let lastSelectedOption = null;
304    return this.parsedSelect.forEach((singleOptgroup) => {
305      const groupedItems = document.createElement("ul");
306      groupedItems.setAttribute("role", "group"), groupedItems.classList.add("dcf-search-and-select-available-items-group", ...this.availableItemsGroupClassList), this.parsedSelect.length !== 1 && (groupedItems.innerHTML = `${groupedItems.innerHTML}
307<li
308class="${this.availableItemsGroupLabelClassList.join(" ")}"
309role="presentation"
310>
311${singleOptgroup.label}
312</li>
312`), singleOptgroup.items.forEach((singleItem) => {
313        const newItem = document.createElement("li");
314        newItem.classList.add(
315          "dcf-search-and-select-available-item",
316          "dcf-search-and-select-clickable",
317          ...this.availableItemClassList
318        ), newItem.setAttribute("role", "option"), newItem.setAttribute("aria-selected", "false"), newItem.setAttribute("aria-disabled", singleItem.disabled), newItem.setAttribute("id", `${singleItem.elemId}-available`), newItem.dataset.value = singleItem.value, newItem.dataset.label = singleItem.label, newItem.dataset.elemId = singleItem.elemId, newItem.innerHTML = `<span
319    class="dcf-search-and-select-available-item-label">
320    ${singleItem.label}
321</span>
322<span class="dcf-search-and-select-available-item-indicator" aria-hidden="true">
323    ${this.availableItemIndicatorSVG}
324</span>`, groupedItems.append(newItem), singleItem.disabled === !1 && singleItem.selected === !0 && (lastSelectedOption = newItem);
325      }), availableItems.append(groupedItems);
326    }), lastSelectedOption !== null && (lastSelectedOption.setAttribute("aria-selected", "true"), this.inputElement.value = lastSelectedOption.dataset.label), availableItems;
327  }
328  /**
329   * Builds the available items UL from output of parse select
330   * MULTIPLE
331   * @returns { HTMLUListElement }
332   */
333  #buildAvailableItemsMultiple() {
334    const availableItems = document.createElement("ul");
335    return availableItems.setAttribute("role", "listbox"), this.parsedSelect.forEach((singleOptgroup) => {
336      const groupedItems = document.createElement("ul");
337      groupedItems.setAttribute("role", "group"), groupedItems.classList.add("dcf-search-and-select-available-items-group", ...this.availableItemsGroupClassList), this.parsedSelect.length !== 1 && (groupedItems.innerHTML = `${groupedItems.innerHTML}
338<li
339class="${this.availableItemsGroupLabelClassList.join(" ")}"
340role="presentation"
341>
342${singleOptgroup.label}
343</li>
344            `), singleOptgroup.items.forEach((singleItem) => {
345        const newItem = document.createElement("li");
346        newItem.classList.add(
347          "dcf-search-and-select-available-item",
348          "dcf-search-and-select-clickable",
349          ...this.availableItemClassList
350        ), newItem.setAttribute("role", "option"), newItem.setAttribute("aria-selected", singleItem.disabled ? "false" : singleItem.selected), newItem.setAttribute("aria-disabled", singleItem.disabled), newItem.setAttribute("id", `${singleItem.elemId}-available`), newItem.dataset.value = singleItem.value, newItem.dataset.elemId = singleItem.elemId, newItem.innerHTML = `<span
351    class="dcf-search-and-select-available-item-label">
352    ${singleItem.label}
353</span>
354<span class="dcf-search-and-select-available-item-indicator" aria-hidden="true">
355    ${this.availableItemIndicatorSVG}
356</span>`, groupedItems.append(newItem), singleItem.disabled === !1 && singleItem.selected === !0 && this.#appendNewSelectedItem(newItem);
357      }), availableItems.append(groupedItems);
358    }), availableItems;
359  }
360  /**
361   * We will build a new selected item element and append it to the list of selected items
362   * @param { HTMLLIElement } singleAvailableItem The li from the available items list
363   */
364  #appendNewSelectedItem(singleAvailableItem) {
365    if (!this.#isElementAnAvailableItem(singleAvailableItem))
366      throw new Error("Element is not an available item");
367    const selectedItemLabel = singleAvailableItem.querySelector(".dcf-search-and-select-available-item-label").innerText, newSelectedItem = document.createElement("li");
368    newSelectedItem.dataset.elemId = singleAvailableItem.dataset.elemId, newSelectedItem.setAttribute("id", `${singleAvailableItem.dataset.elemId}-selected`), newSelectedItem.classList.add(
369      "dcf-search-and-select-selected-item",
370      "dcf-search-and-select-clickable",
371      ...this.selectedItemClassList
372    ), newSelectedItem.innerHTML = `<button
373    class="
374        dcf-search-and-select-selected-item-remove-btn
375        ${this.selectedItemButtonClassList.join(" ")}
376    "
377    aria-label="Remove ${selectedItemLabel}"
378    type="button"
379>
380    ${this.selectedItemButtonSVG}
381</button>
382<span class="
383    dcf-search-and-select-selected-item-label
384    ${this.selectedItemLabelClassList.join(" ")}">
385    ${selectedItemLabel}
386</span>`, this.selectedItemsListElement.append(newSelectedItem), this.#isSelectedItemInView(newSelectedItem) || newSelectedItem.scrollIntoView({ behavior: "smooth", block: "nearest" });
387  }
388  /**
389   * Add event listeners for the different parts of the search and select element
390   */
391  #addEventListeners() {
392    return this.multiple ? this.#addEventListenersMultiple() : this.#addEventListenersSingle();
393  }
394  #addEventListenersSingle() {
395    document.body.addEventListener("pointerup", (event) => {
396      this.searchAndSelectElement.contains(event.target) || (this.closeAvailableItems(), this.#setVisualFocusOn(!1));
397    }, !0), this.searchAreaElement.addEventListener("click", () => {
398      this.isComponentDisabled() || (this.#setVisualFocusOn(this.searchAreaElement), this.inputElement.focus(), this.isComponentReadOnly() || this.isAvailableItemsOpen() ? this.closeAvailableItems() : (this.#filterAvailableItems(), this.openAvailableItems())
398);
399    }), this.inputElement.addEventListener("focus", () => {
400      this.#setVisualFocusOn(this.searchAreaElement);
401    }), this.inputElement.addEventListener("keydown", (event) => {
402      if (this.isComponentReadOnly())
403        return;
404      const altKey = event.altKey;
405      let preventDefault = !1;
406      const length = this.inputElement.value.length;
407      switch (event.code) {
408        case "Enter":
409          if (this.#visualFocusOnAvailableItems()) {
410            const currentItemElement = this.getAvailableItemActiveDescendant();
411            currentItemElement !== !1 && (this.#isAvailableItemDisabled(currentItemElement) || (this.#isAvailableItemSelected(currentItemElement) ? this.#removeAvailableItem(currentItemElement) : this.#selectAvailableItem(currentItemElement)));
412          } else
413            this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()), this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getFirstAvailableItem()), this.#scrollActiveAvailableItemInView();
414          preventDefault = !0;
415          break;
416        case "Down":
417        case "ArrowDown":
418          altKey ? this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()) : (this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()), this.#visualFocusOnAvailableItems() ? (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getNextAvailableItem()), this.#scrollActiveAvailableItemInView()) : (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getFirstAvailableItem()), this.#scrollActiveAvailableItemInView())), preventDefault = !0;
419          break;
420        case "Esc":
421        case "Escape":
422          this.isAvailableItemsOpen() && (this.closeAvailableItems(!0), this.#setVisualFocusOn(this.searchAreaElement)), preventDefault = !0;
423          break;
424        case "Up":
425        case "ArrowUp":
426          altKey ? this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()) : (this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()), this.#visualFocusOnAvailableItems() ? (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getPreviousAvailableItem()), this.#scrollActiveAvailableItemInView()) : (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getLastAvailableItem()), this.#scrollActiveAvailableItemInView())), preventDefault = !0;
427          break;
428        case "Tab":
429          this.closeAvailableItems(!0), this.#setVisualFocusOn(!1);
430          break;
431        case "Home":
432          this.inputElement.setSelectionRange(0, 0), preventDefault = !0;
433          break;
434        case "End":
435          this.inputElement.setSelectionRange(length, length), preventDefault = !0;
436          break;
437      }
438      preventDefault && (event.stopPropagation(), event.preventDefault());
439    }), this.inputElement.addEventListener("keyup", (event) => {
440      if (this.isComponentReadOnly())
441        return;
442      const char = event.key;
443      let preventDefault = !1;
444      if (!(event.key === "Escape" || event.key === "Esc")) {
445        switch (event.code) {
446          case "Backspace":
447            this.#setVisualFocusOn(this.searchAreaElement), this.#filterAvailableItems(), this.#setAvailableItemActiveDescendant(!1), preventDefault = !0;
448            break;
449          case "Left":
450          case "ArrowLeft":
451          case "Right":
452          case "ArrowRight":
453          case "Home":
454          case "End":
455            this.#setVisualFocusOn(this.searchAreaElement), preventDefault = !0;
456            break;
457          default:
458            this.#isPrintableCharacter(char) && (this.#setVisualFocusOn(this.searchAreaElement), this.#filterAvailableItems(), this.openAvailableItems(), this.#setAvailableItemActiveDescendant(!1));
459            break;
460        }
461        preventDefault && (event.stopPropagation(), event.preventDefault());
462      }
463    }), this.availableItemsListElement.addEventListener("click", (event) => {
464      const closestItem = event.target.closest(".dcf-search-and-select-available-item");
465      closestItem !== null && (this.#isAvailableItemDisabled(closestItem) || (this.#isAvailableItemSelected(closestItem) ? this.#removeAvailableItem(closestItem) : this.#selectAvailableItem(closestItem)), this.inputElement.focus(), this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(closestItem));
466    }), this.availableItemsListElement.addEventListener("pointermove", (event) => {
467      const currentItem = this.getAvailableItemActiveDescendant(), closestItem = event.target.closest(".dcf-search-and-select-available-item");
468      closestItem !== null && (currentItem === !1 || !closestItem.isSameNode(currentItem)) && this.#setAvailableItemActiveDescendant(closestItem);
469    }), this.availableItemsListElement.addEventListener("pointerout", (event) => {
470      this.availableItemsListElement.isSameNode(event.target) && this.#setAvailableItemActiveDescendant(!1);
471    });
472  }
473  #addEventListenersMultiple() {
474    document.body.addEventListener("pointerup", (event) => {
475      this.searchAndSelectElement.contains(event.target) || (this.closeAvailableItems(), this.#setVisualFocusOn(!1));
476    }, !0), this.searchAreaElement.addEventListener("click", () => {
477      this.isComponentDisabled() || (this.#setVisualFocusOn(this.searchAreaElement), this.inputElement.focus(), this.isAvailableItemsOpen() || this.isComponentReadOnly() ? this.closeAvailableItems() : (this.#filterAvailableItems(), this.openAvailableItems())
477);
478    }), this.inputElement.addEventListener("focus", () => {
479      this.#setVisualFocusOn(this.searchAreaElement);
480    }), this.inputElement.addEventListener("keydown", (event) => {
481      if (this.isComponentReadOnly())
482        return;
483      const altKey = event.altKey, shiftKey = event.shiftKey;
484      let preventDefault = !1;
485      const length = this.inputElement.value.length;
486      switch (event.code) {
487        case "Enter":
488          if (this.#visualFocusOnAvailableItems()) {
489            const currentItemElement = this.getAvailableItemActiveDescendant();
490            currentItemElement !== !1 && (this.#isAvailableItemDisabled(currentItemElement) || (this.#isAvailableItemSelected(currentItemElement) ? this.#removeAvailableItem(currentItemElement) : this.#selectAvailableItem(currentItemElement)));
491          } else
492            this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()), this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getFirstAvailableItem()), this.#scrollActiveAvailableItemInView();
493          preventDefault = !0;
494          break;
495        case "Down":
496        case "ArrowDown":
497          altKey ? this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()) : (this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()), this.#visualFocusOnAvailableItems() ? (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getNextAvailableItem()), this.#scrollActiveAvailableItemInView()) : (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getFirstAvailableItem()), this.#scrollActiveAvailableItemInView())), preventDefault = !0;
498          break;
499        case "Esc":
500        case "Escape":
501          this.isAvailableItemsOpen() && (this.closeAvailableItems(!0), this.#setVisualFocusOn(this.searchAreaElement)), preventDefault = !0;
502          break;
503        case "Up":
504        case "ArrowUp":
505          altKey ? this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()) : (this.isAvailableItemsOpen() || (this.#filterAvailableItems(), this.openAvailableItems()), this.#visualFocusOnAvailableItems() ? (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getPreviousAvailableItem()), this.#scrollActiveAvailableItemInView()) : (this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(this.getLastAvailableItem()), this.#scrollActiveAvailableItemInView())), preventDefault = !0;
506          break;
507        case "Tab":
508          this.closeAvailableItems(!0), shiftKey || this.#setVisualFocusOn(!1);
509          break;
510        case "Home":
511          this.inputElement.setSelectionRange(0, 0), preventDefault = !0;
512          break;
513        case "End":
514          this.inputElement.setSelectionRange(length, length), preventDefault = !0;
515          break;
516      }
517      preventDefault && (event.stopPropagation(), event.preventDefault());
518    }), this.inputElement.addEventListener("keyup", (event) => {
519      if (this.isComponentReadOnly())
520        return;
521      const char = event.key;
522      let preventDefault = !1;
523      if (!(event.key === "Escape" || event.key === "Esc")) {
524        switch (event.code) {
525          case "Backspace":
526            this.#setVisualFocusOn(this.searchAreaElement), this.#filterAvailableItems(), this.#setAvailableItemActiveDescendant(!1), preventDefault = !0;
527            break;
528          case "Left":
529          case "ArrowLeft":
530          case "Right":
531          case "ArrowRight":
532          case "Home":
533          case "End":
534            this.#setVisualFocusOn(this.searchAreaElement), preventDefault = !0;
535            break;
536          default:
537            this.#isPrintableCharacter(char) && (this.#setVisualFocusOn(this.searchAreaElement), this.#filterAvailableItems(), this.openAvailableItems(), this.#setAvailableItemActiveDescendant(!1));
538            break;
539        }
540        preventDefault && (event.stopPropagation(), event.preventDefault());
541      }
542    }), this.availableItemsListElement.addEventListener("click", (event) => {
543      const closestItem = event.target.closest(".dcf-search-and-select-available-item");
544      closestItem !== null && (this.#isAvailableItemDisabled(closestItem) || (this.#isAvailableItemSelected(closestItem) ? this.#removeAvailableItem(closestItem) : this.#selectAvailableItem(closestItem)), this.inputElement.focus(), this.#setVisualFocusOn(this.availableItemsListElement), this.#setAvailableItemActiveDescendant(closestItem));
545    }), this.availableItemsListElement.addEventListener("pointermove", (event) => {
546      const currentItem = this.getAvailableItemActiveDescendant(), closestItem = event.target.closest(".dcf-search-and-select-available-item");
547      closestItem !== null && (currentItem === !1 || !closestItem.isSameNode(currentItem)) && this.#setAvailableItemActiveDescendant(closestItem);
548    }), this.availableItemsListElement.addEventListener("pointerout", (event) => {
549      this.availableItemsListElement.isSameNode(event.target) && this.#setAvailableItemActiveDescendant(!1);
550    }), this.selectedItemsListElement.addEventListener("focus", () => {
551      this.#setVisualFocusOn(!1);
552    }, !0), this.selectedItemsListElement.addEventListener("click", (event) => {
553      if (this.isComponentDisabled())
554        return;
555      const closestSelectedItem = event.target.closest(".dcf-search-and-select-selected-item");
556      if (closestSelectedItem === null)
557        return;
558      if (event.target.closest(".dcf-search-and-select-selected-item-remove-btn") !== null && !this.isComponentReadOnly()) {
559        this.selectedItemsListElement.focus(), this.#removeSelectedItem(closestSelectedItem), this.#setAvailableItemActiveDescendant(!1), event.stopPropagation();
560        return;
561      }
562      event.stopPropagation();
563    });
564  }
565  /**
566   * Will turn the component's disabled mode on or off
567   * @param { bool } boolDisabled the new disabled state
568   */
569  #setDisabled(boolDisabled) {
570    return this.multiple ? this.#setDisabledMultiple(boolDisabled) : this.#setDisabledSingle(boolDisabled);
571  }
572  #setDisabledSingle(boolDisabled) {
573    let formattedBoolDisabled = boolDisabled;
574    typeof formattedBoolDisabled != "boolean" && (formattedBoolDisabled = !1), formattedBoolDisabled ? (this.inputElement.setAttribute("disabled", "disabled"), this.openButtonElement.setAttribute("disabled", "disabled"), this.searchAndSelectElement.classList.add("dcf-search-and-select-disabled"), this.#setVisualFocusOn(!1), this.closeAvailableItems()) : (this.inputElement.removeAttribute("disabled"), this.openButtonElement.removeAttribute("disabled"), this.searchAndSelectElement.classList.remove("dcf-search-and-select-disabled"));
575  }
576  #setDisabledMultiple(boolDisabled) {
577    let formattedBoolDisabled = boolDisabled;
578    typeof formattedBoolDisabled != "boolean" && (formattedBoolDisabled = !1), formattedBoolDisabled ? (this.inputElement.setAttribute("disabled", "disabled"), this.openButtonElement.setAttribute("disabled", "disabled"), this.searchAndSelectElement.classList.add("dcf-search-and-select-disabled"), this.selectedItemsListElement.setAttribute("aria-disabled", "true"), this.selectedItemsListElement.querySelectorAll("button").forEach((selectedItemButton) => {
579      selectedItemButton.setAttribute("disabled", "disabled");
580    }), this.#setVisualFocusOn(!1), this.closeAvailableItems()) : (this.inputElement.removeAttribute("disabled"), this.openButtonElement.removeAttribute("disabled"), this.searchAndSelectElement.classList.remove("dcf-search-and-select-disabled"), this.selectedItemsListElement.removeAttribute("aria-disabled"), this.selectedItemsListElement.querySelectorAll("button").forEach((selectedItemButton) => {
581      selectedItemButton.removeAttribute("disabled");
582    }));
583  }
584  /**
585   * Determines if the component is in disabled mode
586   * @returns { bool } true if the component is disabled
587   */
588  isComponentDisabled() {
589    return this.inputElement.getAttribute("disabled") !== null;
590  }
591  /**
592   * Will turn the component's readonly mode on or off
593   * @param { bool } boolReadOnly the new readonly state
594   */
595  #setReadOnly(boolReadOnly) {
596    return this.multiple ? this.#setReadOnlyMultiple(boolReadOnly) : this.#setReadOnlySingle(boolReadOnly);
597  }
598  #setReadOnlySingle(boolReadOnly) {
599    let formattedBoolReadOnly = boolReadOnly;
600    typeof formattedBoolReadOnly != "boolean" && (formattedBoolReadOnly = !1), formattedBoolReadOnly ? (this.inputElement.setAttribute("readonly", "readonly"), this.openButtonElement.setAttribute("readonly", "readonly"), this.closeAvailableItems()) : (this.inputElement.removeAttribute("readonly"), this.openButtonElement.removeAttribute("readonly"));
601  }
602  #setReadOnlyMultiple(boolReadOnly) {
603    let formattedBoolReadOnly = boolReadOnly;
604    typeof formattedBoolReadOnly != "boolean" && (formattedBoolReadOnly = !1), formattedBoolReadOnly ? (this.inputElement.setAttribute("readonly", "readonly"), this.openButtonElement.setAttribute("readonly", "readonly"), this.selectedItemsListElement.setAttribute("aria-readonly", "true"), this.selectedItemsListElement.querySelectorAll("button").forEach((selectedItemButton) => {
605      selectedItemButton.setAttribute("readonly", "readonly");
606    }), this.closeAvailableItems()) : (this.inputElement.removeAttribute("readonly"), this.openButtonElement.removeAttribute("readonly"), this.selectedItemsListElement.removeAttribute("aria-readonly"), this.selectedItemsListElement.querySelectorAll("button").forEach((selectedItemButton) => {
607      selectedItemButton.removeAttribute("readonly");
608    }));
609  }
610  /**
611   * Determines if the component is in readonly mode
612   * @returns { bool } true if the component is readonly
613   */
614  isComponentReadOnly() {
615    return this.inputElement.getAttribute("readonly") !== null;
616  }
617  /**
618   * Determines if the keyboard input was a printable character or not
619   * @param { string } str string to test
620   * @returns { bool } true if the string was a printable character
621   */
622  #isPrintableCharacter(str) {
623    return str.length === 1 && str.match(/\S| /);
624  }
625  /**
626   * Determines if the available items list is expanded or not
627   * @returns { bool } true if the available items list is expanded
628   */
629  isAvailableItemsOpen() {
630    return !this.availableItemsListElement.classList.contains("dcf-d-none");
631  }
632  /**
633   * Handles functionality of opening/expanding the available items list
634   */
635  openAvailableItems() {
636    this.inputElement.setAttribute("aria-expanded", "true"), this.openButtonElement.setAttribute("aria-expanded", "true"), this.availableItemsListElement.classList.remove("dcf-d-none");
637  }
638  /**
639   * Handles functionality of closing/un-expanding the available items list
640   */
641  closeAvailableItems() {
642    this.inputElement.setAttribute("aria-expanded", "false"), this.openButtonElement.setAttribute("aria-expanded", "false"), this.availableItemsListElement.classList.add("dcf-d-none");
643  }
644  /**
645   * Determines if the visual focus is on the available items list
646   * @returns { bool } true if the available items list has visual focus
647   */
648  #visualFocusOnAvailableItems() {
649    return this.availableItemsListElement.dataset.focused === "true";
650  }
651  /**
652   * Handles functionality of how to set the visual focus on an element
653   * @param { HTMLElement|false } elementToFocus The element to focus on or false to not focus on anything
654   */
655  #setVisualFocusOn(elementToFocus) {
656    this.currentFocus !== null && this.availableItemsListElement.isSameNode(this.currentFocus) ? (this.searchAreaElement.classList.remove("dcf-search-and-select-visual-focus"), delete this.availableItemsListElement.dataset.focused) : this.currentFocus !== null && (this.currentFocus.classList.remove("dcf-search-and-select-visual-focus"), delete this.currentFocus.dataset.focused), elementToFocus !== !1 && this.availableItemsListElement.isSameNode(elementToFocus) ? (this.searchAreaElement.classList.add("dcf-search-and-select-visual-focus"), this.availableItemsListElement.dataset.focused = "true", this.currentFocus = elementToFocus) : elementToFocus !== !1 ? (elementToFocus.classList.add("dcf-search-and-select-visual-focus"), elementToFocus.dataset.focused = "true", this.currentFocus = elementToFocus) : this.currentFocus = null;
657  }
658  /**
659   * Handles functionality of how to set the visual hover on an element
660   * @param { HTMLElement|false } elementToHover The element to hover on or false to not hover on anything
661   */
662  #setVisualHover(elementToHover) {
663    this.searchAndSelectElement.querySelectorAll(".dcf-search-and-select-visual-hover").forEach((elem) => {
664      elem.classList.remove("dcf-search-and-select-visual-hover");
665    }), elementToHover !== !1 ? (elementToHover.classList.add("dcf-search-and-select-visual-hover"), this.currentHover = elementToHover) : this.currentHover = null;
666  }
667  /**
668   * Gets the currently active item in the available items list
669   * @returns { HTMLLIElement|false } The currently active element in the available items list or false if there is none
670   */
671  getAvailableItemActiveDescendant() {
672    const currentItemID = this.inputElement.getAttribute("aria-activedescendant");
673    if (currentItemID !== null && currentItemID !== "") {
674      const currentItemElement = document.getElementById(currentItemID);
675      if (currentItemElement !== null)
676        return currentItemElement;
677    }
678    return !1;
679  }
680  /**
681   * Handles functionality of setting the active element on the available items list
682   * @param { HTMLLIElement|false } itemToSet The list item to set or false if there is none
683   */
684  #setAvailableItemActiveDescendant(itemToSet) {
685    if (itemToSet !== !1 && !this.#isElementAnAvailableItem(itemToSet))
686      throw new Error("Element is not an available item");
687    itemToSet !== !1 ? (this.inputElement.setAttribute("aria-activedescendant", itemToSet.getAttribute("id")), this.#setVisualHover(itemToSet)) : (this.#setVisualHover(!1), this.inputElement.setAttribute("aria-activedescendant", ""));
688  }
689  /**
690   * Handles functionality of scrolling the current active item into view
691   */
692  #scrollActiveAvailableItemInView() {
693    const currentItemElement = this.getAvailableItemActiveDescendant();
694    currentItemElement !== !1 && !this.#isAvailableItemInView(currentItemElement) && currentItemElement.scrollIntoView({ behavior: "smooth", block: "nearest" });
695  }
696  /**
697   * Gets the next available item that is currently being shown
698   * This will loop the beginning if we are at the end of the list
699   * @returns { HTMLLIElement|null } The next shown available item or null if there is none
700   */
701  getNextAvailableItem() {
702    let nextElement = null, nextElementFlag = !1;
703    for (let index = 0; index < this.listOfAvailableItems.length; index++) {
704      if (nextElementFlag) {
705        nextElement = this.listOfAvailableItems[index];
706        break;
707      }
708      this.listOfAvailableItems[index].getAttribute("id") === this.inputElement.getAttribute("aria-activedescendant") && (nextElementFlag = !0);
709    }
710    return nextElement === null ? this.getFirstAvailableItem() : nextElement;
711  }
712  /**
713   * Gets the previous available item that is currently being shown
714   * This will loop to the end if we are the beginning of the list
715   * @returns { HTMLLIElement|null } The previous shown available item or null if there is none
716   */
717  getPreviousAvailableItem() {
718    let previousElement = null;
719    for (let index = 0; index < this.listOfAvailableItems.length && this.listOfAvailableItems[index].getAttribute("id") !== this.inputElement.getAttribute("aria-activedescendant"); index++)
720      previousElement = this.listOfAvailableItems[index];
721    return previousElement === null ? this.getLastAvailableItem() : previousElement;
722  }
723  /**
724   * Gets the first available item that is currently being shown
725   * @returns { HTMLLIElement|null } The first shown available item or null if there is none
726   */
727  getFirstAvailableItem() {
728    return this.listOfAvailableItems.length === 0 ? !1 : this.listOfAvailableItems[0];
729  }
730  /**
731   * Gets the last available item that is currently being shown
732   * @returns { HTMLLIElement|null } The last shown available item or null if there is none
733   */
734  getLastAvailableItem
734() {
735    return this.listOfAvailableItems.length === 0 ? !1 : this.listOfAvailableItems[this.listOfAvailableItems.length - 1];
736  }
737  /**
738   * Handles the functionality of selecting an available item
739   * @param { HTMLLIElement } itemToSelect The available item to select
740   */
741  #selectAvailableItem(itemToSelect) {
742    return this.multiple ? this.#selectAvailableItemMultiple(itemToSelect) : this.#selectAvailableItemSingle(itemToSelect);
743  }
744  #selectAvailableItemSingle(itemToSelect) {
745    if (!this.#isElementAnAvailableItem(itemToSelect))
746      throw new Error("Element is not an available item");
747    this.availableItemsListElement.querySelectorAll("li.dcf-search-and-select-available-item").forEach((singleOption) => {
748      singleOption.setAttribute("aria-selected", "false");
749    }), itemToSelect.setAttribute("aria-selected", "true"), this.selectElement.querySelectorAll("option").forEach((singleOption) => {
750      singleOption.value === itemToSelect.dataset.value ? singleOption.setAttribute("selected", "selected") : singleOption.removeAttribute("selected", "selected");
751    }), this.closeAvailableItems(), this.inputElement.value = itemToSelect.dataset.label;
752  }
753  #selectAvailableItemMultiple(itemToSelect) {
754    if (!this.#isElementAnAvailableItem(itemToSelect))
755      throw new Error("Element is not an available item");
756    itemToSelect.setAttribute("aria-selected", "true"), this.selectElement.querySelectorAll("option").forEach((singleOption) => {
757      singleOption.value === itemToSelect.dataset.value && singleOption.setAttribute("selected", "selected");
758    }), this.#appendNewSelectedItem(itemToSelect);
759  }
760  /**
761   * Handles the functionality of de-selecting an available item
762   * @param { HTMLLIElement } itemToRemove The available item to de-select
763   */
764  #removeAvailableItem(itemToRemove) {
765    if (!this.#isElementAnAvailableItem(itemToRemove))
766      throw new Error("Element is not an available item");
767    itemToRemove.setAttribute("aria-selected", "false"), this.selectElement.querySelectorAll("option").forEach((singleOption) => {
768      singleOption.value === itemToRemove.dataset.value && singleOption.removeAttribute("selected");
769    }), this.multiple ? this.selectedItemsListElement.querySelectorAll(`li[data-elem-id="${itemToRemove.dataset.elemId}"]`).forEach((singleSelectedItem) => {
770      singleSelectedItem.remove();
771    }) : (this.inputElement.value = "", this.#filterAvailableItems());
772  }
773  /**
774   * Handles the functionality of de-selecting a selected item
775   * @param { HTMLLIElement } itemToRemove The selected item to de-select
776   */
777  #removeSelectedItem(itemToRemove) {
778    if (!this.#isElementASelectedItem(itemToRemove))
779      throw new Error("Element is not a selected item");
780    const availableItem = this.availableItemsListElement.querySelector(`li[data-elem-id="${itemToRemove.dataset.elemId}"]`);
781    availableItem.setAttribute("aria-selected", "false"), this.selectElement.querySelectorAll("option").forEach((singleOption) => {
782      singleOption.value === availableItem.dataset.value && singleOption.removeAttribute("selected");
783    }), itemToRemove.remove(), this.selectedItemsListElement.children.length === 0 && (this.selectedItemsListElement.setAttribute("tabindex", "-1"), this.inputElement.focus());
784  }
785  /**
786   * Checks if the element has the class `dcf-search-and-select-available-item`
787   * @param { HTMLElement } elementToCheck The element to check
788   * @returns { bool } true if it does contain that class
789   */
790  #isElementAnAvailableItem(elementToCheck) {
791    return elementToCheck.classList.contains("dcf-search-and-select-available-item");
792  }
793  /**
794   * Checks if the available item is selected
795   * @param { HTMLLIElement } itemToCheck The item to check if it is selected
796   * @returns { bool } true if the item is selected
797   */
798  #isAvailableItemSelected(itemToCheck) {
799    if (!this.#isElementAnAvailableItem(itemToCheck))
800      throw new Error("Element is not an available item");
801    return itemToCheck.getAttribute("aria-selected") === "true";
802  }
803  /**
804   * Checks if the available item is disabled
805   * @param { HTMLLIElement } itemToCheck The item to check if it is disabled
806   * @returns { bool } true if the item is disabled
807   */
808  #isAvailableItemDisabled(itemToCheck) {
809    if (!this.#isElementAnAvailableItem(itemToCheck))
810      throw new Error("Element is not an available item");
811    return itemToCheck.getAttribute("aria-disabled") === "true";
812  }
813  /**
814   * Calculates if the available item is in view
815   * @param { HTMLLIElement } itemToCheck The item to check if it is in view
816   * @returns { bool } true if it is in view
817   */
818  #isAvailableItemInView(itemToCheck) {
819    if (!this.#isElementAnAvailableItem(itemToCheck))
820      throw new Error("Element is not an available item");
821    const listRect = this.availableItemsListElement.getBoundingClientRect(), itemToCheckRect = itemToCheck.getBoundingClientRect();
822    return itemToCheckRect.top >= listRect.top && itemToCheckRect.bottom <= listRect.bottom;
823  }
824  /**
825   * Calculates if the selected item is in view
826   * @param { HTMLLIElement } itemToCheck The item to check if it is in view
827   * @returns { bool } true if it is in view
828   */
829  #isSelectedItemInView(itemToCheck) {
830    if (!this.#isElementASelectedItem(itemToCheck))
831      throw new Error("Element is not a selected item");
832    const listRect = this.searchAreaElement.getBoundingClientRect(), itemToCheckRect = itemToCheck.getBoundingClientRect();
833    return itemToCheckRect.top >= listRect.top && itemToCheckRect.bottom <= listRect.bottom;
834  }
835  /**
836   * Checks if the element has the class `dcf-search-and-select-selected-item`
837   * @param { HTMLElement } elementToCheck The element to check
838   * @returns { bool } true if it does contain that class
839   */
840  #isElementASelectedItem(elementToCheck) {
841    return elementToCheck.classList.contains("dcf-search-and-select-selected-item");
842  }
843  /**
844   * Filters available items and hides any item that does not contain the input value's string
845   */
846  #filterAvailableItems() {
847    const searchTerm = this.inputElement.value.trim().toUpperCase(), allItems = this.availableItemsListElement.querySelectorAll("li.dcf-search-and-select-available-item"), allItemGroups = this.availableItemsListElement.querySelectorAll(".dcf-search-and-select-available-items-group");
848    this.listOfAvailableItems = [], this.availableItemsListElement.querySelectorAll(".dcf-search-and-select-no-results").forEach((singleNoResult) => {
849      singleNoResult.remove();
850    });
851    let noItemsFound = !0;
852    if (allItems.forEach((singleItem) => {
853      const itemLabel = singleItem.querySelector(".dcf-search-and-select-available-item-label").innerText.toUpperCase();
854      searchTerm === "" || itemLabel.includes(searchTerm) ? (singleItem.classList.remove("dcf-d-none"), singleItem.classList.add("dcf-d-flex"), this.listOfAvailableItems.push(singleItem), noItemsFound = !1) : (singleItem.classList.add("dcf-d-none"), singleItem.classList.remove("dcf-d-flex"));
855    }), allItemGroups.forEach((singleGroup) => {
856      singleGroup.querySelectorAll(".dcf-search-and-select-available-item:not(.dcf-d-none)").length === 0 ? singleGroup.classList.add("dcf-d-none") : singleGroup.classList.remove("dcf-d-none");
857    }), noItemsFound) {
858      const noItemsFoundElement = document.createElement("ul");
859      noItemsFoundElement.setAttribute("role", "presentation"), noItemsFoundElement.classList.add("dcf-search-and-select-no-results", ...this.availableItemsGroupClassList), noItemsFoundElement.innerHTML = `<li
860class="${this.availableItemsNoResultsClassList.join(" ")}" role="option">
861    No results found
862</li>`, this.availableItemsListElement.append(noItemsFoundElement);
863    }
864  }
865}
866class UNLSearchSelect extends DCFSearchSelect {
867  static {
868    __name(this, "UNLSearchSelect");
869  }
870  constructor(selectElement, options = {}) {
871    "availableItemsListClassList" in options || (options.availableItemsListClassList = [
872      "dcf-absolute",
873      "dcf-d-none",
874      "dcf-mb-0",
875      "dcf-pl-0",
876      "dcf-w-100%",
877      "dcf-z-2",
878      "unl-box-shadow"
879    ]), "selectedItemButtonClassList" in options || (options.selectedItemButtonClassList = [
880      "dcf-btn",
881      "dcf-btn-secondary",
882      "dcf-h-100%",
883      "dcf-p-3",
884      "dcf-z-1"
885    ]), super(selectElement, options), window.UNL = window.UNL || {}, window.UNL.classes = window.UNL.classes || {}, window.UNL.classes[this.selectElement.getAttribute("id")] = this, this.selectElement.dispatchEvent(new Event("UNLClassReady"));
886  }
887}
888export {
889  UNLSearchSelect as default
890};
891//# sourceMappingURL=component.search-select.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.