JSFiddle - React, Tailwind, and code Playground

by lega911

HTML

<script src="https://angularlight.org/bin/alight_1.0.alpha.last.js"></script>
<table width="90%">
  <tr>
    <th></th>
    <th al-for="col in columns">{{col}}</th>
  </tr>
  <tr al-for="row in 30">
    <th>{{row+shift}}</th>
    <td al-for="col in columns" contenteditable changed!="$element, row, col"></td>
  </tr>
</table>

CSS

td {
  user-select: text;
  background: #fff;
}
table, th, td {
  border: 1px solid #ddd;
}
table {
  position: fixed;
  border-collapse: collapse;
}
body {
  height: 250000px;
}

JavaScript

var app = {
	columns: ['A', 'B', 'C', 'D'],
  data: {},
  shift: 0,
  changed: function(el, row, col) {
  	this.watch('shift', (shift) => {
    	el.innerText = app.data[col + (row+shift)] || '';
    })
    el.addEventListener('keyup', () => app.data[col + (row+app.shift)] = el.innerText);
    el.addEventListener('keydown', (e) => {
      if(e.keyCode == 13) {
      	e.preventDefault();
        el.blur();
      }
    })
  }
};

r = alight('body', app);

document.addEventListener('scroll', (e) => {
	app.shift = Math.floor(document.body.scrollTop/20);
  r.scan();
});