npm package: @laterinc/data-table
Description: Complete data table solution with shadcn/ui and TanStack Table
Latest version: 0.3.0

# @laterinc/data-table

A comprehensive, production-ready data table solution built on TanStack Table and shadcn/ui. This package provides everything you need to build powerful, feature-rich data tables with minimal setup.

## ✨ Features

- **🎯 Zero Config**: Works out of the box with sensible defaults
- **🔧 Fully Customizable**: Extensive customization options for advanced use cases
- **📦 All-in-One**: Includes TanStack Table, shadcn/ui components, and custom hooks
- **🎨 Beautiful UI**: Pre-styled components based on shadcn/ui
- **⚡ Performance**: Built with React best practices and optimized for performance
- **🔍 Rich Filtering**: Column filters, global search, faceted filters
- **📊 Sorting**: Multi-column sorting support
- **✅ Row Selection**: Single and multi-row selection
- **📄 Pagination**: Client-side and server-side pagination
- **👁️ Column Visibility**: Toggle column visibility
- **🎛️ Bulk Actions**: Perform actions on multiple rows
- **📱 Responsive**: Mobile-friendly design
- **🎭 TypeScript**: Fully typed for better DX

## 📦 Installation

```bash
npm install @laterinc/data-table
# or
pnpm add @laterinc/data-table
# or
yarn add @laterinc/data-table
```

### Peer Dependencies

This package requires React 18+ or 19+:

```bash
npm install react react-dom
```

## 🚀 Quick Start

### Basic Example

```tsx
import {
  useDataTable,
  DataTable,
  DataTablePagination,
  DataTableColumnHeader,
  Checkbox,
  type ColumnDef,
} from '@laterinc/data-table';
import '@laterinc/data-table/styles';

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

const columns: ColumnDef<User>[] = [
  {
    id: 'select',
    header: ({ table }) => (
      <Checkbox
        checked={table.getIsAllPageRowsSelected()}
        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
      />
    ),
    cell: ({ row }) => (
      <Checkbox
        checked={row.getIsSelected()}
        onCheckedChange={(value) => row.toggleSelected(!!value)}
      />
    ),
  },
  {
    accessorKey: 'name',
    header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
  },
  {
    accessorKey: 'email',
    header: 'Email',
  },
  {
    accessorKey: 'role',
    header: 'Role',
  },
];

function UsersTable({ data }: { data: User[] }) {
  const { table } = useDataTable({
    columns,
    data,
    enableRowSelection: true,
    enableSorting: true,
    enablePagination: true,
  });

  return (
    <div className="space-y-4">
      <DataTable table={table} />
      <DataTablePagination table={table} />
    </div>
  );
}
```

### Advanced Example with Filters and Bulk Actions

```tsx
import {
  useDataTable,
  DataTable,
  DataTablePagination,
  DataTableFacetedFilter,
  DataTableBulkActions,
  Input,
  type BulkActionDefinition,
} from '@laterinc/data-table';
import { Trash2, Mail } from 'lucide-react';

function AdvancedTable({ data }: { data: User[] }) {
  const { table, rowSelection, resetSelection } = useDataTable({
    columns,
    data,
    enableRowSelection: true,
    enableSorting: true,
    enableFiltering: true,
    enablePagination: true,
    pageSize: 20,
  });

  const bulkActions: BulkActionDefinition<User>[] = [
    {
      label: 'Send Email',
      icon: Mail,
      onClick: (rows) => {
        console.log('Sending email to', rows.length, 'users');
        resetSelection();
      },
    },
    {
      label: 'Delete',
      icon: Trash2,
      variant: 'destructive',
      onClick: (rows) => {
        console.log('Deleting', rows.length, 'users');
        resetSelection();
      },
    },
  ];

  const selectedCount = Object.keys(rowSelection).length;
  const selectedRows = table.getFilteredSelectedRowModel().rows;

  return (
    <div className="space-y-4">
      {/* Search */}
      <Input
        placeholder="Search users..."
        value={(table.getColumn('name')?.getFilterValue() as string) ?? ''}
        onChange={(e) => table.getColumn('name')?.setFilterValue(e.target.value)}
      />

      {/* Filters */}
      <div className="flex gap-2">
        <DataTableFacetedFilter
          column={table.getColumn('role')}
          title="Role"
          options={[
            { label: 'Admin', value: 'admin' },
            { label: 'User', value: 'user' },
          ]}
        />
      </div>

      {/* Bulk Actions */}
      {selectedCount > 0 && (
        <DataTableBulkActions
          selectedCount={selectedCount}
          actions={bulkActions}
          selectedRows={selectedRows}
        />
      )}

      {/* Table */}
      <DataTable table={table} />
      <DataTablePagination table={table} />
    </div>
  );
}
```

