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);