npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alwinkc/tanstack-table-components

v1.1.2

Published

A React table component library built on TanStack Table with pagination support

Readme

TanStack Table Components

A React component library built on top of @tanstack/react-table with built-in pagination support and beautiful pre-compiled styling.

Features

  • 🎨 Beautiful, modern table design with dark mode support
  • 📱 Responsive and mobile-friendly
  • 🔄 Built-in pagination component
  • 🎯 Full TypeScript support
  • 🚀 Built on TanStack Table v8
  • ⚛️ React 18 & 19 compatible
  • ✨ Pre-compiled CSS - works without Tailwind!
  • 📦 Tiny bundle size (< 10KB)

Installation

npm install @alwinkc/tanstack-table-components @tanstack/react-table
# or
yarn add @alwinkc/tanstack-table-components @tanstack/react-table
# or
pnpm add @alwinkc/tanstack-table-components @tanstack/react-table

Peer Dependencies

This package requires the following peer dependencies:

npm install @tanstack/react-table react react-dom

Supported versions:

  • React: ^18.0.0 or ^19.0.0
  • React DOM: ^18.0.0 or ^19.0.0
  • TanStack Table: ^8.0.0

Setup

Import the CSS in your app's entry point:

// src/index.tsx or src/App.tsx
import "@alwinkc/tanstack-table-components/styles.css";

That's it! No Tailwind configuration needed. The styles are pre-compiled and ready to use.

Non-invasive CSS: The styles are scoped to component classes only and won't affect your existing styles. No CSS reset or global styles are included.

Usage

Basic Example

import "@alwinkc/tanstack-table-components/styles.css";
import {
  useReactTable,
  getCoreRowModel,
  getPaginationRowModel,
  ColumnDef,
} from "@tanstack/react-table";
import { TableComponent, Pagination } from "@alwinkc/tanstack-table-components";

interface User {
  id: number;
  name: string;
  email: string;
  role: string;
}

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

function MyTable() {
  const [data, setData] = useState<User[]>([
    { id: 1, name: "John Doe", email: "[email protected]", role: "Admin" },
    { id: 2, name: "Jane Smith", email: "[email protected]", role: "User" },
    // ... more data
  ]);

  const [pagination, setPagination] = useState({
    pageIndex: 0,
    pageSize: 10,
  });

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    onPaginationChange: setPagination,
    state: {
      pagination,
    },
  });

  return (
    <div>
      <TableComponent table={table} />
      <Pagination
        pagination={true}
        totalPages={table.getPageCount()}
        currentPage={pagination.pageIndex + 1}
        handlePageChange={(page) => table.setPageIndex(page - 1)}
        pageSize={pagination.pageSize}
        onPageSizeChange={(size) => table.setPageSize(size)}
      />
    </div>
  );
}

API Reference

TableComponent

The main table component that renders your data with extensive customization options.

Simple/User-Friendly Props

Quick and easy props for common use cases:

| Prop | Type | Default | Description | | --------------------- | --------------------------------- | -------------- | --------------------------------------- | | table | Table<TData> | Required | TanStack Table instance | | className | string | "" | Additional CSS classes for wrapper | | striped | boolean | false | Alternating row background colors | | hoverable | boolean | false | Row hover effects | | bordered | boolean | false | Add borders around table | | compact | boolean | false | Reduced padding/spacing | | stickyHeader | boolean | false | Fixed header on scroll | | loading | boolean | false | Show loading state | | loadingMessage | string \| () => React.ReactNode | "Loading..." | Custom loading message | | highlightOnHover | boolean | false | Highlight row on hover (blue highlight) | | selectedRowId | string \| number | undefined | ID of selected row to highlight | | getRowId | (row: Row<TData>) => string | undefined | Function to get unique row ID | | size | "sm" \| "md" \| "lg" | undefined | Predefined size variants (sm/md/lg) | | emptyStateMessage | string \| () => React.ReactNode | "No data..." | Custom empty state message | | emptyStateClassName | string | undefined | Custom class for empty state |

Advanced Customization Props

For complex scenarios requiring full control:

Header Customization:

| Prop | Type | Description | | ------------------- | -------------------------------------------- | ----------------------------------------------- | | theadClassName | string | Custom class for <thead> | | theadRowClassName | string | Custom class for header row | | thClassName | string \| (header) => string | Custom class for header cells (can be function) | | thStyle | CSSProperties \| (header) => CSSProperties | Custom inline styles for header cells | | onHeaderClick | (header: Header<TData>) => void | Click handler for header cells |

Body Customization:

| Prop | Type | Description | | ---------------- | ------------------------------------------------ | --------------------------------------------- | | tbodyClassName | string | Custom class for <tbody> | | trClassName | string \| (row, index) => string | Custom class for body rows (can be function) | | trStyle | CSSProperties \| (row, index) => CSSProperties | Custom inline styles for body rows | | tdClassName | string \| (cell) => string | Custom class for body cells (can be function) | | tdStyle | CSSProperties \| (cell) => CSSProperties | Custom inline styles for body cells |

