projects

DataGrid

2024·live·github

A zero-dependency headless table library for React. Brings sorting, filtering, pagination, and virtual scrolling without imposing any UI opinions.


Why another table library?

Most table libraries bundle UI with logic. You get a styled component that looks fine in a demo and fights you in production. DataGrid separates the two entirely — it handles state and computation, you handle rendering.

import { useDataGrid } from '@ufraan/datagrid';
 
function UsersTable({ users }: { users: User[] }) {
  const { rows, headers, sort, filter } = useDataGrid({
    data: users,
    columns: [
      { key: 'name',  label: 'Name',   sortable: true },
      { key: 'email', label: 'Email',  sortable: true },
      { key: 'role',  label: 'Role',   filterable: true },
    ],
  });
 
  return (
    <table>
      <thead>
        <tr>
          {headers.map(h => (
            <th key={h.key} onClick={() => sort(h.key)}>
              {h.label} {h.sorted && (h.sortDir === 'asc' ? '↑' : '↓')}
            </th>
          ))}
        </tr>
      </thead>
      <tbody>
        {rows.map(row => (
          <tr key={row.id}>
            {row.cells.map(cell => <td key={cell.key}>{cell.value}</td>)}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Features

  • Sorting — single and multi-column, stable sort
  • Filtering — global and per-column, debounced
  • Pagination — controlled or uncontrolled
  • Virtual scrolling — renders only visible rows for large datasets
  • Accessibility — correct ARIA roles, keyboard navigation
  • TypeScript — fully typed, generics for row data

Performance

RowsSort (ms)Filter (ms)Render (ms)
1,000218
10,00018612*
100,0001906014*

*With virtual scrolling enabled — only visible rows are in the DOM.