document.querySelectorAll(".gx-select").forEach(select => { const trigger = select.querySelector(".gx-select-trigger"); const menu = select.querySelector(".gx-select-menu"); const valueElement = select.querySelector(".gx-select-value"); const items = menu.querySelectorAll(".gx-select-item"); let open = false; let index = -1; /* OPEN/CLOSE */ trigger.addEventListener("click", () => toggleMenu()); function toggleMenu() { open = !open; select.classList.toggle("open", open); if (open) { index = -1; positionMenu(); } } /* SMART POSITIONING */ function positionMenu() { const rect = menu.getBoundingClientRect(); if (rect.bottom > window.innerHeight) { menu.style.top = "auto"; menu.style.bottom = "calc(100% + 6px)"; } } /* ITEM CLICK */ items.forEach((item, i) => { item.addEventListener("click", () => { items.forEach(i => i.classList.remove("selected")); item.classList.add("selected"); valueElement.textContent = item.textContent; select.dataset.value = item.dataset.value; toggleMenu(); }); }); /* CLICK OUTSIDE */ document.addEventListener("click", e => { if (!select.contains(e.target)) { select.classList.remove("open"); open = false; } }); /* KEYBOARD NAVIGATION */ trigger.addEventListener("keydown", e => { if (!open && (e.key === "ArrowDown" || e.key === "Enter")) { toggleMenu(); return; } if (!open) return; if (e.key === "ArrowDown") { index = (index + 1) % items.length; highlight(); } else if (e.key === "ArrowUp") { index = (index - 1 + items.length) % items.length; highlight(); } else if (e.key === "Enter") { if (index >= 0) items[index].click(); } else if (e.key === "Escape") { toggleMenu(); } }); function highlight() { items.forEach(i => i.classList.remove("selected")); if (index >= 0) items[index].classList.add("selected"); } });