JSFiddle - React, Tailwind, and code Playground

by gangadharjannu

HTML

<section>
  <header></header>
  <main></main>
</section>

CSS

html {
  box-sizing: border-box;
  font-size: 16px;
}

*,
*:before,
*:after {
  box-sizing: inherit;
}

body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
ol,
ul {
  margin: 0;
  padding: 0;
}

ol,
ul {
  list-style: none;
}

img {
  max-width: 100%;
  height: auto;
}

body {
  padding: 10px;
}

a>sub {
  padding-left: 10px;
  font-weight: normal;
}

#tabs {
  height: 30px;
  position: relative;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

#tabs li {
  list-style: none;
  border: 1px solid #ccc;
  border-top-left-radius: 3px;
  border-top-right-radius: 3px;
}

#tabs li a {
  display: block;
  padding: 5px;
  background-color: #f1f1f1;
  text-decoration: none;
  outline: none;
}

#tabs li.active {
  border-bottom: solid 1px #f1f1f1;
  font-weight: bold;
}

#tabs li.active:after {
  content: '';
  display: block;
  height: 1px;
  width: 1px;
  position: absolute;
  bottom: -1px;
  left: 0px;
  background-color: #ccc;
}

.container {
  background-color: #f1f1f1;
  border-left: solid 1px #ccc;
  border-bottom: solid 1px #ccc;
  border-right: solid 1px #ccc;
  padding-top: 20px;
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  height: 100%;
}

/* contact card styling */

.contact {
  position: relative;
  padding: 10px;
  box-sizing: border-box;
  width: 50%;
}

.contact:after {
  content: '';
  background: black;
  position: absolute;
  bottom: 5px;
  height: 1px;
  width: 95%;
  margin: 0 auto;
}

.contact .close-icon {
  position: absolute;
  top: 10px;
  right: 10px;
}

a,
.contact .close-icon {
  cursor: pointer;
}

.contact .contact-img {
  float: left;
  margin-right: 20px;
}

.contact .contact-img img {
  width: 50px;
  height: 50px;
  border-radius: 50%;
}

.contact h5 {
  margin-bottom: 10px;
}

.contact .contact-details {
  float: left;
  padding-right: 50px;
}

.contact .contact-details p>label {
  width: 100px;
  float: left;
  text-align: left;
}

.contact .contact-user-name {
  clear: both;
}

.contact-card {
  position: absolute;
 ...

JavaScript

$(document).ready(function() {
  // config JSON
  var configJSON = {
    title: 'Contact List',
    userUrl: 'https://api.randomuser.me/',
    numberCards: 20,
    tabs: [
      'a',
      'b',
      'c',
      'd',
      'e',
      'f',
      'g',
      'h',
      'i',
      'j',
      'k',
      'l',
      'm',
      'n',
      'o',
      'p',
      'q',
      'r',
      's',
      't',
      'u',
      'v',
      'w',
      'x',
      'y',
      'z'
    ]
  };

  var ContactList = {
    init: function(config) {
      // 1. add header
      this.updateHeader(config.title);

      // 2. add tabs
      this.generateContactGroupTabs(config.tabs);

      // 3. add contacts
      this.generateContacts(config.numberCards, config.userUrl);
    },

    // 1. add header
    updateHeader: function(title) {
      $('section>header').html('<h1>' + title + '</h2>');
    },

    generateContactGroupTabs: function(tabs) {
      // 1. generate tabs
      var ul = $("<ul id='tabs'></ul>");
      var tabsContainer = '';
      tabs.forEach(function(tabName) {
        ul.append(
          '<li><a id="tab' +
          tabName.toUpperCase() +
          '">' +
          tabName +
          '<sub>0</sub>' +
          '</a></li>'
        );
        tabsContainer +=
          '<div class="container" id="tab' +
          tabName.toUpperCase() +
          'Content"></div>';
      });

      $('section>main')
        .append(ul)
        .append(tabsContainer);

      // tabs show/hide functionality
      $('#tabs li:first').addClass('active');
      $('.container').hide();
      $('.container:first').show();

      $('#tabs li').on('click', function() {
        var t = $(this)
          .children('a')
          .attr('id');
        $(this)
          .siblings()
          .removeClass('active');
        $(this).addClass('active');
        $('.container').hide();
        $('#' + t + 'Content').show();
      });
    },

    generateContacts: function(contactsLimit, APIUrl) {
      // fetch...