@manhphi1309/table
v0.2.13
Published
A robust and accessible table component library for the shadcn-custom monorepo. It provides primitive HTML table components as well as a powerful `DataTable` wrapper integrated with `@tanstack/react-table` for data-driven grids.
Readme
@manhphi1309/table
A robust and accessible table component library for the shadcn-custom monorepo. It provides primitive HTML table components as well as a powerful DataTable wrapper integrated with @tanstack/react-table for data-driven grids.
Subcomponents
TableTableHeaderTableBodyTableFooterTableHeadTableRowTableCellTableCaptionDataTableDataTableHeaderDataTableBodyDataTableFooteruseDataTable
Dependencies
@manhphi1309/utils@tanstack/react-table
Installation
npm install @manhphi1309/tableUsage Example
Primitive Table
For simple, static tables:
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@manhphi1309/table"
export default function SimpleTable() {
return (
<Table>
<TableCaption>A list of your recent invoices.</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Invoice</TableHead>
<TableHead>Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>INV001</TableCell>
<TableCell>$250.00</TableCell>
</TableRow>
</TableBody>
</Table>
)
}DataTable
For data-driven tables, you can integrate with TanStack Table. We offer two ways to initialize your table instances depending on your layout needs: the standard useReactTable or our enhanced useDataTable.
Sizing Mental Model (size, minSize, maxSize)
Our DataTable uses native HTML table-layout: fixed combined with width: 100%. This triggers a very specific native browser rendering engine behavior that you must be aware of:
- Underflowing Tables (Total Column Size < Container Width): If the sum of all your columns is smaller than the screen width, the browser will ignore your strict sizes and proportionally stretch all columns to fill the empty space. This is native HTML table behavior.
- Overflowing Tables (Total Column Size > Container Width): Once the table overflows and forces horizontal scroll, your strict
sizedefinitions finally lock into place. size(Fixed Width): Settingsizeacts as the strict pixel baseline for the column.minSize/maxSize: These act as hard boundaries applied on top of the calculated sizes to prevent columns from getting too small or too large.
Example of strict sizing with boundaries:
const columns: ColumnDef<Payment>[] = [
{
accessorKey: "id",
header: "ID",
size: 100, // The baseline size
minSize: 80, // It will never shrink below 80px (even if window is tiny)
maxSize: 300, // It will never stretch beyond 300px (even if window is massive)
},
]1. Standard: useReactTable
Description:
The native hook provided directly by @tanstack/react-table.
What it does:
It initializes your table instance with standard TanStack behavior. By default, its core engine enforces a hardcoded size: 150 on any column where you do not explicitly define a size.
Usage Example:
"use client"
import {
ColumnDef,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table"
import { DataTable } from "@manhphi1309/table"
type Payment = { id: string; amount: number; status: string }
const columns: ColumnDef<Payment>[] = [
// Without a size defined, TanStack silently injects size: 150
{ accessorKey: "id", header: "ID" },
{ accessorKey: "amount", header: "Amount" },
]
export default function StandardTable({ data }: { data: Payment[] }) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
return <DataTable table={table} />
}2. Enhanced: useDataTable
Description:
A custom wrapper hook exported by @manhphi1309/table that enhances the native TanStack hook with modern CSS Flexbox-like layout capabilities.
What it does:
It intercepts your column definitions before TanStack processes them. If it detects that you completely omitted the size property from a column, it automatically injects meta: { stretch: true }. This signals the <DataTable> component to apply width: auto, allowing that single column to absorb the vast majority of the empty space on large screens (rather than every column stretching equally).
Usage Example:
"use client"
import { ColumnDef, getCoreRowModel } from "@tanstack/react-table"
import { DataTable, useDataTable } from "@manhphi1309/table"
type Payment = { id: string; amount: number; status: string }
const columns: ColumnDef<Payment>[] = [
// This column is strictly locked to 60px wide
{ accessorKey: "id", header: "ID", size: 60 },
// This column is strictly locked to 100px wide
{ accessorKey: "status", header: "Status", size: 100 },
// ELASTIC COLUMN
// By omitting 'size', useDataTable flags this to stretch (width: auto)
// It will absorb almost all the empty space on massive monitors!
{ accessorKey: "amount", header: "Amount" },
]
export default function EnhancedTable({ data }: { data: Payment[] }) {
const table = useDataTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
return <DataTable table={table} withVerticalBorders />
}3. Comparison: useReactTable vs useDataTable
| Feature | useReactTable (Native) | useDataTable (Enhanced) |
| ------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Missing size behavior | Forces exactly 150px | Forces width: auto (stretches to fill space) |
| When Table is Smaller Than Screen | ALL columns stretch proportionally to fill the empty space (Native browser behavior) | The elastic column(s) aggressively stretch to absorb the space, leaving fixed columns closer to their intended size |
| Horizontal Scrolling | Works perfectly, columns lock to strict sizes | Retains TanStack's 150px minimum width limit, ensuring stretched columns never collapse to 0px when overflowed |
| Best used for... | Data-heavy grids where every column needs a strict pixel size | Modern UI layouts where you want a "Main" column (like a Description or Email) to automatically fill empty space |
