DEV Community

Cover image for Creating a Context Menu for my Bookmark Manager
Marian
Marian

Posted on

Creating a Context Menu for my Bookmark Manager

Today I replaced the topbar entries of my bookmark manager called Crumb Collector with a context menu, because they did not fit properly anymore on mobile devices. The app is written using the MERN stack, so in this post I'd like to share how I created this context menu in React.

Alt Text

I also finally managed to properly loop the cover image GIF, but that's not the topic of this post.😉

The Requirement

I used to have just the Log In button in the top right corner, but wanted to add a few more icons, which made it too wide for mobile devices. I wanted the context menu to open when the user hovers over it and it should include important links on the site as well as links to my blog, Twitter and Dev.to.

The Basic Setup

The topbar is a div-element with fixed position, so that it is always at the top of the screen. I am using FontAwesome for the caret icon. The More entry is the container for our context menu. The menu itself is placed outside of the viewport using position: absolute and right: -10rem and will be made visible when we hover over More.

I added a transition-delay to .topbar-menu so that it does not disappear immediately, when the mouse leaves the element that triggered the hover-effect.

The JSX

<div className='topbar'>
  <div className='topbar-items'>
    {handleDarkmode}
    <span className="more" >
      More <i className="fas fa-caret-down"></i>
        <ul className="topbar-menu">
          <li>...</li>
          <li>...</li>
        </ul>
    </span>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

The CSS

/* This is the topbar, pinned to the top.*/
.topbar {
  position: fixed;
  display: flex;
  flex-direction: row;
  height: 48px;
  width: 100%;
  background-color: #252525;
  line-height: 36px;
  z-index: 2;
  top: 0;
}

/* This is the class for the topbar items.*/
.topbar-items {
  display: flex;
  margin-left: auto;
  margin-right: 2rem;
  align-items: center;
  cursor: pointer;
  color: white;
}

/* This is the context menu, placed outside of the viewport 
 */
.topbar-menu {
  position: absolute;
  right: -10rem;
  margin-top: 0.8rem;
  background-color: #1c75da;
  display: flex;
  flex-direction: column;
  transition: 0.1s;
  transition-delay: 0.3s;
  text-align: center;
  width: auto;
  border-radius: 0.3rem;
  font-weight: 700;
}
Enter fullscreen mode Exit fullscreen mode

Displaying The Context Menu

I want the menu to show up automatically when I hover over More, so I have to add :hover to the menu entry in combination with class .topbar-menu. On hover, the menu will move into the viewport using transform: translateX.

.more:hover .topbar-menu {
  transform: translateX(-11rem);
  transition: 0.1s;
}
Enter fullscreen mode Exit fullscreen mode

Styling the menu

The first four items are just regular list-items that are styled like this:

The JSX

        <ul className="topbar-menu">
          <li className="dropdown">
            <Link className='profile-link' to="/support">
              Contact
            </Link>
          <li>          
        </ul>
Enter fullscreen mode Exit fullscreen mode

The CSS

.dropdown {
  width: 140px;
  height: 2rem;
  line-height: 2rem;
  cursor: pointer;
  border-bottom: 1px solid white;
}

.profile-link {
  text-decoration: none;
  color: white;
  width: max-content;
  width: 100%;
  height: 100%;
  display: block;
  font-size: 0.9rem
}

.profile-link:hover {
  background-color: #4490E1;
  border-radius: 0.3rem;
}
Enter fullscreen mode Exit fullscreen mode

To avoid making the menu unnecessary long, I wanted to place the social icons all in one row. I added a second class to the list-item and changed the display property to inline-flex and added flex: 0.34 to give each 1/3rd of the width.

The JSX

<li className="dropdown social">
  <a className="profile-link social"
     rel="noopener nofollow noreferrer"
     href="https://dev.to/isarisariver">
       <i className="fab fa-dev" 
          title="DEV Profile">  
       </i>
  </a>
</li>
Enter fullscreen mode Exit fullscreen mode

The CSS

li.dropdown.social {
  display: flex;
  justify-content: space-evenly;
}

.profile-link.social {
  display: inline-flex;
  width: auto;
  font-size: 1.2rem;
  align-items: center;
  flex: 0.34;
  justify-content: center;
  border-radius: 0.3rem;
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

And that's it. I hope it can help you with your next project! If you have any questions, just drop me a message. 😄

Top comments (0)