Event Handlers:

| Prop | Type | Description | | ------------------ | ----------------------------- | ---------------------------------- | | onRowClick | (row: Row<TData>) => void | Click handler for rows | | onRowDoubleClick | (row: Row<TData>) => void | Double-click handler for rows | | onRowMouseEnter | (row: Row<TData>) => void | Mouse enter handler for rows | | onRowMouseLeave | (row: Row<TData>) => void | Mouse leave handler for rows | | onCellClick | (cell: Cell<TData>) => void | Click handler for individual cells |

Pagination

A pagination component that works seamlessly with TanStack Table.

Props

| Prop | Type | Required | Default | Description | | ------------------ | ------------------------ | -------- | ------- | ------------------------------- | | pagination | boolean | No | - | Whether to show pagination | | totalPages | number | No | 1 | Total number of pages | | currentPage | number | No | 1 | Current active page (1-indexed) | | handlePageChange | (page: number) => void | Yes | - | Callback when page changes | | pageSize | number | Yes | - | Current page size | | onPageSizeChange | (size: number) => void | Yes | - | Callback when page size changes |

Styling

The components use Tailwind CSS classes and support:

  • Light and dark mode (using dark: variants)
  • Responsive design
  • Hover states
  • Custom scrollbars
  • Smooth transitions

You can customize the appearance by:

  1. Overriding Tailwind classes in your config
  2. Passing custom className props to TableComponent
  3. Using Tailwind's dark mode configuration

TypeScript Support

This library is written in TypeScript and provides full type definitions. The components are generic and will infer types from your data:

interface MyData {
  id: number;
  name: string;
}

// TypeScript will infer the correct types
const table = useReactTable<MyData>({ ... });
<TableComponent<MyData> table={table} />

Examples

Simple Table with Striped Rows

<TableComponent table={table} striped hoverable size="md" />

Table with Row Selection

function SelectableTable() {
  const [selectedId, setSelectedId] = useState<number | undefined>();

  return (
    <TableComponent
      table={table}
      hoverable
      selectedRowId={selectedId}
      getRowId={(row) => row.original.id}
      onRowClick={(row) => setSelectedId(row.original.id)}
    />
  );
}

Compact Bordered Table

<TableComponent table={table} bordered compact stickyHeader />

Custom Row Styling

<TableComponent
  table={table}
  trClassName={(row) =>
    row.original.status === "active" ? "bg-green-50" : "bg-red-50"
  }
  tdClassName={(cell) =>
    cell.column.id === "amount" ? "font-bold text-right" : ""
  }
/>

Loading State

function TableWithLoading() {
  const [isLoading, setIsLoading] = useState(true);

  return (
    <TableComponent
      table={table}
      loading={isLoading}
      loadingMessage="Fetching data..."
    />
  );
}

Interactive Table

<TableComponent
  table={table}
  hoverable
  onRowClick={(row) => console.log("Row clicked:", row.original)}
  onRowDoubleClick={(row) => navigate(`/details/${row.original.id}`)}
  onCellClick={(cell) => console.log("Cell clicked:", cell.getValue())}
  onHeaderClick={(header) => header.column.toggleSorting()}
/>

With Server-Side Pagination

function ServerPaginatedTable() {
  const [data, setData] = useState([]);
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
  const [totalRows, setTotalRows] = useState(0);

  useEffect(() => {
    // Fetch data from your API
    fetchData(pagination.pageIndex, pagination.pageSize).then((result) => {
      setData(result.data);
      setTotalRows(result.total);
    });
  }, [pagination]);

  const table = useReactTable({
    data,
    columns,
    pageCount: Math.ceil(totalRows / pagination.pageSize),
    state: { pagination },
    onPaginationChange: setPagination,
    manualPagination: true,
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <>
      <TableComponent table={table} />
      <Pagination
        pagination={true}
        totalPages={table.getPageCount()}
        currentPage={pagination.pageIndex + 1}
        handlePageChange={(page) => table.setPageIndex(page - 1)}
        pageSize={pagination.pageSize}
        onPageSizeChange={(size) => table.setPageSize(size)}
      />
    </>
  );
}

Custom Column Sizing

const columns: ColumnDef<User>[] = [
  {
    accessorKey: "id",
    header: "ID",
    size: 60, // Fixed width
  },
  {
    accessorKey: "name",
    header: "Name",
    size: 200,
  },
  {
    accessorKey: "email",
    header: "Email",
    // Uses default size (150px) if not specified
  },
];

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Troubleshooting

Styles Not Showing

If your table appears unstyled:

  1. Make sure you imported the CSS:

    import "@alwinkc/tanstack-table-components/styles.css";
  2. Check your bundler is processing CSS:

    • Vite: Should work out of the box
    • Next.js: Should work out of the box
    • Webpack: Make sure css-loader is configured

Dark Mode Not Working

Add the dark class to your root HTML element:

<html className="dark">

License

MIT

Credits

Built with: