import $ from 'jquery'; import Cookies from '../utils/cookies'; const MOBILE_BREAKPOINT = 48 - 0.062; const DESKTOP_BREAKPOINT = 75 + 0.063; const EVENTS = 'touchstart._grav click._grav'; const TARGETS = '[data-sidebar-mobile-toggle], #overlay'; const MOBILE_QUERY = `(max-width: ${MOBILE_BREAKPOINT}em)`; const DESKTOP_QUERY = `(min-width: ${DESKTOP_BREAKPOINT}em)`; let map = new global.Map(); export default class Sidebar { constructor() { this.timeout = null; this.isOpen = false; this.body = $('body'); this.matchMedia = global.matchMedia(MOBILE_QUERY); this.enable(); } enable() { const sidebar = $('#admin-sidebar'); this.matchMedia.addListener(this._getBound('checkMatch')); this.checkMatch(this.matchMedia); this.body.on(EVENTS, '[data-sidebar-toggle]', this._getBound('toggleSidebarState')); if (sidebar.data('quickopen')) { sidebar.hover(this._getBound('quickOpenIn'), this._getBound('quickOpenOut')); } } disable() { const sidebar = $('#admin-sidebar'); this.close(); this.matchMedia.removeListener(this._getBound('checkMatch')); this.body.off(EVENTS, '[data-sidebar-toggle]', this._getBound('toggleSidebarState')); if (sidebar.data('quickopen')) { sidebar.off('mouseenter mouseleave'); } } attach() { this.body.on(EVENTS, TARGETS, this._getBound('toggle')); } detach() { this.body.off(EVENTS, TARGETS, this._getBound('toggle')); } quickOpenIn(/* event */) { let isDesktop = global.matchMedia(DESKTOP_QUERY).matches; let delay = $('#admin-sidebar').data('quickopen-delay') || 500; if (this.body.hasClass('sidebar-mobile-open')) { return; } let shouldQuickOpen = isDesktop ? this.body.hasClass('sidebar-closed') : !this.body.hasClass('sidebar-open'); if (!shouldQuickOpen && !this.body.hasClass('sidebar-quickopen')) { return this.quickOpenOut(); } this.timeout = setTimeout(() => { this.body.addClass('sidebar-open sidebar-quickopen'); $(global).trigger('sidebar_state._grav', isDesktop); }, delay); } quickOpenOut(/* event */) { clearTimeout(this.timeout); if (this.body.hasClass('sidebar-quickopen')) { this.body.removeClass('sidebar-open sidebar-quickopen'); } return true; } open(event, quick = false) { if (event) { event.preventDefault(); } let overlay = $('#overlay'); let sidebar = $('#admin-sidebar'); this.body.addClass('sidebar-mobile-open'); overlay.css('display', 'block'); if (!quick) { sidebar.css('display', 'block').animate({ opacity: 1 }, 200, () => { this.isOpen = true; }); } else { sidebar.css({ display: 'block', opacity: 1 }); this.isOpen = true; } } close(event, quick = false) { if (event) { event.preventDefault(); } let overlay = $('#overlay'); let sidebar = $('#admin-sidebar'); this.body.removeClass('sidebar-mobile-open'); overlay.css('display', 'none'); if (!quick) { sidebar.animate({ opacity: 0 }, 200, () => { sidebar.css('display', 'none'); this.isOpen = false; }); } else { sidebar.css({ opacity: 0, display: 'none' }); this.isOpen = false; } } toggle(event) { if (event) { event.preventDefault(); } return this[this.isOpen ? 'close' : 'open'](event); } toggleSidebarState(event) { if (event) { event.preventDefault(); } clearTimeout(this.timeout); let isDesktop = global.matchMedia(DESKTOP_QUERY).matches; let cookie = null; if (isDesktop) { this.body.removeClass('sidebar-open'); } if (!isDesktop) { this.body.removeClass('sidebar-closed'); this.body.removeClass('sidebar-mobile-open'); } this.body.toggleClass(`sidebar-${isDesktop ? 'closed' : 'open'}`); $(global).trigger('sidebar_state._grav', isDesktop); if (isDesktop) { cookie = !this.body.hasClass('sidebar-closed'); } else { cookie = this.body.hasClass('sidebar-open'); } Cookies.set('grav-admin-sidebar', cookie, { expires: Infinity }); } checkMatch(data) { let sidebar = $('#admin-sidebar'); let overlay = $('#overlay'); this.isOpen = false; overlay.css('display', 'none'); sidebar.css({ display: data.matches ? 'none' : 'inherit', opacity: data.matches ? 0 : 1 }); if (data.matches) { this.body.removeClass('sidebar-open sidebar-closed'); } this[data.matches ? 'attach' : 'detach'](); } _resetMap() { return map.clear(); } _getBound(fn) { if (map.has(fn)) { return map.get(fn); } return map.set(fn, this[fn].bind(this)).get(fn); } } export let Instance = new Sidebar();