UNPKG

@vkm-js/dropdown

Version:

An Alpinejs plugin that creates a beautiful and customizable dropdown.

111 lines (107 loc) 5.19 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/dropdown/builds/module.js var module_exports = {}; __export(module_exports, { default: () => module_default, dropdown: () => src_default }); module.exports = __toCommonJS(module_exports); // packages/dropdown/src/index.js function src_default(Alpine) { Alpine.data("dropdown", () => ({ open: false, exitHover: false, keyboardTrigger: false, toggle() { this.open = this.open ? this.close() : true; }, close(focusAfter) { this.open = false; this.keyboardTrigger = false; focusAfter && focusAfter.focus(); } })); Alpine.directive("dropdown", (el, { modifiers }, { cleanup }) => { let { triggerEl, dropdownEl, position, closeOnClickInside, isHoverable } = getDropdownOptions(el, modifiers); const placement = "x-anchor." + (position || "bottom-start"); if (!triggerEl || !dropdownEl) { return !triggerEl ? console.warn("Dropdown JS: Attribute data-trigger is not set!") : console.warn("Dropdown JS: Attribute data-dropdown is not set!"); } if (!el.id) { el.id = crypto.getRandomValues(new Uint32Array(1))[0].toString(36) + Date.now().toString(36); } el.setAttribute("x-data", "dropdown"); el.classList.add("relative"); el.setAttribute("x-on:keydown.esc.window", "close()"); el.setAttribute("x-on:keydown.escape.prevent.stop", "close()"); if (isHoverable) { triggerEl.setAttribute("x-on:mouseover", "open = true"); el.setAttribute("x-on:mouseenter", "console.log('mousenter'),exitHover ? clearTimeout(exitHover) : true"); el.setAttribute("x-on:mouseleave.prevent", "console.log('mouseleave'), exitHover = setTimeout(() => { open = false }, 50)"); } else { triggerEl.setAttribute("x-on:click", "toggle()"); } if (!triggerEl.id) { triggerEl.id = `btn-${el.id}`; } triggerEl.setAttribute("x-ref", "dropdownBtn"); triggerEl.setAttribute("x-on:keydown.space.prevent", "keyboardTrigger = true"); triggerEl.setAttribute("x-on:keydown.enter.prevent", "keyboardTrigger = true"); triggerEl.setAttribute("x-on:keydown.down.prevent", "keyboardTrigger = true"); triggerEl.setAttribute(":aria-expanded", "(open || keyboardTrigger).toString()"); triggerEl.setAttribute("aria-haspopup", "true"); triggerEl.setAttribute("aria-label", "Dropdown"); dropdownEl.setAttribute("x-cloak", ""); dropdownEl.setAttribute("x-transition.origin.top.left", ""); dropdownEl.setAttribute("x-trap", "keyboardTrigger"); dropdownEl.setAttribute(placement, "$refs.dropdownBtn"); dropdownEl.setAttribute("x-ref", "panel"); dropdownEl.setAttribute("x-show", "open || keyboardTrigger"); if (!modifiers.includes("custom")) { dropdownEl.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"); } else { dropdownEl.classList.add("absolute", "z-1000"); } dropdownEl.setAttribute("x-on:click.outside", "close()"); if (closeOnClickInside) { dropdownEl.setAttribute("x-on:click", "close()"); } dropdownEl.setAttribute("x-on:keydown.down.prevent", "$focus.wrap().next()"); dropdownEl.setAttribute("x-on:keydown.up.prevent", "$focus.wrap().previous()"); dropdownEl.setAttribute("x-on:keydown.tab", "close()"); dropdownEl.setAttribute("x-on:keydown.shift.tab", "close()"); dropdownEl.setAttribute("role", "menu"); dropdownEl.setAttribute("aria-orientation", "vertical"); dropdownEl.setAttribute("aria-labelledby", triggerEl.id); el.setAttribute("x-data", "dropdown"); }); function getDropdownOptions(el, modifiers) { let triggerEl = el.querySelector("[data-trigger]"), dropdownEl = el.querySelector("[data-dropdown]"), position = getPlacement(modifiers), isHoverable = modifiers.includes("hover"), closeOnClickInside = modifiers.includes("select"); return { triggerEl, dropdownEl, position, closeOnClickInside, isHoverable }; } function getPlacement(modifiers) { return ["top", "top-start", "top-end", "right", "right-start", "right-end", "bottom", "bottom-start", "bottom-end", "left", "left-start", "left-end"].find((i) => modifiers.includes(i)) || ""; } } // packages/dropdown/builds/module.js var module_default = src_default; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { dropdown });