/** * Bongoto Shop – Main JS (CLEAN) * File: assets/js/main.js * * Scope: * - Mobile menu fallback (only if no drawer exists) * - Sticky header shadow * - Mobile search toggle * - Mini-cart toggle * - Global ESC to close open UI * - Woo products slider arrows (jQuery) */ (function () { 'use strict'; const qs = (s, r = document) => r.querySelector(s); const qsa = (s, r = document) => Array.from(r.querySelectorAll(s)); const on = (t, h, o = document, opt = { passive: true }) => o.addEventListener(t, h, opt); const isMobile = () => matchMedia('(max-width: 768px)').matches; /* ---------------- Mobile Menu (fallback if no drawer) ---------------- */ if (!qs('.bt-drawer')) { const mobileToggle = qs('.bt-menu-toggle'); const menu = qs('.bt-primary-menu'); const closeMenu = () => { if (!menu) return; menu.classList.remove('is-open'); document.documentElement.classList.remove('bt-menu-open'); mobileToggle?.setAttribute('aria-expanded', 'false'); }; if (mobileToggle && menu) { mobileToggle.addEventListener('click', (e) => { e.preventDefault(); const expanded = mobileToggle.getAttribute('aria-expanded') === 'true'; mobileToggle.setAttribute('aria-expanded', String(!expanded)); menu.classList.toggle('is-open'); document.documentElement.classList.toggle('bt-menu-open', !expanded); }); // Outside click on('click', (e) => { if (!menu.classList.contains('is-open')) return; if (menu.contains(e.target) || mobileToggle.contains(e.target)) return; closeMenu(); }); // ESC to close document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeMenu(); }); } } /* ---------------- Sticky Header Shadow ---------------- */ const header = qs('.bt-header'); if (header && header.classList.contains('bt-header--sticky')) { const onScroll = () => header.classList.toggle('bt-header-scrolled', window.scrollY > 10); on('scroll', onScroll, window); onScroll(); } /* ---------------- Search Toggle (mobile only) ---------------- */ const toggleSearch = (btn) => { const host = btn.closest('.bt-header-search'); if (!host) return; const dd = host.querySelector('.bt-search-dropdown'); if (!dd) return; const willOpen = dd.hasAttribute('hidden'); dd.hidden = !willOpen ? true : false; btn.setAttribute('aria-expanded', String(willOpen)); if (willOpen) { dd.querySelector('input,textarea,select')?.focus?.({ preventScroll: true }); } }; qsa('.bt-search-toggle').forEach((btn) => { btn.addEventListener('click', (e) => { e.preventDefault(); if (!isMobile()) return; // desktop handled by header.js toggleSearch(btn); }); }); // Close mobile search on outside click on('click', (e) => { if (!isMobile()) return; qsa('.bt-search-dropdown').forEach((dd) => { const host = dd.closest('.bt-header-search'); const toggle = host?.querySelector('.bt-search-toggle'); const inside = host?.contains(e.target); if (!inside && !dd.hasAttribute('hidden')) { dd.hidden = true; toggle?.setAttribute('aria-expanded', 'false'); } }); }); /* ---------------- Mini Cart Toggle ---------------- */ const cartLink = qs('.bt-cart-link'); const miniCart = qs('.bt-mini-cart'); if (cartLink && miniCart) { cartLink.addEventListener('click', (e) => { e.preventDefault(); const visible = miniCart.classList.toggle('is-visible'); miniCart.hidden = !visible; // keep [hidden] in sync cartLink.setAttribute('aria-expanded', String(visible)); }); // Close on outside click on('click', (e) => { if (!miniCart.classList.contains('is-visible')) return; if (miniCart.contains(e.target) || cartLink.contains(e.target)) return; miniCart.classList.remove('is-visible'); miniCart.hidden = true; cartLink.setAttribute('aria-expanded', 'false'); }); } /* ---------------- Global ESC ---------------- */ document.addEventListener('keydown', (e) => { if (e.key !== 'Escape') return; // Close all search dropdowns qsa('.bt-search-dropdown').forEach((dd) => { dd.hidden = true; }); // Close mini-cart if (miniCart) { miniCart.classList.remove('is-visible'); miniCart.hidden = true; cartLink?.setAttribute('aria-expanded', 'false'); } // Close fallback mobile menu (if used) const menu = qs('.bt-primary-menu.is-open'); if (menu && !qs('.bt-drawer')) { menu.classList.remove('is-open'); document.documentElement.classList.remove('bt-menu-open'); qs('.bt-menu-toggle')?.setAttribute('aria-expanded', 'false'); } }); })(); /* ================= Woo Products Slider Controls ================= */ (function ($) { // Arrow controls placed in an HTML widget next to the shortcode widget $(document).on('click', '.bt-ps-prev, .bt-ps-next', function (e) { e.preventDefault(); const $wrap = $(this).closest('.elementor-widget-html, .bt-ps-arrows'); const $shortcode = $wrap.nextAll('.elementor-widget-shortcode').first(); const $track = $shortcode.find('.bt-product-slider ul.products').first(); if (!$track.length) return; const $firstCard = $track.find('li.product').first(); const cardW = $firstCard.outerWidth(true) || 260; const visible = Math.max(1, Math.floor($track.innerWidth() / cardW)); const jump = cardW * Math.min(3, visible); // up to 3 cards (or visible count) const dir = $(this).hasClass('bt-ps-prev') ? -1 : 1; $track.animate({ scrollLeft: $track.scrollLeft() + dir * jump }, 280); }); })(jQuery);