Data Table

A table component with sorting, filtering, and pagination compatible with VitNode API.

Usage

import { DataTable } from 'vitnode/components/table/data-table';
<DataTable
  columns={[
    { id: 'name', label: 'Name' },
    { id: 'email', label: 'Email' },
    { id: 'role', label: 'Role' },
    { id: 'status', label: 'Status' },
    { id: 'id', label: 'Actions' },
  ]}
  edges={data.edges}
  pageInfo={data.pageInfo}
  order={{
    defaultOrder: {
      column: 'name',
      order: 'asc',
    },
  }}
/>
PropTypeDefault
pageInfo
{ hasNextPage: boolean; hasPreviousPage: boolean; startCursor: string; endCursor: string; }
-
order
{ columns?: string[]; defaultOrder: { column: string; order: 'asc' | 'desc'; }; }
-
edges
Array
-
columns
{ id: string; label: string; cell?: (props: { row: any; allData: any[]; }) => JSX.Element; }[]
-

Cell Renderer

You can customize how each cell is rendered using the cell property. The renderer function receives the current row data and all table data as parameters.

<DataTable
  columns={[
    {
      id: 'id',
      label: 'Id',
      cell: ({ row, allData }) => (
        <span>
          {row.id} - all data {allData.length}
        </span>
      ),
    },
    { id: 'createdAt', label: 'Created at' },
  ]}
  edges={data.edges}
  pageInfo={data.pageInfo}
  order={{
    columns: ['createdAt', 'id'],
    defaultOrder: {
      order: 'desc',
    },
  }}
/>

Order Configuration

If you want to enable sorting on specific columns, you can specify them in the columns property.

order={{
  columns: ['createdAt', 'id', 'name'],
  defaultOrder: {
    column: 'createdAt',
    order: 'desc',
  }
}}

Complete Example

Here's a complete example showing how to use the DataTable component in a page:

import {
  DataTable,
  SearchParamsDataTable,
} from 'vitnode/components/table/data-table';
import { userModule } from '@/api/modules/user/user.module';
import { fetcher } from 'vitnode/lib/fetcher';

export const UsersView = async ({
  searchParams,
}: {
  searchParams: Promise<SearchParamsDataTable>;
}) => {
  const query = await searchParams;
  const res = await fetcher(userModule, {
    path: '/users',
    method: 'get',
    module: 'user',
    args: {
      query,
    },
    withPagination: true,
  });
  const data = await res.json();

  return (
    <div className="container mx-auto p-4">
      <DataTable
        columns={[
          {
            id: 'id',
            label: 'ID',
          },
          {
            id: 'username',
            label: 'Username',
            cell: ({ row }) => (
              <span className="font-medium">{row.username}</span>
            ),
          },
          { id: 'email', label: 'Email' },
          { id: 'createdAt', label: 'Created at' },
        ]}
        edges={data.edges}
        order={{
          columns: ['id', 'username', 'email', 'createdAt'],
          defaultOrder: {
            column: 'createdAt',
            order: 'desc',
          },
        }}
        pageInfo={data.pageInfo}
      />
    </div>
  );
};

On this page