JSFiddle - React, Tailwind, and code Playground

by Ian Sadovy

HTML

<h1>Simple</h1>
<div id="grid2"></div>

CSS

html,
body {
  font-family: sans-serif;
  font-size: 14px;
  background-color: white;
}

div.fm-scroll-pane {
  border: 1px solid #555;
  overflow: auto;
}

div.fm-scroll-pane div.fm-scroll-content {
  position: relative;
}

div.fm-scroll-pane div.fm-placeholder {
  /*background-color: red;*/
  /*opacity: 0.1;*/
  /*z-index: 2;*/
  position: relative;
}

div.fm-table-container,
div.fm-sheet-canvas {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  overflow: hidden;
}

div.fm-cell {
  box-sizing: border-box;
  vertical-align: top;
  border-right: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  padding: 3px 4px;
  line-height: 22px;
}


/* simple grid */

.fm-simple-grid {
  position: relative;
}

div.fm-simple-grid div.fm-row {
  white-space: nowrap;
  box-sizing: border-box;
}

div.fm-simple-grid div.fm-row > div.fm-cell {
  display: inline-block;
}


/* simple grid 2 */

.fm-simple-grid-2 {
  position: relative;
}

div.fm-simple-grid-2 div.fm-sheet-canvas > div.fm-row {
  white-space: nowrap;
  box-sizing: border-box;
}

div.fm-simple-grid-2 div.fm-row > div.fm-cell {
  display: inline-block;
  /*max-width: 200px;*/
  white-space: normal;
}


/* smooth grid */

.fm-smooth-grid div.fm-cell {
  position: absolute;
}

JavaScript

class UIElement {
  constructor(tag = "div", className = "") {
    this._element = document.createElement(tag);
    this.addClass("fm-ui-element");
    this.addClass(className);
  }
  get element() {
    return this._element;
  }
  addChild(child) {
    this.element.appendChild(child.element);
  }
  addClass(className) {
    className = className.trim();
    if (className.length > 0 && this.element.classList.contains(className) == false) {
      this._element.classList.add(className);
    }
  }
  get width() {
    return this.element.clientWidth;
  }
  set width(value) {
    this.element.style.width = value + "px";
  }
  get height() {
    return this.element.clientHeight;
  }
  set height(value) {
    this.element.style.height = value + "px";
  }
  html(value) {
    this.element.innerHTML = value;
  }
}
/// <reference path="src/IUIElement.ts" />
/// <reference path="src/UIElement.ts" /> 
class SmoothGrid {
  constructor(options) {
    console.log("Grid constructor", options);
    options.width = options.width || 800;
    options.height = options.height || 600;
    this._scrollPane = new ScrollPane();
    this._scrollPane.width = options.width;
    this._scrollPane.height = options.height;
    this._dataProvider = new SmoothDataProvider(options.data || [], options.width, options.height);
    this._sheetCanvas = new SmoothSheetCanvas(this._dataProvider, this._scrollPane);
    this._container = options.container || document.body;
    this._container.classList.add("fm-smooth-grid");
    //this._container.appendChild(this._sheetCanvas.element);
    this._container.appendChild(this._scrollPane.element);
    this.build();
  }
  build() {
    this._scrollPane.contentWidth = this._dataProvider.contentWidth;
    this._scrollPane.contentHeight = this._dataProvider.contentHeight;
    this._sheetCanvas.draw();
  }
}
class GridConsts {}
GridConsts.CELL_WIDTH = 100;
GridConsts.CELL_HEIGHT = 30;
class SimpleGrid {
  constructor(options) {
    console.log("Grid constructor",...