JSFiddle - React, Tailwind, and code Playground
by NOVUSIDEA
HTML
<script src="https://unpkg.com/[email protected]/dist/axios.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<react class="react-button" name="yes"></react>
<div id="reactions">
<react class="react-button" name="yes">
<div class="react-icon">
<svg class="svg-symbol"><use xlink:href="#thumb-up"/></svg>
<div class="loading"></div>
</div>
<div class="react-text">Ja</div>
<template #count="count"></template>
</react>
<react class="react-button" name="maybe">
<div class="react-icon">
<svg class="svg-symbol"><use xlink:href="#maybe"/></svg>
<div class="loading"></div>
</div>
<div>Vielleicht</div>
</react>
<react class="react-button" name="no">
<div class="react-icon">
<svg class="svg-symbol"><use xlink:href="#thumb-down"/></svg>
<div class="loading"></div>
</div>
<div>Nein</div>
</react>
</div>
</div>
<svg style="display:none">
<symbol id="maybe" viewBox="0 0 24 24">
<title>maybe</title>
<path d="m11.979 2.0017c-1.395-0.06335-2.4009 1.6346-1.6774 2.8278 0.61323 1.2546 2.5854 1.3245 3.2859 0.11636 0.83097-1.2153-0.13243-2.9865-1.6084-2.9441zm-6.1245 4.3155c-1.0142-0.20321-1.4623 1.1263-0.76746 1.7487 0.49887 0.71496 0.94383 1.4718 1.4803 2.1575 0.76398 0.74649 1.8077 0.1298 2.3482-0.55971 0.31089-0.15681 1.1214-1.3354 0.9921-0.47874-0.013751 1.3381 0.027495 2.6801-0.020596 4.0158-0.3534 2.5584-0.72855 5.1144-1.0683 7.6743-0.066858 0.90825 1.1377 1.4826 1.8011 0.84216 0.50304-0.49485 0.40683-1.2573 0.56811-1.8973 0.263-1.5961 0.52599-3.1923 0.78897-4.7883 0.34722 2.0758 0.66633 4.1577 1.0313 6.2298 0.25243 0.95547 1.7529 0.99372 2.0496 0.05775...
CSS
* {
box-sizing: border-box;
}
#reactions {
display: flex;
justify-content: space-around;
}
.react-button {
background: beige;
cursor: pointer;
padding: 0;
border: 0;
display: flex;
flex-direction: column;
align-items: center;
flex: 0 0 30%;
max-width: 30%;
font-size: 18px;
}
.react-button:disabled {
opacity: 0.5;
}
.react-icon {
font-size: 50px;
}
.svg-symbol {
display: block;
width: 1em;
height: 1em;
}
.react-button .loading {
position: relative;
display: block;
width: 1em;
height: 1em;
display: none;
}
.react-button .loading::before {
content: ' ';
position: absolute;
top: 0.15em;
left: 0.15em;
right: 0.15em;
bottom: 0.15em;
border: 0.1em solid currentColor;
border-bottom-color: transparent;
border-radius: 1em;
animation-name: spin;
animation-duration: 0.8s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.react-button.reaction-loaded .svg-symbol {
display: none;
}
.react-button.reaction-loaded .loading {
display: block;
}
@-webkit-keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
JavaScript
Vue.component('react', {
props: {
name: String,
count: Number,
loading: Boolean,
},
data: function () {
return {
count: 0,
}
},
template: '<button @click="react" :class="{\'reaction-loaded\': loading}" :disabled="loading"><slot></slot><slot name="count">{{ count }}</slot></button>',
methods: {
react: function(){
var _this = this,
min = 150,
max = 300,
randomNumber = Math.floor(Math.random() * max) + min;
_this.loading = true;
console.log( randomNumber );
axios.post('/echo/json/', {count: this.name}).then(function (response) {
setTimeout(function(){
_this.count++;
_this.loading = false;
console.log( response );
}, randomNumber);
}).catch(function (error) {
//console.log(error);
}).then(function () {
//console.log('every time');
});
}
}
});
new Vue({
el: '#app'
});