JSFiddle - React, Tailwind, and code Playground

by Plippie Plop

HTML

<nav id="list">
<ul class="menu">
  <li class="first-menu"><a>Item 1</a></li>
  <li class="first-menu"><a>Item 2</a>
    <ul>
      <li><a>item 2 sub 1</a></li>
      <li><a>Item 2 sub 2</a></li>
    </ul>
  </li>
  <li class="first-menu"><a>Item 3</a>
    <ul>
      <li><a>item 3 sub 1</a></li>
      <li><a>Item 3 sub 2</a>
        <ul>
          <li><a>Item 2 sub-sub 1</a></li>
          <li><a>Item 2 sub-sub 2</a></li>
        </ul>
      </li>
    </ul>
  </li>
   <li class="first-menu"><a>Item 4</a>
    <ul>
      <li><a>item 4 sub 1</a></li>
      <li><a>Item 4 sub 2</a>
        <ul>
          <li><a>Item 4 sub-sub 1</a></li>
          <li><a>Item 4 sub-sub 2</a></li>
        </ul>
      </li>
    </ul>
  </li>

</ul>
</nav>

CSS

@import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');

* {
  box-sizing: border-box;
}

ul,
li {
  margin: 0;
  padding: 0;
  list-style: none;
  position: relative;
  outline: none;
}

#list {
  display: flex;
  background-color: lightgrey;
  position: relative;
  width: auto;
  font-family: "Oswald";
  padding: 0.5rem;
}


.menu a {
  display: flex;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  padding: 0.5rem 1.5rem 0.5rem 0.5rem;
  background-color: white;
  min-width: 150px;
  cursor: pointer;
  position: relative;

}

.menu a:hover {
  background-color: rgba(0, 0, 0, 0.02);
}


.menu li a.active {
  background-color: rgb(124 192 251);
}
.menu a.active:hover{
  background-color:rgba(124 192 251, 0.5);
}

.menu .open a.active {
  background-color: rgb(155 209 255);
}

#list .first-menu:first-of-type > a {
  border-radius: 0.25rem 0.25rem 0 0;
}

#list .first-menu:last-of-type > a {
  border-radius: 0 0 0.25rem 0.25rem;
  border-bottom: 0;
}

#list .has-sub>a::after {
  position: absolute;
  right: 0;
  top: 0;
  transform: translateY(50%);
  content: "▼";
  color: grey;
  padding: 0.25rem;
  font-size: 0.6rem;
}

#list .has-sub.open>ul>li>a {
  background-color: rgb(155 209 255);
}

#list .has-sub.open .open>ul>li>a {
  background-color: rgb(178 220 255);
}



#list .has-sub.open>a::after {
  content: "▲";
}

#list .has-sub.open>a::before {
  content: '';
  position: absolute;
  z-index: 1;
  top: 99%;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: 0;
  height: 0;
  border-top: solid 0.3rem rgba(0, 0, 0, 0.5);
  border-left: solid 0.3rem rgba(0, 0, 0, 0);
  border-right: solid 0.3rem rgba(0, 0, 0, 0);
}


#list .menu ul {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.2s;


}

#list .menu li.open>ul {
  max-height: 10em;
  transition: max-height 0.2s;
}

JavaScript

const list = $("#list");


list.find('a').each(function(idx, elm) {
  console.log(idx, elm);
  $(elm).closest('li').attr('data-menu-index', idx);

  if ($(elm).closest('li').children('ul').length) {
    $(elm).closest('li').addClass('has-sub');
  }

});

list.find('.active').parents('li').addClass('open').find('> a').addClass('active');

list.on('click', 'a', function(e) {
  let $this = $(this);

  if (!$this.hasClass('active')) {
  console.log("not active");
  
  list.find('.open').removeClass('open');
  list.find('.active').removeClass('active');
  
    $this.addClass('active').parents('li').addClass('open').find('> a').addClass('active');
  } else {
  console.log("IS active");
    $this.removeClass('active').closest('li').removeClass('open');
    $this.children('li').removeClass('open');
  }

});