import { Controller } from "@hotwired/stimulus" export default class extends Controller { connect() { this.element.style.position = 'relative' this.boundClosePopupOnClickOutside = this.closePopupOnClickOutside.bind(this) } toggle(event) { const margin = 12 const btn = event.currentTarget const popup_menu = btn.nextElementSibling popup_menu.classList.toggle('open') btn.classList.toggle('open') if (popup_menu.classList.contains('open')) { const bound_rect = popup_menu.getBoundingClientRect() // Open to the right if (btn.classList.contains('open--right')) { popup_menu.style.left = btn.offsetWidth + margin + 'px' popup_menu.style.top = "0px" const viewportHeight = window.innerHeight || document.documentElement.clientHeight; // Overflow buttom if (bound_rect.bottom > viewportHeight) { popup_menu.style.bottom = "0px" popup_menu.style.top = "auto" } } else { const viewportWidth = window.innerWidth || document.documentElement.clientWidth; // Overflow right if (bound_rect.right > viewportWidth) { popup_menu.style.left = '-' + (bound_rect.width - btn.offsetWidth) + 'px' } } document.addEventListener('mousedown', this.boundClosePopupOnClickOutside) } else { popup_menu.removeAttribute('style') } event.preventDefault() } close_open(e) { document.querySelectorAll('.popup-menu.open, .has-popup-menu.open').forEach((node) => { node.classList.remove('open') node.removeAttribute('style') }) document.removeEventListener('mousedown', this.boundClosePopupOnClickOutside) } closePopupOnClickOutside(e) { const popup_menu = e.target.closest('.popup-menu, .has-popup-menu'); if (popup_menu == null) { document.querySelectorAll('.popup-menu.open, .has-popup-menu.open').forEach((node) => { node.classList.remove('open') node.removeAttribute('style') }) document.removeEventListener('mousedown', this.boundClosePopupOnClickOutside) } } }