JSFiddle - React, Tailwind, and code Playground

by angchen

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto"
      rel="stylesheet"
    />
    <link href="https://fonts.googleapis.com/css2?family=Material+Icons+Outlined" rel="stylesheet">
   
  </head>
  <body>
    <div class="commutes">
      <div class="commutes-map">
        <div id="map"></div>
      </div>
      <div class="commutes-info">
        <div class="commutes-initial-state">
          <svg width="53" height="53" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M41 20H18.6c-9.5 0-10.8 13.5 0 13.5h14.5C41 33.5 41 45 33 45H17.7" stroke="#D2E3FC" stroke-width="5"></path>
            <path d="M41 22c.2 0 .4 0 .6-.2l.4-.5c.3-1 .7-1.7 1.1-2.5l2-3c.8-1 1.5-2 2-3 .6-1 .9-2.3.9-3.8 0-2-.7-3.6-2-5-1.4-1.3-3-2-5-2s-3.6.7-5 2c-1.3 1.4-2 3-2 5 0 1.4.3 2.6.8 3.6s1.2 2 2 3.2c.9 1 1.6 2 2 2.8.5.9 1 1.7 1.2 2.7l.4.5.6.2Zm0-10.5c-.7 0-1.3-.2-1.8-.7-.5-.5-.7-1.1-.7-1.8s.2-1.3.7-1.8c.5-.5 1.1-.7 1.8-.7s1.3.2 1.8.7c.5.5.7 1.1.7 1.8s-.2 1.3-.7 1.8c-.5.5-1.1.7-1.8.7Z" fill="#185ABC"></path>
            <path d="m12 32-8 6v12h5v-7h6v7h5V38l-8-6Z" fill="#4285F4"></path>
            </svg>
          <div class="commutes-initial-state-description">
            <h2 class="heading">Add a destination</h2>
            <p>See travel time and directions for places nearby</p>
          </div>
            <button class="commutes-add-button">
            <span class="material-icons-outlined">add</span>
            <span class="label">Add destination</span>
            </button>
        </div>
        <div class="commutes-destination-list">
          <div class="commutes-destination">
           
          </div>
          <div  class="commutes-list-controls">
            <div class="left-control hide material-icons-outlined" data-direction="-1">
              chevron_left
            </div>
            <div...

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.hide {
  display: none;
}

.commutes {
  height: 100%;
  min-width: 360px !important;
  max-width: 100% !important;
  font-family: Arial, sans-serif;
  resize: both;
  display: flex;
  justify-content: center;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: stretch;
}

.commutes-info {
  box-sizing: border-box;
  border-top: none;
  overflow: hidden;
  border-radius: 0 0 8px 8px;
  position: relative;
  max-width: 100%;
  flex: 0 0 110px;
}

.commutes-initial-state {
  display: none;
  border: 1px solid #dadce0;
  border-radius: 8px;
  justify-content: space-between;
  padding: 16px;
  box-sizing: border-box;
  height: 98px;
  margin-top: 8px;
}

.commutes-initial-state svg {
  flex: 0 0 53px;
  margin-right: 16px;
  align-self: center;
}

.commutes-initial-state-description {
  align-self: center;
  flex-grow: 1;
  margin-right: 16px;
}

.commutes-initial-state-description h2 {
  margin: 0;
  color: #202124;
  font: 22px/28px Arial, sans-serif;
}

.commutes-initial-state-description p {
  margin: 0;
  color: #5f6368;
  font: 13px/20px Arial, sans-serif;
}

.commutes-destination-list {
  display: flex;
  
  border: 1px solid #dadce0;
  border-radius: 8px;
  box-sizing: border-box;
  height: 98px;
  margin-top: 8px;
}

.commutes-destination-list .commutes-list-controls {
  display: flex;
    position: absolute;
    top: 50%;
    margin-top: -20px;
    padding: 8px;
    border-radius: 40px;
    background-color: #fff;
    z-index: 100;
    box-shadow: 0 2px 3px 0 rgb(60 64 67 / 30%), 0 6px 10px 4px rgb(60 64 67 / 15%);
    cursor: pointer;
}

.commutes-destination-list .right-control {
    right: 16px;
}

.commutes-destination-list:hover .commutes-list-controls {
    display: block;
}

.commutes button {
  align-self: center;
  cursor: pointer;
  border-radius: 4px;
}

.commutes-initial-state .commutes-add-button {
  background-color: #4285f4;
  color: #fff;
  border-color: #fff;
 ...

JavaScript

let map;

/** Hides a DOM element and optionally focuses on focusEl. */
function hideElement(el, focusEl) {
  el.style.display = 'none';
  if (focusEl) focusEl.focus();
}

/** Shows a DOM element that has been hidden and optionally focuses on focusEl. */
function showElement(el, focusEl) {
  el.style.display = 'block';
  if (focusEl) focusEl.focus();
}

/** Determines if a DOM element contains content that cannot be scrolled into view. */
function hasHiddenContent(el) {
  const noscroll = window.getComputedStyle(el).overflowY.includes('hidden');
  return noscroll && el.scrollHeight > el.clientHeight;
}


function updateMapView(destination) {
  if (!destination && !destination.geometry && !destination.geometry.location) return;
  /* map = new google.maps.LatLng(destination.geometry.location.toJSON()) */
  const location = destination.geometry.location.toJSON();
  let myLatlng = new google.maps.LatLng(location);
  map.setCenter(location);
  
  new google.maps.Marker({
    position: myLatlng,
    map,
    title: destination.name,
  });
}

function initMap() {
  initializeCommutesPanel();
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: -34.397,
      lng: 150.644
    },
    zoom: 8,
  });
}

function initializeCommutesPanel() {
  const widgetEl = document.querySelector('.commutes');
  const addCommutesButtonEl = widgetEl.querySelector('.commutes-add-button');
  const commutesModal = widgetEl.querySelector('.commutes-modal-container');

  const cancelButton = commutesModal.querySelector('.cancel-button');

  const input = document.getElementById("destination-address-input");
  const autocomplete = new google.maps.places.Autocomplete(input);
  const addButton = commutesModal.querySelector('.primary-button');
  
  addCommutesButtonEl.addEventListener('click', () => {
    showElement(commutesModal);
  });
  
  let destinationToAdd;
  let destinations;

  addButton.addEventListener('click', () => {
    const destinationAddress =...