JSFiddle - React, Tailwind, and code Playground

by Vasil Svetoslavov

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<div class="container" style="padding: 4rem;">
  <button type="button" class="btn btn-primary btn-open-wizard" data-toggle="modal" data-target="#cardWizardModal" onclick="resetStep();">
    Open Wizard
  </button>
  <form>

    <div class="form-check">
      <input class="form-check-input" type="checkbox" value="" id="optShowProgress" checked onclick="showProgress=this.checked;console.log(showProgress);">
      <label class="form-check-label" for="optShowProgress">
        Show progress
      </label>
    </div>

    <div class="modal modal-lg fade" id="cardWizardModal" tabindex="-1" aria-labelledby="cardWizardTitle" aria-hidden="true" data-backdrop="static">
      <div class="modal-dialog modal-dialog-scrollable">
        <div class="modal-content">
          <div class="modal-header">
            <h3 class="modal-title" id="cardWizardTitle">Replace Card
                      <div class="d-flex align-items-center">

              <div class="row" id="linkContainer">
              </div>

            </div>
            </h3>
  
          </div>
          <div class="modal-body">

            <!-- Step 1 -->
            <div class="step step-1" data-hint="Replacement Reason">

              <div class="alert alert-warning">
                WARNING! This card will be replaced with a <em>Swift Go To Hell</em> card
              </div>

              <div class="alert alert-danger bg-gradient">
                IMPORTANT! There are products on this card that can not be migrated
              </div>

              <div class="row">
                <div class="col-xs-6 col-xs-offset-3">

                  <div class="form-group">
                    <label...

CSS

/*
.card-wizard {
  border: 1px solid #ccc;
  padding: 10px;
  border-radius: 5px;
  margin-top: 20px;
}
*/
:root {
  --bs-primary: #000 !important;
}

.product+.product {
  margin-top: 5px;
}

.hidden {
  display: none !important;
}

.product {
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 5px;
}

.product-title {
  font-weight: bold;
}


.toast-translucent {
  opacity: 0.9;
}

.toast-translucent:hover {
  opacity :1;
}

a.indicator-link {
	display: inline-block;
	opacity: .75;
	font-size: 10px;
	height: 20px;
	width: 20px;
	border-radius: 10px;
  text-align: center;
  color: white;
  text-decoration: none;
  padding-top: 2px;
  padding-left: 1px;
}

a.indicator-link:focus,
a.indicator-link:active,
a.indicator-link:hover,
a.indicator-link.active {
	opacity: 1;
}

.indicator.col {

}

.link-container {

}

/* Redefine classes from BS5 */
.bg-secondary {
  background-color: #999;
}

.d-flex {
  display: flex !important;
}
.col{
  flex:1 0 0%;
}
.row {
  display: flex;
}
.align-items-center{align-items:center!important}
.justify-content-center{justify-content:center!important}
.justify-content-between{justify-content:space-between!important}
.float-start{float:left!important}

JavaScript

var currentStep = 1;

var showProgress = true;

var tooltipsInitialized = false;

function isStepPresent(step) {
  var stepEl = $('.step.step-' + step);
  if (stepEl.length > 0) {
    return true;
  }
  return false;
}

function isFirstStep(step) {
  if (step == 1) {
    return true;
  }

  return false;
}

function isLastStep(step) {
  return !isStepPresent(step + 1);
}

function goToStep(step) {

  if (step == currentStep) {
    return;
  }
  if (!isStepPresent(step)) {
    return;
  }

  currentStep = step;

	$('.indicator-link').removeClass('active');
  $('.indicator-link').removeClass('bg-primary');
  $('.indicator-link').removeClass('bg-secondary');
  $('.indicator-link').addClass('bg-secondary');

  if (showProgress) {
    for (s = 1; s <= step; s++) {
      $('.indicator-link.link-step-' + s).removeClass('bg-secondary');
      $('.indicator-link.link-step-' + s).addClass('bg-primary');
    }
  } else {
    $('.indicator-link.link-step-' + step).removeClass('bg-secondary');
    $('.indicator-link.link-step-' + step).addClass('bg-primary');
  }
  
  $('.indicator-link.link-step-' + step).addClass('active');

  $('.btn-back').removeClass('hidden');
  $('.btn-next').removeClass('hidden');
  $('.btn-finish').removeClass('hidden');

  if (isFirstStep(step)) {
    $('.btn-back').addClass('hidden');
  }

  if (isLastStep(step)) {
    $('.btn-next').addClass('hidden');
  } else {
    $('.btn-finish').addClass('hidden');
  }

  $('.step').slideUp();
  //$('.step-' + step).removeClass('hidden');
  $('.step.step-' + step).slideDown();
}

function initTooltips() {
  /* if (tooltipsInitialized) {
    return;
  } */

  $('[data-bs-toggle="tooltip"]').each(function(idx, el) {
    //new bootstrap.Tooltip(el);
  });

  tooltipsInitialized = true;
}

function resetStep() {
  currentStep = 1;
  $('#linkContainer').html(null);

  //create step links
  var s = 1;
  while (isStepPresent(s)) {
    var linkClass = s == 1 ? 'bg-primary' : 'bg-secondary';
    linkClass += s == 1 ?...