JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<h4>Group #1</h4>
<a data-eclb-group="1" href="https://dummyimage.com/600x600/ececec/353535.png"><img src="https://dummyimage.com/600x600/ececec/353535.png" width="100" style="border: 1px solid #ccc;"/></a>
<a data-eclb-group="1" href="https://dummyimage.com/600x300/fff/353535.png"><img src="https://dummyimage.com/600x300/fff/353535.png" width="100" style="border: 1px solid #ccc;"/></a>

<hr />

<h4>Group #2</h4>
<a data-eclb-group="2" href="https://dummyimage.com/300x600/ececec/353535.png"><img src="https://dummyimage.com/300x600/ececec/353535.png" width="100" style="border: 1px solid #ccc;"/></a>
<a data-eclb-group="2" href="https://dummyimage.com/1200x600/ececec/353535.png"><img src="https://dummyimage.com/1200x600/ececec/353535.png" width="100" style="border: 1px solid #ccc;"/></a>
<a data-eclb-group="2" href="https://dummyimage.com/300x600/ececec/353535.png"><img src="https://dummyimage.com/300x600/ececec/353535.png" width="100" style="border: 1px solid #ccc;"/></a>

SCSS

#eclb-target{
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;
  font-size: 16px;
  font-family: sans-serif;
  color: #353535;
  font-weight: bold;
  
  &,
  *,
  *:before,
  *:after{
    box-sizing: border-box;
  }
  
  &:not(.eclb-image-loaded){
    #eclb-inner{
      //opacity: 0;
    }
    
    button{
      opacity: 0;
    }
    
  }
  
}

#eclb-fade{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  background-color: rgba(0, 0, 0, 0.9);
}

#eclb-wrap{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

#eclb-inner{
  position: relative;
  padding: 1em;
  background-color: #fff;
  max-width: 90%;
  min-width: 200px;
  z-index: 2;
  overflow: hidden;
  box-shadow: 0 0.2em 0.6em -0.1em rgba(0, 0, 0, 1);
  opacity: 1;
  transition: opacity 300ms;
  
  button{
    background-color: #fff;
    border: 0;
    font-family: inherit;
    font-weight: inherit;
    font-size: inherit;
    text-transform: uppercase;
    color: inherit;
    padding: 0.75em;
    position: absolute;
    line-height: 1;
    cursor: pointer;
    transition: opacity 300ms;
    
    &[disabled]{
      color: #999;
      opacity: 0;
      cursor: default;
    }
    
    &:hover,
    &:focus,
    &:active{
      outline: none;
    }
    
  }
  
}

#eclb-next{
  right: 1em;
  top: 50%;
  transform: translateY(-50%);
  box-shadow: -0.2em 0 0.6em -0.2em rgba(0, 0, 0, 0.3);
  opacity: 0.5;
  
  &:hover:not([disabled]),
  &:active:not([disabled]){
    opacity: 1;
  }
  
}

#eclb-prev{
  left: 1em;
  top: 50%;
  transform: translateY(-50%);
  box-shadow: 0.2em 0 0.6em -0.2em rgba(0, 0, 0, 0.3);
  opacity: 0.5;
  
  &:hover:not([disabled]),
  &:active:not([disabled]){
    opacity: 1;
  }
  
}

#eclb-close{
  top: 0em;
  right: 0em;
}

#eclb-stage{
  position: relative;
  min-height: 100px;
  
  img{
    max-width: 100%;
    max-height: 85vh;
  }
  
 ...

JavaScript

console.clear();
/**
 * EC Lightbox
 * @param  {object} images Array of image URLs
 * @param  {mixed}  image  Index or URL of image to autoload
 */
function eclb(images, image){
  // Set up variables

  // Image list vars
  this.CURRENT = 0;
  this.IMAGES = images;

  // Target vars
  this.TARGET_ID = 'eclb-target';
  this.TARGET_STATE = 0;

  // Stage vars
  this.STAGE_ID = 'eclb-stage';
  this.STAGE_STATE = 0;

  // Stage vars
  this.NEXT_STATE = 0;
  this.PREV_STATE = 0;

  // If initial image index or string is provided, open upon initialization
  if(typeof image !== 'undefined'){
    this.openLightbox(image);
  }

  return this;
}


/**
 * Closes lightbox target
 */
eclb.prototype.closeLightbox = function(){
  var _t = this,
      lb;

  // Fail if target isn't open
  if(_t.TARGET_STATE !== 1){
    return false;
  }

  // Get target
  lb = document.getElementById(_t.TARGET_ID);

  // Fade out
  return _fade('out', lb, 600, 'easeOut', function(){
    // Remove target from DOM
    lb.parentNode.removeChild(lb);

    // Reset states
    _t.TARGET_STATE = 0;
    _t.STAGE_STATE = 0;

    return true;
  });
}


/**
 * Opens lightbox with image index or string
 * @param  {mixed} image Image index or matching string
 */
eclb.prototype.openLightbox = function(image){
  var _t = this,
      lb;

  // Only run if target state is closed (0)
  if(_t.TARGET_STATE !== 0){
    return false;
  }

  // Image index detection
  if(typeof image === 'string'){
    image = _t.IMAGES.indexOf(image); // Match first instance of image string
  }else if(typeof current !== 'number'){
    current = 0; // Default index to first
  }

  // Check index is in array range
  if(!_t.IMAGES[image]){
    return false;
  }

  // Update current image index
  _t.CURRENT = image;

  // Update state to opening (2)
  _t.TARGET_STATE = 2;

  // Create lightbox DOM object
  lb = _render({
    tag: 'div',
    attr: {
      'id': _t.TARGET_ID
    },
    css: {
      'display': 'none' // display: none for...