npm package: @hazemazzam/paginated-data-table
Description: Compound components for building paginated data table layouts
Author: hazemazzam
Latest version: 1.0.2

# @hazemazzam/paginated-data-table

Compound components for paginated data table layouts with React + TanStack Table.

This package provides the state and UX shell for paginated tables:
- loading overlay (first load + refetch)
- error state rendering
- table area layout
- optional batch-actions slot

It is intentionally UI-agnostic through compound components, so you can plug in your own design system.

## Installation

```bash
npm i @hazemazzam/paginated-data-table
```

## Peer Dependencies

- `react`
- `react-dom`
- `@tanstack/react-table`

## Exports

- `PaginatedDataTable` (compound component API)
- `usePaginatedDataTableContext`
- `TableControls`
- `TableActions`
- `TablePagination`
- `PaginatedListQueryFlags` (type)
- `PaginatedTablePaginationState` (type)
- `TablePaginationProps` (type)

## Compound Component Usage

Use this API when you want full control over layout order and composition.

```tsx
import {
  PaginatedDataTable,
  TableControls,
  TableActions,
  TablePagination,
} from "@hazemazzam/paginated-data-table";

<PaginatedDataTable.Root table={table} query={query} pagination={pagination}>
  <PaginatedDataTable.Container className="rounded-lg border p-2">
    <PaginatedDataTable.LoadingOverlay />
    <PaginatedDataTable.ErrorState>
      {(error) => <div>Custom error: {String(error)}</div>}
    </PaginatedDataTable.ErrorState>

    <PaginatedDataTable.Content>
      <PaginatedDataTable.Controls>
        {({ pagination }) => (
          <TableControls>
            <div>Filters area</div>
            <TableActions>
              <TablePagination
                page={pagination.page}
                pages={pagination.pages}
                setPage={pagination.setPage}
              />
            </TableActions>
          </TableControls>
        )}
      </PaginatedDataTable.Controls>

      <PaginatedDataTable.Table>
        {(table) => <MyDataTable table={table} />}
      </PaginatedDataTable.Table>
    </PaginatedDataTable.Content>
  </PaginatedDataTable.Container>

  <PaginatedDataTable.BatchActions>
    <MyBatchActions />
  </PaginatedDataTable.BatchActions>
</PaginatedDataTable.Root>;
```

You can optionally guard against stuck requests:

```tsx
<PaginatedDataTable.Root
  table={table}
  query={query}
  pagination={pagination}
  loadingTimeoutMs={15000}
  loadingTimeoutMessage="Request timed out. Please retry."
>
  {/* ... */}
</PaginatedDataTable.Root>
```

## Props

### query (PaginatedListQueryFlags)

- `isPending: boolean`
- `isFetching: boolean`
- `isError: boolean`
- `hasData: boolean`
- `error?: unknown`

### pagination (PaginatedTablePaginationState)

- `page: number`
- `pages: number`
- `limit: number`
- `setPage(page: number): void`
- `setLimit(limit: number): void`

### Root optional props

- `loadingTimeoutMs?: number` (default `15000`)
- `loadingTimeoutMessage?: string` (default `"Request is taking too long. Please try again."`)

## Extra Components

### `TableControls`

A simple flex container (`justify-between`) for the table toolbar row.

### `TableActions`

A right-aligned flex container (`justify-end`) meant for page-size and pagination controls.

### `TablePagination`

Simple previous/next pagination component with current page display.

```tsx
import { TablePagination } from "@hazemazzam/paginated-data-table";

<TablePagination page={page} pages={pages} setPage={setPage} />;
```

## Behavior Notes

- Shows loading overlay when:
  - first load (`isPending`)
  - fetching before any successful data (`isFetching && !hasData`)
- Shows refetch overlay when fetching while data exists (`isFetching && hasData`)
- Shows error section only when `isError && !hasData`
- If initial loading exceeds `loadingTimeoutMs`, loading overlay is replaced by error state
- Renders table content otherwise

## Versioning

Semver:
- patch: docs and fixes
- minor: backward-compatible API additions
- major: breaking API changes