JSFiddle - React, Tailwind, and code Playground
by joplomacedo
HTML
<button data-state="loading" class="btn">
<span class="btn__content">
<span class="if if-idle">Submeter</span>
<span class="if if-loading">Submetendo. Aguarde por favor.</span>
<span class="if if-success">Submetido. Obrigado.</span>
</span>
<span class="btn__loadingBar">
<span class="btn__loadingBar__grower"></span>
</span>
</button>
CSS
*,
*:before,
*:after{
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0;
background: none;
font: inherit;
outline: none;
}
html {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
}
.btn {
position: relative;
cursor: pointer;
padding: 1em;
background-color: red;
color: #fff;
border-radius: 3px;
}
.btn .btn__content > .if {
display: none;
}
.btn[data-state="idle"] .btn__content > .if-idle,
.btn[data-state="loading"] .btn__content > .if-loading,
.btn[data-state="success"] .btn__content > .if-success {
display: block;
}
.btn__loadingBar {
height: 5px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(255,255,255,.3);
}
.btn__loadingBar__grower {
display: block;
width: 0;
height: 100%;
background-color: rgba(255,255,255,.7);
}
/* state */
.btn[data-state="loading"] .btn--loadingBar {
display: block;
}
.btn[data-state="loading"] .btn__loadingBar__grower,
.btn[data-state="success"] .btn__loadingBar__grower {
animation-name: grow;
animation-fill-mode: both;
}
.btn[data-state="loading"] .btn__loadingBar__grower {
animation-duration: 30s;
}
.btn[data-state="success"] .btn__loadingBar__grower {
animation-duration: 3.6s;
}
@keyframes grow{
0%{
width: 0%;
}
100%{
width: 100%;
}
}
JavaScript
const btn = document.querySelector('.btn')
let completeTimeout;
btn.addEventListener('click', () => {
clearTimeout(completeTimeout);
startLoading(btn);
completeTimeout = setTimeout(() => {
completeLoading(btn)
}, 3000);
})
function startLoading(btn) {
btn.setAttribute('data-state', 'loading');
}
function completeLoading(btn) {
btn.setAttribute('data-state', 'success');
}