JSFiddle - React, Tailwind, and code Playground

by darshanags

HTML

<div class="has-dropdown" tabindex="0">
  <button class="js-dropdown-trigger">
        Dropdown
    </button>

  <div class="dropdown">
    <div class="dropdown__item">
      Some random text with a <a href="#" class="stop-propagation">link</a> in it.
    </div>
    <div class="dropdown__divider"></div>
    <div class="dropdown__item">
      <a href="#">Item One</a>
    </div>
    <div class="dropdown__item">
      <a href="#">Item Two</a>
    </div>
    <div class="dropdown__item">
      <a href="#">Item Three</a>
    </div>
  </div>
</div>

<div class="has-dropdown" tabindex="0">
  <button class="js-dropdown-trigger">
        Dropdown
    </button>

  <div class="dropdown">
    <div class="dropdown__item">
      Some random text with a <a href="#" class="stop-propagation">link</a> in it.
    </div>
    <div class="dropdown__divider"></div>
    <div class="dropdown__item">
      <a href="#">Item One</a>
    </div>
    <div class="dropdown__item">
      <a href="#">Item Two</a>
    </div>
    <div class="dropdown__item">
      <a href="#">Item Three</a>
    </div>
  </div>
</div>

<input name="tf" type="text"/>

CSS

.has-dropdown {
  display: inline-flex;
  position: relative;
}

.dropdown {
  background-color: #eee;
  border: 1px solid #999;
  display: none;
  flex-direction: column;
  position: absolute;
  top: 100%;
  left: 0;
  width: 300px;
  margin-top: 5px;
}

.dropdown.is-active {
  display: flex;
}

.dropdown__item {
  padding: 10px;
}

.dropdown__divider {
  border-bottom: 1px solid #999;
}

JavaScript

$('.has-dropdown').off().on('click', '.js-dropdown-trigger', (event) => {
  const $dropdown = $(event.currentTarget).next('.dropdown');

  if (!$dropdown.hasClass('is-active')) {
    $dropdown.addClass('is-active');
  } else {
    $dropdown.removeClass('is-active');
  }
});

$('.has-dropdown').on('focusout', function(event) {
  const $reltarget = $(event.relatedTarget);
  const $currenttarget = $(event.currentTarget);
  const $dropdown = $currenttarget.children('.dropdown');

  // remove 'is-active' class only if the element
  // that is gaining focus is not a child of the parent.
  // parent = div.has-dropdown
  if (!$reltarget.closest('.has-dropdown').is($currenttarget)) {
    $dropdown.removeClass('is-active');
  }

});