<div id="dataTableContainer"></div>
/* General styles */
body {
  font-family: Arial, sans-serif;
}

.table-container {
  border: 1px solid #e5e7eb;
  border-bottom: none;
  overflow: auto;
  height: 400px;
}

.table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  table-layout: fixed;
}

.table th,
.table td {
  padding: 8px;
  text-align: center;
  border: 1px solid #e5e7eb;
}

.table td:nth-child(1),
table th:nth-child(1) {
  background: red;
  position: sticky;
  left: 0;
  z-index: 5;
  color: white;
}
.table th:nth-child(1) {
  z-index: 6;
}

.table th {
  background-color: #1e3a8a;
  color: white;
  font-size: 14px;
  font-weight: bold;
  position: sticky;
  top: 0;
  z-index: 2;
}

.table td {
  font-size: 14px;
  color: #6b7280;
}

.table tr:nth-child(odd) {
  background-color: #f9fafb;
}

.table tr:hover {
  background-color: rgba(14, 116, 144, 0.1);
}

.no-data {
  text-align: center;
  font-size: 14px;
  color: #9ca3af;
}
class DataTable {
  constructor(containerId, columns, data, onRowClick) {
    this.container = document.getElementById(containerId);
    this.columns = columns;
    this.data = data;
    this.onRowClick = onRowClick;

    this.render();
  }

  render() {
    const tableContainer = document.createElement("div");
    tableContainer.className = "table-container";

    const table = document.createElement("table");
    table.className = "table";
    table.style.width = `max(100%, ${this.columns.reduce(
      (acc, col) => acc + (col.width || 200),
      0
    )}px)`;

    // Create table header
    const thead = document.createElement("thead");
    const headerRow = document.createElement("tr");

    this.columns.forEach((col) => {
      const th = document.createElement("th");
      th.style.width = `${col.width || 200}px`;
      th.textContent = col.label;
      headerRow.appendChild(th);
    });

    thead.appendChild(headerRow);
    table.appendChild(thead);

    // Create table body
    const tbody = document.createElement("tbody");

    if (this.data.length > 0) {
      this.data.forEach((row, rowIndex) => {
        const tr = document.createElement("tr");
        tr.className = rowIndex % 2 === 0 ? "bg-white" : "bg-neutral-50";
        tr.addEventListener("click", () => {
          if (this.onRowClick) this.onRowClick(row);
        });

        this.columns.forEach((col) => {
          const td = document.createElement("td");
          const cellData =
            row[col.key] !== null && row[col.key] !== undefined
              ? row[col.key]
              : "-";

          td.textContent = col.render
            ? col.render(cellData, row) || "-"
            : cellData;
          tr.appendChild(td);
        });

        tbody.appendChild(tr);
      });
    } else {
      const noDataRow = document.createElement("tr");
      const noDataCell = document.createElement("td");
      noDataCell.colSpan = this.columns.length;
      noDataCell.className = "no-data";
      noDataCell.textContent = "No rows to display";
      noDataRow.appendChild(noDataCell);
      tbody.appendChild(noDataRow);
    }

    table.appendChild(tbody);
    tableContainer.appendChild(table);
    this.container.innerHTML = "";
    this.container.appendChild(tableContainer);
  }
}

// Usage example
const columns = [
  { label: "Name", key: "name", width: 150 },
  { label: "Age", key: "age", width: 100 },
  { label: "Email", key: "email", width: 200 },
  { label: "Email", key: "email", width: 200 },
  { label: "Email", key: "email", width: 200 }
];

const data = [
  { name: "John Doe", age: 25, email: "john.doe@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" },
  { name: "Jane Smith", age: 30, email: "jane.smith@example.com" }
];

const onRowClick = (row) => {
  alert(`Row clicked: ${JSON.stringify(row)}`);
};

new DataTable("dataTableContainer", columns, data, onRowClick);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.