UNPKG

@vkm-js/dropdown

Version:

An Alpinejs plugin that creates a beautiful and customizable dropdown.

2 lines (1 loc) 2.92 kB
(()=>{function d(s){s.data("dropdown",()=>({open:!1,exitHover:!1,keyboardTrigger:!1,toggle(){this.open=this.open?this.close():!0},close(e){this.open=!1,this.keyboardTrigger=!1,e&&e.focus()}})),s.directive("dropdown",(e,{modifiers:r},{cleanup:a})=>{let{triggerEl:o,dropdownEl:t,position:n,closeOnClickInside:i,isHoverable:p}=u(e,r),b="x-anchor."+(n||"bottom-start");if(!o||!t)return console.warn(o?"Dropdown JS: Attribute data-dropdown is not set!":"Dropdown JS: Attribute data-trigger is not set!");e.id||(e.id=crypto.getRandomValues(new Uint32Array(1))[0].toString(36)+Date.now().toString(36)),e.setAttribute("x-data","dropdown"),e.classList.add("relative"),e.setAttribute("x-on:keydown.esc.window","close()"),e.setAttribute("x-on:keydown.escape.prevent.stop","close()"),p?(o.setAttribute("x-on:mouseover","open = true"),e.setAttribute("x-on:mouseenter","console.log('mousenter'),exitHover ? clearTimeout(exitHover) : true"),e.setAttribute("x-on:mouseleave.prevent","console.log('mouseleave'), exitHover = setTimeout(() => { open = false }, 50)")):o.setAttribute("x-on:click","toggle()"),o.id||(o.id=`btn-${e.id}`),o.setAttribute("x-ref","dropdownBtn"),o.setAttribute("x-on:keydown.space.prevent","keyboardTrigger = true"),o.setAttribute("x-on:keydown.enter.prevent","keyboardTrigger = true"),o.setAttribute("x-on:keydown.down.prevent","keyboardTrigger = true"),o.setAttribute(":aria-expanded","(open || keyboardTrigger).toString()"),o.setAttribute("aria-haspopup","true"),o.setAttribute("aria-label","Dropdown"),t.setAttribute("x-cloak",""),t.setAttribute("x-transition.origin.top.left",""),t.setAttribute("x-trap","keyboardTrigger"),t.setAttribute(b,"$refs.dropdownBtn"),t.setAttribute("x-ref","panel"),t.setAttribute("x-show","open || keyboardTrigger"),r.includes("custom")?t.classList.add("absolute","z-1000"):t.classList.add("absolute","mt-2","shadow-lg","bg-white/90","dark:bg-black/90","rounded-sm","flex","flex-col","w-full","min-w-72","z-1000","py-2"),t.setAttribute("x-on:click.outside","close()"),i&&t.setAttribute("x-on:click","close()"),t.setAttribute("x-on:keydown.down.prevent","$focus.wrap().next()"),t.setAttribute("x-on:keydown.up.prevent","$focus.wrap().previous()"),t.setAttribute("x-on:keydown.tab","close()"),t.setAttribute("x-on:keydown.shift.tab","close()"),t.setAttribute("role","menu"),t.setAttribute("aria-orientation","vertical"),t.setAttribute("aria-labelledby",o.id),e.setAttribute("x-data","dropdown")});function u(e,r){let a=e.querySelector("[data-trigger]"),o=e.querySelector("[data-dropdown]"),t=l(r),n=r.includes("hover"),i=r.includes("select");return{triggerEl:a,dropdownEl:o,position:t,closeOnClickInside:i,isHoverable:n}}function l(e){return["top","top-start","top-end","right","right-start","right-end","bottom","bottom-start","bottom-end","left","left-start","left-end"].find(r=>e.includes(r))||""}}document.addEventListener("alpine:init",()=>{window.Alpine.plugin(d)});})();