diff --git a/examples/react/basic-table-helper/src/main.tsx b/examples/react/basic-table-helper/src/main.tsx index 9008fd43f7..cc32daea62 100644 --- a/examples/react/basic-table-helper/src/main.tsx +++ b/examples/react/basic-table-helper/src/main.tsx @@ -1,10 +1,9 @@ import * as React from 'react' import ReactDOM from 'react-dom/client' -import { createTableHelper } from '@tanstack/react-table' +import { useTable } from '@tanstack/react-table' +import type { ColumnDef } from '@tanstack/react-table' import './index.css' -// This example uses the new `createTableHelper` method to create a re-usable table helper object instead of independently using the standalone `useTable` hook and `createColumnHelper` method. You can choose to use either way. - // 1. Define what the shape of your data will be for each row type Person = { firstName: string @@ -51,67 +50,69 @@ const defaultData: Array = [ }, ] -// 3. New in V9! Tell the table which features and row models we want to use. In this case, this will be a basic table with no additional features -const tableHelper = createTableHelper({ - _features: {}, - _rowModels: {}, // client-side row models. `Core` row model is now included by default, but you can still override it here - debugTable: true, - // TData: {} as Person, // optionally, set the TData type for the table helper. Omit if this will be a table helper for multiple tables of all different data types -}) - -// 4. Create a helper object to help define our columns -// const { columnHelper } = tableHelper // if TData was set in the table helper options - otherwise use the createColumnHelper method below -const columnHelper = tableHelper.createColumnHelper() - -// 5. Define the columns for your table with a stable reference (in this case, defined statically outside of a react component) -const columns = columnHelper.columns([ - // accessorKey method (most common for simple use-cases) - columnHelper.accessor('firstName', { - cell: (info) => info.getValue(), - footer: (info) => info.column.id, - }), - // accessorFn used (alternative) along with a custom id - columnHelper.accessor((row) => row.lastName, { - id: 'lastName', - cell: (info) => {info.getValue()}, - header: () => Last Name, - footer: (info) => info.column.id, - }), - // accessorFn used to transform the data - columnHelper.accessor((row) => Number(row.age), { - id: 'age', - header: () => 'Age', - cell: (info) => info.renderValue(), - footer: (info) => info.column.id, - }), - columnHelper.accessor('visits', { - header: () => Visits, - footer: (info) => info.column.id, - }), - columnHelper.accessor('status', { - header: 'Status', - footer: (info) => info.column.id, - }), - columnHelper.accessor('progress', { - header: 'Profile Progress', - footer: (info) => info.column.id, - }), -]) +// 3. Define the features for your table. In this case, this will be a basic table with no additional features +const _features = {} function App() { - // 6. Store data with a stable reference + // 4. Define the columns for your table with a stable reference + const columns = React.useMemo>>( + () => [ + // accessorKey method (most common for simple use-cases) + { + accessorKey: 'firstName', + cell: (info) => info.getValue(), + footer: (info) => info.column.id, + }, + // accessorFn used (alternative) along with a custom id + { + accessorFn: (row) => row.lastName, + id: 'lastName', + cell: (info) => {info.getValue()}, + header: () => Last Name, + footer: (info) => info.column.id, + }, + // accessorFn used to transform the data + { + accessorFn: (row) => Number(row.age), + id: 'age', + header: () => 'Age', + cell: (info) => info.getValue(), + footer: (info) => info.column.id, + }, + { + accessorKey: 'visits', + header: () => Visits, + footer: (info) => info.column.id, + }, + { + accessorKey: 'status', + header: 'Status', + footer: (info) => info.column.id, + }, + { + accessorKey: 'progress', + header: 'Profile Progress', + footer: (info) => info.column.id, + }, + ], + [], + ) + + // 5. Store data with a stable reference const [data, _setData] = React.useState(() => [...defaultData]) const rerender = React.useReducer(() => ({}), {})[1] - // 7. Create the table instance with the required columns and data. - // Features and row models are already defined in the table helper object above - const table = tableHelper.useTable({ + // 6. Create the table instance with the required columns and data. + // Features and row models are defined in the useTable options + const table = useTable({ + _features, columns, data, - // add additional table options here or in the table helper above + _rowModels: {}, // client-side row models. `Core` row model is now included by default, but you can still override it here + debugTable: true, }) - // 8. Render your table markup from the table instance APIs + // 7. Render your table markup from the table instance APIs return (
diff --git a/examples/react/column-dnd/src/main.tsx b/examples/react/column-dnd/src/main.tsx index 7a71769600..67e5464076 100644 --- a/examples/react/column-dnd/src/main.tsx +++ b/examples/react/column-dnd/src/main.tsx @@ -1,9 +1,10 @@ import React from 'react' import ReactDOM from 'react-dom/client' import { + FlexRender, columnOrderingFeature, columnSizingFeature, - createTableHelper, + useTable, } from '@tanstack/react-table' import { DndContext, @@ -29,19 +30,15 @@ import type { Person } from './makeData' import type { Cell, ColumnDef, Header } from '@tanstack/react-table' import './index.css' -const tableHelper = createTableHelper({ - _features: { columnOrderingFeature, columnSizingFeature }, - _rowModels: {}, - TData: {} as Person, - debugTable: true, - debugHeaders: true, - debugColumns: true, -}) +const _features = { + columnOrderingFeature, + columnSizingFeature, +} const DraggableTableHeader = ({ header, }: { - header: Header + header: Header }) => { const { attributes, isDragging, listeners, setNodeRef, transform } = useSortable({ @@ -60,7 +57,7 @@ const DraggableTableHeader = ({ return ( ) } function App() { - const columns = React.useMemo< - Array> - >( + const columns = React.useMemo>>( () => [ { accessorKey: 'firstName', @@ -143,16 +138,18 @@ function App() { const rerender = () => setData(() => makeData(20)) - const table = tableHelper.useTable( - { - columns, - data, - initialState: { - columnOrder: columns.map((c) => c.id!), - }, + const table = useTable({ + _features, + columns, + data, + _rowModels: {}, + initialState: { + columnOrder: columns.map((c) => c.id!), }, - (state) => state, - ) + debugTable: true, + debugHeaders: true, + debugColumns: true, + }) // reorder columns after drag & drop function handleDragEnd(event: DragEndEvent) { diff --git a/examples/react/column-ordering/src/makeData.ts b/examples/react/column-ordering/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/column-ordering/src/makeData.ts +++ b/examples/react/column-ordering/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/column-pinning-split/src/makeData.ts b/examples/react/column-pinning-split/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/column-pinning-split/src/makeData.ts +++ b/examples/react/column-pinning-split/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/column-pinning-sticky/src/makeData.ts b/examples/react/column-pinning-sticky/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/column-pinning-sticky/src/makeData.ts +++ b/examples/react/column-pinning-sticky/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/column-pinning/src/makeData.ts b/examples/react/column-pinning/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/column-pinning/src/makeData.ts +++ b/examples/react/column-pinning/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/column-resizing-performant/src/makeData.ts b/examples/react/column-resizing-performant/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/column-resizing-performant/src/makeData.ts +++ b/examples/react/column-resizing-performant/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/custom-features/src/main.tsx b/examples/react/custom-features/src/main.tsx index 97d1cfb428..cced32066c 100644 --- a/examples/react/custom-features/src/main.tsx +++ b/examples/react/custom-features/src/main.tsx @@ -8,7 +8,6 @@ import { createSortedRowModel, filterFns, functionalUpdate, - makeStateUpdater, rowPaginationFeature, rowSortingFeature, sortFns, @@ -19,7 +18,6 @@ import { makeData } from './makeData' import type { Column, ColumnDef, - OnChangeFn, Table, TableFeature, Updater, @@ -37,7 +35,6 @@ export interface TableState_Density { // define types for our new feature's table options export interface TableOptions_Density { enableDensity?: boolean - onDensityChange?: OnChangeFn } // Define types for our new feature's table APIs @@ -63,10 +60,9 @@ export const densityPlugin: TableFeature = { }, // define the new feature's default options - getDefaultTableOptions: (table) => { + getDefaultTableOptions: () => { return { enableDensity: true, - onDensityChange: makeStateUpdater('density', table), } }, // if you need to add a default column definition... @@ -75,11 +71,15 @@ export const densityPlugin: TableFeature = { // define the new feature's table instance methods constructTableAPIs: (table) => { table.setDensity = (updater) => { - const safeUpdater: Updater = (old) => { - const newState = functionalUpdate(updater, old) - return newState - } - return table.options.onDensityChange?.(safeUpdater) + table.store.setState((prev) => { + const prevState = prev as TableState_Density & typeof prev + const oldDensity = prevState.density + const newDensity = functionalUpdate(updater, oldDensity) + return { + ...prev, + density: newDensity, + } + }) } table.toggleDensity = (value) => { table.setDensity?.((old) => { @@ -151,7 +151,6 @@ function App() { ) const [data, _setData] = React.useState(() => makeData(1000)) - const [density, setDensity] = React.useState('md') const table = useTable({ _features, @@ -163,162 +162,162 @@ function App() { columns, data, debugTable: true, - state: { - density, // passing the density state to the table, TS is still happy :) - }, - onDensityChange: setDensity, // using the new onDensityChange option, TS is still happy :) }) return ( -
-
- -
- {header.isPlaceholder ? null : } + {header.isPlaceholder ? null : } @@ -71,7 +68,7 @@ const DraggableTableHeader = ({ const DragAlongCell = ({ cell, }: { - cell: Cell + cell: Cell }) => { const { isDragging, setNodeRef, transform } = useSortable({ id: cell.column.id, @@ -88,15 +85,13 @@ const DragAlongCell = ({ return ( - +
- - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { + ({ density: state.density })}> + {({ density }) => ( +
+
+ +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + ) + })} + + ))} + + + {table.getRowModel().rows.map((row) => { return ( - + + {row.getAllCells().map((cell) => { + return ( + + ) + })} + ) })} - - ))} - - - {table.getRowModel().rows.map((row) => { - return ( - - {row.getAllCells().map((cell) => { - return ( - - ) - })} - - ) - })} - -
+
+ + {{ + asc: ' 🔼', + desc: ' 🔽', + }[header.column.getIsSorted() as string] ?? null} +
+ {header.column.getCanFilter() ? ( +
+ +
+ ) : null} +
-
- - {{ - asc: ' 🔼', - desc: ' 🔽', - }[header.column.getIsSorted() as string] ?? null} -
- {header.column.getCanFilter() ? ( -
- -
- ) : null} -
+ +
- -
-
-
- - - - - -
Page
- - {table.store.state.pagination.pageIndex + 1} of{' '} - {table.getPageCount().toLocaleString()} - -
- - | Go to page: - { - const page = e.target.value ? Number(e.target.value) - 1 : 0 - table.setPageIndex(page) - }} - className="border p-1 rounded w-16" - /> - - -
-
- Showing {table.getRowModel().rows.length.toLocaleString()} of{' '} - {table.getRowCount().toLocaleString()} Rows -
-
{JSON.stringify(table.store.state.pagination, null, 2)}
-
+ + +
+
+ + + + + +
Page
+ + {table.store.state.pagination.pageIndex + 1} of{' '} + {table.getPageCount().toLocaleString()} + +
+ + | Go to page: + { + const page = e.target.value ? Number(e.target.value) - 1 : 0 + table.setPageIndex(page) + }} + className="border p-1 rounded w-16" + /> + + +
+
+ Showing {table.getRowModel().rows.length.toLocaleString()} of{' '} + {table.getRowCount().toLocaleString()} Rows +
+
{JSON.stringify(table.store.state.pagination, null, 2)}
+
+ )} + ) } diff --git a/examples/react/custom-features/src/makeData.ts b/examples/react/custom-features/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/custom-features/src/makeData.ts +++ b/examples/react/custom-features/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/editable-data/src/main.tsx b/examples/react/editable-data/src/main.tsx index 20d29edc0a..73a97a3df5 100644 --- a/examples/react/editable-data/src/main.tsx +++ b/examples/react/editable-data/src/main.tsx @@ -4,10 +4,10 @@ import { columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, - createTableHelper, filterFns, rowPaginationFeature, tableFeatures, + useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { @@ -25,14 +25,6 @@ const _features = tableFeatures({ columnFilteringFeature, }) -const tableHelper = createTableHelper({ - _features, - _rowModels: { - filteredRowModel: createFilteredRowModel(filterFns), - paginatedRowModel: createPaginatedRowModel(), - }, -}) - declare module '@tanstack/react-table' { interface TableMeta { updateData: (rowIndex: number, columnId: string, value: unknown) => void @@ -40,7 +32,7 @@ declare module '@tanstack/react-table' { } // Give our default column cell renderer editing superpowers! -const defaultColumn: Partial> = { +const defaultColumn: Partial> = { cell: ({ getValue, row: { index }, column: { id }, table }) => { const initialValue = getValue() // We need to keep and update the state of the cell normally @@ -85,9 +77,7 @@ function useSkipper() { function App() { const rerender = React.useReducer(() => ({}), {})[1] - const columns = React.useMemo< - Array> - >( + const columns = React.useMemo>>( () => [ { header: 'Name', @@ -145,9 +135,14 @@ function App() { const [autoResetPageIndex, skipAutoResetPageIndex] = useSkipper() - const table = tableHelper.useTable({ + const table = useTable({ + _features, columns, data, + _rowModels: { + filteredRowModel: createFilteredRowModel(filterFns), + paginatedRowModel: createPaginatedRowModel(), + }, defaultColumn, autoResetPageIndex, // Provide our updateData function to our table meta diff --git a/examples/react/editable-data/src/makeData.ts b/examples/react/editable-data/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/editable-data/src/makeData.ts +++ b/examples/react/editable-data/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/filters-faceted/src/makeData.ts b/examples/react/filters-faceted/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/filters-faceted/src/makeData.ts +++ b/examples/react/filters-faceted/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/filters/src/makeData.ts b/examples/react/filters/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/filters/src/makeData.ts +++ b/examples/react/filters/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/fully-controlled/src/main.tsx b/examples/react/fully-controlled/src/main.tsx index 8b1f72bf0b..dc6e64d06d 100644 --- a/examples/react/fully-controlled/src/main.tsx +++ b/examples/react/fully-controlled/src/main.tsx @@ -129,7 +129,7 @@ function App() { {table.getRowModel().rows.map((row) => ( - {row.getVisibleCells().map((cell) => ( + {row.getAllCells().map((cell) => ( diff --git a/examples/react/fully-controlled/src/makeData.ts b/examples/react/fully-controlled/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/fully-controlled/src/makeData.ts +++ b/examples/react/fully-controlled/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/pagination/src/makeData.ts b/examples/react/pagination/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/pagination/src/makeData.ts +++ b/examples/react/pagination/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/query-router-search-params/src/components/debouncedInput.tsx b/examples/react/query-router-search-params/src/components/debouncedInput.tsx index 316f354d15..b561a77bf1 100644 --- a/examples/react/query-router-search-params/src/components/debouncedInput.tsx +++ b/examples/react/query-router-search-params/src/components/debouncedInput.tsx @@ -23,7 +23,6 @@ export function DebouncedInput({ }, debounce) return () => clearTimeout(timeout) - // eslint-disable-next-line react-hooks/exhaustive-deps }, [value]) return ( diff --git a/examples/react/row-dnd/src/main.tsx b/examples/react/row-dnd/src/main.tsx index ddca8ceac7..2748f6a02f 100644 --- a/examples/react/row-dnd/src/main.tsx +++ b/examples/react/row-dnd/src/main.tsx @@ -1,7 +1,7 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' -import { useTable } from '@tanstack/react-table' +import { FlexRender, useTable } from '@tanstack/react-table' // needed for table body level scope DnD setup import { @@ -29,6 +29,8 @@ import type { DragEndEvent, UniqueIdentifier } from '@dnd-kit/core' import type { Person } from './makeData' import type { ColumnDef, Row } from '@tanstack/react-table' +const _features = {} + // Cell Component const RowDragHandleCell = ({ rowId }: { rowId: string }) => { const { attributes, listeners } = useSortable({ @@ -43,7 +45,7 @@ const RowDragHandleCell = ({ rowId }: { rowId: string }) => { } // Row Component -const DraggableRow = ({ row }: { row: Row }) => { +const DraggableRow = ({ row }: { row: Row }) => { const { transform, transition, setNodeRef, isDragging } = useSortable({ id: row.original.userId, }) @@ -58,9 +60,9 @@ const DraggableRow = ({ row }: { row: Row }) => { return ( // connect row ref to dnd-kit, apply important styles - {row.getVisibleCells().map((cell) => ( - - + {row.getAllCells().map((cell) => ( + + ))} @@ -69,7 +71,7 @@ const DraggableRow = ({ row }: { row: Row }) => { // Table Component function App() { - const columns = React.useMemo>>( + const columns = React.useMemo>>( () => [ // Create a dedicated drag handle column. Alternatively, you could just set up dnd events on the rows themselves. { diff --git a/examples/react/row-pinning/src/makeData.ts b/examples/react/row-pinning/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/row-pinning/src/makeData.ts +++ b/examples/react/row-pinning/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/sub-components/src/makeData.ts b/examples/react/sub-components/src/makeData.ts index b9fb014aba..95302cdf16 100644 --- a/examples/react/sub-components/src/makeData.ts +++ b/examples/react/sub-components/src/makeData.ts @@ -36,7 +36,7 @@ const newPerson = (): Person => { export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] - return range(len).map((d): Person => { + return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, diff --git a/examples/react/virtualized-columns-experimental/src/main.tsx b/examples/react/virtualized-columns-experimental/src/main.tsx index 97ea54bf98..ab74c1d09d 100644 --- a/examples/react/virtualized-columns-experimental/src/main.tsx +++ b/examples/react/virtualized-columns-experimental/src/main.tsx @@ -1,14 +1,16 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' +import { useVirtualizer } from '@tanstack/react-virtual' import { + FlexRender, columnSizingFeature, createSortedRowModel, - FlexRender, rowSortingFeature, sortFns, useTable, } from '@tanstack/react-table' +import { makeColumns, makeData } from './makeData' import type { Cell, ColumnDef, @@ -17,9 +19,7 @@ import type { ReactTable, Row, } from '@tanstack/react-table' -import { useVirtualizer } from '@tanstack/react-virtual' import type { Virtualizer } from '@tanstack/react-virtual' -import { makeColumns, makeData } from './makeData' import type { Person } from './makeData' const _features = { @@ -81,19 +81,19 @@ interface TableContainerProps { function TableContainer({ table }: TableContainerProps) { const visibleColumns = table.getAllLeafColumns() - //The virtualizers need to know the scrollable container element + // The virtualizers need to know the scrollable container element const tableContainerRef = React.useRef(null) - //we are using a slightly different virtualization strategy for columns (compared to virtual rows) in order to support dynamic row heights + // we are using a slightly different virtualization strategy for columns (compared to virtual rows) in order to support dynamic row heights const columnVirtualizer = useVirtualizer< HTMLDivElement, HTMLTableCellElement >({ count: visibleColumns.length, - estimateSize: (index) => visibleColumns[index].getSize(), //estimate width of each column for accurate scrollbar dragging + estimateSize: (index) => visibleColumns[index].getSize(), // estimate width of each column for accurate scrollbar dragging getScrollElement: () => tableContainerRef.current, horizontal: true, - overscan: 3, //how many columns to render on each side off screen each way (adjust this for performance) + overscan: 3, // how many columns to render on each side off screen each way (adjust this for performance) onChange: (instance) => { // requestAnimationFrame(() => { const virtualColumns = instance.getVirtualItems() @@ -120,9 +120,9 @@ function TableContainer({ table }: TableContainerProps) { className="container" ref={tableContainerRef} style={{ - overflow: 'auto', //our scrollable table container - position: 'relative', //needed for sticky header - height: '800px', //should be a fixed height + overflow: 'auto', // our scrollable table container + position: 'relative', // needed for sticky header + height: '800px', // should be a fixed height }} > ({ sorting: state.sorting })}> @@ -259,12 +259,12 @@ function TableBody({ const { rows } = table.getRowModel() - //dynamic row height virtualization - alternatively you could use a simpler fixed row height strategy without the need for `measureElement` + // dynamic row height virtualization - alternatively you could use a simpler fixed row height strategy without the need for `measureElement` const rowVirtualizer = useVirtualizer({ count: rows.length, - estimateSize: () => 33, //estimate row height for accurate scrollbar dragging + estimateSize: () => 33, // estimate row height for accurate scrollbar dragging getScrollElement: () => tableContainerRef.current, - //measure dynamic row height, except in firefox because it measures table border height incorrectly + // measure dynamic row height, except in firefox because it measures table border height incorrectly measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 @@ -294,7 +294,7 @@ function TableBody({ ref={tableBodyRef} style={{ display: 'grid', - position: 'relative', //needed for absolute positioning of rows + position: 'relative', // needed for absolute positioning of rows }} > {virtualRowIndexes.map((virtualRowIndex) => { @@ -335,13 +335,13 @@ function TableBodyRow({ return ( { if (node && typeof virtualRowIndex !== 'undefined') { rowVirtualizer.measureElement(node) rowRefsMap.current.set(virtualRowIndex, node) } - }} //measure dynamic row height + }} // measure dynamic row height key={row.id} style={{ display: 'flex', diff --git a/examples/react/virtualized-columns/src/main.tsx b/examples/react/virtualized-columns/src/main.tsx index e6a9ff013e..4f2c6e353f 100644 --- a/examples/react/virtualized-columns/src/main.tsx +++ b/examples/react/virtualized-columns/src/main.tsx @@ -2,6 +2,7 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { + FlexRender, columnSizingFeature, createSortedRowModel, rowSortingFeature, @@ -214,7 +215,7 @@ function TableHeadCell({ header }: TableHeadCellProps) { onClick: header.column.getToggleSortingHandler(), }} > - + {{ asc: ' 🔼', desc: ' 🔽', @@ -344,7 +345,7 @@ function TableBodyCell({ cell }: TableBodyCellProps) { width: cell.column.getSize(), }} > - + ) } diff --git a/examples/react/virtualized-columns/src/makeData.ts b/examples/react/virtualized-columns/src/makeData.ts index 2d45800b12..9e2a7d4ebf 100644 --- a/examples/react/virtualized-columns/src/makeData.ts +++ b/examples/react/virtualized-columns/src/makeData.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker' -export const makeColumns = (num) => +export const makeColumns = (num: number) => [...Array(num)].map((_, i) => { return { accessorKey: i.toString(), @@ -9,10 +9,16 @@ export const makeColumns = (num) => } }) -export const makeData = (num, columns) => +export const makeData = ( + num: number, + columns: Array<{ accessorKey: string }>, +) => [...Array(num)].map(() => ({ ...Object.fromEntries( - columns.map((col) => [col.accessorKey, faker.person.firstName()]), + columns.map((col: { accessorKey: string }) => [ + col.accessorKey, + faker.person.firstName(), + ]), ), })) diff --git a/examples/react/virtualized-rows/src/main.tsx b/examples/react/virtualized-rows/src/main.tsx index a5edcf876a..e3ac7671cf 100644 --- a/examples/react/virtualized-rows/src/main.tsx +++ b/examples/react/virtualized-rows/src/main.tsx @@ -4,6 +4,7 @@ import ReactDOM from 'react-dom/client' import './index.css' import { + FlexRender, columnSizingFeature, createSortedRowModel, rowSortingFeature, @@ -249,7 +250,7 @@ function TableBodyRow({ row, virtualRow, rowVirtualizer }: TableBodyRowProps) { width: cell.column.getSize(), }} > - + ) })} diff --git a/packages/table-core/src/types/TableOptions.ts b/packages/table-core/src/types/TableOptions.ts index 2a3567be10..0f0994d948 100644 --- a/packages/table-core/src/types/TableOptions.ts +++ b/packages/table-core/src/types/TableOptions.ts @@ -16,8 +16,9 @@ import type { TableOptions_RowPagination } from '../features/row-pagination/rowP import type { TableOptions_RowPinning } from '../features/row-pinning/rowPinningFeature.types' import type { TableOptions_RowSelection } from '../features/row-selection/rowSelectionFeature.types' import type { TableOptions_RowSorting } from '../features/row-sorting/rowSortingFeature.types' -import type { RowData, UnionToIntersection } from './type-utils' +import type { RowData, UnionToIntersection, Updater } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' +import type { TableState } from './TableState' export interface TableOptions_Plugins< TFeatures extends TableFeatures, @@ -95,7 +96,11 @@ export type TableOptions< > & ExtractFeatureTypes<'TableOptions', TFeatures> & TableOptions_Plugins & - DebugOptions + DebugOptions & + // Temporary backward compatibility for onStateChange + { + onStateChange?: (updater: Updater>) => void + } // export type TableOptions< // TFeatures extends TableFeatures,