TNKS Data Table

Examples

Real-world implementation examples for common use cases

Implementation Examples

Learn from real-world implementations of the Advanced Data Table Component.

Live Examples

You can see these examples running in the demo application:

Quick Start Examples

Minimal Table

Simplest possible implementation:

src/app/(section)/users/page.tsx
"use client";

import { DataTable } from "@/components/data-table/data-table";
import { ColumnDef } from "@tanstack/react-table";
import { useUsersData } from "./utils/data-fetching";

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

export default function UsersPage() {
  return (
    <DataTable
      getColumns={() => columns}
      fetchDataFn={useUsersData}
      idField="id"
    />
  );
}

Table with Row Selection

Add checkboxes for bulk operations:

import { Checkbox } from "@/components/ui/checkbox";

const getColumns = (handleRowDeselection): ColumnDef<User>[] => [
  {
    id: "select",
    header: ({ table }) => (
      <Checkbox
        checked={table.getIsAllPageRowsSelected()}
        onCheckedChange={(value) =>
          table.toggleAllPageRowsSelected(!!value)
        }
      />
    ),
    cell: ({ row }) => (
      <Checkbox
        checked={row.getIsSelected()}
        onCheckedChange={(value) => row.toggleSelected(!!value)}
      />
    ),
    size: 50,
  },
  { accessorKey: "name", header: "Name" },
  { accessorKey: "email", header: "Email" },
];

<DataTable
  getColumns={getColumns}
  fetchDataFn={useUsersData}
  idField="id"
  config={{ enableRowSelection: true }}
/>

Table with Export

Enable CSV and Excel export:

export function useExportConfig() {
  return {
    headers: ["id", "name", "email", "created_at"],
    columnMapping: {
      id: "ID",
      name: "Name",
      email: "Email",
      created_at: "Created",
    },
    entityName: "users",
  };
}

<DataTable
  getColumns={getColumns}
  fetchDataFn={useUsersData}
  exportConfig={useExportConfig()}
  idField="id"
/>

Table with Subrows

Display hierarchical data:

<DataTable
  getColumns={getColumns}
  fetchDataFn={useOrdersData}
  idField="id"
  subRowsConfig={{
    enabled: true,
    mode: 'same-columns',
    expandIconPosition: 'first',
  }}
/>

Common Patterns

Custom Toolbar Actions

Add your own buttons to the toolbar:

const ToolbarOptions = ({ selectedRows, resetSelection }) => (
  <div className="flex gap-2">
    <AddUserButton />
    {selectedRows.length > 0 && (
      <>
        <Button onClick={() => handleBulkDelete(selectedRows)}>
          Delete ({selectedRows.length})
        </Button>
        <Button onClick={resetSelection}>Clear</Button>
      </>
    )}
  </div>
);

<DataTable
  getColumns={getColumns}
  fetchDataFn={useUsersData}
  idField="id"
  renderToolbarContent={({ selectedRows, resetSelection }) => (
    <ToolbarOptions
      selectedRows={selectedRows}
      resetSelection={resetSelection}
    />
  )}
/>

Row Click Handler

Execute logic when a row is clicked:

const handleRowClick = (user: User, index: number) => {
  router.push(`/users/${user.id}`);
  // or
  setSelectedUser(user);
  setDialogOpen(true);
};

<DataTable
  getColumns={getColumns}
  fetchDataFn={useUsersData}
  idField="id"
  onRowClick={handleRowClick}
/>

Custom Column Rendering

Format and style cell content:

{
  accessorKey: "status",
  header: "Status",
  cell: ({ row }) => {
    const status = row.getValue("status");
    const variant = {
      active: "success",
      inactive: "secondary",
      pending: "warning",
    }[status] || "outline";

    return <Badge variant={variant}>{status}</Badge>;
  },
}

Sortable Columns

Add sorting to columns:

import { DataTableColumnHeader } from "@/components/data-table/column-header";

{
  accessorKey: "name",
  header: ({ column }) => (
    <DataTableColumnHeader column={column} title="Name" />
  ),
  enableSorting: true,
}

Date Formatting

Format dates consistently:

import { format } from "date-fns";

{
  accessorKey: "created_at",
  header: "Created",
  cell: ({ row }) => {
    const date = new Date(row.getValue("created_at"));
    return <div>{format(date, "MMM d, yyyy HH:mm")}</div>;
  },
}

Currency Formatting

Display monetary values:

{
  accessorKey: "amount",
  header: "Amount",
  cell: ({ row }) => {
    const amount = parseFloat(row.getValue("amount"));
    return (
      <div className="font-medium">
        ${amount.toLocaleString('en-US', {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        })}
      </div>
    );
  },
}

Row Actions Menu

Add actions to each row:

import { DotsHorizontalIcon } from "@radix-ui/react-icons";

{
  id: "actions",
  cell: ({ row }) => (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="sm">
          <DotsHorizontalIcon />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem onClick={() => handleEdit(row.original)}>
          Edit
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => handleDelete(row.original)}>
          Delete
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  ),
}

Next Steps

How is this guide?