basecoat-css
Version:
Tailwind CSS for Basecoat components
1 lines • 3.93 kB
JavaScript
(()=>{const e=e=>{const t=e.querySelector(":scope > button"),a=t.querySelector(":scope > span"),n=e.querySelector(":scope > [data-popover]"),i=n.querySelector('[role="listbox"]'),r=e.querySelector(':scope > input[type="hidden"]'),o=e.querySelector('header input[type="text"]');if(!(t&&n&&i&&r)){const a=[];return t||a.push("trigger"),n||a.push("popover"),i||a.push("listbox"),r||a.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${a.join(", ")}`,e)}const s=Array.from(i.querySelectorAll('[role="option"]'));let d=[...s],c=-1;const l=e=>{if(c>-1&&s[c]&&s[c].classList.remove("active"),c=e,c>-1){const e=s[c];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},u=()=>{const e=getComputedStyle(n);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},v=(t,n=!0)=>{if(t&&(a.innerHTML=t.dataset.label||t.innerHTML,r.value=t.dataset.value,i.querySelector('[role="option"][aria-selected="true"]')?.removeAttribute("aria-selected"),t.setAttribute("aria-selected","true"),n)){const a=new CustomEvent("change",{detail:{value:t.dataset.value},bubbles:!0});e.dispatchEvent(a)}},p=(e=!0)=>{if("true"!==n.getAttribute("aria-hidden")){if(o){const e=()=>{o.value="",d=[...s],s.forEach((e=>e.setAttribute("aria-hidden","false")))};u()?n.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),n.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),l(-1)}},f=e=>{if(!e)return;const t=r.value,a=e.dataset.value;null!=a&&a!==t&&v(e),p()};if(o){const e=()=>{const e=o.value.trim().toLowerCase();l(-1),d=[],s.forEach((t=>{const a=(t.dataset.label||t.textContent).trim().toLowerCase().includes(e);t.setAttribute("aria-hidden",String(!a)),a&&d.push(t)}))};o.addEventListener("input",e)}let b=s.find((e=>e.dataset.value===r.value));b||(b=s.find((e=>void 0!==e.dataset.value))??s[0]),v(b,!1);const E=e=>{const a="false"===n.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!a)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void p();if("Enter"===e.key)return void(c>-1&&f(s[c]));if(0===d.length)return;const i=c>-1?d.indexOf(s[c]):-1;let r=i;switch(e.key){case"ArrowDown":i<d.length-1&&(r=i+1);break;case"ArrowUp":i>0?r=i-1:-1===i&&(r=0);break;case"Home":r=0;break;case"End":r=d.length-1}if(r!==i){const e=d[r];l(s.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&d.includes(t)){const e=s.indexOf(t);e!==c&&l(e)}})),i.addEventListener("mouseleave",(()=>{const e=i.querySelector('[role="option"][aria-selected="true"]');l(e?s.indexOf(e):-1)})),t.addEventListener("keydown",E),o&&o.addEventListener("keydown",E);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?p():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),o&&(u()?n.addEventListener("transitionend",(()=>{o.focus()}),{once:!0}):o.focus()),n.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const a=i.querySelector('[role="option"][aria-selected="true"]');a&&(l(s.indexOf(a)),a.scrollIntoView({block:"nearest"}))})()})),i.addEventListener("click",(e=>{const t=e.target.closest('[role="option"]');t&&f(t)})),document.addEventListener("click",(t=>{e.contains(t.target)||p(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&p(!1)})),n.setAttribute("aria-hidden","true"),e.selectByValue=e=>{const t=s.find((t=>t.dataset.value===e));f(t)},e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})();