@facetui/react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +60 -0
- package/README.md +509 -0
- package/THEMING.md +168 -0
- package/dist/index.cjs +1220 -0
- package/dist/index.d.cts +367 -0
- package/dist/index.d.ts +367 -0
- package/dist/index.js +1209 -0
- package/package.json +122 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
type SortDirection = "asc" | "desc" | false;
|
|
5
|
+
type AccessorFn<TData> = (row: TData) => unknown;
|
|
6
|
+
type RowSelectionState = Record<string, boolean>;
|
|
7
|
+
interface HeaderContext<TData> {
|
|
8
|
+
column: RuntimeColumn<TData>;
|
|
9
|
+
table: TableInstance<TData>;
|
|
10
|
+
}
|
|
11
|
+
interface CellContext<TData> {
|
|
12
|
+
row: Row<TData>;
|
|
13
|
+
column: RuntimeColumn<TData>;
|
|
14
|
+
/** Pre-extracted cell value via accessorKey / accessorFn */
|
|
15
|
+
value: unknown;
|
|
16
|
+
table: TableInstance<TData>;
|
|
17
|
+
}
|
|
18
|
+
interface ColumnDef<TData> {
|
|
19
|
+
/** Must be unique across all columns. Used as sort key, visibility key, etc. */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Header content. Pass a string or a render function for custom headers. */
|
|
22
|
+
header: ReactNode | ((ctx: HeaderContext<TData>) => ReactNode);
|
|
23
|
+
/**
|
|
24
|
+
* Simple key-based accessor. Provide either this or `accessorFn`, not both.
|
|
25
|
+
* TypeScript will infer the value type from the key.
|
|
26
|
+
*/
|
|
27
|
+
accessorKey?: keyof TData;
|
|
28
|
+
/**
|
|
29
|
+
* Function-based accessor for computed or nested values.
|
|
30
|
+
* @example accessorFn: (row) => `${row.firstName} ${row.lastName}`
|
|
31
|
+
*/
|
|
32
|
+
accessorFn?: AccessorFn<TData>;
|
|
33
|
+
/**
|
|
34
|
+
* Custom cell renderer. If omitted, the raw value is rendered as a string.
|
|
35
|
+
* @example cell: ({ value }) => <Badge>{String(value)}</Badge>
|
|
36
|
+
*/
|
|
37
|
+
cell?: (ctx: CellContext<TData>) => ReactNode;
|
|
38
|
+
enableSorting?: boolean;
|
|
39
|
+
enableHiding?: boolean;
|
|
40
|
+
enableResizing?: boolean;
|
|
41
|
+
/** Initial pixel width. Respected as a CSS width on the <th>/<td>. */
|
|
42
|
+
size?: number;
|
|
43
|
+
minSize?: number;
|
|
44
|
+
maxSize?: number;
|
|
45
|
+
/** Arbitrary metadata — useful for passing flags into custom renderers */
|
|
46
|
+
meta?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
interface Row<TData> {
|
|
49
|
+
/** Stable string identifier (from getRowId or the row's array index) */
|
|
50
|
+
id: string;
|
|
51
|
+
/** The original data item */
|
|
52
|
+
original: TData;
|
|
53
|
+
/** Position within the current page */
|
|
54
|
+
index: number;
|
|
55
|
+
getIsSelected: () => boolean;
|
|
56
|
+
/** False when `enableRowSelection` is a predicate function that rejects this row */
|
|
57
|
+
getCanSelect: () => boolean;
|
|
58
|
+
toggleSelected: (value?: boolean) => void;
|
|
59
|
+
}
|
|
60
|
+
interface RuntimeColumn<TData> extends ColumnDef<TData> {
|
|
61
|
+
getIsSorted: () => SortDirection;
|
|
62
|
+
toggleSort: (multiSort?: boolean) => void;
|
|
63
|
+
getIsVisible: () => boolean;
|
|
64
|
+
toggleVisibility: (value?: boolean) => void;
|
|
65
|
+
getSize: () => number;
|
|
66
|
+
}
|
|
67
|
+
interface PaginationState {
|
|
68
|
+
pageIndex: number;
|
|
69
|
+
pageSize: number;
|
|
70
|
+
}
|
|
71
|
+
interface PaginationOptions {
|
|
72
|
+
/**
|
|
73
|
+
* Set true when pagination is handled server-side.
|
|
74
|
+
* When true, the component will NOT slice `data` — it renders whatever you pass.
|
|
75
|
+
* You MUST also provide `rowCount` so the page count can be calculated.
|
|
76
|
+
*/
|
|
77
|
+
manualPagination?: boolean;
|
|
78
|
+
/** Total number of rows across all pages. Required when manualPagination=true. */
|
|
79
|
+
rowCount?: number;
|
|
80
|
+
pageSizeOptions?: number[];
|
|
81
|
+
onPaginationChange?: (state: PaginationState) => void;
|
|
82
|
+
}
|
|
83
|
+
interface SortingState {
|
|
84
|
+
id: string;
|
|
85
|
+
desc: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface SortingOptions {
|
|
88
|
+
/** Set true when sorting is handled server-side. */
|
|
89
|
+
manualSorting?: boolean;
|
|
90
|
+
enableMultiSort?: boolean;
|
|
91
|
+
onSortingChange?: (state: SortingState[]) => void;
|
|
92
|
+
}
|
|
93
|
+
interface ColumnFilter {
|
|
94
|
+
id: string;
|
|
95
|
+
value: unknown;
|
|
96
|
+
}
|
|
97
|
+
type ColumnFiltersState = ColumnFilter[];
|
|
98
|
+
interface FilteringOptions {
|
|
99
|
+
/** Set true when filtering is handled server-side. */
|
|
100
|
+
manualFiltering?: boolean;
|
|
101
|
+
/** Controlled global filter value. Pass to sync with external state. */
|
|
102
|
+
globalFilter?: string;
|
|
103
|
+
onGlobalFilterChange?: (value: string) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Controlled per-column filter values. Uncontrolled state is used when omitted.
|
|
106
|
+
* Applied as a case-insensitive substring match, ANDed across all entries.
|
|
107
|
+
*/
|
|
108
|
+
columnFilters?: ColumnFiltersState;
|
|
109
|
+
onColumnFiltersChange?: (filters: ColumnFiltersState) => void;
|
|
110
|
+
}
|
|
111
|
+
interface RowSelectionOptions<TData> {
|
|
112
|
+
/**
|
|
113
|
+
* true/undefined → checkbox column is injected, all rows selectable
|
|
114
|
+
* false → row selection disabled entirely (no checkbox column)
|
|
115
|
+
* fn → checkbox column is injected; fn decides per-row eligibility
|
|
116
|
+
*/
|
|
117
|
+
enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
|
|
118
|
+
enableMultiRowSelection?: boolean;
|
|
119
|
+
onRowSelectionChange?: (state: RowSelectionState) => void;
|
|
120
|
+
}
|
|
121
|
+
interface RenderSlots<TData> {
|
|
122
|
+
/** Replaces the entire toolbar. Receives the live table instance. */
|
|
123
|
+
renderToolbar?: (table: TableInstance<TData>) => ReactNode;
|
|
124
|
+
/** Replaces the default empty state illustration. */
|
|
125
|
+
renderEmpty?: () => ReactNode;
|
|
126
|
+
/** Replaces the loading overlay. */
|
|
127
|
+
renderLoading?: () => ReactNode;
|
|
128
|
+
/**
|
|
129
|
+
* Wraps each <tr>. Useful for making rows into <Link> elements.
|
|
130
|
+
* @example renderRowWrapper={(row, children) => <Link href={`/users/${row.id}`}>{children}</Link>}
|
|
131
|
+
*/
|
|
132
|
+
renderRowWrapper?: (row: Row<TData>, children: ReactNode) => ReactNode;
|
|
133
|
+
}
|
|
134
|
+
interface ClassNameOverrides {
|
|
135
|
+
root?: string;
|
|
136
|
+
table?: string;
|
|
137
|
+
thead?: string;
|
|
138
|
+
theadRow?: string;
|
|
139
|
+
th?: string;
|
|
140
|
+
tbody?: string;
|
|
141
|
+
tr?: string;
|
|
142
|
+
td?: string;
|
|
143
|
+
pagination?: string;
|
|
144
|
+
toolbar?: string;
|
|
145
|
+
}
|
|
146
|
+
interface DataTableProps<TData> extends PaginationOptions, SortingOptions, FilteringOptions, RowSelectionOptions<TData>, RenderSlots<TData> {
|
|
147
|
+
data: TData[];
|
|
148
|
+
columns: ColumnDef<TData>[];
|
|
149
|
+
/** Derive a stable row id from the row's data. Defaults to array index. */
|
|
150
|
+
getRowId?: (row: TData, index: number) => string;
|
|
151
|
+
isLoading?: boolean;
|
|
152
|
+
/** Visual density preset. Controls cell padding. */
|
|
153
|
+
density?: "compact" | "default" | "comfortable";
|
|
154
|
+
classNames?: ClassNameOverrides;
|
|
155
|
+
style?: CSSProperties;
|
|
156
|
+
"aria-label"?: string;
|
|
157
|
+
"aria-describedby"?: string;
|
|
158
|
+
}
|
|
159
|
+
interface TableInstance<TData> {
|
|
160
|
+
rows: Row<TData>[];
|
|
161
|
+
columns: RuntimeColumn<TData>[];
|
|
162
|
+
pagination: PaginationState;
|
|
163
|
+
sorting: SortingState[];
|
|
164
|
+
rowSelection: RowSelectionState;
|
|
165
|
+
globalFilter: string;
|
|
166
|
+
columnFilters: ColumnFiltersState;
|
|
167
|
+
pageCount: number;
|
|
168
|
+
getIsAllRowsSelected: () => boolean;
|
|
169
|
+
getIsSomeRowsSelected: () => boolean;
|
|
170
|
+
toggleAllRowsSelected: (value?: boolean) => void;
|
|
171
|
+
setSorting: (updater: SortingState[] | ((prev: SortingState[]) => SortingState[])) => void;
|
|
172
|
+
setPagination: (updater: PaginationState | ((prev: PaginationState) => PaginationState)) => void;
|
|
173
|
+
setGlobalFilter: (value: string) => void;
|
|
174
|
+
setColumnFilters: (updater: ColumnFiltersState | ((prev: ColumnFiltersState) => ColumnFiltersState)) => void;
|
|
175
|
+
/** Total row count after filtering — useful for status text */
|
|
176
|
+
filteredRowCount: number;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* <DataTable> — batteries-included composed component.
|
|
181
|
+
*
|
|
182
|
+
* For full layout control, export the individual primitives and
|
|
183
|
+
* `useDataTable` from the barrel and assemble them yourself.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* <DataTable
|
|
187
|
+
* data={users}
|
|
188
|
+
* columns={columns}
|
|
189
|
+
* aria-label="Users table"
|
|
190
|
+
* enableRowSelection
|
|
191
|
+
* pageSizeOptions={[10, 20, 50]}
|
|
192
|
+
* />
|
|
193
|
+
*/
|
|
194
|
+
declare function DataTable<TData>({ renderToolbar, renderEmpty, renderLoading, renderRowWrapper, isLoading, density, classNames, style, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, ...rest }: DataTableProps<TData>): react.JSX.Element;
|
|
195
|
+
|
|
196
|
+
interface DataTableHeaderProps<TData> {
|
|
197
|
+
table: TableInstance<TData>;
|
|
198
|
+
density: "compact" | "default" | "comfortable";
|
|
199
|
+
classNames?: ClassNameOverrides;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Renders <thead> with sortable column headers.
|
|
203
|
+
* Each sortable header uses a <button> so keyboard users can trigger sorts.
|
|
204
|
+
* A select-all checkbox is prepended when row selection is enabled.
|
|
205
|
+
*/
|
|
206
|
+
declare function DataTableHeader<TData>({ table, density, classNames, }: DataTableHeaderProps<TData>): react.JSX.Element;
|
|
207
|
+
|
|
208
|
+
interface DataTableBodyProps<TData> {
|
|
209
|
+
table: TableInstance<TData>;
|
|
210
|
+
density: "compact" | "default" | "comfortable";
|
|
211
|
+
isLoading: boolean;
|
|
212
|
+
renderEmpty?: () => ReactNode;
|
|
213
|
+
renderRowWrapper?: (row: Row<TData>, children: ReactNode) => ReactNode;
|
|
214
|
+
classNames?: ClassNameOverrides;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Renders <tbody> with data rows, empty state, and per-cell value resolution.
|
|
218
|
+
* Each row's checkbox uses Radix Checkbox for full keyboard and ARIA support.
|
|
219
|
+
*/
|
|
220
|
+
declare function DataTableBody<TData>({ table, density, isLoading, renderEmpty, renderRowWrapper, classNames, }: DataTableBodyProps<TData>): react.JSX.Element;
|
|
221
|
+
|
|
222
|
+
interface DataTableToolbarProps<TData> {
|
|
223
|
+
table: TableInstance<TData>;
|
|
224
|
+
classNames?: ClassNameOverrides;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Default toolbar: global search input on the left, column-toggle on the right.
|
|
228
|
+
* Replace entirely via the `renderToolbar` prop on <DataTable>.
|
|
229
|
+
*/
|
|
230
|
+
declare function DataTableToolbar<TData>({ table, classNames, }: DataTableToolbarProps<TData>): react.JSX.Element;
|
|
231
|
+
|
|
232
|
+
interface DataTableColumnToggleProps<TData> {
|
|
233
|
+
table: TableInstance<TData>;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Column visibility toggle built on react-aria-components `Menu` with
|
|
237
|
+
* `selectionMode="multiple"` — each item is a `menuitemcheckbox`, fully
|
|
238
|
+
* keyboard-navigable and screen-reader annotated.
|
|
239
|
+
*/
|
|
240
|
+
declare function DataTableColumnToggle<TData>({ table, }: DataTableColumnToggleProps<TData>): react.JSX.Element;
|
|
241
|
+
|
|
242
|
+
interface DataTablePaginationProps<TData> {
|
|
243
|
+
table: TableInstance<TData>;
|
|
244
|
+
pageSizeOptions: number[];
|
|
245
|
+
classNames?: ClassNameOverrides;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Pagination bar with:
|
|
249
|
+
* - Selected-row count (when row selection is active)
|
|
250
|
+
* - "Rows per page" selector via Radix Select
|
|
251
|
+
* - Current page info + navigation buttons
|
|
252
|
+
*
|
|
253
|
+
* All buttons carry descriptive aria-labels and are disabled when the
|
|
254
|
+
* action is unavailable, preventing screen-reader confusion.
|
|
255
|
+
*/
|
|
256
|
+
declare function DataTablePagination<TData>({ table, pageSizeOptions, classNames, }: DataTablePaginationProps<TData>): react.JSX.Element;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Core headless hook. Wraps a TanStack Table instance and adapts it to
|
|
260
|
+
* FacetUI's `TableInstance` contract, which both the composed <DataTable> and
|
|
261
|
+
* the individual primitives consume via context.
|
|
262
|
+
*
|
|
263
|
+
* TanStack Table owns the state machine and the filter → sort → paginate →
|
|
264
|
+
* select pipeline. This hook owns:
|
|
265
|
+
* - the FacetUI-shaped public API (stable regardless of the engine)
|
|
266
|
+
* - the auto-injected checkbox column
|
|
267
|
+
* - the controlled-or-observable state pattern:
|
|
268
|
+
* · internal state drives the UI by default
|
|
269
|
+
* · an `onChange` callback makes a feature observable without handing
|
|
270
|
+
* ownership to the caller
|
|
271
|
+
* · passing the feature's prop (e.g. `globalFilter`) AND its `onChange`
|
|
272
|
+
* makes it fully controlled
|
|
273
|
+
*/
|
|
274
|
+
declare function useDataTable<TData>(props: DataTableProps<TData>): TableInstance<TData>;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Access the nearest DataTable's live instance from any primitive component.
|
|
278
|
+
* Throws if called outside a <DataTable> tree.
|
|
279
|
+
*/
|
|
280
|
+
declare function useDataTableContext<TData>(): TableInstance<TData>;
|
|
281
|
+
|
|
282
|
+
interface UseColumnSortOptions {
|
|
283
|
+
enableMultiSort?: boolean;
|
|
284
|
+
onSortingChange?: (state: SortingState[]) => void;
|
|
285
|
+
}
|
|
286
|
+
interface UseColumnSortReturn {
|
|
287
|
+
sorting: SortingState[];
|
|
288
|
+
setSorting: (updater: SortingState[] | ((prev: SortingState[]) => SortingState[])) => void;
|
|
289
|
+
/** Cycle a single column through: none → asc → desc → none */
|
|
290
|
+
toggleSort: (columnId: string, multiSort?: boolean) => void;
|
|
291
|
+
clearSort: () => void;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Standalone sort state hook. Use directly when building a custom table layout
|
|
295
|
+
* that doesn't use the full <DataTable> component.
|
|
296
|
+
*/
|
|
297
|
+
declare function useColumnSort({ enableMultiSort, onSortingChange, }?: UseColumnSortOptions): UseColumnSortReturn;
|
|
298
|
+
|
|
299
|
+
interface UsePaginationOptions {
|
|
300
|
+
initialPageSize?: number;
|
|
301
|
+
onPaginationChange?: (state: PaginationState) => void;
|
|
302
|
+
}
|
|
303
|
+
interface UsePaginationReturn {
|
|
304
|
+
pagination: PaginationState;
|
|
305
|
+
setPagination: (updater: PaginationState | ((prev: PaginationState) => PaginationState)) => void;
|
|
306
|
+
goToPage: (pageIndex: number) => void;
|
|
307
|
+
goToFirstPage: () => void;
|
|
308
|
+
goToLastPage: (pageCount: number) => void;
|
|
309
|
+
nextPage: () => void;
|
|
310
|
+
previousPage: () => void;
|
|
311
|
+
setPageSize: (size: number) => void;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Standalone pagination state hook. Safe to use outside <DataTable> when
|
|
315
|
+
* only a subset of table behaviour is needed.
|
|
316
|
+
*/
|
|
317
|
+
declare function usePagination({ initialPageSize, onPaginationChange, }?: UsePaginationOptions): UsePaginationReturn;
|
|
318
|
+
|
|
319
|
+
interface UseRowSelectionOptions {
|
|
320
|
+
enableMultiRowSelection?: boolean;
|
|
321
|
+
onRowSelectionChange?: (state: RowSelectionState) => void;
|
|
322
|
+
}
|
|
323
|
+
interface UseRowSelectionReturn {
|
|
324
|
+
rowSelection: RowSelectionState;
|
|
325
|
+
setRowSelection: (state: RowSelectionState) => void;
|
|
326
|
+
toggleRow: (rowId: string, value?: boolean) => void;
|
|
327
|
+
toggleAllRows: (rows: Row<unknown>[], value?: boolean) => void;
|
|
328
|
+
clearSelection: () => void;
|
|
329
|
+
isSelected: (rowId: string) => boolean;
|
|
330
|
+
selectedCount: number;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Standalone row-selection hook. Use when building a custom table layout
|
|
334
|
+
* without the full <DataTable> component.
|
|
335
|
+
*/
|
|
336
|
+
declare function useRowSelection({ enableMultiRowSelection, onRowSelectionChange, }?: UseRowSelectionOptions): UseRowSelectionReturn;
|
|
337
|
+
|
|
338
|
+
interface UseColumnVisibilityReturn {
|
|
339
|
+
columnVisibility: Record<string, boolean>;
|
|
340
|
+
isVisible: (columnId: string) => boolean;
|
|
341
|
+
toggleColumn: (columnId: string, value?: boolean) => void;
|
|
342
|
+
showAll: () => void;
|
|
343
|
+
hideAll: (hideableIds: string[]) => void;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Standalone column-visibility hook. Initialises all columns to visible.
|
|
347
|
+
* Respects the `enableHiding: false` guard on individual ColumnDefs — when you
|
|
348
|
+
* call hideAll, pass only the ids where enableHiding !== false.
|
|
349
|
+
*/
|
|
350
|
+
declare function useColumnVisibility<TData>(columns: ColumnDef<TData>[]): UseColumnVisibilityReturn;
|
|
351
|
+
|
|
352
|
+
interface UseGlobalFilterOptions {
|
|
353
|
+
onGlobalFilterChange?: (value: string) => void;
|
|
354
|
+
}
|
|
355
|
+
interface UseGlobalFilterReturn<TData> {
|
|
356
|
+
globalFilter: string;
|
|
357
|
+
setGlobalFilter: (value: string) => void;
|
|
358
|
+
/** Apply the current filter against any dataset client-side */
|
|
359
|
+
filterData: (data: TData[]) => TData[];
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Standalone global-filter hook. The filter is applied as a case-insensitive
|
|
363
|
+
* substring match against all accessible column values.
|
|
364
|
+
*/
|
|
365
|
+
declare function useGlobalFilter<TData>(columns: ColumnDef<TData>[], { onGlobalFilterChange }?: UseGlobalFilterOptions): UseGlobalFilterReturn<TData>;
|
|
366
|
+
|
|
367
|
+
export { type AccessorFn, type CellContext, type ClassNameOverrides, type ColumnDef, type ColumnFilter, type ColumnFiltersState, DataTable, DataTableBody, DataTableColumnToggle, DataTableHeader, DataTablePagination, type DataTableProps, DataTableToolbar, type FilteringOptions, type HeaderContext, type PaginationOptions, type PaginationState, type RenderSlots, type Row, type RowSelectionOptions, type RowSelectionState, type RuntimeColumn, type SortDirection, type SortingOptions, type SortingState, type TableInstance, useColumnSort, useColumnVisibility, useDataTable, useDataTableContext, useGlobalFilter, usePagination, useRowSelection };
|