JSFiddle - React, Tailwind, and code Playground

by ozzon91

HTML

<div id="app">
  <wizard>          
    <wz-step :disable="d">
        <h1>Step one</h1>
    </wz-step>
    
    <wz-step :disable="d2">
        <h1>Step two</h1>
        
    </wz-step>
    
    <wz-step>
        <h1>Step three</h1>
        
    </wz-step>
    
    <wz-prev>Prev</wz-prev> 
    <wz-next>Next</wz-next>
  </wizard>
  
  <button @click="toggle">Step one disable:{{d}}</button>
  <button @click="toggle2">Step two disable:{{d2}}</button>
</div>

<template id="t-wizard">
  <div class="wizard">
    <slot></slot>
    
    <p style="text-align: center;">
      <span v-for="(s,i) in steps" class="nav-item" :class="{'active': i === currentIndex}"></span> 
    </p>
  </div>
</template>

<template id="t-wz-step">
  <div class="wizard__step" :class="{'wizard__step--current': isCurrent}">
    <slot></slot>
  </div>
</template>

<template id="t-wz-prev">
  <button @click="prev"><slot></slot></button> 
</template>

<template id="t-wz-next">
  <button @click="next"><slot></slot></button> 
</template>

SCSS

.wizard {
  .nav-item {
    background: green;
    border-radius: 50%;
    display: inline-block;
    margin-right: 3px;
    right: 3px;
    width: 15px;
    height: 15px;
    
    &.active {
      background: red;
    }
  }
  
  &__step {
    display: none;
    
    &--current {
      display: block;
    }
  }
}

Babel + JSX

Vue.component('wizard', {
	name: 'wizard',
	template: '#t-wizard',
  mounted: function() {
  	this.refreshSteps();
    
    if(this.steps.length) {
    	if(!this.currentStep) {
      	this.steps[0].isCurrent = true;
      }
    }
  },
  methods: {
  	refreshSteps() {
    	let hasDisabledCurrentStep = -1;
      this.stepsAll = this.$children.filter(el => el.$options.name === 'wz-step');
      this.steps = this.$children.filter(el => el.$options.name === 'wz-step' && !el.disable);
      
    	this.stepsAll.forEach((el, i) => {
      	if(el.$options.name === 'wz-step' && el.isCurrent && el.disable) {
        	hasDisabledCurrentStep = i;
        }
      });
      
      console.log('hasDisabledCurrentStep', hasDisabledCurrentStep)
      
      if(hasDisabledCurrentStep != -1) {
      	
        for(let i = hasDisabledCurrentStep; i < this.stepsAll.length; ++i) {
        	if(!this.stepsAll[i].disable) {
          	this.currentStep = this.stepsAll[i];
            break;
          }
        }
        
        if(hasDisabledCurrentStep > 0 && !this.currentStep) {
        	for(let i = hasDisabledCurrentStep; i > 0; --i) {
        		if(!this.stepsAll[i].disable) {
          		this.currentStep = this.stepsAll[i];
            	break;
          	}
        	}
        }
        
        if(this.currentStep) {
        	this.stepsAll[hasDisabledCurrentStep].isCurrent = false;
        
        	let index = this.steps.findIndex(el => this.currentStep.$el === el.$el);
        
        	this.currentIndex = index;
        	this.steps[this.currentIndex].isCurrent = true;
        }
        
      } else {
      	let index = this.steps.findIndex(el => el.isCurrent);
        if(index != -1) this.currentIndex = index;
      	this.currentStep = null;
      }
      
      
      
    },
    
  	next() {    
      let index = this.steps.findIndex(el => el.isCurrent);
      
      if((index != -1) && index < this.steps.length-1) {
      	this.currentIndex = index+1;
       ...