JSFiddle - React, Tailwind, and code Playground

by Milan Gladiš

HTML

<!-- Start of vectary Zendesk Widget script -->
<script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=180150ed-d9fd-4605-94d3-9c7146355178"> </script>
<!-- End of vectary Zendesk Widget script -->
<div class="bubble" id="bubble">
  <div class="bubble-agents">
    <div class="bubble-agent">
      <img src="https://lh4.googleusercontent.com/-Ztx_YfEIZqI/AAAAAAAAAAI/AAAAAAAAAAA/4dghMVs0-RM/s40-k-cc-mo/photo.jpg" alt="">
    </div>
    <div class="bubble-agent">
      <img src="https://media-exp1.licdn.com/dms/image/C4E03AQE-R98Nj3sHTw/profile-displayphoto-shrink_200_200/0?e=1586995200&v=beta&t=z8Fkdd8II99-1uF0ryidauWdwLhrpLzkUEScTPw7YB0" alt="">
    </div>
    <div class="bubble-agent">
      <img src="https://media-exp1.licdn.com/dms/image/C4D03AQHZtzblPeWzEQ/profile-displayphoto-shrink_200_200/0?e=1587600000&v=beta&t=1zXo9feVhe3V4vtoPhwSXp0RXvQ9EutiL53N1yWnDG8" alt="">
    </div>
  </div>
  <div class="bubble-text">
    <div class="bubble-status"></div>
    <div class="bubble-message">Need Help?</div>
  </div>
</div>

SCSS

.bubble {
  position: absolute;
  z-index: 100000;
  right: 250px;
  bottom: 20px;
  background-color: #fff;
  border: 1px solid rgba(58,59,60,0.3);
  border-radius: 100px;
  padding: 0 15px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  cursor: default;
  transition: all 0.2s ease;
  pointer-events: none;
  
  &.hidden {
    opacity: 0;
    margin-bottom: -20px;
  }
  
  &.visible {
    opacity: 1;
  }

  &.online, &.offline, &.away {
    cursor: pointer;
    pointer-events: auto;
    &:hover {
      border-color: #684CD6;
    }
    .bubble-message {
      opacity: 1;
    }
  }
}


.bubble-agents {
  display: flex;
  .bubble.online &, .bubble.away & {
    padding-left: 5px;
  }
}

.bubble-agent {
  width: 20px;
  height: 20px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 1);
  border-radius: 90px;
  margin-left: -20px;
  transition: all 0.2s ease;
  overflow: hidden;
  position: relative;
  z-index: 1;
  opacity: 0;
  
   .bubble.online &, .bubble.away & {  
    margin-left: -10px;
    margin-right: 5px;
    opacity: 1;
  }
  .bubble.offline & {
    /* margin-right: -13px; */
    opacity: 0;
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    .bubble.away & {
      filter: grayscale(1);
    }
  }
}


.bubble-status {
  font-family: "Open Sans";
  font-weight: bold;
  font-size: 10px;
  line-height: 12px;
  color: rgba(0, 0, 0, 0.5);
  margin-top: -13px;
  opacity: 0.4;
  transition: all 0.2s ease;
  white-space: nowrap;

  &::after {
    content: '\00a0\00a0';
  }
  
  .bubble.online &, .bubble.away & {
    margin-top: 0;
    opacity: 0.4;
  }
  .bubble.online & {
    &::after {
      content: "We're Online";
    }
  }
  .bubble.away & {
    &::after {
      content: "We're Away";
    }
  }
}


.bubble-message {
  font-family: Open Sans;
  font-weight: bold;
  font-size: 13px;
  line-height: 18px;
  color: rgba(0, 0, 0, 0.8);
  white-space: nowrap;
  opacity: 0.4;
}

JavaScript

var waitForZopim = setInterval(function () {
  if (window.$zopim === undefined || window.$zopim.livechat === undefined) {
    return;
  }

  $zopim(function(){
    var bubble_el = document.getElementById("bubble");
    bubble_el.addEventListener('click', function() {
      $zopim.livechat.window.show();
    });
  
    $zopim.livechat.setOnConnected(bubble);
    $zopim.livechat.setOnStatus(bubble);
    $zopim.livechat.window.onShow(function(){
      bubble_el.classList.remove("visible");
      bubble_el.classList.add("hidden");
    });
    $zopim.livechat.window.onHide(function(){
      bubble_el.classList.remove("hidden");
      bubble_el.classList.add("visible");
      bubble();
    });
    $zopim.livechat.setOnChatStart(function(){
      $zopim.livechat.window.show();
    });
    $zopim.livechat.setOnUnreadMsgs(function(){
      $zopim.livechat.window.show();
    });
  
    function bubble(status){
      $zopim.livechat.button.hide();
      if(status=='online') {
        bubble_el.classList.remove("away", "offline");
        bubble_el.classList.add("online");
  
      } else if(status=='away') {
        bubble_el.classList.remove("online", "offline");
        bubble_el.classList.add("away");
  
      } else if(status=='offline') {
        bubble_el.classList.remove("online", "away");
        bubble_el.classList.add("offline");
      }
    }
  
  });
  
  clearInterval(waitForZopim);
}, 100);