Sample loading Buttons
by philll_t
HTML
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.min.css">
<div id='main'
class="container text-center">
<template v-for="(class_name, index) in loadingClasses">
<div :key='class_name'>
<br />
<strong>
{{class_name}}
</strong>
<br />
<button :class="`btn btn-primary ${class_name} ${modifier}`"
v-on:click="loading = !loading"
>
<transition name="`transition-${index}`" mode="out-in"
:enter-active-class="`animate__animated animate__${enterAnimationClasses[index]}`"
:leave-active-class="`animate__animated animate__${leaveAnimationClasses[index]}`">
<span v-if="modifier === 'success'" class="text success-text" key='a'>
Done <i class="fas fa-check"></i>
</span>
<span class="text error-text" v-else-if="modifier === 'error'" key='b'>
Error <i class="fas fa-exclamation-triangle"></i>
</span>
<span key="c" class="text loading-text" v-else-if="modifier === 'loading'">
Please wait...
</span>
<span v-else class="text idle-text" key='d'>
Button
</span>
</transition>
</button>
</div>
</template>
<br />
<button class="btn btn-secondary"
v-on:click="modifier=''">
No State
</button>
<button class="btn btn-primary"
v-on:click="modifier='loading'">
Loading modifiers
</button>
<button class="btn btn-success"
v-on:click="modifier='success'">
Success Modifiers
</button>
<button...
SCSS
@keyframes back-n-forth {
from {
left: -20%;
width: 20px;
}
to {
left: calc(120% - 20px);
}
}
@keyframes infinite-load {
0% {
left: 0px;
width: 0%;
}
50% {
right: 0px;
width: 100%;
}
100% {
right: 0px;
width: 0%;
}
}
@keyframes zoom-out {
from {
transform: scale(1);
}
to {
transform: scale(0.0);
}
}
@keyframes pulse {
from {
box-shadow: inset 0px 0 10px rgba(255, 255, 255, 0.1);
text-shaodw: 0 0 10xp rgba(0, 0, 0, 0.0);
}
to {
text-shaodw: 0 0 10xp rgba(0, 0, 0, 1);
box-shadow: inset 0 0 20px rgba(255, 255, 255, 0.8);
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {transform: rotate(360deg)}
}
.pb-btn {
&.btn-primary {
background-color: orangered;
border: darken(orangered, 10%) 1px solid;
}
&-loading {
position: relative;
&.loading {
&:after {
content: "";
display: block;
background-color: white;
opacity: 0.5;
animation: back-n-forth 500ms infinite linear alternate;
position: absolute;
width: 20px;
left: 0px;
bottom: 0px;
height: 5px;
}
}
}
&-loading-a {
&.loading {
position: relative;
animation: pulse 600ms infinite linear alternate;
box-shadow: none;
}
}
&-loading-b {
position: relative;
&.loading{
&:after {
content: "";
display: block;
background-color: rgba(255, 255, 255, 0.5);
opacity: 1;
animation: infinite-load 900ms ease-in-out infinite;
position: absolute;
width: 20px;
bottom: 0px;
height: 5px;
}
}
}
.loading-text {
display: block;
transition: transform 500ms;
transform: scale(1);
}
transition: 500ms;
width: 200px;
&-loading-c {
position: relative;
&.loading {
...
Vue
var app = new Vue({
el: '#main',
props: {
loadingClasses : {
type: Array,
default: () => (
[
'btn-loading',
'btn-loading-a',
'btn-loading-b',
'btn-loading-c',
]
)
},
enterAnimationClasses: {
type: Array,
default: () => ([
'bounceIn',
'bounceIn',
'bounceIn',
'bounceIn',
])
},
leaveAnimationClasses: {
type: Array,
default: () => ([
'bounceOut',
'bounceOut',
'bounceOut',
'bounceOut',
])
},
modifier: {
type: String,
default: "",
},
},
data: {
loading: true,
}
})