From b2744504d30d2cfef1e0a06c92cde2218e0035f6 Mon Sep 17 00:00:00 2001
From: Thomas <thomas@lekoala.be>
Date: Mon, 15 Nov 2021 11:09:52 +0100
Subject: [PATCH] accessibility features

---
 readme.md       |  7 +++++++
 tags.js         | 15 ++++++++++-----
 tags.min.js     |  2 +-
 tags.min.js.map |  4 ++--
 4 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/readme.md b/readme.md
index 7389f31..429db65 100644
--- a/readme.md
+++ b/readme.md
@@ -12,6 +12,7 @@ No additional CSS needed! Supports creation of new tags.
 ```js
 import Tags from "./tags.js";
 Tags.init();
+// Tags.init(selector, opts);
 ```
 
 By default, only provided options are available. Validation error
@@ -57,6 +58,12 @@ Use attribute `data-suggestions-threshold` to determine how many characters need
 
 *NOTE: don't forget the [] if you need multiple values!*
 
+## Accessibility
+
+You can set accessibility labels when passing options:
+- clearLabel ("Clear" by default)
+- searchLabel ("Type a value" by default)
+
 ## Tips
 
 - Use arrow down to show dropdown (and arrow up to hide it)
diff --git a/tags.js b/tags.js
index 296a47a..370f6bb 100644
--- a/tags.js
+++ b/tags.js
@@ -18,8 +18,9 @@ const VALUE_ATTRIBUTE = "data-value";
 class Tags {
   /**
    * @param {HTMLSelectElement} selectElement
+   * @param {Object} opts
    */
-  constructor(selectElement) {
+  constructor(selectElement, opts = {}) {
     this.selectElement = selectElement;
     this.selectElement.style.display = "none";
     this.placeholder = this.getPlaceholder();
@@ -28,6 +29,8 @@ class Tags {
     this.allowClear = selectElement.dataset.allowClear ? true : false;
     this.suggestionsThreshold = selectElement.dataset.suggestionsThreshold ? parseInt(selectElement.dataset.suggestionsThreshold) : 1;
     this.keyboardNavigation = false;
+    this.clearLabel = opts.clearLabel ?? "Clear";
+    this.searchLabel = opts.searchLabel ?? "Type a value";
 
     // Create elements
     this.holderElement = document.createElement("div");
@@ -52,12 +55,13 @@ class Tags {
   /**
    * Attach to all elements matched by the selector
    * @param {string} selector
+   * @param {Object} opts
    */
-  static init(selector = "select[multiple]") {
+  static init(selector = "select[multiple]", opts = {}) {
     let list = document.querySelectorAll(selector);
     for (let i = 0; i < list.length; i++) {
       let el = list[i];
-      let inst = new Tags(el);
+      let inst = new Tags(el, opts);
     }
   }
 
@@ -119,10 +123,11 @@ class Tags {
   configureSearchInput() {
     let self = this;
     this.searchInput.type = "text";
-    this.searchInput.autocomplete = false;
+    this.searchInput.autocomplete = "off";
     this.searchInput.style.border = 0;
     this.searchInput.style.outline = 0;
     this.searchInput.style.maxWidth = "100%";
+    this.searchInput.ariaLabel = this.searchLabel;
 
     this.adjustWidth();
 
@@ -457,7 +462,7 @@ class Tags {
     span.setAttribute(VALUE_ATTRIBUTE, value);
 
     if (this.allowClear) {
-      html = '<span class="me-2" style="font-size:0.65em"><button type="button" class="btn-close btn-close-white"></button></span>' + html;
+      html = '<span class="me-2" style="font-size:0.65em"><button type="button" class="btn-close btn-close-white" aria-label="' + this.clearLabel + '"></button></span>' + html;
     }
 
     span.innerHTML = html;
diff --git a/tags.min.js b/tags.min.js
index a5b06d5..c74743d 100644
--- a/tags.min.js
+++ b/tags.min.js
@@ -1,2 +1,2 @@
-var m="is-active",o=["is-active","bg-primary","text-white"],a="data-value",c=class{constructor(t){this.selectElement=t,this.selectElement.style.display="none",this.placeholder=this.getPlaceholder(),this.allowNew=!!t.dataset.allowNew,this.showAllSuggestions=!!t.dataset.showAllSuggestions,this.allowClear=!!t.dataset.allowClear,this.suggestionsThreshold=t.dataset.suggestionsThreshold?parseInt(t.dataset.suggestionsThreshold):1,this.keyboardNavigation=!1,this.holderElement=document.createElement("div"),this.containerElement=document.createElement("div"),this.dropElement=document.createElement("ul"),this.searchInput=document.createElement("input"),this.holderElement.appendChild(this.containerElement),this.containerElement.appendChild(this.searchInput),this.holderElement.appendChild(this.dropElement),this.selectElement.parentNode.insertBefore(this.holderElement,this.selectElement.nextSibling),this.configureSearchInput(),this.configureHolderElement(),this.configureDropElement(),this.configureContainerElement(),this.buildSuggestions()}static init(t="select[multiple]"){let e=document.querySelectorAll(t);for(let l=0;l<e.length;l++){let i=e[l],s=new c(i)}}getPlaceholder(){let t=this.selectElement.querySelector("option");if(!!t){if(!t.value){let e=t.innerText;return t.remove(),e}return this.selectElement.getAttribute("placeholder")?this.selectElement.getAttribute("placeholder"):this.selectElement.getAttribute("data-placeholder")?this.selectElement.getAttribute("data-placeholder"):""}}configureDropElement(){this.dropElement.classList.add("dropdown-menu"),this.dropElement.classList.add("p-0"),this.dropElement.style.maxHeight="280px",this.dropElement.style.overflowY="auto",this.dropElement.addEventListener("mouseenter",t=>{this.keyboardNavigation=!1})}configureHolderElement(){this.holderElement.classList.add("form-control"),this.holderElement.classList.add("dropdown")}configureContainerElement(){this.containerElement.addEventListener("click",e=>{this.searchInput.focus()});let t=this.selectElement.querySelectorAll("option[selected]");for(let e=0;e<t.length;e++){let l=t[e];!l.value||this.addItem(l.innerText,l.value)}}configureSearchInput(){let t=this;this.searchInput.type="text",this.searchInput.autocomplete=!1,this.searchInput.style.border=0,this.searchInput.style.outline=0,this.searchInput.style.maxWidth="100%",this.adjustWidth(),this.searchInput.addEventListener("input",e=>{this.adjustWidth(),this.searchInput.value.length>=this.suggestionsThreshold?this.showSuggestions():this.hideSuggestions()}),this.searchInput.addEventListener("focus",e=>{this.searchInput.value.length>=this.suggestionsThreshold&&this.showSuggestions()}),this.searchInput.addEventListener("focusout",e=>{setTimeout(function(){t.hideSuggestions()},100)}),this.searchInput.addEventListener("keydown",e=>{switch(e.keyCode||e.key){case 13:case"Enter":let i=this.getActiveSelection();i?(this.addItem(i.innerText,i.getAttribute(a)),this.resetSearchInput(),this.hideSuggestions(),this.removeActiveSelection()):this.allowNew&&this.addItem(this.searchInput.value,null,!0)&&(this.resetSearchInput(),this.hideSuggestions()),e.preventDefault();break;case 38:case"ArrowUp":e.preventDefault(),this.keyboardNavigation=!0;let s=this.moveSelectionUp();this.searchInput.value.length==0&&this.dropElement.classList.contains("show")&&!s&&this.hideSuggestions();break;case 40:case"ArrowDown":e.preventDefault(),this.keyboardNavigation=!0,this.moveSelectionDown(),this.searchInput.value.length==0&&!this.dropElement.classList.contains("show")&&this.showSuggestions();break;case 8:case"Backspace":this.searchInput.value.length==0&&(this.removeLastItem(),this.adjustWidth(),this.hideSuggestions());break}})}moveSelectionUp(){let t=this.getActiveSelection();if(t){let e=t.parentNode;do e=e.previousSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...o),e.querySelector("a").classList.add(...o),e.parentNode.scrollTop=e.offsetTop-e.parentNode.offsetTop,e):null}return null}moveSelectionDown(){let t=this.getActiveSelection();if(t){let e=t.parentNode;do e=e.nextSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...o),e.querySelector("a").classList.add(...o),e.offsetTop>e.parentNode.offsetHeight-e.offsetHeight&&(e.parentNode.scrollTop+=e.offsetHeight),e):null}return null}adjustWidth(){this.searchInput.value?this.searchInput.size=this.searchInput.value.length+1:this.getSelectedValues().length?(this.searchInput.placeholder="",this.searchInput.size=1):(this.searchInput.size=this.placeholder.length,this.searchInput.placeholder=this.placeholder)}buildSuggestions(){let t=this.selectElement.querySelectorAll("option");for(let e=0;e<t.length;e++){let l=t[e];if(!l.getAttribute("value"))continue;let i=document.createElement("li"),s=document.createElement("a");i.append(s),s.classList.add("dropdown-item"),s.setAttribute(a,l.getAttribute("value")),s.setAttribute("href","#"),s.innerText=l.innerText,this.dropElement.appendChild(i),s.addEventListener("mouseenter",n=>{this.keyboardNavigation||(this.removeActiveSelection(),i.querySelector("a").classList.add(...o))}),s.addEventListener("mousemove",n=>{this.keyboardNavigation=!1}),s.addEventListener("click",n=>{n.preventDefault(),this.addItem(s.innerText,s.getAttribute(a)),this.resetSearchInput(),this.hideSuggestions()})}}resetSearchInput(){this.searchInput.value="",this.adjustWidth()}getSelectedValues(){let t=this.selectElement.querySelectorAll("option:checked");return Array.from(t).map(e=>e.value)}showSuggestions(){this.dropElement.classList.contains("show")||this.dropElement.classList.add("show"),this.dropElement.style.left=this.searchInput.offsetLeft+"px";let t=this.searchInput.value.toLocaleLowerCase(),e=this.getSelectedValues(),l=this.dropElement.querySelectorAll("li"),i=!1,s=null,n=!1;for(let r=0;r<l.length;r++){let h=l[r],p=h.innerText.toLocaleLowerCase(),d=h.querySelector("a");if(d.classList.remove(...o),e.indexOf(d.getAttribute(a))!=-1){h.style.display="none";continue}n=!0;let u=t.length===0||p.indexOf(t)!==-1;this.showAllSuggestions||this.suggestionsThreshold===0||u?(h.style.display="list-item",i=!0,!s&&u&&(s=h)):h.style.display="none"}i||this.dropElement.classList.remove("show"),s?(this.holderElement.classList.contains("is-invalid")&&this.holderElement.classList.remove("is-invalid"),s.querySelector("a").classList.add(...o),s.parentNode.scrollTop=s.offsetTop-s.parentNode.offsetTop):!this.allowNew&&!(t.length===0&&!n)&&this.holderElement.classList.add("is-invalid")}hideSuggestions(){this.dropElement.classList.contains("show")&&this.dropElement.classList.remove("show"),this.holderElement.classList.contains("is-invalid")&&this.holderElement.classList.remove("is-invalid")}getActiveSelection(){return this.dropElement.querySelector("a."+m)}removeActiveSelection(){let t=this.getActiveSelection();t&&t.classList.remove(...o)}removeLastItem(){let t=this.containerElement.querySelectorAll("span");if(!t.length)return;let e=t[t.length-1];this.removeItem(e.getAttribute(a))}addItem(t,e,l=!1){e||(e=t);let i=this.selectElement.querySelector('option[value="'+e+'"]');if(i||(i=Array.from(this.selectElement.querySelectorAll("option")).find(r=>r.textContent==t)),l&&i&&i.getAttribute("selected"))return!1;let s=t,n=document.createElement("span");return n.classList.add("badge"),n.classList.add("bg-primary"),n.classList.add("me-2"),n.setAttribute(a,e),this.allowClear&&(s='<span class="me-2" style="font-size:0.65em"><button type="button" class="btn-close btn-close-white"></button></span>'+s),n.innerHTML=s,this.containerElement.insertBefore(n,this.searchInput),this.allowClear&&n.querySelector("button").addEventListener("click",r=>{r.preventDefault(),r.stopPropagation(),this.removeItem(e),document.activeElement.blur()}),i?i.setAttribute("selected","selected"):(i=document.createElement("option"),i.value=e,i.innerText=t,i.setAttribute("selected","selected"),this.selectElement.appendChild(i)),!0}removeItem(t){let e=this.containerElement.querySelector("span["+a+'="'+t+'"]');if(!e)return;e.remove();let l=this.selectElement.querySelector('option[value="'+t+'"]');l&&l.removeAttribute("selected")}},f=c;export{f as default};
+var m="is-active",o=["is-active","bg-primary","text-white"],a="data-value",c=class{constructor(t,e={}){this.selectElement=t,this.selectElement.style.display="none",this.placeholder=this.getPlaceholder(),this.allowNew=!!t.dataset.allowNew,this.showAllSuggestions=!!t.dataset.showAllSuggestions,this.allowClear=!!t.dataset.allowClear,this.suggestionsThreshold=t.dataset.suggestionsThreshold?parseInt(t.dataset.suggestionsThreshold):1,this.keyboardNavigation=!1,this.clearLabel=e.clearLabel??"Clear",this.searchLabel=e.searchLabel??"Type a value",this.holderElement=document.createElement("div"),this.containerElement=document.createElement("div"),this.dropElement=document.createElement("ul"),this.searchInput=document.createElement("input"),this.holderElement.appendChild(this.containerElement),this.containerElement.appendChild(this.searchInput),this.holderElement.appendChild(this.dropElement),this.selectElement.parentNode.insertBefore(this.holderElement,this.selectElement.nextSibling),this.configureSearchInput(),this.configureHolderElement(),this.configureDropElement(),this.configureContainerElement(),this.buildSuggestions()}static init(t="select[multiple]",e={}){let l=document.querySelectorAll(t);for(let s=0;s<l.length;s++){let i=l[s],n=new c(i,e)}}getPlaceholder(){let t=this.selectElement.querySelector("option");if(!!t){if(!t.value){let e=t.innerText;return t.remove(),e}return this.selectElement.getAttribute("placeholder")?this.selectElement.getAttribute("placeholder"):this.selectElement.getAttribute("data-placeholder")?this.selectElement.getAttribute("data-placeholder"):""}}configureDropElement(){this.dropElement.classList.add("dropdown-menu"),this.dropElement.classList.add("p-0"),this.dropElement.style.maxHeight="280px",this.dropElement.style.overflowY="auto",this.dropElement.addEventListener("mouseenter",t=>{this.keyboardNavigation=!1})}configureHolderElement(){this.holderElement.classList.add("form-control"),this.holderElement.classList.add("dropdown")}configureContainerElement(){this.containerElement.addEventListener("click",e=>{this.searchInput.focus()});let t=this.selectElement.querySelectorAll("option[selected]");for(let e=0;e<t.length;e++){let l=t[e];!l.value||this.addItem(l.innerText,l.value)}}configureSearchInput(){let t=this;this.searchInput.type="text",this.searchInput.autocomplete="off",this.searchInput.style.border=0,this.searchInput.style.outline=0,this.searchInput.style.maxWidth="100%",this.searchInput.ariaLabel=this.searchLabel,this.adjustWidth(),this.searchInput.addEventListener("input",e=>{this.adjustWidth(),this.searchInput.value.length>=this.suggestionsThreshold?this.showSuggestions():this.hideSuggestions()}),this.searchInput.addEventListener("focus",e=>{this.searchInput.value.length>=this.suggestionsThreshold&&this.showSuggestions()}),this.searchInput.addEventListener("focusout",e=>{setTimeout(function(){t.hideSuggestions()},100)}),this.searchInput.addEventListener("keydown",e=>{switch(e.keyCode||e.key){case 13:case"Enter":let s=this.getActiveSelection();s?(this.addItem(s.innerText,s.getAttribute(a)),this.resetSearchInput(),this.hideSuggestions(),this.removeActiveSelection()):this.allowNew&&this.addItem(this.searchInput.value,null,!0)&&(this.resetSearchInput(),this.hideSuggestions()),e.preventDefault();break;case 38:case"ArrowUp":e.preventDefault(),this.keyboardNavigation=!0;let i=this.moveSelectionUp();this.searchInput.value.length==0&&this.dropElement.classList.contains("show")&&!i&&this.hideSuggestions();break;case 40:case"ArrowDown":e.preventDefault(),this.keyboardNavigation=!0,this.moveSelectionDown(),this.searchInput.value.length==0&&!this.dropElement.classList.contains("show")&&this.showSuggestions();break;case 8:case"Backspace":this.searchInput.value.length==0&&(this.removeLastItem(),this.adjustWidth(),this.hideSuggestions());break}})}moveSelectionUp(){let t=this.getActiveSelection();if(t){let e=t.parentNode;do e=e.previousSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...o),e.querySelector("a").classList.add(...o),e.parentNode.scrollTop=e.offsetTop-e.parentNode.offsetTop,e):null}return null}moveSelectionDown(){let t=this.getActiveSelection();if(t){let e=t.parentNode;do e=e.nextSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...o),e.querySelector("a").classList.add(...o),e.offsetTop>e.parentNode.offsetHeight-e.offsetHeight&&(e.parentNode.scrollTop+=e.offsetHeight),e):null}return null}adjustWidth(){this.searchInput.value?this.searchInput.size=this.searchInput.value.length+1:this.getSelectedValues().length?(this.searchInput.placeholder="",this.searchInput.size=1):(this.searchInput.size=this.placeholder.length,this.searchInput.placeholder=this.placeholder)}buildSuggestions(){let t=this.selectElement.querySelectorAll("option");for(let e=0;e<t.length;e++){let l=t[e];if(!l.getAttribute("value"))continue;let s=document.createElement("li"),i=document.createElement("a");s.append(i),i.classList.add("dropdown-item"),i.setAttribute(a,l.getAttribute("value")),i.setAttribute("href","#"),i.innerText=l.innerText,this.dropElement.appendChild(s),i.addEventListener("mouseenter",n=>{this.keyboardNavigation||(this.removeActiveSelection(),s.querySelector("a").classList.add(...o))}),i.addEventListener("mousemove",n=>{this.keyboardNavigation=!1}),i.addEventListener("click",n=>{n.preventDefault(),this.addItem(i.innerText,i.getAttribute(a)),this.resetSearchInput(),this.hideSuggestions()})}}resetSearchInput(){this.searchInput.value="",this.adjustWidth()}getSelectedValues(){let t=this.selectElement.querySelectorAll("option:checked");return Array.from(t).map(e=>e.value)}showSuggestions(){this.dropElement.classList.contains("show")||this.dropElement.classList.add("show"),this.dropElement.style.left=this.searchInput.offsetLeft+"px";let t=this.searchInput.value.toLocaleLowerCase(),e=this.getSelectedValues(),l=this.dropElement.querySelectorAll("li"),s=!1,i=null,n=!1;for(let r=0;r<l.length;r++){let h=l[r],p=h.innerText.toLocaleLowerCase(),d=h.querySelector("a");if(d.classList.remove(...o),e.indexOf(d.getAttribute(a))!=-1){h.style.display="none";continue}n=!0;let u=t.length===0||p.indexOf(t)!==-1;this.showAllSuggestions||this.suggestionsThreshold===0||u?(h.style.display="list-item",s=!0,!i&&u&&(i=h)):h.style.display="none"}s||this.dropElement.classList.remove("show"),i?(this.holderElement.classList.contains("is-invalid")&&this.holderElement.classList.remove("is-invalid"),i.querySelector("a").classList.add(...o),i.parentNode.scrollTop=i.offsetTop-i.parentNode.offsetTop):!this.allowNew&&!(t.length===0&&!n)&&this.holderElement.classList.add("is-invalid")}hideSuggestions(){this.dropElement.classList.contains("show")&&this.dropElement.classList.remove("show"),this.holderElement.classList.contains("is-invalid")&&this.holderElement.classList.remove("is-invalid")}getActiveSelection(){return this.dropElement.querySelector("a."+m)}removeActiveSelection(){let t=this.getActiveSelection();t&&t.classList.remove(...o)}removeLastItem(){let t=this.containerElement.querySelectorAll("span");if(!t.length)return;let e=t[t.length-1];this.removeItem(e.getAttribute(a))}addItem(t,e,l=!1){e||(e=t);let s=this.selectElement.querySelector('option[value="'+e+'"]');if(s||(s=Array.from(this.selectElement.querySelectorAll("option")).find(r=>r.textContent==t)),l&&s&&s.getAttribute("selected"))return!1;let i=t,n=document.createElement("span");return n.classList.add("badge"),n.classList.add("bg-primary"),n.classList.add("me-2"),n.setAttribute(a,e),this.allowClear&&(i='<span class="me-2" style="font-size:0.65em"><button type="button" class="btn-close btn-close-white" aria-label="'+this.clearLabel+'"></button></span>'+i),n.innerHTML=i,this.containerElement.insertBefore(n,this.searchInput),this.allowClear&&n.querySelector("button").addEventListener("click",r=>{r.preventDefault(),r.stopPropagation(),this.removeItem(e),document.activeElement.blur()}),s?s.setAttribute("selected","selected"):(s=document.createElement("option"),s.value=e,s.innerText=t,s.setAttribute("selected","selected"),this.selectElement.appendChild(s)),!0}removeItem(t){let e=this.containerElement.querySelector("span["+a+'="'+t+'"]');if(!e)return;e.remove();let l=this.selectElement.querySelector('option[value="'+t+'"]');l&&l.removeAttribute("selected")}},f=c;export{f as default};
 //# sourceMappingURL=tags.min.js.map
diff --git a/tags.min.js.map b/tags.min.js.map
index 3258ae8..a7ec26c 100644
--- a/tags.min.js.map
+++ b/tags.min.js.map
@@ -1,7 +1,7 @@
 {
   "version": 3,
   "sources": ["tags.js"],
-  "sourcesContent": ["/**\r\n * Bootstrap 5 tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\nclass Tags {\r\n  /**\r\n   * @param {HTMLSelectElement} selectElement\r\n   */\r\n  constructor(selectElement) {\r\n    this.selectElement = selectElement;\r\n    this.selectElement.style.display = \"none\";\r\n    this.placeholder = this.getPlaceholder();\r\n    this.allowNew = selectElement.dataset.allowNew ? true : false;\r\n    this.showAllSuggestions = selectElement.dataset.showAllSuggestions ? true : false;\r\n    this.allowClear = selectElement.dataset.allowClear ? true : false;\r\n    this.suggestionsThreshold = selectElement.dataset.suggestionsThreshold ? parseInt(selectElement.dataset.suggestionsThreshold) : 1;\r\n    this.keyboardNavigation = false;\r\n\r\n    // Create elements\r\n    this.holderElement = document.createElement(\"div\");\r\n    this.containerElement = document.createElement(\"div\");\r\n    this.dropElement = document.createElement(\"ul\");\r\n    this.searchInput = document.createElement(\"input\");\r\n\r\n    this.holderElement.appendChild(this.containerElement);\r\n    this.containerElement.appendChild(this.searchInput);\r\n    this.holderElement.appendChild(this.dropElement);\r\n    // insert after\r\n    this.selectElement.parentNode.insertBefore(this.holderElement, this.selectElement.nextSibling);\r\n\r\n    // Configure them\r\n    this.configureSearchInput();\r\n    this.configureHolderElement();\r\n    this.configureDropElement();\r\n    this.configureContainerElement();\r\n    this.buildSuggestions();\r\n  }\r\n\r\n  /**\r\n   * Attach to all elements matched by the selector\r\n   * @param {string} selector\r\n   */\r\n  static init(selector = \"select[multiple]\") {\r\n    let list = document.querySelectorAll(selector);\r\n    for (let i = 0; i < list.length; i++) {\r\n      let el = list[i];\r\n      let inst = new Tags(el);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @returns {string}\r\n   */\r\n  getPlaceholder() {\r\n    let firstOption = this.selectElement.querySelector(\"option\");\r\n    if (!firstOption) {\r\n      return;\r\n    }\r\n    if (!firstOption.value) {\r\n      let placeholder = firstOption.innerText;\r\n      firstOption.remove();\r\n      return placeholder;\r\n    }\r\n    if (this.selectElement.getAttribute(\"placeholder\")) {\r\n      return this.selectElement.getAttribute(\"placeholder\");\r\n    }\r\n    if (this.selectElement.getAttribute(\"data-placeholder\")) {\r\n      return this.selectElement.getAttribute(\"data-placeholder\");\r\n    }\r\n    return \"\";\r\n  }\r\n\r\n  configureDropElement() {\r\n    this.dropElement.classList.add(\"dropdown-menu\");\r\n    this.dropElement.classList.add(\"p-0\");\r\n    this.dropElement.style.maxHeight = \"280px\";\r\n    this.dropElement.style.overflowY = \"auto\";\r\n\r\n    // If the mouse was outside, entering remove keyboard nav mode\r\n    this.dropElement.addEventListener(\"mouseenter\", (event) => {\r\n      this.keyboardNavigation = false;\r\n    });\r\n  }\r\n\r\n  configureHolderElement() {\r\n    this.holderElement.classList.add(\"form-control\");\r\n    this.holderElement.classList.add(\"dropdown\");\r\n  }\r\n\r\n  configureContainerElement() {\r\n    this.containerElement.addEventListener(\"click\", (event) => {\r\n      this.searchInput.focus();\r\n    });\r\n\r\n    // add initial values\r\n    let initialValues = this.selectElement.querySelectorAll(\"option[selected]\");\r\n    for (let j = 0; j < initialValues.length; j++) {\r\n      let initialValue = initialValues[j];\r\n      if (!initialValue.value) {\r\n        continue;\r\n      }\r\n      this.addItem(initialValue.innerText, initialValue.value);\r\n    }\r\n  }\r\n\r\n  configureSearchInput() {\r\n    let self = this;\r\n    this.searchInput.type = \"text\";\r\n    this.searchInput.autocomplete = false;\r\n    this.searchInput.style.border = 0;\r\n    this.searchInput.style.outline = 0;\r\n    this.searchInput.style.maxWidth = \"100%\";\r\n\r\n    this.adjustWidth();\r\n\r\n    this.searchInput.addEventListener(\"input\", (event) => {\r\n      this.adjustWidth();\r\n      if (this.searchInput.value.length >= this.suggestionsThreshold) {\r\n        this.showSuggestions();\r\n      } else {\r\n        this.hideSuggestions();\r\n      }\r\n    });\r\n    this.searchInput.addEventListener(\"focus\", (event) => {\r\n      if (this.searchInput.value.length >= this.suggestionsThreshold) {\r\n        this.showSuggestions();\r\n      }\r\n    });\r\n    this.searchInput.addEventListener(\"focusout\", (event) => {\r\n      setTimeout(function () {\r\n        self.hideSuggestions();\r\n      }, 100);\r\n    });\r\n    // keypress doesn't send arrow keys\r\n    this.searchInput.addEventListener(\"keydown\", (event) => {\r\n      // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n      let key = event.keyCode || event.key;\r\n      switch (key) {\r\n        case 13:\r\n        case \"Enter\":\r\n          let selection = this.getActiveSelection();\r\n          if (selection) {\r\n            this.addItem(selection.innerText, selection.getAttribute(VALUE_ATTRIBUTE));\r\n            this.resetSearchInput();\r\n            this.hideSuggestions();\r\n            this.removeActiveSelection();\r\n          } else {\r\n            // We use what is typed\r\n            if (this.allowNew) {\r\n              let res = this.addItem(this.searchInput.value, null, true);\r\n              if (res) {\r\n                this.resetSearchInput();\r\n                this.hideSuggestions();\r\n              }\r\n            }\r\n          }\r\n          event.preventDefault();\r\n          break;\r\n        case 38:\r\n        case \"ArrowUp\":\r\n          event.preventDefault();\r\n          this.keyboardNavigation = true;\r\n          let newSelection = this.moveSelectionUp();\r\n          // If we use arrow up without input and there is no new selection, hide suggestions\r\n          if (this.searchInput.value.length == 0 && this.dropElement.classList.contains(\"show\") && !newSelection) {\r\n            this.hideSuggestions();\r\n          }\r\n          break;\r\n        case 40:\r\n        case \"ArrowDown\":\r\n          event.preventDefault();\r\n          this.keyboardNavigation = true;\r\n          this.moveSelectionDown();\r\n          // If we use arrow down without input, show suggestions\r\n          if (this.searchInput.value.length == 0 && !this.dropElement.classList.contains(\"show\")) {\r\n            this.showSuggestions();\r\n          }\r\n          break;\r\n        case 8:\r\n        case \"Backspace\":\r\n          if (this.searchInput.value.length == 0) {\r\n            this.removeLastItem();\r\n            this.adjustWidth();\r\n            this.hideSuggestions();\r\n          }\r\n          break;\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * @returns {HTMLElement}\r\n   */\r\n  moveSelectionUp() {\r\n    let active = this.getActiveSelection();\r\n    if (active) {\r\n      let prev = active.parentNode;\r\n      do {\r\n        prev = prev.previousSibling;\r\n      } while (prev && prev.style.display == \"none\");\r\n      if (!prev) {\r\n        return null;\r\n      }\r\n      active.classList.remove(...ACTIVE_CLASSES);\r\n      prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      // Don't use scrollIntoView as it scrolls the whole window\r\n      prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n      return prev;\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * @returns {HTMLElement}\r\n   */\r\n  moveSelectionDown() {\r\n    let active = this.getActiveSelection();\r\n    if (active) {\r\n      let next = active.parentNode;\r\n      do {\r\n        next = next.nextSibling;\r\n      } while (next && next.style.display == \"none\");\r\n      if (!next) {\r\n        return null;\r\n      }\r\n      active.classList.remove(...ACTIVE_CLASSES);\r\n      next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      // This is the equivalent of scrollIntoView(false) but only for parent node\r\n      if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n        next.parentNode.scrollTop += next.offsetHeight;\r\n      }\r\n      return next;\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Adjust the field to fit its content\r\n   */\r\n  adjustWidth() {\r\n    if (this.searchInput.value) {\r\n      this.searchInput.size = this.searchInput.value.length + 1;\r\n    } else {\r\n      // Show the placeholder only if empty\r\n      if (this.getSelectedValues().length) {\r\n        this.searchInput.placeholder = \"\";\r\n        this.searchInput.size = 1;\r\n      } else {\r\n        this.searchInput.size = this.placeholder.length;\r\n        this.searchInput.placeholder = this.placeholder;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Add suggestions from element\r\n   */\r\n  buildSuggestions() {\r\n    let options = this.selectElement.querySelectorAll(\"option\");\r\n    for (let i = 0; i < options.length; i++) {\r\n      let opt = options[i];\r\n      if (!opt.getAttribute(\"value\")) {\r\n        continue;\r\n      }\r\n      let newChild = document.createElement(\"li\");\r\n      let newChildLink = document.createElement(\"a\");\r\n      newChild.append(newChildLink);\r\n      newChildLink.classList.add(\"dropdown-item\");\r\n      newChildLink.setAttribute(VALUE_ATTRIBUTE, opt.getAttribute(\"value\"));\r\n      newChildLink.setAttribute(\"href\", \"#\");\r\n      newChildLink.innerText = opt.innerText;\r\n      this.dropElement.appendChild(newChild);\r\n\r\n      // Hover sets active item\r\n      newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n        // Don't trigger enter if using arrows\r\n        if (this.keyboardNavigation) {\r\n          return;\r\n        }\r\n        this.removeActiveSelection();\r\n        newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      });\r\n      // Moving the mouse means no longer using keyboard\r\n      newChildLink.addEventListener(\"mousemove\", (event) => {\r\n        this.keyboardNavigation = false;\r\n      });\r\n\r\n      newChildLink.addEventListener(\"click\", (event) => {\r\n        event.preventDefault();\r\n        this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE));\r\n        this.resetSearchInput();\r\n        this.hideSuggestions();\r\n      });\r\n    }\r\n  }\r\n\r\n  resetSearchInput() {\r\n    this.searchInput.value = \"\";\r\n    this.adjustWidth();\r\n  }\r\n\r\n  /**\r\n   * @returns {array}\r\n   */\r\n  getSelectedValues() {\r\n    let selected = this.selectElement.querySelectorAll(\"option:checked\");\r\n    return Array.from(selected).map((el) => el.value);\r\n  }\r\n\r\n  /**\r\n   * The element create with buildSuggestions\r\n   */\r\n  showSuggestions() {\r\n    if (!this.dropElement.classList.contains(\"show\")) {\r\n      this.dropElement.classList.add(\"show\");\r\n    }\r\n\r\n    // Position next to search input\r\n    this.dropElement.style.left = this.searchInput.offsetLeft + \"px\";\r\n\r\n    // Get search value\r\n    let search = this.searchInput.value.toLocaleLowerCase();\r\n\r\n    // Get current values\r\n    let values = this.getSelectedValues();\r\n\r\n    // Filter the list according to search string\r\n    let list = this.dropElement.querySelectorAll(\"li\");\r\n    let found = false;\r\n    let firstItem = null;\r\n    let hasPossibleValues = false;\r\n    for (let i = 0; i < list.length; i++) {\r\n      let item = list[i];\r\n      let text = item.innerText.toLocaleLowerCase();\r\n      let link = item.querySelector(\"a\");\r\n\r\n      // Remove previous selection\r\n      link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n      // Hide selected values\r\n      if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n        item.style.display = \"none\";\r\n        continue;\r\n      }\r\n\r\n      hasPossibleValues = true;\r\n\r\n      // Check search length since we can trigger dropdown with arrow\r\n      let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n      if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n        item.style.display = \"list-item\";\r\n        found = true;\r\n        if (!firstItem && isMatched) {\r\n          firstItem = item;\r\n        }\r\n      } else {\r\n        item.style.display = \"none\";\r\n      }\r\n    }\r\n\r\n    // Special case if nothing matches\r\n    if (!found) {\r\n      this.dropElement.classList.remove(\"show\");\r\n    }\r\n\r\n    // Always select first item\r\n    if (firstItem) {\r\n      if (this.holderElement.classList.contains(\"is-invalid\")) {\r\n        this.holderElement.classList.remove(\"is-invalid\");\r\n      }\r\n      firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n    } else {\r\n      // No item and we don't allow new items => error\r\n      if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n        this.holderElement.classList.add(\"is-invalid\");\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * The element create with buildSuggestions\r\n   */\r\n  hideSuggestions() {\r\n    if (this.dropElement.classList.contains(\"show\")) {\r\n      this.dropElement.classList.remove(\"show\");\r\n    }\r\n    if (this.holderElement.classList.contains(\"is-invalid\")) {\r\n      this.holderElement.classList.remove(\"is-invalid\");\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @returns {HTMLElement}\r\n   */\r\n  getActiveSelection() {\r\n    return this.dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n  }\r\n\r\n  removeActiveSelection() {\r\n    let selection = this.getActiveSelection();\r\n    if (selection) {\r\n      selection.classList.remove(...ACTIVE_CLASSES);\r\n    }\r\n  }\r\n\r\n  removeLastItem() {\r\n    let items = this.containerElement.querySelectorAll(\"span\");\r\n    if (!items.length) {\r\n      return;\r\n    }\r\n    let lastItem = items[items.length - 1];\r\n    this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n  }\r\n\r\n  /**\r\n   * @param {string} text\r\n   * @param {string} value\r\n   * @param {boolean} checkSelected\r\n   * @return {boolean}\r\n   */\r\n  addItem(text, value, checkSelected = false) {\r\n    if (!value) {\r\n      value = text;\r\n    }\r\n\r\n    // Find by label and value\r\n    let opt = this.selectElement.querySelector('option[value=\"' + value + '\"]');\r\n    if (!opt) {\r\n      opt = Array.from(this.selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n    }\r\n    if (checkSelected) {\r\n      if (opt && opt.getAttribute(\"selected\")) {\r\n        return false;\r\n      }\r\n    }\r\n\r\n    // create span\r\n    let html = text;\r\n    let span = document.createElement(\"span\");\r\n    span.classList.add(\"badge\");\r\n    span.classList.add(\"bg-primary\");\r\n    span.classList.add(\"me-2\");\r\n    span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n    if (this.allowClear) {\r\n      html = '<span class=\"me-2\" style=\"font-size:0.65em\"><button type=\"button\" class=\"btn-close btn-close-white\"></button></span>' + html;\r\n    }\r\n\r\n    span.innerHTML = html;\r\n    this.containerElement.insertBefore(span, this.searchInput);\r\n\r\n    if (this.allowClear) {\r\n      span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n        event.preventDefault();\r\n        event.stopPropagation();\r\n        this.removeItem(value);\r\n        document.activeElement.blur();\r\n      });\r\n    }\r\n\r\n    // update select\r\n    if (opt) {\r\n      opt.setAttribute(\"selected\", \"selected\");\r\n    } else {\r\n      // we need to create a new option\r\n      opt = document.createElement(\"option\");\r\n      opt.value = value;\r\n      opt.innerText = text;\r\n      opt.setAttribute(\"selected\", \"selected\");\r\n      this.selectElement.appendChild(opt);\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * @param {string} value\r\n   */\r\n  removeItem(value) {\r\n    let item = this.containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n    if (!item) {\r\n      return;\r\n    }\r\n    item.remove();\r\n\r\n    // update select\r\n    let opt = this.selectElement.querySelector('option[value=\"' + value + '\"]');\r\n    if (opt) {\r\n      opt.removeAttribute(\"selected\");\r\n    }\r\n  }\r\n}\r\n\r\nexport default Tags;\r\n"],
-  "mappings": "AAaA,GAAM,GAAe,YACf,EAAiB,CAAC,YAAa,aAAc,cAC7C,EAAkB,aAExB,OAAW,CAIT,YAAY,EAAe,CACzB,KAAK,cAAgB,EACrB,KAAK,cAAc,MAAM,QAAU,OACnC,KAAK,YAAc,KAAK,iBACxB,KAAK,SAAW,IAAc,QAAQ,SACtC,KAAK,mBAAqB,IAAc,QAAQ,mBAChD,KAAK,WAAa,IAAc,QAAQ,WACxC,KAAK,qBAAuB,EAAc,QAAQ,qBAAuB,SAAS,EAAc,QAAQ,sBAAwB,EAChI,KAAK,mBAAqB,GAG1B,KAAK,cAAgB,SAAS,cAAc,OAC5C,KAAK,iBAAmB,SAAS,cAAc,OAC/C,KAAK,YAAc,SAAS,cAAc,MAC1C,KAAK,YAAc,SAAS,cAAc,SAE1C,KAAK,cAAc,YAAY,KAAK,kBACpC,KAAK,iBAAiB,YAAY,KAAK,aACvC,KAAK,cAAc,YAAY,KAAK,aAEpC,KAAK,cAAc,WAAW,aAAa,KAAK,cAAe,KAAK,cAAc,aAGlF,KAAK,uBACL,KAAK,yBACL,KAAK,uBACL,KAAK,4BACL,KAAK,yBAOA,MAAK,EAAW,mBAAoB,CACzC,GAAI,GAAO,SAAS,iBAAiB,GACrC,OAAS,GAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,GAAI,GAAK,EAAK,GACV,EAAO,GAAI,GAAK,IAOxB,gBAAiB,CACf,GAAI,GAAc,KAAK,cAAc,cAAc,UACnD,GAAI,EAAC,EAGL,IAAI,CAAC,EAAY,MAAO,CACtB,GAAI,GAAc,EAAY,UAC9B,SAAY,SACL,EAET,MAAI,MAAK,cAAc,aAAa,eAC3B,KAAK,cAAc,aAAa,eAErC,KAAK,cAAc,aAAa,oBAC3B,KAAK,cAAc,aAAa,oBAElC,IAGT,sBAAuB,CACrB,KAAK,YAAY,UAAU,IAAI,iBAC/B,KAAK,YAAY,UAAU,IAAI,OAC/B,KAAK,YAAY,MAAM,UAAY,QACnC,KAAK,YAAY,MAAM,UAAY,OAGnC,KAAK,YAAY,iBAAiB,aAAc,AAAC,GAAU,CACzD,KAAK,mBAAqB,KAI9B,wBAAyB,CACvB,KAAK,cAAc,UAAU,IAAI,gBACjC,KAAK,cAAc,UAAU,IAAI,YAGnC,2BAA4B,CAC1B,KAAK,iBAAiB,iBAAiB,QAAS,AAAC,GAAU,CACzD,KAAK,YAAY,UAInB,GAAI,GAAgB,KAAK,cAAc,iBAAiB,oBACxD,OAAS,GAAI,EAAG,EAAI,EAAc,OAAQ,IAAK,CAC7C,GAAI,GAAe,EAAc,GACjC,AAAI,CAAC,EAAa,OAGlB,KAAK,QAAQ,EAAa,UAAW,EAAa,QAItD,sBAAuB,CACrB,GAAI,GAAO,KACX,KAAK,YAAY,KAAO,OACxB,KAAK,YAAY,aAAe,GAChC,KAAK,YAAY,MAAM,OAAS,EAChC,KAAK,YAAY,MAAM,QAAU,EACjC,KAAK,YAAY,MAAM,SAAW,OAElC,KAAK,cAEL,KAAK,YAAY,iBAAiB,QAAS,AAAC,GAAU,CACpD,KAAK,cACL,AAAI,KAAK,YAAY,MAAM,QAAU,KAAK,qBACxC,KAAK,kBAEL,KAAK,oBAGT,KAAK,YAAY,iBAAiB,QAAS,AAAC,GAAU,CACpD,AAAI,KAAK,YAAY,MAAM,QAAU,KAAK,sBACxC,KAAK,oBAGT,KAAK,YAAY,iBAAiB,WAAY,AAAC,GAAU,CACvD,WAAW,UAAY,CACrB,EAAK,mBACJ,OAGL,KAAK,YAAY,iBAAiB,UAAW,AAAC,GAAU,CAGtD,OADU,EAAM,SAAW,EAAM,SAE1B,QACA,QACH,GAAI,GAAY,KAAK,qBACrB,AAAI,EACF,MAAK,QAAQ,EAAU,UAAW,EAAU,aAAa,IACzD,KAAK,mBACL,KAAK,kBACL,KAAK,yBAGD,KAAK,UACG,KAAK,QAAQ,KAAK,YAAY,MAAO,KAAM,KAEnD,MAAK,mBACL,KAAK,mBAIX,EAAM,iBACN,UACG,QACA,UACH,EAAM,iBACN,KAAK,mBAAqB,GAC1B,GAAI,GAAe,KAAK,kBAExB,AAAI,KAAK,YAAY,MAAM,QAAU,GAAK,KAAK,YAAY,UAAU,SAAS,SAAW,CAAC,GACxF,KAAK,kBAEP,UACG,QACA,YACH,EAAM,iBACN,KAAK,mBAAqB,GAC1B,KAAK,oBAED,KAAK,YAAY,MAAM,QAAU,GAAK,CAAC,KAAK,YAAY,UAAU,SAAS,SAC7E,KAAK,kBAEP,UACG,OACA,YACH,AAAI,KAAK,YAAY,MAAM,QAAU,GACnC,MAAK,iBACL,KAAK,cACL,KAAK,mBAEP,SAQR,iBAAkB,CAChB,GAAI,GAAS,KAAK,qBAClB,GAAI,EAAQ,CACV,GAAI,GAAO,EAAO,WAClB,EACE,GAAO,EAAK,sBACL,GAAQ,EAAK,MAAM,SAAW,QACvC,MAAK,GAGL,GAAO,UAAU,OAAO,GAAG,GAC3B,EAAK,cAAc,KAAK,UAAU,IAAI,GAAG,GAEzC,EAAK,WAAW,UAAY,EAAK,UAAY,EAAK,WAAW,UACtD,GANE,KAQX,MAAO,MAMT,mBAAoB,CAClB,GAAI,GAAS,KAAK,qBAClB,GAAI,EAAQ,CACV,GAAI,GAAO,EAAO,WAClB,EACE,GAAO,EAAK,kBACL,GAAQ,EAAK,MAAM,SAAW,QACvC,MAAK,GAGL,GAAO,UAAU,OAAO,GAAG,GAC3B,EAAK,cAAc,KAAK,UAAU,IAAI,GAAG,GAErC,EAAK,UAAY,EAAK,WAAW,aAAe,EAAK,cACvD,GAAK,WAAW,WAAa,EAAK,cAE7B,GARE,KAUX,MAAO,MAMT,aAAc,CACZ,AAAI,KAAK,YAAY,MACnB,KAAK,YAAY,KAAO,KAAK,YAAY,MAAM,OAAS,EAGxD,AAAI,KAAK,oBAAoB,OAC3B,MAAK,YAAY,YAAc,GAC/B,KAAK,YAAY,KAAO,GAExB,MAAK,YAAY,KAAO,KAAK,YAAY,OACzC,KAAK,YAAY,YAAc,KAAK,aAQ1C,kBAAmB,CACjB,GAAI,GAAU,KAAK,cAAc,iBAAiB,UAClD,OAAS,GAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACvC,GAAI,GAAM,EAAQ,GAClB,GAAI,CAAC,EAAI,aAAa,SACpB,SAEF,GAAI,GAAW,SAAS,cAAc,MAClC,EAAe,SAAS,cAAc,KAC1C,EAAS,OAAO,GAChB,EAAa,UAAU,IAAI,iBAC3B,EAAa,aAAa,EAAiB,EAAI,aAAa,UAC5D,EAAa,aAAa,OAAQ,KAClC,EAAa,UAAY,EAAI,UAC7B,KAAK,YAAY,YAAY,GAG7B,EAAa,iBAAiB,aAAc,AAAC,GAAU,CAErD,AAAI,KAAK,oBAGT,MAAK,wBACL,EAAS,cAAc,KAAK,UAAU,IAAI,GAAG,MAG/C,EAAa,iBAAiB,YAAa,AAAC,GAAU,CACpD,KAAK,mBAAqB,KAG5B,EAAa,iBAAiB,QAAS,AAAC,GAAU,CAChD,EAAM,iBACN,KAAK,QAAQ,EAAa,UAAW,EAAa,aAAa,IAC/D,KAAK,mBACL,KAAK,qBAKX,kBAAmB,CACjB,KAAK,YAAY,MAAQ,GACzB,KAAK,cAMP,mBAAoB,CAClB,GAAI,GAAW,KAAK,cAAc,iBAAiB,kBACnD,MAAO,OAAM,KAAK,GAAU,IAAI,AAAC,GAAO,EAAG,OAM7C,iBAAkB,CAChB,AAAK,KAAK,YAAY,UAAU,SAAS,SACvC,KAAK,YAAY,UAAU,IAAI,QAIjC,KAAK,YAAY,MAAM,KAAO,KAAK,YAAY,WAAa,KAG5D,GAAI,GAAS,KAAK,YAAY,MAAM,oBAGhC,EAAS,KAAK,oBAGd,EAAO,KAAK,YAAY,iBAAiB,MACzC,EAAQ,GACR,EAAY,KACZ,EAAoB,GACxB,OAAS,GAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,GAAI,GAAO,EAAK,GACZ,EAAO,EAAK,UAAU,oBACtB,EAAO,EAAK,cAAc,KAM9B,GAHA,EAAK,UAAU,OAAO,GAAG,GAGrB,EAAO,QAAQ,EAAK,aAAa,KAAqB,GAAI,CAC5D,EAAK,MAAM,QAAU,OACrB,SAGF,EAAoB,GAGpB,GAAI,GAAY,EAAO,SAAW,GAAK,EAAK,QAAQ,KAAY,GAChE,AAAI,KAAK,oBAAsB,KAAK,uBAAyB,GAAK,EAChE,GAAK,MAAM,QAAU,YACrB,EAAQ,GACJ,CAAC,GAAa,GAChB,GAAY,IAGd,EAAK,MAAM,QAAU,OAKzB,AAAK,GACH,KAAK,YAAY,UAAU,OAAO,QAIpC,AAAI,EACE,MAAK,cAAc,UAAU,SAAS,eACxC,KAAK,cAAc,UAAU,OAAO,cAEtC,EAAU,cAAc,KAAK,UAAU,IAAI,GAAG,GAC9C,EAAU,WAAW,UAAY,EAAU,UAAY,EAAU,WAAW,WAGxE,CAAC,KAAK,UAAY,CAAE,GAAO,SAAW,GAAK,CAAC,IAC9C,KAAK,cAAc,UAAU,IAAI,cAQvC,iBAAkB,CAChB,AAAI,KAAK,YAAY,UAAU,SAAS,SACtC,KAAK,YAAY,UAAU,OAAO,QAEhC,KAAK,cAAc,UAAU,SAAS,eACxC,KAAK,cAAc,UAAU,OAAO,cAOxC,oBAAqB,CACnB,MAAO,MAAK,YAAY,cAAc,KAAO,GAG/C,uBAAwB,CACtB,GAAI,GAAY,KAAK,qBACrB,AAAI,GACF,EAAU,UAAU,OAAO,GAAG,GAIlC,gBAAiB,CACf,GAAI,GAAQ,KAAK,iBAAiB,iBAAiB,QACnD,GAAI,CAAC,EAAM,OACT,OAEF,GAAI,GAAW,EAAM,EAAM,OAAS,GACpC,KAAK,WAAW,EAAS,aAAa,IASxC,QAAQ,EAAM,EAAO,EAAgB,GAAO,CAC1C,AAAK,GACH,GAAQ,GAIV,GAAI,GAAM,KAAK,cAAc,cAAc,iBAAmB,EAAQ,MAItE,GAHK,GACH,GAAM,MAAM,KAAK,KAAK,cAAc,iBAAiB,WAAW,KAAK,AAAC,GAAO,EAAG,aAAe,IAE7F,GACE,GAAO,EAAI,aAAa,YAC1B,MAAO,GAKX,GAAI,GAAO,EACP,EAAO,SAAS,cAAc,QAClC,SAAK,UAAU,IAAI,SACnB,EAAK,UAAU,IAAI,cACnB,EAAK,UAAU,IAAI,QACnB,EAAK,aAAa,EAAiB,GAE/B,KAAK,YACP,GAAO,uHAAyH,GAGlI,EAAK,UAAY,EACjB,KAAK,iBAAiB,aAAa,EAAM,KAAK,aAE1C,KAAK,YACP,EAAK,cAAc,UAAU,iBAAiB,QAAS,AAAC,GAAU,CAChE,EAAM,iBACN,EAAM,kBACN,KAAK,WAAW,GAChB,SAAS,cAAc,SAK3B,AAAI,EACF,EAAI,aAAa,WAAY,YAG7B,GAAM,SAAS,cAAc,UAC7B,EAAI,MAAQ,EACZ,EAAI,UAAY,EAChB,EAAI,aAAa,WAAY,YAC7B,KAAK,cAAc,YAAY,IAG1B,GAMT,WAAW,EAAO,CAChB,GAAI,GAAO,KAAK,iBAAiB,cAAc,QAAU,EAAkB,KAAO,EAAQ,MAC1F,GAAI,CAAC,EACH,OAEF,EAAK,SAGL,GAAI,GAAM,KAAK,cAAc,cAAc,iBAAmB,EAAQ,MACtE,AAAI,GACF,EAAI,gBAAgB,cAKnB,EAAQ",
+  "sourcesContent": ["/**\r\n * Bootstrap 5 tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\nclass Tags {\r\n  /**\r\n   * @param {HTMLSelectElement} selectElement\r\n   * @param {Object} opts\r\n   */\r\n  constructor(selectElement, opts = {}) {\r\n    this.selectElement = selectElement;\r\n    this.selectElement.style.display = \"none\";\r\n    this.placeholder = this.getPlaceholder();\r\n    this.allowNew = selectElement.dataset.allowNew ? true : false;\r\n    this.showAllSuggestions = selectElement.dataset.showAllSuggestions ? true : false;\r\n    this.allowClear = selectElement.dataset.allowClear ? true : false;\r\n    this.suggestionsThreshold = selectElement.dataset.suggestionsThreshold ? parseInt(selectElement.dataset.suggestionsThreshold) : 1;\r\n    this.keyboardNavigation = false;\r\n    this.clearLabel = opts.clearLabel ?? \"Clear\";\r\n    this.searchLabel = opts.searchLabel ?? \"Type a value\";\r\n\r\n    // Create elements\r\n    this.holderElement = document.createElement(\"div\");\r\n    this.containerElement = document.createElement(\"div\");\r\n    this.dropElement = document.createElement(\"ul\");\r\n    this.searchInput = document.createElement(\"input\");\r\n\r\n    this.holderElement.appendChild(this.containerElement);\r\n    this.containerElement.appendChild(this.searchInput);\r\n    this.holderElement.appendChild(this.dropElement);\r\n    // insert after\r\n    this.selectElement.parentNode.insertBefore(this.holderElement, this.selectElement.nextSibling);\r\n\r\n    // Configure them\r\n    this.configureSearchInput();\r\n    this.configureHolderElement();\r\n    this.configureDropElement();\r\n    this.configureContainerElement();\r\n    this.buildSuggestions();\r\n  }\r\n\r\n  /**\r\n   * Attach to all elements matched by the selector\r\n   * @param {string} selector\r\n   * @param {Object} opts\r\n   */\r\n  static init(selector = \"select[multiple]\", opts = {}) {\r\n    let list = document.querySelectorAll(selector);\r\n    for (let i = 0; i < list.length; i++) {\r\n      let el = list[i];\r\n      let inst = new Tags(el, opts);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @returns {string}\r\n   */\r\n  getPlaceholder() {\r\n    let firstOption = this.selectElement.querySelector(\"option\");\r\n    if (!firstOption) {\r\n      return;\r\n    }\r\n    if (!firstOption.value) {\r\n      let placeholder = firstOption.innerText;\r\n      firstOption.remove();\r\n      return placeholder;\r\n    }\r\n    if (this.selectElement.getAttribute(\"placeholder\")) {\r\n      return this.selectElement.getAttribute(\"placeholder\");\r\n    }\r\n    if (this.selectElement.getAttribute(\"data-placeholder\")) {\r\n      return this.selectElement.getAttribute(\"data-placeholder\");\r\n    }\r\n    return \"\";\r\n  }\r\n\r\n  configureDropElement() {\r\n    this.dropElement.classList.add(\"dropdown-menu\");\r\n    this.dropElement.classList.add(\"p-0\");\r\n    this.dropElement.style.maxHeight = \"280px\";\r\n    this.dropElement.style.overflowY = \"auto\";\r\n\r\n    // If the mouse was outside, entering remove keyboard nav mode\r\n    this.dropElement.addEventListener(\"mouseenter\", (event) => {\r\n      this.keyboardNavigation = false;\r\n    });\r\n  }\r\n\r\n  configureHolderElement() {\r\n    this.holderElement.classList.add(\"form-control\");\r\n    this.holderElement.classList.add(\"dropdown\");\r\n  }\r\n\r\n  configureContainerElement() {\r\n    this.containerElement.addEventListener(\"click\", (event) => {\r\n      this.searchInput.focus();\r\n    });\r\n\r\n    // add initial values\r\n    let initialValues = this.selectElement.querySelectorAll(\"option[selected]\");\r\n    for (let j = 0; j < initialValues.length; j++) {\r\n      let initialValue = initialValues[j];\r\n      if (!initialValue.value) {\r\n        continue;\r\n      }\r\n      this.addItem(initialValue.innerText, initialValue.value);\r\n    }\r\n  }\r\n\r\n  configureSearchInput() {\r\n    let self = this;\r\n    this.searchInput.type = \"text\";\r\n    this.searchInput.autocomplete = \"off\";\r\n    this.searchInput.style.border = 0;\r\n    this.searchInput.style.outline = 0;\r\n    this.searchInput.style.maxWidth = \"100%\";\r\n    this.searchInput.ariaLabel = this.searchLabel;\r\n\r\n    this.adjustWidth();\r\n\r\n    this.searchInput.addEventListener(\"input\", (event) => {\r\n      this.adjustWidth();\r\n      if (this.searchInput.value.length >= this.suggestionsThreshold) {\r\n        this.showSuggestions();\r\n      } else {\r\n        this.hideSuggestions();\r\n      }\r\n    });\r\n    this.searchInput.addEventListener(\"focus\", (event) => {\r\n      if (this.searchInput.value.length >= this.suggestionsThreshold) {\r\n        this.showSuggestions();\r\n      }\r\n    });\r\n    this.searchInput.addEventListener(\"focusout\", (event) => {\r\n      setTimeout(function () {\r\n        self.hideSuggestions();\r\n      }, 100);\r\n    });\r\n    // keypress doesn't send arrow keys\r\n    this.searchInput.addEventListener(\"keydown\", (event) => {\r\n      // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n      let key = event.keyCode || event.key;\r\n      switch (key) {\r\n        case 13:\r\n        case \"Enter\":\r\n          let selection = this.getActiveSelection();\r\n          if (selection) {\r\n            this.addItem(selection.innerText, selection.getAttribute(VALUE_ATTRIBUTE));\r\n            this.resetSearchInput();\r\n            this.hideSuggestions();\r\n            this.removeActiveSelection();\r\n          } else {\r\n            // We use what is typed\r\n            if (this.allowNew) {\r\n              let res = this.addItem(this.searchInput.value, null, true);\r\n              if (res) {\r\n                this.resetSearchInput();\r\n                this.hideSuggestions();\r\n              }\r\n            }\r\n          }\r\n          event.preventDefault();\r\n          break;\r\n        case 38:\r\n        case \"ArrowUp\":\r\n          event.preventDefault();\r\n          this.keyboardNavigation = true;\r\n          let newSelection = this.moveSelectionUp();\r\n          // If we use arrow up without input and there is no new selection, hide suggestions\r\n          if (this.searchInput.value.length == 0 && this.dropElement.classList.contains(\"show\") && !newSelection) {\r\n            this.hideSuggestions();\r\n          }\r\n          break;\r\n        case 40:\r\n        case \"ArrowDown\":\r\n          event.preventDefault();\r\n          this.keyboardNavigation = true;\r\n          this.moveSelectionDown();\r\n          // If we use arrow down without input, show suggestions\r\n          if (this.searchInput.value.length == 0 && !this.dropElement.classList.contains(\"show\")) {\r\n            this.showSuggestions();\r\n          }\r\n          break;\r\n        case 8:\r\n        case \"Backspace\":\r\n          if (this.searchInput.value.length == 0) {\r\n            this.removeLastItem();\r\n            this.adjustWidth();\r\n            this.hideSuggestions();\r\n          }\r\n          break;\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * @returns {HTMLElement}\r\n   */\r\n  moveSelectionUp() {\r\n    let active = this.getActiveSelection();\r\n    if (active) {\r\n      let prev = active.parentNode;\r\n      do {\r\n        prev = prev.previousSibling;\r\n      } while (prev && prev.style.display == \"none\");\r\n      if (!prev) {\r\n        return null;\r\n      }\r\n      active.classList.remove(...ACTIVE_CLASSES);\r\n      prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      // Don't use scrollIntoView as it scrolls the whole window\r\n      prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n      return prev;\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * @returns {HTMLElement}\r\n   */\r\n  moveSelectionDown() {\r\n    let active = this.getActiveSelection();\r\n    if (active) {\r\n      let next = active.parentNode;\r\n      do {\r\n        next = next.nextSibling;\r\n      } while (next && next.style.display == \"none\");\r\n      if (!next) {\r\n        return null;\r\n      }\r\n      active.classList.remove(...ACTIVE_CLASSES);\r\n      next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      // This is the equivalent of scrollIntoView(false) but only for parent node\r\n      if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n        next.parentNode.scrollTop += next.offsetHeight;\r\n      }\r\n      return next;\r\n    }\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * Adjust the field to fit its content\r\n   */\r\n  adjustWidth() {\r\n    if (this.searchInput.value) {\r\n      this.searchInput.size = this.searchInput.value.length + 1;\r\n    } else {\r\n      // Show the placeholder only if empty\r\n      if (this.getSelectedValues().length) {\r\n        this.searchInput.placeholder = \"\";\r\n        this.searchInput.size = 1;\r\n      } else {\r\n        this.searchInput.size = this.placeholder.length;\r\n        this.searchInput.placeholder = this.placeholder;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Add suggestions from element\r\n   */\r\n  buildSuggestions() {\r\n    let options = this.selectElement.querySelectorAll(\"option\");\r\n    for (let i = 0; i < options.length; i++) {\r\n      let opt = options[i];\r\n      if (!opt.getAttribute(\"value\")) {\r\n        continue;\r\n      }\r\n      let newChild = document.createElement(\"li\");\r\n      let newChildLink = document.createElement(\"a\");\r\n      newChild.append(newChildLink);\r\n      newChildLink.classList.add(\"dropdown-item\");\r\n      newChildLink.setAttribute(VALUE_ATTRIBUTE, opt.getAttribute(\"value\"));\r\n      newChildLink.setAttribute(\"href\", \"#\");\r\n      newChildLink.innerText = opt.innerText;\r\n      this.dropElement.appendChild(newChild);\r\n\r\n      // Hover sets active item\r\n      newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n        // Don't trigger enter if using arrows\r\n        if (this.keyboardNavigation) {\r\n          return;\r\n        }\r\n        this.removeActiveSelection();\r\n        newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      });\r\n      // Moving the mouse means no longer using keyboard\r\n      newChildLink.addEventListener(\"mousemove\", (event) => {\r\n        this.keyboardNavigation = false;\r\n      });\r\n\r\n      newChildLink.addEventListener(\"click\", (event) => {\r\n        event.preventDefault();\r\n        this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE));\r\n        this.resetSearchInput();\r\n        this.hideSuggestions();\r\n      });\r\n    }\r\n  }\r\n\r\n  resetSearchInput() {\r\n    this.searchInput.value = \"\";\r\n    this.adjustWidth();\r\n  }\r\n\r\n  /**\r\n   * @returns {array}\r\n   */\r\n  getSelectedValues() {\r\n    let selected = this.selectElement.querySelectorAll(\"option:checked\");\r\n    return Array.from(selected).map((el) => el.value);\r\n  }\r\n\r\n  /**\r\n   * The element create with buildSuggestions\r\n   */\r\n  showSuggestions() {\r\n    if (!this.dropElement.classList.contains(\"show\")) {\r\n      this.dropElement.classList.add(\"show\");\r\n    }\r\n\r\n    // Position next to search input\r\n    this.dropElement.style.left = this.searchInput.offsetLeft + \"px\";\r\n\r\n    // Get search value\r\n    let search = this.searchInput.value.toLocaleLowerCase();\r\n\r\n    // Get current values\r\n    let values = this.getSelectedValues();\r\n\r\n    // Filter the list according to search string\r\n    let list = this.dropElement.querySelectorAll(\"li\");\r\n    let found = false;\r\n    let firstItem = null;\r\n    let hasPossibleValues = false;\r\n    for (let i = 0; i < list.length; i++) {\r\n      let item = list[i];\r\n      let text = item.innerText.toLocaleLowerCase();\r\n      let link = item.querySelector(\"a\");\r\n\r\n      // Remove previous selection\r\n      link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n      // Hide selected values\r\n      if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n        item.style.display = \"none\";\r\n        continue;\r\n      }\r\n\r\n      hasPossibleValues = true;\r\n\r\n      // Check search length since we can trigger dropdown with arrow\r\n      let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n      if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n        item.style.display = \"list-item\";\r\n        found = true;\r\n        if (!firstItem && isMatched) {\r\n          firstItem = item;\r\n        }\r\n      } else {\r\n        item.style.display = \"none\";\r\n      }\r\n    }\r\n\r\n    // Special case if nothing matches\r\n    if (!found) {\r\n      this.dropElement.classList.remove(\"show\");\r\n    }\r\n\r\n    // Always select first item\r\n    if (firstItem) {\r\n      if (this.holderElement.classList.contains(\"is-invalid\")) {\r\n        this.holderElement.classList.remove(\"is-invalid\");\r\n      }\r\n      firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n      firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n    } else {\r\n      // No item and we don't allow new items => error\r\n      if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n        this.holderElement.classList.add(\"is-invalid\");\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * The element create with buildSuggestions\r\n   */\r\n  hideSuggestions() {\r\n    if (this.dropElement.classList.contains(\"show\")) {\r\n      this.dropElement.classList.remove(\"show\");\r\n    }\r\n    if (this.holderElement.classList.contains(\"is-invalid\")) {\r\n      this.holderElement.classList.remove(\"is-invalid\");\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @returns {HTMLElement}\r\n   */\r\n  getActiveSelection() {\r\n    return this.dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n  }\r\n\r\n  removeActiveSelection() {\r\n    let selection = this.getActiveSelection();\r\n    if (selection) {\r\n      selection.classList.remove(...ACTIVE_CLASSES);\r\n    }\r\n  }\r\n\r\n  removeLastItem() {\r\n    let items = this.containerElement.querySelectorAll(\"span\");\r\n    if (!items.length) {\r\n      return;\r\n    }\r\n    let lastItem = items[items.length - 1];\r\n    this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n  }\r\n\r\n  /**\r\n   * @param {string} text\r\n   * @param {string} value\r\n   * @param {boolean} checkSelected\r\n   * @return {boolean}\r\n   */\r\n  addItem(text, value, checkSelected = false) {\r\n    if (!value) {\r\n      value = text;\r\n    }\r\n\r\n    // Find by label and value\r\n    let opt = this.selectElement.querySelector('option[value=\"' + value + '\"]');\r\n    if (!opt) {\r\n      opt = Array.from(this.selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n    }\r\n    if (checkSelected) {\r\n      if (opt && opt.getAttribute(\"selected\")) {\r\n        return false;\r\n      }\r\n    }\r\n\r\n    // create span\r\n    let html = text;\r\n    let span = document.createElement(\"span\");\r\n    span.classList.add(\"badge\");\r\n    span.classList.add(\"bg-primary\");\r\n    span.classList.add(\"me-2\");\r\n    span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n    if (this.allowClear) {\r\n      html = '<span class=\"me-2\" style=\"font-size:0.65em\"><button type=\"button\" class=\"btn-close btn-close-white\" aria-label=\"' + this.clearLabel + '\"></button></span>' + html;\r\n    }\r\n\r\n    span.innerHTML = html;\r\n    this.containerElement.insertBefore(span, this.searchInput);\r\n\r\n    if (this.allowClear) {\r\n      span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n        event.preventDefault();\r\n        event.stopPropagation();\r\n        this.removeItem(value);\r\n        document.activeElement.blur();\r\n      });\r\n    }\r\n\r\n    // update select\r\n    if (opt) {\r\n      opt.setAttribute(\"selected\", \"selected\");\r\n    } else {\r\n      // we need to create a new option\r\n      opt = document.createElement(\"option\");\r\n      opt.value = value;\r\n      opt.innerText = text;\r\n      opt.setAttribute(\"selected\", \"selected\");\r\n      this.selectElement.appendChild(opt);\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * @param {string} value\r\n   */\r\n  removeItem(value) {\r\n    let item = this.containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n    if (!item) {\r\n      return;\r\n    }\r\n    item.remove();\r\n\r\n    // update select\r\n    let opt = this.selectElement.querySelector('option[value=\"' + value + '\"]');\r\n    if (opt) {\r\n      opt.removeAttribute(\"selected\");\r\n    }\r\n  }\r\n}\r\n\r\nexport default Tags;\r\n"],
+  "mappings": "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",
   "names": []
 }