## 📚 API Reference

### Hooks

#### `useDataTable`

The main hook for creating a table instance with all features enabled.

```tsx
const {
  table,              // TanStack Table instance
  rowSelection,       // Current row selection state
  sorting,            // Current sorting state
  columnFilters,      // Current filter state
  columnVisibility,   // Current visibility state
  pagination,         // Current pagination state
  resetSelection,     // Reset row selection
  resetFilters,       // Reset all filters
  resetSorting,       // Reset sorting
  resetPagination,    // Reset pagination
  resetAll,           // Reset everything
} = useDataTable({
  columns,            // Column definitions
  data,               // Data array
  enableRowSelection: true,
  enableSorting: true,
  enableFiltering: true,
  enablePagination: true,
  pageSize: 10,
  // ... more options
});
```

#### `useServerDataTable`

Hook for server-side data tables with manual pagination/sorting/filtering.

```tsx
const { table, ... } = useServerDataTable({
  columns,
  data,
  rowCount: totalItems, // Total number of items from server
});
```

### Components

#### `DataTable`

Main table component that renders the table UI.

```tsx
<DataTable
  table={table}
  isLoading={false}
  emptyState={<CustomEmptyState />}
  loadingState={<CustomLoadingState />}
  stickyHeader={false}
  getRowClassName={(row) => row.isHighlighted ? 'bg-yellow-50' : ''}
/>
```

#### `DataTablePagination`

Pagination controls with page size selector.

```tsx
<DataTablePagination table={table} />
```

#### `DataTableToolbar`

Customizable toolbar for filters and actions.

```tsx
<DataTableToolbar table={table}>
  {/* Your custom toolbar content */}
</DataTableToolbar>
```

#### `DataTableFacetedFilter`

Multi-select filter for categorical columns.

```tsx
<DataTableFacetedFilter
  column={table.getColumn('status')}
  title="Status"
  options={[
    { label: 'Active', value: 'active' },
    { label: 'Inactive', value: 'inactive' },
  ]}
/>
```

#### `DataTableColumnHeader`

Sortable column header with sort indicators.

```tsx
<DataTableColumnHeader column={column} title="Name" />
```

#### `DataTableViewOptions`

Column visibility toggle dropdown.

```tsx
<DataTableViewOptions table={table} />
```

#### `DataTableBulkActions`

Bulk action buttons for selected rows.

```tsx
<DataTableBulkActions
  selectedCount={selectedCount}
  selectedRows={selectedRows}
  actions={[
    {
      label: 'Delete',
      icon: Trash2,
      variant: 'destructive',
      onClick: (rows) => handleDelete(rows),
    },
  ]}
/>
```

### Re-exported from TanStack Table

For convenience, all TanStack Table exports are re-exported:

```tsx
import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  flexRender,
  type ColumnDef,
  type Table,
  type Row,
  // ... and more
} from '@laterinc/data-table';
```

### shadcn/ui Components

All necessary shadcn/ui components are included:

```tsx
import {
  Button,
  Checkbox,
  Input,
  Select,
  Badge,
  Table,
  DropdownMenu,
  Popover,
  Command,
  Tooltip,
  Dialog,
  Separator,
} from '@laterinc/data-table';
```

## 🎨 Styling

Import the base styles in your root component:

```tsx
import '@laterinc/data-table/styles';
```

The package uses Tailwind CSS. Make sure you have Tailwind configured in your project and include the package in your `tailwind.config.js`:

```js
module.exports = {
  content: [
    './src/**/*.{js,ts,jsx,tsx}',
    './node_modules/@laterinc/data-table/**/*.{js,ts,jsx,tsx}',
  ],
  // ... rest of your config
};
```

## 🔧 TypeScript

The package is fully typed. All types are exported for your convenience:

```tsx
import type {
  ColumnDef,
  Table,
  Row,
  FilterOption,
  BulkActionDefinition,
  UseDataTableOptions,
} from '@laterinc/data-table';
```

## 📖 Examples

Check out the `/stories` directory for more comprehensive examples:

- Basic table with selection
- Advanced table with filtering
- Server-side pagination
- Custom renderers
- Bulk actions
- And more!

## 🤝 Contributing

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

## 📄 License

MIT © LaterInc

## 🙏 Credits

Built with:
- [TanStack Table](https://tanstack.com/table) - Headless table library
- [shadcn/ui](https://ui.shadcn.com/) - UI components
- [Radix UI](https://www.radix-ui.com/) - Unstyled, accessible components
- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework