Skip to content

Latest commit

 

History

History
368 lines (303 loc) · 9.27 KB

File metadata and controls

368 lines (303 loc) · 9.27 KB
title Basic Table
description Add pagination, sorting, and column visibility controls to your data table.

import CodePreview from "@/components/markdown/code-preview/code-preview.astro" import CollapsiblePreview from "@/components/markdown/collapsible-preview.astro" import CliCommandCode from "@/components/markdown/cli-command-code/cli-command-code.astro"

Introduction

The Basic Table builds on the Simple Table by adding pagination, sorting, and column visibility. This is the most common table implementation and suitable for most use cases.

Installation

Install the DataTable core and add-ons for this example:

First time using @niko-table? See the Installation Guide to set up the registry.

For other add-ons or manual copy-paste, see the Installation Guide.

Prerequisites

We are going to build a table to show products. Here's what our data looks like:

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

const data: Product[] = [
  { id: "1", name: "Laptop", category: "Electronics", price: 999, stock: 50 },
  { id: "2", name: "Mouse", category: "Electronics", price: 29, stock: 150 },
  // ...
]

Basic Table

Let's start by building a basic table with pagination and sorting.

Column Definitions

First, we'll define our columns with sortable headers.

"use client"

import {
  DataTableColumnHeader,
  DataTableColumnTitle,
} from "@/components/niko-table/components/data-table-column-header"
import { DataTableColumnSortMenu } from "@/components/niko-table/components/data-table-column-sort"
import type { DataTableColumnDef } from "@/components/niko-table/types"

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

export const columns: DataTableColumnDef<Product>[] = [
  {
    accessorKey: "name",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Product" },
  },
  {
    accessorKey: "category",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Category" },
  },
  {
    accessorKey: "price",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Price" },
    cell: ({ row }) => {
      const price = parseFloat(row.getValue("price"))
      return <div className="font-medium">${price.toFixed(2)}</div>
    },
  },
  {
    accessorKey: "stock",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Stock" },
  },
]

<DataTable /> component

Next, we'll create a <DataTable /> component with pagination and sorting enabled.

"use client"

import { DataTableRoot } from "@/components/niko-table/core/data-table-root"
import { DataTable } from "@/components/niko-table/core/data-table"
import {
  DataTableHeader,
  DataTableBody,
} from "@/components/niko-table/core/data-table-structure"
import { DataTableToolbarSection } from "@/components/niko-table/components/data-table-toolbar-section"
import { DataTablePagination } from "@/components/niko-table/components/data-table-pagination"
import { DataTableViewMenu } from "@/components/niko-table/components/data-table-view-menu"
import {
  DataTableColumnHeader,
  DataTableColumnTitle,
} from "@/components/niko-table/components/data-table-column-header"
import { DataTableColumnSortMenu } from "@/components/niko-table/components/data-table-column-sort"
import type { DataTableColumnDef } from "@/components/niko-table/types"

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

const columns: DataTableColumnDef<Product>[] = [
  {
    accessorKey: "name",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Product" },
  },
  {
    accessorKey: "category",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Category" },
  },
  {
    accessorKey: "price",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Price" },
    cell: ({ row }) => {
      const price = parseFloat(row.getValue("price"))
      return <div className="font-medium">${price.toFixed(2)}</div>
    },
  },
  {
    accessorKey: "stock",
    header: () => (
      <DataTableColumnHeader>
        <DataTableColumnTitle />
        <DataTableColumnSortMenu />
      </DataTableColumnHeader>
    ),
    meta: { label: "Stock" },
  },
]

export function BasicTable({ data }: { data: Product[] }) {
  return (
    <DataTableRoot
      data={data}
      columns={columns}
      config={{
        enablePagination: true,
        enableSorting: true,
        enableMultiSort: true,
        initialPageSize: 10,
      }}
    >
      <DataTableToolbarSection className="justify-between">
        <h2 className="text-lg font-semibold">Products</h2>
        <DataTableViewMenu />
      </DataTableToolbarSection>

      <DataTable>
        <DataTableHeader />
        <DataTableBody />
      </DataTable>

      <DataTablePagination pageSizeOptions={[5, 10, 20]} />
    </DataTableRoot>
  )
}

Pagination

Pagination is automatically enabled when you set enablePagination: true in the config. The DataTablePagination component provides:

  • Page navigation (Previous/Next)
  • Page size selector
  • Current page info (e.g., "1-10 of 100")

Custom Page Sizes

You can customize the available page sizes:

<DataTablePagination pageSizeOptions={[10, 25, 50, 100]} />

Sorting

Sorting is enabled by using DataTableColumnHeader in your column definitions. Click any column header to sort by that column.

Multi-Column Sorting

Hold Shift and click multiple column headers to sort by multiple columns:

<DataTableRoot
  data={data}
  columns={columns}
  config={{
    enableMultiSort: true, // Enable multi-column sorting
  }}
>
  {/* ... */}
</DataTableRoot>

Disable Sorting

To disable sorting for a specific column:

{
  accessorKey: "id",
  header: "ID",
  enableSorting: false, // This column cannot be sorted
}

Column Visibility

The DataTableViewMenu component adds a dropdown to show/hide columns:

<DataTableToolbarSection className="justify-between">
  <h2 className="text-lg font-semibold">Products</h2>
  <DataTableViewMenu />
</DataTableToolbarSection>

Disable Column Hiding

To prevent specific columns from being hidden:

{
  accessorKey: "id",
  header: "ID",
  enableHiding: false, // This column cannot be hidden
}

Controlled State

Full control over table state:

import { useState } from "react"
import type {
  PaginationState,
  SortingState,
  VisibilityState,
} from "@tanstack/react-table"

export function ControlledBasicTable({ data }: { data: Product[] }) {
  const [pagination, setPagination] = useState<PaginationState>({
    pageIndex: 0,
    pageSize: 10,
  })
  const [sorting, setSorting] = useState<SortingState>([])
  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})

  return (
    <DataTableRoot
      data={data}
      columns={columns}
      state={{
        pagination,
        sorting,
        columnVisibility,
      }}
      onPaginationChange={setPagination}
      onSortingChange={setSorting}
      onColumnVisibilityChange={setColumnVisibility}
    >
      <DataTableToolbarSection className="justify-between">
        <h2 className="text-lg font-semibold">Products</h2>
        <DataTableViewMenu />
      </DataTableToolbarSection>

      <DataTable>
        <DataTableHeader />
        <DataTableBody />
      </DataTable>

      <DataTablePagination />
    </DataTableRoot>
  )
}

When to Use

✅ Use Basic Table when:

  • You have 50+ rows that need pagination
  • Users need to sort data
  • You want column visibility controls
  • You don't need search or filtering

❌ Consider other options when:

Next Steps