### Install Shadcn UI Base Components
Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt
Before installing the data-table component, ensure you have the necessary Shadcn UI base components installed. This command initializes Shadcn UI in your project.
```bash
npx shadcn@latest init
```
```bash
npx shadcn@latest add button checkbox input select popover calendar dropdown-menu separator table command
```
--------------------------------
### Install Shadcn UI Components
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Use the Shadcn CLI to initialize Shadcn UI and install all required base components for the data table. Do not copy these manually.
```bash
# Initialize Shadcn UI (if you haven't already)
npx shadcn@latest init
# Install all required components in one command
npx shadcn@latest add alert avatar badge button calendar checkbox command dialog dropdown-menu form input label popover select separator skeleton sonner table
```
--------------------------------
### CamelCase API Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Illustrates column and table configuration setup for APIs using camelCase. The accessorKeys and defaultSortBy should directly correspond to the API's camelCase field names.
```typescript
// API Response
{
"data": [
{
"id": 1,
"userName": "John Doe",
"createdAt": "2023-01-01T10:00:00Z",
"totalExpenses": "1234.56"
}
]
}
// Column Definitions (matches API exactly)
{
accessorKey: "userName", // ✅ Matches API field
header: "Name"
}
{
accessorKey: "createdAt", // ✅ Matches API field
header: "Created"
}
// Table Configuration
config={{
defaultSortBy: "createdAt", // ✅ Matches API field
// ... other options
}}
```
--------------------------------
### Install Dependencies and Run Checks
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/CODE_QUALITY_REPORT.md
Install project dependencies and run essential checks like type checking, linting, and building. These commands are typically run locally before testing or deployment.
```bash
npm install
npm run typecheck
npm run lint
npm run build
```
--------------------------------
### Install Shadcn UI Components and Data Table
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Install required Shadcn UI components and the data-table component using the Shadcn CLI. Ensure table styles are added to your globals.css.
```bash
npx shadcn@latest init
npx shadcn@latest add button checkbox input select popover calendar dropdown-menu separator table command
npx shadcn@latest add https://tnks-data-table.vercel.app/r/data-table.json
npx shadcn@latest add https://tnks-data-table.vercel.app/r/calendar-date-picker.json
```
--------------------------------
### Install tnks-data-table and Calendar Component
Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt
Install the data-table component and its companion CalendarDatePicker component using the Shadcn CLI. This command fetches the component definitions from the provided registry URL.
```bash
npx shadcn@latest add https://tnks-data-table.vercel.app/r/data-table.json
```
```bash
npx shadcn@latest add https://tnks-data-table.vercel.app/r/calendar-date-picker.json
```
--------------------------------
### Install Core Data Table Dependencies with npm
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Install the core npm packages required for the data table functionality, including react-table, react-query, and form handling libraries.
```bash
npm install @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react
npm install @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot
npm install react-day-picker cmdk
npm install @types/xlsx
npm install --save-dev @tanstack/eslint-plugin-query
```
--------------------------------
### Name-based Sorting Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of configuring a DataTable for alphabetical sorting by a 'name' column in ascending order.
```typescript
// Alphabetical ordering
defaultSortBy: "name",
defaultSortOrder: "asc"
```
--------------------------------
### Add Entity Page Setup
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Sets up the main page component for managing entities, including metadata and suspense for the entity table.
```typescript
// src/app/(section)/entities/page.tsx
import { Metadata } from "next";
import { Suspense } from "react";
import EntityTable from "./entity-table";
export const metadata: Metadata = {
title: "Entities Management",
};
export default function EntitiesPage() {
return (
Entities List
Loading...}>
);
}
```
--------------------------------
### Complete TNKS Data Table Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
A full example demonstrating the TNKS Data Table with row selection, toolbar options, data fetching, and conditional row click handling for navigation or modal display. Ensure all imported components and functions are correctly defined.
```typescript
// src/app/(section)/users/users-table/index.tsx
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { DataTable } from "@/components/data-table/data-table";
import { User } from "./schema";
import { UserDetailModal } from "./components/user-detail-modal";
export default function UsersTable() {
const router = useRouter();
const [selectedUser, setSelectedUser] = useState(null);
const [isModalOpen, setIsModalOpen] = useState(false);
// Handle row clicks with conditional logic
const handleRowClick = (user: User, rowIndex: number) => {
// Option 1: Navigate to detail page
if (user.role === 'admin') {
router.push(`/admin/users/${user.id}`);
return;
}
// Option 2: Open modal for regular users
setSelectedUser(user);
setIsModalOpen(true);
};
return (
<>
getColumns={getColumns}
exportConfig={useExportConfig()}
fetchDataFn={useUsersData}
fetchByIdsFn={fetchUsersByIds}
idField="id"
onRowClick={handleRowClick}
renderToolbarContent={({ selectedRows, allSelectedIds, totalSelectedCount, resetSelection }) => (
)}
config={{
enableRowSelection: true,
enableSearch: true,
enableDateFilter: true,
enableColumnVisibility: true,
enableUrlState: true,
}}
/>
>
);
}
```
--------------------------------
### Install Core Data Table Dependencies with Bun
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Install the core npm packages required for the data table functionality using Bun. This includes react-table, react-query, and form handling libraries.
```bash
bun add @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot react-day-picker cmdk @types/xlsx
```
--------------------------------
### Priority-based Sorting Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of configuring a DataTable to sort by a 'priority' column in descending order, showing high priority items first.
```typescript
// Show high priority items first
defaultSortBy: "priority",
defaultSortOrder: "desc"
```
--------------------------------
### Row Click Navigation Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of using the 'onRowClick' handler for navigation. It utilizes 'useRouter' from 'next/navigation' to redirect to a user detail page based on the clicked row's ID.
```typescript
import { useRouter } from 'next/navigation';
function UsersTable() {
const router = useRouter();
const handleRowClick = (user: User, rowIndex: number) => {
// Navigate to user detail page
router.push(`/users/${user.id}`);
};
return (
// ... other props
onRowClick={handleRowClick}
/>
);
}
```
--------------------------------
### Install Core Data Table Dependencies with pnpm
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Install the core npm packages required for the data table functionality using pnpm. This includes react-table, react-query, and form handling libraries.
```bash
pnpm add @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot react-day-picker cmdk @types/xlsx
```
--------------------------------
### React Query Provider Setup
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Configure the React Query provider by wrapping your root layout with QueryClientProvider. This sets up default options for queries, such as staleTime and retry behavior.
```typescript
// src/app/layout.tsx or your root layout
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState } from "react";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const [queryClient] = useState(() => new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
retry: false,
},
},
}));
return (
{children}
);
}
```
--------------------------------
### DataTable Component Example
Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt
A complete working example demonstrating the integration of the DataTable component with React Query for data fetching and Zod for schema validation. Includes API fetch function, React Query hook, column definitions, and export configuration.
```tsx
"use client";
import { DataTable } from "@/components/data-table/data-table";
import { ColumnDef } from "@tanstack/react-table";
import { useQuery, keepPreviousData } from "@tanstack/react-query";
import { z } from "zod";
import { Checkbox } from "@/components/ui/checkbox";
import { DataTableColumnHeader } from "@/components/data-table/column-header";
// 1. Define schema with Zod
const userSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string(),
created_at: z.string(),
expense_count: z.number(),
total_expenses: z.string(),
});
type User = z.infer;
const usersResponseSchema = z.object({
success: z.boolean(),
data: z.array(userSchema),
pagination: z.object({
page: z.number(),
limit: z.number(),
total_pages: z.number(),
total_items: z.number(),
}),
});
// 2. API fetch function
async function fetchUsers({ page = 1, limit = 10, search = "", from_date = "", to_date = "", sort_by = "created_at", sort_order = "desc" }) {
const params = new URLSearchParams({ page: String(page), limit: String(limit), sort_by, sort_order });
if (search) params.set("search", search);
if (from_date) params.set("from_date", from_date);
if (to_date) params.set("to_date", to_date);
const res = await fetch(`/api/users?${params}`);
if (!res.ok) throw new Error(res.statusText);
return usersResponseSchema.parse(await res.json());
}
// 3. React Query hook (mark with isQueryHook = true)
function useUsersData(page: number, pageSize: number, search: string, dateRange: { from_date: string; to_date: string }, sortBy: string, sortOrder: string) {
return useQuery({
queryKey: ["users", page, pageSize, search, dateRange, sortBy, sortOrder],
queryFn: () => fetchUsers({ page, limit: pageSize, search, from_date: dateRange.from_date, to_date: dateRange.to_date, sort_by: sortBy, sort_order: sortOrder }),
placeholderData: keepPreviousData,
});
}
useUsersData.isQueryHook = true; // Required flag
// 4. Fetch by IDs (for cross-page selection/export)
async function fetchUsersByIds(ids: number[]): Promise {
const params = new URLSearchParams();
ids.forEach(id => params.append("id", String(id)));
const res = await fetch(`/api/users/by-ids?${params}`);
const data = await res.json();
return data.data;
}
// 5. Column definitions
const getColumns = (handleRowDeselection: ((rowId: string) => void) | null | undefined): ColumnDef[] => {
const base: ColumnDef[] = [
{ accessorKey: "id", header: ({ column }) => , size: 70 },
{ accessorKey: "name", header: ({ column }) => , size: 200 },
{ accessorKey: "email", header: ({ column }) => , size: 250 },
{ accessorKey: "created_at", header: ({ column }) => , size: 120 },
];
if (handleRowDeselection === null) return base;
return [
{
id: "select",
header: ({ table }) => (
table.toggleAllPageRowsSelected(!!v)}
aria-label="Select all"
/>
),
cell: ({ row }) => (
{ row.toggleSelected(!!v); if (!v) handleRowDeselection?.(row.id); }}
aria-label="Select row"
/>
),
enableSorting: false,
enableHiding: false,
size: 50,
},
...base,
];
};
// 6. Export config
const exportConfig = {
entityName: "users",
headers: ["id", "name", "email", "created_at"],
columnMapping: { id: "ID", name: "Name", email: "Email", created_at: "Joined Date" },
columnWidths: [{ wch: 10 }, { wch: 20 }, { wch: 30 }, { wch: 20 }],
};
// 7. Render the DataTable
export default function UserTable() {
return (
getColumns={getColumns}
fetchDataFn={useUsersData}
fetchByIdsFn={fetchUsersByIds}
exportConfig={exportConfig}
idField="id"
pageSizeOptions={[10, 20, 50, 100]}
onRowClick={(user, idx) => console.log("Clicked", user.name, "at row", idx)}
config={{
enableRowSelection: true,
enableClickRowSelect: false,
enableKeyboardNavigation: true,
enableSearch: true,
enableDateFilter: true,
enableColumnVisibility: true,
enableUrlState: true,
}}
/>
);
}
```
--------------------------------
### Row Click Modal/Dialog Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of using 'onRowClick' to open a modal or dialog. It sets the selected user state and toggles the modal's visibility when a row is clicked.
```typescript
function UsersTable() {
const [selectedUser, setSelectedUser] = useState(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const handleRowClick = (user: User, rowIndex: number) => {
setSelectedUser(user);
setIsModalOpen(true);
};
return (
<>
// ... other props
onRowClick={handleRowClick}
/>
>
);
}
```
--------------------------------
### Snake_case API Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Demonstrates how to define columns and table configuration when your API response uses snake_case. Ensure accessorKeys and defaultSortBy exactly match the API field names.
```typescript
// API Response
{
"data": [
{
"id": 1,
"user_name": "John Doe",
"created_at": "2023-01-01T10:00:00Z",
"total_expenses": "1234.56"
}
]
}
// Column Definitions (matches API exactly)
{
accessorKey: "user_name", // ✅ Matches API field
header: "Name"
}
{
accessorKey: "created_at", // ✅ Matches API field
header: "Created"
}
// Table Configuration
config={{
defaultSortBy: "created_at", // ✅ Matches API field
// ... other options
}}
```
--------------------------------
### Example Exported Data Row
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Illustrates the format of an exported data row, including both original and newly calculated columns with their mapped headers.
```text
Customer ID | Full Name | Email | Phone | Age | Join Date | Total Transactions | Total Spending | Account Status | Customer Tier | Years as Customer | Spending Category | Risk Assessment
1 | John Doe | john@example.com | (555) 123-4567 | 32 | 15/01/2023 10:30 AM | 15 | $2,450.75 | ACTIVE | PREMIUM | 1 | HIGH_SPENDER | LOW_RISK
```
--------------------------------
### Customize Toolbar with Custom Components
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Implement custom components for the toolbar area. This example shows how to add buttons for actions like adding entities or bulk deletion.
```typescript
"use client";
import * as React from "react";
import { Button } from "@/components/ui/button";
import { AddEntityPopup } from "./actions/add-entity-popup";
import { BulkDeletePopup } from "./actions/bulk-delete-popup";
interface ToolbarOptionsProps {
selectedEntities: { id: number; name: string }[];
allSelectedIds?: number[];
totalSelectedCount: number;
resetSelection: () => void;
}
export const ToolbarOptions = ({
selectedEntities,
allSelectedIds = [],
totalSelectedCount,
resetSelection,
}: ToolbarOptionsProps) => {
const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);
return (
{totalSelectedCount > 0 && (
<>
>
)}
);
};
```
--------------------------------
### List Endpoint GET Request
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Defines the GET request for the list endpoint, including optional parameters for searching, filtering by date, sorting, and pagination.
```http
GET /api/entities
```
--------------------------------
### Install Core Data Table Dependencies with Yarn
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Install the core npm packages required for the data table functionality using Yarn. This includes react-table, react-query, and form handling libraries.
```bash
yarn add @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot react-day-picker cmdk @types/xlsx
```
--------------------------------
### Date-based Sorting Example
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of configuring a DataTable to sort by date in descending order, showing the newest records first. Use 'created_at' or 'createdAt' based on your API's case convention.
```typescript
// Show newest records first
defaultSortBy: "created_at", // or "createdAt" for camelCase
defaultSortOrder: "desc"
```
--------------------------------
### Example Column Definition for Data Table
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Demonstrates a column definition for a data table, including accessor key, custom header and cell rendering, and configuration for sorting and hiding.
```typescript
{
accessorKey: "name",
header: ({ column }) => (
),
cell: ({ row }) => {
// Custom rendering with additional styling or components
return (
{row.getValue("name")}
);
},
enableSorting: true,
enableHiding: true,
size: 200,
}
```
--------------------------------
### Install npm Dependencies for tnks-data-table
Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt
Alternatively, you can manually install the required npm dependencies for the Advanced Data Table component. This includes libraries for React Table, state management, form handling, UI utilities, and date manipulation.
```bash
npm install @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod \
sonner date-fns date-fns-tz exceljs class-variance-authority clsx tailwind-merge lucide-react \
@radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu \
@radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator react-day-picker cmdk
```
--------------------------------
### Client-Side DataTable Configuration for Cross-Page Selection
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
This example shows how to configure the DataTable component to enable cross-page selection and fetching by IDs. It requires the `fetchOrdersByIds` function to be imported and passed to the `fetchByIdsFn` prop, and `subRowsConfig` to be enabled.
```typescript
import { fetchOrdersByIds } from "@/api/order/fetch-orders-by-ids";
```
--------------------------------
### Server-Side Pagination Response Structure
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example JSON structure for server-side pagination response, including current page, items per page, total pages, and total items.
```json
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 10,
"total_pages": 5,
"total_items": 48
}
}
```
--------------------------------
### Configure React Query for Data Fetching
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Optimize data fetching using React Query by configuring `queryKey`, `queryFn`, `placeholderData`, `staleTime`, and `refetchOnWindowFocus`. This setup enables automatic caching, background refetching, and stale data management.
```typescript
useQuery({
queryKey: ["entities", ...], // Include all filters in the queryKey
queryFn: () => fetchEntities({...}),
placeholderData: keepPreviousData, // Show previous data while loading new data
staleTime: 30000, // Data is considered fresh for 30 seconds
refetchOnWindowFocus: false, // Disable refetching when window regains focus
})
```
--------------------------------
### Basic Data Formatting for Export
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of using a `DataTransformFunction` to format existing data fields during export. This includes timestamp and currency formatting, requiring specific utility functions.
```typescript
import { DataTransformFunction } from "@/components/data-table/utils/export-utils";
import { formatTimestampToReadable, formatCurrency } from "@/utils/format";
const transformFunction: DataTransformFunction = (row: User) => ({
...row,
// Format existing columns
created_at: formatTimestampToReadable(row.created_at), // "01/15/2023 10:30 AM"
total_expenses: formatCurrency(row.total_expenses), // "$1,234.56"
phone: formatPhoneNumber(row.phone), // "(123) 456-7890"
});
```
--------------------------------
### Camel Case API Request Parameters
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of API request parameters using camelCase, matching column definitions. Ensure 'sortBy' and 'sortOrder' match your accessorKey case format.
```typescript
// Column Definition
{ accessorKey: "createdAt" }
// API Request Parameters
{
"search": "john",
"sortBy": "createdAt", // ✅ Matches column case
"sortOrder": "desc",
"page": 1,
"limit": 10
}
```
--------------------------------
### API Response Structure for Orders with Subrows
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of an API response structure where parent rows (orders) contain subrows (product items). Each subrow can have its own set of properties.
```typescript
{
success: true,
data: [
{
id: 1,
order_id: "ORD-00001",
customer_name: "John Doe",
product_name: "Laptop", // First product shown in parent row
quantity: 1,
price: "999.99",
total_amount: "2499.97",
subRows: [
{
id: 2,
order_id: "ORD-00001",
product_name: "Mouse", // Additional products as subrows
quantity: 2,
price: "25.00"
},
// ... more items
]
}
]
}
```
--------------------------------
### Basic DataTable with Row Click Handling
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of integrating the DataTable component with basic row click handling. The 'onRowClick' prop accepts a callback function that receives row data and index.
```typescript
getColumns={getColumns}
exportConfig={useExportConfig()}
fetchDataFn={useEntitiesData}
fetchByIdsFn={fetchEntitiesByIds}
idField="id"
onRowClick={(rowData, rowIndex) => {
console.log('Clicked row:', rowData);
console.log('Row index:', rowIndex);
}}
config={{
enableRowSelection: true,
enableSearch: true,
enableDateFilter: true,
}}
/>
```
--------------------------------
### Snake Case API Request Parameters
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of API request parameters using snake_case, matching column definitions. Ensure 'sort_by' and 'sort_order' match your accessorKey case format.
```typescript
// Column Definition
{ accessorKey: "created_at" }
// API Request Parameters
{
"search": "john",
"sort_by": "created_at", // ✅ Matches column case
"sort_order": "desc",
"page": 1,
"limit": 10
}
```
--------------------------------
### Hono.js Server-Side API Implementation for Data Table
Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt
Example implementation of a server-side API endpoint using Hono.js that handles filtering, sorting, pagination, and returns data in the expected JSON format for a data table.
```typescript
// Expected GET /api/entities query parameters:
// ?search=alice&from_date=2024-01-01&to_date=2024-12-31
// &sort_by=created_at&sort_order=desc&page=2&limit=20
// Expected JSON response:
// {
// "success": true,
// "data": [ { "id": 1, "name": "Alice", ... }, ... ],
// "pagination": { "page": 2, "limit": 20, "total_pages": 10, "total_items": 196 }
// }
// Example Hono.js server implementation (src/api/users route):
import { Hono } from "hono";
import { db } from "@/db";
import { users } from "@/db/schema";
import { like, gte, lte, asc, desc, count } from "drizzle-orm";
const router = new Hono();
router.get("/", async (c) => {
const { search = "", from_date, to_date, sort_by = "created_at", sort_order = "desc", page = "1", limit = "10" } = c.req.query();
const pageNum = Math.max(1, parseInt(page));
const limitNum = Math.min(100, parseInt(limit));
const offset = (pageNum - 1) * limitNum;
const where = [];
if (search) where.push(like(users.name, `%${search}%`));
if (from_date) where.push(gte(users.created_at, new Date(from_date)));
if (to_date) where.push(lte(users.created_at, new Date(to_date)));
const orderFn = sort_order === "asc" ? asc : desc;
const sortCol = users[sort_by as keyof typeof users] ?? users.created_at;
const [data, [{ total }]] = await Promise.all([
db.select().from(users).where(...where).orderBy(orderFn(sortCol)).limit(limitNum).offset(offset),
db.select({ total: count() }).from(users).where(...where),
]);
return c.json({
success: true,
data,
pagination: { page: pageNum, limit: limitNum, total_pages: Math.ceil(total / limitNum), total_items: total },
});
});
// Error response format (consistent across all endpoints):
// { "success": false, "error": "Not found", "details": [] }
// HTTP 400 (validation), 404 (not found), 409 (conflict), 500 (server error)
```
--------------------------------
### Run Seed Script
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/src/scripts/README.md
Execute the database seeding script using npm. Ensure your .env file is configured with the correct database connection string.
```bash
# Run the seed script
npm run seed
```
--------------------------------
### Add Data Table Component from Local Registry
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Use this command to add the data-table component from a local development server. Ensure the server is running at http://localhost:3000.
```bash
npx shadcn@latest add http://localhost:3000/r/data-table.json
```
```bash
npx shadcn@latest add http://localhost:3000/r/calendar-date-picker.json
```
--------------------------------
### Migration from Complex Case Systems
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Shows the recommended approach for migrating from systems requiring manual case conversion to the direct matching method. Use accessorKeys that precisely match your API response fields.
```typescript
// ❌ Old Complex Way (don't do this)
{
accessorKey: "userName", // camelCase column
apiField: "user_name", // snake_case API
needsConversion: true
}
// ✅ New Simple Way (recommended)
{
accessorKey: "user_name" // Matches API exactly
header: "User Name" // Human readable display
}
```
--------------------------------
### Implement Virtualized Rendering with useVirtualizer
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Use the `useVirtualizer` hook for efficient rendering of large tables. Ensure the `tableContainerRef` is correctly attached to a scrollable container and `estimateSize` is set to an approximate row height.
```tsx
import { useVirtualizer } from "@tanstack/react-virtual";
// Inside your component:
const tableContainerRef = React.useRef(null);
const rowVirtualizer = useVirtualizer({
count: rows.length,
getScrollElement: () => tableContainerRef.current,
estimateSize: () => 35, // Approximate row height
overscan: 10,
});
// Use with your table:
)}
config={{
enableRowSelection: true,
enableSearch: true,
enableDateFilter: true,
enableColumnVisibility: true,
enableUrlState: true,
}}
/>
);
}
```
--------------------------------
### Create Response Format
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
The expected JSON format for a successful response from the create endpoint, including the newly created entity's data.
```json
{
"success": true,
"data": {
"id": 49,
"name": "New Entity",
"email": "new@example.com",
"created_at": "2025-04-14T06:44:16Z",
...
}
}
```
--------------------------------
### Clone TNKS Data Table Repository for Local Development
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Clone the TNKS Data Table repository to your local machine to set up the component for development or testing purposes.
```bash
git clone https://github.com/jacksonkasi1/tnks-data-table.git
cd tnks-data-table
```
--------------------------------
### Accessing Selected Rows in Toolbar
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
Example of using the 'renderToolbarContent' prop to access and display information about selected rows. Provides selected rows, all selected IDs, total count, and a reset function.
```typescript
renderToolbarContent={({
selectedRows, // Currently visible selected rows
allSelectedIds, // All selected IDs across pages
totalSelectedCount, // Total number of selected items
resetSelection // Function to reset selection
}) => (
)}
```
--------------------------------
### Customize Data Table Column Rendering with React
Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md
This example demonstrates how to customize the rendering of a 'status' column in a data table. It maps different status strings to corresponding `Badge` variants for visual representation.
```typescript
{
accessorKey: "status",
header: ({ column }) => (
),
cell: ({ row }) => {
const status = row.getValue("status") as string;
// Map status to badge variant
const variant = {
active: "success",
inactive: "secondary",
pending: "warning",
error: "destructive",
}[status] || "outline";
return (