yaminncco / vue-sidebar-menu

A Vue.js Sidebar Menu Component

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Detect click outside on mobile and collapse

guifsdev opened this issue · comments

How can I implement a functionality with this sidebar for when its on mobile and the user clicks outside the element, if the sidebar is not collapsed it becomes collapsed? My idea is to completely hide the sidebar when the user clicks the toggle and isOnMobile is true, and assign :relative based on the said value.

This was my attempt:

  <sidebar-menu
    id="sidebarMenu"
    ref="sidebarMenu"
    :relative="!isOnMobile"
    :menu="menu"
    :collapsed="collapsed"
    width="220px"
    :widthCollapsed="isOnMobile ? '0' : '50px'"
    @item-click="onItemClick"
  >
And on mounted hook:
const sidebar = this.$refs.sidebarMenu;   
const element = document.getElementById("sidebar");

document.addEventListener("click", (event) => {
  event.stopPropagation();
  const isClickOutside = !element.contains(event.target);
  if (isClickOutside && !sidebar.isCollapsed && sidebar.isOnMobile) {
    sidebar.isCollapsed = true;
  }
});

Did anyone find a simpler method of achieving this? 

I recommend to use a new state and hide the sidebar offscreen with translateX, then with a full screen overlay you can trigger the click event

<div id="sidebar" :class="[isOnMobile && isHidden && 'isHidden']">
  <sidebar-menu
    id="sidebarMenu"
    ref="sidebarMenu"
    :relative="!isOnMobile"
    :menu="menu"
    :collapsed="collapsed"
    width="220px"
    @item-click="onItemClick"
  />
  <div
    v-if="isOnMobile && !isHidden"
    class="sidebar-overlay"
    @click="onCLickOutside"
  />
</div>

onCLickOutside() {
  this.isHidden = true
}

#sidebar .v-sidebar-menu {
  transition: 300ms all ease;
}
#sidebar.isHidden .v-sidebar-menu {
  transform: translateX(-100%);
}
#sidebar .sidebar-overlay {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background-color: #000;
  opacity: 0.5;
  z-index: 900;
}

Thank you @yaminncco, this worked perfectly!