Handsontable example

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/handsontable.full.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/styles/handsontable.min.css" /> 
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/styles/ht-theme-main.css" /> 
<script src="https://handsontable.com/docs/scripts/fixer.js"></script>


  <div class="fixed-header">
    <h3>My Fixed Navigation (50px height)</h3>
  </div>
  
  <div id="example1"></div>

  <div style="padding: 20px;">
    <h1>HEADER</h1>
    <p>Some text here. Some text here. Some text here. Some text here. Some text here. Some text here. Some text here.</p>
  </div>

  <script type="module" src="script.js"></script>
</body>
</html>

SCSS

body {
  margin: 0;
  padding: 0;
}

.fixed-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 50px;
  background: #333;
  color: white;
  display: flex;
  align-items: center;
  padding: 0 20px;
  z-index: 1000;
}

/* Container for proper spacing */
#example1 {
  margin: 20px;
  margin-top: 70px; /* 50px nav + 20px spacing */
}

/* Fix the column headers at 50px */
#example1 .ht_clone_top {
  position: fixed !important;
  top: 50px !important;
  z-index: 102 !important;
}

/* Fix the corner (where row headers meet column headers) */
#example1 .ht_clone_top_inline_start_corner {
  position: fixed !important;
  top: 50px !important;
  z-index: 103 !important;
}

/* Ensure row headers are visible */
#example1 .ht_clone_inline_start {
  z-index: 101 !important;
}

/* Hide the original column headers in the master table to remove the gap */
#example1 .ht_master thead {
  display: none !important;
}

/* Also hide column headers in the inline start clone (row headers area) */
#example1 .ht_clone_inline_start thead {
  display: none !important;
}

/* Remove any bottom border/margin from fixed headers */
#example1 .ht_clone_top,
#example1 .ht_clone_top_inline_start_corner {
  margin-bottom: 0 !important;
  border-bottom: none !important;
}

/* Remove any top border/margin from the master table body */
#example1 .ht_master tbody tr:first-child td,
#example1 .ht_clone_inline_start tbody tr:first-child th {
  border-top: none !important;
}

Babel + JSX

import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
import 'handsontable/styles/handsontable.css';
import 'handsontable/styles/ht-theme-main.css';

// Register all Handsontable's modules
registerAllModules();

// Generate an array of arrays with dummy data
const data = new Array(100) // number of rows
  .fill(null)
  .map((_, row) =>
    new Array(50) // number of columns
      .fill(null)
      .map((_, column) => `${row}, ${column}`)
  );

const container = document.querySelector('#example1');

const hot = new Handsontable(container, {
  themeName: 'ht-theme-main',
  data,
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  contextMenu: true,
  autoWrapRow: true,
  autoWrapCol: true,
  licenseKey: 'non-commercial-and-evaluation',
});

// Synchronize horizontal scrolling
hot.addHook('afterScrollHorizontally', function() {
  const masterHolder = hot.view._wt.wtTable.holder;
  const topClone = container.querySelector('.ht_clone_top .wtHolder');
  
  if (topClone) {
    topClone.scrollLeft = masterHolder.scrollLeft;
  }
});

// Update fixed header positions
function updateHeaderPositions() {
  const containerRect = container.getBoundingClientRect();
  const topClone = container.querySelector('.ht_clone_top');
  const cornerClone = container.querySelector('.ht_clone_top_inline_start_corner');
  
  if (topClone && containerRect) {
    topClone.style.left = `${containerRect.left}px`;
    topClone.style.width = `${containerRect.width}px`;
  }
  
  if (cornerClone && containerRect) {
    cornerClone.style.left = `${containerRect.left}px`;
  }
}

// Initialize
setTimeout(updateHeaderPositions, 100);
window.addEventListener('resize', updateHeaderPositions);
window.addEventListener('scroll', updateHeaderPositions);