JSFiddle - React, Tailwind, and code Playground

by ttquang1063750

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.min.js"></script>
<div class="content">
    <div class="config">
        <label for="position">
            Set position of legends
            <select id="position">
                <option value="top" selected>top</option>
                <option value="right">right</option>
                <option value="bottom">bottom</option>
                <option value="left">left</option>
            </select>
        </label>
    </div>
    <div class="container" id="container">
        <div class="legends" id="legends">
            <div class="legend" id="add">+ Add new</div>
        </div>
        <div class="chart" id="chart">chart</div>
    </div>
</div>

SCSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.content {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;

  .config {
    padding: 10px 0;
    text-align: center;
    flex-shrink: 1;
  }

  .container {
    flex: 1;
    display: flex;
    border: 1px solid green;

    &.top,
    &.bottom {
      flex-direction: column;
    }

    &.right,
    &.bottom {
      .legends {
        order: 1;
      }
    }

    &.left,
    &.right {
      .legends {
        flex-direction: column;
      }
    }

    &.left {
      .legends {
        align-items: flex-end;
      }
    }

    .legends {
      flex-shrink: 1;
      display: flex;
      flex-wrap: wrap;
      gap: 5px;
      align-items: flex-start;
      padding: 10px;

      .legend {
        border: 1px solid pink;
        padding: 5px 15px 5px 5px;
        width: max-content;
        position: relative;
        line-height: 1;
        
        &:last-child {
          padding: 5px;
        }
        
        button {
          position: absolute;
          right: 2px;
          top: 1px;
          outline: none;
          border: none;
          cursor: pointer;
          background-color: transparent;
        }
      }
    }

    .chart {
      flex: 1;
      background: gray;
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
    }
  }
}

JavaScript

const select = document.getElementById('position');
    const legends = document.getElementById('legends');
    const add = document.getElementById('add');

    select.addEventListener('change', (event) => {
        const position = event.target.value;
        changePosition(position);
    }, false);

    add.addEventListener('click', (event) => {
        generateLegend(event.target);
    }, false);

    function generateLegend(beforeTarget) {
        const legend = faker.name.jobType();
        const div = document.createElement('DIV');
        div.setAttribute('class', 'legend');
        div.innerHTML = `${legend} <button title="Click to remove legend: ${legend}" onclick="this.parentNode.remove()">x</button>`;
        legends.insertBefore(div, beforeTarget);
        previewChartSize();
    }

    function previewChartSize() {
        setTimeout(() => {
            const chart = document.getElementById('chart');
            const width = chart.clientWidth;
            const height = chart.clientHeight;
            chart.innerHTML = `Chart <br>${width}x${height}`;
        }, 100);
    }

    function changePosition(position) {
        const container = document.getElementById('container');
        container.classList.remove('top', 'right', 'left', 'bottom');
        container.classList.add(position);
        previewChartSize();
    }

    changePosition(select.value);
    generateLegend(add);
    generateLegend(add);