From 37438684efa47870daf4159e94641f960226d127 Mon Sep 17 00:00:00 2001 From: cyphercodes Date: Wed, 29 Apr 2026 15:18:06 +0300 Subject: [PATCH] fix(react-table): type column contexts with React table --- packages/react-table/src/index.ts | 14 +- packages/react-table/src/useTable.ts | 138 ++++++++++++++++-- .../tests/column-context.test-d.ts | 43 ++++++ 3 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 packages/react-table/tests/column-context.test-d.ts diff --git a/packages/react-table/src/index.ts b/packages/react-table/src/index.ts index 2f7d5e1c07..9af6a6b919 100755 --- a/packages/react-table/src/index.ts +++ b/packages/react-table/src/index.ts @@ -3,4 +3,16 @@ export * from '@tanstack/table-core' export * from './FlexRender' export * from './Subscribe' export * from './createTableHook' -export * from './useTable' +export { useTable } from './useTable' +export type { + AccessorColumnDef, + AccessorFnColumnDef, + AccessorKeyColumnDef, + CellContext, + ColumnDef, + DisplayColumnDef, + GroupColumnDef, + HeaderContext, + ReactTable, + TableOptions, +} from './useTable' diff --git a/packages/react-table/src/useTable.ts b/packages/react-table/src/useTable.ts index 4fe97567f9..df425a41f2 100644 --- a/packages/react-table/src/useTable.ts +++ b/packages/react-table/src/useTable.ts @@ -7,10 +7,18 @@ import { FlexRender } from './FlexRender' import { Subscribe } from './Subscribe' import type { CellData, + ColumnDefTemplate, + AccessorColumnDef as CoreAccessorColumnDef, + AccessorFnColumnDef as CoreAccessorFnColumnDef, + AccessorKeyColumnDef as CoreAccessorKeyColumnDef, + CellContext as CoreCellContext, + DisplayColumnDef as CoreDisplayColumnDef, + GroupColumnDef as CoreGroupColumnDef, + HeaderContext as CoreHeaderContext, + TableOptions as CoreTableOptions, RowData, Table, TableFeatures, - TableOptions, TableState, } from '@tanstack/table-core' import type { Atom, ReadonlyAtom } from '@tanstack/react-store' @@ -106,26 +114,138 @@ export type ReactTable< * console.log(table.state.globalFilter) */ readonly state: Readonly & { - columns: TableOptions['columns'] - data: TableOptions['data'] + columns: TableOptions['columns'] + data: TableOptions['data'] } } +export type CellContext< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = Omit, 'table'> & { + table: ReactTable +} + +export type HeaderContext< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = Omit, 'table'> & { + table: ReactTable +} + +type ColumnDefWithReactContext< + TColumnDef extends object, + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData, + TSelected, +> = Omit & { + cell?: ColumnDefTemplate> + footer?: ColumnDefTemplate> + header?: + | string + | ColumnDefTemplate> +} + +export type DisplayColumnDef< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = ColumnDefWithReactContext< + CoreDisplayColumnDef, + TFeatures, + TData, + TValue, + TSelected +> + +export type GroupColumnDef< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = ColumnDefWithReactContext< + Omit, 'columns'>, + TFeatures, + TData, + TValue, + TSelected +> & { + columns?: ReadonlyArray> +} + +export type AccessorFnColumnDef< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = ColumnDefWithReactContext< + CoreAccessorFnColumnDef, + TFeatures, + TData, + TValue, + TSelected +> + +export type AccessorKeyColumnDef< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = ColumnDefWithReactContext< + CoreAccessorKeyColumnDef, + TFeatures, + TData, + TValue, + TSelected +> + +export type AccessorColumnDef< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = + | AccessorKeyColumnDef + | AccessorFnColumnDef + +export type ColumnDef< + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + TSelected = {}, +> = + | DisplayColumnDef + | GroupColumnDef + | AccessorColumnDef + +export type TableOptions< + TFeatures extends TableFeatures, + TData extends RowData, + TSelected = {}, +> = Omit, 'columns' | 'defaultColumn'> & { + columns: ReadonlyArray> + defaultColumn?: Partial> +} + export function useTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( - tableOptions: TableOptions, + tableOptions: TableOptions, selector: (state: TableState) => TSelected = () => ({}) as TSelected, ): ReactTable { const [table] = useState(() => { - const tableInstance = constructTable(tableOptions) as ReactTable< - TFeatures, - TData, - TSelected - > + const tableInstance = constructTable( + tableOptions as CoreTableOptions, + ) as ReactTable tableInstance.Subscribe = ((props: any) => { return Subscribe({ diff --git a/packages/react-table/tests/column-context.test-d.ts b/packages/react-table/tests/column-context.test-d.ts new file mode 100644 index 0000000000..20b2079b97 --- /dev/null +++ b/packages/react-table/tests/column-context.test-d.ts @@ -0,0 +1,43 @@ +import { globalFilteringFeature, tableFeatures, useTable } from '../src' +import type { ColumnDef } from '../src' + +const _features = tableFeatures({ globalFilteringFeature }) + +type Person = { + id: string + name: string +} + +const data: Person[] = [{ id: '1', name: 'Ada' }] + +const columns: Array> = [ + { + accessorKey: 'name', + header: ({ table }) => + table.Subscribe({ + selector: (state) => ({ globalFilter: state.globalFilter }), + children: null, + }), + cell: ({ table }) => + table.Subscribe({ + selector: (state) => ({ globalFilter: state.globalFilter }), + children: null, + }), + }, +] + +function TestTable() { + const table = useTable({ + _features, + data, + columns, + state: { globalFilter: '' }, + }) + + return table.Subscribe({ + selector: (state) => ({ globalFilter: state.globalFilter }), + children: null, + }) +} + +void TestTable