nextjs-reusable-table
Use this skill when building or customising data tables with nextjs-reusable-table. Covers installation, all props, sorting, pagination, search, row actions, dark mode, custom styling, and Tailwind setup for Next.js 13+ and React 18+.
Best use case
nextjs-reusable-table is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use this skill when building or customising data tables with nextjs-reusable-table. Covers installation, all props, sorting, pagination, search, row actions, dark mode, custom styling, and Tailwind setup for Next.js 13+ and React 18+.
Teams using nextjs-reusable-table should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/nextjs-reusable-table/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How nextjs-reusable-table Compares
| Feature / Agent | nextjs-reusable-table | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use this skill when building or customising data tables with nextjs-reusable-table. Covers installation, all props, sorting, pagination, search, row actions, dark mode, custom styling, and Tailwind setup for Next.js 13+ and React 18+.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# nextjs-reusable-table Skill
## When to Use This Skill
Invoke this skill when the user is:
- Installing or setting up `nextjs-reusable-table`
- Rendering a `<TableComponent>` with data
- Adding sorting, pagination, search, or row actions to a table
- Customising table styles via `customClassNames` or `disableDefaultStyles`
- Using `TableSkeleton`, `PaginationComponent`, or `ActionDropdown` standalone
- Debugging style leaking, Tailwind config, or dark mode issues
## Installation
```bash
npm install nextjs-reusable-table
```
Then import the CSS (required for `.rtbl-*` scoped styles):
```ts
// In your root layout or _app.tsx
import "nextjs-reusable-table/dist/index.css";
```
**Tailwind v3** — add to `tailwind.config.js` so utilities used inside the library are generated:
```js
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/nextjs-reusable-table/dist/**/*.{js,mjs}",
]
```
**Tailwind v4** — add a `@source` directive:
```css
@import "tailwindcss";
@source "../node_modules/nextjs-reusable-table/dist";
```
## Basic Usage
```tsx
"use client";
import { TableComponent } from "nextjs-reusable-table";
import "nextjs-reusable-table/dist/index.css";
interface User {
id: string;
name: string;
email: string;
role: string;
}
const users: User[] = [
{ id: "1", name: "Alice", email: "alice@example.com", role: "Admin" },
{ id: "2", name: "Bob", email: "bob@example.com", role: "User" },
];
export default function UsersTable() {
return (
<TableComponent<User>
columns={["Name", "Email", "Role"]}
data={users}
props={["name", "email", "role"]}
/>
);
}
```
## Core Props Reference
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `columns` | `string[]` | required | Column header labels |
| `data` | `T[]` | required | Row data array |
| `props` | `ReadonlyArray<keyof T>` | required | Object keys to display per column |
| `loading` | `boolean` | `false` | Show loading skeleton |
| `searchValue` | `string` | — | Filter rows by this string (searches all columns) |
| `actions` | `boolean` | `false` | Enable per-row action dropdown |
| `actionTexts` | `string[]` | — | Labels for dropdown actions |
| `actionFunctions` | `Array<(item: T) => void>` | — | Handlers for dropdown actions |
| `rowOnClick` | `(item: T) => void` | — | Row click handler |
| `enableDarkMode` | `boolean` | `true` | Auto-detect OS dark mode |
| `disableDefaultStyles` | `boolean` | `false` | Strip all default styles (full headless mode) |
| `enablePagination` | `boolean` | `false` | Enable built-in pagination |
| `page` | `number` | `1` | Current page (controlled) |
| `setPage` | `(page: number) => void` | — | Page change handler |
| `itemsPerPage` | `number` | `10` | Rows per page |
| `totalPages` | `number` | — | Override for server-side pagination |
| `sortableProps` | `Array<keyof T>` | `[]` | Columns that trigger `onSort` |
| `onSort` | `(prop: keyof T) => void` | — | Sort handler |
| `formatValue` | `(value: string, prop: string, item: T) => ReactNode` | — | Custom cell renderer |
| `formatHeader` | `(header: string, prop: string, index: number) => ReactNode` | — | Custom header renderer |
| `renderRow` | `(item: T, index: number) => ReactNode` | — | Full custom row renderer |
| `renderPagination` | `(props) => ReactNode` | — | Custom pagination renderer |
| `showRemoveColumns` | `boolean` | `false` | Show column hide/show controls |
| `maxHeight` | `string \| number` | `"600px"` | Scroll container max height |
| `scrollBehavior` | `"auto" \| "scroll" \| "visible" \| "hidden"` | `"auto"` | Overflow scroll style |
| `tableLayout` | `"auto" \| "fixed" \| "inherit"` | — | CSS `table-layout` |
| `cellExpansion` | `CellExpansionConfig` | `{enabled:true,maxWidth:200,behavior:"truncate"}` | Cell truncation/expansion |
| `accessibility` | `AccessibilityConfig` | `{keyboardNavigation:true}` | ARIA and keyboard config |
| `noContentProps` | `{text?,icon?,name?}` | — | Empty state customisation |
| `customClassNames` | `CustomClassNames` | `{}` | Per-element Tailwind class overrides |
| `customStyles` | `{container?,table?,scrollContainer?,loading?}` | `{}` | Inline style overrides |
## Common Patterns
### Sorting (client-side)
```tsx
const [sortProp, setSortProp] = useState<keyof User | null>(null);
const [sortAsc, setSortAsc] = useState(true);
const sorted = useMemo(() => {
if (!sortProp) return users;
return [...users].sort((a, b) =>
sortAsc
? String(a[sortProp]).localeCompare(String(b[sortProp]))
: String(b[sortProp]).localeCompare(String(a[sortProp]))
);
}, [users, sortProp, sortAsc]);
<TableComponent<User>
columns={["Name", "Email"]}
data={sorted}
props={["name", "email"]}
sortableProps={["name", "email"]}
onSort={(prop) => {
if (prop === sortProp) setSortAsc((a) => !a);
else { setSortProp(prop); setSortAsc(true); }
}}
/>
```
### Pagination (built-in)
```tsx
const [page, setPage] = useState(1);
<TableComponent<User>
columns={["Name", "Email"]}
data={users}
props={["name", "email"]}
enablePagination
page={page}
setPage={setPage}
itemsPerPage={20}
/>
```
### Row Actions
```tsx
<TableComponent<User>
columns={["Name", "Email"]}
data={users}
props={["name", "email"]}
actions
actionTexts={["Edit", "Delete"]}
actionFunctions={[
(user) => router.push(`/users/${user.id}/edit`),
(user) => deleteUser(user.id),
]}
/>
```
### Custom Cell Rendering
```tsx
<TableComponent<User>
columns={["Name", "Status"]}
data={users}
props={["name", "status"]}
formatValue={(value, prop) => {
if (prop === "status") {
return (
<span className={value === "active" ? "text-green-600" : "text-red-500"}>
{value}
</span>
);
}
return value;
}}
/>
```
### Headless Mode (full style control)
```tsx
<TableComponent<User>
columns={["Name", "Email"]}
data={users}
props={["name", "email"]}
disableDefaultStyles
customClassNames={{
container: "border rounded-xl shadow",
table: "w-full text-sm",
thead: "bg-slate-100",
th: "px-4 py-3 text-left font-semibold",
tr: "border-b hover:bg-slate-50",
td: "px-4 py-3",
}}
/>
```
## Standalone Components
```tsx
import {
TableSkeleton,
PaginationComponent,
ActionDropdown,
NoContentComponent,
} from "nextjs-reusable-table";
// Loading skeleton
<TableSkeleton enableDarkMode />
// Pagination only
<PaginationComponent
page={page}
setPage={setPage}
totalPages={totalPages}
/>
```
## Utility Functions
```ts
import { formatDate, isDateString, trimText } from "nextjs-reusable-table";
formatDate(new Date(), true); // "Mar 8, 2026, 09:30 AM"
isDateString("2024-01-15"); // true
trimText("Long string here", 20); // "Long string here..."
```
## Troubleshooting
| Issue | Fix |
|-------|-----|
| Tailwind classes not applying | Add library dist to Tailwind `content` / `@source` — see Installation above |
| Styles leaking into other pages | Upgrade to v4.1.0+ (skeleton CSS `@import` removed from `dist/index.css`) |
| React peer dep warning | Library requires `react >=18`. Run `npm install react@latest react-dom@latest` |
| `"use client"` error in Pages Router | Wrap import in a client component or use dynamic import with `ssr: false` |
| Dark mode not activating | Pass `enableDarkMode={true}` (default) and ensure your OS dark mode is on, or toggle manually via `enableDarkMode={false}` |
## Full API Reference
See [references/api-reference.md](references/api-reference.md) for complete type definitions.Related Skills
world-extractable-value
Extract value from world transitions via Markov blanket arbitrage. WEV = PoA - 1. Paradigm Multiverse Finance integration.
unstable-manifold
Manifold of points diverging from equilibrium
stable-manifold
Manifold of points converging to equilibrium
performing-soc-tabletop-exercise
Performs tabletop exercises for SOC teams simulating security incidents through discussion-based scenarios to test incident response procedures, communication workflows, and decision-making under pressure without impacting production systems. Use when organizations need to validate IR playbooks, train analysts, or meet compliance requirements for incident response testing.
performing-ransomware-tabletop-exercise
Plans and facilitates tabletop exercises simulating ransomware incidents to test organizational readiness, decision-making, and communication procedures. Designs realistic scenarios based on current ransomware threat actors (LockBit, ALPHV/BlackCat, Cl0p), injects covering double extortion, backup destruction, and regulatory notification requirements. Evaluates participant responses against NIST CSF and CISA guidelines. Activates for requests involving ransomware tabletop, incident response exercise, or ransomware readiness drill.
implementing-immutable-backup-with-restic
Implements immutable backup strategy using restic with S3-compatible storage and object lock for ransomware-resistant data protection. Automates backup creation, integrity verification via restic check --read-data, snapshot retention policy enforcement, and restore testing. Integrates with AWS S3 Object Lock, MinIO, and Backblaze B2 for WORM (Write Once Read Many) storage that prevents backup deletion or encryption by ransomware actors.
World Extractable Value via Pair-Graph Hodge Decomposition
**Status**: 🧪 Draft — K₃/K₄/K₅ verified
nextjs-expert
Next.js 14+ gotchas and decision criteria. Covers server/client boundary, caching strategy, and data fetching patterns Claude commonly gets wrong.
nextjs-react
This skill should be used when the user asks about "Next.js security", "React security", "Server Components", "Server Actions", "Route Handlers", "RSC vulnerabilities", "SSR security", or needs comprehensive Next.js/React security analysis during whitebox security review.
nextjs-app-router-patterns
Master Next.js 14+ App Router with Server Components, streaming, parallel routes, and advanced data fetching. Use when building Next.js applications, implementing SSR/SSG, or optimizing React Server Components.
postgresql-table-design
Use this skill when designing or reviewing a PostgreSQL-specific schema. Covers best-practices, data types, indexing, constraints, performance patterns, and advanced features
draftable-automation
Automate Draftable tasks via Rube MCP (Composio). Always search tools first for current schemas.