// Фикс дропдаунов кита на мобильных: GnDropdown позиционирует меню от левого
// края триггера (position:absolute; left:0), и у триггеров у правого края
// экрана меню вылезает наружу. Кит не даёт ручек позиционирования — после
// открытия выравниваем меню (и по горизонтали, и по вертикали) в пределах
// вьюпорта, не трогая стили кита.
export function installDropdownClamp(): void {
const clamp = () => {
for (const dropdown of Array.from(document.querySelectorAll<HTMLElement>('.dropdown.is-open'))) {
const menu = dropdown.querySelector<HTMLElement>('.dropdown-menu')
if (!menu) continue
const rect = dropdown.getBoundingClientRect()
const vw = document.documentElement.clientWidth
const vh = window.innerHeight
// Горизонталь: если меню не помещается справа от триггера — открыть влево
menu.style.left = 'auto'
menu.style.right = 'auto'
if (rect.left + menu.offsetWidth > vw - 8) menu.style.right = '0'
else menu.style.left = '0'
// Вертикаль: если не помещается под триггером, но есть место сверху — открыть вверх
menu.style.top = ''
menu.style.bottom = ''
if (rect.bottom + 8 + menu.offsetHeight > vh && rect.top - menu.offsetHeight > 0) {
menu.style.top = 'auto'
menu.style.bottom = 'calc(100% + 8px)'
}
}
}
// Открытие дропдауна происходит по клику синхронно, DOM обновляется в
// микротаске Vue — macrotask setTimeout отрабатывает уже после рендера
document.addEventListener('click', () => setTimeout(clamp, 0), true)
}