Custom Select Element

by Jason Park

HTML

<div class="select">
  <select class="select-input">
    <option value="option 1">Option 1</option>
    <option value="option 2">Option 2</option>
    <option value="option 3">Option 3</option>
  </select>
  <div class="option-group-container">
    <div class="option-group">
      <div class="option">Option 1</div>
      <div class="option">Option 2</div>
      <div class="option">Option 3</div>
    </div>
  </div>
</div>

<p>
  Hello World.
</p>

CSS

select {
  appearance: none;
  padding: 0.5rem;
}

.option-group.show {
  visibility: visible;
  opacity: 1;
}

.option-group-container {
  position: relative;
  z-index: auto;
}

.option-group {
  border: 1px solid black;
  width: fit-content;
  visibility: none;
  opacity: 0;
  /* transition: opacity 0.3s ease-in; */
  position: absolute;
  left: 0.5rem;
  top: 0.1rem;
}

.option {
  border-bottom: 1px solid black;
  background-color: white;
  padding: 0.3rem;
}

.option:last-child {
  border-bottom: none;
}

JavaScript

const selectInput = document.querySelector(".select .select-input");
selectInput.addEventListener("mousedown", (e) =>  {
  console.log("click!");
  e.preventDefault();
  toggleOptionGroup();
});

const options = document.querySelectorAll(".select .option-group .option");
for (const option of options) {
  option.addEventListener("mousedown", (e) => {
    const index = Array.prototype.indexOf.call(options, option);
    selectInput.selectedIndex= index;
    toggleOptionGroup();
  })
}

function toggleOptionGroup() {
  const optionGroup = document.querySelector(".select .option-group");
  optionGroup.classList.toggle("show");
}