JSFiddle - React, Tailwind, and code Playground

by borcagos

HTML

<!DOCTYPE html>
<html lang="en">

  <head>
    <title>The Geovisualization Example</title>
    <meta name="viewport" content="initial-scale=1.0, width=device-width" />
    <link rel="stylesheet" type="text/css" href="https://js.cit.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
    <link rel="stylesheet" type="text/css" href="./dist/ui.css?dp-version=1533195059">
    <link rel="stylesheet" type="text/css" href="./dist/index.css?dp-version=1533195059">
  </head>

  <body>
    <div class="dl-map"></div>
    <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-core.js"></script>
    <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-service.js"></script>
    <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-ui.js"></script>
    <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
    <script type="text/javascript" src="https://js.cit.api.here.com/v3/3.0/mapsjs-clustering.js"></script>
    <script type="text/javascript" src="https://js.cit.datalens.api.here.com/latest/mapsjs-datalens.js"></script>
    <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
    <script type="text/javascript" src="./dist/ui.js"></script>
    <script type="text/javascript" src="./dist/index.js"></script>
  </body>

</html>

CSS

body {
  margin: 0;
  padding: 0;
}

.dl-map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.dl-panel {
  margin: 10px;
  width: 200px;
  background-color: rgba(31, 38, 42, 0.8);
  color: white;
  padding: 0 1em;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  cursor: default;
}

.dl-panel>* {
  margin: 0.5em 0 !important;
}

.dl-panel__header {
  font-size: 1.5em;
}

.dl-label {
  opacity: 0.7;
}

.dl-color-legend__labels {
  width: 200px;
  display: flex;
  justify-content: space-between;
}

.dl-color-legend__labels>div {
  line-height: 20px;
  text-align: center;
  padding: 0 5px;
  opacity: 0.7;
}

.dl-multiselect {
  display: flex;
  width: 200px;
  flex-wrap: wrap;
}

.dl-multiselect__option {
  padding: 5px;
  overflow: hidden;
}

.dl-multiselect__input {
  display: none;
}

.dl-multiselect__label {
  display: block;
  position: relative;
  line-height: 20px;
  padding-left: 25px;
  cursor: pointer;
}

.dl-multiselect__label:before {
  content: '';
  width: 20px;
  height: 20px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 4px;
  background-color: rgba(0, 0, 0, 0.3);
}

.dl-multiselect__label:after {
  content: '';
  width: 8px;
  height: 5px;
  position: absolute;
  top: 5px;
  left: 5px;
  border: 3px solid white;
  border-top: none;
  border-right: none;
  background: transparent;
  opacity: 0;
  transform: rotate(-45deg);
  transition: all 0.3s ease-out;
}

.dl-multiselect__input:checked+.dl-multiselect__label:after {
  opacity: 0.7;
}

.dl-slider {
  width: 100%;
  margin: 0;
  height: 25px;
  position: relative;
}

.dl-slider::before {
  content: '';
  display: block;
  position: absolute;
  top: 12px;
  width: 100%;
  height: 1px;
  background-color: white;
  opacity: 0.7;
}

.dl-slider__input {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background: none;
  height: 0px;
  position: absolute;
  transform:...

JavaScript

(function() {
  'use strict';

  /**
   * Panel which holds controls
   * @class
   * @extends external:H.ui.Control
   */
  class Panel extends H.ui.Control {
    /**
     * @param {string} header - panel title
     */
    constructor(header) {
      super();
      this.header_ = header;
      this.setAlignment('top-left');
    }
    renderInternal(el, doc) {
      this.addClass('dl-panel');
      el.innerHTML = `
            <div class="dl-panel__header">${this.header_}</div>
        `;
      super.renderInternal(el, doc);
    }
    addChild(control) {
      //subscribe on events of child controls
      control.setParentEventTarget(this);
      return super.addChild(control);
    }
  }

  /**
   * Range slider
   * @class
   * @extends external:H.ui.Control
   */
  class Slider extends H.ui.Control {
    /**
     * @param {number} initValue - between 0..100
     */
    constructor(initValue = 100) {
      super();
      this.initValue = initValue;
    }
    renderInternal(el) {
      this.addClass('dl-slider');
      el.innerHTML = `<input
            type="range"
            min="0"
            max="100"
            value="${this.initValue}"
            autocomplete="off"
            class="dl-slider__input"
        />`;
      this.input = el.children[0];
      this.input.addEventListener('change', () => {
        this.dispatchEvent('change');
      });
    }
    /**
     * @returns {number} value always between 0..100
     */
    getValue() {
      return Number(this.input.value);
    }
  }

  /**
   * Slider with two handles
   * @class
   * @extends Slider
   */
  class Range extends Slider {
    /**
     * @param {number[]} initRange
     */
    constructor(initRange = [0, 100]) {
      super(initRange[0]);
      this.initRange = initRange;
    }
    renderInternal(el) {
      super.renderInternal(el);
      this.addClass('dl-range');
      el.innerHTML += `<input
            type="range"
            min="0"
            max="100"
           ...