JSFiddle - React, Tailwind, and code Playground

by Константин Дралюк

HTML

<script src="https://npmcdn.com/vue/dist/vue.js"></script>

<div id="exercise">
  <!-- 1) Start the Effect with the Button. The Effect should alternate the "highlight" or "shrink" class on each new setInterval tick (attach respective class to the div with id "effect" below) -->
https://jsfiddle.net/dralyuk/uxb860q6/#run  <div>
    <button @click="startEffect" >Start Effect</button>
    <div id="effect" :class="effectClass"></div>
  </div>
  <!-- 2) Create a couple of CSS classes and attach them via the array syntax -->
  <hr>
  <div :class="['colorRed', 'bold']">I have got several classes :)</div>
  <!-- 3) Let the user enter a class (create some example classes) and attach it -->
  <hr>
  <div>
    <span><i>bgRed, bgBlue, bgYellow</i> - </span>
    <input type="text" v-model="userClass">
    <div :class="['box', userClass]"></div>
  </div>
  <!-- 4) Let the user enter a class and enter true/ false for another class (create some example classes) and attach the classes -->
  <div>
    <hr>
    <span>class </span>
    <input type="text" v-model="userClass2">
    <span> is yellow? </span>
    <input type="text" v-model="userClass3">
    <div class="box" :class="[userClass2, {'bgYellow': userClass3 === 'true'}]"></div>
  </div>
  <!-- 5) Repeat 3) but now with values for styles (instead of class names). Attach the respective styles.  -->
  <div>
    <hr>
    <span>Enter background color </span>
    <input type="text" v-model="userBgColor">
    <div class="box" :style="{'background': userBgColor}"></div>
  </div>
  <!-- 6) Create a simple progress bar with setInterval and style bindings. Start it by hitting the below button. -->
  <div>
    <hr>
    <button v-on:click="startProgress">Start Progress</button>
    <div class="statusBar">
      <div class="statusBar__line" :style="{'width': statusBarPercent + '%'}"></div>
      {{ statusBarPercent }} %
    </div>
  </div>
</div>

CSS

#effect {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

.highlight {
  background-color: red;
  width: 200px !important;
}

.shrink {
  background-color: gray;
  width: 50px !important;
}

.colorRed {
  color: red;
}

.bold {
  font-weight: bold;
}

.box {
  width: 80px;
  height: 80px;
  margin: 10px;
  border: 1px solid #ddd;
  -webkit-box-shadow: 1px 3px 5px rgba(0,0,0,0.2);
  -moz-box-shadow: 1px 3px 5px rgba(0,0,0,0.2);
  box-shadow: 1px 3px 5px rgba(0,0,0,0.2);
}

.bgRed {
  background: red;
}

.bgBlue {
  background: blue;
}

.bgYellow {
  background: yellow;
}

.statusBar {
  height: 20px;
  width: 160px;
  margin: 10px;
  -webkit-box-shadow: inset 1px 3px 5px rgba(0,0,0,0.2);
  -moz-box-shadow: inset 1px 3px 5px rgba(0,0,0,0.2);
  box-shadow: inset 1px 3px 5px rgba(0,0,0,0.2); 
  background: #ddd;
}

.statusBar__line {
  height: 100%;
  width: 0;
  background: green;
}

JavaScript

new Vue({
  el: '#exercise',
  data: {
		effectClasses: ['highlight', 'shrink'],
    effectClass: '',
    userClass: 'bgBlue',
    userClass2: 'bgRed',
    userClass3: 'false', // don't know how to convert v-model value to boolean, so dirty hack here is
    userBgColor: 'black',
    statusBarPercent: 0
  },
  methods: {
    startEffect: function() {
    	var vm = this;
      setInterval(function(){
      	var classes = vm.effectClasses;
      	vm.effectClass = classes[Math.ceil(Math.random() * classes.length) - 1];
      }, 1000);
    },
    startProgress: function() {
    	var vm = this;
      var st = setInterval(function(){
      	if (vm.statusBarPercent < 100) {
        	return vm.statusBarPercent++;
        }
        return clearInterval(st);
      }, 50);
    },
  }
});