JSFiddle - React, Tailwind, and code Playground

by joplomacedo

HTML

<button class="btn" data-state="idle">
  <span class="btn__text">
    <span data-if-state="idle">Enviar</span>
    <span data-if-state="loading">A enviar... Por favor aguarde.</span>
    <span data-if-state="success">Enviado com sucesso. Obrigado.</span>
  </span>
  
  <span class="btn__loadingBar">
    <span class="btn__loadingBar__grower"></span>
  </span>
</button>

CSS

[data-if-state] {
  display: none;
}

.btn[data-state="idle"] [data-if-state="idle"],
.btn[data-state="loading"] [data-if-state="loading"],
.btn[data-state="success"] [data-if-state="success"] {
  display: block;
}

JavaScript

class Machine {
  constructor( def ){
  	this.currentState = def.initialState;
		this.states = def.states;
    this.init();
  }
  
  init() {
  	this.setState(this.currentState)
  }
  
	setState( state ) {
  	if ( !(state in this.states ) ) return;
   	
    const currentStateDef = this.states[this.currentState];
    const newStateDef = this.states[state];
    
		currentStateDef && this.currentStateDef.leave.call(this);
    this.newStateDef.enter.call(this);
  }
}



const  btnMachine  = new Machine({
  intialState: "idle",
  states: {
    idle: {
      enter(){
					btn__text.innerText = "Submeter";
      },
      leave(){

      },
    },
    loading: {
      enter(){
					btn__text.innerText = "A submeter";
      },
      leave(){

      },
    },
    success: {
      enter(){
					btn__text.innerText = "Sucesso";
      },
      leave(){

      }
    }
  }
})