JSFiddle - React, Tailwind, and code Playground

by Plippie Plop

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<h3>
PVH: Testing 3 state toggle VS Select dropdown
</h3>
<div class="form-inline">
  <input type="text" placeholder="Test Text">

  <div class="tristate-toggler">
    <div class="tristate-radio-wrapper">
      <input id="on-01" class="tristate state-on" name="state-d1" type="radio" value="Yes">
      <label for="on-01"><i class="fa fa-check"></i></label>
      <input id="na-01" class="tristate state-maybe" name="state-d1" type="radio" value="NULL" checked="checked">
      <label for="na-01"><i class="fa fa-minus"></i></label>
      <input id="off-01" class="tristate state-off" name="state-d1" type="radio" value="No">
      <label for="off-01"><i class="fa fa-times"></i></label>
      <div class="tristate-toggle-btn"></div>
    </div>
    <div class="label">Ontvangen?</div>
  </div>
    <div class="tristate-toggler">
    <div class="tristate-radio-wrapper text-mode">
      <input id="on-02" class="tristate state-on" name="state-d2" type="radio" value="Yes">
      <label for="on-02">Ja</label>
      <input id="na-02" class="tristate state-maybe" name="state-d2" type="radio" value="NULL" checked="checked">
      <label for="na-02"><i class="fa fa-minus"></i></label>
      <input id="off-02" class="tristate state-off" name="state-d2" type="radio" value="No">
      <label for="off-02">Nee</label>
      <div class="tristate-toggle-btn"></div>
    </div>
    <div class="label">Ontvangen?</div>
  </div>
  
  <select id="sel-2" data-placeholder="Ontvangen?">  
  <option>Ontvangen?</option>
  <option value="Yes">Ja</option>
  <option value="No">Nee</option>
  </select>
  
</div>
<h3>
  Result
</h3>
<pre class="code"></pre>

CSS

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

*, *:before, *:after {
    box-sizing: inherit;
}

body {
  font-family: Roboto, Sans-Serif;
}

.form-inline {
  display: flex;
  flex-wrap: wrap;
  max-width:60vw;
  margin:0 auto;
  border:1px solid lightgrey;
  padding:1rem;
  
}

input::placeholder {
  color: rgb(160, 160, 160);
}

input, select {
  border: 1px solid lightgrey;
  border-radius: 3px;
  margin-right: 0.4rem;
  margin-bottom: 0.4rem;
  padding: 0.5rem;
  color: rgb(40, 40, 40);
  flex: 1 0 120px;
}


/* tristate toggler */
.tristate-toggler {
  display: inline-flex;
  border: 1px solid lightgrey;
  border-radius: 3px;
  align-items: center;
  justify-content: flex-start;
  flex: 1 1 180px;
height:40px;
  padding:0;
  position: relative;
  margin-right: 0.4rem;
  margin-bottom: 0.4rem;
  padding-right:0.5rem;
  min-width:0;
  max-width:180px;
}

.tristate-toggler > .label { 
  color: rgb(40, 40, 40);
  font-size:0.8rem;
  padding-right:1rem; 
}

.tristate-toggler .tristate-radio-wrapper {
  position: relative;
  display: flex;
  border-radius: 0.5rem;
  background-color: rgb(240, 240, 240);
  border: 0 solid rgba(0, 0, 0, .2);
  padding: 0;
  margin-left: 0.25rem;
  margin-right:0.5rem;
  align-items: center;

}

.tristate-toggler input[type="radio"] {
  position: absolute;
  overflow: hidden;
  border: 0;
  clip: rect(0 0 0 0);
  height: 0;
  width: 0;
  padding: 0;
  margin: 0;
}

.tristate-toggler .tristate-radio-wrapper label {
  display: flex;
  flex: 0;
  cursor: pointer;
  z-index: 1;
  width: 33%;
  padding: 0.5rem 0.6rem;
  transition: color 0.2s ease-in-out;
  font-size:0.6rem;
}
.tristate-toggler .tristate-radio-wrapper.text-mode{
  border-radius:3px;
}

.tristate-toggler .tristate-radio-wrapper input:checked+label {
  color: white;
}

.tristate-toggler .tristate-toggle-btn {
  border-radius: 0.5rem;
  background-color: green;
  position: absolute;
  padding: calc(0.4rem * 2) 0;
  z-index: 0;
  width: 27px;
 ...

JavaScript

const $code = document.querySelector('.code');
const triStateToggle = {};



triStateToggle.init = function() {

  const $triState = document.querySelectorAll('.tristate-toggler');
  const $radio = document.querySelectorAll(".tristate");
  
  console.log($triState);
  console.log($radio);

  for (let i = 0; i < $radio.length; i++) { 
    $radio[i].addEventListener("click", triStateToggle.setStatus) 
  }


};

triStateToggle.setStatus = function(elm){ 
 $elm = elm.target;
    console.log('clicked', $elm);
     $elm.classList.toggle("active");
      $code.textContent = $elm.value;  
};


window.EventTarget.prototype.jon = function(type, delegateSelector, listener) {
    this.addEventListener(type, function (event) {
        if (event.target && event.target.matches(delegateSelector)) {
            listener.call(event.target, event)
        }
    });
}

document.addEventListener('DOMContentLoaded', function(){ 
  triStateToggle.init()
}, false);