Estados de carga simples para botónes de Bootstrap
Éste es un lifehack de CSS que suelo utilizar en todos los proyectos de Bootstrap en los que trabajo (y en los que no utilizan Bootstrap también)
Bootstrap no incluye por defecto una forma sencilla de mostrar un estado de carga en los botones, aunque propone una solución combinando varios elementos
<button class="btn btn-primary" disabled>
<span class="spinner-border spinner-border-sm"></span>
<span>Guardar</span>
</button>
Bootstrap provee la clase .spinner-border para dibujar un loading spinner independiente, y la clase .btn para estilar el botón, pero ésta solución me parece sucia y poco intuitiva
Se vuelve trabajoso si queremos aplicar el estado de carga al botón dinámicamente, porque implica utilizar Javascript para renderizar/eliminar nodos adicionales dentro del botón, o mantenerlos en el dom siempre y mostrarlos/ocultarlos
.btn-loading
Entonces lo que suelo hacer es crear la clase .btn-loading que hereda las propiedades CSS del spinner y las aplica en un pseudo-elemento ::before del botón
.btn-loading::before {
content: '';
margin-right: 0.4em;
margin-top: -4px;
@extend .spinner-border;
@extend .spinner-border-sm;
}
<button class="btn btn-primary btn-loading" disabled>
Guardar
</button>
Delegando la responsabilidad de dibujar el spinner al CSS, y simplificando el proceso de switchear el estado de carga del botón simplemente haciendo toggle a la clase .btn-loading
const stateChanger = document.querySelector('#btn-demo-state-changer');
const stateChangerTarget = document.querySelector('#btn-demo-state-changer-target');
stateChanger.addEventListener('click', () => {
stateChangerTarget.classList.toggle('btn-loading');
stateChangerTarget.disabled = !stateChangerTarget.disabled;
});