JSFiddle - React, Tailwind, and code Playground

by tlgreg

HTML

<script type="text/x-template" id="appSwitch">
  <div class="switch" @click="switchValue">
    <div class="switch-btn btn-on" :class="{ active: value }">On</div>
    <div class="switch-btn btn-off" :class="{ active: !value }">Off</div>
  </div>
</script>

<div id="app">
  <form @submit.prevent="false">
    <app-switch v-model="switchState"></app-switch>
    <button type="submit">OK</button>
  </form>
  <p v-if="switchState">Switch is on</p>
  <p v-else>Switch is off</p>
</div>

SCSS

.switch {
  display: inline-flex;
  margin: .25em;
  box-shadow: 0 0 1px rgba(0,0,0,.25),
              1px 1px 0 rgba(0,0,0,.25);
  border-radius: .25em;
  font-family: monospace;
  font-weight: 800;
  text-transform: uppercase;
  user-select: none;
  
  .switch-btn {
    padding-top: .25em;
    padding-bottom: .25em;
    cursor: default;
    background-color: lightgray;
    
    &.btn-on {
      padding-left: .75em;
      padding-right: .75em;
      border-top-left-radius: inherit;
      border-bottom-left-radius: inherit;
      
      &.active {
        background-color: lightgreen;
        color: darkgreen;
      }
    }
    
    &.btn-off {
      padding-left: .5em;
      padding-right: .5em;
      border-top-right-radius: inherit;
      border-bottom-right-radius: inherit;
      
      &.active {
        background-color: lightcoral;
        color: darkred;
      }
    }
  }
}

Babel + JSX

const AppSwitch = {
	template: '#appSwitch',
  props: {
  	value: {
    	type: Boolean,
      default: false,
    },
  },
  methods: {
  	switchValue() {
    	this.$emit('input', !this.value)
      this.$emit('change', !this.value)
    },
  },
}

new Vue({
	el: '#app',
  data: {
  	switchState: false,
  },
  components: {
  	appSwitch: AppSwitch,
  }
})