Basic Handsontable Sheet

HTML

<script src="https://cdn.tailwindcss.com"></script>

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css"
/>

<script src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>

<div class="w-full max-w-4xl mx-auto bg-white p-6 md:p-8 rounded-xl shadow-lg">
  <h1 class="text-2xl md:text-3xl font-bold text-center text-gray-800 mb-6">
    Basic Handsontable Spreadsheet
  </h1>

  <div class="mb-4">
    <label
      for="cell-editor"
      class="block text-sm font-medium text-gray-700 mb-1"
    >
      Selected Cell Value:
    </label>
    <input
      type="text"
      id="cell-editor"
      disabled
      class="w-full p-2 border border-gray-300 rounded-md shadow-sm bg-gray-50 disabled:opacity-70"
      placeholder="Select a cell to edit its value..."
    />
  </div>

  <div id="hot-container" class="rounded-lg border border-gray-300"></div>
</div>

CSS

/* Use Inter font */
        body {
            font-family: 'Inter', sans-serif;
        }
        /* Style the Handsontable container */
        #hot-container {
            width: 100%;
            height: 60vh; /* 60% of the viewport height */
            overflow: hidden; /* Handsontable manages its own scrolling */
        }

JavaScript

const data = [
  ["A1", "Tesla", "Model S", "2021", "85000"],
  ["A2", "Ford", "Mustang", "2022", "55000"],
  ["A3", "Toyota", "Camry", "2023", "35000"],
  ["A4", "Honda", "Civic", "2022", "28000"],
  ["A5", "Chevrolet", "Corvette", "2023", "95000"],
  ["A6", "BMW", "3 Series", "2021", "48000"],
  ["A7", "Mercedes", "C-Class", "2022", "52000"],
  ["A8", "Audi", "A4", "2023", "49000"],
];

const container = document.getElementById("hot-container");

const cellEditor = document.getElementById("cell-editor");

let selectedRow = null;
let selectedCol = null;
const hot = new Handsontable(container, {
  data: data,
  rowHeaders: true,
  colHeaders: ["ID", "Make", "Model", "Year", "Price"],
  height: "auto",
  width: "auto",
  stretchH: "all",
  contextMenu: true,
  dropdownMenu: true,
  filters: true,
  columnSorting: true,
  manualColumnResize: true,
  manualRowResize: true,
  outsideClickDeselects: false,
  afterSelection(row, col, row2, col2) {
    if (row === row2 && col === col2) {
      selectedRow = row;
      selectedCol = col;

      const cellValue = hot.getDataAtCell(row, col);
      cellEditor.value =
        cellValue === null || cellValue === undefined ? "" : cellValue;
      cellEditor.disabled = false;
    } else {
      selectedRow = null;
      selectedCol = null;
      cellEditor.value = "[Multiple cells selected]";
      cellEditor.disabled = true;
    }
  },

  afterDeselect() {
    setTimeout(() => {
      if (document.activeElement === cellEditor) {
        return;
      }

      selectedRow = null;
      selectedCol = null;
      cellEditor.value = "";
      cellEditor.disabled = true;
    }, 0);
  },

  afterChange(changes, source) {
    if (source === "input-editor") {
      return;
    }

    if (changes) {
      changes.forEach(([row, prop, oldVal, newVal]) => {
        const col = hot.propToCol(prop);

        if (row === selectedRow && col === selectedCol) {
         ...