/**
* @fileoverview DataTable — typed, dependency-free data grid built on the
* Saasflare Table primitives. Consumers pass `data: T[]` + typed `columns` and
* get client-side multi-column sort, row selection (controlled/uncontrolled),
* client-side pagination (via {@link usePagination}), sticky header, density,
* and empty/loading states out of the box — zero TanStack, zero wiring.
* @module packages/ui/components/ui/data-table
* @layer composed
*
* Server-side / TanStack: pass `manualSort` + `manualPagination` and drive
* state from `onSortChange` / `onPageChange`. The component stays
* dependency-free; `@tanstack/react-table` is NEVER a dependency of `@saasflare/ui`.
*
* @component
* @example
* import { DataTable } from "@saasflare/ui";
*
*/
import * as React from "react";
import { type SaasflareComponentProps } from "../../providers";
import { type DataTableColumn, type DataTableSort, type DataTableAlign, type DataTableDensity, type DataTableSelectionMode } from "../../hooks/use-data-table";
export type { DataTableColumn, DataTableSort, DataTableAlign, DataTableDensity };
/**
* Props for {@link DataTable}, generic over the row type `T`.
*
* Sorting, selection, and pagination each work controlled or uncontrolled;
* pass `manualSort` / `manualPagination` to hand ordering and slicing over to
* a server or TanStack layer while keeping the rendering here.
*/
interface DataTableProps extends Omit, "children" | keyof SaasflareComponentProps>, SaasflareComponentProps {
/** Row data. */
data: T[];
/** Typed column definitions. */
columns: DataTableColumn[];
/** Stable row key. String key of `T` or a function. Falls back to row index (logs a dev warning, since index keys break selection across sort/paginate). */
getRowId?: keyof T | ((row: T, index: number) => string);
/** Uncontrolled initial sort. */
defaultSort?: DataTableSort[];
/** Controlled sort state. Presence switches sorting to controlled. */
sort?: DataTableSort[];
/** Fires on header activation with the next sort array. */
onSortChange?: (sort: DataTableSort[]) => void;
/** Allow stacking multiple sort columns (shift-click adds a column). Default `false` (single-column). */
multiSort?: boolean;
/** Skip internal sorting (server/TanStack drives order). Header still emits `onSortChange`. Default `false`. */
manualSort?: boolean;
/** `"none"` (default) | `"single"` | `"multiple"`. Renders a leading checkbox column when not `"none"`. */
selectionMode?: DataTableSelectionMode;
/** Uncontrolled initial selected row-id set. */
defaultSelectedKeys?: string[];
/** Controlled selected row-id set. */
selectedKeys?: string[];
/** Fires with the next selected row-id array. */
onSelectedKeysChange?: (keys: string[]) => void;
/** Predicate to disable selection for specific rows (their checkbox is disabled + excluded from select-all). */
isRowSelectable?: (row: T) => boolean;
/** Rows per page. Omit / `0` disables pagination (renders all rows, no footer). */
pageSize?: number;
/** Uncontrolled initial page (1-indexed). Default `1`. */
defaultPage?: number;
/** Controlled page (1-indexed). */
page?: number;
/** Fires on page change. */
onPageChange?: (page: number) => void;
/** Skip internal pagination/slicing (server drives the window). `data` is treated as the current page; pass `rowCount` for the footer. Default `false`. */
manualPagination?: boolean;
/** Total row count when `manualPagination` — drives the page-count math in the footer. */
rowCount?: number;
/** Loading flag — renders `loadingRows` skeleton rows; disables sort/select while true. */
loading?: boolean;
/** Skeleton row count while `loading`. Default = `pageSize || 5`. */
loadingRows?: number;
/** Rendered in a full-width body row when `data` is empty and not loading. Defaults to a built-in message. */
emptyState?: React.ReactNode;
/** Pin the header on vertical scroll within a `maxHeight` container. Default `false`. */
stickyHeader?: boolean;
/** Max body height (enables internal scroll; required for `stickyHeader` to be useful). e.g. `"24rem"`. */
maxHeight?: number | string;
/** Density preset. Default `"comfortable"`. */
density?: DataTableDensity;
/** Optional row click handler. Receives row + index. Adds `cursor-pointer` + keyboard activation when set. */
onRowClick?: (row: T, index: number) => void;
/** Accessible caption (visually hidden by default) describing the table. */
caption?: React.ReactNode;
/** Hide the built-in pagination footer even when paginated (consumer renders own Pagination). Default `false`. */
hidePagination?: boolean;
}
/**
* Dependency-free, typed, sortable + selectable + paginated data table built on
* the Saasflare Table primitives. Resolves the four design axes
* (surface/radius/animated/iconWeight) and emits data-surface/data-radius/data-animated.
*
* Selection note: the header "select all" checkbox operates on the
* **current page** only (it toggles the visible page's selectable rows;
* off-page selections are preserved).
*
* @component
* @layer composed
*
* @example
*
*/
declare function DataTable(props: DataTableProps): React.JSX.Element;
export { DataTable, type DataTableProps };