ahmedallem.
Engineering · 3 min read

Getting Started with Allem UI Data Grid: Sortable, Filterable Tables for React

Learn how to set up @allem-ui/data-grid with TanStack Table to build sortable, filterable, and paginated data tables in React.

Ahmed Allem

Ahmed Allem

Founder & CTO · Aviation, AI & Startups

ShareShare
Getting Started with Allem UI Data Grid: Sortable, Filterable Tables for React

@allem-ui/data-grid is an advanced data table component built on TanStack Table. It provides sorting, filtering, row selection, and pagination with zero configuration. The grid inherits Allem UI's design system and supports dark mode out of the box.

Installation

npm install @allem-ui/data-grid @tanstack/react-table

If you have not already set up the Allem UI theme, add it too:

npm install @allem-ui/theme

Then include the data grid in your Tailwind content paths:

// tailwind.config.ts
import { allemPreset } from "@allem-ui/theme";

export default {
  presets: [allemPreset],
  darkMode: "class",
  content: [
    "./src/**/*.{ts,tsx}",
    "./node_modules/@allem-ui/data-grid/dist/**/*.{js,mjs}",
  ],
};

Basic Table

Define your columns and data, then render a DataGrid:

import { DataGrid, type ColumnDef } from "@allem-ui/data-grid";

type User = { name: string; email: string; role: string };

const columns: ColumnDef<User>[] = [
  { accessorKey: "name", header: "Name" },
  { accessorKey: "email", header: "Email" },
  { accessorKey: "role", header: "Role" },
];

const data: User[] = [
  { name: "Alice Johnson", email: "alice@example.com", role: "Admin" },
  { name: "Bob Smith", email: "bob@example.com", role: "Editor" },
  { name: "Carol Davis", email: "carol@example.com", role: "Viewer" },
];

export default function UsersTable() {
  return <DataGrid data={data} columns={columns} />;
}

That gives you a styled, accessible table with no additional configuration.

Adding Sorting and Filtering

Enable features with boolean props:

<DataGrid
  data={data}
  columns={columns}
  enableSorting
  enableFiltering
/>

With enableSorting, users can click column headers to sort ascending or descending. With enableFiltering, a search input appears above the table for global text filtering.

Row Selection

Add checkboxes for selecting rows:

<DataGrid
  data={data}
  columns={columns}
  enableRowSelection
/>

This adds a checkbox column on the left with a "select all" checkbox in the header.

Pagination

For large datasets, enable pagination:

<DataGrid
  data={data}
  columns={columns}
  enablePagination
  pageSize={10}
/>

The grid renders page controls at the bottom. The default page size is 10 rows.

Combine everything for a complete data management interface:

import { DataGrid, type ColumnDef } from "@allem-ui/data-grid";

type Product = {
  id: string;
  name: string;
  category: string;
  price: number;
  stock: number;
};

const columns: ColumnDef<Product>[] = [
  { accessorKey: "name", header: "Product" },
  { accessorKey: "category", header: "Category" },
  {
    accessorKey: "price",
    header: "Price",
    cell: ({ getValue }) => `$${(getValue() as number).toFixed(2)}`,
  },
  {
    accessorKey: "stock",
    header: "Stock",
    cell: ({ getValue }) => {
      const stock = getValue() as number;
      return (
        <span className={stock < 10 ? "text-red-500" : "text-green-500"}>
          {stock} units
        </span>
      );
    },
  },
];

export default function ProductsPage() {
  return (
    <DataGrid
      data={products}
      columns={columns}
      enableSorting
      enableFiltering
      enableRowSelection
      enablePagination
      pageSize={20}
      emptyMessage="No products found."
      onRowClick={(row) => console.log("Selected:", row.name)}
    />
  );
}

Props Reference

Prop Type Default Description
data T[] required Array of row data
columns ColumnDef<T>[] required TanStack column definitions
enableSorting boolean false Click headers to sort
enableFiltering boolean false Global search input
enableRowSelection boolean false Checkbox selection
enablePagination boolean false Page controls
pageSize number 10 Rows per page
loading boolean false Show loading overlay
emptyMessage string Message when no data
onRowClick (row: T) => void Row click handler

Loading and Empty States

Handle async data with the loading prop:

const [data, setData] = useState<User[]>([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
  fetchUsers().then((users) => {
    setData(users);
    setLoading(false);
  });
}, []);

<DataGrid
  data={data}
  columns={columns}
  loading={loading}
  emptyMessage="No users found."
/>

Custom Cell Renderers

Use the cell property in column definitions to render custom content:

const columns: ColumnDef<User>[] = [
  {
    accessorKey: "name",
    header: "Name",
    cell: ({ row }) => (
      <div className="flex items-center gap-2">
        <Avatar name={row.original.name} size="sm" />
        <span>{row.original.name}</span>
      </div>
    ),
  },
  {
    accessorKey: "role",
    header: "Role",
    cell: ({ getValue }) => (
      <Badge variant={getValue() === "Admin" ? "solid" : "outline"}>
        {getValue() as string}
      </Badge>
    ),
  },
];

What's Next