basecoat-css
Version:
Tailwind CSS for Basecoat components
1 lines • 5.75 kB
JavaScript
(()=>{const e=e=>{const t=e.querySelector(":scope > button"),r=t.querySelector(":scope > span"),n=e.querySelector(":scope > [data-popover]"),i=n?n.querySelector('[role="listbox"]'):null,a=e.querySelector(':scope > input[type="hidden"]'),s=e.querySelector('header input[type="text"]');if(!(t&&n&&i&&a)){const r=[];return t||r.push("trigger"),n||r.push("popover"),i||r.push("listbox"),a||r.push("input"),void console.error(`Select component initialisation failed. Missing element(s): ${r.join(", ")}`,e)}const o=Array.from(i.querySelectorAll('[role="option"]')),c=o.filter((e=>"true"!==e.getAttribute("aria-disabled")));let l=[...c],d=-1;const u="true"===i.getAttribute("aria-multiselectable"),f=u?new Set:null,p=u?e.dataset.placeholder||"":null,v="true"===e.dataset.closeOnSelect,h=e=>e.dataset.value??e.textContent.trim(),b=e=>{if(d>-1&&c[d]&&c[d].classList.remove("active"),d=e,d>-1){const e=c[d];e.classList.add("active"),e.id?t.setAttribute("aria-activedescendant",e.id):t.removeAttribute("aria-activedescendant")}else t.removeAttribute("aria-activedescendant")},m=()=>{const e=getComputedStyle(n);return parseFloat(e.transitionDuration)>0||parseFloat(e.transitionDelay)>0},y=(t,n=!0)=>{let i;if(u){const e=Array.isArray(t)?t:[];f.clear(),e.forEach((e=>f.add(e)));const n=c.filter((e=>f.has(e)));0===n.length?(r.textContent=p,r.classList.add("text-muted-foreground")):(r.textContent=n.map((e=>e.dataset.label||e.textContent.trim())).join(", "),r.classList.remove("text-muted-foreground")),i=n.map(h),a.value=JSON.stringify(i)}else{const e=t;if(!e)return;r.innerHTML=e.innerHTML,i=h(e),a.value=i}c.forEach((e=>{(u?f.has(e):e===t)?e.setAttribute("aria-selected","true"):e.removeAttribute("aria-selected")})),n&&e.dispatchEvent(new CustomEvent("change",{detail:{value:i},bubbles:!0}))},A=(e=!0)=>{if("true"!==n.getAttribute("aria-hidden")){if(s){const e=()=>{s.value="",l=[...c],o.forEach((e=>e.setAttribute("aria-hidden","false")))};m()?n.addEventListener("transitionend",e,{once:!0}):e()}e&&t.focus(),n.setAttribute("aria-hidden","true"),t.setAttribute("aria-expanded","false"),b(-1)}},E=e=>{f.has(e)?f.delete(e):f.add(e),y(c.filter((e=>f.has(e))))},g=e=>{if(u){const t=c.find((t=>h(t)===e&&!f.has(t)));if(!t)return;f.add(t),y(c.filter((e=>f.has(e))))}else{const t=c.find((t=>h(t)===e));if(!t)return;a.value!==e&&y(t),A()}},w=e=>{if(!u)return;const t=c.find((t=>h(t)===e&&f.has(t)));t&&(f.delete(t),y(c.filter((e=>f.has(e)))))},L=e=>{if(!u)return;const t=c.find((t=>h(t)===e));t&&E(t)};if(s){const e=()=>{const e=s.value.trim().toLowerCase();b(-1),l=[],o.forEach((t=>{if(t.hasAttribute("data-force"))return t.setAttribute("aria-hidden","false"),void(c.includes(t)&&l.push(t));const r=(t.dataset.filter||t.textContent).trim().toLowerCase(),n=(t.dataset.keywords||"").toLowerCase().split(/[\s,]+/).filter(Boolean).some((t=>t.includes(e))),i=r.includes(e)||n;t.setAttribute("aria-hidden",String(!i)),i&&c.includes(t)&&l.push(t)}))};s.addEventListener("input",e)}if(u){const e=c.filter((e=>"true"===e.getAttribute("aria-selected")));try{const t=JSON.parse(a.value||"[]"),r=new Set(c.map(h)),n=Array.isArray(t)?t.filter((e=>r.has(e))):[],i=[];n.length>0?n.forEach((e=>{const t=c.find((t=>h(t)===e&&!i.includes(t)));t&&i.push(t)})):i.push(...e),y(i,!1)}catch(t){y(e,!1)}}else{const e=c.find((e=>h(e)===a.value))||c[0];e&&y(e,!1)}const x=e=>{const r="false"===n.getAttribute("aria-hidden");if(!["ArrowDown","ArrowUp","Enter","Home","End","Escape"].includes(e.key))return;if(!r)return void("Enter"!==e.key&&"Escape"!==e.key&&(e.preventDefault(),t.click()));if(e.preventDefault(),"Escape"===e.key)return void A();if("Enter"===e.key){if(d>-1){const e=c[d];u?(E(e),v&&A()):(a.value!==h(e)&&y(e),A())}return}if(0===l.length)return;const i=d>-1?l.indexOf(c[d]):-1;let s=i;switch(e.key){case"ArrowDown":i<l.length-1&&(s=i+1);break;case"ArrowUp":i>0?s=i-1:-1===i&&(s=0);break;case"Home":s=0;break;case"End":s=l.length-1}if(s!==i){const e=l[s];b(c.indexOf(e)),e.scrollIntoView({block:"nearest",behavior:"smooth"})}};i.addEventListener("mousemove",(e=>{const t=e.target.closest('[role="option"]');if(t&&l.includes(t)){const e=c.indexOf(t);e!==d&&b(e)}})),i.addEventListener("mouseleave",(()=>{const e=i.querySelector('[role="option"][aria-selected="true"]');b(e?c.indexOf(e):-1)})),t.addEventListener("keydown",x),s&&s.addEventListener("keydown",x);t.addEventListener("click",(()=>{"true"===t.getAttribute("aria-expanded")?A():(()=>{document.dispatchEvent(new CustomEvent("basecoat:popover",{detail:{source:e}})),s&&(m()?n.addEventListener("transitionend",(()=>{s.focus()}),{once:!0}):s.focus()),n.setAttribute("aria-hidden","false"),t.setAttribute("aria-expanded","true");const r=i.querySelector('[role="option"][aria-selected="true"]');r&&(b(c.indexOf(r)),r.scrollIntoView({block:"nearest"}))})()})),i.addEventListener("click",(e=>{const r=e.target.closest('[role="option"]');if(!r)return;const n=c.find((e=>e===r));n&&(u?(E(n),v?A():(b(c.indexOf(n)),s?s.focus():t.focus())):(a.value!==h(n)&&y(n),A()))})),document.addEventListener("click",(t=>{e.contains(t.target)||A(!1)})),document.addEventListener("basecoat:popover",(t=>{t.detail.source!==e&&A(!1)})),n.setAttribute("aria-hidden","true"),Object.defineProperty(e,"value",{get:()=>u?c.filter((e=>f.has(e))).map(h):a.value,set:e=>{if(u){const t=Array.isArray(e)?e:null!=e?[e]:[],r=[];t.forEach((e=>{const t=c.find((t=>h(t)===e&&!r.includes(t)));t&&r.push(t)})),y(r)}else{const t=c.find((t=>h(t)===e));t&&(y(t),A())}}}),e.select=g,e.selectByValue=g,u&&(e.deselect=w,e.toggle=L,e.selectAll=()=>y(c),e.selectNone=()=>y([])),e.dataset.selectInitialized=!0,e.dispatchEvent(new CustomEvent("basecoat:initialized"))};window.basecoat&&window.basecoat.register("select","div.select:not([data-select-initialized])",e)})();