JSFiddle - React, Tailwind, and code Playground

change transition based on app state

by Travis Almand

HTML

<div id="app">
  <div id="response">
    <transition :name="currentTransition">
      <div id="notification" v-if="answerChecked">{{ response }}</div>
    </transition>
  </div>

  <div id="problem">
    <input v-model="a" readonly /> +
    <input v-model="b" readonly /> =
    <input v-model="answer">
    <button v-if="!answerChecked" @click="check">check</button>
    <button v-else @click="reset">reset</button>
  </div>
</div>

SCSS

#app {
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100vh;
  justify-content: center;
  overflow: hidden;
  position: relative;
  width: 100vw;
}

#response {
  height: 100px;
}

#notification {
  border: {
    color: black;
    radius: 10px;
    style: solid;
    width: 2px;
  }
  margin: 20px;
  padding: 20px;
}

#problem {
  align-items: center;
  border: {
    color: black;
    radius: 16px;
    style: solid;
    width: 2px;
  }
  box-sizing: border-box;
  font-size: 24px;
  padding: 16px;
  text-align: center;
  
  input {
    font-size: 24px;
    text-align: center;
    width: 2em;
  }
  button {
    font-size: 24px;
    margin-top: 16px;
    width: 100%;
  }
}

.positive-enter-active {
  animation: positive 1s;
}
@keyframes positive {
  0% {
    transform: translate3d(0, 0, 0);
  }
  25% {
    transform: translate3d(0, -20px, 0);
  }
  50% {
    transform: translate3d(0, 20px, 0);
  }
  75% {
    transform: translate3d(0, -20px, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

.negative-enter-active {
  animation: negative 1s;
}
@keyframes negative {
  0% {
    transform: translate3d(0, 0, 0);
  }
  25% {
    transform: translate3d(-20px, 0, 0);
  }
  50% {
    transform: translate3d(20px, 0, 0);
  }
  75% {
    transform: translate3d(-20px, 0, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

Vue

Vue.component('notification', {
  template: '<div id="notification"><slot></slot></div>'
})

new Vue({
  el: "#app",
  data: {
    a: 0,
    b: 0,
    answer: null,
    response: false,
    answerChecked: false,
    currentTransition: ''
  },
  methods: {
  	randomProblem: function () {
    	this.a = Math.floor(Math.random() * Math.floor(10));
      this.b = Math.floor(Math.random() * Math.floor(10));
    },
    check: function () {
      this.response = this.a + this.b === parseInt(this.answer);
      this.answerChecked = true;
      this.currentTransition = this.response ? 'positive' : 'negative';
    },
    reset: function () {
    	this.answer = null;
      this.answerChecked = false;
      this.randomProblem();
    }
  },
  mounted () {
  	this.randomProblem();
  }
})