Skip to content
ilinxa/pro-ui

Data Table

alphav0.1.2

A typed, composable table primitive with column accessors and per-cell rendering.

Category: Data DisplayUpdated: 2026-08-11Created: 2026-04-26Author: ilinxa

Context

DataTable is the foundational data display component — every more advanced table (sortable, paginated, virtualized) in this registry is expected to compose on top of it. It is deliberately small: one render, no client state, no DOM-level magic.

Installation

Initialize shadcn (once per project)Seeds lib/utils.ts and components.json. Skip if you've already used any shadcn component.
pnpm dlx shadcn@latest init
Register the @ilinxa namespace (once per project)Add to your components.json. Merge with existing config.
"registries": {
  "@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}
Install the component
pnpm dlx shadcn@latest add @ilinxa/data-table

Add -fixtures for dummy data:

pnpm dlx shadcn@latest add @ilinxa/data-table-fixtures

Preview

A starter table rendered from dummy data.
NameRoleStatusLast Seen
Aria Montgomeryaria@ilinxa.dev
OwnerActive2 minutes ago
Bilal Hashemibilal@ilinxa.dev
AdminActive1 hour ago
Camille Okaforcamille@ilinxa.dev
MemberInvited
Dimitri Volkovdimitri@ilinxa.dev
MemberActiveYesterday
Esme Tanakaesme@ilinxa.dev
ViewerSuspended3 weeks ago

Demo source

demo.tsxtsx

Usage

When to use

Reach for DataTable when you need to render a list of records with consistent column structure. It is intentionally unopinionated about sorting, filtering, and pagination — those concerns compose on top via the column accessor and parent state.

Basic example

import { DataTable, type DataTableColumn } from "@/components/data-table"

type User = { id: string; name: string; email: string }

const columns: DataTableColumn<User>[] = [
  { id: "name",  header: "Name",  accessor: (r) => r.name },
  { id: "email", header: "Email", accessor: (r) => r.email },
]

export function Example({ users }: { users: User[] }) {
  return (
    <DataTable
      columns={columns}
      rows={users}
      rowKey={(r) => r.id}
    />
  )
}

Notes

  • accessor can return any ReactNode, so composing badges, avatars, or actions per cell is the intended path.
  • Column align applies to both header and cells; use width for fixed-width columns (e.g. action menus).
  • Pass an emptyState node to override the default empty message.

Features

  • Generic over row type — fully type-safe column accessors
  • Per-column alignment and fixed widths
  • Custom empty state slot
  • Composes any ReactNode in cells (badges, avatars, actions)

Tags

tabledatalisttyped

Dependencies

shadcn primitives: table