Dropdown Component

Code to approximate the look of a dropdown from our design doc

by sperske

HTML

<div class="dropdown">
  <div class="input">
    <div class="value">JWK</div>
    <div class="action"><svg width="10" height="8" fill="none">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M.65.65c.2-.2.5-.2.7 0L5 4.29 8.65.65a.5.5 0 1 1 .7.7L5 5.71.65 1.35a.5.5 0 0 1 0-.7Z" fill="#646B81" />
      </svg></div>
  </div>
  <div class='options'>
    <div data-value="JWK">JWK</div>
    <div data-value="PKCSv1">PKCS#1</div>
    <div data-value="PKCSv8">PKCS#8</div>
  </div>
</div>
<p>
  Some other paragraph that appears under this option
</p>

CSS

.dropdown {
  box-sizing: border-box;
  font-family: Arial;
  max-width: 20em;
  height: 32px;
  background: #FFFFFF;
  border: 1px solid #646B81;
  border-radius: 4px;
  user-select: none;
}

.dropdown:focus {
  border-color: rgba(59, 130, 246, 0.5);
  box-shadow: 0px 1px 8px rgba(59, 130, 246, 0.5);
  outline: none;
}

.input {
  display: flex;
  align-items: center;
  padding: 4px 8px 4px 12px;
}

.value {
  font-style: normal;
  font-weight: 400;
  font-size: 14px;
  line-height: 22px;
  font-feature-settings: 'ss03'on;
  color: #161719;
  flex-grow: 1;
}

.action {
  flex-shrink: 1;
}

.action>svg {
  transition-duration: 0.3s;
  transition-property: transform;
}

.dropdown.open .action>svg {
  transform: rotate(180deg);
}

.dropdown .options {
  display: none;
}

.dropdown.open .options {
  display: block;
  padding: 3px 0;
  top: 8px;
  position: relative;
  width: 100%;
  background: #FFFFFF;
  box-shadow: 0px 1px 8px rgba(26, 33, 52, 0.1);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
}

.options>div {
  padding: 9px 19px;
  line-height: 21px;
}

.options>div:hover {
  background-color: rgba(26, 33, 52, 0.1)
}

JavaScript

document.querySelectorAll('.dropdown').forEach((el) => {
  function toggleOpen(event) {
    el.classList.toggle('open');
    if (event.target.dataset.value) {
      el.querySelector('.value').innerHTML = event.target.innerHTML
    }
  }
  el.setAttribute('tabindex', '0')
  el.addEventListener('click', toggleOpen)
  el.addEventListener('keyup', (event) => {
    switch (event.code) {
      case 'Enter':
      case 'Space':
        toggleOpen(event)
        break
      case 'ArrowUp':
        break
      case 'ArrowDown':
        break
    }
  })
})